summaryrefslogtreecommitdiff
path: root/navit
diff options
context:
space:
mode:
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2008-05-18 10:01:53 +0000
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2008-05-18 10:01:53 +0000
commit0b74d7f4ee6d448ac811e2741e8cb1ed04f5ce76 (patch)
treebe7bb1cb1020f4022e41c004e2fa9d561ea3580d /navit
parentf46eb419c46011d6d103b7f06cb2c842a2cbe6c9 (diff)
downloadnavit-0b74d7f4ee6d448ac811e2741e8cb1ed04f5ce76.tar.gz
Fix:Core:Renamed src to navit for cleanup of includes
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@1059 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit')
-rw-r--r--navit/Doxyfile1228
-rw-r--r--navit/Makefile.am43
-rw-r--r--navit/attr.c248
-rw-r--r--navit/attr.h80
-rw-r--r--navit/attr_def.h135
-rw-r--r--navit/binding/Makefile.am10
-rw-r--r--navit/binding/dbus/Makefile.am5
-rw-r--r--navit/binding/dbus/binding_dbus.c267
-rw-r--r--navit/binding/dbus/navit.introspect16
-rwxr-xr-xnavit/binding/dbus/test.py11
-rw-r--r--navit/binding/python/Makefile.am5
-rw-r--r--navit/binding/python/binding_python.c283
-rw-r--r--navit/callback.c173
-rw-r--r--navit/callback.h130
-rw-r--r--navit/color.h8
-rw-r--r--navit/compass.c137
-rw-r--r--navit/compass.h7
-rw-r--r--navit/coord.c225
-rw-r--r--navit/coord.h55
-rw-r--r--navit/country.c413
-rw-r--r--navit/country.h22
-rw-r--r--navit/cursor.c167
-rw-r--r--navit/cursor.h14
-rw-r--r--navit/data.h66
-rw-r--r--navit/data/Makefile.am8
-rw-r--r--navit/data/binfile/Makefile.am4
-rw-r--r--navit/data/binfile/binfile.c644
-rw-r--r--navit/data/garmin/Makefile.am25
-rw-r--r--navit/data/garmin/gar2navit.c291
-rw-r--r--navit/data/garmin/gar2navit.h31
-rw-r--r--navit/data/garmin/garmin.c794
-rw-r--r--navit/data/garmin/garmin.h10
-rw-r--r--navit/data/garmin/garmintypes.txt412
-rw-r--r--navit/data/garmin/gentypes.c195
-rw-r--r--navit/data/garmin_img/Makefile.am4
-rw-r--r--navit/data/garmin_img/garmin_img.c1493
-rw-r--r--navit/data/mg/Makefile.am4
-rw-r--r--navit/data/mg/block.c267
-rw-r--r--navit/data/mg/map.c466
-rw-r--r--navit/data/mg/mg.h295
-rw-r--r--navit/data/mg/poly.c241
-rw-r--r--navit/data/mg/street.c728
-rw-r--r--navit/data/mg/town.c264
-rw-r--r--navit/data/mg/tree.c244
-rw-r--r--navit/data/poi_geodownload/Makefile.am6
-rw-r--r--navit/data/poi_geodownload/libmdb/Makefile.am4
-rw-r--r--navit/data/poi_geodownload/libmdb/backend.c301
-rw-r--r--navit/data/poi_geodownload/libmdb/catalog.c138
-rw-r--r--navit/data/poi_geodownload/libmdb/data.c856
-rw-r--r--navit/data/poi_geodownload/libmdb/dump.c39
-rw-r--r--navit/data/poi_geodownload/libmdb/file.c376
-rw-r--r--navit/data/poi_geodownload/libmdb/iconv.c63
-rw-r--r--navit/data/poi_geodownload/libmdb/include/Makefile.am1
-rw-r--r--navit/data/poi_geodownload/libmdb/include/mdbtools.h536
-rw-r--r--navit/data/poi_geodownload/libmdb/index.c905
-rw-r--r--navit/data/poi_geodownload/libmdb/kkd.c149
-rw-r--r--navit/data/poi_geodownload/libmdb/like.c78
-rw-r--r--navit/data/poi_geodownload/libmdb/map.c133
-rw-r--r--navit/data/poi_geodownload/libmdb/mem.c50
-rw-r--r--navit/data/poi_geodownload/libmdb/money.c139
-rw-r--r--navit/data/poi_geodownload/libmdb/options.c86
-rw-r--r--navit/data/poi_geodownload/libmdb/props.c127
-rw-r--r--navit/data/poi_geodownload/libmdb/sargs.c273
-rw-r--r--navit/data/poi_geodownload/libmdb/stats.c74
-rw-r--r--navit/data/poi_geodownload/libmdb/table.c368
-rw-r--r--navit/data/poi_geodownload/libmdb/worktable.c99
-rw-r--r--navit/data/poi_geodownload/libmdb/write.c878
-rw-r--r--navit/data/poi_geodownload/poi_geodownload.c756
-rw-r--r--navit/data/textfile/Makefile.am4
-rw-r--r--navit/data/textfile/textfile.c376
-rw-r--r--navit/data/textfile/textfile.h31
-rw-r--r--navit/data_window.c22
-rw-r--r--navit/data_window.h25
-rw-r--r--navit/data_window_int.h12
-rw-r--r--navit/debug.c87
-rw-r--r--navit/debug.h28
-rw-r--r--navit/destination.h10
-rw-r--r--navit/draw_info.h11
-rw-r--r--navit/endianess.h34
-rw-r--r--navit/event.c19
-rw-r--r--navit/event.h2
-rw-r--r--navit/fib-1.1/Makefile.am3
-rw-r--r--navit/fib-1.1/README26
-rwxr-xr-xnavit/fib-1.1/configure1045
-rw-r--r--navit/fib-1.1/configure.in17
-rw-r--r--navit/fib-1.1/fh_extractmin.397
-rw-r--r--navit/fib-1.1/fh_makeheap.317
-rw-r--r--navit/fib-1.1/fh_makekeyheap.384
-rw-r--r--navit/fib-1.1/fib.c699
-rw-r--r--navit/fib-1.1/fib.h64
-rw-r--r--navit/fib-1.1/fibpriv.h98
-rw-r--r--navit/fib-1.1/fibtest.c80
-rw-r--r--navit/fib-1.1/fibtest.out37
-rw-r--r--navit/fib-1.1/fibtest2.c69
-rw-r--r--navit/fib-1.1/fibtest2.out37
-rw-r--r--navit/fib-1.1/tt.c64
-rw-r--r--navit/fib-1.1/tt.out29
-rw-r--r--navit/fib-1.1/use.c126
-rw-r--r--navit/file.c316
-rw-r--r--navit/file.h46
-rw-r--r--navit/graphics.c1021
-rw-r--r--navit/graphics.h146
-rw-r--r--navit/graphics/Makefile.am10
-rw-r--r--navit/graphics/gtk_drawing_area/Makefile.am5
-rw-r--r--navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c916
-rw-r--r--navit/graphics/gtk_gl_ext/graphics_gtk_gl_ext.c333
-rw-r--r--navit/graphics/null/Makefile.am4
-rw-r--r--navit/graphics/null/graphics_null.c208
-rw-r--r--navit/graphics/opengl/Makefile.am5
-rw-r--r--navit/graphics/opengl/graphics_opengl.c826
-rw-r--r--navit/graphics/qt_qpainter/Makefile.am5
-rw-r--r--navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp682
-rw-r--r--navit/gtkext.h6
-rw-r--r--navit/gui.c123
-rw-r--r--navit/gui.h46
-rw-r--r--navit/gui/Makefile.am8
-rw-r--r--navit/gui/gtk/Makefile.am5
-rw-r--r--navit/gui/gtk/datawindow.c171
-rw-r--r--navit/gui/gtk/destination.c505
-rw-r--r--navit/gui/gtk/gui_gtk.h36
-rw-r--r--navit/gui/gtk/gui_gtk_action.c569
-rw-r--r--navit/gui/gtk/gui_gtk_statusbar.c162
-rw-r--r--navit/gui/gtk/gui_gtk_window.c564
-rw-r--r--navit/gui/internal/Makefile.am5
-rw-r--r--navit/gui/internal/gui_internal.c407
-rw-r--r--navit/gui/sdl/Makefile.am6
-rw-r--r--navit/gui/sdl/cegui_keyboard.cpp94
-rw-r--r--navit/gui/sdl/cegui_keyboard.h5
-rw-r--r--navit/gui/sdl/datafiles/Makefile.am20
-rwxr-xr-xnavit/gui/sdl/datafiles/fonts/DejaVuSans-10.font2
-rwxr-xr-xnavit/gui/sdl/datafiles/fonts/DejaVuSans-12.font2
-rwxr-xr-xnavit/gui/sdl/datafiles/fonts/DejaVuSans-14.font2
-rwxr-xr-xnavit/gui/sdl/datafiles/fonts/DejaVuSans.ttfbin0 -> 407768 bytes
-rw-r--r--navit/gui/sdl/datafiles/fonts/Font.xsd34
-rw-r--r--navit/gui/sdl/datafiles/imagesets/Imageset.xsd28
-rw-r--r--navit/gui/sdl/datafiles/imagesets/Mineque-Black.imageset37
-rwxr-xr-xnavit/gui/sdl/datafiles/imagesets/TaharezLook.imageset242
-rwxr-xr-xnavit/gui/sdl/datafiles/imagesets/TaharezLook.tgabin0 -> 63621 bytes
-rw-r--r--navit/gui/sdl/datafiles/imagesets/navit-skin-black-imageset.tgabin0 -> 190107 bytes
-rw-r--r--navit/gui/sdl/datafiles/layouts/GUILayout.xsd63
-rw-r--r--navit/gui/sdl/datafiles/layouts/Mineque.layout258
-rwxr-xr-xnavit/gui/sdl/datafiles/layouts/TaharezLook.layout260
-rw-r--r--navit/gui/sdl/datafiles/looknfeel/Falagard.xsd399
-rwxr-xr-xnavit/gui/sdl/datafiles/looknfeel/Mineque.looknfeel1476
-rwxr-xr-xnavit/gui/sdl/datafiles/looknfeel/TaharezLook.looknfeel4534
-rw-r--r--navit/gui/sdl/datafiles/schemes/GUIScheme.xsd54
-rwxr-xr-xnavit/gui/sdl/datafiles/schemes/Mineque.scheme67
-rwxr-xr-xnavit/gui/sdl/datafiles/schemes/TaharezLook.scheme47
-rw-r--r--navit/gui/sdl/gui_sdl.h20
-rw-r--r--navit/gui/sdl/gui_sdl_window.cpp903
-rw-r--r--navit/gui/sdl/sdl_events.cpp810
-rw-r--r--navit/gui/sdl/sdl_events.h40
-rw-r--r--navit/gui/sdl/wmcontrol.c1252
-rw-r--r--navit/gui/sdl/wmcontrol.h7
-rw-r--r--navit/item.c153
-rw-r--r--navit/item.h70
-rw-r--r--navit/item_def.h406
-rw-r--r--navit/layer.h12
-rw-r--r--navit/layout.c139
-rw-r--r--navit/layout.h70
-rw-r--r--navit/locations.txt1
-rw-r--r--navit/log.c235
-rw-r--r--navit/log.h15
-rw-r--r--navit/main.c246
-rw-r--r--navit/main.h16
-rw-r--r--navit/map-share.h8
-rw-r--r--navit/map.c250
-rw-r--r--navit/map.h157
-rw-r--r--navit/map_data.h35
-rw-r--r--navit/maps/Makefile.am23
-rw-r--r--navit/mapset.c120
-rw-r--r--navit/mapset.h22
-rw-r--r--navit/maptype.c30
-rw-r--r--navit/maptype.h21
-rw-r--r--navit/menu.c26
-rw-r--r--navit/menu.h30
-rw-r--r--navit/navigation.c982
-rw-r--r--navit/navigation.h29
-rw-r--r--navit/navit.c1583
-rw-r--r--navit/navit.dtd77
-rw-r--r--navit/navit.h80
-rw-r--r--navit/navit.xml2413
-rw-r--r--navit/osd.c100
-rw-r--r--navit/osd.h16
-rw-r--r--navit/osd/Makefile.am1
-rw-r--r--navit/osd/core/Makefile.am4
-rw-r--r--navit/osd/core/osd_core.c578
-rw-r--r--navit/osm2navit.c2442
-rw-r--r--navit/param.c46
-rw-r--r--navit/param.h15
-rw-r--r--navit/phrase.c34
-rw-r--r--navit/phrase.h8
-rw-r--r--navit/plugin.c200
-rw-r--r--navit/plugin.h137
-rw-r--r--navit/plugin_def.h11
-rw-r--r--navit/point.h13
-rw-r--r--navit/popup.c259
-rw-r--r--navit/popup.h8
-rw-r--r--navit/profile.c43
-rw-r--r--navit/profile.h17
-rw-r--r--navit/projection.c43
-rw-r--r--navit/projection.h16
-rw-r--r--navit/route.c1780
-rw-r--r--navit/route.h84
-rwxr-xr-xnavit/script/check_itemdef26
-rw-r--r--navit/script/download_index.html145
-rwxr-xr-xnavit/script/geotag36
-rwxr-xr-xnavit/script/get_map5
-rwxr-xr-xnavit/script/gps_emu19
-rwxr-xr-xnavit/script/gps_emu246
-rwxr-xr-xnavit/script/gps_emu312
-rw-r--r--navit/script/mapExtract.class.php283
-rw-r--r--navit/script/map_index.php42
-rw-r--r--navit/script/mapextract.php225
-rwxr-xr-xnavit/script/wiki2def37
-rw-r--r--navit/search.c332
-rw-r--r--navit/search.h52
-rw-r--r--navit/speech.c41
-rw-r--r--navit/speech.h19
-rw-r--r--navit/speech/Makefile.am4
-rw-r--r--navit/speech/cmdline/Makefile.am4
-rw-r--r--navit/speech/cmdline/speech_cmdline.c47
-rw-r--r--navit/speech/speech_dispatcher/Makefile.am6
-rw-r--r--navit/speech/speech_dispatcher/speech_speech_dispatcher.c67
-rw-r--r--navit/tools/gpx2navit_txt/AUTHORS9
-rw-r--r--navit/tools/gpx2navit_txt/COPYING339
-rw-r--r--navit/tools/gpx2navit_txt/ChangeLog21
-rw-r--r--navit/tools/gpx2navit_txt/INSTALL17
-rw-r--r--navit/tools/gpx2navit_txt/Makefile.am27
-rw-r--r--navit/tools/gpx2navit_txt/NEWS64
-rw-r--r--navit/tools/gpx2navit_txt/README117
-rw-r--r--navit/tools/gpx2navit_txt/TODO1
-rw-r--r--navit/tools/gpx2navit_txt/config.guess1453
-rw-r--r--navit/tools/gpx2navit_txt/config.sub1566
-rw-r--r--navit/tools/gpx2navit_txt/configure.ac47
-rwxr-xr-xnavit/tools/gpx2navit_txt/depcomp423
-rw-r--r--navit/tools/gpx2navit_txt/develop/structures.gifbin0 -> 39033 bytes
-rwxr-xr-xnavit/tools/gpx2navit_txt/install-sh251
-rw-r--r--navit/tools/gpx2navit_txt/man/Makefile.am2
-rw-r--r--navit/tools/gpx2navit_txt/man/gpx2navit_txt.1103
-rwxr-xr-xnavit/tools/gpx2navit_txt/missing336
-rwxr-xr-xnavit/tools/gpx2navit_txt/mkinstalldirs99
-rw-r--r--navit/tools/gpx2navit_txt/pinatest2.gpx4790
-rw-r--r--navit/tools/gpx2navit_txt/src/Makefile.am26
-rw-r--r--navit/tools/gpx2navit_txt/src/config.h.in99
-rw-r--r--navit/tools/gpx2navit_txt/src/elementControl.c226
-rw-r--r--navit/tools/gpx2navit_txt/src/emess.h32
-rw-r--r--navit/tools/gpx2navit_txt/src/errorcode.h22
-rw-r--r--navit/tools/gpx2navit_txt/src/geod_for.c108
-rw-r--r--navit/tools/gpx2navit_txt/src/geod_inv.c73
-rw-r--r--navit/tools/gpx2navit_txt/src/geod_set.c95
-rw-r--r--navit/tools/gpx2navit_txt/src/geodesic.h51
-rw-r--r--navit/tools/gpx2navit_txt/src/gpx2navit_txt.h273
-rw-r--r--navit/tools/gpx2navit_txt/src/main.c389
-rw-r--r--navit/tools/gpx2navit_txt/src/misc.c344
-rw-r--r--navit/tools/gpx2navit_txt/src/parser.c148
-rw-r--r--navit/tools/gpx2navit_txt/src/setmeta.c54
-rw-r--r--navit/tools/gpx2navit_txt/src/setpath.c241
-rw-r--r--navit/tools/gpx2navit_txt/src/setwpt.c52
-rw-r--r--navit/tools/gpx2navit_txt/src/utils.c199
-rw-r--r--navit/track.c318
-rw-r--r--navit/track.h26
-rw-r--r--navit/transform.c747
-rw-r--r--navit/transform.h48
-rw-r--r--navit/types.h12
-rw-r--r--navit/util.c36
-rw-r--r--navit/util.h11
-rw-r--r--navit/vehicle.c197
-rw-r--r--navit/vehicle.h32
-rw-r--r--navit/vehicle/Makefile.am4
-rw-r--r--navit/vehicle/demo/Makefile.am4
-rw-r--r--navit/vehicle/demo/vehicle_demo.c176
-rw-r--r--navit/vehicle/file/Makefile.am4
-rw-r--r--navit/vehicle/file/vehicle_file.c500
-rw-r--r--navit/vehicle/gpsd/Makefile.am5
-rw-r--r--navit/vehicle/gpsd/vehicle_gpsd.c285
-rw-r--r--navit/xmlconfig.c1097
-rw-r--r--navit/xmlconfig.h8
-rw-r--r--navit/xpm/Makefile.am8
-rw-r--r--navit/xpm/airport.xpm75
-rw-r--r--navit/xpm/attraction.xpm141
-rw-r--r--navit/xpm/bank.xpm76
-rw-r--r--navit/xpm/bar.xpm52
-rw-r--r--navit/xpm/bus.xpm165
-rw-r--r--navit/xpm/cafe.xpm25
-rw-r--r--navit/xpm/camping.xpm24
-rw-r--r--navit/xpm/car_dealer.xpm26
-rw-r--r--navit/xpm/church.xpm26
-rw-r--r--navit/xpm/cinema.xpm116
-rw-r--r--navit/xpm/cursor.xpm28
-rw-r--r--navit/xpm/dumping-station.xpm112
-rw-r--r--navit/xpm/exit.xpm78
-rw-r--r--navit/xpm/fastfood.xpm188
-rw-r--r--navit/xpm/firebrigade.xpm84
-rw-r--r--navit/xpm/flag_bk_tr.xpm27
-rw-r--r--navit/xpm/flag_bk_wh.xpm28
-rw-r--r--navit/xpm/flag_bl_wh.xpm28
-rw-r--r--navit/xpm/flag_wh_bk.xpm28
-rw-r--r--navit/xpm/fuel.xpm26
-rw-r--r--navit/xpm/gc_event.xpm41
-rw-r--r--navit/xpm/gc_multi.xpm50
-rw-r--r--navit/xpm/gc_mystery.xpm40
-rw-r--r--navit/xpm/gc_question.xpm25
-rw-r--r--navit/xpm/gc_reference.xpm40
-rw-r--r--navit/xpm/gc_stages.xpm45
-rw-r--r--navit/xpm/gc_tradi.xpm41
-rw-r--r--navit/xpm/gc_webcam.xpm44
-rw-r--r--navit/xpm/golf.xpm275
-rw-r--r--navit/xpm/heliport.xpm19
-rw-r--r--navit/xpm/highway_exit.xpm65
-rw-r--r--navit/xpm/hospital.xpm24
-rw-r--r--navit/xpm/hotel.xpm26
-rw-r--r--navit/xpm/information.xpm70
-rw-r--r--navit/xpm/level_crossing.xpm16
-rw-r--r--navit/xpm/library.xpm34
-rw-r--r--navit/xpm/mini_roundabout.xpm18
-rw-r--r--navit/xpm/museum.xpm67
-rw-r--r--navit/xpm/nav_left_1.xpm69
-rw-r--r--navit/xpm/nav_left_2.xpm69
-rw-r--r--navit/xpm/nav_right_1.xpm69
-rw-r--r--navit/xpm/nav_right_2.xpm69
-rw-r--r--navit/xpm/nav_straight.xpm69
-rw-r--r--navit/xpm/parking.xpm24
-rw-r--r--navit/xpm/peak.xpm13
-rw-r--r--navit/xpm/pharmacy.xpm39
-rw-r--r--navit/xpm/picnic.xpm66
-rw-r--r--navit/xpm/police.xpm82
-rw-r--r--navit/xpm/post.xpm25
-rw-r--r--navit/xpm/restaurant.xpm73
-rw-r--r--navit/xpm/restroom.xpm134
-rw-r--r--navit/xpm/shopping.xpm20
-rw-r--r--navit/xpm/skiing.xpm139
-rw-r--r--navit/xpm/sports.xpm95
-rw-r--r--navit/xpm/swimming.xpm138
-rw-r--r--navit/xpm/telephone.xpm38
-rw-r--r--navit/xpm/theater.xpm72
-rw-r--r--navit/xpm/tower.xpm35
-rw-r--r--navit/xpm/townhall.xpm109
-rw-r--r--navit/xpm/traffic_signals.xpm139
-rw-r--r--navit/xpm/trailerpark.xpm110
-rw-r--r--navit/xpm/unknown.xpm24
-rw-r--r--navit/zipfile.h55
342 files changed, 71883 insertions, 0 deletions
diff --git a/navit/Doxyfile b/navit/Doxyfile
new file mode 100644
index 000000000..e21675546
--- /dev/null
+++ b/navit/Doxyfile
@@ -0,0 +1,1228 @@
+# Doxyfile 1.4.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = navit
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 0.0
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = ../doc
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is YES.
+
+SHOW_DIRECTORIES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from the
+# version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the progam writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT =
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = YES
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that a graph may be further truncated if the graph's
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default),
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, which results in a white background.
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/navit/Makefile.am b/navit/Makefile.am
new file mode 100644
index 000000000..56fff1551
--- /dev/null
+++ b/navit/Makefile.am
@@ -0,0 +1,43 @@
+include $(top_srcdir)/Makefile.inc
+DIST_SUBDIRS=binding data fib-1.1 gui graphics osd speech vehicle xpm maps
+SUBDIRS=binding data fib-1.1 gui graphics osd speech vehicle xpm
+if BUILD_SAMPLEMAP
+ SUBDIRS += maps
+endif
+
+AM_CPPFLAGS = -I$(top_srcdir)/navit/fib-1.1 @NAVIT_CFLAGS@ -DPREFIX=\"@prefix@\" -DMODULE=navit
+BUILT_SOURCES=osm2navit
+bin_PROGRAMS = navit osm2navit
+
+pkgdata_DATA = navit.xml
+
+EXTRA_DIST = navit.xml
+
+navit_SOURCES = attr.c callback.c compass.c coord.c country.c cursor.c data_window.c debug.c \
+ event.c file.c graphics.c gui.c item.c layout.c log.c main.c map.c \
+ mapset.c maptype.c menu.c navit.c navigation.c osd.c param.c phrase.c plugin.c popup.c \
+ profile.c projection.c route.c search.c speech.c transform.c track.c \
+ util.c vehicle.c xmlconfig.c attr.h attr_def.h callback.h color.h compass.h coord.h country.h \
+ cursor.h data.h data_window.h data_window_int.h debug.h destination.h draw_info.h endianess.h event.h \
+ file.h graphics.h gtkext.h gui.h item.h item_def.h log.h layer.h layout.h main.h map-share.h map.h\
+ map_data.h mapset.h maptype.h menu.h navigation.h navit.h osd.h \
+ param.h phrase.h plugin.h point.h plugin_def.h projection.h popup.h route.h profile.h search.h speech.h \
+ transform.h track.h util.h vehicle.h xmlconfig.h
+
+osm2navit_SOURCES = osm2navit.c item.c debug.c zipfile.h
+
+navit_LDADD = @NAVIT_LIBS@ @ZLIB_LIBS@ -Lfib-1.1 -lfib
+
+if !PLUGINS
+ navit_SOURCES += builtin.c
+ navit_LDADD += $(wildcard $(top_builddir)/navit/*/*/*.la)
+endif
+
+builtin.c:
+ ls $(top_builddir)/navit/*/*/*.la | sed -e "s/.la/_init(void);/" -e "s/.*lib/extern void module_/" >builtin.c
+ echo "extern void builtin_init(void);" >>builtin.c
+ echo "void builtin_init(void) {" >>builtin.c
+ ls $(top_builddir)/navit/*/*/*.la | sed -e "s/.la/_init();/" -e "s/.*lib/ module_/" >>builtin.c
+ echo "}" >>builtin.c
+
+osm2navit_LDADD = @NAVIT_LIBS@ @ZLIB_LIBS@
diff --git a/navit/attr.c b/navit/attr.c
new file mode 100644
index 000000000..be0c8f2f0
--- /dev/null
+++ b/navit/attr.c
@@ -0,0 +1,248 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <glib.h>
+#include "debug.h"
+#include "item.h"
+#include "coord.h"
+#include "transform.h"
+#include "color.h"
+#include "attr.h"
+#include "map.h"
+
+struct attr_name {
+ enum attr_type attr;
+ char *name;
+};
+
+
+static struct attr_name attr_names[]={
+#define ATTR2(x,y) ATTR(y)
+#define ATTR(x) { attr_##x, #x },
+#include "attr_def.h"
+#undef ATTR2
+#undef ATTR
+};
+
+enum attr_type
+attr_from_name(const char *name)
+{
+ int i;
+
+ for (i=0 ; i < sizeof(attr_names)/sizeof(struct attr_name) ; i++) {
+ if (! strcmp(attr_names[i].name, name))
+ return attr_names[i].attr;
+ }
+ return attr_none;
+}
+
+char *
+attr_to_name(enum attr_type attr)
+{
+ int i;
+
+ for (i=0 ; i < sizeof(attr_names)/sizeof(struct attr_name) ; i++) {
+ if (attr_names[i].attr == attr)
+ return attr_names[i].name;
+ }
+ return NULL;
+}
+
+struct attr *
+attr_new_from_text(const char *name, const char *value)
+{
+ enum attr_type attr;
+ struct attr *ret;
+ struct coord_geo *g;
+ struct coord c;
+
+ ret=g_new0(struct attr, 1);
+ dbg(1,"enter name='%s' value='%s'\n", name, value);
+ attr=attr_from_name(name);
+ ret->type=attr;
+ switch (attr) {
+ case attr_item_type:
+ ret->u.item_type=item_from_name(value);
+ break;
+ default:
+ if (attr >= attr_type_string_begin && attr <= attr_type_string_end) {
+ ret->u.str=(char *)value;
+ break;
+ }
+ if (attr >= attr_type_int_begin && attr <= attr_type_int_end) {
+ ret->u.num=atoi(value);
+ break;
+ }
+ if (attr >= attr_type_color_begin && attr <= attr_type_color_end) {
+ struct color *color=g_new0(struct color, 1);
+ int r,g,b,a;
+ ret->u.color=color;
+ if(strlen(value)==7){
+ sscanf(value,"#%02x%02x%02x", &r, &g, &b);
+ color->r = (r << 8) | r;
+ color->g = (g << 8) | g;
+ color->b = (b << 8) | b;
+ color->a = (65535);
+ } else if(strlen(value)==9){
+ sscanf(value,"#%02x%02x%02x%02x", &r, &g, &b, &a);
+ color->r = (r << 8) | r;
+ color->g = (g << 8) | g;
+ color->b = (b << 8) | b;
+ color->a = (a << 8) | a;
+ } else {
+ dbg(0,"color %s has unknown format\n",value);
+ }
+ break;
+ }
+ if (attr >= attr_type_coord_geo_start && attr <= attr_type_coord_geo_end) {
+ g=g_new(struct coord_geo, 1);
+ ret->u.coord_geo=g;
+ coord_parse(value, projection_mg, &c);
+ transform_to_geo(projection_mg, &c, g);
+ break;
+ }
+ dbg(1,"default\n");
+ g_free(ret);
+ ret=NULL;
+ }
+ return ret;
+}
+
+char *
+attr_to_text(struct attr *attr, struct map *map, int pretty)
+{
+ char *ret;
+ enum attr_type type=attr->type;
+
+ if (type >= attr_type_item_begin && type <= attr_type_item_end) {
+ struct item *item=attr->u.item;
+ if (! item)
+ return g_strdup("(nil)");
+ return g_strdup_printf("type=0x%x id=0x%x,0x%x map=%p (%s:%s)", item->type, item->id_hi, item->id_lo, item->map, item->map ? map_get_type(item->map) : "", item->map ? map_get_filename(item->map) : "");
+ }
+ if (type >= attr_type_string_begin && type <= attr_type_string_end) {
+ if (map) {
+ char *mstr=map_convert_string(map, attr->u.str);
+ ret=g_strdup(mstr);
+ } else
+ ret=g_strdup(attr->u.str);
+ return ret;
+ }
+ if (type >= attr_type_int_begin && type <= attr_type_int_end)
+ return g_strdup_printf("%d", attr->u.num);
+ return g_strdup("(no text)");
+}
+
+struct attr *
+attr_search(struct attr **attrs, struct attr *last, enum attr_type attr)
+{
+ dbg(1, "enter attrs=%p\n", attrs);
+ while (*attrs) {
+ dbg(1,"*attrs=%p\n", *attrs);
+ if ((*attrs)->type == attr) {
+ return *attrs;
+ }
+ attrs++;
+ }
+ return NULL;
+}
+
+int
+attr_generic_get_attr(struct attr **attrs, enum attr_type type, struct attr *attr, struct attr_iter *iter)
+{
+ while (*attrs) {
+ if ((*attrs)->type == type) {
+ *attr=**attrs;
+ return 1;
+ }
+ attrs++;
+ }
+ return 0;
+}
+
+int
+attr_data_size(struct attr *attr)
+{
+ if (attr->type >= attr_type_string_begin && attr->type <= attr_type_string_end) {
+ return strlen(attr->u.str)+1;
+ }
+ if (attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) {
+ return sizeof(attr->u.num);
+ }
+ return 0;
+}
+
+void *
+attr_data_get(struct attr *attr)
+{
+ if (attr->type >= attr_type_string_begin && attr->type <= attr_type_string_end) {
+ return attr->u.str;
+ }
+ if (attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) {
+ return &attr->u.num;
+ }
+ return NULL;
+}
+
+void
+attr_data_set(struct attr *attr, void *data)
+{
+ if (attr->type >= attr_type_string_begin && attr->type <= attr_type_string_end) {
+ attr->u.str=data;
+ }
+ if (attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) {
+ attr->u.num=*((int *)data);
+ }
+}
+
+void
+attr_free(struct attr *attr)
+{
+ if (attr->type == attr_position_coord_geo)
+ g_free(attr->u.coord_geo);
+ if (attr->type >= attr_type_color_begin && attr->type <= attr_type_color_end)
+ g_free(attr->u.color);
+ g_free(attr);
+}
+
+struct attr *
+attr_dup(struct attr *attr)
+{
+ int size;
+ struct attr *ret=g_new0(struct attr, 1);
+ ret->type=attr->type;
+ if (attr->type >= attr_type_int_begin && attr->type <= attr_type_int_end) {
+ ret->u.num=attr->u.num;
+ } else {
+ size=attr_data_size(attr);
+ if (size) {
+ ret->u.data=g_malloc(size);
+ memcpy(ret->u.data, attr->u.data, size);
+ }
+ }
+ return ret;
+}
+
+void
+attr_list_free(struct attr **attrs)
+{
+ int count=0;
+ while (attrs[count]) {
+ attr_free(attrs[count++]);
+ }
+ g_free(attrs);
+}
+
+struct attr **
+attr_list_dup(struct attr **attrs)
+{
+ struct attr **ret=attrs;
+ int i,count=0;
+
+ while (attrs[count])
+ count++;
+ ret=g_new0(struct attr *, count+1);
+ for (i = 0 ; i < count ; i++)
+ ret[i]=attr_dup(attrs[i]);
+ return ret;
+}
diff --git a/navit/attr.h b/navit/attr.h
new file mode 100644
index 000000000..dda3116d7
--- /dev/null
+++ b/navit/attr.h
@@ -0,0 +1,80 @@
+#ifndef NAVIT_ATTR_H
+#define NAVIT_ATTR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifndef ATTR_H
+#define ATTR_H
+
+#include "projection.h"
+
+enum item_type;
+
+enum attr_type {
+#define ATTR2(x,y) attr_##y=x,
+#define ATTR(x) attr_##x,
+#include "attr_def.h"
+#undef ATTR2
+#undef ATTR
+};
+
+#define AF_ONEWAY (1<<0)
+#define AF_ONEWAYREV (1<<1)
+#define AF_NOPASS (AF_ONEWAY|AF_ONEWAYREV)
+#define AF_ONEWAYMASK (AF_ONEWAY|AF_ONEWAYREV)
+#define AF_SEGMENTED (1<<2)
+
+
+struct attr {
+ enum attr_type type;
+ union {
+ char *str;
+ void *data;
+ int num;
+ struct item *item;
+ enum item_type item_type;
+ enum projection projection;
+ double * numd;
+ struct color *color;
+ struct coord_geo *coord_geo;
+ struct navit *navit;
+ struct callback *callback;
+ struct vehicle *vehicle;
+ struct layout *layout;
+ struct map *map;
+ struct log *log;
+ struct route *route;
+ struct navigation *navigation;
+ struct coord *coord;
+ struct pcoord *pcoord;
+ struct gui *gui;
+ struct graphics *graphics;
+ } u;
+};
+
+/* prototypes */
+enum attr_type;
+struct attr;
+struct attr_iter;
+struct map;
+enum attr_type attr_from_name(const char *name);
+char *attr_to_name(enum attr_type attr);
+struct attr *attr_new_from_text(const char *name, const char *value);
+char *attr_to_text(struct attr *attr, struct map *map, int pretty);
+struct attr *attr_search(struct attr **attrs, struct attr *last, enum attr_type attr);
+int attr_generic_get_attr(struct attr **attrs, enum attr_type type, struct attr *attr, struct attr_iter *iter);
+int attr_data_size(struct attr *attr);
+void *attr_data_get(struct attr *attr);
+void attr_data_set(struct attr *attr, void *data);
+void attr_free(struct attr *attr);
+struct attr *attr_dup(struct attr *attr);
+void attr_list_free(struct attr **attrs);
+struct attr **attr_list_dup(struct attr **attrs);
+/* end of prototypes */
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/navit/attr_def.h b/navit/attr_def.h
new file mode 100644
index 000000000..f9c025567
--- /dev/null
+++ b/navit/attr_def.h
@@ -0,0 +1,135 @@
+/* prototypes */
+
+/* common */
+ATTR2(0x00000000,none)
+ATTR(any)
+
+ATTR2(0x00010000,type_item_begin)
+ATTR(town_streets_item)
+ATTR(street_name_item)
+ATTR(street_name_numbers_item)
+ATTR(street_item)
+ATTR(street_number_item)
+ATTR(item_type) /* fixme */
+ATTR2(0x0001ffff,type_item_end)
+
+ATTR2(0x00020000,type_int_begin)
+ATTR(h)
+ATTR(id)
+ATTR(flags)
+ATTR(w)
+ATTR(x)
+ATTR(y)
+ATTR(flush_size)
+ATTR(flush_time)
+ATTR(zipfile_ref)
+ATTR(country_id)
+ATTR(position_sats)
+ATTR(position_sats_used)
+ATTR(update)
+ATTR(follow)
+ATTR(length)
+ATTR(time)
+ATTR(destination_length)
+ATTR(destination_time)
+ATTR(speed)
+ATTR(interval)
+ATTR(position_qual)
+ATTR(zoom)
+ATTR(retry_interval)
+ATTR(projection)
+ATTR(offroad)
+ATTR(vocabulary_name)
+ATTR(vocabulary_name_systematic)
+ATTR(vocabulary_distances)
+ATTR(announce_name_systematic_first)
+ATTR2(0x00028000,type_boolean_begin)
+/* boolean */
+ATTR(overwrite)
+ATTR(active)
+ATTR(cursor)
+ATTR(orientation)
+ATTR(tracking)
+ATTR(menubar)
+ATTR(statusbar)
+ATTR(toolbar)
+ATTR(animate)
+ATTR2(0x0002ffff,type_int_end)
+ATTR2(0x00030000,type_string_begin)
+ATTR(type)
+ATTR(label)
+ATTR(data)
+ATTR(charset)
+ATTR(country_all)
+ATTR(country_iso3)
+ATTR(country_iso2)
+ATTR(country_car)
+ATTR(country_name)
+ATTR(town_name)
+ATTR(town_postal)
+ATTR(district_name)
+ATTR(street_name)
+ATTR(street_name_systematic)
+ATTR(street_number)
+ATTR(debug)
+ATTR(address)
+ATTR(phone)
+ATTR(entry_fee)
+ATTR(open_hours)
+ATTR(skin)
+ATTR(fullscreen)
+ATTR(view_mode)
+ATTR(tilt)
+ATTR(media_window_title)
+ATTR(media_cmd)
+ATTR(image_codec)
+/* poi */
+ATTR(icon)
+ATTR(info_html)
+ATTR(price_html)
+/* navigation */
+ATTR(navigation_short)
+ATTR(navigation_long)
+ATTR(navigation_long_exact)
+ATTR(navigation_speech)
+ATTR(name)
+ATTR(source)
+ATTR(description)
+ATTR(gc_type)
+ATTR(layout)
+ATTR(position_nmea)
+ATTR(gpsd_query)
+ATTR(on_eof)
+ATTR2(0x0003ffff,type_string_end)
+ATTR(order_limit)
+ATTR2(0x00050000,type_double_start)
+ATTR(position_height)
+ATTR(position_speed)
+ATTR(position_direction)
+ATTR2(0x0005ffff,type_double_end)
+ATTR2(0x00060000,type_coord_geo_start)
+ATTR(position_coord_geo)
+ATTR(center)
+ATTR2(0x0006ffff,type_coord_geo_end)
+ATTR2(0x00070000,type_color_begin)
+ATTR(color)
+ATTR(color2)
+ATTR2(0x0007ffff,type_color_end)
+ATTR2(0x00080000,type_object_begin)
+ATTR(navit)
+ATTR(log)
+ATTR(callback)
+ATTR(route)
+ATTR(navigation)
+ATTR(vehicle)
+ATTR(map)
+ATTR(bookmark_map)
+ATTR(former_destination_map)
+ATTR(graphics)
+ATTR(gui)
+ATTR2(0x0008ffff,type_object_end)
+ATTR2(0x00090000,type_coord_begin)
+ATTR2(0x0009ffff,type_coord_end)
+ATTR2(0x000a0000,type_pcoord_begin)
+ATTR(destination)
+ATTR2(0x000affff,type_pcoord_end)
diff --git a/navit/binding/Makefile.am b/navit/binding/Makefile.am
new file mode 100644
index 000000000..540a233cd
--- /dev/null
+++ b/navit/binding/Makefile.am
@@ -0,0 +1,10 @@
+SUBDIRS=
+if USE_BINDING_PYTHON
+ SUBDIRS+=python
+endif
+if USE_BINDING_DBUS
+ SUBDIRS+=dbus
+endif
+
+DIST_SUBDIRS=python dbus
+
diff --git a/navit/binding/dbus/Makefile.am b/navit/binding/dbus/Makefile.am
new file mode 100644
index 000000000..55b7b2908
--- /dev/null
+++ b/navit/binding/dbus/Makefile.am
@@ -0,0 +1,5 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ @DBUS_CFLAGS@ -I$(top_srcdir)/src -DMODULE=binding_dbus
+modulebinding_LTLIBRARIES = libbinding_dbus.la
+libbinding_dbus_la_SOURCES = binding_dbus.c
+libbinding_dbus_la_LIBADD = @DBUS_LIBS@
diff --git a/navit/binding/dbus/binding_dbus.c b/navit/binding/dbus/binding_dbus.c
new file mode 100644
index 000000000..5f682180c
--- /dev/null
+++ b/navit/binding/dbus/binding_dbus.c
@@ -0,0 +1,267 @@
+#include <string.h>
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include "config.h"
+#include "main.h"
+#include "navit.h"
+#include "coord.h"
+#include "plugin.h"
+#include "debug.h"
+
+
+static DBusConnection *connection;
+
+static char *service_name="org.navit-project.navit";
+static char *object_path="/org/navit_project/navit";
+
+GHashTable *object_hash;
+GHashTable *object_count;
+
+static char *
+object_new(char *type, void *object)
+{
+ int id;
+ char *ret;
+ dbg(0,"enter %s\n", type);
+ id=(int)g_hash_table_lookup(object_count, type);
+ g_hash_table_insert(object_count, type, (void *)(id+1));
+ ret=g_strdup_printf("%s/%s/%d", object_path, type, id);
+ g_hash_table_insert(object_hash, ret, object);
+ dbg(0,"return %s\n", ret);
+ return (ret);
+}
+
+static void *
+object_get(const char *path)
+{
+ return g_hash_table_lookup(object_hash, path);
+}
+
+static void *
+object_get_from_message_arg(DBusMessage *message, char *type)
+{
+ char *opath;
+ char *prefix;
+ DBusError error;
+ void *ret=NULL;
+
+ dbus_error_init(&error);
+ if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &opath, DBUS_TYPE_INVALID)) {
+ dbus_error_free(&error);
+ dbg(0,"wrong arg type\n");
+ return NULL;
+ }
+ prefix=g_strdup_printf("%s/%s/", object_path, type);
+ if (!strncmp(prefix, opath, strlen(prefix)))
+ ret=object_get(opath);
+ else
+ dbg(0,"wrong object type\n");
+ g_free(prefix);
+ return ret;
+}
+
+static void *
+object_get_from_message(DBusMessage *message, char *type)
+{
+ const char *opath=dbus_message_get_path(message);
+ char *prefix;
+ void *ret=NULL;
+
+ prefix=g_strdup_printf("%s/%s/", object_path, type);
+ if (!strncmp(prefix, opath, strlen(prefix)))
+ ret=object_get(opath);
+ else
+ dbg(0,"wrong object type\n");
+ g_free(prefix);
+ return ret;
+}
+
+static DBusHandlerResult
+empty_reply(DBusConnection *connection, DBusMessage *message)
+{
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return(message);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+request_main_get_navit(DBusConnection *connection, DBusMessage *message)
+{
+ DBusMessage *reply;
+ DBusError error;
+ struct iter *iter;
+ struct navit *navit;
+ char *opath;
+
+ dbus_error_init(&error);
+
+ if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &opath, DBUS_TYPE_INVALID)) {
+ dbg(0,"Error parsing\n");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ dbg(0,"opath=%s\n", opath);
+ iter=object_get(opath);
+ navit=main_get_navit(iter);
+ if (navit) {
+ reply = dbus_message_new_method_return(message);
+ opath=object_new("navit",navit);
+ dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &opath, DBUS_TYPE_INVALID);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static DBusHandlerResult
+request_main_iter(DBusConnection *connection, DBusMessage *message)
+{
+ DBusMessage *reply;
+ struct iter *iter=main_iter_new();
+ dbg(0,"iter=%p\n", iter);
+ char *opath=object_new("main_iter",iter);
+ reply = dbus_message_new_method_return(message);
+ dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &opath, DBUS_TYPE_INVALID);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+request_main_iter_destroy(DBusConnection *connection, DBusMessage *message)
+{
+ struct iter *iter;
+
+ iter=object_get_from_message_arg(message, "main_iter");
+ if (! iter)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ main_iter_destroy(iter);
+
+ return empty_reply(connection, message);
+}
+static int
+pcoord_get_from_message(DBusMessage *message, struct pcoord *pc)
+{
+ DBusMessageIter iter,iter2;
+
+ dbus_message_iter_init(message, &iter);
+ dbg(0,"%s\n", dbus_message_iter_get_signature(&iter));
+ dbus_message_iter_recurse(&iter, &iter2);
+
+ if (dbus_message_iter_get_arg_type(&iter2) != DBUS_TYPE_INT32)
+ return 0;
+ dbus_message_iter_get_basic(&iter2, &pc->pro);
+ dbus_message_iter_next(&iter2);
+ if (dbus_message_iter_get_arg_type(&iter2) != DBUS_TYPE_INT32)
+ return 0;
+ dbus_message_iter_get_basic(&iter2, &pc->x);
+ dbus_message_iter_next(&iter2);
+ if (dbus_message_iter_get_arg_type(&iter2) != DBUS_TYPE_INT32)
+ return 0;
+ dbus_message_iter_get_basic(&iter2, &pc->y);
+ dbus_message_iter_next(&iter2);
+ if (dbus_message_iter_get_arg_type(&iter2) != DBUS_TYPE_INVALID)
+ return 0;
+ return 1;
+}
+
+static DBusHandlerResult
+request_navit_set_center(DBusConnection *connection, DBusMessage *message)
+{
+ struct pcoord pc;
+ struct navit *navit;
+ navit=object_get_from_message(message, "navit");
+ if (! navit)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ if (!pcoord_get_from_message(message, &pc))
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ navit_set_center(navit, &pc);
+ return empty_reply(connection, message);
+}
+
+static DBusHandlerResult
+navit_handler_func(DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ dbg(0,"type=%s interface=%s path=%s member=%s signature=%s\n", dbus_message_type_to_string(dbus_message_get_type(message)), dbus_message_get_interface(message), dbus_message_get_path(message), dbus_message_get_member(message), dbus_message_get_signature(message));
+#if 0
+ if (dbus_message_is_method_call (message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
+ DBusMessage *reply;
+ gchar *idata;
+ dbg(0,"Introspect\n");
+ if (! strcmp(dbus_message_get_path(message), "/org/navit_project/navit")) {
+ g_file_get_contents("binding/dbus/navit.introspect", &idata, NULL, NULL);
+ reply = dbus_message_new_method_return(message);
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &idata, DBUS_TYPE_INVALID);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+ g_free(idata);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ }
+#endif
+ if (dbus_message_is_method_call (message, "org.navit_project.navit", "iter") &&
+ dbus_message_has_signature(message, ""))
+ return request_main_iter(connection, message);
+ if (dbus_message_is_method_call (message, "org.navit_project.navit", "iter_destroy") &&
+ dbus_message_has_signature(message, "o"))
+ return request_main_iter_destroy(connection, message);
+ if (dbus_message_is_method_call (message, "org.navit_project.navit", "get_navit") &&
+ dbus_message_has_signature(message,"o"))
+ return request_main_get_navit(connection, message);
+ if (dbus_message_is_method_call (message, "org.navit_project.navit.navit", "set_center") &&
+ dbus_message_has_signature(message,"(iii)"))
+ return request_navit_set_center(connection, message);
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static DBusObjectPathVTable dbus_navit_vtable = {
+ NULL,
+ navit_handler_func,
+ NULL
+};
+
+#if 0
+DBusHandlerResult
+filter(DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ dbg(0,"type=%s interface=%s path=%s member=%s signature=%s\n", dbus_message_type_to_string(dbus_message_get_type(message)), dbus_message_get_interface(message), dbus_message_get_path(message), dbus_message_get_member(message), dbus_message_get_signature(message));
+ if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) {
+ }
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+#endif
+
+void plugin_init(void)
+{
+ DBusError error;
+
+ object_hash=g_hash_table_new(g_str_hash, g_str_equal);
+ object_count=g_hash_table_new(g_str_hash, g_str_equal);
+ dbg(0,"enter 1\n");
+ dbus_error_init(&error);
+ connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
+ if (!connection) {
+ dbg(0,"Failed to open connection to session message bus: %s", error.message);
+ dbus_error_free(&error);
+ return;
+ }
+ dbus_connection_setup_with_g_main(connection, NULL);
+#if 0
+ dbus_connection_add_filter(connection, filter, NULL, NULL);
+ dbus_bus_add_match(connection, "type='signal',""interface='" DBUS_INTERFACE_DBUS "'", &error);
+#endif
+ dbus_connection_register_fallback(connection, object_path, &dbus_navit_vtable, NULL);
+ dbus_bus_request_name(connection, service_name, 0, &error);
+ if (dbus_error_is_set(&error)) {
+ dbg(0,"Failed to request name: %s", error.message);
+ dbus_error_free (&error);
+ }
+}
diff --git a/navit/binding/dbus/navit.introspect b/navit/binding/dbus/navit.introspect
new file mode 100644
index 000000000..8afea2d6f
--- /dev/null
+++ b/navit/binding/dbus/navit.introspect
@@ -0,0 +1,16 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.navit_project.navit">
+ <method name="iter_new">
+ <arg name="iter" type="o" direction="out"/>
+ </method>
+ <method name="get_navit">
+ <arg name="iter" type="o" direction="in"/>
+ <arg name="navit" type="o" direction="out"/>
+ </method>
+ <method name="iter_destroy">
+ <arg name="iter" type="o" direction="in"/>
+ </method>
+ </interface>
+</node>
diff --git a/navit/binding/dbus/test.py b/navit/binding/dbus/test.py
new file mode 100755
index 000000000..5f69fddbf
--- /dev/null
+++ b/navit/binding/dbus/test.py
@@ -0,0 +1,11 @@
+#! /usr/bin/python
+import dbus
+bus = dbus.SessionBus()
+conn = bus.get_object('org.navit-project.navit',
+ '/org/navit_project/navit')
+iface = dbus.Interface(conn, dbus_interface='org.navit_project.navit');
+iter=iface.iter();
+navit=bus.get_object('org.navit-project.navit', conn.get_navit(iter));
+iface.iter_destroy(iter);
+navit_iface = dbus.Interface(navit, dbus_interface='org.navit_project.navit.navit');
+navit_iface.set_center((1,0x138a4a,0x5d773f));
diff --git a/navit/binding/python/Makefile.am b/navit/binding/python/Makefile.am
new file mode 100644
index 000000000..637492080
--- /dev/null
+++ b/navit/binding/python/Makefile.am
@@ -0,0 +1,5 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ @PYTHON_CFLAGS@ -I$(top_srcdir)/src -DMODULE=binding_python
+modulebinding_LTLIBRARIES = libbinding_python.la
+libbinding_python_la_SOURCES = binding_python.c
+libbinding_python_la_LIBADD = @PYTHON_LIBS@
diff --git a/navit/binding/python/binding_python.c b/navit/binding/python/binding_python.c
new file mode 100644
index 000000000..cb33f83b3
--- /dev/null
+++ b/navit/binding/python/binding_python.c
@@ -0,0 +1,283 @@
+#include "config.h"
+#include <glib.h>
+#include <Python.h>
+#include <fcntl.h>
+#include "coord.h"
+#include "projection.h"
+#include "map.h"
+#include "mapset.h"
+#include "plugin.h"
+
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+#define Obj_HEAD PyObject_HEAD_INIT(NULL);
+#else
+#define Obj_HEAD PyObject_HEAD_INIT(&PyType_Type)
+#endif
+
+/* *** coord *** */
+
+typedef struct {
+ PyObject_HEAD
+ struct coord *c;
+} coordObject;
+
+static void coord_destroy_py(coordObject *self);
+
+PyTypeObject coord_Type = {
+ Obj_HEAD
+ .tp_name="coord",
+ .tp_basicsize=sizeof(coordObject),
+ .tp_dealloc=(destructor)coord_destroy_py,
+};
+
+
+/* *** map *** */
+
+typedef struct {
+ PyObject_HEAD
+ struct map *m;
+} mapObject;
+
+static void map_destroy_py(mapObject *self);
+static PyObject *map_getattr_py(PyObject *self, char *name);
+
+PyTypeObject map_Type = {
+ Obj_HEAD
+ .tp_name="map",
+ .tp_basicsize=sizeof(mapObject),
+ .tp_dealloc=(destructor)map_destroy_py,
+ .tp_getattr=map_getattr_py,
+};
+
+/* *** IMPLEMENTATIONS *** */
+
+/* *** coord *** */
+
+static PyObject *
+coord_new_py(PyObject *self, PyObject *args)
+{
+ coordObject *ret;
+ int x,y;
+ if (!PyArg_ParseTuple(args, "ii:navit.coord",&x,&y))
+ return NULL;
+ ret=PyObject_NEW(coordObject, &coord_Type);
+ ret->c=coord_new(x,y);
+ return (PyObject *)ret;
+}
+
+static void
+coord_destroy_py(coordObject *self)
+{
+ coord_destroy(self->c);
+}
+
+/* *** coord_rect *** */
+
+typedef struct {
+ PyObject_HEAD
+ struct coord_rect *r;
+} coord_rectObject;
+
+
+static void coord_rect_destroy_py(coord_rectObject *self);
+
+PyTypeObject coord_rect_Type = {
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+ PyObject_HEAD_INIT(NULL);
+#else
+ PyObject_HEAD_INIT(&PyType_Type)
+#endif
+ .tp_name="coord_rect",
+ .tp_basicsize=sizeof(coord_rectObject),
+ .tp_dealloc=(destructor)coord_rect_destroy_py,
+};
+
+static PyObject *
+coord_rect_new_py(PyObject *self, PyObject *args)
+{
+ coord_rectObject *ret;
+ coordObject *lu,*rd;
+ if (!PyArg_ParseTuple(args, "O!O!:navit.coord_rect_rect",&coord_Type,&lu,&coord_Type,&rd))
+ return NULL;
+ ret=PyObject_NEW(coord_rectObject, &coord_rect_Type);
+ ret->r=coord_rect_new(lu->c,rd->c);
+ return (PyObject *)ret;
+}
+
+static void
+coord_rect_destroy_py(coord_rectObject *self)
+{
+ coord_rect_destroy(self->r);
+}
+
+/* *** map_rect *** */
+
+typedef struct {
+ PyObject_HEAD
+ struct map_rect *mr;
+} map_rectObject;
+
+
+static void map_rect_destroy_py(map_rectObject *self);
+
+PyTypeObject map_rect_Type = {
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+ PyObject_HEAD_INIT(NULL);
+#else
+ PyObject_HEAD_INIT(&PyType_Type)
+#endif
+ .tp_name="map_rect",
+ .tp_basicsize=sizeof(map_rectObject),
+ .tp_dealloc=(destructor)map_rect_destroy_py,
+};
+
+static PyObject *
+map_rect_new_py(mapObject *self, PyObject *args)
+{
+ map_rectObject *ret;
+ coord_rectObject *r;
+ if (!PyArg_ParseTuple(args, "O!:navit.map_rect_rect",&coord_rect_Type,&r))
+ return NULL;
+ ret=PyObject_NEW(map_rectObject, &map_rect_Type);
+ ret->mr=map_rect_new(self->m, NULL);
+ return (PyObject *)ret;
+}
+
+static void
+map_rect_destroy_py(map_rectObject *self)
+{
+ map_rect_destroy(self->mr);
+}
+
+
+/* *** map *** */
+
+
+
+static PyMethodDef map_methods[] = {
+ {"map_rect_new", (PyCFunction) map_rect_new_py, METH_VARARGS },
+ {NULL, NULL },
+};
+
+static PyObject *
+map_getattr_py(PyObject *self, char *name)
+{
+ return Py_FindMethod(map_methods, self, name);
+}
+
+
+static PyObject *
+map_new_py(PyObject *self, PyObject *args)
+{
+ mapObject *ret;
+ char *type, *filename;
+
+ if (!PyArg_ParseTuple(args, "ss:navit.map", &type, &filename))
+ return NULL;
+ ret=PyObject_NEW(mapObject, &map_Type);
+ ret->m=map_new(type,NULL);
+ return (PyObject *)ret;
+}
+
+static void
+map_destroy_py(mapObject *self)
+{
+ map_destroy(self->m);
+}
+
+/* *** mapset *** */
+
+
+typedef struct {
+ PyObject_HEAD
+ struct mapset *ms;
+} mapsetObject;
+
+
+static void mapset_destroy_py(mapsetObject *self);
+static PyObject *mapset_getattr_py(PyObject *self, char *name);
+
+PyTypeObject mapset_Type = {
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+ PyObject_HEAD_INIT(NULL);
+#else
+ PyObject_HEAD_INIT(&PyType_Type)
+#endif
+ .tp_name="mapset",
+ .tp_basicsize=sizeof(mapsetObject),
+ .tp_dealloc=(destructor)mapset_destroy_py,
+ .tp_getattr=mapset_getattr_py,
+};
+
+static PyObject *
+mapset_add_py(mapsetObject *self, PyObject *args)
+{
+ mapObject *map;
+ if (!PyArg_ParseTuple(args, "O:navit.mapset", &map))
+ return NULL;
+ Py_INCREF(map);
+ mapset_add(self->ms, map->m);
+ return Py_BuildValue("");
+}
+
+static PyMethodDef mapset_methods[] = {
+ {"add", (PyCFunction) mapset_add_py, METH_VARARGS },
+ {NULL, NULL },
+};
+
+static PyObject *
+mapset_getattr_py(PyObject *self, char *name)
+{
+ return Py_FindMethod(mapset_methods, self, name);
+}
+
+static PyObject *
+mapset_new_py(PyObject *self, PyObject *args)
+{
+ mapsetObject *ret;
+ if (!PyArg_ParseTuple(args, ":navit.mapset"))
+ return NULL;
+ ret=PyObject_NEW(mapsetObject, &mapset_Type);
+ ret->ms=mapset_new();
+ return (PyObject *)ret;
+}
+
+static void
+mapset_destroy_py(mapsetObject *self)
+{
+ mapset_destroy(self->ms);
+}
+
+
+
+static PyMethodDef navitMethods[]={
+ {"coord", coord_new_py, METH_VARARGS, "Create a new coordinate point."},
+ {"coord_rect", coord_rect_new_py, METH_VARARGS, "Create a new coordinate rectangle."},
+ {"map", map_new_py, METH_VARARGS, "Create a new map."},
+ {"mapset", mapset_new_py, METH_VARARGS, "Create a new mapset."},
+ {NULL, NULL, 0, NULL}
+};
+
+
+void
+plugin_init(void)
+{
+ int fd,size;
+ char buffer[65536];
+
+ return;
+
+ Py_Initialize();
+ Py_InitModule("navit", navitMethods);
+ fd=open("startup.py",O_RDONLY);
+ if (fd >= 0) {
+ size=read(fd, buffer, 65535);
+ if (size > 0) {
+ buffer[size]='\0';
+ PyRun_SimpleString(buffer);
+ }
+ }
+
+ Py_Finalize();
+ exit(0);
+}
diff --git a/navit/callback.c b/navit/callback.c
new file mode 100644
index 000000000..b8c386aa6
--- /dev/null
+++ b/navit/callback.c
@@ -0,0 +1,173 @@
+#include <glib.h>
+#include <string.h>
+#include "item.h"
+#include "debug.h"
+#include "callback.h"
+
+struct callback {
+ void (*func)();
+ int pcount;
+ enum attr_type type;
+ void *p[0];
+
+};
+
+struct callback_list {
+ GList *list;
+};
+
+struct callback_list *
+callback_list_new(void)
+{
+ struct callback_list *ret=g_new0(struct callback_list, 1);
+
+ return ret;
+}
+
+struct callback *
+callback_new_attr(void (*func)(void), enum attr_type type, int pcount, void **p)
+{
+ struct callback *ret;
+ int i;
+
+ ret=g_malloc0(sizeof(struct callback)+pcount*sizeof(void *));
+ ret->func=func;
+ ret->pcount=pcount;
+ ret->type=type;
+ for (i = 0 ; i < pcount ; i++) {
+ ret->p[i]=p[i];
+ }
+ return ret;
+}
+
+struct callback *
+callback_new(void (*func)(void), int pcount, void **p)
+{
+ return callback_new_attr(func, attr_none, pcount, p);
+}
+
+void
+callback_set_arg(struct callback *cb, int arg, void *p)
+{
+ if (arg < 0 || arg > cb->pcount)
+ return;
+ cb->p[arg]=p;
+}
+
+void
+callback_list_add(struct callback_list *l, struct callback *cb)
+{
+ l->list=g_list_prepend(l->list, cb);
+}
+
+
+struct callback *
+callback_list_add_new(struct callback_list *l, void (*func)(void), int pcount, void **p)
+{
+ struct callback *ret;
+
+ ret=callback_new(func, pcount, p);
+ callback_list_add(l, ret);
+ return ret;
+}
+
+void
+callback_list_remove(struct callback_list *l, struct callback *cb)
+{
+ l->list=g_list_remove(l->list, cb);
+}
+
+void
+callback_list_remove_destroy(struct callback_list *l, struct callback *cb)
+{
+ callback_list_remove(l, cb);
+ g_free(cb);
+}
+
+void
+callback_call(struct callback *cb, int pcount, void **p)
+{
+ int i;
+ void *pf[8];
+ if (! cb)
+ return;
+ if (cb->pcount + pcount <= 8) {
+ dbg(1,"cb->pcount=%d\n", cb->pcount);
+ if (cb->pcount && cb->p)
+ dbg(1,"cb->p[0]=%p\n", cb->p[0]);
+ dbg(1,"pcount=%d\n", pcount);
+ if (pcount && p)
+ dbg(1,"p[0]=%p\n", p[0]);
+ for (i = 0 ; i < cb->pcount ; i++)
+ pf[i]=cb->p[i];
+ for (i = 0 ; i < pcount ; i++)
+ pf[i+cb->pcount]=p[i];
+ switch (cb->pcount+pcount) {
+ case 8:
+ cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5],pf[6],pf[7]);
+ break;
+ case 7:
+ cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5],pf[6]);
+ break;
+ case 6:
+ cb->func(pf[0],pf[1],pf[2],pf[3],pf[4],pf[5]);
+ break;
+ case 5:
+ cb->func(pf[0],pf[1],pf[2],pf[3],pf[4]);
+ break;
+ case 4:
+ cb->func(pf[0],pf[1],pf[2],pf[3]);
+ break;
+ case 3:
+ cb->func(pf[0],pf[1],pf[2]);
+ break;
+ case 2:
+ cb->func(pf[0],pf[1]);
+ break;
+ case 1:
+ cb->func(pf[0]);
+ break;
+ case 0:
+ cb->func();
+ break;
+ }
+ } else {
+ g_warning("too many parameters for callback (%d+%d)\n", cb->pcount, pcount);
+ }
+}
+
+void
+callback_list_call_attr(struct callback_list *l, enum attr_type type, int pcount, void **p)
+{
+ GList *cbi;
+ struct callback *cb;
+
+ cbi=l->list;
+ while (cbi) {
+ cb=cbi->data;
+ if (type == attr_any || cb->type == attr_any || cb->type == type)
+ callback_call(cb, pcount, p);
+ cbi=g_list_next(cbi);
+ }
+
+}
+
+void
+callback_list_call(struct callback_list *l, int pcount, void **p)
+{
+ callback_list_call_attr(l, attr_any, pcount, p);
+}
+
+
+void
+callback_list_destroy(struct callback_list *l)
+{
+ GList *cbi;
+ cbi=l->list;
+ while (cbi) {
+ g_free(cbi->data);
+ cbi=g_list_next(cbi);
+ }
+ g_list_free(l->list);
+ g_free(l);
+}
diff --git a/navit/callback.h b/navit/callback.h
new file mode 100644
index 000000000..ebdaf047a
--- /dev/null
+++ b/navit/callback.h
@@ -0,0 +1,130 @@
+#ifndef NAVIT_CALLBACK_H
+#define NAVIT_CALLBACK_H
+
+#include "item.h"
+#include "attr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* prototypes */
+enum attr_type;
+struct callback;
+struct callback_list;
+struct callback_list *callback_list_new(void);
+struct callback * callback_new_attr(void (*func)(void), enum attr_type type, int pcount, void **p);
+struct callback *callback_new(void (*func)(void), int pcount, void **p);
+void callback_set_arg(struct callback *cb, int arg, void *p);
+void callback_list_add(struct callback_list *l, struct callback *cb);
+struct callback *callback_list_add_new(struct callback_list *l, void (*func)(void), int pcount, void **p);
+void callback_list_remove(struct callback_list *l, struct callback *cb);
+void callback_list_remove_destroy(struct callback_list *l, struct callback *cb);
+void callback_call(struct callback *cb, int pcount, void **p);
+void callback_list_call_attr(struct callback_list *l, enum attr_type type, int pcount, void **p);
+void callback_list_call(struct callback_list *l, int pcount, void **p);
+void callback_list_destroy(struct callback_list *l);
+/* end of prototypes */
+
+static inline struct callback *callback_new_attr_0(void (*func)(void), enum attr_type type)
+{
+ return callback_new_attr(func, type, 0, NULL);
+}
+
+static inline struct callback *callback_new_0(void (*func)(void))
+{
+ return callback_new(func, 0, NULL);
+}
+
+static inline struct callback *callback_new_attr_1(void (*func)(void), enum attr_type type, void *p1)
+{
+ void *p[1];
+ p[0]=p1;
+ return callback_new_attr(func, type, 1, p);
+}
+
+static inline struct callback *callback_new_1(void (*func)(void), void *p1)
+{
+ void *p[1];
+ p[0]=p1;
+ return callback_new(func, 1, p);
+}
+
+static inline struct callback *callback_new_attr_2(void (*func)(void), enum attr_type type, void *p1, void *p2)
+{
+ void *p[2];
+ p[0]=p1;
+ p[1]=p2;
+ return callback_new_attr(func, type, 2, p);
+}
+
+static inline struct callback *callback_new_2(void (*func)(void), void *p1, void *p2)
+{
+ void *p[2];
+ p[0]=p1;
+ p[1]=p2;
+ return callback_new(func, 2, p);
+}
+
+static inline struct callback *callback_new_3(void (*func)(void), void *p1, void *p2, void *p3)
+{
+ void *p[3];
+ p[0]=p1;
+ p[1]=p2;
+ p[2]=p3;
+ return callback_new(func, 3, p);
+}
+
+static inline void callback_call_0(struct callback *cb)
+{
+ callback_call(cb, 0, NULL);
+}
+
+static inline void callback_call_1(struct callback *cb, void *p1)
+{
+ void *p[1];
+ p[0]=p1;
+ callback_call(cb, 1, p);
+}
+
+static inline void callback_list_call_0(struct callback_list *l)
+{
+ callback_list_call(l, 0, NULL);
+}
+
+static inline void callback_list_call_attr_1(struct callback_list *l, enum attr_type type, void *p1)
+{
+ void *p[1];
+ p[0]=p1;
+ callback_list_call_attr(l, type, 1, p);
+}
+
+static inline void callback_list_call_1(struct callback_list *l, void *p1)
+{
+ void *p[1];
+ p[0]=p1;
+ callback_list_call(l, 1, p);
+}
+
+static inline void callback_list_call_attr_2(struct callback_list *l, enum attr_type type, void *p1, void *p2)
+{
+ void *p[2];
+ p[0]=p1;
+ p[1]=p2;
+ callback_list_call_attr(l, type, 2, p);
+}
+
+static inline void callback_list_call_2(struct callback_list *l, void *p1, void *p2)
+{
+ void *p[2];
+ p[0]=p1;
+ p[1]=p2;
+ callback_list_call(l, 2, p);
+}
+
+#define callback_cast(x) (void (*)(void))(x)
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/navit/color.h b/navit/color.h
new file mode 100644
index 000000000..17d3d9c80
--- /dev/null
+++ b/navit/color.h
@@ -0,0 +1,8 @@
+#ifndef NAVIT_COLOR_H
+#define NAVIT_COLOR_H
+
+struct color {
+ int r,g,b,a;
+};
+
+#endif
diff --git a/navit/compass.c b/navit/compass.c
new file mode 100644
index 000000000..7bb9ee812
--- /dev/null
+++ b/navit/compass.c
@@ -0,0 +1,137 @@
+#include <math.h>
+#include <stdio.h>
+#include <glib.h>
+#include "point.h"
+#include "coord.h"
+#include "graphics.h"
+#include "transform.h"
+#include "item.h"
+#include "route.h"
+#include "vehicle.h"
+#include "navit.h"
+#include "compass.h"
+
+#if 0
+struct compass {
+ struct graphics *gr;
+ struct graphics_gc *bg;
+ struct graphics_gc *white;
+ struct graphics_gc *green;
+ struct graphics_font *font;
+};
+
+static void
+transform_rotate(struct point *center, int angle, struct point *p, int count)
+{
+ int i,x,y;
+ double dx,dy;
+ for (i = 0 ; i < count ; i++)
+ {
+ dx=sin(M_PI*angle/180.0);
+ dy=cos(M_PI*angle/180.0);
+ x=dy*p->x-dx*p->y;
+ y=dx*p->x+dy*p->y;
+
+ p->x=center->x+x;
+ p->y=center->y+y;
+ p++;
+ }
+}
+
+static void
+handle(struct graphics *gr, struct graphics_gc *gc, struct point *p, int r, int dir)
+{
+ struct point ph[3];
+ int l=r*0.4;
+
+ ph[0].x=0;
+ ph[0].y=r;
+ ph[1].x=0;
+ ph[1].y=-r;
+ transform_rotate(p, dir, ph, 2);
+ gr->draw_lines(gr, gc, ph, 2);
+ ph[0].x=-l;
+ ph[0].y=-r+l;
+ ph[1].x=0;
+ ph[1].y=-r;
+ ph[2].x=l;
+ ph[2].y=-r+l;
+ transform_rotate(p, dir, ph, 3);
+ gr->draw_lines(gr, gc, ph, 3);
+}
+
+void
+compass_draw(struct compass *comp, struct container *co)
+{
+ struct point p;
+ struct coord *pos, *dest;
+ double *vehicle_dir,dir,distance;
+ int dx,dy;
+ char buffer[16];
+
+ if (! co->vehicle)
+ return;
+
+ vehicle_dir=vehicle_dir_get(co->vehicle);
+ comp->gr->draw_mode(comp->gr, draw_mode_begin);
+ p.x=0;
+ p.y=0;
+ comp->gr->draw_rectangle(comp->gr, comp->bg, &p, 60, 80);
+ p.x=30;
+ p.y=30;
+ comp->gr->draw_circle(comp->gr, comp->white, &p, 50);
+ if (co->flags->orient_north)
+ handle(comp->gr,comp->white, &p, 20,0);
+ else
+ handle(comp->gr, comp->white, &p, 20, -*vehicle_dir);
+#if 0 /* FIXME */
+ dest=route_get_destination(co->route);
+ if (dest) {
+ pos=vehicle_pos_get(co->vehicle);
+ dx=dest->x-pos->x;
+ dy=dest->y-pos->y;
+ dir=atan2(dx,dy)*180.0/M_PI;
+#if 0
+ printf("dx %d dy %d dir=%f vehicle_dir=%f\n", dx, dy, dir, *vehicle_dir);
+#endif
+ if (! co->flags->orient_north)
+ dir-=*vehicle_dir;
+ handle(comp->gr, comp->green, &p, 20, dir);
+ p.x=8;
+ p.y=72;
+ distance=transform_distance(projection_mg, pos, dest)/1000.0;
+ if (distance >= 100)
+ sprintf(buffer,"%.0f km", distance);
+ else if (distance >= 10)
+ sprintf(buffer,"%.1f km", distance);
+ else
+ sprintf(buffer,"%.2f km", distance);
+
+ comp->gr->draw_text(comp->gr, comp->green, NULL, comp->font, buffer, &p, 0x10000, 0);
+ }
+#endif
+ comp->gr->draw_mode(comp->gr, draw_mode_end);
+}
+
+struct compass *
+compass_new(struct container *co)
+{
+ struct compass *this=g_new0(struct compass, 1);
+ struct point p;
+ p.x=10;
+ p.y=10;
+ this->gr=co->gra->overlay_new(co->gra, &p, 60, 80);
+ this->bg=this->gr->gc_new(this->gr);
+ this->gr->gc_set_foreground(this->bg, 0, 0, 0);
+ this->white=this->gr->gc_new(this->gr);
+ this->gr->gc_set_foreground(this->white, 0xffff, 0xffff, 0xffff);
+ this->gr->gc_set_linewidth(this->white, 2);
+ this->green=this->gr->gc_new(this->gr);
+ this->gr->gc_set_foreground(this->green, 0x0, 0xffff, 0x0);
+ this->gr->gc_set_linewidth(this->green, 2);
+
+ this->font=this->gr->font_new(this->gr, 200);
+ compass_draw(this, co);
+ return this;
+}
+#endif
diff --git a/navit/compass.h b/navit/compass.h
new file mode 100644
index 000000000..cb864170a
--- /dev/null
+++ b/navit/compass.h
@@ -0,0 +1,7 @@
+#ifndef NAVIT_COMPASS_H
+#define NAVIT_COMPASS_H
+
+struct compass * compass_new(struct container *co);
+void compass_draw(struct compass *comp, struct container *co);
+
+#endif
diff --git a/navit/coord.c b/navit/coord.c
new file mode 100644
index 000000000..74b6a1041
--- /dev/null
+++ b/navit/coord.c
@@ -0,0 +1,225 @@
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "debug.h"
+#include "coord.h"
+#include "transform.h"
+#include "projection.h"
+/**
+ * @defgroup coord Coordinate handling functions
+ * @{
+ */
+
+/**
+ * Get a coordinate
+ *
+ * @param p Pointer to the coordinate
+ * @returns the coordinate
+ */
+
+struct coord *
+coord_get(unsigned char **p)
+{
+ struct coord *ret=(struct coord *)(*p);
+ *p += sizeof(*ret);
+ return ret;
+}
+
+struct coord *
+coord_new(int x, int y)
+{
+ struct coord *c=g_new(struct coord, 1);
+
+ c->x=x;
+ c->y=y;
+
+ return c;
+}
+
+void
+coord_destroy(struct coord *c)
+{
+ g_free(c);
+}
+
+struct coord_rect *
+coord_rect_new(struct coord *lu, struct coord *rl)
+{
+ struct coord_rect *r=g_new(struct coord_rect, 1);
+
+ g_assert(lu->x <= rl->x);
+ g_assert(lu->y >= rl->y);
+
+ r->lu=*lu;
+ r->rl=*rl;
+
+ return r;
+
+}
+
+void
+coord_rect_destroy(struct coord_rect *r)
+{
+ g_free(r);
+}
+
+int
+coord_rect_overlap(struct coord_rect *r1, struct coord_rect *r2)
+{
+ g_assert(r1->lu.x <= r1->rl.x);
+ g_assert(r1->lu.y >= r1->rl.y);
+ g_assert(r2->lu.x <= r2->rl.x);
+ g_assert(r2->lu.y >= r2->rl.y);
+ dbg(1,"0x%x,0x%x - 0x%x,0x%x vs 0x%x,0x%x - 0x%x,0x%x\n", r1->lu.x, r1->lu.y, r1->rl.x, r1->rl.y, r2->lu.x, r2->lu.y, r2->rl.x, r2->rl.y);
+ if (r1->lu.x > r2->rl.x)
+ return 0;
+ if (r1->rl.x < r2->lu.x)
+ return 0;
+ if (r1->lu.y < r2->rl.y)
+ return 0;
+ if (r1->rl.y > r2->lu.y)
+ return 0;
+ return 1;
+}
+
+int
+coord_rect_contains(struct coord_rect *r, struct coord *c)
+{
+ g_assert(r->lu.x <= r->rl.x);
+ g_assert(r->lu.y >= r->rl.y);
+ if (c->x < r->lu.x)
+ return 0;
+ if (c->x > r->rl.x)
+ return 0;
+ if (c->y < r->rl.y)
+ return 0;
+ if (c->y > r->lu.y)
+ return 0;
+ return 1;
+}
+
+void
+coord_rect_extend(struct coord_rect *r, struct coord *c)
+{
+ if (c->x < r->lu.x)
+ r->lu.x=c->x;
+ if (c->x > r->rl.x)
+ r->rl.x=c->x;
+ if (c->y < r->rl.y)
+ r->rl.y=c->y;
+ if (c->y > r->lu.y)
+ r->lu.y=c->y;
+}
+
+ /* [Proj:][Ð]DMM.ss[S][S]... N/S [D][D]DMM.ss[S][S]... E/W */
+ /* [Proj:][-][D]D.d[d]... [-][D][D]D.d[d]... */
+ /* [Proj:][-]0xX [-]0xX */
+/*
+ * Currently supported:
+ * [Proj:]-0xX [-]0xX
+ * - where Proj can be mg/garmin, defaults to mg
+ * [Proj:][D][D]Dmm.ss[S][S] N/S [D][D]DMM.ss[S][S]... E/W
+ * [Proj:][-][D]D.d[d]... [-][D][D]D.d[d]
+ * - where Proj can be geo
+ */
+
+int
+coord_parse(const char *c_str, enum projection pro, struct coord *c_ret)
+{
+ int debug=0;
+ char *proj=NULL,*s,*co;
+ const char *str=c_str;
+ int args,ret = 0;
+ struct coord_geo g;
+ struct coord c;
+ enum projection str_pro=projection_none;
+
+ dbg(1,"enter('%s',%d,%p)\n", c_str, pro, c_ret);
+ s=strchr(str,' ');
+ co=strchr(str,':');
+ if (co && co < s) {
+ proj=malloc(co-str+1);
+ strncpy(proj, str, co-str);
+ proj[co-str]='\0';
+ dbg(1,"projection=%s\n", proj);
+ str=co+1;
+ s=strchr(str,' ');
+ if (!strcmp(proj, "mg"))
+ str_pro = projection_mg;
+ else if (!strcmp(proj, "garmin"))
+ str_pro = projection_garmin;
+ else if (!strcmp(proj, "geo"))
+ str_pro = projection_none;
+ else {
+ dbg(0, "Unknown projection: %s\n", proj);
+ goto out;
+ }
+ }
+ if (! s)
+ return 0;
+ while (*s == ' ') {
+ s++;
+ }
+ if (!strncmp(str, "0x", 2) || !strncmp(str,"-0x", 3)) {
+ args=sscanf(str, "%x %x%n",&c.x, &c.y, &ret);
+ if (args < 2)
+ goto out;
+ dbg(1,"str='%s' x=0x%x y=0x%x c=%d\n", str, c.x, c.y, ret);
+ dbg(1,"rest='%s'\n", str+ret);
+
+ if (str_pro == projection_none)
+ str_pro=projection_mg;
+ if (str_pro != pro) {
+ transform_to_geo(str_pro, &c, &g);
+ transform_from_geo(pro, &g, &c);
+ }
+ *c_ret=c;
+ } else if (*s == 'N' || *s == 'n' || *s == 'S' || *s == 's') {
+ double lng, lat;
+ char ns, ew;
+ dbg(1,"str='%s'\n", str);
+ args=sscanf(str, "%lf %c %lf %c%n", &lat, &ns, &lng, &ew, &ret);
+ if (args < 4)
+ goto out;
+ if (str_pro == projection_none) {
+ g.lat=floor(lat/100);
+ lat-=g.lat*100;
+ g.lat+=lat/60;
+ g.lng=floor(lng/100);
+ lng-=g.lng*100;
+ g.lng+=lng/60;
+ if (ns == 's' || ns == 'S')
+ g.lat=-g.lat;
+ if (ew == 'w' || ew == 'W')
+ g.lng=-g.lng;
+ transform_from_geo(pro, &g, c_ret);
+ }
+ dbg(3,"str='%s' x=%f ns=%c y=%f ew=%c c=%d\n", str, lng, ns, lat, ew, ret);
+ dbg(3,"rest='%s'\n", str+ret);
+ } else {
+ double lng, lat;
+ args=sscanf(str, "%lf %lf%n", &lng, &lat, &ret);
+ if (args < 2)
+ goto out;
+ dbg(1,"str='%s' x=%f y=%f c=%d\n", str, lng, lat, ret);
+ dbg(1,"rest='%s'\n", str+ret);
+ g.lng=lng;
+ g.lat=lat;
+ transform_from_geo(pro, &g, c_ret);
+ }
+ if (debug)
+ printf("rest='%s'\n", str+ret);
+ ret+=str-c_str;
+ if (debug) {
+ printf("args=%d\n", args);
+ printf("ret=%d delta=%d ret_str='%s'\n", ret, str-c_str, c_str+ret);
+ }
+out:
+ if (proj)
+ free(proj);
+ return ret;
+}
+
+/** @} */
diff --git a/navit/coord.h b/navit/coord.h
new file mode 100644
index 000000000..62c45f5a9
--- /dev/null
+++ b/navit/coord.h
@@ -0,0 +1,55 @@
+#ifndef NAVIT_COORD_H
+#define NAVIT_COORD_H
+#include "projection.h"
+
+/*! A integer mercator coordinate */
+struct coord {
+ int x; /*!< X-Value */
+ int y; /*!< Y-Value */
+};
+
+/*! A integer mercator coordinate carrying its projection */
+struct pcoord {
+ enum projection pro;
+ int x; /*!< X-Value */
+ int y; /*!< Y-Value */
+};
+
+struct coord_rect {
+ struct coord lu;
+ struct coord rl;
+};
+
+//! A double mercator coordinate
+struct coord_d {
+ double x; /*!< X-Value */
+ double y; /*!< Y-Value */
+};
+
+//! A WGS84 coordinate
+struct coord_geo {
+ double lng; /*!< Longitude */
+ double lat; /*!< Latitude */
+};
+
+//! A cartesian coordinate
+struct coord_geo_cart {
+ double x; /*!< X-Value */
+ double y; /*!< Y-Value */
+ double z; /*!< Z-Value */
+};
+
+enum projection;
+
+struct coord * coord_get(unsigned char **p);
+struct coord * coord_new(int x, int y);
+void coord_destroy(struct coord *c);
+int coord_parse(const char *c_str, enum projection pro, struct coord *c_ret);
+struct coord_rect * coord_rect_new(struct coord *lu, struct coord *rl);
+void coord_rect_destroy(struct coord_rect *r);
+int coord_rect_overlap(struct coord_rect *r1, struct coord_rect *r2);
+int coord_rect_contains(struct coord_rect *r, struct coord *c);
+void coord_rect_extend(struct coord_rect *r, struct coord *c);
+
+
+#endif
diff --git a/navit/country.c b/navit/country.c
new file mode 100644
index 000000000..0fa7a084b
--- /dev/null
+++ b/navit/country.c
@@ -0,0 +1,413 @@
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <libintl.h>
+#include "debug.h"
+#include "item.h"
+#include "country.h"
+#include "search.h"
+
+struct country {
+ int id;
+ char *car;
+ char *iso2;
+ char *iso3;
+ char *name;
+};
+
+#define gettext_noop(String) String
+#define _(STRING) gettext(STRING)
+#define _n(STRING) gettext_noop(STRING)
+
+static struct country country[]= {
+ { 20, "AND", "AD", "AND", /* 020 */ _n("Andorra")},
+ {784, "UAE", "AE", "ARE", /* 784 */ _n("United Arab Emirates")},
+ { 4, "AFG", "AF", "AFG", /* 004 */ _n("Afghanistan")},
+ { 28, "AG", "AG", "ATG", /* 028 */ _n("Antigua and Barbuda")},
+ {660, NULL, "AI", "AIA", /* 660 */ _n("Anguilla")},
+ { 8, "AL", "AL", "ALB", /* 008 */ _n("Albania")},
+ { 51, "ARM", "AM", "ARM", /* 051 */ _n("Armenia")},
+ {530, "NA", "AN", "ANT", /* 530 */ _n("Netherlands Antilles")},
+ { 24, "ANG", "AO", "AGO", /* 024 */ _n("Angola")},
+ { 10, NULL, "AQ", "ATA", /* 010 */ _n("Antarctica")},
+ { 32, "RA", "AR", "ARG", /* 032 */ _n("Argentina")},
+ { 16, NULL, "AS", "ASM", /* 016 */ _n("American Samoa")},
+ { 40, "A", "AT", "AUT", /* 040 */ _n("Austria")},
+ { 36, "AUS", "AU", "AUS", /* 036 */ _n("Australia")},
+ {533, "ARU", "AW", "ABW", /* 533 */ _n("Aruba")},
+ {248, "AX", "AX", "ALA", /* 248 */ _n("Aland Islands")},
+ { 31, "AZ", "AZ", "AZE", /* 031 */ _n("Azerbaijan")},
+ { 70, "BiH", "BA", "BIH", /* 070 */ _n("Bosnia and Herzegovina")},
+ { 52, "BDS", "BB", "BRB", /* 052 */ _n("Barbados")},
+ { 50, "BD", "BD", "BGD", /* 050 */ _n("Bangladesh")},
+ { 56, "B", "BE", "BEL", /* 056 */ _n("Belgium")},
+ {854, "BF", "BF", "BFA", /* 854 */ _n("Burkina Faso")},
+ {100, "BG", "BG", "BGR", /* 100 */ _n("Bulgaria")},
+ { 48, "BRN", "BH", "BHR", /* 048 */ _n("Bahrain")},
+ {108, "RU", "BI", "BDI", /* 108 */ _n("Burundi")},
+ {204, "BJ", "BJ", "BEN", /* 204 */ _n("Benin")},
+ {652, NULL, "BL", "BLM", /* 652 */ _n("Saint Barthelemy")},
+ { 60, NULL, "BM", "BMU", /* 060 */ _n("Bermuda")},
+ { 96, "BRU", "BN", "BRN", /* 096 */ _n("Brunei Darussalam")},
+ { 68, "BOL", "BO", "BOL", /* 068 */ _n("Bolivia")},
+ { 76, "BR", "BR", "BRA", /* 076 */ _n("Brazil")},
+ { 44, "BS", "BS", "BHS", /* 044 */ _n("Bahamas")},
+ { 64, "BHT", "BT", "BTN", /* 064 */ _n("Bhutan")},
+ { 74, NULL, "BV", "BVT", /* 074 */ _n("Bouvet Island")},
+ { 72, "RB", "BW", "BWA", /* 072 */ _n("Botswana")},
+ {112, "BY", "BY", "BLR", /* 112 */ _n("Belarus")},
+ { 84, "BZ", "BZ", "BLZ", /* 084 */ _n("Belize")},
+ {124, "CDN", "CA", "CAN", /* 124 */ _n("Canada")},
+ {166, NULL, "CC", "CCK", /* 166 */ _n("Cocos (Keeling) Islands")},
+ {180, "CGO", "CD", "COD", /* 180 */ _n("Congo, Democratic Republic of the")},
+ {140, "RCA", "CF", "CAF", /* 140 */ _n("Central African Republic")},
+ {178, NULL, "CG", "COG", /* 178 */ _n("Congo")},
+ {756, "CH", "CH", "CHE", /* 756 */ _n("Switzerland")},
+ {384, "CI", "CI", "CIV", /* 384 */ _n("Cote d'Ivoire")},
+ {184, NULL, "CK", "COK", /* 184 */ _n("Cook Islands")},
+ {152, "RCH", "CL", "CHL", /* 152 */ _n("Chile")},
+ {120, "CAM", "CM", "CMR", /* 120 */ _n("Cameroon")},
+ {156, "RC", "CN", "CHN", /* 156 */ _n("China")},
+ {170, "CO", "CO", "COL", /* 170 */ _n("Colombia")},
+ {188, "CR", "CR", "CRI", /* 188 */ _n("Costa Rica")},
+ {192, "C", "CU", "CUB", /* 192 */ _n("Cuba")},
+ {132, "CV", "CV", "CPV", /* 132 */ _n("Cape Verde")},
+ {162, NULL, "CX", "CXR", /* 162 */ _n("Christmas Island")},
+ {196, "CY", "CY", "CYP", /* 196 */ _n("Cyprus")},
+ {203, "CZ", "CZ", "CZE", /* 203 */ _n("Czech Republic")},
+ {276, "D", "DE", "DEU", /* 276 */ _n("Germany")},
+ {262, "DJI", "DJ", "DJI", /* 262 */ _n("Djibouti")},
+ {208, "DK", "DK", "DNK", /* 208 */ _n("Denmark")},
+ {212, "WD", "DM", "DMA", /* 212 */ _n("Dominica")},
+ {214, "DOM", "DO", "DOM", /* 214 */ _n("Dominican Republic")},
+ { 12, "DZ", "DZ", "DZA", /* 012 */ _n("Algeria")},
+ {218, "EC", "EC", "ECU", /* 218 */ _n("Ecuador")},
+ {233, "EST", "EE", "EST", /* 233 */ _n("Estonia")},
+ {818, "ET", "EG", "EGY", /* 818 */ _n("Egypt")},
+ {732, "WSA", "EH", "ESH", /* 732 */ _n("Western Sahara")},
+ {232, "ER", "ER", "ERI", /* 232 */ _n("Eritrea")},
+ {724, "E", "ES", "ESP", /* 724 */ _n("Spain")},
+ {231, "ETH", "ET", "ETH", /* 231 */ _n("Ethiopia")},
+ {246, "FIN", "FI", "FIN", /* 246 */ _n("Finland")},
+ {242, "FJI", "FJ", "FJI", /* 242 */ _n("Fiji")},
+ {238, NULL, "FK", "FLK", /* 238 */ _n("Falkland Islands (Malvinas)")},
+ {583, "FSM", "FM", "FSM", /* 583 */ _n("Micronesia, Federated States of")},
+ {234, "FO", "FO", "FRO", /* 234 */ _n("Faroe Islands")},
+ {250, "F", "FR", "FRA", /* 250 */ _n("France")},
+ {266, "G", "GA", "GAB", /* 266 */ _n("Gabon")},
+ {826, "GB", "GB", "GBR", /* 826 */ _n("United Kingdom")},
+ {308, "WG", "GD", "GRD", /* 308 */ _n("Grenada")},
+ {268, "GE", "GE", "GEO", /* 268 */ _n("Georgia")},
+ {254, NULL, "GF", "GUF", /* 254 */ _n("French Guiana")},
+ {831, NULL, "GG", "GGY", /* 831 */ _n("Guernsey")},
+ {288, "GH", "GH", "GHA", /* 288 */ _n("Ghana")},
+ {292, "GBZ", "GI", "GIB", /* 292 */ _n("Gibraltar")},
+ {304, "KN", "GL", "GRL", /* 304 */ _n("Greenland")},
+ {270, "WAG", "GM", "GMB", /* 270 */ _n("Gambia")},
+ {324, "RG", "GN", "GIN", /* 324 */ _n("Guinea")},
+ {312, NULL, "GP", "GLP", /* 312 */ _n("Guadeloupe")},
+ {226, "GQ", "GQ", "GNQ", /* 226 */ _n("Equatorial Guinea")},
+ {300, "GR", "GR", "GRC", /* 300 */ _n("Greece")},
+ {239, NULL, "GS", "SGS", /* 239 */ _n("South Georgia and the South Sandwich Islands")},
+ {320, "GCA", "GT", "GTM", /* 320 */ _n("Guatemala")},
+ {316, NULL, "GU", "GUM", /* 316 */ _n("Guam")},
+ {624, "GUB", "GW", "GNB", /* 624 */ _n("Guinea-Bissau")},
+ {328, "GUY", "GY", "GUY", /* 328 */ _n("Guyana")},
+ {344, "HK", "HK", "HKG", /* 344 */ _n("Hong Kong")},
+ {334, NULL, "HM", "HMD", /* 334 */ _n("Heard Island and McDonald Islands")},
+ {340, "HN", "HN", "HND", /* 340 */ _n("Honduras")},
+ {191, "HR", "HR", "HRV", /* 191 */ _n("Croatia")},
+ {332, "RH", "HT", "HTI", /* 332 */ _n("Haiti")},
+ {348, "H", "HU", "HUN", /* 348 */ _n("Hungary")},
+ {360, "RI", "ID", "IDN", /* 360 */ _n("Indonesia")},
+ {372, "IRL", "IE", "IRL", /* 372 */ _n("Ireland")},
+ {376, "IL", "IL", "ISR", /* 376 */ _n("Israel")},
+ {833, NULL, "IM", "IMN", /* 833 */ _n("Isle of Man")},
+ {356, "IND", "IN", "IND", /* 356 */ _n("India")},
+ { 86, NULL, "IO", "IOT", /* 086 */ _n("British Indian Ocean Territory")},
+ {368, "IRQ", "IQ", "IRQ", /* 368 */ _n("Iraq")},
+ {364, "IR", "IR", "IRN", /* 364 */ _n("Iran, Islamic Republic of")},
+ {352, "IS", "IS", "ISL", /* 352 */ _n("Iceland")},
+ {380, "I", "IT", "ITA", /* 380 */ _n("Italy")},
+ {832, NULL, "JE", "JEY", /* 832 */ _n("Jersey")},
+ {388, "JA", "JM", "JAM", /* 388 */ _n("Jamaica")},
+ {400, "JOR", "JO", "JOR", /* 400 */ _n("Jordan")},
+ {392, "J", "JP", "JPN", /* 392 */ _n("Japan")},
+ {404, "EAK", "KE", "KEN", /* 404 */ _n("Kenya")},
+ {417, "KS", "KG", "KGZ", /* 417 */ _n("Kyrgyzstan")},
+ {116, "K", "KH", "KHM", /* 116 */ _n("Cambodia")},
+ {296, "KIR", "KI", "KIR", /* 296 */ _n("Kiribati")},
+ {174, "COM", "KM", "COM", /* 174 */ _n("Comoros")},
+ {659, "KAN", "KN", "KNA", /* 659 */ _n("Saint Kitts and Nevis")},
+ {408, "KP", "KP", "PRK", /* 408 */ _n("Korea, Democratic People's Republic of")},
+ {410, "ROK", "KR", "KOR", /* 410 */ _n("Korea, Republic of")},
+ {414, "KWT", "KW", "KWT", /* 414 */ _n("Kuwait")},
+ {136, NULL, "KY", "CYM", /* 136 */ _n("Cayman Islands")},
+ {398, "KZ", "KZ", "KAZ", /* 398 */ _n("Kazakhstan")},
+ {418, "LAO", "LA", "LAO", /* 418 */ _n("Lao People's Democratic Republic")},
+ {422, "RL", "LB", "LBN", /* 422 */ _n("Lebanon")},
+ {662, "WL", "LC", "LCA", /* 662 */ _n("Saint Lucia")},
+ {438, "FL", "LI", "LIE", /* 438 */ _n("Liechtenstein")},
+ {144, "CL", "LK", "LKA", /* 144 */ _n("Sri Lanka")},
+ {430, "LB", "LR", "LBR", /* 430 */ _n("Liberia")},
+ {426, "LS", "LS", "LSO", /* 426 */ _n("Lesotho")},
+ {440, "LT", "LT", "LTU", /* 440 */ _n("Lithuania")},
+ {442, "L", "LU", "LUX", /* 442 */ _n("Luxembourg")},
+ {428, "LV", "LV", "LVA", /* 428 */ _n("Latvia")},
+ {434, "LAR", "LY", "LBY", /* 434 */ _n("Libyan Arab Jamahiriya")},
+ {504, "MA", "MA", "MAR", /* 504 */ _n("Morocco")},
+ {492, "MC", "MC", "MCO", /* 492 */ _n("Monaco")},
+ {498, "MD", "MD", "MDA", /* 498 */ _n("Moldova, Republic of")},
+ {499, "MNE", "ME", "MNE", /* 499 */ _n("Montenegro")},
+ {663, NULL, "MF", "MAF", /* 663 */ _n("Saint Martin (French part)")},
+ {450, "RM", "MG", "MDG", /* 450 */ _n("Madagascar")},
+ {584, "MH", "MH", "MHL", /* 584 */ _n("Marshall Islands")},
+ {807, "MK", "MK", "MKD", /* 807 */ _n("Macedonia, the former Yugoslav Republic of")},
+ {466, "RMM", "ML", "MLI", /* 466 */ _n("Mali")},
+ {104, "MYA", "MM", "MMR", /* 104 */ _n("Myanmar")},
+ {496, "MGL", "MN", "MNG", /* 496 */ _n("Mongolia")},
+ {446, NULL, "MO", "MAC", /* 446 */ _n("Macao")},
+ {580, NULL, "MP", "MNP", /* 580 */ _n("Northern Mariana Islands")},
+ {474, NULL, "MQ", "MTQ", /* 474 */ _n("Martinique")},
+ {478, "RIM", "MR", "MRT", /* 478 */ _n("Mauritania")},
+ {500, NULL, "MS", "MSR", /* 500 */ _n("Montserrat")},
+ {470, "M", "MT", "MLT", /* 470 */ _n("Malta")},
+ {480, "MS", "MU", "MUS", /* 480 */ _n("Mauritius")},
+ {462, "MV", "MV", "MDV", /* 462 */ _n("Maldives")},
+ {454, "MW", "MW", "MWI", /* 454 */ _n("Malawi")},
+ {484, "MEX", "MX", "MEX", /* 484 */ _n("Mexico")},
+ {458, "MAL", "MY", "MYS", /* 458 */ _n("Malaysia")},
+ {508, "MOC", "MZ", "MOZ", /* 508 */ _n("Mozambique")},
+ {516, "NAM", "NA", "NAM", /* 516 */ _n("Namibia")},
+ {540, "NCL", "NC", "NCL", /* 540 */ _n("New Caledonia")},
+ {562, "RN", "NE", "NER", /* 562 */ _n("Niger")},
+ {574, NULL, "NF", "NFK", /* 574 */ _n("Norfolk Island")},
+ {566, "NGR", "NG", "NGA", /* 566 */ _n("Nigeria")},
+ {558, "NIC", "NI", "NIC", /* 558 */ _n("Nicaragua")},
+ {528, "NL", "NL", "NLD", /* 528 */ _n("Netherlands")},
+ {578, "N", "NO", "NOR", /* 578 */ _n("Norway")},
+ {524, "NEP", "NP", "NPL", /* 524 */ _n("Nepal")},
+ {520, "NAU", "NR", "NRU", /* 520 */ _n("Nauru")},
+ {570, NULL, "NU", "NIU", /* 570 */ _n("Niue")},
+ {554, "NZ", "NZ", "NZL", /* 554 */ _n("New Zealand")},
+ {512, "OM", "OM", "OMN", /* 512 */ _n("Oman")},
+ {591, "PA", "PA", "PAN", /* 591 */ _n("Panama")},
+ {604, "PE", "PE", "PER", /* 604 */ _n("Peru")},
+ {258, NULL, "PF", "PYF", /* 258 */ _n("French Polynesia")},
+ {598, "PNG", "PG", "PNG", /* 598 */ _n("Papua New Guinea")},
+ {608, "RP", "PH", "PHL", /* 608 */ _n("Philippines")},
+ {586, "PK", "PK", "PAK", /* 586 */ _n("Pakistan")},
+ {616, "PL", "PL", "POL", /* 616 */ _n("Poland")},
+ {666, NULL, "PM", "SPM", /* 666 */ _n("Saint Pierre and Miquelon")},
+ {612, NULL, "PN", "PCN", /* 612 */ _n("Pitcairn")},
+ {630, "PRI", "PR", "PRI", /* 630 */ _n("Puerto Rico")},
+ {275, "AUT", "PS", "PSE", /* 275 */ _n("Palestinian Territory, Occupied")},
+ {620, "P", "PT", "PRT", /* 620 */ _n("Portugal")},
+ {585, "PAL", "PW", "PLW", /* 585 */ _n("Palau")},
+ {600, "PY", "PY", "PRY", /* 600 */ _n("Paraguay")},
+ {634, "Q", "QA", "QAT", /* 634 */ _n("Qatar")},
+ {638, NULL, "RE", "REU", /* 638 */ _n("Reunion")},
+ {642, "RO", "RO", "ROU", /* 642 */ _n("Romania")},
+ {688, "SRB", "RS", "SRB", /* 688 */ _n("Serbia")},
+ {643, "RUS", "RU", "RUS", /* 643 */ _n("Russian Federation")},
+ {646, "RWA", "RW", "RWA", /* 646 */ _n("Rwanda")},
+ {682, "KSA", "SA", "SAU", /* 682 */ _n("Saudi Arabia")},
+ { 90, "SOL", "SB", "SLB", /* 090 */ _n("Solomon Islands")},
+ {690, "SY", "SC", "SYC", /* 690 */ _n("Seychelles")},
+ {736, "SUD", "SD", "SDN", /* 736 */ _n("Sudan")},
+ {752, "S", "SE", "SWE", /* 752 */ _n("Sweden")},
+ {702, "SGP", "SG", "SGP", /* 702 */ _n("Singapore")},
+ {654, NULL, "SH", "SHN", /* 654 */ _n("Saint Helena")},
+ {705, "SLO", "SI", "SVN", /* 705 */ _n("Slovenia")},
+ {744, NULL, "SJ", "SJM", /* 744 */ _n("Svalbard and Jan Mayen")},
+ {703, "SK", "SK", "SVK", /* 703 */ _n("Slovakia")},
+ {694, "WAL", "SL", "SLE", /* 694 */ _n("Sierra Leone")},
+ {674, "RSM", "SM", "SMR", /* 674 */ _n("San Marino")},
+ {686, "SN", "SN", "SEN", /* 686 */ _n("Senegal")},
+ {706, "SO", "SO", "SOM", /* 706 */ _n("Somalia")},
+ {740, "SME", "SR", "SUR", /* 740 */ _n("Suriname")},
+ {678, "STP", "ST", "STP", /* 678 */ _n("Sao Tome and Principe")},
+ {222, "ES", "SV", "SLV", /* 222 */ _n("El Salvador")},
+ {760, "SYR", "SY", "SYR", /* 760 */ _n("Syrian Arab Republic")},
+ {748, "SD", "SZ", "SWZ", /* 748 */ _n("Swaziland")},
+ {796, NULL, "TC", "TCA", /* 796 */ _n("Turks and Caicos Islands")},
+ {148, "TD", "TD", "TCD", /* 148 */ _n("Chad")},
+ {260, "ARK", "TF", "ATF", /* 260 */ _n("French Southern Territories")},
+ {768, "RT", "TG", "TGO", /* 768 */ _n("Togo")},
+ {764, "T", "TH", "THA", /* 764 */ _n("Thailand")},
+ {762, "TJ", "TJ", "TJK", /* 762 */ _n("Tajikistan")},
+ {772, NULL, "TK", "TKL", /* 772 */ _n("Tokelau")},
+ {626, "TL", "TL", "TLS", /* 626 */ _n("Timor-Leste")},
+ {795, "TM", "TM", "TKM", /* 795 */ _n("Turkmenistan")},
+ {788, "TN", "TN", "TUN", /* 788 */ _n("Tunisia")},
+ {776, "TON", "TO", "TON", /* 776 */ _n("Tonga")},
+ {792, "TR", "TR", "TUR", /* 792 */ _n("Turkey")},
+ {780, "TT", "TT", "TTO", /* 780 */ _n("Trinidad and Tobago")},
+ {798, "TUV", "TV", "TUV", /* 798 */ _n("Tuvalu")},
+ {158, NULL, "TW", "TWN", /* 158 */ _n("Taiwan, Province of China")},
+ {834, "EAT", "TZ", "TZA", /* 834 */ _n("Tanzania, United Republic of")},
+ {804, "UA", "UA", "UKR", /* 804 */ _n("Ukraine")},
+ {800, "EAU", "UG", "UGA", /* 800 */ _n("Uganda")},
+ {581, NULL, "UM", "UMI", /* 581 */ _n("United States Minor Outlying Islands")},
+ {840, "USA", "US", "USA", /* 840 */ _n("United States")},
+ {858, "ROU", "UY", "URY", /* 858 */ _n("Uruguay")},
+ {860, "UZ", "UZ", "UZB", /* 860 */ _n("Uzbekistan")},
+ {336, "SCV", "VA", "VAT", /* 336 */ _n("Holy See (Vatican City State)")},
+ {670, "WV", "VC", "VCT", /* 670 */ _n("Saint Vincent and the Grenadines")},
+ {862, "YV", "VE", "VEN", /* 862 */ _n("Venezuela")},
+ { 92, NULL, "VG", "VGB", /* 092 */ _n("Virgin Islands, British")},
+ {850, NULL, "VI", "VIR", /* 850 */ _n("Virgin Islands, U.S.")},
+ {704, "VN", "VN", "VNM", /* 704 */ _n("Viet Nam")},
+ {548, "VAN", "VU", "VUT", /* 548 */ _n("Vanuatu")},
+ {876, NULL, "WF", "WLF", /* 876 */ _n("Wallis and Futuna")},
+ {882, "WS", "WS", "WSM", /* 882 */ _n("Samoa")},
+ {887, "YAR", "YE", "YEM", /* 887 */ _n("Yemen")},
+ {175, NULL, "YT", "MYT", /* 175 */ _n("Mayotte")},
+ {710, "ZA", "ZA", "ZAF", /* 710 */ _n("South Africa") },
+ {894, "Z", "ZM", "ZMB", /* 894 */ _n("Zambia")},
+ {716, "ZW", "ZW", "ZWE", /* 716 */ _n("Zimbabwe")},
+};
+
+
+struct country_search {
+ struct attr search;
+ int len;
+ int partial;
+ struct item item;
+ int count;
+ struct country *country;
+ enum attr_type attr_next;
+};
+
+static int
+country_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+ struct country_search *this_=priv_data;
+ struct country *country=this_->country;
+
+ attr->type=attr_type;
+ switch (attr_type) {
+ case attr_any:
+ while (this_->attr_next != attr_none) {
+ if (country_attr_get(this_, this_->attr_next, attr))
+ return 1;
+ }
+ return 0;
+ case attr_label:
+ attr->u.str=gettext(country->name);
+ this_->attr_next=attr_country_id;
+ return 1;
+ case attr_country_id:
+ attr->u.num=country->id;
+ this_->attr_next=country->car ? attr_country_car : attr_country_iso2;
+ return 1;
+ case attr_country_car:
+ attr->u.str=country->car;
+ this_->attr_next=attr_country_iso2;
+ return attr->u.str ? 1 : 0;
+ case attr_country_iso2:
+ attr->u.str=country->iso2;
+ this_->attr_next=attr_country_iso3;
+ return 1;
+ case attr_country_iso3:
+ attr->u.str=country->iso3;
+ this_->attr_next=attr_country_name;
+ return 1;
+ case attr_country_name:
+ attr->u.str=gettext(country->name);
+ this_->attr_next=attr_none;
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+
+
+struct item_methods country_meth = {
+ NULL, /* coord_rewind */
+ NULL, /* coord_get */
+ NULL, /* attr_rewind */
+ country_attr_get, /* attr_get */
+};
+
+struct country_search *
+country_search_new(struct attr *search, int partial)
+{
+ struct country_search *ret=g_new(struct country_search, 1);
+ ret->search=*search;
+ if (search->type != attr_country_id)
+ ret->len=strlen(search->u.str);
+ else
+ ret->len=0;
+ ret->partial=partial;
+ ret->count=0;
+
+ ret->item.type=type_country_label;
+ ret->item.id_hi=0;
+ ret->item.map=NULL;
+ ret->item.meth=&country_meth;
+ ret->item.priv_data=ret;
+
+ return ret;
+}
+
+static int
+match(struct country_search *this_, enum attr_type type, const char *name)
+{
+ int ret;
+ if (!name)
+ return 0;
+ if (this_->search.type != type && this_->search.type != attr_country_all)
+ return 0;
+ if (this_->partial)
+ ret=(strncasecmp(this_->search.u.str, name, this_->len) == 0);
+ else
+ ret=(strcasecmp(this_->search.u.str, name) == 0);
+ return ret;
+
+}
+
+
+struct item *
+country_search_get_item(struct country_search *this_)
+{
+ for (;;) {
+ if (this_->count >= sizeof(country)/sizeof(struct country))
+ return NULL;
+ this_->country=&country[this_->count++];
+ if ((this_->search.type == attr_country_id && this_->search.u.num == this_->country->id) ||
+ match(this_, attr_country_iso3, this_->country->iso3) ||
+ match(this_, attr_country_iso2, this_->country->iso2) ||
+ match(this_, attr_country_car, this_->country->car) ||
+ match(this_, attr_country_name, gettext(this_->country->name))) {
+ this_->item.id_lo=this_->country->id;
+ return &this_->item;
+ }
+ }
+}
+
+static struct attr country_default_attr;
+static char iso2[3];
+
+struct attr *
+country_default(void)
+{
+ char *lang;
+ if (country_default_attr.u.str)
+ return &country_default_attr;
+ lang=getenv("LANG");
+ if (!lang || strlen(lang) < 5)
+ return NULL;
+ strncpy(iso2, lang+3, 2);
+ country_default_attr.type=attr_country_iso2;
+ country_default_attr.u.str=iso2;
+ return &country_default_attr;
+}
+
+void
+country_search_destroy(struct country_search *this_)
+{
+ g_free(this_);
+}
diff --git a/navit/country.h b/navit/country.h
new file mode 100644
index 000000000..8e435f3a1
--- /dev/null
+++ b/navit/country.h
@@ -0,0 +1,22 @@
+#ifndef NAVIT_COUNTRY_H
+#define NAVIT_COUNTRY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* prototypes */
+struct attr;
+struct country_search;
+struct item;
+struct country_search *country_search_new(struct attr *search, int partial);
+struct item *country_search_get_item(struct country_search *this_);
+struct attr *country_default(void);
+void country_search_destroy(struct country_search *this_);
+/* end of prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/navit/cursor.c b/navit/cursor.c
new file mode 100644
index 000000000..cf706c24b
--- /dev/null
+++ b/navit/cursor.c
@@ -0,0 +1,167 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <math.h>
+#include <glib.h>
+#include "debug.h"
+#include "coord.h"
+#include "transform.h"
+#include "projection.h"
+#include "point.h"
+#include "graphics.h"
+#include "vehicle.h"
+#include "navit.h"
+#include "callback.h"
+#include "color.h"
+#include "cursor.h"
+#include "compass.h"
+/* #include "track.h" */
+
+
+
+struct cursor {
+ struct graphics *gra;
+#define NUM_GC 5
+ struct graphics_gc *cursor_gc[NUM_GC];
+ struct graphics_gc *cursor_gc2[NUM_GC];
+ int current_gc;
+ int last_dir;
+ int last_draw_dir;
+ guint animate_timer;
+ struct point cursor_pnt;
+};
+
+
+void
+cursor_draw(struct cursor *this_, struct point *pnt, int dir, int draw_dir, int force)
+{
+ int x=this_->cursor_pnt.x;
+ int y=this_->cursor_pnt.y;
+ int r=12,lw=2;
+ double dx,dy;
+ double fac1,fac2;
+ struct point cpnt[3];
+ struct graphics *gra=this_->gra;
+
+ if (pnt && x == pnt->x && y == pnt->y && !force)
+ return;
+ if (!graphics_ready(gra))
+ return;
+ this_->last_dir = dir;
+ this_->last_draw_dir = draw_dir;
+ cpnt[0]=this_->cursor_pnt;
+ cpnt[0].x-=r+lw;
+ cpnt[0].y-=r+lw;
+ graphics_draw_restore(gra, &cpnt[0], (r+lw)*2, (r+lw)*2);
+ if (pnt) {
+ graphics_draw_mode(gra, draw_mode_cursor);
+ this_->cursor_pnt=*pnt;
+ x=pnt->x;
+ y=pnt->y;
+ cpnt[0].x=x;
+ cpnt[0].y=y;
+ graphics_draw_circle(gra, this_->cursor_gc[this_->current_gc], &cpnt[0], r*2);
+ if (this_->cursor_gc2[this_->current_gc])
+ graphics_draw_circle(gra, this_->cursor_gc2[this_->current_gc], &cpnt[0], r*2-4);
+ if (draw_dir) {
+ dx=sin(M_PI*dir/180.0);
+ dy=-cos(M_PI*dir/180.0);
+
+ fac1=0.7*r;
+ fac2=0.4*r;
+ cpnt[0].x=x-dx*fac1+dy*fac2;
+ cpnt[0].y=y-dy*fac1-dx*fac2;
+ cpnt[1].x=x+dx*r;
+ cpnt[1].y=y+dy*r;
+ cpnt[2].x=x-dx*fac1-dy*fac2;
+ cpnt[2].y=y-dy*fac1+dx*fac2;
+ graphics_draw_lines(gra, this_->cursor_gc[this_->current_gc], cpnt, 3);
+
+ if (this_->cursor_gc2[this_->current_gc]) {
+ r-=4;
+ fac1=0.7*r;
+ fac2=0.4*r;
+ cpnt[0].x=x-dx*fac1+dy*fac2;
+ cpnt[0].y=y-dy*fac1-dx*fac2;
+ cpnt[1].x=x+dx*r;
+ cpnt[1].y=y+dy*r;
+ cpnt[2].x=x-dx*fac1-dy*fac2;
+ cpnt[2].y=y-dy*fac1+dx*fac2;
+ graphics_draw_lines(gra, this_->cursor_gc2[this_->current_gc], cpnt, 3);
+ }
+ } else {
+ cpnt[1]=cpnt[0];
+ graphics_draw_lines(gra, this_->cursor_gc[this_->current_gc], cpnt, 2);
+ if (this_->cursor_gc2[this_->current_gc])
+ graphics_draw_circle(gra, this_->cursor_gc2[this_->current_gc], &cpnt[0], 4);
+ }
+ graphics_draw_mode(gra, draw_mode_end);
+ }
+}
+
+static gboolean cursor_animate(struct cursor * this)
+{
+ struct point p;
+ this->current_gc++;
+ if (this->current_gc >= NUM_GC)
+ this->current_gc=0;
+ p.x = this->cursor_pnt.x;
+ p.y = this->cursor_pnt.y;
+ cursor_draw(this, &p, this->last_dir, this->last_draw_dir, 1);
+ return TRUE;
+}
+
+struct cursor *
+cursor_new(struct graphics *gra, struct color *c, struct color *c2, int animate)
+{
+ unsigned char dash_list[] = { 4, 6 };
+ int i;
+ struct cursor *this=g_new(struct cursor,1);
+ dbg(2,"enter gra=%p c=%p\n", gra, c);
+ this->gra=gra;
+ this->animate_timer=0;
+ for (i=0;i<NUM_GC;i++) {
+ this->cursor_gc[i]=NULL;
+ this->cursor_gc2[i]=NULL;
+ }
+ this->current_gc=0;
+ for (i=0;i<NUM_GC;i++) {
+ this->cursor_gc[i]=graphics_gc_new(gra);
+ graphics_gc_set_foreground(this->cursor_gc[i], c);
+ graphics_gc_set_linewidth(this->cursor_gc[i], 2);
+ if (c2) {
+ this->cursor_gc2[i]=graphics_gc_new(gra);
+ graphics_gc_set_foreground(this->cursor_gc2[i], c2);
+ }
+ if (animate) {
+ graphics_gc_set_dashes(this->cursor_gc[i], 2, (NUM_GC-i)*2, dash_list, 2);
+ if(this->cursor_gc2[i])
+ graphics_gc_set_dashes(this->cursor_gc2[i], 2, i*2, dash_list, 2);
+ } else {
+ graphics_gc_set_linewidth(this->cursor_gc[i], 2);
+ if(this->cursor_gc2[i])
+ graphics_gc_set_linewidth(this->cursor_gc2[i], 2);
+ break; // no need to create other GCs if we are not animating
+ }
+ }
+ if (animate)
+ this->animate_timer=g_timeout_add(250, (GSourceFunc)cursor_animate, (gpointer *)this);
+ dbg(2,"ret=%p\n", this);
+ return this;
+}
+
+void
+cursor_destroy(struct cursor *this_)
+{
+ int i;
+ if (this_->animate_timer)
+ g_source_remove(this_->animate_timer);
+ for (i=0;i<NUM_GC;i++)
+ if(this_->cursor_gc[i])
+ graphics_gc_destroy(this_->cursor_gc[i]);
+ if(this_->cursor_gc2[i])
+ graphics_gc_destroy(this_->cursor_gc2[i]);
+ g_free(this_);
+}
diff --git a/navit/cursor.h b/navit/cursor.h
new file mode 100644
index 000000000..203ef0801
--- /dev/null
+++ b/navit/cursor.h
@@ -0,0 +1,14 @@
+#ifndef NAVIT_CURSOR_H
+#define NAVIT_CURSOR_H
+
+/* prototypes */
+struct color;
+struct cursor;
+struct graphics;
+struct point;
+void cursor_draw(struct cursor *this_, struct point *pnt, int dir, int draw_dir, int force);
+struct cursor *cursor_new(struct graphics *gra, struct color *c, struct color *c2, int animate);
+void cursor_destroy(struct cursor *this_);
+/* end of prototypes */
+
+#endif
diff --git a/navit/data.h b/navit/data.h
new file mode 100644
index 000000000..451742673
--- /dev/null
+++ b/navit/data.h
@@ -0,0 +1,66 @@
+#ifndef NAVIT_DATA_H
+#define NAVIT_DATA_H
+
+static inline unsigned char
+get_u8(unsigned char **p)
+{
+ return *((*p)++);
+}
+
+static inline unsigned short
+get_u16(unsigned char **p) {
+ unsigned short ret;
+ ret=*((unsigned short *)*p);
+ *p+=sizeof(unsigned short);
+ return ret;
+}
+
+static inline unsigned short
+get_u16_unal(unsigned char **p) {
+ unsigned short ret;
+ ret=*(*p)++;
+ ret|=(*(*p)++) << 8;
+ return ret;
+}
+
+
+static inline unsigned int
+get_u24(unsigned char **p) {
+ unsigned long ret;
+ ret=get_u16(p);
+ ret|=*((*p)++) << 16;
+ return ret;
+}
+
+
+static inline unsigned int
+get_u32(unsigned char **p) {
+ unsigned long ret;
+ ret=*((unsigned int *)*p);
+ *p+=sizeof(unsigned int);
+ return ret;
+}
+
+static inline unsigned int
+get_u32_unal(unsigned char **p) {
+ unsigned long ret;
+ ret=*(*p)++;
+ ret|=(*(*p)++) << 8;
+ ret|=(*(*p)++) << 16;
+ ret|=(*(*p)++) << 24;
+ return ret;
+}
+
+static inline char *
+get_string(unsigned char **p)
+{
+ char *ret=(char *)(*p);
+ while (**p) (*p)++;
+ (*p)++;
+ return ret;
+}
+
+#define L(x) ({ unsigned char *t=(unsigned char *)&(x); t[0] | (t[1] << 8) | (t[2] << 16) | (t[3] << 24); })
+
+#endif
+
diff --git a/navit/data/Makefile.am b/navit/data/Makefile.am
new file mode 100644
index 000000000..e82f9dae4
--- /dev/null
+++ b/navit/data/Makefile.am
@@ -0,0 +1,8 @@
+SUBDIRS=mg textfile poi_geodownload binfile
+# garmin_img
+if HAVELIBGARMIN
+SUBDIRS+=garmin
+endif
+
+DIST_SUBDIRS=mg textfile poi_geodownload binfile garmin
+
diff --git a/navit/data/binfile/Makefile.am b/navit/data/binfile/Makefile.am
new file mode 100644
index 000000000..69e26f542
--- /dev/null
+++ b/navit/data/binfile/Makefile.am
@@ -0,0 +1,4 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=data_binfile
+moduledata_LTLIBRARIES = libdata_binfile.la
+libdata_binfile_la_SOURCES = binfile.c
diff --git a/navit/data/binfile/binfile.c b/navit/data/binfile/binfile.c
new file mode 100644
index 000000000..51508cc65
--- /dev/null
+++ b/navit/data/binfile/binfile.c
@@ -0,0 +1,644 @@
+#include <glib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "config.h"
+#include "debug.h"
+#include "plugin.h"
+#include "projection.h"
+#include "map.h"
+#include "maptype.h"
+#include "item.h"
+#include "attr.h"
+#include "coord.h"
+#include "transform.h"
+#include "file.h"
+#include "zipfile.h"
+#include "endianess.h"
+
+static int map_id;
+
+
+struct minmax {
+ short min;
+ short max;
+};
+
+struct tile {
+ int *start;
+ int *end;
+ int *pos;
+ int *pos_coord_start;
+ int *pos_coord;
+ int *pos_attr_start;
+ int *pos_attr;
+ int *pos_next;
+ int zipfile_num;
+};
+
+struct map_priv {
+ int id;
+ char *filename;
+ struct file *fi;
+ struct zip_cd *index_cd;
+ int cde_size;
+ struct zip_eoc *eoc;
+ int zip_members;
+};
+
+struct map_rect_priv {
+ int *start;
+ int *end;
+ enum attr_type attr_last;
+ int label;
+ int *label_attr[2];
+ struct map_selection *sel;
+ struct map_priv *m;
+ struct item item;
+ int tile_depth;
+ struct tile tiles[8];
+ struct tile *t;
+ int country_id;
+};
+
+struct map_search_priv {
+ struct map_rect_priv *mr;
+ struct attr *search;
+ struct map_selection *ms;
+ int partial;
+ GHashTable *search_results;
+};
+
+
+static void minmax_to_cpu(struct minmax * mima) {
+ g_assert(mima != NULL);
+ mima->min = le16_to_cpu(mima->min);
+ mima->max = le16_to_cpu(mima->max);
+}
+
+static void lfh_to_cpu(struct zip_lfh *lfh) {
+ g_assert(lfh != NULL);
+ lfh->ziplocsig = le32_to_cpu(lfh->ziplocsig);
+ lfh->zipver = le16_to_cpu(lfh->zipver);
+ lfh->zipgenfld = le16_to_cpu(lfh->zipgenfld);
+ lfh->zipmthd = le16_to_cpu(lfh->zipmthd);
+ lfh->ziptime = le16_to_cpu(lfh->ziptime);
+ lfh->zipdate = le16_to_cpu(lfh->zipdate);
+ lfh->zipcrc = le32_to_cpu(lfh->zipcrc);
+ lfh->zipsize = le32_to_cpu(lfh->zipsize);
+ lfh->zipuncmp = le32_to_cpu(lfh->zipuncmp);
+ lfh->zipfnln = le16_to_cpu(lfh->zipfnln);
+ lfh->zipxtraln = le16_to_cpu(lfh->zipxtraln);
+}
+
+static void cd_to_cpu(struct zip_cd *zcd) {
+ g_assert(zcd != NULL);
+ zcd->zipccrc = le32_to_cpu(zcd->zipccrc);
+ zcd->zipcsiz = le32_to_cpu(zcd->zipcsiz);
+ zcd->zipcunc = le32_to_cpu(zcd->zipcunc);
+ zcd->zipcfnl = le16_to_cpu(zcd->zipcfnl);
+ zcd->zipcxtl = le16_to_cpu(zcd->zipcxtl);
+ zcd->zipccml = le16_to_cpu(zcd->zipccml);
+ zcd->zipdsk = le16_to_cpu(zcd->zipdsk);
+ zcd->zipint = le16_to_cpu(zcd->zipint);
+ zcd->zipext = le32_to_cpu(zcd->zipext);
+ zcd->zipofst = le32_to_cpu(zcd->zipofst);
+}
+
+static void eoc_to_cpu(struct zip_eoc *eoc) {
+ g_assert(eoc != NULL);
+ eoc->zipesig = le32_to_cpu(eoc->zipesig);
+ eoc->zipedsk = le16_to_cpu(eoc->zipedsk);
+ eoc->zipecen = le16_to_cpu(eoc->zipecen);
+ eoc->zipenum = le16_to_cpu(eoc->zipenum);
+ eoc->zipecenn = le16_to_cpu(eoc->zipecenn);
+ eoc->zipecsz = le32_to_cpu(eoc->zipecsz);
+ eoc->zipeofst = le32_to_cpu(eoc->zipeofst);
+ eoc->zipecoml = le16_to_cpu(eoc->zipecoml);
+}
+
+static void
+map_destroy_binfile(struct map_priv *m)
+{
+ dbg(1,"map_destroy_binfile\n");
+ g_free(m);
+}
+
+static void
+binfile_coord_rewind(void *priv_data)
+{
+ struct map_rect_priv *mr=priv_data;
+ struct tile *t=mr->t;
+ t->pos_coord=t->pos_coord_start;
+}
+
+static int
+binfile_coord_get(void *priv_data, struct coord *c, int count)
+{
+ struct map_rect_priv *mr=priv_data;
+ struct tile *t=mr->t;
+ int ret=0;
+ dbg(2,"binfile_coord_get %d\n",count);
+ while (count--) {
+ dbg(2,"%p vs %p\n", t->pos_coord, t->pos_attr_start);
+ if (t->pos_coord >= t->pos_attr_start)
+ break;
+ c->x=le32_to_cpu(*(t->pos_coord++));
+ c->y=le32_to_cpu(*(t->pos_coord++));
+ c++;
+ ret++;
+ }
+ return ret;
+}
+
+static void
+binfile_attr_rewind(void *priv_data)
+{
+ struct map_rect_priv *mr=priv_data;
+ struct tile *t=mr->t;
+ t->pos_attr=t->pos_attr_start;
+
+}
+
+static int
+binfile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+ struct map_rect_priv *mr=priv_data;
+ struct tile *t=mr->t;
+ enum attr_type type;
+ int i,size;
+
+ if (attr_type != mr->attr_last) {
+ t->pos_attr=t->pos_attr_start;
+ mr->attr_last=attr_type;
+ }
+ while (t->pos_attr < t->pos_next) {
+ size=le32_to_cpu(*(t->pos_attr++));
+ type=le32_to_cpu(t->pos_attr[0]);
+ if (type == attr_label)
+ mr->label=1;
+ if (type == attr_town_name)
+ mr->label_attr[0]=t->pos_attr;
+ if (type == attr_street_name)
+ mr->label_attr[0]=t->pos_attr;
+ if (type == attr_street_name_systematic)
+ mr->label_attr[1]=t->pos_attr;
+ if (type == attr_type || attr_type == attr_any) {
+ if (attr_type == attr_any) {
+ dbg(1,"pos %p attr %s size %d\n", t->pos_attr-1, attr_to_name(type), size);
+ }
+ attr->type=type;
+ attr_data_set(attr, t->pos_attr+1);
+ t->pos_attr+=size;
+ return 1;
+ } else {
+ t->pos_attr+=size;
+ }
+ }
+ if (!mr->label && (attr_type == attr_any || attr_type == attr_label)) {
+ for (i = 0 ; i < sizeof(mr->label_attr)/sizeof(int *) ; i++) {
+ if (mr->label_attr[i]) {
+ mr->label=1;
+ attr->type=attr_label;
+ attr_data_set(attr, mr->label_attr[i]+1);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static struct item_methods methods_binfile = {
+ binfile_coord_rewind,
+ binfile_coord_get,
+ binfile_attr_rewind,
+ binfile_attr_get,
+};
+
+static void
+push_tile(struct map_rect_priv *mr, struct tile *t)
+{
+ g_assert(mr->tile_depth < 8);
+ mr->t=&mr->tiles[mr->tile_depth++];
+ *(mr->t)=*t;
+ mr->t->pos=mr->t->pos_next=mr->t->start;
+}
+
+static int
+pop_tile(struct map_rect_priv *mr)
+{
+ if (mr->tile_depth <= 1)
+ return 0;
+ file_data_free(mr->m->fi, (unsigned char *)(mr->t->start));
+ mr->t=&mr->tiles[--mr->tile_depth-1];
+ return 1;
+}
+
+
+static int
+zipfile_to_tile(struct file *f, struct zip_cd *cd, struct tile *t)
+{
+ char buffer[1024];
+ struct zip_lfh *lfh;
+ char *zipfn;
+ dbg(1,"enter %p %p %p\n", f, cd, t);
+ dbg(1,"cd->zipofst=0x%x\n", cd->zipofst);
+ t->start=NULL;
+ lfh=(struct zip_lfh *)(file_data_read(f,cd->zipofst,sizeof(struct zip_lfh)));
+ lfh_to_cpu(lfh);
+ zipfn=(char *)(file_data_read(f,cd->zipofst+sizeof(struct zip_lfh), lfh->zipfnln));
+ strncpy(buffer, zipfn, lfh->zipfnln);
+ buffer[lfh->zipfnln]='\0';
+ dbg(1,"0x%x '%s' %d %d,%d\n", lfh->ziplocsig, buffer, sizeof(*cd)+cd->zipcfnl, lfh->zipsize, lfh->zipuncmp);
+ switch (lfh->zipmthd) {
+ case 0:
+ t->start=(int *)(file_data_read(f,cd->zipofst+sizeof(struct zip_lfh)+lfh->zipfnln, lfh->zipuncmp));
+ t->end=t->start+lfh->zipuncmp/4;
+ break;
+ case 8:
+ t->start=(int *)(file_data_read_compressed(f,cd->zipofst+sizeof(struct zip_lfh)+lfh->zipfnln, lfh->zipsize, lfh->zipuncmp));
+ t->end=t->start+lfh->zipuncmp/4;
+ break;
+ default:
+ dbg(0,"Unknown compression method %d\n", lfh->zipmthd);
+ }
+ file_data_free(f, (unsigned char *)zipfn);
+ file_data_free(f, (unsigned char *)lfh);
+ return t->start != NULL;
+}
+
+static void
+push_zipfile_tile(struct map_rect_priv *mr, int zipfile)
+{
+ struct map_priv *m=mr->m;
+ struct file *f=m->fi;
+ struct tile t;
+ struct zip_cd *cd=(struct zip_cd *)(file_data_read(f, m->eoc->zipeofst + zipfile*m->cde_size, sizeof(struct zip_cd)));
+ cd_to_cpu(cd);
+ dbg(1,"enter %p %d\n", mr, zipfile);
+ t.zipfile_num=zipfile;
+ if (zipfile_to_tile(f, cd, &t))
+ push_tile(mr, &t);
+ file_data_free(f, (unsigned char *)cd);
+}
+
+static struct map_rect_priv *
+map_rect_new_binfile(struct map_priv *map, struct map_selection *sel)
+{
+ struct map_rect_priv *mr;
+ struct tile t;
+
+ dbg(1,"map_rect_new_binfile\n");
+ mr=g_new0(struct map_rect_priv, 1);
+ mr->m=map;
+ mr->sel=sel;
+ mr->item.id_hi=0;
+ mr->item.id_lo=0;
+ dbg(1,"zip_members=%d\n", map->zip_members);
+ if (map->eoc)
+ push_zipfile_tile(mr, map->zip_members-1);
+ else {
+ unsigned char *d=file_data_read(map->fi, 0, map->fi->size);
+ t.start=(int *)d;
+ t.end=(int *)(d+map->fi->size);
+ t.zipfile_num=0;
+ push_tile(mr, &t);
+ }
+ mr->item.meth=&methods_binfile;
+ mr->item.priv_data=mr;
+ return mr;
+}
+
+
+static void
+map_rect_destroy_binfile(struct map_rect_priv *mr)
+{
+ while (pop_tile(mr));
+ file_data_free(mr->m->fi, (unsigned char *)(mr->tiles[0].start));
+ g_free(mr);
+}
+
+static void
+setup_pos(struct map_rect_priv *mr)
+{
+ int size,coord_size;
+ struct tile *t=mr->t;
+ size=le32_to_cpu(*(t->pos++));
+ if (size > 1024*1024 || size < 0) {
+ fprintf(stderr,"size=0x%x\n", size);
+#if 0
+ fprintf(stderr,"offset=%d\n", (unsigned char *)(mr->pos)-mr->m->f->begin);
+#endif
+ g_error("size error");
+ }
+ t->pos_next=t->pos+size;
+ mr->item.type=le32_to_cpu(*(t->pos++));
+ coord_size=le32_to_cpu(*(t->pos++));
+ t->pos_coord_start=t->pos_coord=t->pos;
+ t->pos_attr_start=t->pos_attr=t->pos_coord+coord_size;
+}
+
+static int
+selection_contains(struct map_selection *sel, struct coord_rect *r, struct minmax *mima)
+{
+ int order;
+ if (! sel)
+ return 1;
+ while (sel) {
+ if (coord_rect_overlap(r, &sel->u.c_rect)) {
+ order=sel->order[0];
+ if (sel->order[1] > order)
+ order=sel->order[1];
+ if (sel->order[2] > order)
+ order=sel->order[2];
+ dbg(1,"min %d max %d order %d\n", mima->min, mima->max, order);
+ if (!mima->min && !mima->max)
+ return 1;
+ if (order >= mima->min && order <= mima->max)
+ return 1;
+ }
+ sel=sel->next;
+ }
+ return 0;
+}
+
+static void
+map_parse_country_binfile(struct map_rect_priv *mr)
+{
+ struct attr at;
+ if (binfile_attr_get(mr->item.priv_data, attr_country_id, &at)) {
+ if (at.u.num == mr->country_id)
+ {
+ if (binfile_attr_get(mr->item.priv_data, attr_zipfile_ref, &at))
+ {
+ push_zipfile_tile(mr, at.u.num);
+ }
+ }
+ }
+}
+
+static struct item *
+map_rect_get_item_binfile(struct map_rect_priv *mr)
+{
+ struct tile *t;
+ struct minmax *mima;
+ for (;;) {
+ t=mr->t;
+ if (! t)
+ return NULL;
+ t->pos=t->pos_next;
+ if (t->pos >= t->end) {
+ if (pop_tile(mr))
+ continue;
+ return NULL;
+ }
+ mr->item.id_hi=t->zipfile_num;
+ mr->item.id_lo=t->pos-t->start;
+ mr->label=0;
+ memset(mr->label_attr, 0, sizeof(mr->label_attr));
+ setup_pos(mr);
+ if ((mr->item.type == type_submap) && (!mr->country_id)) {
+ struct coord_rect r;
+ r.lu.x=le32_to_cpu(t->pos_coord[0]);
+ r.lu.y=le32_to_cpu(t->pos_coord[3]);
+ r.rl.x=le32_to_cpu(t->pos_coord[2]);
+ r.rl.y=le32_to_cpu(t->pos_coord[1]);
+ mima=(struct minmax *)(t->pos_attr+2);
+ minmax_to_cpu(mima);
+ if (!mr->m->eoc || !selection_contains(mr->sel, &r, mima)) {
+ continue;
+ }
+ dbg(1,"pushing zipfile %d from %d\n", le32_to_cpu(t->pos_attr[5]), t->zipfile_num);
+ push_zipfile_tile(mr, le32_to_cpu(t->pos_attr[5]));
+ continue;
+
+ }
+ if (mr->country_id)
+ {
+ if (mr->item.type == type_countryindex) {
+ map_parse_country_binfile(mr);
+ }
+ if (mr->item.type >= type_town_label && mr->item.type <= type_district_label_1e7)
+ {
+ return &mr->item;
+ } else {
+ continue;
+ }
+ }
+ return &mr->item;
+ }
+}
+
+static struct item *
+map_rect_get_item_byid_binfile(struct map_rect_priv *mr, int id_hi, int id_lo)
+{
+ struct tile *t;
+ if (mr->m->eoc)
+ push_zipfile_tile(mr, id_hi);
+ t=mr->t;
+ t->pos=t->start+id_lo;
+ mr->item.id_hi=id_hi;
+ mr->item.id_lo=id_lo;
+ mr->label=0;
+ memset(mr->label_attr, 0, sizeof(mr->label_attr));
+ setup_pos(mr);
+ return &mr->item;
+}
+
+static struct map_search_priv *
+binmap_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial)
+{
+ struct map_rect_priv *map_rec;
+ struct map_search_priv *msp;
+ struct map_selection *ms;
+ struct item *town;
+ int i;
+
+ switch (search->type) {
+ case attr_country_name:
+ break;
+ case attr_town_name:
+ msp = g_new(struct map_search_priv, 1);
+ msp->search_results = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+ map_rec = map_rect_new_binfile(map, NULL);
+ map_rec->country_id = item->id_lo;
+ msp->mr = map_rec;
+ msp->search = search;
+ msp->partial = partial;
+ return msp;
+ break;
+ case attr_town_postal:
+ break;
+ case attr_street_name:
+ ms = g_new(struct map_selection, 1);
+ ms->next = NULL;
+ for (i = 0; i < layer_end; i++)
+ {
+ ms->order[i] = 18;
+ }
+ map_rec = map_rect_new_binfile(map, ms);
+ town = map_rect_get_item_byid_binfile(map_rec, item->id_hi, item->id_lo);
+ if (town) {
+ struct map_search_priv *msp = g_new(struct map_search_priv, 1);
+ struct coord *c = g_new(struct coord, 1);
+ int size = 10000;
+ switch (town->type) {
+ case type_town_label_2e5:
+ size = 10000;
+ break;
+ case type_town_label_2e4:
+ size = 2500;
+ break;
+ case type_town_label_2e3:
+ size = 1000;
+ break;
+ case type_town_label_2e2:
+ size = 1000;
+ break;
+ default:
+ break;
+ }
+ item_coord_get(town, c, 1);
+ ms->u.c_rect.lu.x = c->x-size;
+ ms->u.c_rect.lu.y = c->y+size;
+ ms->u.c_rect.rl.x = c->x+size;
+ ms->u.c_rect.rl.y = c->y-size;
+
+ map_rect_destroy_binfile(map_rec);
+ map_rec = map_rect_new_binfile(map, ms);
+ msp->mr = map_rec;
+ msp->search = search;
+ msp->partial = partial;
+ msp->search_results = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+ return msp;
+ }
+ map_rect_destroy_binfile(map_rec);
+ g_free(ms);
+ break;
+ default:
+ break;
+ }
+ return NULL;
+}
+static int
+ascii_cmp(char *name, char *match, int partial)
+{
+ if (partial)
+ return g_ascii_strncasecmp(name, match, strlen(match));
+ else
+ return g_ascii_strcasecmp(name, match);
+}
+
+static struct item *
+binmap_search_get_item(struct map_search_priv *map_search)
+{
+ struct item* it;
+ while ((it = map_rect_get_item_binfile(map_search->mr))) {
+ if (map_search->search->type == attr_town_name) {
+ if ((it->type >= type_town_label) && (it->type <= type_town_label_1e7)) {
+ struct attr at;
+ if (binfile_attr_get(it->priv_data, attr_label, &at)) {
+ if (!ascii_cmp(at.u.str, map_search->search->u.str, map_search->partial)) {
+ return it;
+ }
+ }
+ }
+ } else if (map_search->search->type == attr_street_name) {
+ if ((it->type == type_street_3_city) || (it->type == type_street_2_city) || (it->type == type_street_1_city)) {
+ struct attr at;
+ if (binfile_attr_get(it->priv_data, attr_label, &at)) {
+ if (!ascii_cmp(at.u.str, map_search->search->u.str, map_search->partial)) {
+ if (!g_hash_table_lookup(map_search->search_results, at.u.str)) {
+ g_hash_table_insert(map_search->search_results, g_strdup(at.u.str), "");
+ return it;
+ }
+ }
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+static void
+binmap_search_destroy(struct map_search_priv *ms)
+{
+ g_hash_table_destroy(ms->search_results);
+ g_free(ms->mr->sel);
+ map_rect_destroy_binfile(ms->mr);
+ g_free(ms);
+}
+
+static struct map_methods map_methods_binfile = {
+ projection_mg,
+ "utf-8",
+ map_destroy_binfile,
+ map_rect_new_binfile,
+ map_rect_destroy_binfile,
+ map_rect_get_item_binfile,
+ map_rect_get_item_byid_binfile,
+ binmap_search_new,
+ binmap_search_destroy,
+ binmap_search_get_item
+};
+
+static struct map_priv *
+map_new_binfile(struct map_methods *meth, struct attr **attrs)
+{
+ struct map_priv *m;
+ struct attr *data=attr_search(attrs, NULL, attr_data);
+ struct file_wordexp *wexp;
+ struct zip_cd *first_cd;
+ char **wexp_data;
+ int *magic,cde_index_size;
+ if (! data)
+ return NULL;
+
+ wexp=file_wordexp_new(data->u.str);
+ wexp_data=file_wordexp_get_array(wexp);
+ dbg(1,"map_new_binfile %s\n", data->u.str);
+ *meth=map_methods_binfile;
+
+ m=g_new0(struct map_priv, 1);
+ m->id=++map_id;
+ m->filename=g_strdup(wexp_data[0]);
+ dbg(0,"file_create %s\n", m->filename);
+ m->fi=file_create(m->filename);
+ if (! m->fi) {
+ dbg(0,"Failed to load %s\n", m->filename);
+ g_free(m);
+ return NULL;
+ }
+ file_wordexp_destroy(wexp);
+ magic=(int *)file_data_read(m->fi, 0, 4);
+ *magic = le32_to_cpu(*magic);
+ if (*magic == 0x04034b50) {
+ cde_index_size=sizeof(struct zip_cd)+sizeof("index")-1;
+ m->eoc=(struct zip_eoc *)file_data_read(m->fi,m->fi->size-sizeof(struct zip_eoc), sizeof(struct zip_eoc));
+ eoc_to_cpu(m->eoc);
+ printf("magic 0x%x\n", m->eoc->zipesig);
+ m->index_cd=(struct zip_cd *)file_data_read(m->fi,m->fi->size-sizeof(struct zip_eoc)-cde_index_size, cde_index_size);
+ cd_to_cpu(m->index_cd);
+ first_cd=(struct zip_cd *)file_data_read(m->fi,m->eoc->zipeofst, sizeof(struct zip_cd));
+ cd_to_cpu(first_cd);
+ m->cde_size=sizeof(struct zip_cd)+first_cd->zipcfnl;
+ m->zip_members=(m->eoc->zipecsz-cde_index_size)/m->cde_size+1;
+ printf("cde_size %d\n", m->cde_size);
+ printf("members %d\n",m->zip_members);
+ printf("0x%x\n", m->eoc->zipesig);
+ printf("0x%x\n", m->index_cd->zipcensig);
+ file_data_free(m->fi, (unsigned char *)first_cd);
+ } else
+ file_mmap(m->fi);
+ file_data_free(m->fi, (unsigned char *)magic);
+ return m;
+}
+
+void
+plugin_init(void)
+{
+ dbg(1,"binfile: plugin_init\n");
+ plugin_register_map_type("binfile", map_new_binfile);
+}
+
diff --git a/navit/data/garmin/Makefile.am b/navit/data/garmin/Makefile.am
new file mode 100644
index 000000000..800e6dfd7
--- /dev/null
+++ b/navit/data/garmin/Makefile.am
@@ -0,0 +1,25 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=data_garmin
+AM_CPPFLAGS+= @LIBGARMIN_CFLAGS@
+INCLUDES=-I$(top_srcdir)/src/data/garmin/libgarmin
+AM_CPPFLAGS+=-I$(top_srcdir)/src/data/garmin/libgarmin
+AM_CPPFLAGS+=-I$(srcdir)
+
+moduledata_LTLIBRARIES = libdata_garmin.la
+libdata_garmin_la_SOURCES = garmin.c garmin.h gar2navit.c gar2navit.h
+libdata_garmin_la_LIBADD = @LIBGARMIN_LIBS@
+nodist_libdata_garmin_la_SOURCES = g2nbuiltin.h
+builddir = @builddir@
+
+gar2navit.l$(OBJEXT): g2nbuiltin.h
+
+CLEANFILES = g2nbuiltin.h
+
+noinst_PROGRAMS=gentypes
+gentypes_SOURCES=gentypes.c
+
+g2nbuiltin.h: gentypes garmintypes.txt
+ ./gentypes garmintypes.txt $@
+
+EXTRA_DIST = garmintypes.txt
+
diff --git a/navit/data/garmin/gar2navit.c b/navit/data/garmin/gar2navit.c
new file mode 100644
index 000000000..687217d24
--- /dev/null
+++ b/navit/data/garmin/gar2navit.c
@@ -0,0 +1,291 @@
+/*
+ Copyright (C) 2007 Alexander Atanasov <aatanasov@gmail.com>
+
+ 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; version 2 of the License.
+
+ 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
+
+ Garmin and MapSource are registered trademarks or trademarks
+ of Garmin Ltd. or one of its subsidiaries.
+
+*/
+
+/*
+ Street's are routable by:
+ ALL - by all
+ W pedestrian (1<<0)
+ B bycycle (1<<1)
+ M motorcycle (1<<2)
+ C car (1<<3)
+ T truck (1<<4)
+ L largetruck (1<<5)
+File format is:
+
+POINT
+0x0100 = town_label_1e5, Megapolis (10M +)
+0x0200 = town_label_5e4, Megapolis (5-10M)
+...
+0x1e00-0x1e3f = district_label, District, Province, State Name
+...
+POLYLINE
+0x00 = ALL, street_1_land, Road
+0x01 = MCTL, highway_land, Major HWY thick
+0x02 = MCTL, street_4_land, Principal HWY-thick
+0x03 = MCTL, street_2_land, Principal HWY-medium
+....
+POLYGONE
+0x01 = town_poly, City (>200k)
+0x02 = town_poly, City (<200k)
+0x03 = town_poly, Village
+
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include "item.h"
+#include "attr.h"
+#include "garmin.h"
+#include "gar2navit.h"
+
+static int add_def(struct gar2nav_conv *conv, int type, unsigned short minid,
+ unsigned short maxid, unsigned int routable, char *ntype,
+ char *descr)
+{
+ enum item_type it;
+ struct gar2navit *g2n;
+ dlog(11, "type=%d routable=%u min=%04X max=%04X ntype=%s descr=%s\n",
+ type, routable, minid, maxid, ntype, descr);
+ it = item_from_name(ntype);
+ if (it==type_none) {
+ dlog(1, "Please define: %s\n", ntype);
+ }
+ g2n = calloc(1, sizeof(*g2n));
+ if (!g2n)
+ return -1;
+ g2n->id = minid;
+ g2n->maxid = maxid;
+ g2n->ntype = it;
+ g2n->descr = strdup(descr);
+ g2n->routable = routable;
+ if (type == 1) {
+ g2n->next = conv->points;
+ conv->points = g2n;
+ } else if (type == 2) {
+ g2n->next = conv->polylines;
+ conv->polylines = g2n;
+ } else if (type == 3) {
+ g2n->next = conv->polygons;
+ conv->polygons = g2n;
+ }
+ return 0;
+}
+
+static unsigned int get_rtmask(char *p)
+{
+ char *cp;
+ unsigned int mask = 0;
+ cp = p;
+ while (*cp) {
+ if (!strcasecmp(cp, "none"))
+ return 0;
+ if (!strcasecmp(cp, "all")) {
+ mask = ~0;
+ break;
+ } if (*cp == 'W')
+ mask |= RT_PEDESTRIAN;
+ else if (*cp == 'B')
+ mask |= RT_BYCYCLE;
+ else if (*cp == 'M')
+ mask |= RT_MOTORCYCLE;
+ else if (*cp == 'C')
+ mask |= RT_CAR;
+ else if (*cp == 'T')
+ mask |= RT_TRUCK;
+ else if (*cp == 'L')
+ mask |= RT_LONGTRUCK;
+ cp++;
+ }
+ return mask;
+}
+
+static int load_types_file(char *file, struct gar2nav_conv *conv)
+{
+ char buf[4096];
+ char descr[4096];
+ char ntype[4096];
+ char rtby[4096];
+ FILE *fp;
+ unsigned int minid, maxid, routable;
+ int rc;
+ int type = -1;
+
+ fp = fopen(file, "r");
+ if (!fp)
+ return -1;
+ while (fgets(buf, sizeof(buf), fp)) {
+ if (*buf == '#' || *buf == '\n')
+ continue;
+ routable = 0;
+ if (!strncasecmp(buf, "POINT", 5)) {
+ type = 1;
+ continue;
+ } else if (!strncasecmp(buf, "POI", 3)) {
+ type = 1;
+ continue;
+ } else if (!strncasecmp(buf, "POLYLINE", 8)) {
+ type = 2;
+ continue;
+ } else if (!strncasecmp(buf, "POLYGONE", 8)) {
+ type = 3;
+ continue;
+ }
+ // assume only lines are routable
+ if (type == 2) {
+ rc = sscanf(buf, "0x%04X = %[^\t, ] , %[^\t, ], %[^\n]",
+ &minid, rtby, ntype, descr);
+ if (rc != 4) {
+ dlog(1, "Invalid line rc=%d:[%s]\n",rc, buf);
+ dlog(1, "minid=%04X ntype=[%s] des=[%s]\n",
+ minid, ntype, descr);
+ continue;
+ }
+ routable = get_rtmask(rtby);
+ } else {
+ rc = sscanf(buf, "0x%04X - 0x%04X = %[^\t , ] , %[^\n]",
+ &minid, &maxid, ntype, descr);
+ if (rc != 4) {
+ maxid = 0;
+ rc = sscanf(buf, "0x%04X = %[^\t, ], %[^\n]",
+ &minid, ntype, descr);
+ if (rc != 3) {
+ dlog(1, "Invalid line rc=%d:[%s]\n",rc, buf);
+ dlog(1, "minid=%04X ntype=[%s] des=[%s]\n",
+ minid, ntype, descr);
+ continue;
+ }
+ }
+ }
+ add_def(conv, type, minid, maxid, routable, ntype, descr);
+ }
+ fclose(fp);
+ return 1;
+}
+
+struct gar2nav_conv *g2n_conv_load(char *file)
+{
+ struct gar2nav_conv *c;
+ int rc;
+
+ c = calloc(1, sizeof(*c));
+ if (!c)
+ return c;
+ rc = load_types_file(file, c);
+ if (rc < 0) {
+ dlog(1, "Failed to load: [%s]\n", file);
+ free(c);
+ return NULL;
+ }
+ return c;
+}
+
+enum item_type g2n_get_type(struct gar2nav_conv *c, int type, unsigned short id)
+{
+ struct gar2navit *def = NULL;
+ if (type == G2N_POINT)
+ def = c->points;
+ else if (type == G2N_POLYLINE)
+ def = c->polylines;
+ else if (type == G2N_POLYGONE)
+ def = c->polygons;
+ else {
+ dlog(1, "Unknown conversion type:%d\n", type);
+ return type_none;
+ }
+
+ if (!def) {
+ dlog(5, "No conversion data for %d\n", type);
+ return type_none;
+ }
+
+ while (def) {
+ if ((!def->maxid && def->id == id) ||
+ (def->id <= id && id <= def->maxid))
+ return def->ntype;
+ def = def->next;
+ }
+ dlog(5, "Type[%d]:ID:[%04X] unknown\n", type, id);
+ return type_none;
+}
+
+int g2n_get_routable(struct gar2nav_conv *c, int type, unsigned short id)
+{
+ struct gar2navit *def = NULL;
+ if (type == G2N_POINT)
+ def = c->points;
+ else if (type == G2N_POLYLINE)
+ def = c->polylines;
+ else if (type == G2N_POLYGONE)
+ def = c->polygons;
+ else {
+ dlog(1, "Unknown conversion type:%d\n", type);
+ return type_none;
+ }
+
+ if (!def) {
+ dlog(5, "No conversion data for %d\n", type);
+ return type_none;
+ }
+
+ while (def) {
+ if ((!def->maxid && def->id == id) ||
+ (def->id <= id && id <= def->maxid))
+ return def->routable;
+ def = def->next;
+ }
+ dlog(5, "Type[%d]:ID:[%04X] unknown\n", type, id);
+ return 0;
+}
+
+char *g2n_get_descr(struct gar2nav_conv *c, int type, unsigned short id)
+{
+ struct gar2navit *def = NULL;
+ if (type == G2N_POINT)
+ def = c->points;
+ else if (type == G2N_POLYLINE)
+ def = c->polylines;
+ else if (type == G2N_POLYGONE)
+ def = c->polygons;
+ else {
+ dlog(1, "Unknown conversion type:%d\n", type);
+ return NULL;
+ }
+ while (def) {
+ if ((!def->maxid && def->id == id) ||
+ (def->id <= id && id <= def->maxid))
+ return def->descr;
+ def = def->next;
+ }
+ dlog(5, "Type[%d]:ID:[%04X] unknown\n", type, id);
+ return NULL;
+}
+
+#if 0
+int main(int argc, char **argv)
+{
+ load_types_file(argv[1], NULL);
+ return 0;
+}
+#endif
+
+#include "g2nbuiltin.h"
diff --git a/navit/data/garmin/gar2navit.h b/navit/data/garmin/gar2navit.h
new file mode 100644
index 000000000..de68298ad
--- /dev/null
+++ b/navit/data/garmin/gar2navit.h
@@ -0,0 +1,31 @@
+#define RT_PEDESTRIAN (1<<0)
+#define RT_BYCYCLE (1<<1)
+#define RT_MOTORCYCLE (1<<2)
+#define RT_CAR (1<<3)
+#define RT_TRUCK (1<<4)
+#define RT_LONGTRUCK (1<<5)
+
+struct gar2navit {
+ unsigned short id;
+ unsigned short maxid;
+ enum item_type ntype;
+ int routable;
+ char *descr;
+ struct gar2navit *next;
+};
+
+#define G2N_POINT 1
+#define G2N_POLYLINE 2
+#define G2N_POLYGONE 3
+
+struct gar2nav_conv {
+ struct gar2navit *points;
+ struct gar2navit *polylines;
+ struct gar2navit *polygons;
+};
+
+struct gar2nav_conv *g2n_conv_load(char *file);
+enum item_type g2n_get_type(struct gar2nav_conv *c, int type, unsigned short id);
+char *g2n_get_descr(struct gar2nav_conv *c, int type, unsigned short id);
+int g2n_get_routable(struct gar2nav_conv *c, int type, unsigned short id);
+struct gar2nav_conv *g2n_default_conv(void);
diff --git a/navit/data/garmin/garmin.c b/navit/data/garmin/garmin.c
new file mode 100644
index 000000000..d6d39d490
--- /dev/null
+++ b/navit/data/garmin/garmin.c
@@ -0,0 +1,794 @@
+/*
+ Copyright (C) 2007 Alexander Atanasov <aatanasov@gmail.com>
+
+ 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; version 2 of the License.
+
+ 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
+
+ Garmin and MapSource are registered trademarks or trademarks
+ of Garmin Ltd. or one of its subsidiaries.
+
+*/
+
+#include <glib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include "config.h"
+#include "plugin.h"
+#include "data.h"
+#include "projection.h"
+#include "map.h"
+#include "maptype.h"
+#include "item.h"
+#include "attr.h"
+#include "coord.h"
+#include "transform.h"
+#include <stdio.h>
+#include "attr.h"
+#include "coord.h"
+#include <libgarmin.h>
+#include "garmin.h"
+#include "gar2navit.h"
+
+
+static int map_id;
+
+struct map_priv {
+ int id;
+ char *filename;
+ struct gar2nav_conv *conv;
+ struct gar *g;
+};
+
+struct map_rect_priv {
+ int id;
+ struct coord_rect r;
+ char *label; // FIXME: Register all strings for searches
+ int limit;
+ struct map_priv *mpriv;
+ struct gmap *gmap;
+ struct gobject *cobj;
+ struct gobject *objs;
+ struct item item;
+ unsigned int last_coord;
+ void *last_itterated;
+ struct coord last_c;
+ void *last_oattr;
+ unsigned int last_attr;
+ struct gar_search *search;
+};
+
+int garmin_debug = 10;
+
+void
+logfn(char *file, int line, int level, char *fmt, ...)
+{
+ va_list ap;
+ if (level > garmin_debug)
+ return;
+ va_start(ap, fmt);
+ fprintf(stdout, "%s:%d:%d|", file, line, level);
+ vfprintf(stdout, fmt, ap);
+ va_end(ap);
+}
+// need a base map and a map
+struct gscale {
+ char *label;
+ float scale;
+ int bits;
+};
+
+static struct gscale mapscales[] = {
+ {"7000 km", 70000.0, 8}
+ ,{"5000 km", 50000.0, 8}
+ ,{"3000 km", 30000.0, 9}
+ ,{"2000 km", 20000.0, 9}
+ ,{"1500 km", 15000.0, 10}
+ ,{"1000 km", 10000.0, 10}
+ ,{"700 km", 7000.0, 11}
+ ,{"500 km", 5000.0, 11}
+ ,{"300 km", 3000.0, 13}
+ ,{"200 km", 2000.0, 13}
+ ,{"150 km", 1500.0, 13}
+ ,{"100 km", 1000.0, 14}
+ ,{"70 km", 700.0, 15}
+ ,{"50 km", 500.0, 16}
+ ,{"30 km", 300.0, 16}
+ ,{"20 km", 200.0, 17}
+ ,{"15 km", 150.0, 17}
+ ,{"10 km", 100.0, 18}
+ ,{"7 km", 70.0, 18}
+ ,{"5 km", 50.0, 19}
+ ,{"3 km", 30.0, 19}
+ ,{"2 km", 20.0, 20}
+ ,{"1.5 km", 15.0, 22}
+ ,{"1 km", 10.0, 24}
+ ,{"700 m", 7.0, 24}
+ ,{"500 m", 5.0, 24}
+ ,{"300 m", 3.0, 24}
+ ,{"200 m", 2.0, 24}
+ ,{"150 m", 1.5, 24}
+ ,{"100 m", 1.0, 24}
+ ,{"70 m", 0.7, 24}
+ ,{"50 m", 0.5, 24}
+ ,{"30 m", 0.3, 24}
+ ,{"20 m", 0.2, 24}
+ ,{"15 m", 0.1, 24}
+ ,{"10 m", 0.15, 24}
+};
+
+
+static int
+garmin_object_label(struct gobject *o, struct attr *attr)
+{
+ struct map_rect_priv *mr = o->priv_data;
+ if (!mr) {
+ dlog(1, "Error object do not have priv_data!!\n");
+ return 0;
+ }
+ if (mr->label)
+ free(mr->label);
+ mr->label = gar_get_object_lbl(o);
+#warning FIXME Process label and give only the visible part
+ if (mr->label) {
+ char *cp = mr->label;
+ if (*mr->label == '@' || *mr->label == '^')
+ cp++;
+ /* FIXME: If zoomlevel is high convert ^ in the string to spaces */
+ attr->u.str = cp;
+ return 1;
+ }
+ return 0;
+}
+
+static int
+garmin_object_debug(struct gobject *o, struct attr *attr)
+{
+ struct map_rect_priv *mr = o->priv_data;
+ if (!mr) {
+ dlog(1, "Error object do not have priv_data!!\n");
+ return 0;
+ }
+ if (mr->label)
+ free(mr->label);
+ mr->label = gar_object_debug_str(o);
+ if (mr->label) {
+ attr->u.str = mr->label;
+ return 1;
+ }
+ return 0;
+}
+
+
+static struct map_search_priv *
+gmap_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial)
+{
+ struct map_rect_priv *mr=g_new0(struct map_rect_priv, 1);
+ struct gar_search *gs;
+ int rc;
+
+ dlog(1, "Called!\n");
+ mr->mpriv=map;
+ gs = g_new0(struct gar_search,1);
+ if (!gs) {
+ dlog(1, "Can not init search \n");
+ free(mr);
+ return NULL;
+ }
+ mr->search = gs;
+ switch (search->type) {
+ case attr_country_name:
+ gs->type = GS_COUNTRY;
+ break;
+ case attr_town_name:
+ gs->type = GS_CITY;
+ break;
+ case attr_town_postal:
+ gs->type = GS_ZIP;
+ break;
+ case attr_street_name:
+ gs->type = GS_ROAD;
+ break;
+#if someday
+ case attr_region_name:
+ case attr_intersection:
+ case attr_housenumber:
+#endif
+ default:
+ dlog(1, "Don't know how to search for %d\n", search->type);
+ goto out_err;
+ }
+ gs->match = partial ? GM_START : GM_EXACT;
+ gs->needle = strdup(search->u.str);
+ dlog(5, "Needle: %s\n", gs->needle);
+
+ mr->gmap = gar_find_subfiles(mr->mpriv->g, gs, GO_GET_SEARCH);
+ if (!mr->gmap) {
+ dlog(1, "Can not init search \n");
+ goto out_err;
+ }
+ rc = gar_get_objects(mr->gmap, 0, gs, &mr->objs, GO_GET_SEARCH);
+ if (rc < 0) {
+ dlog(1, "Error loading objects\n");
+ goto out_err;
+ }
+ mr->cobj = mr->objs;
+ dlog(4, "Loaded %d objects\n", rc);
+ return (struct map_search_priv *)mr;
+
+out_err:
+ free(gs);
+ free(mr);
+ return NULL;
+}
+
+/* Assumes that only one item will be itterated at time! */
+static void
+coord_rewind(void *priv_data)
+{
+ struct gobject *g = priv_data;
+ struct map_rect_priv *mr = g->priv_data;
+ mr->last_coord = 0;
+};
+
+static void
+attr_rewind(void *priv_data)
+{
+ struct gobject *g = priv_data;
+ struct map_rect_priv *mr = g->priv_data;
+ mr->last_attr = 0;
+};
+
+static int
+point_coord_get(void *priv_data, struct coord *c, int count)
+{
+ struct gobject *g = priv_data;
+ struct map_rect_priv *mr = g->priv_data;
+ struct gcoord gc;
+ if (!count)
+ return 0;
+ if (g != mr->last_itterated) {
+ mr->last_itterated = g;
+ mr->last_coord = 0;
+ }
+
+ if (mr->last_coord > 0)
+ return 0;
+
+ gar_get_object_coord(mr->gmap, g, &gc);
+ c->x = gc.x;
+ c->y = gc.y;
+ mr->last_coord++;
+// dlog(1,"point: x=%d y=%d\n", c->x, c->y);
+ // dlog(1, "point: x=%f y=%f\n", GARDEG(c->x), GARDEG(c->y));
+ return 1;
+}
+
+static int
+coord_is_segment(void *priv_data)
+{
+ struct gobject *g = priv_data;
+ struct map_rect_priv *mr = g->priv_data;
+
+ if (mr->last_coord == 0)
+ return 0;
+ return gar_is_object_dcoord_node(mr->gmap, g, mr->last_coord - 1);
+}
+
+static int
+poly_coord_get(void *priv_data, struct coord *c, int count)
+{
+ struct gobject *g = priv_data;
+ struct map_rect_priv *mr = g->priv_data;
+ int ndeltas = 0, total = 0;
+ struct gcoord dc;
+
+ if (!count)
+ return 0;
+
+ if (g != mr->last_itterated) {
+ mr->last_itterated = g;
+ mr->last_coord = 0;
+ }
+ ndeltas = gar_get_object_deltas(g);
+ if (mr->last_coord > ndeltas + 1)
+ return 0;
+ while (count --) {
+ if (mr->last_coord == 0) {
+ gar_get_object_coord(mr->gmap, g, &dc);
+ mr->last_c.x = dc.x;
+ mr->last_c.y = dc.y;
+ } else {
+ if (!gar_get_object_dcoord(mr->gmap, g, mr->last_coord - 1, &dc)) {
+ mr->last_coord = ndeltas + 2;
+ return total;
+ }
+ mr->last_c.x += dc.x;
+ mr->last_c.y += dc.y;
+ }
+ c->x = mr->last_c.x;
+ c->y = mr->last_c.y;
+ ddlog(1, "poly: x=%f y=%f\n", GARDEG(c->x), GARDEG(c->y));
+// dlog(1,"poly: x=%d y=%d\n", c->x, c->y);
+ c++;
+ total++;
+ mr->last_coord ++;
+ }
+ return total;
+}
+
+// for _any we must return one by one
+static int
+point_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+ struct gobject *g = priv_data;
+ struct map_rect_priv *mr = g->priv_data;
+ int rc;
+ switch (attr_type) {
+ case attr_any:
+ if (g != mr->last_oattr) {
+ mr->last_oattr = g;
+ mr->last_attr = 0;
+ }
+ switch(mr->last_attr) {
+ case 0:
+ mr->last_attr++;
+ attr->type = attr_label;
+ rc = garmin_object_label(g, attr);
+ if (rc)
+ return rc;
+ case 1:
+ mr->last_attr++;
+ attr->type = attr_debug;
+ rc = garmin_object_debug(g, attr);
+ if (rc)
+ return rc;
+ case 2:
+ mr->last_attr++;
+ if (g->type == GO_POLYLINE) {
+ attr->type = attr_street_name;
+ rc = garmin_object_label(g, attr);
+ if (rc)
+ return rc;
+ }
+ case 3:
+ mr->last_attr++;
+ attr->type = attr_flags;
+ attr->u.num = 0;
+ rc = gar_object_flags(g);
+ if (rc & F_ONEWAY)
+ attr->u.num |= AF_ONEWAY;
+ if (rc & F_SEGMENTED)
+ attr->u.num |= AF_SEGMENTED;
+ return 1;
+ default:
+ return 0;
+ }
+ break;
+ case attr_label:
+ attr->type = attr_label;
+ return garmin_object_label(g, attr);
+ case attr_town_name:
+ attr->type = attr_town_name;
+ return garmin_object_label(g, attr);
+ case attr_street_name:
+ attr->type = attr_street_name;
+ return garmin_object_label(g, attr);
+ case attr_flags:
+ attr->type = attr_flags;
+ attr->u.num = 0;
+ rc = gar_object_flags(g);
+ if (rc & F_ONEWAY)
+ attr->u.num |= AF_ONEWAY;
+ if (rc & F_SEGMENTED)
+ attr->u.num |= AF_SEGMENTED;
+ return 1;
+ default:
+ dlog(1, "Dont know about attribute %d[%04X]=%s yet\n", attr_type,attr_type, attr_to_name(attr_type));
+ }
+
+ return 0;
+}
+
+static struct item_methods methods_garmin_point = {
+ coord_rewind,
+ point_coord_get,
+ attr_rewind,
+ point_attr_get,
+};
+
+static struct item_methods methods_garmin_poly = {
+ coord_rewind,
+ poly_coord_get,
+ attr_rewind, // point_attr_rewind,
+ point_attr_get, // poly_attr_get,
+ coord_is_segment,
+};
+
+static struct item *
+garmin_poi2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype)
+{
+ if (mr->mpriv->conv)
+ mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POINT, otype);
+ mr->item.meth = &methods_garmin_point;
+ return &mr->item;
+}
+
+static struct item *
+garmin_pl2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype)
+{
+ if (mr->mpriv->conv)
+ mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYLINE, otype);
+ mr->item.meth = &methods_garmin_poly;
+ return &mr->item;
+}
+
+static struct item *
+garmin_pg2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype)
+{
+ if (mr->mpriv->conv)
+ mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYGONE, otype);
+ mr->item.meth = &methods_garmin_poly;
+ return &mr->item;
+}
+
+static struct item *
+garmin_obj2item(struct map_rect_priv *mr, struct gobject *o)
+{
+ unsigned short otype;
+ otype = gar_obj_type(o);
+ mr->item.type = type_none;
+ switch (o->type) {
+ case GO_POINT:
+ return garmin_poi2item(mr, o, otype);
+ case GO_POLYLINE:
+ return garmin_pl2item(mr, o, otype);
+ case GO_POLYGON:
+ return garmin_pg2item(mr, o, otype);
+ case GO_ROAD:
+ return garmin_pl2item(mr, o, otype);
+ default:
+ dlog(1, "Unknown garmin object type:%d\n",
+ o->type);
+ }
+ return NULL;
+}
+
+static struct item *
+gmap_rect_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo)
+{
+ struct gobject *o;
+ o = mr->objs = gar_get_object_by_id(mr->mpriv->g, id_hi, id_lo);
+ if (!o) {
+ dlog(1, "Can not find object\n");
+ return NULL;
+ }
+
+ mr->item.id_hi = id_hi;
+ mr->item.id_lo = id_lo;
+ mr->item.priv_data = o;
+ mr->item.type = type_none;
+ o->priv_data = mr;
+ if (!garmin_obj2item(mr, o))
+ return NULL;
+ return &mr->item;
+}
+
+static struct item *
+gmap_rect_get_item(struct map_rect_priv *mr)
+{
+ struct gobject *o;
+ if (!mr->objs)
+ return NULL;
+ if (!mr->cobj)
+ return NULL;
+ // mr->cobj = mr->objs;
+ o = mr->cobj;
+// dlog(1, "gi:o=%p\n", o);
+ mr->cobj = mr->cobj->next;
+ if (o) {
+ mr->item.id_hi = gar_object_mapid(o);
+ mr->item.id_lo = gar_object_index(o);
+ mr->item.priv_data = o;
+ mr->item.type = type_none;
+ o->priv_data = mr;
+ if (!garmin_obj2item(mr, o))
+ return NULL;
+ return &mr->item;
+ }
+ return NULL;
+}
+
+#define max(a,b) ((a) > (b) ? (a) : (b))
+struct nl2gl_t {
+ int g;
+ int bits;
+ char *descr;
+};
+
+struct nl2gl_t nl2gl_1[] = {
+ { /* 0 */ .g = 12, .descr = "0-120m", },
+ { /* 1 */ .g = 11, .descr = "0-120m", },
+ { /* 2 */ .g = 10, .descr = "0-120m", },
+ { /* 3 */ .g = 9, .descr = "0-120m", },
+ { /* 4 */ .g = 8, .descr = "0-120m", },
+ { /* 5 */ .g = 7, .descr = "0-120m", },
+ { /* 6 */ .g = 6, .descr = "0-120m", },
+ { /* 7 */ .g = 5, .descr = "0-120m", },
+ { /* 8 */ .g = 4, .descr = "0-120m", },
+ { /* 9 */ .g = 4, .descr = "0-120m", },
+ { /* 10 */ .g = 3, .descr = "0-120m", },
+ { /* 11 */ .g = 3, .descr = "0-120m", },
+ { /* 12 */ .g = 2, .descr = "0-120m", },
+ { /* 13 */ .g = 2, .descr = "0-120m", },
+ { /* 14 */ .g = 2, .descr = "0-120m", },
+ { /* 15 */ .g = 1, .descr = "0-120m", },
+ { /* 16 */ .g = 1, .descr = "0-120m", },
+ { /* 17 */ .g = 1, .descr = "0-120m", },
+ { /* 18 */ .g = 0, .descr = "0-120m", },
+};
+
+struct nl2gl_t nl2gl[] = {
+ { /* 0 */ .g = 9, .descr = "0-120m", },
+ { /* 1 */ .g = 9, .descr = "0-120m", },
+ { /* 2 */ .g = 8, .descr = "0-120m", },
+ { /* 3 */ .g = 8, .descr = "0-120m", },
+ { /* 4 */ .g = 7, .descr = "0-120m", },
+ { /* 5 */ .g = 7, .descr = "0-120m", },
+ { /* 6 */ .g = 6, .descr = "0-120m", },
+ { /* 7 */ .g = 6, .descr = "0-120m", },
+ { /* 8 */ .g = 5, .descr = "0-120m", },
+ { /* 9 */ .g = 5, .descr = "0-120m", },
+ { /* 10 */ .g = 4, .descr = "0-120m", },
+ { /* 11 */ .g = 4, .descr = "0-120m", },
+ { /* 12 */ .g = 3, .descr = "0-120m", },
+ { /* 13 */ .g = 3, .descr = "0-120m", },
+ { /* 14 */ .g = 2, .descr = "0-120m", },
+ { /* 15 */ .g = 2, .descr = "0-120m", },
+ { /* 16 */ .g = 1, .descr = "0-120m", },
+ { /* 17 */ .g = 1, .descr = "0-120m", },
+ { /* 18 */ .g = 0, .descr = "0-120m", },
+};
+
+static int
+get_level(struct map_selection *sel)
+{
+ int l;
+ l = max(sel->order[layer_town], sel->order[layer_street]);
+ l = max(l, sel->order[layer_poly]);
+ return l;
+}
+
+static int
+garmin_get_selection(struct map_rect_priv *map, struct map_selection *sel)
+{
+ struct gar_rect r;
+ struct gmap *gm;
+ struct gobject **glast = NULL;
+ int rc;
+ int sl, el;
+ int level = 0; // 18; /* max level for maps, overview maps can have bigger
+ /* levels we do not deal w/ them
+ */
+ int flags = 0;
+ if (sel && sel->order[layer_town] == 0 && sel->order[layer_poly] == 0
+ && sel->order[layer_street]) {
+ // Get all roads
+ flags = GO_GET_ROUTABLE;
+ sel = NULL;
+ } else if (sel)
+ flags = GO_GET_SORTED;
+
+ if (sel) {
+ r.lulat = sel->u.c_rect.lu.y;
+ r.lulong = sel->u.c_rect.lu.x;
+ r.rllat = sel->u.c_rect.rl.y;
+ r.rllong = sel->u.c_rect.rl.x;
+ level = get_level(sel);
+// level = nl2gl[level].g;
+ dlog(2, "Looking level=%d for %f %f %f %f\n",
+ level, r.lulat, r.lulong, r.rllat, r.rllong);
+ }
+ gm = gar_find_subfiles(map->mpriv->g, sel ? &r : NULL, flags);
+ if (!gm) {
+ if (sel) {
+ dlog(1, "Can not find map data for the area: %f %f %f %f\n",
+ r.lulat, r.lulong, r.rllat, r.rllong);
+ } else {
+ dlog(1, "Can not find map data\n");
+ }
+ return -1;
+ }
+#if 0
+ sl = (18-(gm->maxlevel - gm->minlevel))/2;
+ el = sl + (gm->maxlevel - gm->minlevel);
+ if (level < sl)
+ level = sl;
+ if (level > el)
+ level = el;
+ level = level - sl;
+ level = (gm->maxlevel - gm->minlevel) - level;
+ dlog(3, "sl=%d el=%d level=%d\n", sl, el, level);
+#endif
+ sl = (18-gm->zoomlevels)/2;
+ el = sl + gm->zoomlevels;
+ if (level < sl)
+ level = sl;
+ if (level > el)
+ level = el;
+ level = level - sl;
+ level = gm->basebits + level;
+ dlog(3, "sl=%d el=%d level=%d\n", sl, el, level);
+ map->gmap = gm;
+ glast = &map->objs;
+ while (*glast) {
+ if ((*glast)->next) {
+ *glast = (*glast)->next;
+ } else
+ break;
+ }
+ rc = gar_get_objects(gm, level, sel ? &r : NULL, glast, flags);
+ if (rc < 0) {
+ dlog(1, "Error loading objects\n");
+ return -1;
+ }
+ map->cobj = map->objs;
+ dlog(2, "Loaded %d objects\n", rc);
+ return rc;
+}
+// Can not return NULL, navit segfaults
+static struct map_rect_priv *
+gmap_rect_new(struct map_priv *map, struct map_selection *sel)
+{
+ struct map_selection *ms = sel;
+ struct map_rect_priv *mr;
+
+ if (!map)
+ return NULL;
+ mr = calloc(1, sizeof(*mr));
+ if (!mr)
+ return mr;
+ mr->mpriv = map;
+ if (!sel) {
+ return mr;
+ } else {
+ while (ms) {
+ dlog(2, "order town:%d street=%d poly=%d\n",
+ ms->order[layer_town],
+ ms->order[layer_street],
+ ms->order[layer_poly]);
+ if (garmin_get_selection(mr, ms) < 0) {
+ // free(mr);
+ // return NULL;
+ }
+ ms = ms->next;
+ }
+ }
+ return mr;
+}
+
+static void
+gmap_rect_destroy(struct map_rect_priv *mr)
+{
+ dlog(11,"destroy maprect\n");
+ if (mr->gmap)
+ gar_free_gmap(mr->gmap);
+ if (mr->objs)
+ gar_free_objects(mr->objs);
+ if (mr->label)
+ free(mr->label);
+ free(mr);
+}
+
+static void
+gmap_search_destroy(struct map_search_priv *ms)
+{
+ gmap_rect_destroy((struct map_rect_priv *)ms);
+}
+
+static void
+gmap_destroy(struct map_priv *m)
+{
+ dlog(5, "garmin_map_destroy\n");
+ if (m->g)
+ gar_free(m->g);
+ if (m->filename)
+ free(m->filename);
+ free(m);
+}
+
+static struct map_methods map_methods = {
+ projection_garmin,
+// NULL, FIXME navit no longer displays labels without charset!
+ "iso8859-1", // update from the map
+ gmap_destroy, //
+ gmap_rect_new,
+ gmap_rect_destroy,
+ gmap_rect_get_item,
+ gmap_rect_get_item_byid,
+ gmap_search_new,
+ gmap_search_destroy,
+ gmap_rect_get_item,
+};
+
+static struct map_priv *
+gmap_new(struct map_methods *meth, struct attr **attrs)
+{
+ struct map_priv *m;
+ struct attr *data;
+ struct attr *debug;
+ char buf[PATH_MAX];
+ struct stat st;
+ int dl = 1;
+ struct gar_config cfg;
+
+ data=attr_search(attrs, NULL, attr_data);
+ if (! data)
+ return NULL;
+ debug=attr_search(attrs, NULL, attr_debug);
+ if (debug) {
+ dl = atoi(debug->u.str);
+ if (!dl)
+ dl = 1;
+ }
+ m=g_new(struct map_priv, 1);
+ m->id=++map_id;
+ m->filename = strdup(data->u.str);
+ if (!m->filename) {
+ g_free(m);
+ return NULL;
+ }
+ memset(&cfg, 0, sizeof(struct gar_config));
+ cfg.opm = OPM_GPS;
+ cfg.debuglevel = dl;
+ garmin_debug = dl;
+ m->g = gar_init_cfg(NULL, logfn, &cfg);
+ if (!m->g) {
+ g_free(m->filename);
+ g_free(m);
+ return NULL;
+ }
+ // we want the data now, later we can load only what's necessery
+ if (gar_img_load(m->g, m->filename, 1) < 0) {
+ gar_free(m->g);
+ g_free(m->filename);
+ g_free(m);
+ return NULL;
+ }
+ m->conv = NULL;
+ snprintf(buf, sizeof(buf), "%s.types", m->filename);
+ if (!stat(buf, &st)) {
+ dlog(1, "Loading custom types from %s\n", buf);
+ m->conv = g2n_conv_load(buf);
+ }
+ if (!m->conv) {
+ dlog(1, "Using builtin types\n");
+ m->conv = g2n_default_conv();
+ }
+ if (!m->conv) {
+ dlog(1, "Failed to load map types\n");
+ }
+ *meth=map_methods;
+ return m;
+}
+
+void
+plugin_init(void)
+{
+ plugin_register_map_type("garmin", gmap_new);
+}
diff --git a/navit/data/garmin/garmin.h b/navit/data/garmin/garmin.h
new file mode 100644
index 000000000..50935b052
--- /dev/null
+++ b/navit/data/garmin/garmin.h
@@ -0,0 +1,10 @@
+#define dlog(x,y ...) logfn(__FILE__,__LINE__,x, ##y)
+#ifdef HARDDEBUG
+#define ddlog(x,y ...) logfn(__FILE__,__LINE__,x, ##y)
+#else
+#define ddlog(x,y ...)
+#endif
+
+extern int garmin_debug;
+void logfn(char *file, int line, int level, char *fmt, ...);
+
diff --git a/navit/data/garmin/garmintypes.txt b/navit/data/garmin/garmintypes.txt
new file mode 100644
index 000000000..fd73d3724
--- /dev/null
+++ b/navit/data/garmin/garmintypes.txt
@@ -0,0 +1,412 @@
+#
+#
+#
+POINT
+0x0000 = label_unkn, Unknown label
+0x0100 = town_label_1e5, Megapolis (10M +)
+0x0200 = town_label_5e4, Megapolis (5-10M)
+0x0300 = town_label_2e4, Big City (2-5M)
+0x0400 = town_label_1e4, Big City (1-2M)
+0x0500 = town_label_5e3, Big City (0.5-1M)
+0x0600 = town_label_2e3, City (200-500k)
+0x0700 = town_label_1e3, City (100-200k)
+0x0800 = town_label_5e2, City (50-100k)
+0x0900 = town_label_2e2, City (20-50k)
+0x0a00 = town_label_1e2, City (10-20k)
+0x0b00 = town_label_5e1, Small City (5-10k)
+0x0c00 = town_label_2e1, Small City (2-5k)
+0x0d00 = town_label_1e1, Village (1-2k)
+0x0e00 = town_label_5e0, Village (500-1000)
+0x0f00 = town_label_2e0, Village (200-500)
+0x1000 = town_label_1e0, Village (100-200)
+0x1100 = town_label_0e0, Village (0-100)
+
+0x1200 = port_label, Port with services
+0x1300 = label_unkn, Unknown label2
+0x1400-0x14FF = country_label, Large Country Name
+0x1500-0x15FF = country_label, Country Name
+0x1c00 = poi_wreck, Unclassified Obstruction
+0x1c01 = poi_wreck, Wreck
+0x1c02 = poi_dangerous, submerged wreck, dangerous
+0x1c03 = poi_nondangerous, submerged wreck, non-dangerous
+0x1c04 = poi_wreck, Wreck, cleared by wire drag
+0x1c05 = poi_rock, Obstruction, visible at high water
+0x1c06 = poi_rock, Obstruction, awash
+0x1c07 = poi_rock, Obstruction, submerged
+0x1c08 = poi_rock, Obstruction, cleared by wire drag
+0x1c09 = poi_rock, Rock, awash
+0x1c0a = poi_rock, Rock, submerged at low Water
+0x1c0b = poi_sounding, Sounding
+0x1d00 = poi_tide, Tide Prediction
+
+0x1e00-0x1e3f = district_label, District, Province, State Name
+0x1f00 = district_label_0e0, Region, District Name
+
+# Fixme if it has label how to change to highway_exit_with_label ??
+0x2000-0x203F = highway_exit, Exit
+0x2100-0x213F = highway_exit, Exit with Services
+0x2200-0x223F = highway_exit, Exit with Restroom
+0x2300-0x233F = highway_exit, Exit with Convinience Store
+0x2400-0x243F = highway_exit, Exit with Weight Station
+0x2500-0x253F = highway_exit, Exit with Toolbooth Booth
+0x2600-0x263F = highway_exit, Exit with Information
+0x2700-0x273F = highway_exit, Exit
+
+0x2800-0x283F = district_label_1e0, Region Name
+
+0x2900 = poi_public_utilities, Services
+
+0x2A00 = poi_dining, Dining(Other)
+0x2A01 = poi_dining, Dining(American)
+0x2A02 = poi_dining, Dining(Asian)
+0x2A03 = poi_dining, Dining(Barbecue)
+0x2A04 = poi_dining, Dining(Chinese)
+0x2A05 = poi_dining, Dining(Deli/Bakery)
+0x2A06 = poi_dining, Dining(International)
+0x2A07 = poi_fastfood, Fast Food
+0x2A08 = poi_dining, Dining(Italian)
+0x2A09 = poi_dining, Dining(Mexican)
+0x2A0A = poi_dining, Dining(Pizza)
+0x2A0B = poi_dining, Dining(Sea Food)
+0x2A0C = poi_dining, Dining(Steak/Grill)
+0x2A0D = poi_dining, Dining(Bagel/Donut)
+0x2A0E = poi_dining, Dining(Cafe/Diner)
+0x2A0F = poi_dining, Dining(French)
+0x2A10 = poi_dining, Dining(German)
+0x2A11 = poi_dining, Dining(British Isles)
+0x2A12 = poi_dining, Dining(Special Foods)
+
+0x2B00 = poi_hotel, Hotel(Other)
+0x2B01 = poi_hotel, Hotel/Motel
+0x2B02 = poi_hotel, Bed & Breakfast inn
+0x2B03 = poi_camp_rv, Camping/RV-Park
+0x2B04 = poi_resort, Resort
+
+0x2C00 = poi_attraction, Amusement Park
+0x2C01 = poi_attraction, Amusement Park
+0x2C02 = poi_museum_history, Museum/History
+0x2C03 = poi_library, Libraries
+0x2C04 = poi_landmark, Land Mark
+0x2C05 = poi_school, School
+0x2C06 = poi_park, Park
+0x2C07 = poi_zoo, Zoo
+0x2C08 = poi_stadium, Sportpark, Stadium,(point)
+0x2C09 = poi_fair, Fair, Conference(point)
+0x2C0A = poi_wine, Wine restaurant(point)
+0x2C0B = poi_worship, Place of Worship
+0x2C0C = poi_hotspring, Hot Spring
+
+0x2D00 = poi_theater, Theater
+0x2D01 = poi_theater, Theater
+0x2D02 = poi_bar, Bar
+0x2D03 = poi_cinema, Cinema
+0x2D04 = poi_casino, Casino
+0x2D05 = poi_golf, Golf
+0x2D06 = poi_skiing, Skiing Center
+0x2D07 = poi_bowling, Bowling
+0x2D08 = poi_icesport, Ice/Sporting
+0x2D09 = poi_swimming, Swimming
+0x2D0A = poi_sport, Sports(point)
+0x2D0B = poi_sailing, Sailing Airport
+
+0x2E00 = poi_shopping, Shoping general
+0x2E01 = poi_shop_department, Department Store
+0x2E02 = poi_shop_grocery, Grocery
+0x2E03 = poi_shop_merchandise, General Merchandiser
+0x2E04 = poi_mall, Shopping Center
+0x2E05 = poi_pharmacy, Pharmacy
+0x2E06 = poi_shopping, Convenience
+0x2E07 = poi_shop_apparel, Apparel
+0x2E08 = poi_shop_handg, House and Garden
+0x2E09 = poi_shop_furnish, Home Furnishing
+0x2E0a = poi_shop_retail, Special Retail
+0x2E0b = poi_shop_computer, Computer/Software
+
+0x2F00 = poi_service, generic service
+0x2F01 = poi_fuel, Fuel/Gas
+0x2F02 = poi_car_rent, Car Rental
+0x2F03 = poi_autoservice, Car Repair
+0x2F04 = poi_airport, Airport
+0x2F05 = poi_post, Post Office
+0x2F06 = poi_bank, Bank
+0x2F07 = poi_car_dealer_parts, Car Dealer(point)
+0x2F08 = poi_bus_station, Bus Station
+0x2F09 = poi_marina, Marina
+0x2F0A = poi_wrecker, Wrecker Service
+0x2F0B = poi_car_parking, Parking
+0x2F0C = poi_rest_room, Restroom
+0x2F0D = poi_auto_club, Automobile Club
+0x2F0E = poi_car_wash, Car Wash
+0x2F0F = poi_garmin, Garmin Dealer
+0x2F10 = poi_personal_service, Personal Service
+0x2F11 = poi_bussines_service, Business Service
+0x2F12 = poi_communication, Communication
+0x2F13 = poi_repair_service, Repair Service
+0x2F14 = poi_social_service, Social Service
+0x2F15 = poi_public_utilities, Utility
+0x2F16 = poi_truck_stop, Truck Stop
+0x2F17 = poi_bus_stop, Bus Stop
+
+0x3000 = poi_emergency, generic emergency/government
+0x3001 = poi_police, Police Station
+0x3002 = poi_hospital, Hospital
+0x3003 = poi_public_office, Public Office
+0x3004 = poi_justice, Justice
+0x3005 = poi_concert, Concert hall(point)
+0x3006 = poi_border_station, Border Station(point)
+0x3007 = poi_goverment_building, Goverment Building
+0x3008 = poi_firebrigade, FireFighters Station
+
+0x4000-0x403F = poi_golf, Golf
+0x4100-0x413F = poi_fish, Fish
+0x4200-0x423F = poi_wreck, Wreck
+0x4300-0x433F = poi_marina, Marina
+0x4400-0x443F = poi_fuel, Gas
+0x4500-0x453F = poi_restaurant, Restaurant
+0x4600-0x463F = poi_bar, Bar
+0x4700-0x473F = poi_boat_ramp, Boat Ramp
+0x4800-0x483F = poi_camping, Camping
+0x4900-0x493F = poi_park, Park
+0x4A00-0x4A3F = poi_picnic, Picnic Area
+0x4B00-0x4B3F = poi_hospital, Hospital
+0x4C00-0x4C3F = poi_information, Information
+0x4D00-0x4D3F = poi_car_parking, Parking
+0x4E00-0x4E3F = poi_restroom, Restroom
+0x4F00-0x4F3F = poi_shower, Shower
+0x5000-0x503F = poi_drinking_water, Drinking Water
+0x5100-0x513F = poi_telephone, Telephone
+0x5200-0x523F = poi_scenic_area, Scenic Area
+0x5300-0x533F = poi_skiing, Skiing
+0x5400-0x543F = poi_swimming, Swimming
+0x5500-0x553F = poi_dam, Dam
+
+0x5600-0x563F = poi_forbiden_area, Forbiden Area
+0x5700-0x573F = poi_danger_area, Danger Area
+0x5800-0x583F = poi_restricted_area, Restricted Area
+
+0x5900 = poi_airport, Generic Airport
+0x5901 = poi_airport, Large Airport
+0x5902 = poi_airport, Medium Airport
+0x5903 = poi_airport, Small Airport
+0x5904 = poi_heliport, Heliport
+0x5905-0x593F = poi_airport, Airport
+
+0x5a00 = poi_mark, Kilometer Pole
+0x5b00 = poi_mark, Kolokol
+0x5c00 = poi_diving, Diving Place
+
+0x5D00-0x5D3F = poi_daymark, Daymark,Green Square
+0x5E00-0x5E3F = poi_daymark, Daymark,Red Triangle
+
+0x6000 = poi_loudspeaker, LoudSpeaker
+0x6100 = poi_building, House
+
+0x6200 = poi_height, Height with point in feet one decimal place
+0x6300 = poi_height, Height without point in feet no decimal place
+0x6400 = poi_manmade_feature, Manmade Feature
+0x6401 = poi_bridge, Bridge
+0x6402 = poi_building, Building
+0x6403 = poi_cemetery, Cemetery
+0x6404 = poi_church, Church
+0x6405 = poi_civil, Civil
+0x6406 = poi_crossing, Crossing
+0x6407 = poi_dam, Dam
+0x6408 = poi_hospital, Hospital
+0x6409 = poi_levee, Levee
+0x640A = poi_locale, Locale
+0x640B = poi_military, Military
+0x640C = poi_mine, Mine
+0x640D = poi_oil_field, Oil Field
+0x640E = poi_park, Park
+0x640F = poi_post, Post
+0x6410 = poi_school, School
+0x6411 = poi_tower, Tower
+0x6412 = poi_trail, Trail
+0x6413 = poi_tunnel, Tunnel
+0x6414 = poi_drinking_water, Drink water
+0x6415 = town_ghost, Ghost Town
+0x6416 = poi_subdivision, Subdivision
+
+0x6500 = poi_water_feature, Water Feature
+0x6501 = poi_water_feature, Arroyo
+0x6502 = poi_water_feature, Sand Bar
+0x6503 = poi_bay, Bay
+0x6504 = poi_bend, Bend
+0x6505 = poi_water_feature, Canal
+0x6506 = poi_water_feature, Channel
+0x6507 = poi_cove, Cove
+0x6508 = poi_water_feature, Falls
+0x6509 = poi_water_feature, Geyser
+0x650A = poi_water_feature, Glacier
+0x650B = poi_marine, Harbour
+0x650C = poi_island, Island
+0x650D = poi_water_feature, Lake
+0x650E = poi_water_feature, Rapids
+0x650F = poi_water_feature, Reservoir
+0x6510 = poi_water_feature, Sea
+0x6511 = poi_water_feature, Spring
+0x6512 = poi_water_feature, Stream
+0x6513 = poi_water_feature, Swamp
+
+0x6600 = poi_land_feature, Land Feature
+0x6601 = poi_land_feature, Arch
+0x6602 = poi_land_feature, Area
+0x6603 = poi_land_feature, Basin
+0x6604 = poi_land_feature, Beach
+0x6605 = poi_land_feature, Bench
+0x6606 = poi_land_feature, Cape
+0x6607 = poi_land_feature, Cliff
+0x6608 = poi_land_feature, Crater
+0x6609 = poi_land_feature, Flat
+0x660A = poi_land_feature, Forest
+0x660B = poi_land_feature, Gap
+0x660C = poi_land_feature, Gut
+0x660D = poi_land_feature, Isthmus
+0x660E = poi_land_feature, Lava
+0x660F = poi_land_feature, Pillar
+0x6610 = poi_land_feature, Plain
+0x6611 = poi_land_feature, Range
+0x6612 = poi_land_feature, Reserve
+0x6613 = poi_land_feature, Ridge
+0x6614 = poi_land_feature, Rock
+0x6615 = poi_land_feature, Slope
+0x6616 = poi_land_feature, Summit
+0x6617 = poi_land_feature, Valley
+0x6618 = poi_land_feature, Woods
+
+# This are dublicated to 0x1700, 0x1800, 0x1900, 0x1A00, 0x1B00
+# fix them if you need them
+0x1600 = poi_marine_type, Beakon
+0x1601 = poi_marine_type, Fog Horn
+0x1602 = poi_marine_type, Radio Beacon
+0x1603 = poi_marine_type, Racon
+0x1604 = poi_marine_type, Day Beacon, red triangle
+0x1605 = poi_marine_type, Day Beacon, green square
+0x1606 = poi_marine_type, Day Beacon, white diamond
+0x1607 = poi_marine_type, unlit Navaid, white
+0x1608 = poi_marine_type, unlit Navaid, red
+0x1609 = poi_marine_type, unlit Navaid, green
+0x160a = poi_marine_type, unlit Navaid, black
+0x160b = poi_marine_type, unlit Navaid, yellow or amber
+0x160c = poi_marine_type, unlit Navaid, orange
+0x160d = poi_marine_type, unlit Navaid, multi colored
+0x160e = poi_marine_type, Navaid, unknown
+0x160f = poi_marine_type, lighted Navaid, white
+0x1610 = poi_marine_type, lighted Navaid, red
+0x1611 = poi_marine_type, lighted Navaid, green
+0x1612 = poi_marine_type, lighted Navaid, yellow or amber
+0x1613 = poi_marine_type, lighted Navaid, orange
+0x1614 = poi_marine_type, lighted Navaid, violet
+0x1615 = poi_marine_type, lighted Navaid, blue
+0x1616 = poi_marine_type, lighted Navaid, multi colored
+
+#
+# Street's are routable by:
+# ALL - by all
+# W pedestrian
+# B bycycle
+# M motorcycle
+# C car
+# T truck
+# L largetruck
+# this is probably, encoded into the map
+
+POLYLINE
+0x00 = ALL, street_1_land, Road
+0x01 = MCTL, highway_land, Major HWY thick
+0x02 = MCTL, street_4_land, Principal HWY-thick
+0x03 = MCTL, street_2_land, Principal HWY-medium
+0x04 = MCTL, street_3_city, Arterial Road-medium
+0x05 = MCTL, street_4_city, Arterial Road-thick
+0x06 = MCTL, street_2_city, Road-thin
+0x07 = MCTL, street_1_city, Alley-thick
+0x08 = MCTL, ramp, Ramp
+0x09 = MCTL, ramp, Ramp highspeed
+0x0a = MCTL, street_0, Unpaved Road-thin
+0x0b = MCTL, ramp, Major HWY Connector-thick
+0x0c = MCTL, roundabout, Roundabout
+0x0d = MCTL, street_unkn, Reservation/Zapovednik?
+0x0e = MCTL, street_unkn, Unknown Element 0x0e
+0x0f = NONE, street_unkn, Unknown Element 0x0f
+0x10 = NONE, street_unkn, Unknown Element 0x10
+0x11 = NONE, street_unkn, Unknown Element 0x11
+0x12 = NONE, street_unkn, Unknown Element 0x12
+0x13 = NONE, street_unkn, Unknown Element 0x13
+0x14 = NONE, rail, Railroad
+0x15 = NONE, water_line, Shoreline
+0x16 = W, street_nopass, Trail
+0x18 = NONE, water_line, Stream-thin
+0x19 = NONE, time_zone, Time-Zone
+0x1a = ALL, ferry, Ferry
+0x1b = ALL, ferry, Ferry
+0x1c = NONE, border_country, Political Boundary
+0x1d = NONE, border_country, County Boundary
+0x1e = NONE, border_country, Intl. Boundary
+0x1f = NONE, water_line, River
+0x20 = NONE, height_line_1, Land Contour (thin) Height in feet
+0x21 = NONE, height_line_2, Land Contour (medium) Height in feet
+0x22 = NONE, height_line_3, Land Contour (thick) Height in feet
+0x23 = NONE, depth_line_1, Depth Contour (thin) Depth in feet
+0x24 = NONE, depth_line_2, Depth Contour (medium) Depth in feet
+0x25 = NONE, depth_line_3, Depth Contour (thick) Depth in feet
+0x26 = NONE, water_line, Intermittent River
+0x27 = NONE, street_nopass, Airport Runway
+0x28 = NONE, pipeline, Pipeline
+0x29 = NONE, powerline, Powerline
+0x2a = NONE, marine_boundary, Marine Boundary (no line)
+0x2b = NONE, marine_hazard, Marine Hazard (no line)
+
+POLYGONE
+0x01 = poly_town, City (>200k)
+0x02 = poly_town, City (<200k)
+0x03 = poly_town, Village
+0x04 = poly_military_zone, Military
+0x05 = poly_car_parking, Parking Lot
+0x06 = poly_car_parking, Parking Garage
+0x07 = poly_airport, Airport
+0x08 = poly_commercial_center, Shopping Center
+0x09 = poly_marine, Marina
+0x0a = poly_university, University/College
+0x0b = poly_hospital, Hospital
+0x0c = poly_industry, Industrial
+0x0d = area, Reservation
+0x0e = poly_airport, Airport Runway
+0x13 = area_unspecified, Man made area
+0x14 = poly_park, National park
+0x15 = poly_park, National park
+0x16 = poly_park, National park
+0x17 = poly_park, City Park
+0x18 = poly_golf_course, Golf
+0x19 = poly_sport, Sport
+0x1a = poly_cemetery, Cemetery
+0x1e = poly_park, State Park
+0x1f = poly_park, State Park
+0x20 = poly_park, State Park
+0x28 = poly_water, Ocean
+0x29 = poly_water, Water Reservour
+0x32 = poly_water, Sea
+0x3b = poly_water, Water Reservour
+0x3c = poly_water, Lake (250-600 km2)
+0x3d = poly_water, Lake (77-250 km2)
+0x3e = poly_water, Lake (25-77 km2)
+0x3f = poly_water, Lake (11-25 km2)
+0x40 = poly_water, Lake (0.25-11 km2)
+0x41 = poly_water, Lake (<0.25 km2)
+0x42 = poly_water, Lake (>3.3k km2)
+0x43 = poly_water, Lake (1.1-3.3k km2)
+0x44 = poly_water, Lake (0.6-1.1k km2)
+0x45 = poly_water, Water Reservour
+0x46 = poly_water, River (>1km)
+0x47 = poly_water, River (200m-1km)
+0x48 = poly_water, River (40-200m)
+0x49 = poly_water, River (<40m)
+0x4a = area, Definition Area
+0x4b = area, Background
+0x4c = poly_water, Intermittent River/Lake
+0x4d = poly_water, Glaciers
+0x4e = plantation, Orchard or plantation
+0x4f = poly_scrub, Scrub
+0x50 = poly_wood, Woods
+0x51 = poly_water, Wetland
+0x52 = tundra, Tundra
+0x53 = poly_flats, Flats
diff --git a/navit/data/garmin/gentypes.c b/navit/data/garmin/gentypes.c
new file mode 100644
index 000000000..0792bc055
--- /dev/null
+++ b/navit/data/garmin/gentypes.c
@@ -0,0 +1,195 @@
+/*
+ Copyright (C) 2007 Alexander Atanasov <aatanasov@gmail.com>
+
+ 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; version 2 of the License.
+
+ 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
+
+ Garmin and MapSource are registered trademarks or trademarks
+ of Garmin Ltd. or one of its subsidiaries.
+
+*/
+
+/*
+ Street's are routable by:
+ ALL - by all
+ W pedestrian (1<<0)
+ B bycycle (1<<1)
+ M motorcycle (1<<2)
+ C car (1<<3)
+ T truck (1<<4)
+ L largetruck (1<<5)
+File format is:
+
+POINT
+0x0100 = town_label_1e5, Megapolis (10M +)
+0x0200 = town_label_5e4, Megapolis (5-10M)
+...
+0x1e00-0x1e3f = district_label, District, Province, State Name
+...
+POLYLINE
+0x00 = ALL, street_1_land, Road
+0x01 = MCTL, highway_land, Major HWY thick
+0x02 = MCTL, street_4_land, Principal HWY-thick
+0x03 = MCTL, street_2_land, Principal HWY-medium
+....
+POLYGONE
+0x01 = town_poly, City (>200k)
+0x02 = town_poly, City (<200k)
+0x03 = town_poly, Village
+
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <unistd.h>
+#include "item.h"
+#include "gar2navit.h"
+
+#define dlog(x, y...) fprintf(stderr, ## y)
+/*
+static int add_def(struct gar2nav_conv *conv, int type, unsigned short minid,
+ unsigned short maxid, unsigned int routable, char *ntype,
+ char *descr)
+*/
+
+static unsigned int get_rtmask(char *p)
+{
+ char *cp;
+ unsigned int mask = 0;
+ cp = p;
+ while (*cp) {
+ if (!strcasecmp(cp, "none"))
+ return 0;
+ if (!strcasecmp(cp, "all")) {
+ mask = ~0;
+ break;
+ } if (*cp == 'W')
+ mask |= RT_PEDESTRIAN;
+ else if (*cp == 'B')
+ mask |= RT_BYCYCLE;
+ else if (*cp == 'M')
+ mask |= RT_MOTORCYCLE;
+ else if (*cp == 'C')
+ mask |= RT_CAR;
+ else if (*cp == 'T')
+ mask |= RT_TRUCK;
+ else if (*cp == 'L')
+ mask |= RT_LONGTRUCK;
+ cp++;
+ }
+ return mask;
+}
+
+static void print_header(FILE *fp)
+{
+ fprintf(fp, "// This is autogenerated file -- DO NOT EDIT\n");
+ fprintf(fp, "struct gar2nav_conv *g2n_default_conv(void)\n"
+ "{\n"
+ "\tstruct gar2nav_conv *conv;\n"
+ "\n"
+ "\tconv = calloc(1, sizeof(*conv));\n"
+ "\tif (!conv)\n"
+ "\t\treturn conv;\n");
+}
+
+static int load_types_file(char *file, char *out)
+{
+ char buf[4096];
+ char descr[4096];
+ char ntype[4096];
+ char rtby[4096];
+ FILE *fp;
+ unsigned int minid, maxid, routable;
+ int rc;
+ int type = -1;
+ FILE *fpout = stdout;
+
+ fp = fopen(file, "r");
+ if (!fp)
+ return -1;
+ if (out) {
+ fpout = fopen(out, "w");
+ if (!fpout)
+ return -1;
+ }
+ print_header(fpout);
+ while (fgets(buf, sizeof(buf), fp)) {
+ if (*buf == '#' || *buf == '\n')
+ continue;
+ routable = 0;
+ if (!strncasecmp(buf, "POINT", 5)) {
+ type = 1;
+ continue;
+ } else if (!strncasecmp(buf, "POI", 3)) {
+ type = 1;
+ continue;
+ } else if (!strncasecmp(buf, "POLYLINE", 8)) {
+ type = 2;
+ continue;
+ } else if (!strncasecmp(buf, "POLYGONE", 8)) {
+ type = 3;
+ continue;
+ }
+ // assume only lines are routable
+ if (type == 2) {
+ rc = sscanf(buf, "0x%04X = %[^\t, ] , %[^\t, ], %[^\n]",
+ &minid, rtby, ntype, descr);
+ if (rc != 4) {
+ dlog(1, "Invalid line rc=%d:[%s]\n",rc, buf);
+ dlog(1, "minid=%04X ntype=[%s] des=[%s]\n",
+ minid, ntype, descr);
+ continue;
+ }
+ routable = get_rtmask(rtby);
+ } else {
+ rc = sscanf(buf, "0x%04X - 0x%04X = %[^\t , ] , %[^\n]",
+ &minid, &maxid, ntype, descr);
+ if (rc != 4) {
+ maxid = 0;
+ rc = sscanf(buf, "0x%04X = %[^\t, ], %[^\n]",
+ &minid, ntype, descr);
+ if (rc != 3) {
+ dlog(1, "Invalid line rc=%d:[%s]\n",rc, buf);
+ dlog(1, "minid=%04X ntype=[%s] des=[%s]\n",
+ minid, ntype, descr);
+ continue;
+ }
+ }
+ }
+ fprintf(fpout, "\tadd_def(conv, %d, %d, %d, %d, \"%s\", \"%s\");\n",
+ type, minid, maxid, routable, ntype, descr);
+
+ }
+ fprintf(fpout, "\treturn conv;\n");
+ fprintf(fpout, "}\n");
+ fclose(fp);
+ if (out)
+ fclose(fpout);
+ return 1;
+}
+
+int main(int argc, char **argv)
+{
+ if (argc!=3) {
+ fprintf(stderr, "Usage: %s garmintypes.txt outfile.c\n",
+ argv[0]);
+ return -1;
+ }
+ if (load_types_file(argv[1], argv[2]) < 0) {
+ unlink(argv[2]);
+ return -1;
+ }
+ return 0;
+}
diff --git a/navit/data/garmin_img/Makefile.am b/navit/data/garmin_img/Makefile.am
new file mode 100644
index 000000000..c48ea390c
--- /dev/null
+++ b/navit/data/garmin_img/Makefile.am
@@ -0,0 +1,4 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=data_garmin_img
+moduledata_LTLIBRARIES = libdata_garmin_img.la
+libdata_garmin_img_la_SOURCES = garmin_img.c
diff --git a/navit/data/garmin_img/garmin_img.c b/navit/data/garmin_img/garmin_img.c
new file mode 100644
index 000000000..d735b027d
--- /dev/null
+++ b/navit/data/garmin_img/garmin_img.c
@@ -0,0 +1,1493 @@
+#include <glib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "config.h"
+#include "plugin.h"
+#include "data.h"
+#include "projection.h"
+#include "map.h"
+#include "maptype.h"
+#include "item.h"
+#include "attr.h"
+#include "coord.h"
+#include "transform.h"
+#include <stdio.h>
+#include "attr.h"
+#include "coord.h"
+
+struct file {
+ FILE *f;
+ int offset;
+};
+
+
+int shift=5;
+int subdiv_next=0x10;
+
+
+static void *
+file_read(struct file *f, int offset, int size)
+{
+ void *ptr;
+ int ret;
+
+ ptr=calloc(size, 1);
+ if (! ptr)
+ return ptr;
+ fseek(f->f, f->offset+offset, SEEK_SET);
+ ret=fread(ptr, size, 1, f->f);
+ if (ret != 1) {
+ printf("fread %d vs %d offset %d+%d(0x%x)\n", ret, size, f->offset, offset,offset);
+ g_assert(1==0);
+ }
+ return ptr;
+}
+
+static void
+file_free(void *ptr)
+{
+ free(ptr);
+}
+
+struct offset_len {
+ int offset;
+ int length;
+} __attribute ((packed));
+
+static void
+dump_offset_len(struct offset_len *off_len)
+{
+ printf("offset: 0x%x(%d) length 0x%x(%d)\n", off_len->offset, off_len->offset, off_len->length, off_len->length);
+}
+
+struct timestamp {
+ short creation_year;
+ char creation_month;
+ char creation_day;
+ char creation_hour;
+ char creation_minute;
+ char creation_second;
+} __attribute__((packed));
+
+struct img_header {
+ char xor;
+ char zero1[9];
+ char update_month;
+ char update_year;
+ char zero2[3];
+ char checksum[1];
+ char signature[7];
+ char unknown1[1];
+ char unknown2[2];
+ char unknown3[2];
+ char unknown4[2];
+ char unknown5[2];
+ char zero3[25];
+ struct timestamp ts;
+ char unknown6;
+ char map_file_identifier[7];
+ char unknown12;
+ char map_description1[20];
+ short unknown13;
+ short unknown14;
+ char e1;
+ char e2;
+ char other[413];
+ char zero4[512];
+ char unknown7;
+ char unknown8[11];
+ int file_offset;
+ char unknown9;
+ char unknown10[15];
+ char unknown11[480];
+} __attribute__((packed));
+
+static void
+dump_ts(struct timestamp *ts)
+{
+ printf("%d-%02d-%02d %02d:%02d:%02d\n", ts->creation_year, ts->creation_month, ts->creation_day, ts->creation_hour, ts->creation_minute, ts->creation_second);
+}
+
+#if 0
+static void
+dump_img(struct img_header *img_hdr)
+{
+ printf("signature: '%s'\n", img_hdr->signature);
+ printf("creation: ");
+ dump_ts(&img_hdr->ts);
+ printf("map_file_identifier: '%s'\n", img_hdr->map_file_identifier);
+ printf("file_offset: 0x%x\n", img_hdr->file_offset);
+ printf("e1: 0x%x(%d)\n", img_hdr->e1, img_hdr->e1);
+ printf("e2: 0x%x(%d)\n", img_hdr->e2, img_hdr->e2);
+ printf("offset 0x%x\n", (int) &img_hdr->e1 - (int) img_hdr);
+ printf("size %d\n", sizeof(*img_hdr));
+}
+#endif
+
+struct fat_block {
+ char flag;
+ char filename[8];
+ char type[3];
+ int size;
+ char zero1;
+ char part;
+ char zero[14];
+ unsigned short blocks[240];
+} __attribute__((packed));
+
+#if 0
+static void
+dump_fat_block(struct fat_block *fat_blk)
+{
+ int i=0;
+ char name[9];
+ char type[4];
+ printf("flag: 0x%x(%d)\n", fat_blk->flag, fat_blk->flag);
+ strcpy(name, fat_blk->filename);
+ name[8]='\0';
+ strcpy(type, fat_blk->type);
+ type[3]='\0';
+ printf("name: '%s.%s'\n", name, type);
+ printf("size: 0x%x(%d)\n", fat_blk->size, fat_blk->size);
+ printf("part: 0x%x(%d)\n", fat_blk->part, fat_blk->part);
+ printf("blocks: ");
+ while (i < 240) {
+ printf("0x%x(%d) ",fat_blk->blocks[i], fat_blk->blocks[i]);
+ if (fat_blk->blocks[i] == 0xffff)
+ break;
+ i++;
+ }
+ printf("size: %d\n", sizeof(*fat_blk));
+
+}
+#endif
+
+struct file_header {
+ short header_len;
+ char type[10];
+ char unknown1;
+ char unknown2;
+ struct timestamp ts;
+} __attribute__((packed));
+
+static void
+dump_file(struct file_header *fil_hdr)
+{
+ printf("header_len: %d\n", fil_hdr->header_len);
+ printf("type: '%s'\n", fil_hdr->type);
+ printf("unknown1: 0x%x(%d)\n", fil_hdr->unknown1, fil_hdr->unknown1);
+ printf("unknown2: 0x%x(%d)\n", fil_hdr->unknown2, fil_hdr->unknown2);
+ printf("creation: ");
+ dump_ts(&fil_hdr->ts);
+ printf("size %d\n", sizeof(*fil_hdr));
+}
+
+struct region_header {
+ struct file_header fil_hdr;
+ struct offset_len offset_len;
+} __attribute__((packed));
+
+#if 0
+static void
+dump_region(struct region_header *rgn_hdr)
+{
+ dump_offset_len(&rgn_hdr->offset_len);
+}
+#endif
+
+struct map_priv {
+ int id;
+ char *filename;
+};
+
+struct map_rect_priv {
+ struct coord_rect r;
+ int limit;
+
+ struct file tre;
+ struct tree_header *tre_hdr;
+ struct file rgn;
+ struct region_header *rgn_hdr;
+ struct file lbl;
+ struct label_header *lbl_hdr;
+ char *label;
+
+ int subdiv_level_count;
+ int subdiv_pos;
+ char *subdiv;
+
+ int rgn_offset;
+ int rgn_end;
+ struct rgn_point *pnt;
+ struct rgn_poly *ply;
+ unsigned char *ply_data;
+ int ply_bitpos;
+ int ply_bitcount;
+ int ply_lngbits;
+ int ply_latbits;
+ int ply_lng;
+ int ply_lat;
+ int ply_lnglimit;
+ int ply_latlimit;
+ int ply_lngsign;
+ int ply_latsign;
+ struct offset_len rgn_items[4];
+ int rgn_type;
+
+ int count;
+
+ FILE *f;
+ long pos;
+ char line[256];
+ int attr_pos;
+ enum attr_type attr_last;
+ char attrs[256];
+ char attr[256];
+ double lat,lng;
+ char lat_c,lng_c;
+ int eoc;
+ struct map_priv *m;
+ struct item item;
+};
+
+static int map_id;
+
+static int
+contains_coord(char *line)
+{
+ return g_ascii_isdigit(line[0]);
+}
+
+static int debug=1;
+
+static int
+get_tag(char *line, char *name, int *pos, char *ret)
+{
+ int len,quoted;
+ char *p,*e,*n;
+
+ if (debug)
+ printf("get_tag %s from %s\n", name, line);
+ if (! name)
+ return 0;
+ len=strlen(name);
+ if (pos)
+ p=line+*pos;
+ else
+ p=line;
+ for(;;) {
+ while (*p == ' ') {
+ p++;
+ }
+ if (! *p)
+ return 0;
+ n=p;
+ e=index(p,'=');
+ if (! e)
+ return 0;
+ p=e+1;
+ quoted=0;
+ while (*p) {
+ if (*p == ' ' && !quoted)
+ break;
+ if (*p == '"')
+ quoted=1-quoted;
+ p++;
+ }
+ if (e-n == len && !strncmp(n, name, len)) {
+ e++;
+ len=p-e;
+ if (e[0] == '"') {
+ e++;
+ len-=2;
+ }
+ strncpy(ret, e, len);
+ ret[len]='\0';
+ if (pos)
+ *pos=p-line;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void
+get_line(struct map_rect_priv *mr)
+{
+ mr->pos=ftell(mr->f);
+ fgets(mr->line, 256, mr->f);
+}
+
+static void
+map_destroy_garmin_img(struct map_priv *m)
+{
+ if (debug)
+ printf("map_destroy_garmin_img\n");
+ g_free(m);
+}
+
+static char *
+map_charset_garmin_img(struct map_priv *m)
+{
+ return "iso8859-1";
+}
+
+static enum projection
+map_projection_garmin_img(struct map_priv *m)
+{
+ return projection_garmin;
+}
+
+struct label_data_offset {
+ struct offset_len offset_len;
+ char multiplier;
+ char data;
+} __attribute ((packed));
+
+#if 0
+static void
+dump_label_data_offset(struct label_data_offset *lbl_dat)
+{
+ dump_offset_len(&lbl_dat->offset_len);
+ printf("multiplier 0x%x(%d)\n", lbl_dat->multiplier, lbl_dat->multiplier);
+ printf("data 0x%x(%d)\n", lbl_dat->data, lbl_dat->data);
+}
+#endif
+
+struct label_data {
+ struct offset_len offset_len;
+ short size;
+ int zero;
+} __attribute ((packed));
+
+static void
+dump_label_data(struct label_data *lbl_dat)
+{
+ dump_offset_len(&lbl_dat->offset_len);
+ printf("size 0x%x(%d)\n", lbl_dat->size, lbl_dat->size);
+}
+
+struct tree_header {
+ struct file_header fil_hdr;
+ char boundary[12];
+ struct offset_len level;
+ struct offset_len subdivision;
+ struct label_data copyright;
+ struct offset_len tre7;
+ short unknown1;
+ char zero1;
+ struct label_data polyline;
+ struct label_data polygon;
+ struct label_data point;
+ int mapid;
+};
+
+static void
+dump_tree_header(struct tree_header *tre_hdr)
+{
+ printf("tree_header:\n");
+ dump_file(&tre_hdr->fil_hdr);
+ printf("level: "); dump_offset_len(&tre_hdr->level);
+ printf("subdivision: "); dump_offset_len(&tre_hdr->subdivision);
+ printf("copyright: "); dump_label_data(&tre_hdr->copyright);
+ printf("polyline: "); dump_label_data(&tre_hdr->polyline);
+ printf("polygon: "); dump_label_data(&tre_hdr->polygon);
+ printf("point: "); dump_label_data(&tre_hdr->point);
+ printf("len: 0x%x(%d)\n", sizeof(*tre_hdr), sizeof(*tre_hdr));
+}
+
+struct label_header {
+ struct file_header fil_hdr;
+ struct label_data_offset label;
+ struct label_data country;
+ struct label_data region;
+ struct label_data city;
+ struct label_data poi_index;
+ struct label_data_offset poi_properties;
+ short zero1;
+ char zero2;
+ struct label_data poi_types;
+ struct label_data zip;
+ struct label_data hway;
+ struct label_data exit;
+ struct label_data hway_data;
+ int unknown1;
+ short unknown2;
+ struct offset_len sort_descriptor;
+ struct label_data lbl13;
+ struct label_data lbl14;
+} __attribute((packed));
+
+#if 0
+static void
+dump_label(struct label_header *lbl_hdr)
+{
+ dump_file(&lbl_hdr->fil_hdr);
+ printf("label:\n");
+ dump_label_data_offset(&lbl_hdr->label);
+ printf("country:\n");
+ dump_label_data(&lbl_hdr->country);
+ printf("region:\n");
+ dump_label_data(&lbl_hdr->region);
+ printf("city:\n");
+ dump_label_data(&lbl_hdr->city);
+ printf("poi_index:\n");
+ dump_label_data(&lbl_hdr->poi_index);
+ printf("poi_properties:\n");
+ dump_label_data_offset(&lbl_hdr->poi_properties);
+ printf("poi_types:\n");
+ dump_label_data(&lbl_hdr->poi_types);
+ printf("zip:\n");
+ dump_label_data(&lbl_hdr->zip);
+ printf("hway:\n");
+ dump_label_data(&lbl_hdr->hway);
+ printf("exit:\n");
+ dump_label_data(&lbl_hdr->exit);
+ printf("hway_data:\n");
+ dump_label_data(&lbl_hdr->hway_data);
+ printf("lbl13:\n");
+ dump_label_data(&lbl_hdr->lbl13);
+ printf("lbl14:\n");
+ dump_label_data(&lbl_hdr->lbl14);
+ printf("len: 0x%x(%d)\n", sizeof(*lbl_hdr), sizeof(*lbl_hdr));
+}
+#endif
+
+struct triple {
+ unsigned char data[3];
+} __attribute((packed));
+
+static unsigned int
+triple_u(struct triple *t)
+{
+ return t->data[0] | (t->data[1] << 8) | (t->data[2] << 16);
+}
+
+static int
+triple(struct triple *t)
+{
+ int ret=t->data[0] | (t->data[1] << 8) | (t->data[2] << 16);
+ if (ret > 1<<23)
+ ret=ret-(1<<24);
+ return ret;
+}
+
+static void
+dump_triple_u(struct triple *t)
+{
+ int val=triple_u(t);
+ printf("0x%x(%d)\n", val, val);
+}
+
+struct tcoord {
+ struct triple lng,lat;
+} __attribute((packed));
+
+static void
+dump_tcoord(struct tcoord *t)
+{
+ printf ("0x%x(%d),0x%x(%d)\n", triple_u(&t->lng), triple_u(&t->lng), triple_u(&t->lat), triple_u(&t->lat));
+}
+
+struct level {
+ unsigned char zoom;
+ unsigned char bits_per_coord;
+ unsigned short subdivisions;
+} __attribute((packed));
+
+static void
+dump_level(struct level *lvl)
+{
+ printf("level:\n");
+ printf("\tzoom 0x%x(%d)\n", lvl->zoom, lvl->zoom);
+ printf("\tbits_per_coord 0x%x(%d)\n", lvl->bits_per_coord, lvl->bits_per_coord);
+ printf("\tsubdivisions 0x%x(%d)\n", lvl->subdivisions, lvl->subdivisions);
+}
+
+struct subdivision {
+ struct triple rgn_offset;
+ unsigned char types;
+ struct tcoord center;
+ unsigned short width;
+ unsigned short height;
+ unsigned short next;
+} __attribute((packed));
+
+static void
+dump_subdivision(struct subdivision *sub)
+{
+ printf("subdivision:\n");
+ printf("\trgn_offset: "); dump_triple_u(&sub->rgn_offset);
+ printf("\ttypes: 0x%x(%d)\n", sub->types, sub->types);
+ printf("\tcenter: "); dump_tcoord(&sub->center);
+ printf("\tsize: 0x%x(%d)x0x%x(%d) %s\n",sub->width & 0x7fff, sub->width & 0x7fff, sub->height, sub->height, sub->width & 0x8000 ? "Terminating" : "");
+ printf("\tnext: 0x%x(%d)\n",sub->next, sub->next);
+
+ printf("\tlen: 0x%x(%d)\n", sizeof(*sub), sizeof(*sub));
+}
+
+struct rgn_point {
+ unsigned char info;
+ struct triple lbl_offset;
+ short lng_delta;
+ short lat_delta;
+ unsigned char subtype;
+} __attribute((packed));
+
+static void
+dump_point(struct rgn_point *pnt)
+{
+ printf("point:\n");
+ printf("\tinfo 0x%x(%d)\n", pnt->info, pnt->info);
+ printf("\tlbl_offset 0x%x(%d)\n", triple_u(&pnt->lbl_offset), triple_u(&pnt->lbl_offset));
+ printf("\tlng_delta 0x%x(%d)\n", pnt->lng_delta, pnt->lng_delta);
+ printf("\tlat_delta 0x%x(%d)\n", pnt->lat_delta, pnt->lat_delta);
+ printf("\tsubtype 0x%x(%d)\n", pnt->subtype, pnt->subtype);
+ printf("\tlen: 0x%x(%d)\n", sizeof(*pnt), sizeof(*pnt));
+}
+
+struct rgn_poly {
+ unsigned char info;
+ struct triple lbl_offset;
+ short lng_delta;
+ short lat_delta;
+ union {
+ struct {
+ unsigned char bitstream_len;
+ unsigned char bitstream_info;
+ } __attribute((packed)) p1;
+ struct {
+ unsigned short bitstream_len;
+ unsigned char bitstream_info;
+ } __attribute((packed)) p2;
+ } __attribute((packed)) u;
+} __attribute((packed));
+
+static void
+dump_poly(struct rgn_poly *ply)
+{
+ printf("poly:\n");
+ printf("\tinfo 0x%x(%d)\n", ply->info, ply->info);
+ printf("\tlbl_offset 0x%x(%d)\n", triple_u(&ply->lbl_offset), triple_u(&ply->lbl_offset));
+ printf("\tlng_delta 0x%x(%d)\n", ply->lng_delta, ply->lng_delta);
+ printf("\tlat_delta 0x%x(%d)\n", ply->lat_delta, ply->lat_delta);
+ if (ply->info & 0x80) {
+ printf("\tbitstream_len 0x%x(%d)\n", ply->u.p2.bitstream_len, ply->u.p2.bitstream_len);
+ printf("\tbitstream_info 0x%x(%d)\n", ply->u.p2.bitstream_info, ply->u.p2.bitstream_info);
+ } else {
+ printf("\tbitstream_len 0x%x(%d)\n", ply->u.p1.bitstream_len, ply->u.p1.bitstream_len);
+ printf("\tbitstream_info 0x%x(%d)\n", ply->u.p1.bitstream_info, ply->u.p1.bitstream_info);
+ }
+ printf("\tlen: 0x%x(%d)\n", sizeof(*ply), sizeof(*ply));
+}
+
+static void
+dump_hex(void *ptr, int len)
+{
+ unsigned char *c=ptr;
+ while (len--) {
+ printf("%02x ", *c++);
+ }
+ printf("\n");
+}
+
+static void
+dump_hex_r(void *ptr, int len, int rec)
+{
+ unsigned char *c=ptr;
+ int l=rec;
+ while (len--) {
+ printf("%02x ", *c++);
+ if (! --l) {
+ printf("\n");
+ l=rec;
+ }
+ }
+ printf("\n");
+}
+
+#if 0
+static void
+dump_label_offset(struct map_rect_priv *mr, int offset)
+{
+ void *p;
+ p=file_read(&mr->lbl, mr->lbl_hdr->label.offset_len.offset+offset, 128);
+ printf("%s\n", (char *)p);
+}
+#endif
+
+
+#if 0
+static void
+dump_region_item(struct subdivision *sub, struct file *rgn, struct map_rect_priv *mr)
+{
+ int offset,item_offset,i,j;
+ unsigned short count=0;
+ unsigned short *offsets[4];
+ unsigned short *file_offsets;
+ struct rgn_point *pnt;
+
+ offset=triple_u(&sub->rgn_offset)+mr->rgn_hdr->offset_len.offset;
+ file_offsets=file_read(rgn, offset, 90*sizeof(unsigned short));
+ printf("0x%x ", offset); dump_hex(file_offsets, 90);
+ for (i=0 ; i < 4 ; i++) {
+ printf("i=%d\n", i);
+ if (sub->types & (0x10 << i)) {
+ if (count) {
+ offsets[i]=&file_offsets[count-1];
+ } else
+ offsets[i]=&count;
+ count++;
+ } else
+ offsets[i]=NULL;
+
+ }
+ count--;
+ count*=2;
+ for (i=0 ; i < 4 ; i++) {
+ printf("i=%d\n", i);
+ if (offsets[i]) {
+ printf("offset[%d]=0x%x(%d)\n", i, *offsets[i], *offsets[i]);
+ switch (i) {
+ case 0:
+ printf("point\n");
+ break;
+ case 1:
+ printf("indexed point\n");
+ break;
+ case 2:
+ printf("polyline\n");
+ break;
+ case 3:
+ printf("polygon\n");
+ break;
+ }
+ item_offset=offset+*offsets[i];
+ switch (i) {
+ case 0:
+ case 1:
+ for (j = 0 ; j < 10 ; j++) {
+ struct coord_geo g;
+ char buffer[1024];
+ double conv=180.0/(1UL<<23);
+ pnt=file_read(rgn, item_offset, sizeof(*pnt)*20);
+ // printf("0x%x ", item_offset); dump_hex(pnt, 32);
+ dump_point(pnt);
+ g.lng=(triple(&sub->center.lng)+(pnt->lng_delta << shift))*conv;
+ g.lat=(triple(&sub->center.lat)+(pnt->lat_delta << shift))*conv;
+ printf("%f %f\n", g.lng, g.lat);
+ transform_geo_text(&g, buffer);
+ printf("%s\n", buffer);
+ dump_label_offset(mr, triple_u(&pnt->lbl_offset));
+ if (pnt->info & 0x80)
+ item_offset+=sizeof(*pnt);
+ else
+ item_offset+=sizeof(*pnt)-1;
+ }
+ }
+ } else {
+ printf("offset[%d] doesn't exist\n", i);
+ }
+ }
+ file_free(file_offsets);
+}
+
+#endif
+
+static void
+dump_levels(struct map_rect_priv *mr)
+{
+ int i,offset;
+ struct level *lvl;
+
+ offset=mr->tre_hdr->level.offset;
+ for (i = 0 ; i < mr->tre_hdr->level.length/sizeof(*lvl) ; i++) {
+ lvl=file_read(&mr->tre, offset, sizeof(*lvl));
+ dump_level(lvl);
+ offset+=sizeof(*lvl);
+ }
+}
+
+#if 0
+static void
+dump_tree(struct file *f, struct file *rgn, struct map_rect_priv *mr)
+{
+ struct tree_header *tre_hdr;
+ struct subdivision *sub;
+ int i,offset;
+
+ tre_hdr=file_read(f, 0, sizeof(*tre_hdr));
+ dump_tree_header(tre_hdr);
+ offset=tre_hdr->subdivision.offset;
+ sub=file_read(f, offset, sizeof(*sub));
+ dump_subdivision(sub);
+ offset+=sizeof(*sub);
+ for (i = 1 ; i < tre_hdr->subdivision.length/sizeof(*sub) ; i++) {
+ printf("i=%d\n", i);
+ sub=file_read(f, offset, sizeof(*sub));
+ dump_subdivision(sub);
+ dump_region_item(sub, rgn, mr);
+ if (sub->width & 0x8000)
+ break;
+ offset+=sizeof(*sub);
+ }
+ file_free(tre_hdr);
+}
+#endif
+
+#if 0
+static void
+dump_labels(struct file *f)
+{
+ struct label_header *lbl_hdr;
+
+ lbl_hdr=file_read(f, 0, sizeof(*lbl_hdr));
+ printf("**labels**\n");
+ dump_label(lbl_hdr);
+ file_free(lbl_hdr);
+#if 0
+ labels=alloca(lbl_hdr.label_length);
+ file_read(f, lbl_hdr.label_offset, labels, lbl_hdr.label_length);
+ l=labels;
+ while (l < labels+lbl_hdr.label_length) {
+ printf("'%s'(%d)\n", l, strlen(l));
+ l+=strlen(l)+1;
+ }
+#endif
+
+}
+#endif
+
+static void
+garmin_img_coord_rewind(void *priv_data)
+{
+}
+
+static void
+parse_line(struct map_rect_priv *mr)
+{
+ int pos=0;
+ sscanf(mr->line,"%lf %c %lf %c %n",&mr->lat,&mr->lat_c,&mr->lng,&mr->lng_c,&pos);
+ if (pos < strlen(mr->line)) {
+ strcpy(mr->attrs, mr->line+pos);
+ }
+}
+
+static int
+get_bits(struct map_rect_priv *mr, int bits)
+{
+ unsigned long ret;
+ ret=L(*((unsigned long *)(mr->ply_data+mr->ply_bitpos/8)));
+ ret >>= (mr->ply_bitpos & 7);
+ ret &= (1 << bits)-1;
+ mr->ply_bitpos+=bits;
+ return ret;
+}
+
+static int
+garmin_img_coord_get(void *priv_data, struct coord *c, int count)
+{
+ struct map_rect_priv *mr=priv_data;
+ struct subdivision *sub=(struct subdivision *)(mr->subdiv+mr->subdiv_pos);
+ int ret=0;
+ int debug=0;
+ if (debug)
+ printf("garmin_img_coord_get %d\n",count);
+ if (debug)
+ dump_subdivision(sub);
+ while (count--) {
+ if (mr->rgn_type < 2) {
+ c->x=triple(&sub->center.lng)+(mr->pnt->lng_delta << shift);
+ c->y=triple(&sub->center.lat)+(mr->pnt->lat_delta << shift);
+ } else {
+ if (! mr->ply_bitpos) {
+ if (mr->ply->info & 0x80) {
+ mr->ply_bitcount=mr->ply->u.p2.bitstream_len*8;
+ mr->ply_lngbits=mr->ply->u.p2.bitstream_info & 0xf;
+ mr->ply_latbits=mr->ply->u.p2.bitstream_info >> 4;
+ } else {
+ mr->ply_bitcount=mr->ply->u.p1.bitstream_len*8;
+ mr->ply_lngbits=mr->ply->u.p1.bitstream_info & 0xf;
+ mr->ply_latbits=mr->ply->u.p1.bitstream_info >> 4;
+ }
+ if (mr->ply_lngbits <= 9)
+ mr->ply_lngbits+=2;
+ if (mr->ply_latbits <= 9)
+ mr->ply_latbits+=2;
+ if (! get_bits(mr,1)) {
+ mr->ply_lngbits+=1;
+ mr->ply_lngsign=0;
+ } else
+ if (get_bits(mr, 1))
+ mr->ply_lngsign=-1;
+ else
+ mr->ply_lngsign=1;
+ if (! get_bits(mr,1)) {
+ mr->ply_latbits+=1;
+ mr->ply_latsign=0;
+ } else
+ if (get_bits(mr, 1))
+ mr->ply_latsign=-1;
+ else
+ mr->ply_latsign=1;
+ mr->ply_lnglimit=1 << (mr->ply_lngbits-1);
+ mr->ply_latlimit=1 << (mr->ply_latbits-1);
+ mr->ply_lng=mr->ply->lng_delta;
+ mr->ply_lat=mr->ply->lat_delta;
+ if (debug)
+ printf("lngbits %d latbits %d bitcount %d\n", mr->ply_lngbits, mr->ply_latbits, mr->ply_bitcount);
+ c->x=0;
+ c->y=0;
+ } else {
+ if (mr->ply_bitpos + mr->ply_lngbits + mr->ply_latbits > mr->ply_bitcount) {
+ if (debug)
+ printf("out of bits %d + %d + %d >= %d\n", mr->ply_bitpos, mr->ply_lngbits, mr->ply_latbits, mr->ply_bitcount);
+ return ret;
+ }
+ c->x=0;
+ c->y=0;
+ int x,y;
+ for (;;) {
+ x=get_bits(mr,mr->ply_lngbits);
+ if (debug)
+ printf("x %d ", x);
+ if (mr->ply_lngsign || x != mr->ply_lnglimit)
+ break;
+ c->x += x-1;
+ }
+ if (mr->ply_lngsign) {
+ c->x=x*mr->ply_lngsign;
+ } else {
+ if (x >= mr->ply_lnglimit)
+ c->x = x - (mr->ply_lnglimit << 1) - c->x;
+ else
+ c->x +=x;
+ }
+ for (;;) {
+ y=get_bits(mr,mr->ply_latbits);
+ if (debug)
+ printf("y %d ", y);
+ if (mr->ply_latsign || y != mr->ply_latlimit)
+ break;
+ c->y += y-1;
+ }
+ if (mr->ply_latsign) {
+ c->y=y*mr->ply_latsign;
+ } else {
+ if (y >= mr->ply_latlimit)
+ c->y = y - (mr->ply_latlimit << 1) - c->y;
+ else
+ c->y +=y;
+ }
+ mr->ply_lng += c->x;
+ mr->ply_lat += c->y;
+ }
+ if (debug)
+ printf(": x %d y %d\n", c->x, c->y);
+
+ c->x=triple(&sub->center.lng)+(mr->ply_lng << shift);
+ c->y=triple(&sub->center.lat)+(mr->ply_lat << shift);
+ }
+#if 0
+ c->x-=0x6f160;
+ c->y-=0x181f59;
+ c->x+=0x168ca1;
+ c->y+=0x68d815;
+#endif
+ c++;
+ ret++;
+ if (mr->rgn_type < 2)
+ return ret;
+ }
+ return ret;
+}
+
+static char *
+get_label_offset(struct map_rect_priv *mr, int offset)
+{
+ g_assert(offset < mr->lbl_hdr->label.offset_len.length);
+ return file_read(&mr->lbl, mr->lbl_hdr->label.offset_len.offset+offset, 128);
+}
+
+static void
+garmin_img_attr_rewind(void *priv_data)
+{
+}
+
+static int
+garmin_img_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+ struct map_rect_priv *mr=priv_data;
+ int debug=0;
+
+ if (debug)
+ printf("garmin_img_attr_get\n");
+ if (attr_type == attr_label) {
+ if (debug)
+ printf("garmin_img_attr_get label\n");
+ attr->type=attr_type;
+ if (mr->rgn_type < 2) {
+ if (mr->label)
+ file_free(mr->label);
+ mr->label=get_label_offset(mr, triple_u(&mr->pnt->lbl_offset) & 0x3fffff);
+ attr->u.str=mr->label;
+ } else {
+ attr->u.str="";
+ }
+ return 1;
+ }
+ return 0;
+}
+
+static struct item_methods methods_garmin_img = {
+ garmin_img_coord_rewind,
+ garmin_img_coord_get,
+ garmin_img_attr_rewind,
+ garmin_img_attr_get,
+};
+
+static int rgn_next_type(struct map_rect_priv *mr)
+{
+ while (mr->rgn_type < 3) {
+ mr->rgn_type++;
+ if (mr->rgn_items[mr->rgn_type].offset && mr->rgn_items[mr->rgn_type].length != 0) {
+ mr->rgn_offset=mr->rgn_items[mr->rgn_type].offset;
+ mr->rgn_end=mr->rgn_offset+mr->rgn_items[mr->rgn_type].length;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+sub_next(struct map_rect_priv *mr, int next)
+{
+ int i,offset,first=-1,last=-1,count=-1;
+ int end;
+ unsigned short *offsets;
+ int debug=0;
+
+ if (mr->subdiv_level_count <= 0)
+ return 1;
+ if (debug)
+ printf("%d left\n", mr->subdiv_level_count);
+ mr->subdiv_level_count--;
+
+#if 0
+ if (next && mr->subdiv[mr->subdiv_current].width & 0x8000)
+ return 1;
+#endif
+ if (debug)
+ dump_hex_r(mr->subdiv+mr->subdiv_pos, 64, 14);
+ mr->subdiv_pos+=next;
+ if (debug)
+ printf("subdiv_pos 0x%x\n", mr->subdiv_pos);
+ if (mr->subdiv_pos > mr->tre_hdr->subdivision.length)
+ return 1;
+ struct subdivision *sub=(struct subdivision *)(mr->subdiv+mr->subdiv_pos);
+ offset=triple_u(&sub->rgn_offset)+mr->rgn_hdr->offset_len.offset;
+ if (debug) {
+ printf("offset=0x%x\n", offset);
+ dump_subdivision(sub);
+ }
+ offsets=file_read(&mr->rgn, offset, 3*sizeof(unsigned short));
+
+ if (! next)
+ next=subdiv_next;
+ if (mr->subdiv_pos+next < mr->tre_hdr->subdivision.length)
+ end=triple_u(&((struct subdivision *)(mr->subdiv+mr->subdiv_pos+next))->rgn_offset)+mr->rgn_hdr->offset_len.offset;
+ else
+ end=mr->rgn_hdr->offset_len.offset+mr->rgn_hdr->offset_len.length;
+ if (debug) {
+ dump_subdivision(sub);
+ dump_hex(offsets, 6);
+ }
+ for (i=0 ; i < 4 ; i++) {
+ if (debug)
+ printf("i=%d ", i);
+ if (sub->types & (0x10 << i)) {
+ if (debug)
+ printf("+ ");
+ if (first == -1) {
+ first=i;
+ mr->rgn_items[i].offset=offset;
+ if (debug)
+ printf("\n");
+ } else {
+ mr->rgn_items[i].offset=offset+offsets[count];
+ if (debug)
+ printf("0x%x\n", offsets[count]);
+ mr->rgn_items[last].length=mr->rgn_items[i].offset-mr->rgn_items[last].offset;
+ }
+ last=i;
+ count++;
+ } else {
+ if (debug)
+ printf("-\n");
+ mr->rgn_items[i].offset=0;
+ mr->rgn_items[i].length=0;
+ }
+
+ }
+ if (first != -1) {
+ mr->rgn_items[first].offset+=count*2;
+ mr->rgn_items[first].length-=count*2;
+ mr->rgn_items[last].length=end-mr->rgn_items[last].offset;
+ }
+ if (debug) {
+ for (i=0 ; i < 4 ; i++) {
+ printf("%d 0x%x 0x%x\n", i, mr->rgn_items[i].offset, mr->rgn_items[i].length);
+ }
+ }
+ mr->rgn_type=-1;
+ rgn_next_type(mr);
+ if (debug)
+ printf("*** offset 0x%x\n", mr->rgn_offset);
+ file_free(offsets);
+ return 0;
+}
+
+int item_count;
+
+static struct map_rect_priv *
+map_rect_new_garmin_img(struct map_priv *map, struct coord_rect *r, struct layer *layers, int limit)
+{
+ struct map_rect_priv *mr;
+ struct img_header img;
+
+ if (debug)
+ printf("map_rect_new_garmin_img\n");
+ mr=g_new0(struct map_rect_priv, 1);
+ mr->m=map;
+ if (r)
+ mr->r=*r;
+ mr->limit=limit;
+ mr->item.id_hi=0;
+ mr->item.id_lo=0;
+ mr->item.meth=&methods_garmin_img;
+ mr->item.priv_data=mr;
+ mr->f=fopen(map->filename, "r");
+
+ fread(&img, sizeof(img), 1, mr->f);
+#if 0
+ dump_img(&img);
+ for (i = 0 ; i < (img.file_offset-sizeof(img))/sizeof(fat_blk) ; i++) {
+ fread(&fat_blk, sizeof(fat_blk), 1, mr->f);
+ if (!fat_blk.flag)
+ break;
+ dump_fat_block(&fat_blk);
+ }
+#endif
+ mr->rgn.offset=0xa*2048;
+ mr->rgn.f=mr->f;
+ mr->rgn_hdr=file_read(&mr->rgn, 0, sizeof(*mr->rgn_hdr));
+
+ mr->tre.offset=0x62b*2048;
+ mr->tre.f=mr->f;
+ mr->tre_hdr=file_read(&mr->tre, 0, sizeof(*mr->tre_hdr));
+
+ mr->lbl.offset=0x64a*2048;
+ mr->lbl.f=mr->f;
+ mr->lbl_hdr=file_read(&mr->lbl, 0, sizeof(*mr->lbl_hdr));
+
+ mr->subdiv=file_read(&mr->tre, mr->tre_hdr->subdivision.offset, mr->tre_hdr->subdivision.length);
+#if 0
+ dump_hex_r(mr->subdiv, mr->tre_hdr->subdivision.length, 16);
+#endif
+ dump_tree_header(mr->tre_hdr);
+
+ dump_levels(mr);
+
+
+ printf("limit=%d\n", limit);
+ if (limit < 3) {
+ mr->subdiv_pos=0;
+ mr->subdiv_level_count=1;
+ shift=11;
+ } else if (limit < 6) {
+ mr->subdiv_pos=1*sizeof(struct subdivision);
+ mr->subdiv_level_count=5;
+ shift=9;
+ } else if (limit < 8) {
+ mr->subdiv_pos=6*sizeof(struct subdivision);
+ mr->subdiv_level_count=9;
+ shift=7;
+ } else if (limit < 10) {
+ mr->subdiv_pos=15*sizeof(struct subdivision);
+ mr->subdiv_level_count=143;
+ shift=5;
+ } else {
+ mr->subdiv_pos=158*sizeof(struct subdivision);
+ mr->subdiv_level_count=4190;
+ shift=2;
+ subdiv_next=14;
+ }
+
+#if 0
+ mr->rgn_offset=triple_u(&mr->subdiv[mr->subdiv_current].rgn_offset)+mr->rgn_hdr->offset_len.offset+4;
+ mr->rgn_type=1;
+ mr->rgn_end=mr->rgn_offset+20*8;
+#endif
+ mr->count=0;
+ item_count=0;
+
+#if 0
+ printf("*** offset 0x%x\n", 0x656c-mr->rgn.offset);
+ printf("*** offset 0x%x\n", mr->rgn_offset);
+#endif
+#if 1
+ sub_next(mr, 0);
+#endif
+#if 0
+ {
+ struct rgn_point *pnt;
+ int i;
+ int offset=0x65cc;
+ for (i = 0 ; i < 26 ; i++) {
+ pnt=file_read(&mr->rgn, 0x656c+8*i-mr->rgn.offset, sizeof(*pnt));
+ // dump_hex(pnt, sizeof(*pnt));
+ dump_point(pnt);
+ dump_label_offset(mr, triple_u(&pnt->lbl_offset));
+ }
+ }
+ exit(0);
+#endif
+#if 0
+ dump_tree(&mr->tre,&mr->rgn,mr);
+#endif
+
+#if 0
+ f.offset=0x64a*2048;
+ f.f=mr->f;
+ dump_labels(&f);
+#endif
+#if 0
+ fseek(mr->f, img.file_offset, SEEK_SET);
+ fread(&fil, sizeof(fil), 1, mr->f);
+ dump_file(&fil);
+ fread(&rgn, sizeof(rgn), 1, mr->f);
+ dump_region(&rgn);
+ fseek(mr->f, rgn.data_length, SEEK_CUR);
+ fread(&fil, sizeof(fil), 1, mr->f);
+ dump_file(&fil);
+#endif
+ return mr;
+}
+
+
+static void
+map_rect_destroy_garmin_img(struct map_rect_priv *mr)
+{
+ fclose(mr->f);
+ g_free(mr);
+}
+
+
+static struct item *
+map_rect_get_item_garmin_img(struct map_rect_priv *mr)
+{
+ char *p,type[256];
+ int ptype;
+ int debug=0;
+
+ item_count++;
+
+ if (debug)
+ printf("map_rect_get_item_garmin_img\n");
+ for (;;) {
+ if (mr->rgn_offset < mr->rgn_end) {
+ if (debug)
+ printf("data available\n");
+ if (mr->rgn_type >= 2) {
+ int len;
+ if (debug)
+ printf("polyline %d\n", mr->count);
+ if (mr->ply)
+ file_free(mr->ply);
+ mr->ply=file_read(&mr->rgn, mr->rgn_offset, sizeof(*mr->ply)*3);
+ if(triple_u(&mr->ply->lbl_offset) >= mr->lbl_hdr->label.offset_len.length) {
+ printf("item_count %d\n", item_count);
+ dump_poly(mr->ply);
+ dump_hex(mr->ply, 32);
+ printf("%d vs %d\n", triple_u(&mr->ply->lbl_offset), mr->lbl_hdr->label.offset_len.length);
+ }
+ g_assert(triple_u(&mr->ply->lbl_offset) < mr->lbl_hdr->label.offset_len.length);
+ if (debug) {
+ dump_hex(mr->ply, 16);
+ dump_poly(mr->ply);
+ }
+ if (mr->ply_data)
+ file_free(mr->ply_data);
+ mr->rgn_offset+=10;
+ if (mr->ply->info & 0x80) {
+ mr->rgn_offset++;
+ len=mr->ply->u.p2.bitstream_len;
+ } else
+ len=mr->ply->u.p1.bitstream_len;
+
+ mr->ply_data=file_read(&mr->rgn, mr->rgn_offset, len);
+ mr->rgn_offset += len;
+ mr->ply_bitpos=0;
+ // dump_hex(mr->ply_data, 32);
+ if (mr->rgn_type == 3) {
+ switch(mr->ply->info & 0x7f) {
+ case 0x1: /* large urban area (>200k) */
+ mr->item.type=type_town_poly;
+ break;
+ case 0xd: /* reservation */
+ mr->item.type=type_park_poly;
+ break;
+ case 0xe: /* airport runway */
+ mr->item.type=type_airport_poly;
+ break;
+ case 0x14: /* national park */
+ mr->item.type=type_park_poly;
+ break;
+ case 0x32: /* sea */
+ case 0x3d: /* large lake (77-250km2) */
+ case 0x4c: /* intermittend water */
+ mr->item.type=type_water_poly;
+ break;
+ case 0x4b: /* background */
+ continue;
+ default:
+ printf("unknown polygon: 0x%x\n", mr->ply->info);
+ mr->item.type=type_street_3_city;
+ }
+ } else {
+ switch(mr->ply->info & 0x3f) {
+ case 0x1: /* major highway */
+ mr->item.type=type_highway_land;
+ break;
+ case 0x2: /* principal highway */
+ mr->item.type=type_street_3_land;
+ break;
+ case 0x6: /* residental street */
+ mr->item.type=type_street_2_land;
+ break;
+ case 0x16: /* walkway/trail */
+ mr->item.type=type_street_1_land;
+ break;
+ case 0x1e: /* international boundary */
+ mr->item.type=type_border_country;
+ break;
+ case 0x20: /* minor land contour 1/10 */
+ mr->item.type=type_height_line_1;
+ break;
+ case 0x21: /* major land contour 1/2 */
+ mr->item.type=type_height_line_2;
+ break;
+ default:
+ printf("unknown polyline: 0x%x\n", mr->ply->info);
+ mr->item.type=type_street_3_city;
+ }
+ }
+ return &mr->item;
+ }
+ if (mr->pnt)
+ file_free(mr->pnt);
+ mr->pnt=file_read(&mr->rgn, mr->rgn_offset, sizeof(*mr->pnt));
+ mr->item.type=type_none;
+ int subtype=mr->pnt->subtype;
+ if (mr->pnt->lbl_offset.data[2] & 0x80)
+ mr->rgn_offset+=9;
+ else {
+ mr->rgn_offset+=8;
+ subtype=0;
+ }
+ switch(mr->pnt->info) {
+ case 0x3: /* large city 2-5M */
+ mr->item.type=type_town_label_2e6;
+ break;
+ case 0xa: /* small city/town 10-20k */
+ mr->item.type=type_town_label_1e4;
+ break;
+ case 0xd: /* settlement 1-2K */
+ mr->item.type=type_town_label_1e3;
+ break;
+ case 0x11: /* settlement less 100 */
+ mr->item.type=type_town_label_5e1;
+ break;
+ case 0x1c:
+ switch(subtype) {
+ case 0x01:
+ mr->item.type=type_poi_wreck;
+ break;
+ }
+ break;
+ case 0x20:
+ mr->item.type=type_highway_exit;
+ break;
+ case 0x25:
+ mr->item.type=type_poi_toll_booth;
+ break;
+ case 0x2b:
+ switch(subtype) {
+ case 0x01:
+ mr->item.type=type_poi_hotel;
+ break;
+ case 0x03:
+ mr->item.type=type_poi_camp_rv;
+ break;
+ }
+ break;
+ case 0x2c:
+ switch(subtype) {
+ case 0x00:
+ mr->item.type=type_poi_attraction;
+ break;
+ case 0x02:
+ mr->item.type=type_poi_museum_history;
+ break;
+ }
+ break;
+ case 0x2e:
+ mr->item.type=type_poi_shopping;
+ break;
+ case 0x2f:
+ switch(subtype) {
+ case 0x01:
+ mr->item.type=type_poi_fuel;
+ break;
+ case 0x07:
+ mr->item.type=type_poi_car_dealer_parts;
+ break;
+ case 0x0b:
+ mr->item.type=type_poi_car_parking;
+ break;
+ case 0x15:
+ mr->item.type=type_poi_public_utilities;
+ break;
+ }
+ break;
+ case 0x30:
+ switch(subtype) {
+ case 0x02:
+ mr->item.type=type_poi_hospital;
+ break;
+ }
+ break;
+ case 0x43:
+ mr->item.type=type_poi_marina;
+ break;
+ case 0x46:
+ mr->item.type=type_poi_bar;
+ break;
+ case 0x48:
+ mr->item.type=type_poi_camping;
+ break;
+ case 0x49:
+ mr->item.type=type_poi_park;
+ break;
+ case 0x4a:
+ mr->item.type=type_poi_picnic;
+ break;
+ case 0x59: /* airport */
+ mr->item.type=type_poi_airport;
+ break;
+ case 0x64:
+ switch(subtype) {
+ case 0x1:
+ mr->item.type=type_poi_bridge;
+ break;
+ case 0x2:
+ mr->item.type=type_poi_building;
+ break;
+ case 0x15:
+ mr->item.type=type_town_ghost;
+ break;
+ }
+ break;
+ case 0x65:
+ switch(subtype) {
+ case 0x0:
+ mr->item.type=type_poi_water_feature;
+ break;
+ case 0xc:
+ mr->item.type=type_poi_island;
+ break;
+ case 0xd:
+ mr->item.type=type_poi_lake;
+ break;
+ }
+ break;
+ case 0x66:
+ switch(subtype) {
+ case 0x0:
+ mr->item.type=type_poi_land_feature;
+ break;
+ case 0x6:
+ mr->item.type=type_poi_cape;
+ break;
+ case 0x14:
+ mr->item.type=type_poi_rock;
+ break;
+ }
+ break;
+ }
+ if (mr->item.type == type_none) {
+ printf("unknown point: 0x%x 0x%x\n", mr->pnt->info, mr->pnt->subtype);
+ dump_point(mr->pnt);
+ printf("label: %s\n", get_label_offset(mr, triple_u(&mr->pnt->lbl_offset) & 0x3fffff));
+ mr->item.type=type_town_label;
+ }
+ return &mr->item;
+ }
+ if (debug)
+ printf("out of data for type\n");
+ if (rgn_next_type(mr)) {
+ if (debug)
+ printf("out of data for region\n");
+ if (sub_next(mr, subdiv_next)) {
+ if (debug)
+ printf("out of data for subdivision\n");
+ return NULL;
+ }
+ }
+ }
+}
+
+static struct item *
+map_rect_get_item_byid_garmin_img(struct map_rect_priv *mr, int id_hi, int id_lo)
+{
+ fseek(mr->f, id_lo, SEEK_SET);
+ get_line(mr);
+ mr->item.id_hi=id_hi;
+ return map_rect_get_item_garmin_img(mr);
+}
+
+static struct map_methods map_methods_garmin_img = {
+ projection_garmin,
+ "iso8859-1",
+ map_destroy_garmin_img,
+ map_charset_garmin_img,
+ map_projection_garmin_img,
+ map_rect_new_garmin_img,
+ map_rect_destroy_garmin_img,
+ map_rect_get_item_garmin_img,
+ map_rect_get_item_byid_garmin_img,
+};
+
+static struct map_priv *
+map_new_garmin_img(struct map_methods *meth, struct attr **attrs)
+{
+ struct map_priv *m;
+ struct attr *data=attr_search(attrs, NULL, attr_data);
+ if (! data)
+ return NULL;
+
+ *meth=map_methods_garmin_img;
+ m=g_new(struct map_priv, 1);
+ m->id=++map_id;
+ m->filename=g_strdup(data->u.str);
+ return m;
+}
+
+void
+plugin_init(void)
+{
+ plugin_register_map_type("garmin_img", map_new_garmin_img);
+}
+
diff --git a/navit/data/mg/Makefile.am b/navit/data/mg/Makefile.am
new file mode 100644
index 000000000..04d92b056
--- /dev/null
+++ b/navit/data/mg/Makefile.am
@@ -0,0 +1,4 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=data_mg
+moduledata_LTLIBRARIES = libdata_mg.la
+libdata_mg_la_SOURCES = map.c block.c town.c tree.c poly.c street.c mg.h
diff --git a/navit/data/mg/block.c b/navit/data/mg/block.c
new file mode 100644
index 000000000..08e9410e0
--- /dev/null
+++ b/navit/data/mg/block.c
@@ -0,0 +1,267 @@
+#include <stdio.h>
+#include <string.h>
+#include "debug.h"
+#include "mg.h"
+
+
+int block_lin_count,block_idx_count,block_active_count,block_mem,block_active_mem;
+
+struct block_index_item {
+ unsigned int blocknum;
+ unsigned int blocks;
+};
+
+struct block_index {
+ unsigned int blocks;
+ unsigned int size;
+ unsigned int next;
+ struct block_index_item list[0];
+};
+
+static struct block *
+block_get(unsigned char **p)
+{
+ struct block *ret=(struct block *)(*p);
+ *p += sizeof(*ret);
+ return ret;
+}
+
+
+static struct block *
+block_get_byid(struct file *file, int id, unsigned char **p_ret)
+{
+ struct block_index *blk_idx;
+ int blk_num,max;
+
+
+ blk_idx=(struct block_index *)(file->begin+0x1000);
+ max=(blk_idx->size-sizeof(struct block_index))/sizeof(struct block_index_item);
+ block_mem+=24;
+ while (id >= max) {
+ blk_idx=(struct block_index *)(file->begin+blk_idx->next*512);
+ id-=max;
+ }
+ blk_num=blk_idx->list[id].blocknum;
+
+ *p_ret=file->begin+blk_num*512;
+ return block_get(p_ret);
+}
+
+int
+block_get_byindex(struct file *file, int idx, struct block_priv *blk)
+{
+ dbg(1,"idx=%d\n", idx);
+ blk->b=block_get_byid(file, idx, &blk->p);
+ blk->block_start=(unsigned char *)(blk->b);
+ blk->p_start=blk->p;
+ blk->end=blk->block_start+blk->b->size;
+
+ return 1;
+}
+
+static void
+block_setup_tags(struct map_rect_priv *mr)
+{
+ int len;
+ unsigned char *p,*t;
+ char *str;
+
+ mr->b.binarytree=0;
+
+ p=mr->file->begin+0x0c;
+ while (*p) {
+ str=get_string(&p);
+ len=get_u32_unal(&p);
+ t=p;
+ /* printf("String '%s' len %d\n", str, len); */
+ if (! strcmp(str,"FirstBatBlock")) {
+ /* printf("%ld\n", get_u32_unal(&t)); */
+ } else if (! strcmp(str,"MaxBlockSize")) {
+ /* printf("%ld\n", get_u32_unal(&t)); */
+ } else if (! strcmp(str,"FREE_BLOCK_LIST")) {
+ /* printf("%ld\n", get_u32_unal(&t)); */
+ } else if (! strcmp(str,"TotalRect")) {
+ mr->b.b_rect.lu.x=get_u32_unal(&t);
+ mr->b.b_rect.lu.y=get_u32_unal(&t);
+ mr->b.b_rect.rl.x=get_u32_unal(&t);
+ mr->b.b_rect.rl.y=get_u32_unal(&t);
+ /* printf("0x%x,0x%x-0x%x,0x%x\n", mr->b.b_rect.lu.x, mr->b.b_rect.lu.y, mr->b.b_rect.rl.x, mr->b.b_rect.rl.y); */
+ } else if (! strcmp(str,"Version")) {
+ /* printf("0x%lx\n", get_u32_unal(&t)); */
+ } else if (! strcmp(str,"Categories")) {
+ /* printf("0x%x\n", get_u16(&t)); */
+ } else if (! strcmp(str,"binaryTree")) {
+ mr->b.binarytree=get_u32_unal(&t);
+ /* printf("%d\n", mr->b.binarytree); */
+ } else if (! strcmp(str,"CategorySets")) {
+ /* printf("0x%x\n", get_u16(&t)); */
+ } else if (! strcmp(str,"Kommentar")) {
+ /* printf("%s\n", get_string(&t)); */
+ }
+ p+=len;
+ }
+}
+
+#if 0
+static void
+block_rect_print(struct coord_rect *r)
+{
+ printf ("0x%x,0x%x-0x%x,0x%x (0x%x,0x%x)", r->lu.x, r->lu.y, r->rl.x, r->rl.y, r->lu.x/2+r->rl.x/2,r->lu.y/2+r->rl.y/2);
+}
+#endif
+
+static void
+block_rect_same(struct coord_rect *r1, struct coord_rect *r2)
+{
+ g_assert(r1->lu.x==r2->lu.x);
+ g_assert(r1->lu.y==r2->lu.y);
+ g_assert(r1->rl.x==r2->rl.x);
+ g_assert(r1->rl.y==r2->rl.y);
+}
+
+int
+block_init(struct map_rect_priv *mr)
+{
+ mr->b.block_num=-1;
+ mr->b.bt.b=NULL;
+ mr->b.bt.next=0;
+ block_setup_tags(mr);
+ if (mr->b.binarytree) {
+ mr->b.bt.next=mr->b.binarytree;
+ mr->b.bt.p=NULL;
+ mr->b.bt.block_count=0;
+ }
+ if (mr->cur_sel && !coord_rect_overlap(&mr->cur_sel->u.c_rect, &mr->b.b_rect))
+ return 0;
+ return block_next(mr);
+}
+
+
+int
+block_next_lin(struct map_rect_priv *mr)
+{
+ for (;;) {
+ block_lin_count++;
+ block_mem+=sizeof(struct block *);
+ mr->b.block_num++;
+ if (! mr->b.block_num)
+ mr->b.p=mr->file->begin+0x2000;
+ else
+ mr->b.p=mr->b.block_start+mr->b.b->blocks*512;
+ if (mr->b.p >= mr->file->end) {
+ dbg(1,"end of blocks %p vs %p\n", mr->b.p, mr->file->end);
+ return 0;
+ }
+ mr->b.block_start=mr->b.p;
+ mr->b.b=block_get(&mr->b.p);
+ mr->b.p_start=mr->b.p;
+ mr->b.end=mr->b.block_start+mr->b.b->size;
+ if (mr->b.b->count == -1) {
+ dbg(1,"empty blocks\n");
+ return 0;
+ }
+ if (!mr->cur_sel || coord_rect_overlap(&mr->cur_sel->u.c_rect, &mr->b.b->r)) {
+ block_active_count++;
+ block_active_mem+=mr->b.b->blocks*512-sizeof(struct block *);
+ dbg(1,"block ok\n");
+ return 1;
+ }
+ dbg(2,"block not in cur_sel\n");
+ }
+}
+
+int
+block_next(struct map_rect_priv *mr)
+{
+ int blk_num,coord,r_h,r_w;
+ struct block_bt_priv *bt=&mr->b.bt;
+
+ if (!mr->b.binarytree || ! mr->cur_sel)
+ return block_next_lin(mr);
+ for (;;) {
+ if (! bt->p) {
+ dbg(1,"block 0x%x\n", bt->next);
+ if (bt->next == -1)
+ return 0;
+ bt->b=block_get_byid(mr->file, bt->next, &bt->p);
+ bt->end=(unsigned char *)mr->b.bt.b+mr->b.bt.b->size;
+ bt->next=bt->b->next;
+ bt->order=0;
+ dbg(1,"size 0x%x next 0x%x\n", bt->b->size, bt->b->next);
+ if (! mr->b.bt.block_count) {
+#if 0
+ if (debug) {
+ printf("idx rect ");
+ block_rect_print(&mr->b.bt.b->r);
+ }
+#endif
+ bt->r=bt->b->r;
+ bt->r_curr=bt->r;
+ coord=get_u32(&mr->b.bt.p);
+ } else {
+ bt->p=(unsigned char *)bt->b+0xc;
+ }
+ bt->block_count++;
+ }
+ while (mr->b.bt.p < mr->b.bt.end) {
+ block_idx_count++;
+ blk_num=get_u32(&mr->b.bt.p);
+ coord=get_u32(&mr->b.bt.p);
+ block_mem+=8;
+ dbg(1,"%p vs %p coord 0x%x ", mr->b.bt.end, mr->b.bt.p, coord);
+ dbg(1,"block 0x%x", blk_num);
+
+ r_w=bt->r_curr.rl.x-bt->r_curr.lu.x;
+ r_h=bt->r_curr.lu.y-bt->r_curr.rl.y;
+#if 0
+ if (debug) {
+ printf(" rect1 ");
+ block_rect_print(&bt->r_curr);
+ printf(" %dx%d", r_w, r_h);
+ }
+#endif
+ mr->b.b=NULL;
+ if (blk_num != -1) {
+ block_mem+=8;
+ if (coord_rect_overlap(&mr->cur_sel->u.c_rect, &bt->r_curr)) {
+ mr->b.b=block_get_byid(mr->file, blk_num, &mr->b.p);
+ mr->b.block_num=blk_num;
+ g_assert(mr->b.b != NULL);
+ mr->b.block_start=(unsigned char *)(mr->b.b);
+ mr->b.p_start=mr->b.p;
+ mr->b.end=mr->b.block_start+mr->b.b->size;
+ block_rect_same(&mr->b.b->r, &bt->r_curr);
+ }
+ }
+ if (coord != -1) {
+ bt->stack[bt->stackp]=bt->r_curr;
+ if (r_w > r_h) {
+ bt->r_curr.rl.x=coord;
+ bt->stack[bt->stackp].lu.x=coord+1;
+ } else {
+ bt->r_curr.lu.y=coord;
+ bt->stack[bt->stackp].rl.y=coord+1;
+ }
+ bt->stackp++;
+ g_assert(bt->stackp < BT_STACK_SIZE);
+ } else {
+ if (bt->stackp) {
+ bt->stackp--;
+ bt->r_curr=bt->stack[bt->stackp];
+ } else {
+ bt->r_curr=bt->r;
+ bt->order++;
+ if (bt->order > 100)
+ return 0;
+ }
+ }
+ if (mr->b.b) {
+ block_active_count++;
+ block_active_mem+=mr->b.b->blocks*512;
+ return 1;
+ }
+ }
+ bt->p=NULL;
+ }
+ return 0;
+}
diff --git a/navit/data/mg/map.c b/navit/data/mg/map.c
new file mode 100644
index 000000000..843516d8c
--- /dev/null
+++ b/navit/data/mg/map.c
@@ -0,0 +1,466 @@
+#include <stdio.h>
+#include <string.h>
+#include "config.h"
+#include "debug.h"
+#include "plugin.h"
+#include "maptype.h"
+#include "mg.h"
+
+
+static struct country_isonum {
+ int country;
+ int isonum;
+ int postal_len;
+ char *postal_prefix;
+} country_isonums[]={
+ { 1,203},
+ { 2,703},
+ { 7,674},
+ { 11,233},
+ { 12,268},
+ { 13,428},
+ { 14,440},
+ { 15,498},
+ { 16,643},
+ { 17,804},
+ { 18,112},
+ { 20,818},
+ { 30,300},
+ { 31,528},
+ { 32, 56},
+ { 33,250},
+ { 34,724},
+ { 36,348},
+ { 39,380},
+ { 40,642},
+ { 41,756},
+ { 43, 40},
+ { 44,826},
+ { 45,208},
+ { 46,752},
+ { 47,578},
+ { 48,616},
+ { 49,276,5,"D@@"},
+ { 50,292},
+ { 51,620},
+ { 52,442},
+ { 53,372},
+ { 54,352},
+ { 55, 8},
+ { 56,470},
+ { 57,196},
+ { 58,246},
+ { 59,100},
+ { 61,422},
+ { 62, 20},
+ { 63,760},
+ { 66,682},
+ { 71,434},
+ { 72,376},
+ { 73,275},
+ { 75,438},
+ { 76,504},
+ { 77, 12},
+ { 78,788},
+ { 81,688},
+ { 83,400},
+ { 85,191},
+ { 86,705},
+ { 87, 70},
+ { 89,807},
+ { 90,792},
+ { 93,492},
+ { 94, 31},
+ { 95, 51},
+ { 98,234},
+ { 99,732},
+ {336,774},
+};
+
+struct map_priv * map_new_mg(struct map_methods *meth, struct attr **attrs);
+
+static int map_id;
+
+static char *file[]={
+ [file_border_ply]="border.ply",
+ [file_bridge_ply]="bridge.ply",
+ [file_build_ply]="build.ply",
+ [file_golf_ply]="golf.ply",
+ [file_height_ply]="height.ply",
+ [file_natpark_ply]="natpark.ply",
+ [file_nature_ply]="nature.ply",
+ [file_other_ply]="other.ply",
+ [file_rail_ply]="rail.ply",
+ [file_sea_ply]="sea.ply",
+ [file_street_bti]="street.bti",
+ [file_street_str]="street.str",
+ [file_strname_stn]="strname.stn",
+ [file_town_twn]="town.twn",
+ [file_tunnel_ply]="tunnel.ply",
+ [file_water_ply]="water.ply",
+ [file_woodland_ply]="woodland.ply",
+};
+
+int mg_country_from_isonum(int isonum)
+{
+ int i;
+ for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++)
+ if (country_isonums[i].isonum == isonum)
+ return country_isonums[i].country;
+ return 0;
+}
+
+int mg_country_to_isonum(int country)
+{
+ int i;
+ for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++)
+ if (country_isonums[i].country == country)
+ return country_isonums[i].isonum;
+ return 0;
+}
+
+int mg_country_postal_len(int country)
+{
+ int i;
+ for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++)
+ if (country_isonums[i].country == country)
+ return country_isonums[i].postal_len;
+ return 0;
+}
+
+static char *mg_country_postal_prefix(int isonum)
+{
+ int i;
+ for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++)
+ if (country_isonums[i].isonum == isonum)
+ return country_isonums[i].postal_prefix;
+ return NULL;
+}
+
+static int
+file_next(struct map_rect_priv *mr)
+{
+ int debug=0;
+ enum layer_type layer;
+
+ for (;;) {
+ mr->current_file++;
+ if (mr->current_file >= file_end)
+ return 0;
+ mr->file=mr->m->file[mr->current_file];
+ if (! mr->file)
+ continue;
+ switch (mr->current_file) {
+ case file_strname_stn:
+ continue;
+ case file_town_twn:
+ layer=layer_town;
+ break;
+ case file_street_str:
+ layer=layer_street;
+ break;
+ default:
+ layer=layer_poly;
+ }
+ if (mr->cur_sel && !mr->cur_sel->order[layer])
+ continue;
+ if (debug)
+ printf("current file: '%s'\n", file[mr->current_file]);
+ mr->cur_sel=mr->xsel;
+ if (block_init(mr))
+ return 1;
+ }
+}
+
+static void
+map_destroy_mg(struct map_priv *m)
+{
+ int i;
+
+ printf("mg_map_destroy\n");
+ for (i = 0 ; i < file_end ; i++) {
+ if (m->file[i])
+ file_destroy(m->file[i]);
+ }
+}
+
+extern int block_lin_count,block_idx_count,block_active_count,block_mem,block_active_mem;
+
+static struct map_rect_priv *
+map_rect_new_mg(struct map_priv *map, struct map_selection *sel)
+{
+ struct map_rect_priv *mr;
+ int i;
+
+ block_lin_count=0;
+ block_idx_count=0;
+ block_active_count=0;
+ block_mem=0;
+ block_active_mem=0;
+ mr=g_new0(struct map_rect_priv, 1);
+ mr->m=map;
+ mr->xsel=sel;
+ mr->current_file=-1;
+ if (sel && sel->next)
+ for (i=0 ; i < file_end ; i++)
+ mr->block_hash[i]=g_hash_table_new(g_int_hash,g_int_equal);
+
+ file_next(mr);
+ return mr;
+}
+
+
+static struct item *
+map_rect_get_item_mg(struct map_rect_priv *mr)
+{
+ for (;;) {
+ switch (mr->current_file) {
+ case file_town_twn:
+ if (town_get(mr, &mr->town, &mr->item))
+ return &mr->item;
+ break;
+ case file_border_ply:
+ case file_bridge_ply:
+ case file_build_ply:
+ case file_golf_ply:
+ /* case file_height_ply: */
+ case file_natpark_ply:
+ case file_nature_ply:
+ case file_other_ply:
+ case file_rail_ply:
+ case file_sea_ply:
+ /* case file_tunnel_ply: */
+ case file_water_ply:
+ case file_woodland_ply:
+ if (poly_get(mr, &mr->poly, &mr->item))
+ return &mr->item;
+ break;
+ case file_street_str:
+ if (street_get(mr, &mr->street, &mr->item))
+ return &mr->item;
+ break;
+ case file_end:
+ return NULL;
+ default:
+ break;
+ }
+ if (block_next(mr))
+ continue;
+ if (mr->cur_sel->next) {
+ mr->cur_sel=mr->cur_sel->next;
+ if (block_init(mr))
+ continue;
+ }
+ if (file_next(mr))
+ continue;
+ dbg(1,"lin_count %d idx_count %d active_count %d %d kB (%d kB)\n", block_lin_count, block_idx_count, block_active_count, (block_mem+block_active_mem)/1024, block_active_mem/1024);
+ return NULL;
+ }
+}
+
+static struct item *
+map_rect_get_item_byid_mg(struct map_rect_priv *mr, int id_hi, int id_lo)
+{
+ mr->current_file = id_hi >> 16;
+ switch (mr->current_file) {
+ case file_town_twn:
+ if (town_get_byid(mr, &mr->town, id_hi, id_lo, &mr->item))
+ return &mr->item;
+ break;
+ case file_street_str:
+ if (street_get_byid(mr, &mr->street, id_hi, id_lo, &mr->item))
+ return &mr->item;
+ break;
+ default:
+ if (poly_get_byid(mr, &mr->poly, id_hi, id_lo, &mr->item))
+ return &mr->item;
+ break;
+ }
+ return NULL;
+}
+
+
+static void
+map_rect_destroy_mg(struct map_rect_priv *mr)
+{
+ int i;
+ for (i=0 ; i < file_end ; i++)
+ if (mr->block_hash[i])
+ g_hash_table_destroy(mr->block_hash[i]);
+ g_free(mr);
+}
+
+static char *
+map_search_mg_convert_special(char *str)
+{
+ char *ret,*c=g_malloc(strlen(str)*2+1);
+
+ ret=c;
+ for (;;) {
+ switch ((unsigned char)(*str)) {
+ case 0xc4:
+ *c++='A';
+ break;
+ case 0xd6:
+ *c++='O';
+ break;
+ case 0xdc:
+ *c++='U';
+ break;
+ case 0xdf:
+ *c++='s';
+ *c++='s';
+ break;
+ case 0xe4:
+ *c++='a';
+ break;
+ case 0xf6:
+ *c++='o';
+ break;
+ case 0xfc:
+ *c++='u';
+ break;
+ default:
+ dbg(1,"0x%x\n", *str);
+ *c++=*str;
+ break;
+ }
+ if (! *str)
+ return ret;
+ str++;
+ }
+}
+
+
+static struct map_search_priv *
+map_search_new_mg(struct map_priv *map, struct item *item, struct attr *search, int partial)
+{
+ struct map_rect_priv *mr=g_new0(struct map_rect_priv, 1);
+ char *prefix;
+ dbg(1,"id_lo=0x%x\n", item->id_lo);
+ dbg(1,"search=%s\n", search->u.str);
+ mr->m=map;
+ mr->search_type=search->type;
+ switch (search->type) {
+ case attr_town_postal:
+ if (item->type != type_country_label)
+ return NULL;
+ prefix=mg_country_postal_prefix(item->id_lo);
+ if (! prefix)
+ return NULL;
+ tree_search_init(map->dirname, "town.b1", &mr->ts, 0);
+ mr->current_file=file_town_twn;
+ mr->search_str=g_strdup_printf("%s%s",prefix,search->u.str);
+ dbg(0,"search_str='%s'\n",mr->search_str);
+ mr->search_country=mg_country_from_isonum(item->id_lo);
+ break;
+ case attr_town_name:
+ if (item->type != type_country_label)
+ return NULL;
+ tree_search_init(map->dirname, "town.b2", &mr->ts, 0x1000);
+ mr->current_file=file_town_twn;
+ mr->search_str=map_search_mg_convert_special(search->u.str);
+ mr->search_country=mg_country_from_isonum(item->id_lo);
+ break;
+ case attr_street_name:
+ if (item->type != type_town_streets)
+ return NULL;
+ dbg(1,"street_assoc=0x%x\n", item->id_lo);
+ tree_search_init(map->dirname, "strname.b1", &mr->ts, 0);
+ mr->current_file=file_strname_stn;
+ mr->search_str=g_strdup(search->u.str);
+ break;
+ default:
+ dbg(0,"unknown search\n");
+ g_free(mr);
+ return NULL;
+ }
+ mr->search_item=*item;
+ mr->search_partial=partial;
+ mr->file=mr->m->file[mr->current_file];
+ block_init(mr);
+ return (struct map_search_priv *)mr;
+}
+
+static void
+map_search_destroy_mg(struct map_search_priv *ms)
+{
+ struct map_rect_priv *mr=(struct map_rect_priv *)ms;
+
+ dbg(1,"mr=%p\n", mr);
+ if (! mr)
+ return;
+ g_free(mr->search_str);
+ tree_search_free(&mr->ts);
+ g_free(mr);
+}
+
+static struct item *
+map_search_get_item_mg(struct map_search_priv *ms)
+{
+ struct map_rect_priv *mr=(struct map_rect_priv *)ms;
+
+ if (! mr)
+ return NULL;
+ switch (mr->search_type) {
+ case attr_town_postal:
+ case attr_town_name:
+ return town_search_get_item(mr);
+ case attr_street_name:
+ return street_search_get_item(mr);
+ default:
+ return NULL;
+ }
+}
+
+static struct map_methods map_methods_mg = {
+ projection_mg,
+ "iso8859-1",
+ map_destroy_mg,
+ map_rect_new_mg,
+ map_rect_destroy_mg,
+ map_rect_get_item_mg,
+ map_rect_get_item_byid_mg,
+ map_search_new_mg,
+ map_search_destroy_mg,
+ map_search_get_item_mg,
+};
+
+struct map_priv *
+map_new_mg(struct map_methods *meth, struct attr **attrs)
+{
+ struct map_priv *m;
+ int i,maybe_missing;
+ struct attr *data;
+ char *filename;
+
+ *meth=map_methods_mg;
+ data=attr_search(attrs, NULL, attr_data);
+ if (! data)
+ return NULL;
+
+ m=g_new(struct map_priv, 1);
+ m->id=++map_id;
+ m->dirname=g_strdup(data->u.str);
+ for (i = 0 ; i < file_end ; i++) {
+ if (file[i]) {
+ filename=g_strdup_printf("%s/%s", data->u.str, file[i]);
+ m->file[i]=file_create_caseinsensitive(filename);
+ if (! m->file[i]) {
+ maybe_missing=(i == file_border_ply || i == file_height_ply || i == file_sea_ply);
+ if (! maybe_missing)
+ g_warning("Failed to load %s", filename);
+ } else
+ file_mmap(m->file[i]);
+ g_free(filename);
+ }
+ }
+
+ return m;
+}
+
+void
+plugin_init(void)
+{
+ plugin_register_map_type("mg", map_new_mg);
+}
diff --git a/navit/data/mg/mg.h b/navit/data/mg/mg.h
new file mode 100644
index 000000000..2600e3ce5
--- /dev/null
+++ b/navit/data/mg/mg.h
@@ -0,0 +1,295 @@
+#include <glib.h>
+#include "item.h"
+#include "attr.h"
+#include "coord.h"
+#include "data.h"
+#include "projection.h"
+#include "map.h"
+#include "file.h"
+
+struct block_data {
+ struct file *file;
+};
+
+struct block {
+ int blocks;
+ int size;
+ int next;
+ struct coord_rect r;
+ int count;
+};
+
+struct item_priv {
+ int cidx;
+ int aidx;
+ unsigned char *cstart,*cp,*cend;
+ unsigned char *astart,*ap,*aend;
+ enum attr_type attr_last;
+ enum attr_type attr_next;
+ struct item item;
+};
+
+struct town_priv {
+ unsigned int id; /*!< Identifier */
+ struct coord c; /*!< Coordinates */
+ char *name; /*!< Name */
+ char *district; /*!< District */
+ char *postal_code1; /*!< Postal code */
+ unsigned char order; /*!< Order (Importance) */
+ unsigned char type; /*!< Type */
+ unsigned short country; /*!< Country */
+ unsigned int unknown2; /*!< Unknown */
+ unsigned char size; /*!< Size of town */
+ unsigned int street_assoc; /*!< Association to streets */
+ unsigned char unknown3; /*!< Unknown */
+ char *postal_code2; /*!< 2nd postal code */
+ unsigned int unknown4; /*!< Unknown */
+
+ int cidx;
+ int aidx;
+ enum attr_type attr_next;
+ char debug[256];
+ char postal[32];
+ struct item town_attr_item;
+};
+
+struct poly_priv {
+ int poly_num;
+ unsigned char *poly_next;
+ int subpoly_num;
+ int subpoly_num_all;
+ unsigned char *subpoly_next;
+ unsigned char *subpoly_start;
+ unsigned char *p;
+ struct coord c[2];
+ char *name;
+ unsigned char order;
+ unsigned char type;
+ unsigned int polys;
+ unsigned int *count;
+ unsigned int count_sum;
+
+ int aidx;
+ enum attr_type attr_next;
+};
+
+struct street_header {
+ unsigned char order;
+ int count;
+} __attribute__((packed));
+
+struct street_type {
+ unsigned char order;
+ unsigned short country;
+} __attribute__((packed));
+
+struct street_header_type {
+ struct street_header *header;
+ int type_count;
+ struct street_type *type;
+};
+
+struct street_str {
+ int segid;
+ unsigned char limit; /* 0x03,0x30=One Way,0x33=No Passing */
+ unsigned char unknown2;
+ unsigned char unknown3;
+ unsigned char type;
+ unsigned int nameid;
+};
+
+struct street_name_segment {
+ int segid;
+ int country;
+};
+
+struct street_name {
+ int len;
+ int country;
+ int townassoc;
+ char *name1;
+ char *name2;
+ int segment_count;
+ struct street_name_segment *segments;
+ int aux_len;
+ unsigned char *aux_data;
+ int tmp_len;
+ unsigned char *tmp_data;
+};
+
+struct street_name_numbers {
+ int len;
+ int tag;
+ int dist;
+ int country;
+ struct coord *c;
+ int first;
+ int last;
+ int segment_count;
+ struct street_name_segment *segments;
+ int aux_len;
+ unsigned char *aux_data;
+ int tmp_len;
+ unsigned char *tmp_data;
+};
+
+struct street_name_number {
+ int len;
+ int tag;
+ struct coord *c;
+ int first;
+ int last;
+ struct street_name_segment *segment;
+};
+
+
+
+struct street_priv {
+ struct file *name_file;
+ struct street_header *header;
+ int type_count;
+ struct street_type *type;
+ struct street_str *str;
+ struct street_str *str_start;
+ unsigned char *coord_begin;
+ unsigned char *p;
+ unsigned char *p_rewind;
+ unsigned char *end;
+ unsigned char *next;
+ int status;
+ int status_rewind;
+ struct coord *ref;
+ int bytes;
+ int more;
+ struct street_name name;
+ enum attr_type attr_next;
+ char debug[256];
+};
+
+enum file_index {
+ file_border_ply=0,
+ file_bridge_ply,
+ file_build_ply,
+ file_golf_ply,
+ file_height_ply,
+ file_natpark_ply,
+ file_nature_ply,
+ file_other_ply,
+ file_rail_ply,
+ file_sea_ply,
+ file_street_bti,
+ file_street_str,
+ file_strname_stn,
+ file_town_twn,
+ file_tunnel_ply,
+ file_water_ply,
+ file_woodland_ply,
+ file_end
+};
+
+struct map_priv {
+ int id;
+ struct file *file[file_end];
+ char *dirname;
+};
+
+#define BT_STACK_SIZE 32
+
+struct block_bt_priv {
+ struct block *b;
+ struct coord_rect r, r_curr;
+ int next;
+ int block_count;
+ struct coord_rect stack[BT_STACK_SIZE];
+ int stackp;
+ int order;
+ unsigned char *p;
+ unsigned char *end;
+};
+
+struct block_priv {
+ int block_num;
+ struct coord_rect b_rect;
+ unsigned char *block_start;
+ struct block *b;
+ unsigned char *p;
+ unsigned char *end;
+ unsigned char *p_start;
+ int binarytree;
+ struct block_bt_priv bt;
+};
+
+struct block_offset {
+ unsigned short offset;
+ unsigned short block;
+};
+
+
+struct tree_search_node {
+ struct tree_hdr *hdr;
+ unsigned char *p;
+ unsigned char *last;
+ unsigned char *end;
+ int low;
+ int high;
+ int last_low;
+ int last_high;
+ };
+
+struct tree_search {
+ struct file *f;
+ int last_node;
+ int curr_node;
+ struct tree_search_node nodes[5];
+};
+
+
+struct map_rect_priv {
+ struct map_selection *xsel;
+ struct map_selection *cur_sel;
+
+ struct map_priv *m;
+ enum file_index current_file;
+ struct file *file;
+ struct block_priv b;
+ struct item item;
+ struct town_priv town;
+ struct poly_priv poly;
+ struct street_priv street;
+ struct tree_search ts;
+ int search_country;
+ struct item search_item;
+ char *search_str;
+ int search_partial;
+ int search_linear;
+ unsigned char *search_p;
+ int search_blk_count;
+ enum attr_type search_type;
+ struct block_offset *search_blk_off;
+ int search_block;
+ GHashTable *block_hash[file_end];
+ struct item_priv item3;
+};
+
+int mg_country_from_isonum(int isonum);
+int mg_country_to_isonum(int country);
+int mg_country_postal_len(int country);
+
+int block_init(struct map_rect_priv *mr);
+int block_next(struct map_rect_priv *mr);
+int block_get_byindex(struct file *file, int idx, struct block_priv *blk);
+int block_next_lin(struct map_rect_priv *mr);
+
+int tree_search_hv(char *dirname, char *filename, unsigned int search1, unsigned int search2, int *result);
+int town_get(struct map_rect_priv *mr, struct town_priv *poly, struct item *item);
+int town_get_byid(struct map_rect_priv *mr, struct town_priv *twn, int id_hi, int id_lo, struct item *item);
+struct item * town_search_get_item(struct map_rect_priv *mr);
+int poly_get(struct map_rect_priv *mr, struct poly_priv *poly, struct item *item);
+int poly_get_byid(struct map_rect_priv *mr, struct poly_priv *poly, int id_hi, int id_lo, struct item *item);
+int street_get(struct map_rect_priv *mr, struct street_priv *street, struct item *item);
+int street_get_byid(struct map_rect_priv *mr, struct street_priv *street, int id_hi, int id_lo, struct item *item);
+struct item * street_search_get_item(struct map_rect_priv *mr);
+void tree_search_init(char *dirname, char *filename, struct tree_search *ts, int offset);
+void tree_search_free(struct tree_search *ts);
+int tree_search_next(struct tree_search *ts, unsigned char **p, int dir);
+int tree_search_next_lin(struct tree_search *ts, unsigned char **p);
diff --git a/navit/data/mg/poly.c b/navit/data/mg/poly.c
new file mode 100644
index 000000000..bc9af2011
--- /dev/null
+++ b/navit/data/mg/poly.c
@@ -0,0 +1,241 @@
+#include <string.h>
+#include "debug.h"
+#include "mg.h"
+
+static void
+poly_coord_rewind(void *priv_data)
+{
+ struct poly_priv *poly=priv_data;
+
+ poly->p=poly->subpoly_start;
+
+}
+
+static int
+poly_coord_get(void *priv_data, struct coord *c, int count)
+{
+ struct poly_priv *poly=priv_data;
+ int ret=0;
+
+ while (count--) {
+ if (poly->p >= poly->subpoly_next)
+ break;
+ c->x=get_u32_unal(&poly->p);
+ c->y=get_u32_unal(&poly->p);
+ c++;
+ ret++;
+ }
+ return ret;
+}
+
+static void
+poly_attr_rewind(void *priv_data)
+{
+ struct poly_priv *poly=priv_data;
+
+ poly->aidx=0;
+}
+
+static int
+poly_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+ struct poly_priv *poly=priv_data;
+
+ attr->type=attr_type;
+ switch (attr_type) {
+ case attr_any:
+ while (poly->attr_next != attr_none) {
+ if (poly_attr_get(poly, poly->attr_next, attr))
+ return 1;
+ }
+ return 0;
+ case attr_label:
+ attr->u.str=poly->name;
+ poly->attr_next=attr_none;
+ if (attr->u.str[0])
+ return 1;
+ return 0;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+static struct item_methods poly_meth = {
+ poly_coord_rewind,
+ poly_coord_get,
+ poly_attr_rewind,
+ poly_attr_get,
+};
+
+static void
+poly_get_data(struct poly_priv *poly, unsigned char **p)
+{
+ poly->c[0].x=get_u32_unal(p);
+ poly->c[0].y=get_u32_unal(p);
+ poly->c[1].x=get_u32_unal(p);
+ poly->c[1].y=get_u32_unal(p);
+ *p+=sizeof(struct coord);
+ poly->name=(char *)(*p);
+ while (**p) {
+ (*p)++;
+ }
+ (*p)++;
+ poly->order=*(*p)++;
+ poly->type=*(*p)++;
+ poly->polys=get_u32_unal(p);
+ poly->count=(unsigned int *)(*p); (*p)+=poly->polys*sizeof(unsigned int);
+ poly->count_sum=get_u32_unal(p);
+}
+
+int
+poly_get(struct map_rect_priv *mr, struct poly_priv *poly, struct item *item)
+{
+ struct coord_rect r;
+
+ for (;;) {
+ if (mr->b.p >= mr->b.end)
+ return 0;
+ if (mr->b.p == mr->b.p_start) {
+ poly->poly_num=0;
+ poly->subpoly_num=0;
+ poly->subpoly_num_all=0;
+ poly->poly_next=mr->b.p;
+ item->meth=&poly_meth;
+ }
+ if (poly->poly_num >= mr->b.b->count)
+ return 0;
+ if (!poly->subpoly_num) {
+ mr->b.p=poly->poly_next;
+ item->id_lo=mr->b.p-mr->file->begin;
+ poly_get_data(poly, &mr->b.p);
+ poly->poly_next=mr->b.p+poly->count_sum*sizeof(struct coord);
+ poly->poly_num++;
+ r.lu=poly->c[0];
+ r.rl=poly->c[1];
+ if (mr->cur_sel && (poly->order > mr->cur_sel->order[layer_poly]*3 || !coord_rect_overlap(&mr->cur_sel->u.c_rect, &r))) {
+ poly->subpoly_num_all+=poly->polys;
+ mr->b.p=poly->poly_next;
+ continue;
+ }
+ switch(poly->type) {
+ case 0x13:
+ item->type=type_poly_wood;
+ break;
+ case 0x14:
+ item->type=type_poly_town;
+ break;
+ case 0x15:
+ item->type=type_poly_cemetery;
+ break;
+ case 0x16:
+ item->type=type_poly_building;
+ break;
+ case 0x17:
+ item->type=type_poly_museum;
+ break;
+ case 0x19:
+ item->type=type_poly_place;
+ break;
+ case 0x1b:
+ item->type=type_poly_commercial_center;
+ break;
+ case 0x1e:
+ item->type=type_poly_industry;
+ break;
+ case 0x23:
+ /* FIXME: what is this ?*/
+ item->type=type_poly_place;
+ break;
+ case 0x24:
+ item->type=type_poly_car_parking;
+ break;
+ case 0x28:
+ item->type=type_poly_airport;
+ break;
+ case 0x29:
+ item->type=type_poly_station;
+ break;
+ case 0x2d:
+ item->type=type_poly_hospital;
+ break;
+ case 0x2e:
+ item->type=type_poly_hospital;
+ break;
+ case 0x2f:
+ item->type=type_poly_university;
+ break;
+ case 0x30:
+ item->type=type_poly_university;
+ break;
+ case 0x32:
+ item->type=type_poly_park;
+ break;
+ case 0x34:
+ item->type=type_poly_sport;
+ break;
+ case 0x35:
+ item->type=type_poly_sport;
+ break;
+ case 0x37:
+ item->type=type_poly_golf_course;
+ break;
+ case 0x38:
+ item->type=type_poly_national_park;
+ break;
+ case 0x39:
+ item->type=type_poly_nature_park;
+ break;
+ case 0x3c:
+ item->type=type_poly_water;
+ break;
+ case 0xbc:
+ item->type=type_water_line;
+ break;
+ case 0xc3:
+ /* FIXME: what is this ?*/
+ item->type=type_border_state;
+ break;
+ case 0xc6:
+ item->type=type_border_country;
+ break;
+ case 0xc7:
+ item->type=type_border_state;
+ break;
+ case 0xd0:
+ item->type=type_rail;
+ break;
+ default:
+ dbg(0,"Unknown poly type 0x%x '%s' 0x%x,0x%x\n", poly->type,poly->name,r.lu.x,r.lu.y);
+ item->type=type_street_unkn;
+ }
+ } else
+ mr->b.p=poly->subpoly_next;
+ dbg(1,"%d %d %s\n", poly->subpoly_num_all, mr->b.block_num, poly->name);
+ item->id_lo=poly->subpoly_num_all | (mr->b.block_num << 16);
+ item->id_hi=(mr->current_file << 16);
+ dbg(1,"0x%x 0x%x\n", item->id_lo, item->id_hi);
+ poly->subpoly_next=mr->b.p+L(poly->count[poly->subpoly_num])*sizeof(struct coord);
+ poly->subpoly_num++;
+ poly->subpoly_num_all++;
+ if (poly->subpoly_num >= poly->polys)
+ poly->subpoly_num=0;
+ poly->subpoly_start=poly->p=mr->b.p;
+ item->priv_data=poly;
+ poly->attr_next=attr_label;
+ return 1;
+ }
+}
+
+int
+poly_get_byid(struct map_rect_priv *mr, struct poly_priv *poly, int id_hi, int id_lo, struct item *item)
+{
+ int count=id_lo & 0xffff;
+ int ret=0;
+ block_get_byindex(mr->m->file[mr->current_file], id_lo >> 16, &mr->b);
+ while (count-- >= 0) {
+ ret=poly_get(mr, poly, item);
+ }
+ return ret;
+}
+
diff --git a/navit/data/mg/street.c b/navit/data/mg/street.c
new file mode 100644
index 000000000..019adb77f
--- /dev/null
+++ b/navit/data/mg/street.c
@@ -0,0 +1,728 @@
+#include <stdio.h>
+#include <string.h>
+#include "debug.h"
+#include "mg.h"
+
+int coord_debug;
+
+static void
+street_name_get(struct street_name *name, unsigned char **p)
+{
+ unsigned char *start=*p;
+ name->len=get_u16_unal(p);
+ name->country=get_u16_unal(p);
+ name->townassoc=get_u32_unal(p);
+ name->name1=get_string(p);
+ name->name2=get_string(p);
+ name->segment_count=get_u32_unal(p);
+ name->segments=(struct street_name_segment *)(*p);
+ (*p)+=(sizeof (struct street_name_segment))*name->segment_count;
+ name->aux_len=name->len-(*p-start);
+ name->aux_data=*p;
+ name->tmp_len=name->aux_len;
+ name->tmp_data=name->aux_data;
+ *p=start+name->len;
+}
+
+static void
+street_name_numbers_get(struct street_name_numbers *name_numbers, unsigned char **p)
+{
+ unsigned char *start=*p;
+ name_numbers->len=get_u16_unal(p);
+ name_numbers->tag=get_u8(p);
+ name_numbers->dist=get_u32_unal(p);
+ name_numbers->country=get_u32_unal(p);
+ name_numbers->c=coord_get(p);
+ name_numbers->first=get_u24(p);
+ name_numbers->last=get_u24(p);
+ name_numbers->segment_count=get_u32_unal(p);
+ name_numbers->segments=(struct street_name_segment *)(*p);
+ (*p)+=sizeof(struct street_name_segment)*name_numbers->segment_count;
+ name_numbers->aux_len=name_numbers->len-(*p-start);
+ name_numbers->aux_data=*p;
+ name_numbers->tmp_len=name_numbers->aux_len;
+ name_numbers->tmp_data=name_numbers->aux_data;
+ *p=start+name_numbers->len;
+}
+
+static void
+street_name_number_get(struct street_name_number *name_number, unsigned char **p)
+{
+ unsigned char *start=*p;
+ name_number->len=get_u16_unal(p);
+ name_number->tag=get_u8(p);
+ name_number->c=coord_get(p);
+ name_number->first=get_u24(p);
+ name_number->last=get_u24(p);
+ name_number->segment=(struct street_name_segment *)p;
+ *p=start+name_number->len;
+}
+
+static void
+street_name_get_by_id(struct street_name *name, struct file *file, unsigned long id)
+{
+ unsigned char *p;
+ if (id) {
+ p=file->begin+id+0x2000;
+ street_name_get(name, &p);
+ }
+}
+
+static int street_get_bytes(struct coord_rect *r)
+{
+ int bytes,dx,dy;
+ bytes=2;
+ dx=r->rl.x-r->lu.x;
+ dy=r->lu.y-r->rl.y;
+ g_assert(dx > 0);
+ g_assert(dy > 0);
+ if (dx > 32767 || dy > 32767)
+ bytes=3;
+ if (dx > 8388608 || dy > 8388608)
+ bytes=4;
+
+ return bytes;
+}
+
+static int street_get_coord(unsigned char **pos, int bytes, struct coord *ref, struct coord *f)
+{
+ unsigned char *p;
+ int x,y,flags=0;
+
+ p=*pos;
+ x=*p++;
+ x|=(*p++) << 8;
+ if (bytes == 2) {
+ if ( x > 0x7fff) {
+ x=0x10000-x;
+ flags=1;
+ }
+ }
+ else if (bytes == 3) {
+ x|=(*p++) << 16;
+ if ( x > 0x7fffff) {
+ x=0x1000000-x;
+ flags=1;
+ }
+ } else {
+ x|=(*p++) << 16;
+ x|=(*p++) << 24;
+ if (x < 0) {
+ x=-x;
+ flags=1;
+ }
+ }
+ y=*p++;
+ y|=(*p++) << 8;
+ if (bytes == 3) {
+ y|=(*p++) << 16;
+ } else if (bytes == 4) {
+ y|=(*p++) << 16;
+ y|=(*p++) << 24;
+ }
+ if (f) {
+ f->x=ref[0].x+x;
+ f->y=ref[1].y+y;
+ }
+ dbg(1,"0x%x,0x%x + 0x%x,0x%x = 0x%x,0x%x\n", x, y, ref[0].x, ref[1].y, f->x, f->y);
+ *pos=p;
+ return flags;
+}
+
+static void
+street_coord_get_begin(unsigned char **p)
+{
+ struct street_str *str;
+
+ str=(struct street_str *)(*p);
+ while (L(str->segid)) {
+ str++;
+ }
+ (*p)=(unsigned char *)str;
+ (*p)+=4;
+}
+
+
+static void
+street_coord_rewind(void *priv_data)
+{
+ /* struct street_priv *street=priv_data; */
+
+}
+
+static int
+street_coord_get_helper(struct street_priv *street, struct coord *c)
+{
+ unsigned char *n;
+ if (street->p+street->bytes*2 >= street->end)
+ return 0;
+ if (street->status >= 4)
+ return 0;
+ n=street->p;
+ if (street_get_coord(&street->p, street->bytes, street->ref, c)) {
+ if (street->status)
+ street->next=n;
+ street->status+=2;
+ if (street->status == 5)
+ return 0;
+ }
+ return 1;
+}
+
+static int
+street_coord_get(void *priv_data, struct coord *c, int count)
+{
+ struct street_priv *street=priv_data;
+ int ret=0,i,scount;
+
+ if (! street->p && count) {
+ street->p=street->coord_begin;
+ scount=street->str-street->str_start;
+ for (i = 0 ; i < scount ; i++) {
+ street->status=L(street->str[i+1].segid) >= 0 ? 0:1;
+ while (street_coord_get_helper(street, c));
+ street->p=street->next;
+ }
+ street->status_rewind=street->status=L(street->str[1].segid) >= 0 ? 0:1;
+ }
+ while (count > 0) {
+ if (street_coord_get_helper(street, c)) {
+ c++;
+ ret++;
+ count--;
+ } else {
+ street->more=0;
+ return ret;
+ }
+ }
+ return ret;
+}
+
+static void
+street_attr_rewind(void *priv_data)
+{
+ /* struct street_priv *street=priv_data; */
+
+}
+
+static int
+street_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+ struct street_priv *street=priv_data;
+ int nameid;
+
+ dbg(1,"segid 0x%x\n", street->str->segid);
+ attr->type=attr_type;
+ switch (attr_type) {
+ case attr_any:
+ while (street->attr_next != attr_none) {
+ if (street_attr_get(street, street->attr_next, attr))
+ return 1;
+ }
+ return 0;
+ case attr_label:
+ street->attr_next=attr_street_name;
+ nameid=L(street->str->nameid);
+ if (! nameid)
+ return 0;
+ if (! street->name.len)
+ street_name_get_by_id(&street->name,street->name_file,nameid);
+ attr->u.str=street->name.name2;
+ if (attr->u.str && attr->u.str[0])
+ return 1;
+ attr->u.str=street->name.name1;
+ if (attr->u.str && attr->u.str[0])
+ return 1;
+ return 0;
+ case attr_street_name:
+ street->attr_next=attr_street_name_systematic;
+ nameid=L(street->str->nameid);
+ if (! nameid)
+ return 0;
+ if (! street->name.len)
+ street_name_get_by_id(&street->name,street->name_file,nameid);
+ attr->u.str=street->name.name2;
+ return ((attr->u.str && attr->u.str[0]) ? 1:0);
+ case attr_street_name_systematic:
+ street->attr_next=attr_flags;
+ nameid=L(street->str->nameid);
+ if (! nameid)
+ return 0;
+ if (! street->name.len)
+ street_name_get_by_id(&street->name,street->name_file,nameid);
+ attr->u.str=street->name.name1;
+ return ((attr->u.str && attr->u.str[0]) ? 1:0);
+ case attr_flags:
+ if (street->str->type & 0x40) {
+ attr->u.num=(street->str->limit & 0x30) ? AF_ONEWAYREV:0;
+ attr->u.num|=(street->str->limit & 0x03) ? AF_ONEWAY:0;
+ } else {
+ attr->u.num=(street->str->limit & 0x30) ? AF_ONEWAY:0;
+ attr->u.num|=(street->str->limit & 0x03) ? AF_ONEWAYREV:0;
+ }
+ street->attr_next=attr_country_id;
+ return 1;
+ case attr_country_id:
+ street->attr_next=attr_debug;
+ nameid=L(street->str->nameid);
+ if (! nameid)
+ return 0;
+ if (! street->name.len)
+ street_name_get_by_id(&street->name,street->name_file,nameid);
+ attr->u.num=mg_country_to_isonum(street->name.country);
+ return 1;
+ case attr_debug:
+ street->attr_next=attr_none;
+ {
+ struct street_str *str=street->str;
+ sprintf(street->debug,"order:0x%x\nsegid:0x%x\nlimit:0x%x\nunknown2:0x%x\nunknown3:0x%x\ntype:0x%x\nnameid:0x%x\ntownassoc:0x%x",street->header->order,str->segid,str->limit,str->unknown2,str->unknown3,str->type,str->nameid, street->name.len ? street->name.townassoc : 0);
+ attr->u.str=street->debug;
+ }
+ return 1;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+static struct item_methods street_meth = {
+ street_coord_rewind,
+ street_coord_get,
+ street_attr_rewind,
+ street_attr_get,
+};
+
+static void
+street_get_data(struct street_priv *street, unsigned char **p)
+{
+ street->header=(struct street_header *)(*p);
+ (*p)+=sizeof(struct street_header);
+ street->type_count=street->header->count;
+ street->type=(struct street_type *)(*p);
+ (*p)+=street->type_count*sizeof(struct street_type);
+}
+
+
+ /*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 */
+static unsigned char limit[]={0,0,1,1,1,2,2,4,6,6,12,13,14,20,20,20,20,20,20};
+
+int
+street_get(struct map_rect_priv *mr, struct street_priv *street, struct item *item)
+{
+ while (street->more) {
+ struct coord c;
+ street_coord_get(street, &c, 1);
+ }
+ if (mr->b.p == mr->b.p_start) {
+ street_get_data(street, &mr->b.p);
+ street->name_file=mr->m->file[file_strname_stn];
+ if (mr->cur_sel && street->header->order > limit[mr->cur_sel->order[layer_street]])
+ return 0;
+ street->end=mr->b.end;
+ street->ref=&mr->b.b->r.lu;
+ street->bytes=street_get_bytes(&mr->b.b->r);
+ street->str_start=street->str=(struct street_str *)mr->b.p;
+ street->coord_begin=mr->b.p;
+ street_coord_get_begin(&street->coord_begin);
+ street->p=street->coord_begin;
+ street->type--;
+ item->meth=&street_meth;
+ item->priv_data=street;
+ } else {
+ street->str++;
+ street->p=street->next;
+ }
+ if (! L(street->str->segid))
+ return 0;
+ if (L(street->str->segid) < 0)
+ street->type++;
+#if 0
+ g_assert(street->p != NULL);
+#endif
+ street->next=NULL;
+ street->status_rewind=street->status=L(street->str[1].segid) >= 0 ? 0:1;
+#if 0
+ if (street->type->country != 0x31) {
+ printf("country=0x%x\n", street->type->country);
+ }
+#endif
+ item->id_hi=street->type->country | (mr->current_file << 16);
+ item->id_lo=L(street->str->segid) > 0 ? L(street->str->segid) : -L(street->str->segid);
+ switch(street->str->type & 0x1f) {
+ case 0xf: /* very small street */
+ if (street->str->limit == 0x33)
+ item->type=type_street_nopass;
+ else
+ item->type=type_street_0;
+ break;
+ case 0xd:
+ item->type=type_ferry;
+ break;
+ case 0xc: /* small street */
+ item->type=type_street_1_city;
+ break;
+ case 0xb:
+ item->type=type_street_2_city;
+ break;
+ case 0xa:
+ if ((street->str->limit == 0x03 || street->str->limit == 0x30) && street->header->order < 4)
+ item->type=type_street_4_city;
+ else
+ item->type=type_street_3_city;
+ break;
+ case 0x9:
+ if (street->header->order < 5)
+ item->type=type_street_4_city;
+ else if (street->header->order < 7)
+ item->type=type_street_2_city;
+ else
+ item->type=type_street_1_city;
+ break;
+ case 0x8:
+ item->type=type_street_2_land;
+ break;
+ case 0x7:
+ if ((street->str->limit == 0x03 || street->str->limit == 0x30) && street->header->order < 4)
+ item->type=type_street_4_city;
+ else
+ item->type=type_street_3_land;
+ break;
+ case 0x6:
+ item->type=type_ramp;
+ break;
+ case 0x5:
+ item->type=type_street_4_land;
+ break;
+ case 0x4:
+ item->type=type_street_4_land;
+ break;
+ case 0x3:
+ item->type=type_street_n_lanes;
+ break;
+ case 0x2:
+ item->type=type_highway_city;
+ break;
+ case 0x1:
+ item->type=type_highway_land;
+ break;
+ default:
+ item->type=type_street_unkn;
+ dbg(0,"unknown type 0x%x\n",street->str->type);
+ }
+#if 0
+ coord_debug=(street->str->unknown2 != 0x40 || street->str->unknown3 != 0x40);
+ if (coord_debug) {
+ item->type=type_street_unkn;
+ printf("%d %02x %02x %02x %02x\n", street->str->segid, street->str->type, street->str->limit, street->str->unknown2, street->str->unknown3);
+ }
+#endif
+ street->p_rewind=street->p;
+ street->name.len=0;
+ street->attr_next=attr_label;
+ street->more=1;
+ return 1;
+}
+
+int
+street_get_byid(struct map_rect_priv *mr, struct street_priv *street, int id_hi, int id_lo, struct item *item)
+{
+ int country=id_hi & 0xffff;
+ int res;
+ dbg(1,"enter(%p,%p,0x%x,0x%x,%p)\n", mr, street, id_hi, id_lo, item);
+ if (! country)
+ return 0;
+ tree_search_hv(mr->m->dirname, "street", (id_lo >> 8) | (country << 24), id_lo & 0xff, &res);
+ dbg(1,"res=0x%x (blk=0x%x)\n", res, res >> 12);
+ block_get_byindex(mr->m->file[mr->current_file], res >> 12, &mr->b);
+ street_get_data(street, &mr->b.p);
+ street->name_file=mr->m->file[file_strname_stn];
+ street->end=mr->b.end;
+ street->ref=&mr->b.b->r.lu;
+ street->bytes=street_get_bytes(&mr->b.b->r);
+ street->str_start=street->str=(struct street_str *)mr->b.p;
+ street->coord_begin=mr->b.p;
+ street_coord_get_begin(&street->coord_begin);
+ street->p=street->coord_begin;
+ street->type--;
+ item->meth=&street_meth;
+ item->priv_data=street;
+ street->str+=(res & 0xfff)-1;
+ dbg(1,"segid 0x%x\n", street->str[1].segid);
+ return street_get(mr, street, item);
+#if 0
+ mr->b.p=mr->b.block_start+(res & 0xffff);
+ return town_get(mr, twn, item);
+#endif
+
+ return 0;
+}
+
+
+struct street_name_index {
+ int block;
+ unsigned short country;
+ int town_assoc;
+ char name[0];
+} __attribute__((packed));
+
+
+static int
+street_search_compare_do(struct map_rect_priv *mr, int country, int town_assoc, char *name)
+{
+ int d;
+
+ dbg(1,"enter");
+ dbg(1,"country 0x%x town_assoc 0x%x name '%s'\n", country, town_assoc, name);
+ d=(mr->search_item.id_hi & 0xffff)-country;
+ dbg(1,"country %d (%d vs %d)\n", d, mr->search_item.id_hi & 0xffff, country);
+ if (!d) {
+ if (mr->search_item.id_lo == town_assoc ) {
+ dbg(1,"town_assoc match (0x%x)\n", town_assoc);
+ if (mr->search_partial)
+ d=strncasecmp(mr->search_str, name, strlen(mr->search_str));
+ else
+ d=strcasecmp(mr->search_str, name);
+ dbg(1,"string %d\n", d);
+ } else {
+ if (town_assoc < mr->search_item.id_lo)
+ d=1;
+ else
+ d=-1;
+ dbg(1,"assoc %d 0x%x-0x%x\n",d, mr->search_item.id_lo, town_assoc);
+ }
+ }
+ dbg(1,"d=%d\n", d);
+ return d;
+}
+
+static int
+street_search_compare(unsigned char **p, struct map_rect_priv *mr)
+{
+ struct street_name_index *i;
+ int ret;
+
+ dbg(1,"enter\n");
+ i=(struct street_name_index *)(*p);
+ *p+=sizeof(*i)+strlen(i->name)+1;
+
+ dbg(1,"block 0x%x\n", i->block);
+
+ ret=street_search_compare_do(mr, i->country, i->town_assoc, i->name);
+ if (ret <= 0)
+ mr->search_block=i->block;
+ return ret;
+}
+
+static void
+street_name_numbers_coord_rewind(void *priv_data)
+{
+ /* struct street_priv *street=priv_data; */
+
+}
+
+static void
+street_name_numbers_attr_rewind(void *priv_data)
+{
+ /* struct street_priv *street=priv_data; */
+
+}
+
+static int
+street_name_numbers_coord_get(void *priv_data, struct coord *c, int count)
+{
+ return 0;
+}
+
+static int
+street_name_numbers_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+ attr->type=attr_type;
+ switch (attr_type) {
+ default:
+ dbg(0,"unknown item\n");
+ return 0;
+ }
+}
+
+
+
+
+
+static struct item_methods street_name_numbers_meth = {
+ street_name_numbers_coord_rewind,
+ street_name_numbers_coord_get,
+ street_name_numbers_attr_rewind,
+ street_name_numbers_attr_get,
+};
+
+
+static void
+street_name_coord_rewind(void *priv_data)
+{
+ /* struct street_priv *street=priv_data; */
+
+}
+
+static void
+street_name_attr_rewind(void *priv_data)
+{
+ /* struct street_priv *street=priv_data; */
+
+}
+
+static int
+street_name_coord_get(void *priv_data, struct coord *c, int count)
+{
+ struct map_rect_priv *mr=priv_data;
+ struct street_name_numbers snns;
+ unsigned char *p=mr->street.name.aux_data;
+
+ dbg(1,"aux_data=%p\n", p);
+ if (count) {
+ street_name_numbers_get(&snns, &p);
+ *c=*(snns.c);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+street_name_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+ struct map_rect_priv *mr=priv_data;
+ struct item *item;
+
+ attr->type=attr_type;
+ switch (attr_type) {
+ case attr_street_name:
+ attr->u.str=mr->street.name.name2;
+ return ((attr->u.str && attr->u.str[0]) ? 1:0);
+ case attr_street_name_systematic:
+ attr->u.str=mr->street.name.name1;
+ return ((attr->u.str && attr->u.str[0]) ? 1:0);
+ case attr_street_name_numbers_item:
+ item=&mr->item3.item;
+ attr->u.item=item;
+ item->type=type_street_name_numbers;
+ item->id_hi=0;
+ item->id_lo=1;
+ item->meth=&street_name_numbers_meth;
+ item->map=NULL;
+ item->priv_data=mr;
+ {
+ int i;
+ struct street_name_numbers nns;
+ unsigned char *p=mr->street.name.aux_data;
+ unsigned char *end=p+mr->street.name.aux_len;
+ printf("len=0x%x\n", mr->street.name.aux_len);
+ for (i = 0 ; i < mr->street.name.aux_len ; i++) {
+ printf("%02x ",mr->street.name.aux_data[i]);
+ }
+ printf("\n");
+ {
+ while (p < end) {
+ unsigned char *pn,*pn_end;
+ struct street_name_number nn;
+ street_name_numbers_get(&nns, &p);
+ printf("name_numbers:\n");
+ printf(" len 0x%x\n", nns.len);
+ printf(" tag 0x%x\n", nns.tag);
+ printf(" dist 0x%x\n", nns.dist);
+ printf(" country 0x%x\n", nns.country);
+ printf(" coord 0x%x,0x%x\n", nns.c->x, nns.c->y);
+ printf(" first %d\n", nns.first);
+ printf(" last %d\n", nns.last);
+ printf(" segment count 0x%x\n", nns.segment_count);
+ printf(" aux_len 0x%x\n", nns.aux_len);
+ pn=nns.aux_data;
+ pn_end=nns.aux_data+nns.aux_len;
+ while (pn < pn_end) {
+ printf(" number:\n");
+ street_name_number_get(&nn, &pn);
+ printf(" len 0x%x\n", nn.len);
+ printf(" tag 0x%x\n", nn.tag);
+ printf(" coord 0x%x,0x%x\n", nn.c->x, nn.c->y);
+ printf(" first %d\n", nn.first);
+ printf(" last %d\n", nn.last);
+ }
+ }
+ }
+ }
+ return 1;
+ default:
+ dbg(0,"unknown item\n");
+ return 0;
+ }
+}
+
+
+
+
+
+static struct item_methods street_name_meth = {
+ street_name_coord_rewind,
+ street_name_coord_get,
+ street_name_attr_rewind,
+ street_name_attr_get,
+};
+
+
+struct item *
+street_search_get_item(struct map_rect_priv *mr)
+{
+ int dir=1,leaf;
+ unsigned char *last;
+
+ dbg(1,"enter\n");
+ if (! mr->search_blk_count) {
+ dbg(1,"partial 0x%x '%s' ***\n", mr->town.street_assoc, mr->search_str);
+ if (mr->search_linear)
+ return NULL;
+ dbg(1,"tree_search_next\n");
+ mr->search_block=-1;
+ while ((leaf=tree_search_next(&mr->ts, &mr->search_p, dir)) != -1) {
+ dir=street_search_compare(&mr->search_p, mr);
+ }
+ dbg(1,"dir=%d mr->search_block=0x%x\n", dir, mr->search_block);
+ if (mr->search_block == -1)
+ return NULL;
+ mr->search_blk_count=1;
+ block_get_byindex(mr->m->file[file_strname_stn], mr->search_block, &mr->b);
+ mr->b.p=mr->b.block_start+12;
+ }
+ dbg(1,"name id 0x%x\n", mr->b.p-mr->m->file[file_strname_stn]->begin);
+ if (! mr->search_blk_count)
+ return NULL;
+ for (;;) {
+ if (mr->b.p >= mr->b.end) {
+ if (!block_next_lin(mr)) {
+ dbg(1,"end of blocks in %p, %p\n", mr->m->file[file_strname_stn]->begin, mr->m->file[file_strname_stn]->end);
+ return NULL;
+ }
+ mr->b.p=mr->b.block_start+12;
+ }
+ while (mr->b.p < mr->b.end) {
+ last=mr->b.p;
+ street_name_get(&mr->street.name, &mr->b.p);
+ dir=street_search_compare_do(mr, mr->street.name.country, mr->street.name.townassoc, mr->street.name.name2);
+ dbg(1,"country 0x%x assoc 0x%x name1 '%s' name2 '%s' dir=%d\n", mr->street.name.country, mr->street.name.townassoc, mr->street.name.name1, mr->street.name.name2, dir);
+ if (dir < 0) {
+ dbg(1,"end of data\n");
+ mr->search_blk_count=0;
+ return NULL;
+ }
+ if (!dir) {
+ dbg(1,"result country 0x%x assoc 0x%x name1 '%s' name2 '%s' dir=%d aux_data=%p len=0x%x\n", mr->street.name.country, mr->street.name.townassoc, mr->street.name.name1, mr->street.name.name2, dir, mr->street.name.aux_data, mr->street.name.aux_len);
+ mr->item.type = type_street_name;
+ mr->item.id_hi=mr->street.name.country | (mr->current_file << 16) | 0x10000000;
+ mr->item.id_lo=last-mr->m->file[mr->current_file]->begin;
+ mr->item.meth=&street_name_meth;
+ mr->item.map=NULL;
+ mr->item.priv_data=mr;
+ return &mr->item;
+ }
+ }
+ }
+}
+
diff --git a/navit/data/mg/town.c b/navit/data/mg/town.c
new file mode 100644
index 000000000..92bd0e742
--- /dev/null
+++ b/navit/data/mg/town.c
@@ -0,0 +1,264 @@
+#include <stdio.h>
+#include <string.h>
+#include "debug.h"
+#include "mg.h"
+
+
+
+static void
+town_coord_rewind(void *priv_data)
+{
+ struct town_priv *twn=priv_data;
+
+ twn->cidx=0;
+}
+
+static int
+town_coord_get(void *priv_data, struct coord *c, int count)
+{
+ struct town_priv *twn=priv_data;
+
+ if (twn->cidx || count <= 0)
+ return 0;
+ twn->cidx=1;
+ *c=twn->c;
+ return 1;
+}
+
+static void
+town_attr_rewind(void *priv_data)
+{
+ struct town_priv *twn=priv_data;
+
+ twn->aidx=0;
+ twn->attr_next=attr_label;
+}
+
+static int
+town_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+ struct town_priv *twn=priv_data;
+ int len;
+
+ attr->type=attr_type;
+ switch (attr_type) {
+ case attr_any:
+ while (twn->attr_next != attr_none) {
+ if (town_attr_get(twn, twn->attr_next, attr))
+ return 1;
+ }
+ return 0;
+ case attr_label:
+ attr->u.str=twn->district;
+ twn->attr_next=attr_town_name;
+ if (attr->u.str[0])
+ return 1;
+ attr->u.str=twn->name;
+ return ((attr->u.str && attr->u.str[0]) ? 1:0);
+ case attr_town_name:
+ attr->u.str=twn->name;
+ twn->attr_next=attr_town_postal;
+ return ((attr->u.str && attr->u.str[0]) ? 1:0);
+ case attr_town_postal:
+ strncpy(twn->postal, twn->postal_code1, 32);
+ attr->u.str=twn->postal;
+ len=mg_country_postal_len(twn->country);
+ if (!len)
+ len=31;
+ twn->postal[len]='\0';
+ twn->attr_next=attr_district_name;
+ return ((attr->u.str && attr->u.str[0]) ? 1:0);
+ case attr_district_name:
+ attr->u.str=twn->district;
+ twn->attr_next=attr_debug;
+ return ((attr->u.str && attr->u.str[0]) ? 1:0);
+ case attr_town_streets_item:
+ twn->town_attr_item.type=type_town_streets;
+ twn->town_attr_item.id_hi=twn->country | (file_town_twn << 16) | 0x10000000;
+ twn->town_attr_item.id_lo=twn->street_assoc;
+ attr->u.item=&twn->town_attr_item;
+ twn->attr_next=attr_debug;
+ return 1;
+ case attr_debug:
+ sprintf(twn->debug, "order %d\nsize %d\nstreet_assoc 0x%x", twn->order, twn->size, twn->street_assoc);
+ attr->u.str=twn->debug;
+ twn->attr_next=attr_none;
+ return 1;
+ default:
+ g_assert(1==0);
+ return 0;
+ }
+ return 1;
+}
+
+static struct item_methods town_meth = {
+ town_coord_rewind,
+ town_coord_get,
+ town_attr_rewind,
+ town_attr_get,
+};
+
+static void
+town_get_data(struct town_priv *twn, unsigned char **p)
+{
+ twn->id=get_u32_unal(p);
+ twn->c.x=get_u32_unal(p);
+ twn->c.y=get_u32_unal(p);
+ twn->name=get_string(p);
+ twn->district=get_string(p);
+ twn->postal_code1=get_string(p);
+ twn->order=get_u8(p); /* 1-15 (19) */
+ twn->country=get_u16_unal(p);
+ twn->type=get_u8(p);
+ twn->unknown2=get_u32_unal(p);
+ twn->size=get_u8(p);
+ twn->street_assoc=get_u32_unal(p);
+ twn->unknown3=get_u8(p);
+ twn->postal_code2=get_string(p);
+ twn->unknown4=get_u32_unal(p);
+#if 0
+ printf("%s\t%s\t%s\t%d\t%d\t%d\n",twn->name,twn->district,twn->postal_code1,twn->order, twn->country, twn->type);
+#endif
+}
+ /*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 */
+static unsigned char limit[]={0,1,2,2,4,6,8,10,11,13,14,14,14,20,20,20,20,20,20};
+
+static enum item_type town_item[]={type_town_label_5e1, type_town_label_1e2, type_town_label_2e2, type_town_label_5e2, type_town_label_1e3, type_town_label_1e3, type_town_label_2e3, type_town_label_5e3, type_town_label_1e4, type_town_label_2e4, type_town_label_5e4, type_town_label_1e5, type_town_label_1e5, type_town_label_2e5, type_town_label_5e5, type_town_label_1e6, type_town_label_2e6};
+static enum item_type district_item[]={type_district_label_5e1, type_district_label_1e2, type_district_label_2e2, type_district_label_5e2, type_district_label_1e3, type_district_label_1e3, type_district_label_2e3, type_district_label_5e3, type_district_label_1e4, type_district_label_2e4, type_district_label_5e4, type_district_label_1e5, type_district_label_1e5, type_district_label_2e5, type_district_label_5e5, type_district_label_1e6, type_district_label_2e6};
+int
+town_get(struct map_rect_priv *mr, struct town_priv *twn, struct item *item)
+{
+ int size;
+ for (;;) {
+ if (mr->b.p >= mr->b.end)
+ return 0;
+ town_get_data(twn, &mr->b.p);
+ twn->cidx=0;
+ twn->aidx=0;
+ twn->attr_next=attr_label;
+ if (! mr->cur_sel || (twn->order <= limit[mr->cur_sel->order[layer_town]] && coord_rect_contains(&mr->cur_sel->u.c_rect,&twn->c))) {
+ switch(twn->type) {
+ case 1:
+ size=twn->size;
+ if (size >= sizeof(town_item)/sizeof(enum item_type))
+ size=sizeof(town_item)/sizeof(enum item_type)-1;
+ item->type=town_item[size];
+ break;
+ case 3:
+ size=twn->size;
+ if (size == 6 && twn->order < 14)
+ size++;
+ if (size == 5 && twn->order < 14)
+ size+=2;
+ if (size >= sizeof(district_item)/sizeof(enum item_type))
+ size=sizeof(district_item)/sizeof(enum item_type)-1;
+ item->type=district_item[size];
+ break;
+ case 4:
+ item->type=type_port_label;
+ break;
+ case 9:
+ item->type=type_highway_exit_label;
+ break;
+ default:
+ printf("unknown town type 0x%x '%s' '%s' 0x%x,0x%x\n", twn->type, twn->name, twn->district, twn->c.x, twn->c.y);
+ item->type=type_town_label;
+ }
+ item->id_hi=twn->country | (mr->current_file << 16);
+ item->id_lo=twn->id;
+ item->priv_data=twn;
+ item->meth=&town_meth;
+ return 1;
+ }
+ }
+}
+
+int
+town_get_byid(struct map_rect_priv *mr, struct town_priv *twn, int id_hi, int id_lo, struct item *item)
+{
+ int country=id_hi & 0xffff;
+ int res;
+ if (!tree_search_hv(mr->m->dirname, "town", (id_lo >> 8) | (country << 24), id_lo & 0xff, &res))
+ return 0;
+ block_get_byindex(mr->m->file[mr->current_file], res >> 16, &mr->b);
+ mr->b.p=mr->b.block_start+(res & 0xffff);
+ return town_get(mr, twn, item);
+}
+
+static int
+town_search_compare(unsigned char **p, struct map_rect_priv *mr)
+{
+ int country, d;
+ char *name;
+
+ if (mr->search_type == attr_town_postal) {
+ mr->search_blk_count=1;
+ mr->search_blk_off=(struct block_offset *)(*p);
+ *p+=4;
+ name=get_string(p);
+ d=0;
+ } else {
+ country=get_u16_unal(p);
+ dbg(1,"country 0x%x ", country);
+ name=get_string(p);
+ dbg(1,"name '%s' ",name);
+ mr->search_blk_count=get_u32_unal(p);
+ mr->search_blk_off=(struct block_offset *)(*p);
+ dbg(1,"len %d ", mr->search_blk_count);
+ (*p)+=mr->search_blk_count*4;
+ d=mr->search_country-country;
+ }
+ if (!d) {
+ if (mr->search_partial)
+ d=strncasecmp(mr->search_str, name, strlen(mr->search_str));
+ else
+ d=strcasecmp(mr->search_str, name);
+ }
+ dbg(1,"%d \n",d);
+ return d;
+
+}
+
+
+
+struct item *
+town_search_get_item(struct map_rect_priv *mr)
+{
+ int dir=1,leaf;
+
+ if (! mr->search_blk_count) {
+ dbg(1,"partial %d 0x%x '%s' ***\n", mr->search_partial, mr->search_country, mr->search_str);
+ if (! mr->search_linear) {
+ while ((leaf=tree_search_next(&mr->ts, &mr->search_p, dir)) != -1) {
+ dir=town_search_compare(&mr->search_p, mr);
+ if (! dir && leaf) {
+ mr->search_linear=1;
+ mr->search_p=NULL;
+ break;
+ }
+ }
+ if (! mr->search_linear) {
+ dbg(1,"not found\n");
+ return NULL;
+ }
+ }
+ if (! tree_search_next_lin(&mr->ts, &mr->search_p)) {
+ dbg(1,"linear not found\n");
+ return NULL;
+ }
+ if (town_search_compare(&mr->search_p, mr)) {
+ dbg(1,"no match\n");
+ return NULL;
+ }
+ dbg(1,"found %d blocks\n",mr->search_blk_count);
+ }
+ if (! mr->search_blk_count)
+ return NULL;
+ dbg(1,"block 0x%x offset 0x%x\n", mr->search_blk_off->block, mr->search_blk_off->offset);
+ block_get_byindex(mr->m->file[mr->current_file], mr->search_blk_off->block, &mr->b);
+ mr->b.p=mr->b.block_start+mr->search_blk_off->offset;
+ town_get(mr, &mr->town, &mr->item);
+ mr->search_blk_off++;
+ mr->search_blk_count--;
+ return &mr->item;
+}
diff --git a/navit/data/mg/tree.c b/navit/data/mg/tree.c
new file mode 100644
index 000000000..077649e96
--- /dev/null
+++ b/navit/data/mg/tree.c
@@ -0,0 +1,244 @@
+#include <stdio.h>
+#include <string.h>
+#include "debug.h"
+#include "mg.h"
+
+struct tree_hdr {
+ unsigned int addr;
+ unsigned int size;
+ unsigned int low;
+};
+
+struct tree_hdr_h {
+ unsigned int addr;
+ unsigned int size;
+};
+
+struct tree_leaf_h {
+ unsigned int lower;
+ unsigned int higher;
+ unsigned int match;
+ unsigned int value;
+};
+
+
+struct tree_hdr_v {
+ unsigned int count;
+ unsigned int next;
+ unsigned int unknown;
+};
+
+struct tree_leaf_v {
+ unsigned char key;
+ int value;
+} __attribute__((packed));
+
+static int
+tree_search_h(struct file *file, unsigned int search)
+{
+ unsigned char *p=file->begin,*end;
+ int last,i=0,value,lower;
+ struct tree_hdr_h *thdr;
+ struct tree_leaf_h *tleaf;
+
+ dbg(1,"enter\n");
+ while (i++ < 1000) {
+ thdr=(struct tree_hdr_h *)p;
+ p+=sizeof(*thdr);
+ end=p+thdr->size;
+ dbg(1,"@0x%x\n", p-file->begin);
+ last=0;
+ while (p < end) {
+ tleaf=(struct tree_leaf_h *)p;
+ p+=sizeof(*tleaf);
+ dbg(1,"low:0x%x high:0x%x match:0x%x val:0x%x search:0x%x\n", tleaf->lower, tleaf->higher, tleaf->match, tleaf->value, search);
+ value=tleaf->value;
+ if (value == search)
+ return tleaf->match;
+ if (value > search) {
+ dbg(1,"lower\n");
+ lower=tleaf->lower;
+ if (lower)
+ last=lower;
+ break;
+ }
+ last=tleaf->higher;
+ }
+ if (! last || last == -1)
+ return 0;
+ p=file->begin+last;
+ }
+ return 0;
+}
+
+static int
+tree_search_v(struct file *file, int offset, int search)
+{
+ unsigned char *p=file->begin+offset;
+ int i=0,count,next;
+ struct tree_hdr_v *thdr;
+ struct tree_leaf_v *tleaf;
+ while (i++ < 1000) {
+ thdr=(struct tree_hdr_v *)p;
+ p+=sizeof(*thdr);
+ count=L(thdr->count);
+ dbg(1,"offset=0x%x count=0x%x\n", p-file->begin, count);
+ while (count--) {
+ tleaf=(struct tree_leaf_v *)p;
+ p+=sizeof(*tleaf);
+ dbg(1,"0x%x 0x%x\n", tleaf->key, search);
+ if (tleaf->key == search)
+ return L(tleaf->value);
+ }
+ next=L(thdr->next);
+ if (! next)
+ break;
+ p=file->begin+next;
+ }
+ return 0;
+}
+
+int
+tree_search_hv(char *dirname, char *filename, unsigned int search_h, unsigned int search_v, int *result)
+{
+ struct file *f_idx_h, *f_idx_v;
+ char buffer[4096];
+ int h,v;
+
+ dbg(1,"enter(%s, %s, 0x%x, 0x%x, %p)\n",dirname, filename, search_h, search_v, result);
+ sprintf(buffer, "%s/%s.h1", dirname, filename);
+ f_idx_h=file_create_caseinsensitive(buffer);
+ if (! f_idx_h)
+ return 0;
+ file_mmap(f_idx_h);
+ sprintf(buffer, "%s/%s.v1", dirname, filename);
+ f_idx_v=file_create_caseinsensitive(buffer);
+ dbg(1,"%p %p\n", f_idx_h, f_idx_v);
+ if (! f_idx_v) {
+ file_destroy(f_idx_h);
+ return 0;
+ }
+ file_mmap(f_idx_v);
+ if ((h=tree_search_h(f_idx_h, search_h))) {
+ dbg(1,"h=0x%x\n", h);
+ if ((v=tree_search_v(f_idx_v, h, search_v))) {
+ dbg(1,"v=0x%x\n", v);
+ *result=v;
+ file_destroy(f_idx_v);
+ file_destroy(f_idx_h);
+ dbg(1,"return 1\n");
+ return 1;
+ }
+ }
+ file_destroy(f_idx_v);
+ file_destroy(f_idx_h);
+ dbg(1,"return 0\n");
+ return 0;
+}
+
+static struct tree_search_node *
+tree_search_enter(struct tree_search *ts, int offset)
+{
+ struct tree_search_node *tsn=&ts->nodes[++ts->curr_node];
+ unsigned char *p;
+ p=ts->f->begin+offset;
+ tsn->hdr=(struct tree_hdr *)p;
+ tsn->p=p+sizeof(struct tree_hdr);
+ tsn->last=tsn->p;
+ tsn->end=p+tsn->hdr->size;
+ tsn->low=tsn->hdr->low;
+ tsn->high=tsn->hdr->low;
+ dbg(1,"pos 0x%x addr 0x%x size 0x%x low 0x%x end 0x%x\n", p-ts->f->begin, tsn->hdr->addr, tsn->hdr->size, tsn->hdr->low, tsn->end-ts->f->begin);
+ return tsn;
+}
+
+int tree_search_next(struct tree_search *ts, unsigned char **p, int dir)
+{
+ struct tree_search_node *tsn=&ts->nodes[ts->curr_node];
+
+ if (! *p)
+ *p=tsn->p;
+ dbg(1,"next *p=%p dir=%d\n", *p, dir);
+ dbg(1,"low1=0x%x high1=0x%x\n", tsn->low, tsn->high);
+ if (dir <= 0) {
+ dbg(1,"down 0x%x\n", tsn->low);
+ if (tsn->low != 0xffffffff) {
+ tsn=tree_search_enter(ts, tsn->low);
+ *p=tsn->p;
+ tsn->high=get_u32(p);
+ ts->last_node=ts->curr_node;
+ dbg(1,"saving last2 %d 0x%x\n", ts->curr_node, tsn->last-ts->f->begin);
+ dbg(1,"high2=0x%x\n", tsn->high);
+ return 0;
+ }
+ return -1;
+ }
+ tsn->low=tsn->high;
+ tsn->last=*p;
+ tsn->high=get_u32_unal(p);
+ dbg(1,"saving last3 %d %p\n", ts->curr_node, tsn->last);
+ if (*p < tsn->end)
+ return (tsn->low == 0xffffffff ? 1 : 0);
+ dbg(1,"end reached high=0x%x\n",tsn->high);
+ if (tsn->low != 0xffffffff) {
+ dbg(1,"low 0x%x\n", tsn->low);
+ tsn=tree_search_enter(ts, tsn->low);
+ *p=tsn->p;
+ tsn->high=get_u32_unal(p);
+ ts->last_node=ts->curr_node;
+ dbg(1,"saving last4 %d 0x%x\n", ts->curr_node, tsn->last-ts->f->begin);
+ dbg(1,"high4=0x%x\n", tsn->high);
+ return 0;
+ }
+ return -1;
+}
+
+int tree_search_next_lin(struct tree_search *ts, unsigned char **p)
+{
+ struct tree_search_node *tsn=&ts->nodes[ts->curr_node];
+ int high;
+
+ dbg(1,"pos=%d 0x%x\n", ts->curr_node, *p-ts->f->begin);
+ if (*p)
+ ts->nodes[ts->last_node].last=*p;
+ *p=tsn->last;
+ for (;;) {
+ high=get_u32_unal(p);
+ if (*p < tsn->end) {
+ ts->last_node=ts->curr_node;
+ while (high != 0xffffffff) {
+ tsn=tree_search_enter(ts, high);
+ dbg(1,"reload %d\n",ts->curr_node);
+ high=tsn->low;
+ }
+ return 1;
+ }
+ dbg(1,"eon %d 0x%x 0x%x\n", ts->curr_node, *p-ts->f->begin, tsn->end-ts->f->begin);
+ if (! ts->curr_node)
+ break;
+ ts->curr_node--;
+ tsn=&ts->nodes[ts->curr_node];
+ *p=tsn->last;
+ }
+
+ return 0;
+}
+
+void
+tree_search_init(char *dirname, char *filename, struct tree_search *ts, int offset)
+{
+ char buffer[4096];
+ sprintf(buffer, "%s/%s", dirname, filename);
+ ts->f=file_create_caseinsensitive(buffer);
+ ts->curr_node=-1;
+ if (ts->f) {
+ file_mmap(ts->f);
+ tree_search_enter(ts, offset);
+ }
+}
+
+void
+tree_search_free(struct tree_search *ts)
+{
+ file_destroy(ts->f);
+}
diff --git a/navit/data/poi_geodownload/Makefile.am b/navit/data/poi_geodownload/Makefile.am
new file mode 100644
index 000000000..6c329b8ea
--- /dev/null
+++ b/navit/data/poi_geodownload/Makefile.am
@@ -0,0 +1,6 @@
+SUBDIRS=libmdb
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -I$(srcdir)/libmdb/include -DMODULE=data_poi_geodownload
+moduledata_LTLIBRARIES = libdata_poi_geodownload.la
+libdata_poi_geodownload_la_SOURCES = poi_geodownload.c
+libdata_poi_geodownload_la_LIBADD = -Llibmdb -lmdb
diff --git a/navit/data/poi_geodownload/libmdb/Makefile.am b/navit/data/poi_geodownload/libmdb/Makefile.am
new file mode 100644
index 000000000..e2e440ba9
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/Makefile.am
@@ -0,0 +1,4 @@
+SUBDIRS=include
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(srcdir)/include
+noinst_LTLIBRARIES = libmdb.la
+libmdb_la_SOURCES=backend.c catalog.c data.c dump.c file.c iconv.c index.c kkd.c like.c map.c mem.c money.c options.c props.c sargs.c stats.c table.c worktable.c write.c
diff --git a/navit/data/poi_geodownload/libmdb/backend.c b/navit/data/poi_geodownload/libmdb/backend.c
new file mode 100644
index 000000000..902805c3e
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/backend.c
@@ -0,0 +1,301 @@
+/* MDB Tools - A library for reading MS Access database files
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+** functions to deal with different backend database engines
+*/
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+static int is_init;
+static GHashTable *mdb_backends;
+
+ /* Access data types */
+static MdbBackendType mdb_access_types[] = {
+ {"Unknown 0x00", 0,0,0 },
+ {"Boolean", 0,0,0},
+ {"Byte", 0,0,0},
+ {"Integer", 0,0,0},
+ {"Long Integer", 0,0,0},
+ {"Currency", 0,0,0},
+ {"Single", 0,0,0},
+ {"Double", 0,0,0},
+ {"DateTime (Short)", 0,0,1},
+ {"Unknown 0x09", 0,0,0},
+ {"Text", 1,0,1},
+ {"OLE", 1,0,1},
+ {"Memo/Hyperlink",1,0,1},
+ {"Unknown 0x0d",0,0,0},
+ {"Unknown 0x0e",0,0,0},
+ {"Replication ID",0,0,0},
+ {"Numeric",1,1,0}
+};
+
+/* Oracle data types */
+static MdbBackendType mdb_oracle_types[] = {
+ {"Oracle_Unknown 0x00",0,0,0},
+ {"NUMBER",1,0,0},
+ {"NUMBER",1,0,0},
+ {"NUMBER",1,0,0},
+ {"NUMBER",1,0,0},
+ {"NUMBER",1,0,0},
+ {"FLOAT",0,0,0},
+ {"FLOAT",0,0,0},
+ {"DATE",0,0,0},
+ {"Oracle_Unknown 0x09",0,0,0},
+ {"VARCHAR2",1,0,1},
+ {"BLOB",1,0,1},
+ {"CLOB",1,0,1},
+ {"Oracle_Unknown 0x0d",0,0,0},
+ {"Oracle_Unknown 0x0e",0,0,0},
+ {"NUMBER",1,0,0},
+ {"NUMBER",1,0,0},
+};
+
+/* Sybase/MSSQL data types */
+static MdbBackendType mdb_sybase_types[] = {
+ {"Sybase_Unknown 0x00",0,0,0},
+ {"bit",0,0,0},
+ {"char",1,0,1},
+ {"smallint",0,0,0},
+ {"int",0,0,0},
+ {"money",0,0,0},
+ {"real",0,0,0},
+ {"float",0,0,0},
+ {"smalldatetime",0,0,0},
+ {"Sybase_Unknown 0x09",0,0,0},
+ {"varchar",1,0,1},
+ {"varbinary",1,0,1},
+ {"text",1,0,1},
+ {"Sybase_Unknown 0x0d",0,0,0},
+ {"Sybase_Unknown 0x0e",0,0,0},
+ {"Sybase_Replication ID",0,0,0},
+ {"numeric",1,1,0},
+};
+
+/* Postgres data types */
+static MdbBackendType mdb_postgres_types[] = {
+ {"Postgres_Unknown 0x00",0,0,0},
+ {"Bool",0,0,0},
+ {"Int2",0,0,0},
+ {"Int4",0,0,0},
+ {"Int8",0,0,0},
+ {"Money",0,0,0},
+ {"Float4",0,0,0},
+ {"Float8",0,0,0},
+ {"Timestamp",0,0,0},
+ {"Postgres_Unknown 0x09",0,0,0},
+ {"Char",1,0,1},
+ {"Postgres_Unknown 0x0b",0,0,0},
+ {"Postgres_Unknown 0x0c",0,0,0},
+ {"Postgres_Unknown 0x0d",0,0,0},
+ {"Postgres_Unknown 0x0e",0,0,0},
+ {"Serial",0,0,0},
+ {"Postgres_Unknown 0x10",0,0,0},
+};
+/* MySQL data types */
+static MdbBackendType mdb_mysql_types[] = {
+ {"Text",1,0,1},
+ {"char",0,0,0},
+ {"int",0,0,0},
+ {"int",0,0,0},
+ {"int",0,0,0},
+ {"float",0,0,0},
+ {"float",0,0,0},
+ {"float",0,0,0},
+ {"date",0,0,1},
+ {"varchar",1,0,1},
+ {"varchar",1,0,1},
+ {"varchar",1,0,1},
+ {"text",1,0,1},
+ {"blob",0,0,0},
+ {"text",1,0,1},
+ {"numeric",1,1,0},
+ {"numeric",1,1,0},
+};
+
+static gboolean mdb_drop_backend(gpointer key, gpointer value, gpointer data);
+
+char *mdb_get_coltype_string(MdbBackend *backend, int col_type)
+{
+ static char buf[16];
+
+ if (col_type > 0x10 ) {
+ // return NULL;
+ snprintf(buf,sizeof(buf), "type %04x", col_type);
+ return buf;
+ } else {
+ return backend->types_table[col_type].name;
+ }
+}
+
+int mdb_coltype_takes_length(MdbBackend *backend, int col_type)
+{
+ return backend->types_table[col_type].needs_length;
+}
+
+/**
+ * mdb_init_backends
+ *
+ * Initializes the mdb_backends hash and loads the builtin backends.
+ * Use mdb_remove_backends() to destroy this hash when done.
+ */
+void mdb_init_backends(void)
+{
+ mdb_backends = g_hash_table_new(g_str_hash, g_str_equal);
+
+ mdb_register_backend(mdb_access_types, "access");
+ mdb_register_backend(mdb_sybase_types, "sybase");
+ mdb_register_backend(mdb_oracle_types, "oracle");
+ mdb_register_backend(mdb_postgres_types, "postgres");
+ mdb_register_backend(mdb_mysql_types, "mysql");
+}
+void mdb_register_backend(MdbBackendType *backend_type, char *backend_name)
+{
+ MdbBackend *backend = (MdbBackend *) g_malloc0(sizeof(MdbBackend));
+ backend->types_table = backend_type;
+ g_hash_table_insert(mdb_backends, backend_name, backend);
+}
+
+/**
+ * mdb_remove_backends
+ *
+ * Removes all entries from and destroys the mdb_backends hash.
+ */
+void mdb_remove_backends(void)
+{
+ g_hash_table_foreach_remove(mdb_backends, mdb_drop_backend, NULL);
+ g_hash_table_destroy(mdb_backends);
+}
+static gboolean mdb_drop_backend(gpointer key, gpointer value, gpointer data)
+{
+ MdbBackend *backend = (MdbBackend *)value;
+ g_free (backend);
+ return TRUE;
+}
+
+/**
+ * mdb_set_default_backend
+ * @mdb: Handle to open MDB database file
+ * @backend_name: Name of the backend to set as default
+ *
+ * Sets the default backend of the handle @mdb to @backend_name.
+ *
+ * Returns: 1 if successful, 0 if unsuccessful.
+ */
+int mdb_set_default_backend(MdbHandle *mdb, char *backend_name)
+{
+ MdbBackend *backend;
+
+ backend = (MdbBackend *) g_hash_table_lookup(mdb_backends, backend_name);
+ if (backend) {
+ mdb->default_backend = backend;
+ mdb->backend_name = (char *) g_strdup(backend_name);
+ is_init = 0;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/**
+ * mdb_get_relationships
+ * @mdb: Handle to open MDB database file
+ *
+ * Generates relationships by reading the MSysRelationships table.
+ * 'szColumn' contains the column name of the child table.
+ * 'szObject' contains the table name of the child table.
+ * 'szReferencedColumn' contains the column name of the parent table.
+ * 'szReferencedObject' contains the table name of the parent table.
+ *
+ * Returns: a string stating that relationships are not supported for the
+ * selected backend, or a string containing SQL commands for setting up
+ * the relationship, tailored for the selected backend. The caller is
+ * responsible for freeing this string.
+ */
+char *mdb_get_relationships(MdbHandle *mdb)
+{
+ unsigned int i;
+ gchar *text = NULL; /* String to be returned */
+ static char *bound[4]; /* Bound values */
+ static MdbTableDef *table; /* Relationships table */
+ int backend = 0; /* Backends: 1=oracle */
+
+ if (strncmp(mdb->backend_name,"oracle",6) == 0) {
+ backend = 1;
+ } else {
+ if (is_init == 0) { /* the first time through */
+ is_init = 1;
+ return (char *) g_strconcat(
+ "-- relationships are not supported for ",
+ mdb->backend_name, NULL);
+ } else { /* the second time through */
+ is_init = 0;
+ return NULL;
+ }
+ }
+
+ if (is_init == 0) {
+ table = mdb_read_table_by_name(mdb, "MSysRelationships", MDB_TABLE);
+ if ((!table) || (table->num_rows == 0)) {
+ return NULL;
+ }
+
+ mdb_read_columns(table);
+ for (i=0;i<4;i++) {
+ bound[i] = (char *) g_malloc0(MDB_BIND_SIZE);
+ }
+ mdb_bind_column_by_name(table, "szColumn", bound[0]);
+ mdb_bind_column_by_name(table, "szObject", bound[1]);
+ mdb_bind_column_by_name(table, "szReferencedColumn", bound[2]);
+ mdb_bind_column_by_name(table, "szReferencedObject", bound[3]);
+ mdb_rewind_table(table);
+
+ is_init = 1;
+ }
+ else if (table->cur_row >= table->num_rows) { /* past the last row */
+ for (i=0;i<4;i++)
+ g_free(bound[i]);
+ is_init = 0;
+ return NULL;
+ }
+
+ if (!mdb_fetch_row(table)) {
+ for (i=0;i<4;i++)
+ g_free(bound[i]);
+ is_init = 0;
+ return NULL;
+ }
+
+ switch (backend) {
+ case 1: /* oracle */
+ text = g_strconcat("alter table ", bound[1],
+ " add constraint ", bound[3], "_", bound[1],
+ " foreign key (", bound[0], ")"
+ " references ", bound[3], "(", bound[2], ")", NULL);
+ break;
+ }
+
+ return (char *)text;
+}
+
diff --git a/navit/data/poi_geodownload/libmdb/catalog.c b/navit/data/poi_geodownload/libmdb/catalog.c
new file mode 100644
index 000000000..dc08abdd2
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/catalog.c
@@ -0,0 +1,138 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+char *
+mdb_get_objtype_string(int obj_type)
+{
+static char *type_name[] = {"Form",
+ "Table",
+ "Macro",
+ "System Table",
+ "Report",
+ "Query",
+ "Linked Table",
+ "Module",
+ "Relationship",
+ "Unknown 0x09",
+ "Unknown 0x0a",
+ "Database"
+ };
+
+ if (obj_type > 11) {
+ return NULL;
+ } else {
+ return type_name[obj_type];
+ }
+}
+
+void mdb_free_catalog(MdbHandle *mdb)
+{
+ unsigned int i;
+
+ if (!mdb->catalog) return;
+ for (i=0; i<mdb->catalog->len; i++)
+ g_free (g_ptr_array_index(mdb->catalog, i));
+ g_ptr_array_free(mdb->catalog, TRUE);
+ mdb->catalog = NULL;
+}
+
+GPtrArray *mdb_read_catalog (MdbHandle *mdb, int objtype)
+{
+ MdbCatalogEntry *entry, msysobj;
+ MdbTableDef *table;
+ char obj_id[256];
+ char obj_name[256];
+ char obj_type[256];
+ char obj_flags[256];
+ int type;
+
+ if (mdb->catalog) mdb_free_catalog(mdb);
+ mdb->catalog = g_ptr_array_new();
+ mdb->num_catalog = 0;
+
+ /* dummy up a catalog entry so we may read the table def */
+ memset(&msysobj, 0, sizeof(MdbCatalogEntry));
+ msysobj.mdb = mdb;
+ msysobj.object_type = MDB_TABLE;
+ msysobj.table_pg = 2;
+ strcpy(msysobj.object_name, "MSysObjects");
+
+ /* mdb_table_dump(&msysobj); */
+
+ table = mdb_read_table(&msysobj);
+ if (!table) return NULL;
+
+ mdb_read_columns(table);
+
+ mdb_bind_column_by_name(table, "Id", obj_id);
+ mdb_bind_column_by_name(table, "Name", obj_name);
+ mdb_bind_column_by_name(table, "Type", obj_type);
+ mdb_bind_column_by_name(table, "Flags", obj_flags);
+
+ mdb_rewind_table(table);
+
+ while (mdb_fetch_row(table)) {
+ type = atoi(obj_type);
+ if (objtype==MDB_ANY || type == objtype) {
+ // fprintf(stdout, "obj_id: %10ld objtype: %-3d obj_name: %s\n",
+ // (atol(obj_id) & 0x00FFFFFF), type, obj_name);
+ entry = (MdbCatalogEntry *) g_malloc0(sizeof(MdbCatalogEntry));
+ entry->mdb = mdb;
+ strcpy(entry->object_name, obj_name);
+ entry->object_type = (type & 0x7F);
+ entry->table_pg = atol(obj_id) & 0x00FFFFFF;
+ entry->flags = atol(obj_flags);
+ mdb->num_catalog++;
+ g_ptr_array_add(mdb->catalog, entry);
+ }
+ }
+ //mdb_dump_catalog(mdb, MDB_TABLE);
+
+ mdb_free_tabledef(table);
+
+ return mdb->catalog;
+}
+
+void
+mdb_dump_catalog(MdbHandle *mdb, int obj_type)
+{
+ unsigned int i;
+ MdbCatalogEntry *entry;
+
+ mdb_read_catalog(mdb, obj_type);
+ for (i=0;i<mdb->num_catalog;i++) {
+ entry = g_ptr_array_index(mdb->catalog,i);
+ if (obj_type==MDB_ANY || entry->object_type==obj_type) {
+ fprintf(stdout,"Type: %-10s Name: %-18s T pg: %04x KKD pg: %04x row: %2d\n",
+ mdb_get_objtype_string(entry->object_type),
+ entry->object_name,
+ (unsigned int) entry->table_pg,
+ (unsigned int) entry->kkd_pg,
+ entry->kkd_rowid);
+ }
+ }
+ return;
+}
+
diff --git a/navit/data/poi_geodownload/libmdb/data.c b/navit/data/poi_geodownload/libmdb/data.c
new file mode 100644
index 000000000..e50e57dbc
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/data.c
@@ -0,0 +1,856 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+#include "time.h"
+#include "math.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+#define OFFSET_MASK 0x1fff
+
+char *mdb_money_to_string(MdbHandle *mdb, int start, char *s);
+static int _mdb_attempt_bind(MdbHandle *mdb,
+ MdbColumn *col, unsigned char isnull, int offset, int len);
+static char *mdb_num_to_string(MdbHandle *mdb, int start, int datatype, int prec, int scale);
+int mdb_copy_ole(MdbHandle *mdb, char *dest, int start, int size);
+
+static char date_fmt[64] = "%x %X";
+
+void mdb_set_date_fmt(const char *fmt)
+{
+ date_fmt[63] = 0;
+ strncpy(date_fmt, fmt, 63);
+}
+
+void mdb_bind_column(MdbTableDef *table, int col_num, void *bind_ptr)
+{
+MdbColumn *col;
+
+ /*
+ ** the column arrary is 0 based, so decrement to get 1 based parameter
+ */
+ col=g_ptr_array_index(table->columns, col_num - 1);
+ col->bind_ptr = bind_ptr;
+}
+int
+mdb_bind_column_by_name(MdbTableDef *table, gchar *col_name, void *bind_ptr)
+{
+ unsigned int i;
+ int col_num = -1;
+ MdbColumn *col;
+
+ for (i=0;i<table->num_cols;i++) {
+ col=g_ptr_array_index(table->columns,i);
+ if (!strcmp(col->name,col_name)) {
+ col_num = col->col_num + 1;
+ mdb_bind_column(table, col_num, bind_ptr);
+ break;
+ }
+ }
+
+ return col_num;
+}
+void mdb_bind_len(MdbTableDef *table, int col_num, int *len_ptr)
+{
+MdbColumn *col;
+
+ col=g_ptr_array_index(table->columns, col_num - 1);
+ col->len_ptr = len_ptr;
+}
+
+/**
+ * mdb_find_pg_row
+ * @mdb: Database file handle
+ * @pg_row: Lower byte contains the row number, the upper three contain page
+ * @buf: Pointer for returning a pointer to the page
+ * @off: Pointer for returning an offset to the row
+ * @len: Pointer for returning the length of the row
+ *
+ * Returns: 0 on success. 1 on failure.
+ */
+int mdb_find_pg_row(MdbHandle *mdb, int pg_row, char **buf, int *off, int *len)
+{
+ unsigned int pg = pg_row >> 8;
+ unsigned int row = pg_row & 0xff;
+
+ if (mdb_read_alt_pg(mdb, pg) != mdb->fmt->pg_size)
+ return 1;
+ mdb_swap_pgbuf(mdb);
+ *off = mdb_pg_get_int16(mdb, mdb->fmt->row_count_offset + 2 + (row*2));
+ *len = mdb_find_end_of_row(mdb, row) - *off + 1;
+ mdb_swap_pgbuf(mdb);
+ *buf = mdb->alt_pg_buf;
+ return 0;
+}
+
+int
+mdb_find_end_of_row(MdbHandle *mdb, int row)
+{
+ MdbFormatConstants *fmt = mdb->fmt;
+ int row_end;
+
+ /* Search the previous "row start" values for the first non-'lookupflag' one.
+ * If we don't find one, then the end of the page is the correct value.
+ */
+#if 1
+ if (row==0) {
+ row_end = fmt->pg_size - 1;
+ } else {
+ row_end = (mdb_pg_get_int16(mdb, ((fmt->row_count_offset + 2) + (row - 1) * 2)) & OFFSET_MASK) - 1;
+ }
+ return row_end;
+#else
+ int i, row_start;
+
+ /* if lookupflag is not set, it's good (deleteflag is ok) */
+ for (i = row - 1; i >= 0; i--) {
+ row_start = mdb_pg_get_int16(mdb, ((fmt->row_count_offset + 2) + i * 2));
+ if (!(row_start & 0x8000)) {
+ break;
+ }
+ }
+
+ if (i == -1) {
+ row_end = fmt->pg_size - 1;
+ } else {
+ row_end = (row_start & OFFSET_MASK) - 1;
+ }
+ return row_end;
+#endif
+}
+int mdb_is_null(unsigned char *null_mask, int col_num)
+{
+int byte_num = (col_num - 1) / 8;
+int bit_num = (col_num - 1) % 8;
+
+ if ((1 << bit_num) & null_mask[byte_num]) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+/* bool has to be handled specially because it uses the null bit to store its
+** value*/
+static int
+mdb_xfer_bound_bool(MdbHandle *mdb, MdbColumn *col, int value)
+{
+
+ col->cur_value_len = value;
+ if (col->bind_ptr) {
+ strcpy(col->bind_ptr, value ? "0" : "1");
+ }
+
+ return 0;
+}
+static int mdb_xfer_bound_ole(MdbHandle *mdb, int start, MdbColumn *col, int len)
+{
+ int ret = 0;
+ if (len) {
+ col->cur_value_start = start;
+ col->cur_value_len = len;
+ } else {
+ col->cur_value_start = 0;
+ col->cur_value_len = 0;
+ }
+ if (col->bind_ptr || col->len_ptr) {
+ //ret = mdb_copy_ole(mdb, col->bind_ptr, start, len);
+ memcpy(col->bind_ptr, &mdb->pg_buf[start], MDB_MEMO_OVERHEAD);
+ }
+ if (col->len_ptr) {
+ *col->len_ptr = MDB_MEMO_OVERHEAD;
+ }
+ return ret;
+}
+static int mdb_xfer_bound_data(MdbHandle *mdb, int start, MdbColumn *col, int len)
+{
+int ret;
+ //if (!strcmp("Name",col->name)) {
+ //printf("start %d %d\n",start, len);
+ //}
+ if (len) {
+ col->cur_value_start = start;
+ col->cur_value_len = len;
+ } else {
+ col->cur_value_start = 0;
+ col->cur_value_len = 0;
+ }
+ if (col->bind_ptr) {
+ if (!len) {
+ strcpy(col->bind_ptr, "");
+ } else if (col->col_type == MDB_NUMERIC) {
+ //fprintf(stdout,"len %d size %d\n",len, col->col_size);
+ char *str = mdb_num_to_string(mdb, start, col->col_type,
+ col->col_prec, col->col_scale);
+ strcpy(col->bind_ptr, str);
+ g_free(str);
+ } else {
+ //fprintf(stdout,"len %d size %d\n",len, col->col_size);
+ char *str = mdb_col_to_string(mdb, mdb->pg_buf, start,
+ col->col_type, len);
+ strcpy(col->bind_ptr, str);
+
+ }
+ ret = strlen(col->bind_ptr);
+ if (col->len_ptr) {
+ *col->len_ptr = ret;
+ }
+ return ret;
+ }
+ return 0;
+}
+int mdb_read_row(MdbTableDef *table, unsigned int row)
+{
+ MdbHandle *mdb = table->entry->mdb;
+ MdbFormatConstants *fmt = mdb->fmt;
+ MdbColumn *col;
+ unsigned int i;
+ int rc;
+ int row_start, row_end;
+ int delflag, lookupflag;
+ MdbField fields[256];
+ int num_fields;
+
+ if (table->num_rows <= row)
+ return 0;
+
+ row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (row*2));
+ row_end = mdb_find_end_of_row(mdb, row);
+
+ delflag = lookupflag = 0;
+ if (row_start & 0x8000) lookupflag++;
+ if (row_start & 0x4000) delflag++;
+ row_start &= OFFSET_MASK; /* remove flags */
+#if MDB_DEBUG
+ fprintf(stdout,"Row %d bytes %d to %d %s %s\n",
+ row, row_start, row_end,
+ lookupflag ? "[lookup]" : "",
+ delflag ? "[delflag]" : "");
+#endif
+
+ if (!table->noskip_del && delflag) {
+ row_end = row_start-1;
+ return 0;
+ }
+
+ num_fields = mdb_crack_row(table, row_start, row_end, fields);
+ if (!mdb_test_sargs(table, fields, num_fields)) return 0;
+
+#if MDB_DEBUG
+ fprintf(stdout,"sarg test passed row %d \n", row);
+#endif
+
+#if MDB_DEBUG
+ buffer_dump(mdb->pg_buf, row_start, row_end);
+#endif
+
+ /* take advantage of mdb_crack_row() to clean up binding */
+ /* use num_cols instead of num_fields -- bsb 03/04/02 */
+ for (i = 0; i < table->num_cols; i++) {
+ col = g_ptr_array_index(table->columns,fields[i].colnum);
+ rc = _mdb_attempt_bind(mdb, col, fields[i].is_null,
+ fields[i].start, fields[i].siz);
+ }
+
+ return 1;
+}
+static int _mdb_attempt_bind(MdbHandle *mdb,
+ MdbColumn *col,
+ unsigned char isnull,
+ int offset,
+ int len)
+{
+ if (col->col_type == MDB_BOOL) {
+ mdb_xfer_bound_bool(mdb, col, isnull);
+ } else if (isnull) {
+ mdb_xfer_bound_data(mdb, 0, col, 0);
+ } else if (col->col_type == MDB_OLE) {
+ mdb_xfer_bound_ole(mdb, offset, col, len);
+ } else {
+ //if (!mdb_test_sargs(mdb, col, offset, len)) {
+ //return 0;
+ //}
+ mdb_xfer_bound_data(mdb, offset, col, len);
+ }
+ return 1;
+}
+int mdb_read_next_dpg(MdbTableDef *table)
+{
+ MdbCatalogEntry *entry = table->entry;
+ MdbHandle *mdb = entry->mdb;
+ int next_pg;
+
+#ifndef SLOW_READ
+ next_pg = mdb_map_find_next(mdb, table->usage_map,
+ table->map_sz, table->cur_phys_pg);
+
+ if (next_pg >= 0) {
+ if (mdb_read_pg(mdb, next_pg)) {
+ table->cur_phys_pg = next_pg;
+ return table->cur_phys_pg;
+ } else {
+ return 0;
+ }
+ }
+ fprintf(stderr, "Warning: defaulting to brute force read\n");
+#endif
+ /* can't do a fast read, go back to the old way */
+ do {
+ if (!mdb_read_pg(mdb, table->cur_phys_pg++))
+ return 0;
+ } while (mdb->pg_buf[0]!=0x01 || mdb_pg_get_int32(mdb, 4)!=entry->table_pg);
+ /* fprintf(stderr,"returning new page %ld\n", table->cur_phys_pg); */
+ return table->cur_phys_pg;
+}
+int mdb_rewind_table(MdbTableDef *table)
+{
+ table->cur_pg_num=0;
+ table->cur_phys_pg=0;
+ table->cur_row=0;
+
+ return 0;
+}
+int
+mdb_fetch_row(MdbTableDef *table)
+{
+ MdbHandle *mdb = table->entry->mdb;
+ MdbFormatConstants *fmt = mdb->fmt;
+ unsigned int rows;
+ int rc;
+ guint32 pg;
+
+ if (table->num_rows==0)
+ return 0;
+
+ /* initialize */
+ if (!table->cur_pg_num) {
+ table->cur_pg_num=1;
+ table->cur_row=0;
+ if ((!table->is_temp_table)&&(table->strategy!=MDB_INDEX_SCAN))
+ if (!mdb_read_next_dpg(table)) return 0;
+ }
+
+ do {
+ if (table->is_temp_table) {
+ GPtrArray *pages = table->temp_table_pages;
+ rows = mdb_get_int16(
+ g_ptr_array_index(pages, table->cur_pg_num-1),
+ fmt->row_count_offset);
+ if (table->cur_row >= rows) {
+ table->cur_row = 0;
+ table->cur_pg_num++;
+ if (table->cur_pg_num > pages->len)
+ return 0;
+ }
+ memcpy(mdb->pg_buf,
+ g_ptr_array_index(pages, table->cur_pg_num-1),
+ fmt->pg_size);
+ } else if (table->strategy==MDB_INDEX_SCAN) {
+
+ if (!mdb_index_find_next(table->mdbidx, table->scan_idx, table->chain, &pg, (guint16 *) &(table->cur_row))) {
+ mdb_index_scan_free(table);
+ return 0;
+ }
+ mdb_read_pg(mdb, pg);
+ } else {
+ rows = mdb_pg_get_int16(mdb,fmt->row_count_offset);
+
+ /* if at end of page, find a new page */
+ if (table->cur_row >= rows) {
+ table->cur_row=0;
+
+ if (!mdb_read_next_dpg(table)) {
+ return 0;
+ }
+ }
+ }
+
+ /* printf("page %d row %d\n",table->cur_phys_pg, table->cur_row); */
+ rc = mdb_read_row(table, table->cur_row);
+ table->cur_row++;
+ } while (!rc);
+
+ return 1;
+}
+void mdb_data_dump(MdbTableDef *table)
+{
+ unsigned int i;
+ char *bound_values[MDB_MAX_COLS];
+
+ for (i=0;i<table->num_cols;i++) {
+ bound_values[i] = (char *) g_malloc(256);
+ mdb_bind_column(table, i+1, bound_values[i]);
+ }
+ mdb_rewind_table(table);
+ while (mdb_fetch_row(table)) {
+ for (i=0;i<table->num_cols;i++) {
+ fprintf(stdout, "column %d is %s\n", i+1, bound_values[i]);
+ }
+ }
+ for (i=0;i<table->num_cols;i++) {
+ g_free(bound_values[i]);
+ }
+}
+
+int mdb_is_fixed_col(MdbColumn *col)
+{
+ return col->is_fixed;
+}
+#if 0
+static char *mdb_data_to_hex(MdbHandle *mdb, char *text, int start, int size)
+{
+int i;
+
+ for (i=start; i<start+size; i++) {
+ sprintf(&text[(i-start)*2],"%02x", mdb->pg_buf[i]);
+ }
+ text[(i-start)*2]='\0';
+
+ return text;
+}
+#endif
+int
+mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr)
+{
+ guint16 ole_len;
+ guint16 ole_flags;
+ char *buf;
+ int pg_row, row_start;
+ int len;
+
+ ole_len = mdb_get_int16(ole_ptr, 0);
+ ole_flags = mdb_get_int16(ole_ptr, 2);
+
+ if (ole_flags == 0x8000) {
+ /* inline fields don't have a next */
+ return 0;
+ } else if (ole_flags == 0x4000) {
+ /* 0x4000 flagged ole's are contained on one page and thus
+ * should be handled entirely with mdb_ole_read() */
+ return 0;
+ } else if (ole_flags == 0x0000) {
+ pg_row = (col->cur_blob_pg << 8) & col->cur_blob_row;
+ if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) {
+ return 0;
+ }
+ if (col->bind_ptr)
+ memcpy(col->bind_ptr, buf + row_start, len);
+ pg_row = mdb_get_int32(buf, row_start);
+ col->cur_blob_pg = pg_row >> 8;
+ col->cur_blob_row = pg_row & 0xff;
+
+ return len;
+ }
+ return 0;
+}
+int
+mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int chunk_size)
+{
+ guint16 ole_len;
+ guint16 ole_flags;
+ char *buf;
+ int pg_row, row_start;
+ int len;
+
+ ole_len = mdb_get_int16(ole_ptr, 0);
+ ole_flags = mdb_get_int16(ole_ptr, 2);
+ mdb_debug(MDB_DEBUG_OLE,"ole len = %d ole flags = %08x",
+ ole_len, ole_flags);
+
+ col->chunk_size = chunk_size;
+
+ if (ole_flags == 0x8000) {
+ /* inline ole field, if we can satisfy it, then do it */
+ len = col->cur_value_len - MDB_MEMO_OVERHEAD;
+ if (chunk_size >= len) {
+ if (col->bind_ptr)
+ memcpy(col->bind_ptr,
+ &mdb->pg_buf[col->cur_value_start +
+ MDB_MEMO_OVERHEAD],
+ len);
+ return len;
+ } else {
+ return 0;
+ }
+ } else if (ole_flags == 0x4000) {
+ pg_row = mdb_get_int32(ole_ptr, 4);
+ col->cur_blob_pg = pg_row >> 8;
+ col->cur_blob_row = pg_row & 0xff;
+ mdb_debug(MDB_DEBUG_OLE,"ole row = %d ole pg = %ld",
+ col->cur_blob_row, col->cur_blob_pg);
+
+ if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) {
+ return 0;
+ }
+ mdb_debug(MDB_DEBUG_OLE,"start %d len %d", row_start, len);
+
+ if (col->bind_ptr) {
+ memcpy(col->bind_ptr, buf + row_start, len);
+ if (mdb_get_option(MDB_DEBUG_OLE))
+ buffer_dump(col->bind_ptr, 0, 16);
+ }
+ return len;
+ } else if (ole_flags == 0x0000) {
+ pg_row = mdb_get_int32(ole_ptr, 4);
+ col->cur_blob_pg = pg_row >> 8;
+ col->cur_blob_row = pg_row & 0xff;
+
+ if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) {
+ return 0;
+ }
+
+ if (col->bind_ptr)
+ memcpy(col->bind_ptr, buf + row_start, len);
+
+ pg_row = mdb_get_int32(buf, row_start);
+ col->cur_blob_pg = pg_row >> 8;
+ col->cur_blob_row = pg_row & 0xff;
+
+ return len;
+ } else {
+ fprintf(stderr,"Unhandled ole field flags = %04x\n", ole_flags);
+ return 0;
+ }
+}
+int mdb_copy_ole(MdbHandle *mdb, char *dest, int start, int size)
+{
+ guint16 ole_len;
+ guint16 ole_flags;
+ guint32 row_start, pg_row;
+ guint32 len;
+ char *buf;
+
+ if (size<MDB_MEMO_OVERHEAD) {
+ return 0;
+ }
+
+ /* The 16 bit integer at offset 0 is the length of the memo field.
+ * The 32 bit integer at offset 4 contains page and row information.
+ */
+ ole_len = mdb_pg_get_int16(mdb, start);
+ ole_flags = mdb_pg_get_int16(mdb, start+2);
+
+ if (ole_flags == 0x8000) {
+ len = size - MDB_MEMO_OVERHEAD;
+ /* inline ole field */
+ if (dest) memcpy(dest, &mdb->pg_buf[start + MDB_MEMO_OVERHEAD],
+ size - MDB_MEMO_OVERHEAD);
+ return len;
+ } else if (ole_flags == 0x4000) {
+ pg_row = mdb_get_int32(mdb->pg_buf, start+4);
+ mdb_debug(MDB_DEBUG_OLE,"Reading LVAL page %06x", pg_row >> 8);
+
+ if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) {
+ return 0;
+ }
+ mdb_debug(MDB_DEBUG_OLE,"row num %d start %d len %d",
+ pg_row & 0xff, row_start, len);
+
+ if (dest)
+ memcpy(dest, buf + row_start, len);
+ return len;
+ } else if (ole_flags == 0x0000) {
+ int cur = 0;
+ pg_row = mdb_get_int32(mdb->pg_buf, start+4);
+ mdb_debug(MDB_DEBUG_OLE,"Reading LVAL page %06x", pg_row >> 8);
+ do {
+ if (mdb_find_pg_row(mdb,pg_row,&buf,&row_start,&len)) {
+ return 0;
+ }
+
+ mdb_debug(MDB_DEBUG_OLE,"row num %d start %d len %d",
+ pg_row & 0xff, row_start, len);
+
+ if (dest)
+ memcpy(dest+cur, buf + row_start + 4, len - 4);
+ cur += len - 4;
+
+ /* find next lval page */
+ pg_row = mdb_get_int32(buf, row_start);
+ } while ((pg_row >> 8));
+ return cur;
+ } else {
+ fprintf(stderr,"Unhandled ole field flags = %04x\n", ole_flags);
+ return 0;
+ }
+}
+static char *mdb_memo_to_string(MdbHandle *mdb, int start, int size)
+{
+ guint16 memo_len;
+ static char text[MDB_BIND_SIZE];
+ guint16 memo_flags;
+ guint32 row_start, pg_row;
+ guint32 len;
+ char *buf;
+
+ if (size<MDB_MEMO_OVERHEAD) {
+ return "";
+ }
+
+#if MDB_DEBUG
+ buffer_dump(mdb->pg_buf, start, start + 12);
+#endif
+
+ /* The 16 bit integer at offset 0 is the length of the memo field.
+ * The 32 bit integer at offset 4 contains page and row information.
+ */
+ memo_len = mdb_pg_get_int16(mdb, start);
+ memo_flags = mdb_pg_get_int16(mdb, start+2);
+
+ if (memo_flags & 0x8000) {
+ /* inline memo field */
+ strncpy(text, &mdb->pg_buf[start + MDB_MEMO_OVERHEAD],
+ size - MDB_MEMO_OVERHEAD);
+ text[size - MDB_MEMO_OVERHEAD]='\0';
+ return text;
+ } else if (memo_flags & 0x4000) {
+ pg_row = mdb_get_int32(mdb->pg_buf, start+4);
+#if MDB_DEBUG
+ printf("Reading LVAL page %06x\n", pg_row >> 8);
+#endif
+ if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) {
+ return "";
+ }
+#if MDB_DEBUG
+ printf("row num %d start %d len %d\n",
+ pg_row & 0xff, row_start, len);
+ buffer_dump(mdb->pg_buf, row_start, row_start + len);
+#endif
+ if (IS_JET3(mdb)) {
+ strncpy(text, buf + row_start, len);
+ text[len]='\0';
+ } else {
+ mdb_unicode2ascii(mdb, buf, row_start, len, text);
+ }
+ return text;
+ } else { /* if (memo_flags == 0x0000) { */
+ pg_row = mdb_get_int32(mdb->pg_buf, start+4);
+#if MDB_DEBUG
+ printf("Reading LVAL page %06x\n", pg_row >> 8);
+#endif
+ text[0]='\0';
+ do {
+ if (mdb_find_pg_row(mdb,pg_row,&buf,&row_start,&len)) {
+ return "";
+ }
+#if MDB_DEBUG
+ printf("row num %d start %d len %d\n",
+ pg_row & 0xff, row_start, len);
+#endif
+ strncat(text, buf + row_start + 4,
+ strlen(text) + len - 4 > MDB_BIND_SIZE ?
+ MDB_BIND_SIZE - strlen(text) : len - 4);
+
+ /* find next lval page */
+ pg_row = mdb_get_int32(mdb->pg_buf, row_start);
+ } while ((pg_row >> 8));
+ return text;
+/*
+ } else {
+ fprintf(stderr,"Unhandled memo field flags = %04x\n", memo_flags);
+ return "";
+*/
+ }
+}
+static char *
+mdb_num_to_string(MdbHandle *mdb, int start, int datatype, int prec, int scale)
+{
+ char *text;
+ gint32 l;
+
+ memcpy(&l, mdb->pg_buf+start+13, 4);
+
+ text = (char *) g_malloc(prec+2);
+ sprintf(text, "%0*" G_GINT32_FORMAT, prec, GINT32_FROM_LE(l));
+ if (scale) {
+ memmove(text+prec-scale, text+prec-scale+1, scale+1);
+ text[prec-scale] = '.';
+ }
+ return text;
+}
+
+static int trim_trailing_zeros(char * buff, int n)
+{
+ char * p = buff + n - 1;
+
+ while (p >= buff && *p == '0')
+ *p-- = '\0';
+
+ if (*p == '.')
+ *p = '\0';
+
+ return 0;
+}
+
+char *mdb_col_to_string(MdbHandle *mdb, unsigned char *buf, int start, int datatype, int size)
+{
+ /* FIX ME -- not thread safe */
+ static char text[MDB_BIND_SIZE];
+ time_t t;
+ int n;
+ float tf;
+ double td;
+
+ switch (datatype) {
+ case MDB_BOOL:
+ /* shouldn't happen. bools are handled specially
+ ** by mdb_xfer_bound_bool() */
+ break;
+ case MDB_BYTE:
+ sprintf(text,"%d",mdb_get_byte(buf, start));
+ return text;
+ break;
+ case MDB_INT:
+ sprintf(text,"%ld",(long)mdb_get_int16(buf, start));
+ return text;
+ break;
+ case MDB_LONGINT:
+ sprintf(text,"%ld",mdb_get_int32(buf, start));
+ return text;
+ break;
+ case MDB_FLOAT:
+ tf = mdb_get_single(mdb->pg_buf, start);
+ n = sprintf(text,"%.*f",FLT_DIG - (int)ceil(log10(tf)), tf);
+ trim_trailing_zeros(text, n);
+ return text;
+ break;
+ case MDB_DOUBLE:
+ td = mdb_get_double(mdb->pg_buf, start);
+ n = sprintf(text,"%.*f",DBL_DIG - (int)ceil(log10(td)), td);
+ trim_trailing_zeros(text, n);
+ return text;
+ break;
+ case MDB_TEXT:
+ if (size<0) {
+ return "";
+ }
+ if (IS_JET4(mdb)) {
+/*
+ int i;
+ for (i=0;i<size;i++) {
+ fprintf(stdout, "%c %02x ", mdb->pg_buf[start+i], mdb->pg_buf[start+i]);
+ }
+ fprintf(stdout, "\n");
+*/
+ mdb_unicode2ascii(mdb, mdb->pg_buf, start, size, text);
+ } else {
+ strncpy(text, &buf[start], size);
+ text[size]='\0';
+ }
+ return text;
+ break;
+ case MDB_SDATETIME:
+ td = mdb_get_double(mdb->pg_buf, start);
+ if (td > 1) {
+ t = (long int)((td - 25569.0) * 86400.0);
+ } else {
+ t = (long int)(td * 86400.0);
+ }
+ strftime(text, MDB_BIND_SIZE, date_fmt, (struct tm*)gmtime(&t));
+ return text;
+
+ break;
+ case MDB_MEMO:
+ return mdb_memo_to_string(mdb, start, size);
+ break;
+ case MDB_MONEY:
+ mdb_money_to_string(mdb, start, text);
+ return text;
+ case MDB_NUMERIC:
+ break;
+ default:
+ return "";
+ break;
+ }
+ return NULL;
+}
+int mdb_col_disp_size(MdbColumn *col)
+{
+ switch (col->col_type) {
+ case MDB_BOOL:
+ return 1;
+ break;
+ case MDB_BYTE:
+ return 4;
+ break;
+ case MDB_INT:
+ return 6;
+ break;
+ case MDB_LONGINT:
+ return 11;
+ break;
+ case MDB_FLOAT:
+ return 10;
+ break;
+ case MDB_DOUBLE:
+ return 10;
+ break;
+ case MDB_TEXT:
+ return col->col_size;
+ break;
+ case MDB_SDATETIME:
+ return 20;
+ break;
+ case MDB_MEMO:
+ return 255;
+ break;
+ case MDB_MONEY:
+ return 21;
+ break;
+ }
+ return 0;
+}
+int mdb_col_fixed_size(MdbColumn *col)
+{
+ switch (col->col_type) {
+ case MDB_BOOL:
+ return 1;
+ break;
+ case MDB_BYTE:
+ return -1;
+ break;
+ case MDB_INT:
+ return 2;
+ break;
+ case MDB_LONGINT:
+ return 4;
+ break;
+ case MDB_FLOAT:
+ return 4;
+ break;
+ case MDB_DOUBLE:
+ return 8;
+ break;
+ case MDB_TEXT:
+ return -1;
+ break;
+ case MDB_SDATETIME:
+ return 4;
+ break;
+ case MDB_MEMO:
+ return -1;
+ break;
+ case MDB_MONEY:
+ return 8;
+ break;
+ }
+ return 0;
+}
diff --git a/navit/data/poi_geodownload/libmdb/dump.c b/navit/data/poi_geodownload/libmdb/dump.c
new file mode 100644
index 000000000..7ee17f9a6
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/dump.c
@@ -0,0 +1,39 @@
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+void buffer_dump(const unsigned char* buf, int start, int end)
+{
+ char asc[20];
+ int j, k;
+
+ memset(asc, 0, sizeof(asc));
+ k = 0;
+ for (j=start; j<=end; j++) {
+ if (k == 0) {
+ fprintf(stdout, "%04x ", j);
+ }
+ fprintf(stdout, "%02x ", buf[j]);
+ asc[k] = isprint(buf[j]) ? buf[j] : '.';
+ k++;
+ if (k == 8) {
+ fprintf(stdout, " ");
+ }
+ if (k == 16) {
+ fprintf(stdout, " %s\n", asc);
+ memset(asc, 0, sizeof(asc));
+ k = 0;
+ }
+ }
+ for (j=k; j<16; j++) {
+ fprintf(stdout, " ");
+ }
+ if (k < 8) {
+ fprintf(stdout, " ");
+ }
+ fprintf(stdout, " %s\n", asc);
+}
diff --git a/navit/data/poi_geodownload/libmdb/file.c b/navit/data/poi_geodownload/libmdb/file.c
new file mode 100644
index 000000000..941830c54
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/file.c
@@ -0,0 +1,376 @@
+/* MDB Tools - A library for reading MS Access database files
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+/*
+typedef struct {
+ int pg_size;
+ guint16 row_count_offset;
+ guint16 tab_num_rows_offset;
+ guint16 tab_num_cols_offset;
+ guint16 tab_num_idxs_offset;
+ guint16 tab_num_ridxs_offset;
+ guint16 tab_usage_map_offset;
+ guint16 tab_first_dpg_offset;
+ guint16 tab_cols_start_offset;
+ guint16 tab_ridx_entry_size;
+ guint16 col_fixed_offset;
+ guint16 col_size_offset;
+ guint16 col_num_offset;
+ guint16 tab_col_entry_size;
+ guint16 tab_free_map_offset;
+ guint16 tab_col_offset_var;
+ guint16 tab_col_offset_fixed;
+ guint16 tab_row_col_num_offset;
+} MdbFormatConstants;
+*/
+MdbFormatConstants MdbJet4Constants = {
+ 4096, 0x0c, 16, 45, 47, 51, 55, 56, 63, 12, 15, 23, 5, 25, 59, 7, 21, 9
+};
+MdbFormatConstants MdbJet3Constants = {
+ 2048, 0x08, 12, 25, 27, 31, 35, 36, 43, 8, 13, 16, 1, 18, 39, 3, 14, 5 /* not sure on 5, need to check */
+};
+
+static ssize_t _mdb_read_pg(MdbHandle *mdb, unsigned char *pg_buf, unsigned long pg);
+
+/**
+ * mdb_find_file:
+ * @filename: path to MDB (database) file
+ *
+ * Finds and returns the absolute path to an MDB file. Function will first try
+ * to fstat file as passed, then search through the $MDBPATH if not found.
+ *
+ * Return value: gchar pointer to absolute path. Caller is responsible for
+ * freeing.
+ **/
+
+static gchar *mdb_find_file(char *file_name)
+{
+ struct stat status;
+ gchar *mdbpath, **dir, *tmpfname;
+ unsigned int i = 0;
+
+ /* try the provided file name first */
+ if (!stat(file_name, &status)) {
+ return g_strdup(file_name);
+ }
+
+ /* Now pull apart $MDBPATH and try those */
+ mdbpath = (gchar *) getenv("MDBPATH");
+ /* no path, can't find file */
+ if (!mdbpath || !strlen(mdbpath)) return NULL;
+
+ dir = g_strsplit(mdbpath, ":", 0);
+ while (dir[i]) {
+ if (!strlen(dir[i])) continue;
+ tmpfname = g_strconcat(dir[i++], "/", file_name, NULL);
+ if (!stat(tmpfname, &status)) {
+ g_strfreev(dir);
+ return tmpfname;
+ }
+ g_free(tmpfname);
+ }
+ g_strfreev(dir);
+ return NULL;
+}
+/**
+ * mdb_open:
+ * @filename: path to MDB (database) file
+ * @flags: MDB_NOFLAGS for read-only, MDB_WRITABLE for read/write
+ *
+ * Opens an MDB file and returns an MdbHandle to it. MDB File may be relative
+ * to the current directory, a full path to the file, or relative to a
+ * component of $MDBPATH.
+ *
+ * Return value: pointer to MdbHandle structure.
+ **/
+MdbHandle *mdb_open(char *filename, MdbFileFlags flags)
+{
+ MdbHandle *mdb;
+
+ mdb = (MdbHandle *) g_malloc0(sizeof(MdbHandle));
+ mdb_set_default_backend(mdb, "access");
+ /* need something to bootstrap with, reassign after page 0 is read */
+ mdb->fmt = &MdbJet3Constants;
+ mdb->f = (MdbFile *) g_malloc0(sizeof(MdbFile));
+ mdb->f->refs = 1;
+ mdb->f->fd = -1;
+ mdb->f->filename = (char *) mdb_find_file(filename);
+ if (!mdb->f->filename) {
+ fprintf(stderr, "Can't alloc filename\n");
+ mdb_close(mdb);
+ return NULL;
+ }
+ if (flags & MDB_WRITABLE) {
+ mdb->f->writable = TRUE;
+ mdb->f->fd = open(mdb->f->filename,O_RDWR);
+ } else {
+ mdb->f->fd = open(mdb->f->filename,O_RDONLY);
+ }
+
+ if (mdb->f->fd==-1) {
+ fprintf(stderr,"Couldn't open file %s\n",mdb->f->filename);
+ mdb_close(mdb);
+ return NULL;
+ }
+ if (!mdb_read_pg(mdb, 0)) {
+ fprintf(stderr,"Couldn't read first page.\n");
+ mdb_close(mdb);
+ return NULL;
+ }
+ if (mdb->pg_buf[0] != 0) {
+ mdb_close(mdb);
+ return NULL;
+ }
+ mdb->f->jet_version = mdb_pg_get_int32(mdb, 0x14);
+ if (IS_JET4(mdb)) {
+ mdb->fmt = &MdbJet4Constants;
+ } else if (IS_JET3(mdb)) {
+ mdb->fmt = &MdbJet3Constants;
+ } else {
+ fprintf(stderr,"Unknown Jet version.\n");
+ mdb_close(mdb);
+ return NULL;
+ }
+
+ return mdb;
+}
+
+/**
+ * mdb_close:
+ * @mdb: Handle to open MDB database file
+ *
+ * Dereferences MDB file, closes if reference count is 0, and destroys handle.
+ *
+ **/
+void
+mdb_close(MdbHandle *mdb)
+{
+ if (!mdb) return;
+ mdb_free_catalog(mdb);
+ g_free(mdb->stats);
+ g_free(mdb->backend_name);
+
+ if (mdb->f) {
+ if (mdb->f->refs > 1) {
+ mdb->f->refs--;
+ } else {
+ if (mdb->f->fd != -1) close(mdb->f->fd);
+ g_free(mdb->f->filename);
+ g_free(mdb->f);
+ }
+ }
+
+ g_free(mdb);
+}
+/**
+ * mdb_clone_handle:
+ * @mdb: Handle to open MDB database file
+ *
+ * Clones an existing database handle. Cloned handle shares the file descriptor
+ * but has its own page buffer, page position, and similar internal variables.
+ *
+ * Return value: new handle to the database.
+ */
+MdbHandle *mdb_clone_handle(MdbHandle *mdb)
+{
+ MdbHandle *newmdb;
+ MdbCatalogEntry *entry, *data;
+ unsigned int i;
+
+ newmdb = (MdbHandle *) g_memdup(mdb, sizeof(MdbHandle));
+ newmdb->stats = NULL;
+ newmdb->catalog = g_ptr_array_new();
+ for (i=0;i<mdb->num_catalog;i++) {
+ entry = g_ptr_array_index(mdb->catalog,i);
+ data = g_memdup(entry,sizeof(MdbCatalogEntry));
+ g_ptr_array_add(newmdb->catalog, data);
+ }
+ mdb->backend_name = NULL;
+ if (mdb->f) {
+ mdb->f->refs++;
+ }
+ return newmdb;
+}
+
+/*
+** mdb_read a wrapper for read that bails if anything is wrong
+*/
+ssize_t mdb_read_pg(MdbHandle *mdb, unsigned long pg)
+{
+ ssize_t len;
+
+ if (pg && mdb->cur_pg == pg) return mdb->fmt->pg_size;
+
+ len = _mdb_read_pg(mdb, mdb->pg_buf, pg);
+ //fprintf(stderr, "read page %d type %02x\n", pg, mdb->pg_buf[0]);
+ mdb->cur_pg = pg;
+ /* kan - reset the cur_pos on a new page read */
+ mdb->cur_pos = 0; /* kan */
+ return len;
+}
+ssize_t mdb_read_alt_pg(MdbHandle *mdb, unsigned long pg)
+{
+ ssize_t len;
+
+ len = _mdb_read_pg(mdb, mdb->alt_pg_buf, pg);
+ return len;
+}
+static ssize_t _mdb_read_pg(MdbHandle *mdb, unsigned char *pg_buf, unsigned long pg)
+{
+ ssize_t len;
+ struct stat status;
+ off_t offset = pg * mdb->fmt->pg_size;
+
+ fstat(mdb->f->fd, &status);
+ if (status.st_size < offset) {
+ fprintf(stderr,"offset %lu is beyond EOF\n",offset);
+ return 0;
+ }
+ if (mdb->stats && mdb->stats->collect)
+ mdb->stats->pg_reads++;
+
+ lseek(mdb->f->fd, offset, SEEK_SET);
+ len = read(mdb->f->fd,pg_buf,mdb->fmt->pg_size);
+ if (len==-1) {
+ perror("read");
+ return 0;
+ }
+ else if (len<mdb->fmt->pg_size) {
+ /* fprintf(stderr,"EOF reached %d bytes returned.\n",len, mdb->fmt->pg_size); */
+ return 0;
+ }
+ return len;
+}
+void mdb_swap_pgbuf(MdbHandle *mdb)
+{
+char tmpbuf[MDB_PGSIZE];
+
+ memcpy(tmpbuf,mdb->pg_buf, MDB_PGSIZE);
+ memcpy(mdb->pg_buf,mdb->alt_pg_buf, MDB_PGSIZE);
+ memcpy(mdb->alt_pg_buf,tmpbuf,MDB_PGSIZE);
+}
+
+
+/* really stupid, just here for consistancy */
+unsigned char mdb_get_byte(unsigned char *buf, int offset)
+{
+ return buf[offset];
+}
+unsigned char mdb_pg_get_byte(MdbHandle *mdb, int offset)
+{
+ if (offset < 0 || offset+1 > mdb->fmt->pg_size) return -1;
+ mdb->cur_pos++;
+ return mdb->pg_buf[offset];
+}
+
+int mdb_get_int16(unsigned char *buf, int offset)
+{
+ return buf[offset+1]*256+buf[offset];
+}
+int mdb_pg_get_int16(MdbHandle *mdb, int offset)
+{
+ if (offset < 0 || offset+2 > mdb->fmt->pg_size) return -1;
+ mdb->cur_pos+=2;
+ return mdb_get_int16(mdb->pg_buf, offset);
+}
+
+gint32 mdb_pg_get_int24_msb(MdbHandle *mdb, int offset)
+{
+ gint32 l = 0;
+ if (offset <0 || offset+3 > mdb->fmt->pg_size) return -1;
+ mdb->cur_pos+=3;
+ memcpy((char *)&l+1, &(mdb->pg_buf[offset]), 3);
+#if 0
+ printf("l=0x%08x 0x%08x\n",l,GINT32_FROM_BE(l));
+#endif
+ return GINT32_FROM_BE(l);
+}
+gint32 mdb_get_int24(unsigned char *buf, int offset)
+{
+ gint32 l = 0;
+ memcpy(&l, &buf[offset], 3);
+ return GINT32_FROM_LE(l);
+}
+gint32 mdb_pg_get_int24(MdbHandle *mdb, int offset)
+{
+ if (offset <0 || offset+3 > mdb->fmt->pg_size) return -1;
+ mdb->cur_pos+=3;
+ return mdb_get_int24(mdb->pg_buf, offset);
+}
+
+long mdb_get_int32(unsigned char *buf, int offset)
+{
+ guint32 l;
+ memcpy(&l, &buf[offset], 4);
+ return (long)GINT32_FROM_LE(l);
+}
+long mdb_pg_get_int32(MdbHandle *mdb, int offset)
+{
+ if (offset <0 || offset+4 > mdb->fmt->pg_size) return -1;
+ mdb->cur_pos+=4;
+ return mdb_get_int32(mdb->pg_buf, offset);
+}
+
+float mdb_get_single(unsigned char *buf, int offset)
+{
+ union {guint32 g; float f;} f;
+ memcpy(&f, &buf[offset], 4);
+ f.g = GUINT32_FROM_LE(f.g);
+ return f.f;
+}
+float mdb_pg_get_single(MdbHandle *mdb, int offset)
+{
+ if (offset <0 || offset+4 > mdb->fmt->pg_size) return -1;
+ mdb->cur_pos+=4;
+ return mdb_get_single(mdb->pg_buf, offset);
+}
+
+double mdb_get_double(unsigned char *buf, int offset)
+{
+ union {guint64 g; double d;} d;
+ memcpy(&d, &buf[offset], 8);
+ d.g = GUINT64_FROM_LE(d.g);
+ return d.d;
+}
+double mdb_pg_get_double(MdbHandle *mdb, int offset)
+{
+ if (offset <0 || offset+8 > mdb->fmt->pg_size) return -1;
+ mdb->cur_pos+=8;
+ return mdb_get_double(mdb->pg_buf, offset);
+}
+
+
+int
+mdb_set_pos(MdbHandle *mdb, int pos)
+{
+ if (pos<0 || pos >= mdb->fmt->pg_size) return 0;
+
+ mdb->cur_pos=pos;
+ return pos;
+}
+int mdb_get_pos(MdbHandle *mdb)
+{
+ return mdb->cur_pos;
+}
diff --git a/navit/data/poi_geodownload/libmdb/iconv.c b/navit/data/poi_geodownload/libmdb/iconv.c
new file mode 100644
index 000000000..9f41afe3c
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/iconv.c
@@ -0,0 +1,63 @@
+/* MDB Tools - A library for reading MS Access database files
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+int
+mdb_unicode2ascii(MdbHandle *mdb, unsigned char *buf, int offset, unsigned int len, char *dest)
+{
+ unsigned int i;
+
+ if (buf[offset]==0xff && buf[offset+1]==0xfe) {
+ strncpy(dest, &buf[offset+2], len-2);
+ dest[len-2]='\0';
+ } else {
+ /* convert unicode to ascii, rather sloppily */
+ for (i=0;i<len;i+=2)
+ dest[i/2] = buf[offset + i];
+ dest[len/2]='\0';
+ }
+ return len;
+}
+
+int
+mdb_ascii2unicode(MdbHandle *mdb, unsigned char *buf, int offset, unsigned int len, char *dest)
+{
+ unsigned int i = 0;
+
+ if (!buf) return 0;
+
+ if (IS_JET3(mdb)) {
+ strncpy(dest, &buf[offset], len);
+ dest[len]='\0';
+ return strlen(dest);
+ }
+
+ while (i<strlen(&buf[offset]) && (i*2+2)<len) {
+ dest[i*2] = buf[offset+i];
+ dest[i*2+1] = 0;
+ i++;
+ }
+
+ return (i*2);
+}
diff --git a/navit/data/poi_geodownload/libmdb/include/Makefile.am b/navit/data/poi_geodownload/libmdb/include/Makefile.am
new file mode 100644
index 000000000..084a7542f
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/include/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = mdbtools.h
diff --git a/navit/data/poi_geodownload/libmdb/include/mdbtools.h b/navit/data/poi_geodownload/libmdb/include/mdbtools.h
new file mode 100644
index 000000000..b17df280f
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/include/mdbtools.h
@@ -0,0 +1,536 @@
+/* MDB Tools - A library for reading MS Access database files
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _mdbtools_h_
+#define _mdbtools_h_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <string.h>
+#include <glib.h>
+
+#ifdef HAVE_ICONV
+#include <iconv.h>
+#endif
+
+#define MDB_DEBUG 0
+
+#define MDB_PGSIZE 4096
+#define MDB_MAX_OBJ_NAME 256
+#define MDB_MAX_COLS 256
+#define MDB_MAX_IDX_COLS 10
+#define MDB_CATALOG_PG 18
+#define MDB_MEMO_OVERHEAD 12
+#define MDB_BIND_SIZE 16384
+
+enum {
+ MDB_PAGE_DB = 0,
+ MDB_PAGE_DATA,
+ MDB_PAGE_TABLE,
+ MDB_PAGE_INDEX,
+ MDB_PAGE_LEAF,
+ MDB_PAGE_MAP
+};
+enum {
+ MDB_VER_JET3 = 0,
+ MDB_VER_JET4 = 1
+};
+enum {
+ MDB_FORM = 0,
+ MDB_TABLE,
+ MDB_MACRO,
+ MDB_SYSTEM_TABLE,
+ MDB_REPORT,
+ MDB_QUERY,
+ MDB_LINKED_TABLE,
+ MDB_MODULE,
+ MDB_RELATIONSHIP,
+ MDB_UNKNOWN_09,
+ MDB_UNKNOWN_0A,
+ MDB_DATABASE_PROPERTY,
+ MDB_ANY = -1
+};
+enum {
+ MDB_BOOL = 0x01,
+ MDB_BYTE = 0x02,
+ MDB_INT = 0x03,
+ MDB_LONGINT = 0x04,
+ MDB_MONEY = 0x05,
+ MDB_FLOAT = 0x06,
+ MDB_DOUBLE = 0x07,
+ MDB_SDATETIME = 0x08,
+ MDB_TEXT = 0x0a,
+ MDB_OLE = 0x0b,
+ MDB_MEMO = 0x0c,
+ MDB_REPID = 0x0f,
+ MDB_NUMERIC = 0x10
+};
+
+/* SARG operators */
+enum {
+ MDB_OR = 1,
+ MDB_AND,
+ MDB_NOT,
+ MDB_EQUAL,
+ MDB_GT,
+ MDB_LT,
+ MDB_GTEQ,
+ MDB_LTEQ,
+ MDB_LIKE,
+ MDB_ISNULL,
+ MDB_NOTNULL
+};
+
+typedef enum {
+ MDB_TABLE_SCAN,
+ MDB_LEAF_SCAN,
+ MDB_INDEX_SCAN
+} MdbStrategy;
+
+typedef enum {
+ MDB_NOFLAGS = 0x00,
+ MDB_WRITABLE = 0x01
+} MdbFileFlags;
+
+enum {
+ MDB_DEBUG_LIKE = 0x0001,
+ MDB_DEBUG_WRITE = 0x0002,
+ MDB_DEBUG_USAGE = 0x0004,
+ MDB_DEBUG_OLE = 0x0008,
+ MDB_DEBUG_ROW = 0x0010,
+ MDB_USE_INDEX = 0x0020
+};
+
+#define mdb_is_logical_op(x) (x == MDB_OR || \
+ x == MDB_AND || \
+ x == MDB_NOT )
+
+#define mdb_is_relational_op(x) (x == MDB_EQUAL || \
+ x == MDB_GT || \
+ x == MDB_LT || \
+ x == MDB_GTEQ || \
+ x == MDB_LTEQ || \
+ x == MDB_LIKE || \
+ x == MDB_ISNULL || \
+ x == MDB_NOTNULL )
+
+enum {
+ MDB_ASC,
+ MDB_DESC
+};
+
+enum {
+ MDB_IDX_UNIQUE = 0x01,
+ MDB_IDX_IGNORENULLS = 0x02,
+ MDB_IDX_REQUIRED = 0x08
+};
+
+#define IS_JET4(mdb) (mdb->f->jet_version==MDB_VER_JET4)
+#define IS_JET3(mdb) (mdb->f->jet_version==MDB_VER_JET3)
+
+/* hash to store registered backends */
+/* extern GHashTable *mdb_backends; */
+
+/* forward declarations */
+typedef struct mdbindex MdbIndex;
+typedef struct mdbsargtree MdbSargNode;
+
+typedef struct {
+ char *name;
+ unsigned char needs_length; /* or precision */
+ unsigned char needs_scale;
+ unsigned char needs_quotes;
+} MdbBackendType;
+
+typedef struct {
+ MdbBackendType *types_table;
+} MdbBackend;
+
+typedef struct {
+ gboolean collect;
+ unsigned long pg_reads;
+} MdbStatistics;
+
+typedef struct {
+ int fd;
+ gboolean writable;
+ char *filename;
+ guint32 jet_version;
+ guint32 db_key;
+ char db_passwd[14];
+ MdbBackend *default_backend;
+ char *backend_name;
+ MdbStatistics *stats;
+ /* free map */
+ int map_sz;
+ unsigned char *free_map;
+ /* reference count */
+ int refs;
+} MdbFile;
+
+/* offset to row count on data pages...version dependant */
+typedef struct {
+ int pg_size;
+ guint16 row_count_offset;
+ guint16 tab_num_rows_offset;
+ guint16 tab_num_cols_offset;
+ guint16 tab_num_idxs_offset;
+ guint16 tab_num_ridxs_offset;
+ guint16 tab_usage_map_offset;
+ guint16 tab_first_dpg_offset;
+ guint16 tab_cols_start_offset;
+ guint16 tab_ridx_entry_size;
+ guint16 col_fixed_offset;
+ guint16 col_size_offset;
+ guint16 col_num_offset;
+ guint16 tab_col_entry_size;
+ guint16 tab_free_map_offset;
+ guint16 tab_col_offset_var;
+ guint16 tab_col_offset_fixed;
+ guint16 tab_row_col_num_offset;
+} MdbFormatConstants;
+
+typedef struct {
+ MdbFile *f;
+ guint32 cur_pg;
+ guint16 row_num;
+ unsigned int cur_pos;
+ unsigned char pg_buf[MDB_PGSIZE];
+ unsigned char alt_pg_buf[MDB_PGSIZE];
+ unsigned int num_catalog;
+ GPtrArray *catalog;
+ MdbBackend *default_backend;
+ char *backend_name;
+ MdbFormatConstants *fmt;
+ MdbStatistics *stats;
+#ifdef HAVE_ICONV
+ iconv_t iconv_out;
+#endif
+} MdbHandle;
+
+typedef struct {
+ MdbHandle *mdb;
+ char object_name[MDB_MAX_OBJ_NAME+1];
+ int object_type;
+ unsigned long table_pg; /* misnomer since object may not be a table */
+ unsigned long kkd_pg;
+ unsigned int kkd_rowid;
+ int num_props;
+ GArray *props;
+ GArray *columns;
+ int flags;
+} MdbCatalogEntry;
+
+typedef struct {
+ gchar *name;
+ GHashTable *hash;
+} MdbProperties;
+
+typedef union {
+ int i;
+ double d;
+ char s[256];
+} MdbAny;
+
+typedef struct {
+ char name[MDB_MAX_OBJ_NAME+1];
+ int col_type;
+ int col_size;
+ void *bind_ptr;
+ int *len_ptr;
+ GHashTable *properties;
+ unsigned int num_sargs;
+ GPtrArray *sargs;
+ GPtrArray *idx_sarg_cache;
+ unsigned char is_fixed;
+ int query_order;
+ /* col_num is the current column order,
+ * does not include deletes */
+ int col_num;
+ int cur_value_start;
+ int cur_value_len;
+ /* MEMO/OLE readers */
+ guint32 cur_blob_pg;
+ int cur_blob_row;
+ int chunk_size;
+ /* numerics only */
+ int col_prec;
+ int col_scale;
+ MdbProperties *props;
+ /* info needed for handling deleted/added columns */
+ int fixed_offset;
+ int var_col_num;
+ /* row_col_num is the row column number order,
+ * including deleted columns */
+ int row_col_num;
+} MdbColumn;
+
+struct mdbsargtree {
+ int op;
+ MdbColumn *col;
+ MdbAny value;
+ void *parent;
+ MdbSargNode *left;
+ MdbSargNode *right;
+};
+
+typedef struct {
+ guint32 pg;
+ int start_pos;
+ int offset;
+ int len;
+ guint16 idx_starts[2000];
+ unsigned char cache_value[256];
+} MdbIndexPage;
+
+typedef int (*MdbSargTreeFunc)(MdbSargNode *, gpointer *data);
+
+#define MDB_MAX_INDEX_DEPTH 10
+
+typedef struct {
+ int cur_depth;
+ guint32 last_leaf_found;
+ int clean_up_mode;
+ MdbIndexPage pages[MDB_MAX_INDEX_DEPTH];
+} MdbIndexChain;
+
+typedef struct {
+ MdbCatalogEntry *entry;
+ char name[MDB_MAX_OBJ_NAME+1];
+ unsigned int num_cols;
+ GPtrArray *columns;
+ unsigned int num_rows;
+ int index_start;
+ unsigned int num_real_idxs;
+ unsigned int num_idxs;
+ GPtrArray *indices;
+ guint32 first_data_pg;
+ guint32 cur_pg_num;
+ guint32 cur_phys_pg;
+ unsigned int cur_row;
+ int noskip_del; /* don't skip deleted rows */
+ /* object allocation map */
+ guint32 map_base_pg;
+ unsigned int map_sz;
+ unsigned char *usage_map;
+ /* pages with free space left */
+ guint32 freemap_base_pg;
+ unsigned int freemap_sz;
+ unsigned char *free_usage_map;
+ /* query planner */
+ MdbSargNode *sarg_tree;
+ MdbStrategy strategy;
+ MdbIndex *scan_idx;
+ MdbHandle *mdbidx;
+ MdbIndexChain *chain;
+ MdbProperties *props;
+ unsigned int num_var_cols; /* to know if row has variable columns */
+ /* temp table */
+ unsigned int is_temp_table;
+ GPtrArray *temp_table_pages;
+} MdbTableDef;
+
+struct mdbindex {
+ int index_num;
+ char name[MDB_MAX_OBJ_NAME+1];
+ unsigned char index_type;
+ guint32 first_pg;
+ int num_rows; /* number rows in index */
+ unsigned int num_keys;
+ short key_col_num[MDB_MAX_IDX_COLS];
+ unsigned char key_col_order[MDB_MAX_IDX_COLS];
+ unsigned char flags;
+ MdbTableDef *table;
+};
+
+typedef struct {
+ char name[MDB_MAX_OBJ_NAME+1];
+} MdbColumnProp;
+
+typedef struct {
+ void *value;
+ int siz;
+ int start;
+ unsigned char is_null;
+ unsigned char is_fixed;
+ int colnum;
+ int offset;
+} MdbField;
+
+typedef struct {
+ int op;
+ MdbAny value;
+} MdbSarg;
+
+/* mem.c */
+extern void mdb_init(void);
+extern void mdb_exit(void);
+
+/* file.c */
+extern ssize_t mdb_read_pg(MdbHandle *mdb, unsigned long pg);
+extern ssize_t mdb_read_alt_pg(MdbHandle *mdb, unsigned long pg);
+extern unsigned char mdb_get_byte(unsigned char *buf, int offset);
+extern int mdb_get_int16(unsigned char *buf, int offset);
+extern gint32 mdb_get_int24(unsigned char *buf, int offset);
+extern long mdb_get_int32(unsigned char *buf, int offset);
+extern float mdb_get_single(unsigned char *buf, int offset);
+extern double mdb_get_double(unsigned char *buf, int offset);
+extern unsigned char mdb_pg_get_byte(MdbHandle *mdb, int offset);
+extern int mdb_pg_get_int16(MdbHandle *mdb, int offset);
+extern gint32 mdb_pg_get_int24(MdbHandle *mdb, int offset);
+extern long mdb_pg_get_int32(MdbHandle *mdb, int offset);
+extern float mdb_pg_get_single(MdbHandle *mdb, int offset);
+extern double mdb_pg_get_double(MdbHandle *mdb, int offset);
+extern gint32 mdb_pg_get_int24_msb(MdbHandle *mdb, int offset);
+extern MdbHandle *mdb_open(char *filename, MdbFileFlags flags);
+extern void mdb_close(MdbHandle *mdb);
+extern MdbHandle *mdb_clone_handle(MdbHandle *mdb);
+extern void mdb_swap_pgbuf(MdbHandle *mdb);
+extern long _mdb_get_int32(unsigned char *buf, int offset);
+
+/* catalog.c */
+extern void mdb_free_catalog(MdbHandle *mdb);
+extern GPtrArray *mdb_read_catalog(MdbHandle *mdb, int obj_type);
+extern void mdb_dump_catalog(MdbHandle *mdb, int obj_type);
+extern char *mdb_get_objtype_string(int obj_type);
+
+/* table.c */
+extern MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry);
+extern void mdb_free_tabledef(MdbTableDef *table);
+extern MdbTableDef *mdb_read_table(MdbCatalogEntry *entry);
+extern MdbTableDef *mdb_read_table_by_name(MdbHandle *mdb, gchar *table_name, int obj_type);
+extern void mdb_append_column(GPtrArray *columns, MdbColumn *in_col);
+extern void mdb_free_columns(GPtrArray *columns);
+extern GPtrArray *mdb_read_columns(MdbTableDef *table);
+extern void mdb_table_dump(MdbCatalogEntry *entry);
+extern guint16 read_pg_if_16(MdbHandle *mdb, int *cur_pos);
+extern guint32 read_pg_if_32(MdbHandle *mdb, int *cur_pos);
+extern int read_pg_if(MdbHandle *mdb, int *cur_pos, int offset);
+extern guint16 read_pg_if_n(MdbHandle *mdb, unsigned char *buf, int *cur_pos, int len);
+extern int mdb_is_user_table(MdbCatalogEntry *entry);
+extern int mdb_is_system_table(MdbCatalogEntry *entry);
+
+/* data.c */
+extern int mdb_bind_column_by_name(MdbTableDef *table, gchar *col_name, void *bind_ptr);
+extern void mdb_data_dump(MdbTableDef *table);
+extern void mdb_bind_column(MdbTableDef *table, int col_num, void *bind_ptr);
+extern int mdb_rewind_table(MdbTableDef *table);
+extern int mdb_fetch_row(MdbTableDef *table);
+extern int mdb_is_fixed_col(MdbColumn *col);
+extern char *mdb_col_to_string(MdbHandle *mdb, unsigned char *buf, int start, int datatype, int size);
+extern int mdb_find_pg_row(MdbHandle *mdb, int pg_row, char **buf, int *off, int *len);
+extern int mdb_find_end_of_row(MdbHandle *mdb, int row);
+extern int mdb_col_fixed_size(MdbColumn *col);
+extern int mdb_col_disp_size(MdbColumn *col);
+extern void mdb_bind_len(MdbTableDef *table, int col_num, int *len_ptr);
+extern int mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr);
+extern int mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int chunk_size);
+extern void mdb_set_date_fmt(const char *);
+extern int mdb_read_row(MdbTableDef *table, unsigned int row);
+
+/* dump.c */
+extern void buffer_dump(const unsigned char* buf, int start, int end);
+
+/* backend.c */
+extern char *mdb_get_coltype_string(MdbBackend *backend, int col_type);
+extern int mdb_coltype_takes_length(MdbBackend *backend, int col_type);
+extern void mdb_init_backends(void);
+extern void mdb_register_backend(MdbBackendType *backend, char *backend_name);
+extern void mdb_remove_backends(void);
+extern int mdb_set_default_backend(MdbHandle *mdb, char *backend_name);
+extern char *mdb_get_relationships(MdbHandle *mdb);
+
+/* sargs.c */
+extern int mdb_test_sargs(MdbTableDef *table, MdbField *fields, int num_fields);
+extern int mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSargNode *node, MdbField *field);
+extern void mdb_sql_walk_tree(MdbSargNode *node, MdbSargTreeFunc func, gpointer data);
+extern int mdb_find_indexable_sargs(MdbSargNode *node, gpointer data);
+extern int mdb_add_sarg_by_name(MdbTableDef *table, char *colname, MdbSarg *in_sarg);
+extern int mdb_test_string(MdbSargNode *node, char *s);
+extern int mdb_test_int(MdbSargNode *node, gint32 i);
+extern int mdb_add_sarg(MdbColumn *col, MdbSarg *in_sarg);
+
+
+
+/* index.c */
+extern GPtrArray *mdb_read_indices(MdbTableDef *table);
+extern void mdb_index_dump(MdbTableDef *table, MdbIndex *idx);
+extern void mdb_index_scan_free(MdbTableDef *table);
+extern int mdb_index_find_next_on_page(MdbHandle *mdb, MdbIndexPage *ipg);
+extern int mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 *pg, guint16 *row);
+extern void mdb_index_hash_text(guchar *text, guchar *hash);
+extern void mdb_index_scan_init(MdbHandle *mdb, MdbTableDef *table);
+extern int mdb_index_find_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 pg, guint16 row);
+extern void mdb_index_swap_n(unsigned char *src, int sz, unsigned char *dest);
+extern void mdb_free_indices(GPtrArray *indices);
+void mdb_index_page_reset(MdbIndexPage *ipg);
+extern MdbIndexPage *mdb_index_read_bottom_pg(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain);
+extern MdbIndexPage *mdb_index_unwind(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain);
+extern void mdb_index_page_init(MdbIndexPage *ipg);
+
+
+/* stats.c */
+extern void mdb_stats_on(MdbHandle *mdb);
+extern void mdb_stats_off(MdbHandle *mdb);
+extern void mdb_dump_stats(MdbHandle *mdb);
+
+/* like.c */
+extern int mdb_like_cmp(char *s, char *r);
+
+/* write.c */
+extern int mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields);
+extern guint16 mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_size);
+extern int mdb_update_index(MdbTableDef *table, MdbIndex *idx, unsigned int num_fields, MdbField *fields, guint32 pgnum, guint16 rownum);
+extern int mdb_pack_row(MdbTableDef *table, unsigned char *row_buffer, unsigned int num_fields, MdbField *fields);
+extern int mdb_replace_row(MdbTableDef *table, int row, unsigned char *new_row, int new_row_size);
+extern int mdb_pg_get_freespace(MdbHandle *mdb);
+extern int mdb_update_row(MdbTableDef *table);
+extern unsigned char *mdb_new_data_pg(MdbCatalogEntry *entry);
+
+/* map.c */
+extern guint32 mdb_map_find_next_freepage(MdbTableDef *table, int row_size);
+guint32 mdb_map_find_next(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg);
+
+/* props.c */
+extern GPtrArray *mdb_read_props_list(gchar *kkd, int len);
+extern void mdb_free_props(MdbProperties *props);
+extern MdbProperties *mdb_read_props(MdbHandle *mdb, GPtrArray *names, gchar *kkd, int len);
+
+/* worktable.c */
+extern MdbTableDef *mdb_create_temp_table(MdbHandle *mdb, char *name);
+extern void mdb_temp_table_add_col(MdbTableDef *table, MdbColumn *col);
+extern void mdb_fill_temp_col(MdbColumn *tcol, char *col_name, int col_size, int col_type, int is_fixed);
+extern void mdb_fill_temp_field(MdbField *field, void *value, int siz, int is_fixed, int is_null, int start, int column);
+extern void mdb_temp_columns_end(MdbTableDef *table);
+
+/* options.c */
+extern int mdb_get_option(unsigned long optnum);
+extern void mdb_debug(int klass, char *fmt, ...);
+
+/* iconv.c */
+extern int mdb_unicode2ascii(MdbHandle *mdb, unsigned char *buf, int offset, unsigned int len, char *dest);
+extern int mdb_ascii2unicode(MdbHandle *mdb, unsigned char *buf, int offset, unsigned int len, char *dest);
+
+#endif /* _mdbtools_h_ */
diff --git a/navit/data/poi_geodownload/libmdb/index.c b/navit/data/poi_geodownload/libmdb/index.c
new file mode 100644
index 000000000..e840536eb
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/index.c
@@ -0,0 +1,905 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000-2004 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+MdbIndexPage *mdb_index_read_bottom_pg(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain);
+MdbIndexPage *mdb_chain_add_page(MdbHandle *mdb, MdbIndexChain *chain, guint32 pg);
+
+char idx_to_text[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0-7 0x00-0x07 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8-15 0x09-0x0f */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 16-23 0x10-0x17 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 24-31 0x19-0x1f */
+' ', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 32-39 0x20-0x27 */
+0x00, 0x00, 0x00, 0x00, 0x00, ' ', ' ', 0x00, /* 40-47 0x29-0x2f */
+'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', /* 48-55 0x30-0x37 */
+'^', '_', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 56-63 0x39-0x3f */
+0x00, '`', 'a', 'b', 'd', 'f', 'g', 'h', /* 64-71 0x40-0x47 */
+'i', 'j', 'k', 'l', 'm', 'o', 'p', 'r', /* 72-79 0x49-0x4f H */
+'s', 't', 'u', 'v', 'w', 'x', 'z', '{', /* 80-87 0x50-0x57 P */
+'|', '}', '~', '5', '6', '7', '8', '9', /* 88-95 0x59-0x5f */
+0x00, '`', 'a', 'b', 'd', 'f', 'g', 'h', /* 96-103 0x60-0x67 */
+'i', 'j', 'k', 'l', 'm', 'o', 'p', 'r', /* 014-111 0x69-0x6f h */
+'s', 't', 'u', 'v', 'w', 'x', 'z', '{', /* 112-119 0x70-0x77 p */
+'|', '}', '~', 0x00, 0x00, 0x00, 0x00, 0x00, /* 120-127 0x78-0x7f */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128-135 0x80-0x87 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */
+0x00, 0x00, 0x00, 0x00, 0x00, '`', 0x00, 0x00, /* 0xc0-0xc7 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
+0x00, '`', 0x00, '`', '`', '`', 0x00, 0x00, /* 0xe0-0xe7 */
+'f', 'f', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
+0x00, 0x00, 0x00, 'r', 0x00, 0x00, 'r', 0x00, /* 0xf0-0xf7 */
+0x81, 0x00, 0x00, 0x00, 'x', 0x00, 0x00, 0x00, /* 0xf8-0xff */
+};
+
+
+GPtrArray *
+mdb_read_indices(MdbTableDef *table)
+{
+ MdbCatalogEntry *entry = table->entry;
+ MdbHandle *mdb = entry->mdb;
+ MdbFormatConstants *fmt = mdb->fmt;
+ MdbIndex *pidx;
+ unsigned int i, j;
+ int idx_num, key_num, col_num;
+ int cur_pos, name_sz, idx2_sz, type_offset;
+ int index_start_pg = mdb->cur_pg;
+ gchar *tmpbuf;
+
+ table->indices = g_ptr_array_new();
+
+ if (IS_JET4(mdb)) {
+ cur_pos = table->index_start + 52 * table->num_real_idxs;
+ idx2_sz = 28;
+ type_offset = 23;
+ } else {
+ cur_pos = table->index_start + 39 * table->num_real_idxs;
+ idx2_sz = 20;
+ type_offset = 19;
+ }
+
+ tmpbuf = (gchar *) g_malloc(idx2_sz);
+ for (i=0;i<table->num_idxs;i++) {
+ read_pg_if_n(mdb, tmpbuf, &cur_pos, idx2_sz);
+ cur_pos += idx2_sz;
+ pidx = (MdbIndex *) g_malloc0(sizeof(MdbIndex));
+ pidx->table = table;
+ pidx->index_num = mdb_get_int16(tmpbuf, 4);
+ pidx->index_type = tmpbuf[type_offset];
+ g_ptr_array_add(table->indices, pidx);
+ }
+ g_free(tmpbuf);
+
+ for (i=0;i<table->num_idxs;i++) {
+ pidx = g_ptr_array_index (table->indices, i);
+ if (IS_JET4(mdb)) {
+ name_sz=read_pg_if_16(mdb, &cur_pos);
+ cur_pos += 2;
+ tmpbuf = g_malloc(name_sz);
+ read_pg_if_n(mdb, tmpbuf, &cur_pos, name_sz);
+ cur_pos += name_sz;
+ mdb_unicode2ascii(mdb, tmpbuf, 0, name_sz, pidx->name);
+ g_free(tmpbuf);
+ } else {
+ read_pg_if(mdb, &cur_pos, 0);
+ name_sz=mdb->pg_buf[cur_pos++];
+ read_pg_if_n(mdb, pidx->name, &cur_pos, name_sz);
+ cur_pos += name_sz;
+ pidx->name[name_sz]='\0';
+ }
+ //fprintf(stderr, "index name %s\n", pidx->name);
+ }
+
+ mdb_read_alt_pg(mdb, entry->table_pg);
+ mdb_read_pg(mdb, index_start_pg);
+ cur_pos = table->index_start;
+ idx_num=0;
+ for (i=0;i<table->num_real_idxs;i++) {
+ if (IS_JET4(mdb)) cur_pos += 4;
+ do {
+ pidx = g_ptr_array_index (table->indices, idx_num++);
+ } while (pidx && pidx->index_type==2);
+
+ /* if there are more real indexes than index entries left after
+ removing type 2's decrement real indexes and continue. Happens
+ on Northwind Orders table.
+ */
+ if (!pidx) {
+ table->num_real_idxs--;
+ continue;
+ }
+
+ pidx->num_rows = mdb_get_int32(mdb->alt_pg_buf,
+ fmt->tab_cols_start_offset +
+ (i*fmt->tab_ridx_entry_size));
+
+ key_num=0;
+ for (j=0;j<MDB_MAX_IDX_COLS;j++) {
+ col_num=read_pg_if_16(mdb,&cur_pos);
+ cur_pos += 2;
+ read_pg_if(mdb, &cur_pos, 0);
+ cur_pos++;
+ if (col_num == 0xFFFF)
+ continue;
+ /* set column number to a 1 based column number and store */
+ pidx->key_col_num[key_num] = col_num + 1;
+ pidx->key_col_order[key_num] =
+ (mdb->pg_buf[cur_pos-1]) ? MDB_ASC : MDB_DESC;
+ key_num++;
+ }
+ pidx->num_keys = key_num;
+
+ cur_pos += 4;
+ pidx->first_pg = read_pg_if_32(mdb, &cur_pos);
+ cur_pos += 4;
+ read_pg_if(mdb, &cur_pos, 0);
+ pidx->flags = mdb->pg_buf[cur_pos++];
+ if (IS_JET4(mdb)) cur_pos += 9;
+ }
+ return NULL;
+}
+void
+mdb_index_hash_text(guchar *text, guchar *hash)
+{
+ unsigned int k;
+
+ for (k=0;k<strlen(text);k++) {
+ hash[k] = idx_to_text[text[k]];
+ if (!(hash[k])) fprintf(stderr,
+ "No translation available for %02x %d\n",
+ text[k],text[k]);
+ }
+ hash[strlen(text)]=0;
+}
+void
+mdb_index_swap_n(unsigned char *src, int sz, unsigned char *dest)
+{
+ int i, j = 0;
+
+ for (i = sz; i > 0; i--) {
+ dest[j++] = src[i];
+ }
+}
+void
+mdb_index_cache_sarg(MdbColumn *col, MdbSarg *sarg, MdbSarg *idx_sarg)
+{
+ //guint32 cache_int;
+ unsigned char *c;
+
+ switch (col->col_type) {
+ case MDB_TEXT:
+ mdb_index_hash_text(sarg->value.s, idx_sarg->value.s);
+ break;
+
+ case MDB_LONGINT:
+ idx_sarg->value.i = GUINT32_SWAP_LE_BE(sarg->value.i);
+ //cache_int = sarg->value.i * -1;
+ c = (unsigned char *) &(idx_sarg->value.i);
+ c[0] |= 0x80;
+ //printf("int %08x %02x %02x %02x %02x\n", sarg->value.i, c[0], c[1], c[2], c[3]);
+ break;
+
+ case MDB_INT:
+ break;
+
+ default:
+ break;
+ }
+}
+#if 0
+int
+mdb_index_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSarg *sarg, int offset, int len)
+{
+char tmpbuf[256];
+int lastchar;
+
+ switch (col->col_type) {
+ case MDB_BYTE:
+ return mdb_test_int(sarg, mdb_pg_get_byte(mdb, offset));
+ break;
+ case MDB_INT:
+ return mdb_test_int(sarg, mdb_pg_get_int16(mdb, offset));
+ break;
+ case MDB_LONGINT:
+ return mdb_test_int(sarg, mdb_pg_get_int32(mdb, offset));
+ break;
+ case MDB_TEXT:
+ strncpy(tmpbuf, &mdb->pg_buf[offset],255);
+ lastchar = len > 255 ? 255 : len;
+ tmpbuf[lastchar]='\0';
+ return mdb_test_string(sarg, tmpbuf);
+ default:
+ fprintf(stderr, "Calling mdb_test_sarg on unknown type. Add code to mdb_test_sarg() for type %d\n",col->col_type);
+ break;
+ }
+ return 1;
+}
+#endif
+int
+mdb_index_test_sargs(MdbHandle *mdb, MdbIndex *idx, unsigned char *buf, int len)
+{
+ unsigned int i, j;
+ MdbColumn *col;
+ MdbTableDef *table = idx->table;
+ MdbSarg *idx_sarg;
+ MdbSarg *sarg;
+ MdbField field;
+ MdbSargNode node;
+ //int c_offset = 0,
+ int c_len;
+
+#if 0
+ fprintf(stderr,"mdb_index_test_sargs called on ");
+ for (i=0;i<len;i++)
+ fprintf(stderr,"%02x ",buf[i]); //mdb->pg_buf[offset+i]);
+ fprintf(stderr,"\n");
+#endif
+ for (i=0;i<idx->num_keys;i++) {
+ //c_offset++; /* the per column null indicator/flags */
+ col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
+ /*
+ * This will go away eventually
+ */
+ if (col->col_type==MDB_TEXT) {
+ //c_len = strlen(&mdb->pg_buf[offset + c_offset]);
+ c_len = strlen(buf);
+ } else {
+ c_len = col->col_size;
+ //fprintf(stderr,"Only text types currently supported. How did we get here?\n");
+ }
+ /*
+ * If we have no cached index values for this column,
+ * create them.
+ */
+ if (col->num_sargs && !col->idx_sarg_cache) {
+ col->idx_sarg_cache = g_ptr_array_new();
+ for (j=0;j<col->num_sargs;j++) {
+ sarg = g_ptr_array_index (col->sargs, j);
+ idx_sarg = g_memdup(sarg,sizeof(MdbSarg));
+ //printf("calling mdb_index_cache_sarg\n");
+ mdb_index_cache_sarg(col, sarg, idx_sarg);
+ g_ptr_array_add(col->idx_sarg_cache, idx_sarg);
+ }
+ }
+
+ for (j=0;j<col->num_sargs;j++) {
+ sarg = g_ptr_array_index (col->idx_sarg_cache, j);
+ /* XXX - kludge */
+ node.op = sarg->op;
+ node.value = sarg->value;
+ //field.value = &mdb->pg_buf[offset + c_offset];
+ field.value = buf;
+ field.siz = c_len;
+ field.is_null = FALSE;
+ if (!mdb_test_sarg(mdb, col, &node, &field)) {
+ /* sarg didn't match, no sense going on */
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+/*
+ * pack the pages bitmap
+ */
+int
+mdb_index_pack_bitmap(MdbHandle *mdb, MdbIndexPage *ipg)
+{
+ int mask_bit = 0;
+ int mask_pos = 0x16;
+ int mask_byte = 0;
+ int elem = 0;
+ int len, start, i;
+
+ start = ipg->idx_starts[elem++];
+
+ while (start) {
+ len = ipg->idx_starts[elem] - start;
+ fprintf(stdout, "len is %d\n", len);
+ for (i=0; i < len; i++) {
+ mask_bit++;
+ if (mask_bit==8) {
+ mask_bit=0;
+ mdb->pg_buf[mask_pos++] = mask_byte;
+ mask_byte = 0;
+ }
+ /* upon reaching the len, set the bit */
+ }
+ mask_byte = (1 << mask_bit) | mask_byte;
+ fprintf(stdout, "mask byte is %02x at %d\n", mask_byte, mask_pos);
+ start = ipg->idx_starts[elem++];
+ }
+ /* flush the last byte if any */
+ mdb->pg_buf[mask_pos++] = mask_byte;
+ /* remember to zero the rest of the bitmap */
+ for (i = mask_pos; i < 0xf8; i++) {
+ mdb->pg_buf[mask_pos++] = 0;
+ }
+ return 0;
+}
+/*
+ * unpack the pages bitmap
+ */
+int
+mdb_index_unpack_bitmap(MdbHandle *mdb, MdbIndexPage *ipg)
+{
+ int mask_bit = 0;
+ int mask_pos = 0x16;
+ int mask_byte;
+ int start = 0xf8;
+ int elem = 0;
+ int len = 0;
+
+ ipg->idx_starts[elem++]=start;
+
+#if 0
+ fprintf(stdout, "Unpacking index page %u\n", ipg->pg);
+#endif
+ do {
+ len = 0;
+ do {
+ mask_bit++;
+ if (mask_bit==8) {
+ mask_bit=0;
+ mask_pos++;
+ }
+ mask_byte = mdb->pg_buf[mask_pos];
+ len++;
+ } while (mask_pos <= 0xf8 && !((1 << mask_bit) & mask_byte));
+ //fprintf(stdout, "%d %d %d %d\n", mask_pos, mask_bit, mask_byte, len);
+
+ start += len;
+ if (mask_pos < 0xf8) ipg->idx_starts[elem++]=start;
+
+ } while (mask_pos < 0xf8);
+
+ /* if we zero the next element, so we don't pick up the last pages starts*/
+ ipg->idx_starts[elem]=0;
+
+ return elem;
+}
+/*
+ * find the next entry on a page (either index or leaf). Uses state information
+ * stored in the MdbIndexPage across calls.
+ */
+int
+mdb_index_find_next_on_page(MdbHandle *mdb, MdbIndexPage *ipg)
+{
+ if (!ipg->pg) return 0;
+
+ /* if this page has not been unpacked to it */
+ if (!ipg->idx_starts[0]){
+ //fprintf(stdout, "Unpacking page %d\n", ipg->pg);
+ mdb_index_unpack_bitmap(mdb, ipg);
+ }
+
+
+ if (ipg->idx_starts[ipg->start_pos + 1]==0) return 0;
+ ipg->len = ipg->idx_starts[ipg->start_pos+1] - ipg->idx_starts[ipg->start_pos];
+ ipg->start_pos++;
+ //fprintf(stdout, "Start pos %d\n", ipg->start_pos);
+
+ return ipg->len;
+}
+void mdb_index_page_reset(MdbIndexPage *ipg)
+{
+ ipg->offset = 0xf8; /* start byte of the index entries */
+ ipg->start_pos=0;
+ ipg->len = 0;
+ ipg->idx_starts[0]=0;
+}
+void mdb_index_page_init(MdbIndexPage *ipg)
+{
+ memset(ipg, 0, sizeof(MdbIndexPage));
+ mdb_index_page_reset(ipg);
+}
+/*
+ * find the next leaf page if any given a chain. Assumes any exhausted leaf
+ * pages at the end of the chain have been peeled off before the call.
+ */
+MdbIndexPage *
+mdb_find_next_leaf(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
+{
+ MdbIndexPage *ipg, *newipg;
+ guint32 pg;
+ guint passed = 0;
+
+ ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
+
+ /*
+ * If we are at the first page deep and it's not an index page then
+ * we are simply done. (there is no page to find
+ */
+
+ if (mdb->pg_buf[0]==MDB_PAGE_LEAF) {
+ /* Indexes can have leaves at the end that don't appear
+ * in the upper tree, stash the last index found so
+ * we can follow it at the end. */
+ chain->last_leaf_found = ipg->pg;
+ return ipg;
+ }
+
+ /*
+ * apply sargs here, currently we don't
+ */
+ do {
+ ipg->len = 0;
+ //printf("finding next on pg %lu\n", ipg->pg);
+ if (!mdb_index_find_next_on_page(mdb, ipg)) {
+ //printf("find_next_on_page returned 0\n");
+ return 0;
+ }
+ pg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 3);
+ //printf("Looking at pg %lu at %lu %d\n", pg, ipg->offset, ipg->len);
+ ipg->offset += ipg->len;
+
+ /*
+ * add to the chain and call this function
+ * recursively.
+ */
+ newipg = mdb_chain_add_page(mdb, chain, pg);
+ newipg = mdb_find_next_leaf(mdb, idx, chain);
+ //printf("returning pg %lu\n",newipg->pg);
+ return newipg;
+ } while (!passed);
+ /* no more pages */
+ return NULL;
+
+}
+MdbIndexPage *
+mdb_chain_add_page(MdbHandle *mdb, MdbIndexChain *chain, guint32 pg)
+{
+ MdbIndexPage *ipg;
+
+ chain->cur_depth++;
+ if (chain->cur_depth > MDB_MAX_INDEX_DEPTH) {
+ fprintf(stderr,"Error! maximum index depth of %d exceeded. This is probably due to a programming bug, If you are confident that your indexes really are this deep, adjust MDB_MAX_INDEX_DEPTH in mdbtools.h and recompile.\n", MDB_MAX_INDEX_DEPTH);
+ exit(1);
+ }
+ ipg = &(chain->pages[chain->cur_depth - 1]);
+ mdb_index_page_init(ipg);
+ ipg->pg = pg;
+
+ return ipg;
+}
+/*
+ * returns the bottom page of the IndexChain, if IndexChain is empty it
+ * initializes it by reading idx->first_pg (the root page)
+ */
+MdbIndexPage *
+mdb_index_read_bottom_pg(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
+{
+ MdbIndexPage *ipg;
+
+ /*
+ * if it's new use the root index page (idx->first_pg)
+ */
+ if (!chain->cur_depth) {
+ ipg = &(chain->pages[0]);
+ mdb_index_page_init(ipg);
+ chain->cur_depth = 1;
+ ipg->pg = idx->first_pg;
+ if (!(ipg = mdb_find_next_leaf(mdb, idx, chain)))
+ return 0;
+ } else {
+ ipg = &(chain->pages[chain->cur_depth - 1]);
+ ipg->len = 0;
+ }
+
+ mdb_read_pg(mdb, ipg->pg);
+
+ return ipg;
+}
+/*
+ * unwind the stack and search for new leaf node
+ */
+MdbIndexPage *
+mdb_index_unwind(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
+{
+ MdbIndexPage *ipg;
+
+ //printf("page %lu finished\n",ipg->pg);
+ if (chain->cur_depth==1) {
+ //printf("cur_depth == 1 we're out\n");
+ return NULL;
+ }
+ /*
+ * unwind the stack until we find something or reach
+ * the top.
+ */
+ ipg = NULL;
+ while (chain->cur_depth>1 && ipg==NULL) {
+ //printf("chain depth %d\n", chain->cur_depth);
+ chain->cur_depth--;
+ ipg = mdb_find_next_leaf(mdb, idx, chain);
+ if (ipg) mdb_index_find_next_on_page(mdb, ipg);
+ }
+ if (chain->cur_depth==1) {
+ //printf("last leaf %lu\n", chain->last_leaf_found);
+ return NULL;
+ }
+ return ipg;
+}
+/*
+ * the main index function.
+ * caller provides an index chain which is the current traversal of index
+ * pages from the root page to the leaf. Initially passed as blank,
+ * mdb_index_find_next will store it's state information here. Each invocation
+ * then picks up where the last one left off, allowing us to scroll through
+ * the index one by one.
+ *
+ * Sargs are applied here but also need to be applied on the whole row b/c
+ * text columns may return false positives due to hashing and non-index
+ * columns with sarg values can't be tested here.
+ */
+int
+mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 *pg, guint16 *row)
+{
+ MdbIndexPage *ipg;
+ int passed = 0;
+ int idx_sz;
+ int idx_start = 0;
+ MdbColumn *col;
+
+ ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
+
+ /*
+ * loop while the sargs don't match
+ */
+ do {
+ ipg->len = 0;
+ /*
+ * if no more rows on this leaf, try to find a new leaf
+ */
+ if (!mdb_index_find_next_on_page(mdb, ipg)) {
+ if (!chain->clean_up_mode) {
+ if (!(ipg = mdb_index_unwind(mdb, idx, chain)))
+ chain->clean_up_mode = 1;
+ }
+ if (chain->clean_up_mode) {
+ //fprintf(stdout,"in cleanup mode\n");
+
+ if (!chain->last_leaf_found) return 0;
+ mdb_read_pg(mdb, chain->last_leaf_found);
+ chain->last_leaf_found = mdb_pg_get_int24(mdb, 0x0c);
+ //printf("next leaf %lu\n", chain->last_leaf_found);
+ mdb_read_pg(mdb, chain->last_leaf_found);
+ /* reuse the chain for cleanup mode */
+ chain->cur_depth = 1;
+ ipg = &chain->pages[0];
+ mdb_index_page_init(ipg);
+ ipg->pg = chain->last_leaf_found;
+ //printf("next on page %d\n",
+ if (!mdb_index_find_next_on_page(mdb, ipg))
+ return 0;
+ }
+ }
+ *row = mdb->pg_buf[ipg->offset + ipg->len - 1];
+#if 0
+ printf("page: ");
+ buffer_dump(mdb->pg_buf, ipg->offset+ipg->len-4, ipg->offset+ipg->len-2);
+#endif
+ *pg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 4);
+#if 0
+ printf("row = %d pg = %lu ipg->pg = %lu offset = %lu len = %d\n", *row, *pg, ipg->pg, ipg->offset, ipg->len);
+#endif
+ col=g_ptr_array_index(idx->table->columns,idx->key_col_num[0]-1);
+ idx_sz = mdb_col_fixed_size(col);
+ /* handle compressed indexes, single key indexes only? */
+ if (idx->num_keys==1 && idx_sz>0 && ipg->len - 4 < idx_sz) {
+#if 0
+ printf("short index found\n");
+ buffer_dump(ipg->cache_value, 0, idx_sz);
+#endif
+ memcpy(&ipg->cache_value[idx_sz - (ipg->len - 4)], &mdb->pg_buf[ipg->offset], ipg->len);
+#if 0
+ buffer_dump(ipg->cache_value, 0, idx_sz);
+#endif
+ } else {
+ idx_start = ipg->offset + (ipg->len - 4 - idx_sz);
+ memcpy(ipg->cache_value, &mdb->pg_buf[idx_start], idx_sz);
+ }
+
+ //idx_start = ipg->offset + (ipg->len - 4 - idx_sz);
+ passed = mdb_index_test_sargs(mdb, idx, ipg->cache_value, idx_sz);
+
+// printf("passed=%d\n", passed);
+
+ buffer_dump(mdb->pg_buf, ipg->offset, ipg->offset+ipg->len-1);
+ ipg->offset += ipg->len;
+
+ } while (!passed);
+
+#if 0
+ fprintf(stdout,"len = %d pos %d\n", ipg->len, ipg->len);
+ buffer_dump(mdb->pg_buf, ipg->offset, ipg->offset+ipg->len-1);
+#endif
+
+ return ipg->len;
+}
+/*
+ * XXX - FIX ME
+ * This function is grossly inefficient. It scans the entire index building
+ * an IndexChain to a specific row. We should be checking the index pages
+ * for matches against the indexed fields to find the proper leaf page, but
+ * getting it working first and then make it fast!
+ */
+int
+mdb_index_find_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 pg, guint16 row)
+{
+ MdbIndexPage *ipg;
+ int passed = 0;
+ guint32 datapg;
+ guint16 datarow;
+
+ ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
+
+ do {
+ ipg->len = 0;
+ /*
+ * if no more rows on this leaf, try to find a new leaf
+ */
+ if (!mdb_index_find_next_on_page(mdb, ipg)) {
+ /* back to top? We're done */
+ if (chain->cur_depth==1)
+ return 0;
+
+ /*
+ * unwind the stack until we find something or reach
+ * the top.
+ */
+ while (chain->cur_depth>1) {
+ chain->cur_depth--;
+ if (!(ipg = mdb_find_next_leaf(mdb, idx, chain)))
+ return 0;
+ mdb_index_find_next_on_page(mdb, ipg);
+ }
+ if (chain->cur_depth==1)
+ return 0;
+ }
+ /* test row and pg */
+ datarow = mdb->pg_buf[ipg->offset + ipg->len - 1];
+ datapg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 4);
+
+ if (datapg == pg && datarow == row) {
+ passed = 1;
+ }
+ ipg->offset += ipg->len;
+ } while (!passed);
+
+ /* index chain from root to leaf should now be in "chain" */
+ return 1;
+}
+
+void mdb_index_walk(MdbTableDef *table, MdbIndex *idx)
+{
+MdbHandle *mdb = table->entry->mdb;
+int cur_pos = 0;
+unsigned char marker;
+MdbColumn *col;
+unsigned int i;
+
+ if (idx->num_keys!=1) return;
+
+ mdb_read_pg(mdb, idx->first_pg);
+ cur_pos = 0xf8;
+
+ for (i=0;i<idx->num_keys;i++) {
+ marker = mdb->pg_buf[cur_pos++];
+ col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
+ //printf("column %d coltype %d col_size %d (%d)\n",i,col->col_type, mdb_col_fixed_size(col), col->col_size);
+ }
+}
+void
+mdb_index_dump(MdbTableDef *table, MdbIndex *idx)
+{
+ unsigned int i;
+ MdbColumn *col;
+
+ fprintf(stdout,"index number %d\n", idx->index_num);
+ fprintf(stdout,"index name %s\n", idx->name);
+ fprintf(stdout,"index first page %d\n", idx->first_pg);
+ fprintf(stdout,"index rows %d\n", idx->num_rows);
+ if (idx->index_type==1) fprintf(stdout,"index is a primary key\n");
+ for (i=0;i<idx->num_keys;i++) {
+ col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
+ fprintf(stdout,"Column %s(%d) Sorted %s Unique: %s\n",
+ col->name,
+ idx->key_col_num[i],
+ idx->key_col_order[i]==MDB_ASC ? "ascending" : "descending",
+ idx->flags & MDB_IDX_UNIQUE ? "Yes" : "No"
+ );
+ }
+ mdb_index_walk(table, idx);
+}
+/*
+ * compute_cost tries to assign a cost to a given index using the sargs
+ * available in this query.
+ *
+ * Indexes with no matching sargs are assigned 0
+ * Unique indexes are preferred over non-uniques
+ * Operator preference is equal, like, isnull, others
+ */
+int mdb_index_compute_cost(MdbTableDef *table, MdbIndex *idx)
+{
+ unsigned int i;
+ MdbColumn *col;
+ MdbSarg *sarg = NULL;
+ int not_all_equal = 0;
+
+ if (!idx->num_keys) return 0;
+ if (idx->num_keys > 1) {
+ for (i=0;i<idx->num_keys;i++) {
+ col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
+ if (col->sargs) sarg = g_ptr_array_index (col->sargs, 0);
+ if (!sarg || sarg->op != MDB_EQUAL) not_all_equal++;
+ }
+ }
+
+ col=g_ptr_array_index(table->columns,idx->key_col_num[0]-1);
+ /*
+ * if this is the first key column and there are no sargs,
+ * then this index is useless.
+ */
+ if (!col->num_sargs) return 0;
+
+ sarg = g_ptr_array_index (col->sargs, 0);
+
+ /*
+ * a like with a wild card first is useless as a sarg */
+ if (sarg->op == MDB_LIKE && sarg->value.s[0]=='%')
+ return 0;
+
+ /*
+ * this needs a lot of tweaking.
+ */
+ if (idx->flags & MDB_IDX_UNIQUE) {
+ if (idx->num_keys == 1) {
+ //printf("op is %d\n", sarg->op);
+ switch (sarg->op) {
+ case MDB_EQUAL:
+ return 1; break;
+ case MDB_LIKE:
+ return 4; break;
+ case MDB_ISNULL:
+ return 12; break;
+ default:
+ return 8; break;
+ }
+ } else {
+ switch (sarg->op) {
+ case MDB_EQUAL:
+ if (not_all_equal) return 2;
+ else return 1;
+ break;
+ case MDB_LIKE:
+ return 6; break;
+ case MDB_ISNULL:
+ return 12; break;
+ default:
+ return 9; break;
+ }
+ }
+ } else {
+ if (idx->num_keys == 1) {
+ switch (sarg->op) {
+ case MDB_EQUAL:
+ return 2; break;
+ case MDB_LIKE:
+ return 5; break;
+ case MDB_ISNULL:
+ return 12; break;
+ default:
+ return 10; break;
+ }
+ } else {
+ switch (sarg->op) {
+ case MDB_EQUAL:
+ if (not_all_equal) return 3;
+ else return 2;
+ break;
+ case MDB_LIKE:
+ return 7; break;
+ case MDB_ISNULL:
+ return 12; break;
+ default:
+ return 11; break;
+ }
+ }
+ }
+ return 0;
+}
+/*
+ * choose_index runs mdb_index_compute_cost for each available index and picks
+ * the best.
+ *
+ * Returns strategy to use (table scan, or index scan)
+ */
+MdbStrategy
+mdb_choose_index(MdbTableDef *table, int *choice)
+{
+ unsigned int i;
+ MdbIndex *idx;
+ int cost = 0;
+ int least = 99;
+
+ *choice = -1;
+ for (i=0;i<table->num_idxs;i++) {
+ idx = g_ptr_array_index (table->indices, i);
+ cost = mdb_index_compute_cost(table, idx);
+ //printf("cost for %s is %d\n", idx->name, cost);
+ if (cost && cost < least) {
+ least = cost;
+ *choice = i;
+ }
+ }
+ /* and the winner is: *choice */
+ if (least==99) return MDB_TABLE_SCAN;
+ return MDB_INDEX_SCAN;
+}
+void
+mdb_index_scan_init(MdbHandle *mdb, MdbTableDef *table)
+{
+ int i;
+
+ if (mdb_get_option(MDB_USE_INDEX) && mdb_choose_index(table, &i) == MDB_INDEX_SCAN) {
+ table->strategy = MDB_INDEX_SCAN;
+ table->scan_idx = g_ptr_array_index (table->indices, i);
+ table->chain = g_malloc0(sizeof(MdbIndexChain));
+ table->mdbidx = mdb_clone_handle(mdb);
+ mdb_read_pg(table->mdbidx, table->scan_idx->first_pg);
+ //printf("best index is %s\n",table->scan_idx->name);
+ }
+ //printf("TABLE SCAN? %d\n", table->strategy);
+}
+void
+mdb_index_scan_free(MdbTableDef *table)
+{
+ if (table->chain) {
+ g_free(table->chain);
+ table->chain = NULL;
+ }
+ if (table->mdbidx) {
+ mdb_close(table->mdbidx);
+ table->mdbidx = NULL;
+ }
+}
+
+void mdb_free_indices(GPtrArray *indices)
+{
+ unsigned int i;
+
+ if (!indices) return;
+ for (i=0; i<indices->len; i++)
+ g_free (g_ptr_array_index(indices, i));
+ g_ptr_array_free(indices, TRUE);
+}
diff --git a/navit/data/poi_geodownload/libmdb/kkd.c b/navit/data/poi_geodownload/libmdb/kkd.c
new file mode 100644
index 000000000..ea72887c4
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/kkd.c
@@ -0,0 +1,149 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+
+/*
+** Note: This code is mostly garbage right now...just a test to parse out the
+** KKD structures.
+*/
+
+GArray *mdb_get_column_props(MdbCatalogEntry *entry, int start)
+{
+int pos, cnt=0;
+int len, tmp, cplen;
+MdbColumnProp prop;
+MdbHandle *mdb = entry->mdb;
+
+ entry->props = g_array_new(FALSE,FALSE,sizeof(MdbColumnProp));
+ len = mdb_pg_get_int16(mdb,start);
+ pos = start + 6;
+ while (pos < start+len) {
+ tmp = mdb_pg_get_int16(mdb,pos); /* length of string */
+ pos += 2;
+ cplen = tmp > MDB_MAX_OBJ_NAME ? MDB_MAX_OBJ_NAME : tmp;
+ g_memmove(prop.name,&mdb->pg_buf[pos],cplen);
+ prop.name[cplen]='\0';
+ pos += tmp;
+ g_array_append_val(entry->props, prop.name);
+ cnt++;
+ }
+ entry->num_props = cnt;
+ return entry->props;
+}
+
+GHashTable *mdb_get_column_def(MdbCatalogEntry *entry, int start)
+{
+GHashTable *hash = NULL;
+MdbHandle *mdb = entry->mdb;
+MdbColumnProp prop;
+int tmp, pos, col_num, val_len, i;
+int len, col_type;
+unsigned char c;
+int end;
+
+ fprintf(stdout,"\n data\n");
+ fprintf(stdout,"-------\n");
+ len = mdb_pg_get_int16(mdb,start);
+ fprintf(stdout,"length = %3d\n",len);
+ pos = start + 6;
+ end = start + len;
+ while (pos < end) {
+ fprintf(stdout,"pos = %3d\n",pos);
+ start = pos;
+ tmp = mdb_pg_get_int16(mdb,pos); /* length of field */
+ pos += 2;
+ col_type = mdb_pg_get_int16(mdb,pos); /* ??? */
+ pos += 2;
+ col_num = 0;
+ if (col_type) {
+ col_num = mdb_pg_get_int16(mdb,pos);
+ pos += 2;
+ }
+ val_len = mdb_pg_get_int16(mdb,pos);
+ pos += 2;
+ fprintf(stdout,"length = %3d %04x %2d %2d ",tmp, col_type, col_num, val_len);
+ for (i=0;i<val_len;i++) {
+ c = mdb->pg_buf[pos+i];
+ if (isprint(c))
+ fprintf(stdout," %c",c);
+ else
+ fprintf(stdout," %02x",c);
+
+ }
+ pos = start + tmp;
+ prop = g_array_index(entry->props,MdbColumnProp,col_num);
+ fprintf(stdout," Property %s",prop.name);
+ fprintf(stdout,"\n");
+ }
+ return hash;
+}
+void mdb_kkd_dump(MdbCatalogEntry *entry)
+{
+int rows;
+int kkd_start, kkd_end;
+int i, tmp, pos, row_type, datapos=0;
+MdbColumnProp prop;
+MdbHandle *mdb = entry->mdb;
+int rowid = entry->kkd_rowid;
+
+
+ mdb_read_pg(mdb, entry->kkd_pg);
+ rows = mdb_pg_get_int16(mdb,8);
+ fprintf(stdout,"number of rows = %d\n",rows);
+ kkd_start = mdb_pg_get_int16(mdb,10+rowid*2);
+ fprintf(stdout,"kkd start = %d %04x\n",kkd_start,kkd_start);
+ kkd_end = mdb->fmt->pg_size;
+ for (i=0;i<rows;i++) {
+ tmp = mdb_pg_get_int16(mdb, 10+i*2);
+ if (tmp < mdb->fmt->pg_size &&
+ tmp > kkd_start &&
+ tmp < kkd_end) {
+ kkd_end = tmp;
+ }
+ }
+ fprintf(stdout,"kkd end = %d %04x\n",kkd_end,kkd_end);
+ pos = kkd_start + 4; /* 4 = K K D \0 */
+ while (pos < kkd_end) {
+ tmp = mdb_pg_get_int16(mdb,pos);
+ row_type = mdb_pg_get_int16(mdb,pos+4);
+ fprintf(stdout,"row size = %3d type = 0x%02x\n",tmp,row_type);
+ if (row_type==0x80) {
+ fprintf(stdout,"\nColumn Properties\n");
+ fprintf(stdout,"-----------------\n");
+ mdb_get_column_props(entry,pos);
+ for (i=0;i<entry->num_props;i++) {
+ prop = g_array_index(entry->props,MdbColumnProp,i);
+ fprintf(stdout,"%3d %s\n",i,prop.name);
+ }
+ }
+ if (row_type==0x01) datapos = pos;
+ pos += tmp;
+ }
+
+ if (datapos) {
+ mdb_get_column_def(entry, datapos);
+ }
+}
+
diff --git a/navit/data/poi_geodownload/libmdb/like.c b/navit/data/poi_geodownload/libmdb/like.c
new file mode 100644
index 000000000..0a23d45cd
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/like.c
@@ -0,0 +1,78 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <mdbtools.h>
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+/**
+ * mdb_like_cmp
+ * @s: String to search within.
+ * @r: Search pattern.
+ *
+ * Tests the string @s to see if it matches the search pattern @r. In the
+ * search pattern, a percent sign indicates matching on any number of
+ * characters, and an underscore indicates matching any single character.
+ *
+ * Returns: 1 if the string matches, 0 if the string does not match.
+ */
+int mdb_like_cmp(char *s, char *r)
+{
+ unsigned int i;
+ int ret;
+
+ mdb_debug(MDB_DEBUG_LIKE, "comparing %s and %s", s, r);
+ switch (r[0]) {
+ case '\0':
+ if (s[0]=='\0') {
+ return 1;
+ } else {
+ return 0;
+ }
+ case '_':
+ /* skip one character */
+ return mdb_like_cmp(&s[1],&r[1]);
+ case '%':
+ /* skip any number of characters */
+ /* the strlen(s)+1 is important so the next call can */
+ /* if there are trailing characters */
+ for(i=0;i<strlen(s)+1;i++) {
+ if (mdb_like_cmp(&s[i],&r[1])) {
+ return 1;
+ }
+ }
+ return 0;
+ default:
+ for(i=0;i<strlen(r);i++) {
+ if (r[i]=='_' || r[i]=='%') break;
+ }
+ if (strncmp(s,r,i)) {
+ return 0;
+ } else {
+ mdb_debug(MDB_DEBUG_LIKE, "at pos %d comparing %s and %s", i, &s[i], &r[i]);
+ ret = mdb_like_cmp(&s[i],&r[i]);
+ mdb_debug(MDB_DEBUG_LIKE, "returning %d (%s and %s)", ret, &s[i], &r[i]);
+ return ret;
+ }
+ }
+}
diff --git a/navit/data/poi_geodownload/libmdb/map.c b/navit/data/poi_geodownload/libmdb/map.c
new file mode 100644
index 000000000..1164b7bed
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/map.c
@@ -0,0 +1,133 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+static guint32
+mdb_map_find_next0(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg)
+{
+ guint32 pgnum, i, usage_bitlen;
+ unsigned char *usage_bitmap;
+
+ pgnum = mdb_get_int32(map, 1);
+ usage_bitmap = map + 5;
+ usage_bitlen = (map_sz - 5) * 8;
+
+ i = (start_pg >= pgnum) ? start_pg-pgnum+1 : 0;
+ for (; i<usage_bitlen; i++) {
+ if (usage_bitmap[i/8] & (1 << (i%8))) {
+ return pgnum + i;
+ }
+ }
+ /* didn't find anything */
+ return 0;
+}
+static int
+mdb_map_find_next1(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg)
+{
+ guint32 map_ind, max_map_pgs, offset, usage_bitlen;
+
+ /*
+ * start_pg will tell us where to (re)start the scan
+ * for the next data page. each usage_map entry points to a
+ * 0x05 page which bitmaps (mdb->fmt->pg_size - 4) * 8 pages.
+ *
+ * map_ind gives us the starting usage_map entry
+ * offset gives us a page offset into the bitmap
+ */
+ usage_bitlen = (mdb->fmt->pg_size - 4) * 8;
+ max_map_pgs = (map_sz - 1) / 4;
+ map_ind = (start_pg + 1) / usage_bitlen;
+ offset = (start_pg + 1) % usage_bitlen;
+
+ for (; map_ind<max_map_pgs; map_ind++) {
+ unsigned char *usage_bitmap;
+ guint32 i, map_pg;
+
+ if (!(map_pg = mdb_get_int32(map, (map_ind*4)+1))) {
+ continue;
+ }
+ if(mdb_read_alt_pg(mdb, map_pg) != mdb->fmt->pg_size) {
+ fprintf(stderr, "Oops! didn't get a full page at %d\n", map_pg);
+ exit(1);
+ }
+
+ usage_bitmap = mdb->alt_pg_buf + 4;
+ for (i=offset; i<usage_bitlen; i++) {
+ if (usage_bitmap[i/8] & (1 << (i%8))) {
+ return map_ind*usage_bitlen + i;
+ }
+ }
+ offset = 0;
+ }
+ /* didn't find anything */
+ return 0;
+}
+guint32
+mdb_map_find_next(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg)
+{
+ if (map[0] == 0) {
+ return mdb_map_find_next0(mdb, map, map_sz, start_pg);
+ } else if (map[0] == 1) {
+ return mdb_map_find_next1(mdb, map, map_sz, start_pg);
+ }
+
+ fprintf(stderr, "Warning: unrecognized usage map type: %d\n", map[0]);
+ return -1;
+}
+guint32
+mdb_alloc_page(MdbTableDef *table)
+{
+ printf("Allocating new page\n");
+ return 0;
+}
+guint32
+mdb_map_find_next_freepage(MdbTableDef *table, int row_size)
+{
+ MdbCatalogEntry *entry = table->entry;
+ MdbHandle *mdb = entry->mdb;
+ guint32 pgnum;
+ guint32 cur_pg = 0;
+ int free_space;
+
+ do {
+ pgnum = mdb_map_find_next(mdb,
+ table->free_usage_map,
+ table->freemap_sz, cur_pg);
+ printf("looking at page %d\n", pgnum);
+ if (!pgnum) {
+ /* allocate new page */
+ pgnum = mdb_alloc_page(table);
+ return pgnum;
+ }
+ cur_pg = pgnum;
+
+ mdb_read_pg(mdb, pgnum);
+ free_space = mdb_pg_get_freespace(mdb);
+
+ } while (free_space < row_size);
+
+ printf("page %d has %d bytes left\n", pgnum, free_space);
+
+ return pgnum;
+}
diff --git a/navit/data/poi_geodownload/libmdb/mem.c b/navit/data/poi_geodownload/libmdb/mem.c
new file mode 100644
index 000000000..208757e72
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/mem.c
@@ -0,0 +1,50 @@
+/* MDB Tools - A library for reading MS Access database files
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+#include <locale.h>
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+/**
+ * mdb_init:
+ *
+ * Initializes the LibMDB library. This function should be called exactly once
+ * by calling program and prior to any other function.
+ *
+ **/
+void mdb_init(void)
+{
+ mdb_init_backends();
+}
+
+/**
+ * mdb_exit:
+ *
+ * Cleans up the LibMDB library. This function should be called exactly once
+ * by the calling program prior to exiting (or prior to final use of LibMDB
+ * functions).
+ *
+ **/
+void mdb_exit(void)
+{
+ mdb_remove_backends();
+}
diff --git a/navit/data/poi_geodownload/libmdb/money.c b/navit/data/poi_geodownload/libmdb/money.c
new file mode 100644
index 000000000..7f2cf6577
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/money.c
@@ -0,0 +1,139 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 1998-1999 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+#define MAXPRECISION 20
+/*
+** these routines are copied from the freetds project which does something
+** very similiar
+*/
+
+static int multiply_byte(unsigned char *product, int num, unsigned char *multiplier);
+static int do_carry(unsigned char *product);
+static char *array_to_string(unsigned char *array, int unsigned scale, char *s);
+
+/**
+ * mdb_money_to_string
+ * @mdb: Handle to open MDB database file
+ * @start: Offset of the field within the current page
+ * @s: String that will receieve the value
+ *
+ * Returns: the string that has received the value.
+ */
+char *mdb_money_to_string(MdbHandle *mdb, int start, char *s)
+{
+ int num_bytes = 8;
+ int i;
+ int neg=0;
+ unsigned char multiplier[MAXPRECISION], temp[MAXPRECISION];
+ unsigned char product[MAXPRECISION];
+ unsigned char money[num_bytes];
+
+ memset(multiplier,0,MAXPRECISION);
+ memset(product,0,MAXPRECISION);
+ multiplier[0]=1;
+ memcpy(money, mdb->pg_buf + start, num_bytes);
+
+ /* Perform two's complement for negative numbers */
+ if (money[7] & 0x80) {
+ neg = 1;
+ for (i=0;i<num_bytes;i++) {
+ money[i] = ~money[i];
+ }
+ for (i=0; i<num_bytes; i++) {
+ money[i] ++;
+ if (money[i]!=0) break;
+ }
+ }
+
+ for (i=0;i<num_bytes;i++) {
+ /* product += multiplier * current byte */
+ multiply_byte(product, money[i], multiplier);
+
+ /* multiplier = multiplier * 256 */
+ memcpy(temp, multiplier, MAXPRECISION);
+ memset(multiplier,0,MAXPRECISION);
+ multiply_byte(multiplier, 256, temp);
+ }
+ if (neg) {
+ s[0]='-';
+ array_to_string(product, 4, &s[1]);
+ } else {
+ array_to_string(product, 4, s);
+ }
+ return s;
+}
+static int multiply_byte(unsigned char *product, int num, unsigned char *multiplier)
+{
+ unsigned char number[3];
+ unsigned int i, j;
+
+ number[0]=num%10;
+ number[1]=(num/10)%10;
+ number[2]=(num/100)%10;
+
+ for (i=0;i<MAXPRECISION;i++) {
+ if (multiplier[i] == 0) continue;
+ for (j=0;j<3;j++) {
+ if (number[j] == 0) continue;
+ product[i+j] += multiplier[i]*number[j];
+ }
+ do_carry(product);
+ }
+ return 0;
+}
+static int do_carry(unsigned char *product)
+{
+ unsigned int j;
+
+ for (j=0;j<MAXPRECISION-1;j++) {
+ if (product[j]>9) {
+ product[j+1]+=product[j]/10;
+ product[j]=product[j]%10;
+ }
+ }
+ if (product[j]>9) {
+ product[j]=product[j]%10;
+ }
+ return 0;
+}
+static char *array_to_string(unsigned char *array, unsigned int scale, char *s)
+{
+ unsigned int top, i, j=0;
+
+ for (top=MAXPRECISION;(top>0) && (top-1>scale) && !array[top-1];top--);
+
+ if (top == 0) {
+ s[j++] = '0';
+ } else {
+ for (i=top; i>0; i--) {
+ if (j == top-scale) s[j++]='.';
+ s[j++]=array[i-1]+'0';
+ }
+ }
+ s[j]='\0';
+
+ return s;
+}
diff --git a/navit/data/poi_geodownload/libmdb/options.c b/navit/data/poi_geodownload/libmdb/options.c
new file mode 100644
index 000000000..cdbbc6627
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/options.c
@@ -0,0 +1,86 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2004 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include <mdbtools.h>
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+#define DEBUG 1
+
+static unsigned long opts;
+static int optset;
+
+static void load_options();
+
+void
+mdb_debug(int klass, char *fmt, ...)
+{
+#ifdef DEBUG
+ va_list ap;
+
+ if (!optset) load_options();
+ if (klass & opts) {
+ va_start(ap, fmt);
+ vfprintf (stdout,fmt, ap);
+ va_end(ap);
+ fprintf(stdout,"\n");
+ }
+#endif
+}
+
+static void
+load_options()
+{
+ char *opt;
+ char *s;
+
+ if (!optset && (s=getenv("MDBOPTS"))) {
+ opt = strtok(s, ":");
+ do {
+ if (!strcmp(opt, "use_index")) opts |= MDB_USE_INDEX;
+ if (!strcmp(opt, "debug_like")) opts |= MDB_DEBUG_LIKE;
+ if (!strcmp(opt, "debug_write")) opts |= MDB_DEBUG_WRITE;
+ if (!strcmp(opt, "debug_usage")) opts |= MDB_DEBUG_USAGE;
+ if (!strcmp(opt, "debug_ole")) opts |= MDB_DEBUG_OLE;
+ if (!strcmp(opt, "debug_row")) opts |= MDB_DEBUG_ROW;
+ if (!strcmp(opt, "debug_all")) {
+ opts |= MDB_DEBUG_LIKE;
+ opts |= MDB_DEBUG_WRITE;
+ opts |= MDB_DEBUG_USAGE;
+ opts |= MDB_DEBUG_OLE;
+ opts |= MDB_DEBUG_ROW;
+ }
+ opt = strtok(NULL,":");
+ } while (opt);
+ }
+ optset = 1;
+}
+int
+mdb_get_option(unsigned long optnum)
+{
+ if (!optset) load_options();
+ return ((opts & optnum) > 0);
+}
diff --git a/navit/data/poi_geodownload/libmdb/props.c b/navit/data/poi_geodownload/libmdb/props.c
new file mode 100644
index 000000000..61db9f543
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/props.c
@@ -0,0 +1,127 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+GPtrArray *
+mdb_read_props_list(gchar *kkd, int len)
+{
+ guint32 record_len;
+ int pos = 0;
+ gchar *name;
+ GPtrArray *names = NULL;
+ int i = 0;
+
+ names = g_ptr_array_new();
+#ifdef MDB_DEBUG
+ buffer_dump(kkd, 0, len - 1);
+#endif
+ pos = 0;
+ while (pos < len) {
+ record_len = mdb_get_int16(kkd, pos);
+ pos += 2;
+#ifdef MDB_DEBUG
+ printf("%02d ",i++);
+ buffer_dump(kkd, pos - 2, pos + record_len - 1);
+#endif
+ name = g_malloc(record_len + 1);
+ strncpy(name, &kkd[pos], record_len);
+ name[record_len] = '\0';
+ pos += record_len;
+ g_ptr_array_add(names, name);
+#ifdef MDB_DEBUG
+ printf("new len = %d\n", names->len);
+#endif
+ }
+ return names;
+}
+void
+mdb_free_props(MdbProperties *props)
+{
+ if (!props) return;
+
+ if (props->name) g_free(props->name);
+ g_free(props);
+}
+MdbProperties *
+mdb_alloc_props()
+{
+ MdbProperties *props;
+
+ props = g_malloc0(sizeof(MdbProperties));
+
+ return props;
+}
+MdbProperties *
+mdb_read_props(MdbHandle *mdb, GPtrArray *names, gchar *kkd, int len)
+{
+ guint32 record_len, name_len;
+ int pos = 0;
+ int elem, dtype, dsize;
+ gchar *name, *value;
+ MdbProperties *props;
+ int i = 0;
+
+#ifdef MDB_DEBUG
+ buffer_dump(kkd, 0, len - 1);
+#endif
+ pos = 0;
+
+ /* skip the name record */
+ record_len = mdb_get_int16(kkd, pos);
+ pos += 4;
+ name_len = mdb_get_int16(kkd, pos);
+ pos += 2;
+ props = mdb_alloc_props();
+ if (name_len) {
+ props->name = g_malloc(name_len + 1);
+ strncpy(props->name, &kkd[pos], name_len);
+ props->name[name_len]='\0';
+ }
+ pos += name_len;
+
+ props->hash = g_hash_table_new(g_str_hash, g_str_equal);
+
+ while (pos < len) {
+ record_len = mdb_get_int16(kkd, pos);
+ elem = mdb_get_int16(kkd, pos + 4);
+ dtype = kkd[pos + 3];
+ dsize = mdb_get_int16(kkd, pos + 6);
+ value = g_malloc(dsize + 1);
+ strncpy(value, &kkd[pos + 8], dsize);
+ value[dsize] = '\0';
+ name = g_ptr_array_index(names,elem);
+#ifdef MDB_DEBUG
+ printf("%02d ",i++);
+ buffer_dump(kkd, pos, pos + record_len - 1);
+ printf("elem %d dsize %d dtype %d\n", elem, dsize, dtype);
+#endif
+ if (dtype == MDB_MEMO) dtype = MDB_TEXT;
+ if (dtype == MDB_BOOL) {
+ g_hash_table_insert(props->hash, g_strdup(name), g_strdup(kkd[pos + 8] ? "yes" : "no"));
+ } else {
+ g_hash_table_insert(props->hash, g_strdup(name), g_strdup(mdb_col_to_string(mdb, kkd, pos + 8, dtype, dsize)));
+ }
+ g_free(value);
+ pos += record_len;
+ }
+ return props;
+
+}
diff --git a/navit/data/poi_geodownload/libmdb/sargs.c b/navit/data/poi_geodownload/libmdb/sargs.c
new file mode 100644
index 000000000..b14aaa946
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/sargs.c
@@ -0,0 +1,273 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * code for handling searchable arguments (sargs) used primary by the sql
+ * engine to support where clause handling. The sargs are configured in
+ * a tree with AND/OR operators connecting the child nodes. NOT operations
+ * have only one child on the left side. Logical operators (=,<,>,etc..)
+ * have no children.
+ *
+ * datatype support is a bit weak at this point. To add more types create
+ * a mdb_test_[type]() function and invoke it from mdb_test_sarg()
+ */
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+void
+mdb_sql_walk_tree(MdbSargNode *node, MdbSargTreeFunc func, gpointer data)
+{
+ if (func(node, data))
+ return;
+ if (node->left) mdb_sql_walk_tree(node->left, func, data);
+ if (node->right) mdb_sql_walk_tree(node->right, func, data);
+}
+int
+mdb_test_string(MdbSargNode *node, char *s)
+{
+int rc;
+
+ if (node->op == MDB_LIKE) {
+ return mdb_like_cmp(s,node->value.s);
+ }
+ rc = strncmp(node->value.s, s, 255);
+ switch (node->op) {
+ case MDB_EQUAL:
+ if (rc==0) return 1;
+ break;
+ case MDB_GT:
+ if (rc<0) return 1;
+ break;
+ case MDB_LT:
+ if (rc>0) return 1;
+ break;
+ case MDB_GTEQ:
+ if (rc<=0) return 1;
+ break;
+ case MDB_LTEQ:
+ if (rc>=0) return 1;
+ break;
+ default:
+ fprintf(stderr, "Calling mdb_test_sarg on unknown operator. Add code to mdb_test_string() for operator %d\n",node->op);
+ break;
+ }
+ return 0;
+}
+int mdb_test_int(MdbSargNode *node, gint32 i)
+{
+ switch (node->op) {
+ case MDB_EQUAL:
+ printf("comparing %x and %x %d\n", i, node->value.i, node->value.i == i);
+ if (node->value.i == i) return 1;
+ break;
+ case MDB_GT:
+ if (node->value.i < i) return 1;
+ break;
+ case MDB_LT:
+ if (node->value.i > i) return 1;
+ break;
+ case MDB_GTEQ:
+ if (node->value.i <= i) return 1;
+ break;
+ case MDB_LTEQ:
+ if (node->value.i >= i) return 1;
+ break;
+ default:
+ fprintf(stderr, "Calling mdb_test_sarg on unknown operator. Add code to mdb_test_int() for operator %d\n",node->op);
+ break;
+ }
+ return 0;
+}
+#if 0
+#endif
+int
+mdb_find_indexable_sargs(MdbSargNode *node, gpointer data)
+{
+ MdbSarg sarg;
+
+ if (node->op == MDB_OR || node->op == MDB_NOT) return 1;
+
+ /*
+ * right now all we do is look for sargs that are anded together from
+ * the root. Later we may put together OR ops into a range, and then
+ * range scan the leaf pages. That is col1 = 2 or col1 = 4 becomes
+ * col1 >= 2 and col1 <= 4 for the purpose of index scans, and then
+ * extra rows are thrown out when the row is tested against the main
+ * sarg tree. range scans are generally only a bit better than table
+ * scanning anyway.
+ *
+ * also, later we should support the NOT operator, but it's generally
+ * a pretty worthless test for indexes, ie NOT col1 = 3, we are
+ * probably better off table scanning.
+ */
+ if (mdb_is_relational_op(node->op) && node->col) {
+ //printf("op = %d value = %s\n", node->op, node->value.s);
+ sarg.op = node->op;
+ sarg.value = node->value;
+ mdb_add_sarg(node->col, &sarg);
+ }
+ return 0;
+}
+int
+mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSargNode *node, MdbField *field)
+{
+char tmpbuf[256];
+int lastchar;
+
+ if (node->op == MDB_ISNULL) {
+ if (field->is_null) return 0;
+ else return 1;
+ } else if (node->op == MDB_NOTNULL) {
+ if (field->is_null) return 1;
+ else return 0;
+ }
+ switch (col->col_type) {
+ case MDB_BOOL:
+ return mdb_test_int(node, !field->is_null);
+ break;
+ case MDB_BYTE:
+ return mdb_test_int(node, (gint32)((char *)field->value)[0]);
+ break;
+ case MDB_INT:
+ return mdb_test_int(node, (gint32)mdb_get_int16(field->value, 0));
+ break;
+ case MDB_LONGINT:
+ return mdb_test_int(node, (gint32)mdb_get_int32(field->value, 0));
+ break;
+ case MDB_TEXT:
+ if (IS_JET4(mdb)) {
+ mdb_unicode2ascii(mdb, field->value, 0, field->siz, tmpbuf);
+ } else {
+ strncpy(tmpbuf, field->value, 255);
+ lastchar = field->siz > 255 ? 255 : field->siz;
+ tmpbuf[lastchar]='\0';
+ }
+ return mdb_test_string(node, tmpbuf);
+ default:
+ fprintf(stderr, "Calling mdb_test_sarg on unknown type. Add code to mdb_test_sarg() for type %d\n",col->col_type);
+ break;
+ }
+ return 1;
+}
+int
+mdb_find_field(int col_num, MdbField *fields, int num_fields)
+{
+ int i;
+
+ for (i=0;i<num_fields;i++) {
+ if (fields[i].colnum == col_num) return i;
+ }
+ return -1;
+}
+int
+mdb_test_sarg_node(MdbHandle *mdb, MdbSargNode *node, MdbField *fields, int num_fields)
+{
+ int elem;
+ MdbColumn *col;
+ int rc;
+
+ if (mdb_is_relational_op(node->op)) {
+ col = node->col;
+ /* for const = const expressions */
+ if (!col) {
+ return (node->value.i);
+ }
+ elem = mdb_find_field(col->col_num, fields, num_fields);
+ if (!mdb_test_sarg(mdb, col, node, &fields[elem]))
+ return 0;
+ } else { /* logical op */
+ switch (node->op) {
+ case MDB_NOT:
+ rc = mdb_test_sarg_node(mdb, node->left, fields, num_fields);
+ return !rc;
+ break;
+ case MDB_AND:
+ if (!mdb_test_sarg_node(mdb, node->left, fields, num_fields))
+ return 0;
+ return mdb_test_sarg_node(mdb, node->right, fields, num_fields);
+ break;
+ case MDB_OR:
+ if (mdb_test_sarg_node(mdb, node->left, fields, num_fields))
+ return 1;
+ return mdb_test_sarg_node(mdb, node->right, fields, num_fields);
+ break;
+ }
+ }
+ return 1;
+}
+int
+mdb_test_sargs(MdbTableDef *table, MdbField *fields, int num_fields)
+{
+ MdbSargNode *node;
+ MdbCatalogEntry *entry = table->entry;
+ MdbHandle *mdb = entry->mdb;
+
+ node = table->sarg_tree;
+
+ /* there may not be a sarg tree */
+ if (!node) return 1;
+
+ return mdb_test_sarg_node(mdb, node, fields, num_fields);
+}
+#if 0
+int mdb_test_sargs(MdbHandle *mdb, MdbColumn *col, int offset, int len)
+{
+MdbSarg *sarg;
+int i;
+
+ for (i=0;i<col->num_sargs;i++) {
+ sarg = g_ptr_array_index (col->sargs, i);
+ if (!mdb_test_sarg(mdb, col, sarg, offset, len)) {
+ /* sarg didn't match, no sense going on */
+ return 0;
+ }
+ }
+
+ return 1;
+}
+#endif
+int mdb_add_sarg(MdbColumn *col, MdbSarg *in_sarg)
+{
+MdbSarg *sarg;
+ if (!col->sargs) {
+ col->sargs = g_ptr_array_new();
+ }
+ sarg = g_memdup(in_sarg,sizeof(MdbSarg));
+ g_ptr_array_add(col->sargs, sarg);
+ col->num_sargs++;
+
+ return 1;
+}
+int mdb_add_sarg_by_name(MdbTableDef *table, char *colname, MdbSarg *in_sarg)
+{
+ MdbColumn *col;
+ unsigned int i;
+
+ for (i=0;i<table->num_cols;i++) {
+ col = g_ptr_array_index (table->columns, i);
+ if (!strcasecmp(col->name,colname)) {
+ return mdb_add_sarg(col, in_sarg);
+ }
+ }
+ /* else didn't find the column return 0! */
+ return 0;
+}
diff --git a/navit/data/poi_geodownload/libmdb/stats.c b/navit/data/poi_geodownload/libmdb/stats.c
new file mode 100644
index 000000000..1abf2857a
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/stats.c
@@ -0,0 +1,74 @@
+/* MDB Tools - A library for reading MS Access database files
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+/**
+ * mdb_stats_on:
+ * @mdb: Handle to the (open) MDB file to collect stats on.
+ *
+ * Begins collection of statistics on an MDBHandle.
+ *
+ * Statistics in LibMDB will track the number of reads from the MDB file. The
+ * collection of statistics is started and stopped with the mdb_stats_on and
+ * mdb_stats_off functions. Collected statistics are accessed by reading the
+ * MdbStatistics structure or calling mdb_dump_stats.
+ *
+ */
+void
+mdb_stats_on(MdbHandle *mdb)
+{
+ if (!mdb->stats)
+ mdb->stats = g_malloc0(sizeof(MdbStatistics));
+
+ mdb->stats->collect = TRUE;
+}
+/**
+ * mdb_stats_off:
+ * @mdb: pointer to handle of MDB file with active stats collection.
+ *
+ * Turns off statistics collection.
+ *
+ * If mdb_stats_off is not called, statistics will be turned off when handle
+ * is freed using mdb_close.
+ **/
+void
+mdb_stats_off(MdbHandle *mdb)
+{
+ if (!mdb->stats) return;
+
+ mdb->stats->collect = FALSE;
+}
+/**
+ * mdb_dump_stats:
+ * @mdb: pointer to handle of MDB file with active stats collection.
+ *
+ * Dumps current statistics to stdout.
+ **/
+void
+mdb_dump_stats(MdbHandle *mdb)
+{
+ if (!mdb->stats) return;
+
+ fprintf(stdout, "Physical Page Reads: %lu\n", mdb->stats->pg_reads);
+}
diff --git a/navit/data/poi_geodownload/libmdb/table.c b/navit/data/poi_geodownload/libmdb/table.c
new file mode 100644
index 000000000..52238ecd9
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/table.c
@@ -0,0 +1,368 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+
+static gint mdb_col_comparer(MdbColumn **a, MdbColumn **b)
+{
+ if ((*a)->col_num > (*b)->col_num)
+ return 1;
+ else if ((*a)->col_num < (*b)->col_num)
+ return -1;
+ else
+ return 0;
+}
+
+static unsigned char mdb_col_needs_size(int col_type)
+{
+ if (col_type == MDB_TEXT) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry)
+{
+ MdbTableDef *table;
+
+ table = (MdbTableDef *) g_malloc0(sizeof(MdbTableDef));
+ table->entry=entry;
+ strcpy(table->name, entry->object_name);
+
+ return table;
+}
+void mdb_free_tabledef(MdbTableDef *table)
+{
+ if (!table) return;
+ if (table->is_temp_table) {
+ unsigned int i;
+ for (i=0; i<table->temp_table_pages->len; i++)
+ g_free(g_ptr_array_index(table->temp_table_pages,i));
+ g_ptr_array_free(table->temp_table_pages, TRUE);
+ }
+ mdb_free_columns(table->columns);
+ mdb_free_indices(table->indices);
+ g_free(table->usage_map);
+ g_free(table->free_usage_map);
+ g_free(table);
+}
+MdbTableDef *mdb_read_table(MdbCatalogEntry *entry)
+{
+ MdbTableDef *table;
+ MdbHandle *mdb = entry->mdb;
+ MdbFormatConstants *fmt = mdb->fmt;
+ int len, row_start, pg_row;
+ char *buf;
+
+ table = mdb_alloc_tabledef(entry);
+
+ mdb_read_pg(mdb, entry->table_pg);
+ if (mdb->pg_buf[0] != 0x02) return NULL; /* not a valid table def page */
+
+ len = mdb_pg_get_int16(mdb,8);
+
+ table->num_rows = mdb_pg_get_int32(mdb, fmt->tab_num_rows_offset);
+ table->num_var_cols = mdb_pg_get_int16(mdb, fmt->tab_num_cols_offset-2);
+ table->num_cols = mdb_pg_get_int16(mdb, fmt->tab_num_cols_offset);
+ table->num_idxs = mdb_pg_get_int32(mdb, fmt->tab_num_idxs_offset);
+ table->num_real_idxs = mdb_pg_get_int32(mdb, fmt->tab_num_ridxs_offset);
+ /* grab a copy of the usage map */
+ pg_row = mdb_pg_get_int32(mdb, fmt->tab_usage_map_offset);
+ mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &(table->map_sz));
+ table->usage_map = g_memdup(buf + row_start, table->map_sz);
+ if (mdb_get_option(MDB_DEBUG_USAGE))
+ buffer_dump(buf, row_start, row_start+table->map_sz-1);
+ mdb_debug(MDB_DEBUG_USAGE,"usage map found on page %ld row %d start %d len %d",
+ pg_row >> 8, pg_row & 0xff, row_start, table->map_sz);
+
+ /* grab a copy of the free space page map */
+ pg_row = mdb_pg_get_int32(mdb, fmt->tab_free_map_offset);
+ mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &(table->freemap_sz));
+ table->free_usage_map = g_memdup(buf + row_start, table->freemap_sz);
+ mdb_debug(MDB_DEBUG_USAGE,"free map found on page %ld row %d start %d len %d\n",
+ pg_row >> 8, pg_row & 0xff, row_start, table->freemap_sz);
+
+ table->first_data_pg = mdb_pg_get_int16(mdb, fmt->tab_first_dpg_offset);
+
+ return table;
+}
+MdbTableDef *mdb_read_table_by_name(MdbHandle *mdb, gchar *table_name, int obj_type)
+{
+ unsigned int i;
+ MdbCatalogEntry *entry;
+
+ mdb_read_catalog(mdb, obj_type);
+
+ for (i=0; i<mdb->num_catalog; i++) {
+ entry = g_ptr_array_index(mdb->catalog, i);
+ if (!strcasecmp(entry->object_name, table_name))
+ return mdb_read_table(entry);
+ }
+
+ return NULL;
+}
+
+/*
+** read the next page if offset is > pg_size
+** return true if page was read
+*/
+int
+read_pg_if(MdbHandle *mdb, int *cur_pos, int offset)
+{
+ if (*cur_pos + offset >= mdb->fmt->pg_size) {
+ mdb_read_pg(mdb, mdb_pg_get_int32(mdb,4));
+ *cur_pos = 8 - (mdb->fmt->pg_size - (*cur_pos));
+ return 1;
+ }
+ return 0;
+}
+guint32
+read_pg_if_32(MdbHandle *mdb, int *cur_pos)
+{
+ unsigned char c[4];
+ int i, rc = 0;
+
+ for (i=0;i<4;i++) {
+ rc += read_pg_if(mdb, cur_pos, i);
+ c[i] = mdb->pg_buf[(*cur_pos) + i];
+ }
+ return mdb_get_int32(c, 0);
+}
+guint16
+read_pg_if_16(MdbHandle *mdb, int *cur_pos)
+{
+ unsigned char low_byte, high_byte;
+ int rc = 0;
+
+ rc += read_pg_if(mdb, cur_pos, 0);
+ low_byte = mdb->pg_buf[*cur_pos];
+ rc += read_pg_if(mdb, cur_pos, 1);
+ high_byte = mdb->pg_buf[(*cur_pos) + 1];
+
+ return (high_byte * 256 + low_byte);
+}
+guint16
+read_pg_if_n(MdbHandle *mdb, unsigned char *buf, int *cur_pos, int len)
+{
+ if (*cur_pos + len < mdb->fmt->pg_size) {
+ memcpy(buf, &mdb->pg_buf[*cur_pos], len);
+ return 0;
+ } else {
+ int half = mdb->fmt->pg_size - *cur_pos;
+ memcpy(buf, &mdb->pg_buf[*cur_pos], half);
+ mdb_read_pg(mdb, mdb_pg_get_int32(mdb,4));
+ memcpy(buf + half, &mdb->pg_buf[8], len - half);
+ *cur_pos = 8 - half;
+ return 1;
+ }
+}
+
+void mdb_append_column(GPtrArray *columns, MdbColumn *in_col)
+{
+ g_ptr_array_add(columns, g_memdup(in_col,sizeof(MdbColumn)));
+}
+void mdb_free_columns(GPtrArray *columns)
+{
+ unsigned int i;
+
+ if (!columns) return;
+ for (i=0; i<columns->len; i++)
+ g_free (g_ptr_array_index(columns, i));
+ g_ptr_array_free(columns, TRUE);
+}
+GPtrArray *mdb_read_columns(MdbTableDef *table)
+{
+ MdbHandle *mdb = table->entry->mdb;
+ MdbFormatConstants *fmt = mdb->fmt;
+ MdbColumn *pcol;
+ unsigned char *col;
+ unsigned int i;
+ int cur_pos, name_sz;
+
+ table->columns = g_ptr_array_new();
+
+ col = (unsigned char *) g_malloc(fmt->tab_col_entry_size);
+
+ cur_pos = fmt->tab_cols_start_offset +
+ (table->num_real_idxs * fmt->tab_ridx_entry_size);
+
+ /* new code based on patch submitted by Tim Nelson 2000.09.27 */
+
+ /*
+ ** column attributes
+ */
+ for (i=0;i<table->num_cols;i++) {
+#ifdef MDB_DEBUG
+ /* printf("column %d\n", i);
+ buffer_dump(mdb->pg_buf, cur_pos ,cur_pos + 18); */
+#endif
+ read_pg_if_n(mdb, col, &cur_pos, fmt->tab_col_entry_size);
+ cur_pos += fmt->tab_col_entry_size;
+ pcol = (MdbColumn *) g_malloc0(sizeof(MdbColumn));
+
+ pcol->col_type = col[0];
+
+ // col_num_offset == 1 or 5
+ pcol->col_num = col[fmt->col_num_offset];
+
+ //fprintf(stdout,"----- column %d -----\n",pcol->col_num);
+ // col_var == 3 or 7
+ pcol->var_col_num = mdb_get_int16(col, fmt->tab_col_offset_var);
+ //fprintf(stdout,"var column pos %d\n",pcol->var_col_num);
+
+ // col_var == 5 or 9
+ pcol->row_col_num = mdb_get_int16(col, fmt->tab_row_col_num_offset);
+ //fprintf(stdout,"row column num %d\n",pcol->row_col_num);
+
+ /* FIXME: can this be right in Jet3 and Jet4? */
+ if (pcol->col_type == MDB_NUMERIC) {
+ pcol->col_prec = col[11];
+ pcol->col_scale = col[12];
+ }
+
+ // col_fixed_offset == 13 or 15
+ pcol->is_fixed = col[fmt->col_fixed_offset] & 0x01 ? 1 : 0;
+
+ // col_fixed_offset == 13 or 15
+ pcol->fixed_offset = mdb_get_int16(col, fmt->tab_col_offset_fixed);
+ //fprintf(stdout,"fixed column offset %d\n",pcol->fixed_offset);
+ //fprintf(stdout,"col type %s\n",pcol->is_fixed ? "fixed" : "variable");
+
+ if (pcol->col_type != MDB_BOOL) {
+ // col_size_offset == 16 or 23
+ pcol->col_size = mdb_get_int16(col, fmt->col_size_offset);
+ } else {
+ pcol->col_size=0;
+ }
+
+ g_ptr_array_add(table->columns, pcol);
+ }
+
+ g_free (col);
+
+ /*
+ ** column names - ordered the same as the column attributes table
+ */
+ for (i=0;i<table->num_cols;i++) {
+ pcol = g_ptr_array_index(table->columns, i);
+
+ if (IS_JET4(mdb)) {
+ char *tmp_buf;
+ name_sz = read_pg_if_16(mdb, &cur_pos);
+ cur_pos += 2;
+ tmp_buf = (char *) g_malloc(name_sz);
+ read_pg_if_n(mdb, tmp_buf, &cur_pos, name_sz);
+ mdb_unicode2ascii(mdb, tmp_buf, 0, name_sz, pcol->name);
+ g_free(tmp_buf);
+ cur_pos += name_sz;
+ } else if (IS_JET3(mdb)) {
+ read_pg_if(mdb, &cur_pos, 0);
+ name_sz = mdb->pg_buf[cur_pos];
+ cur_pos++;
+ read_pg_if_n(mdb, pcol->name, &cur_pos, name_sz);
+ pcol->name[name_sz]='\0';
+ cur_pos += name_sz;
+ } else {
+ fprintf(stderr,"Unknown MDB version\n");
+ }
+ }
+
+ /* Sort the columns by col_num */
+ g_ptr_array_sort(table->columns, (GCompareFunc)mdb_col_comparer);
+
+ table->index_start = cur_pos;
+ return table->columns;
+}
+
+void mdb_table_dump(MdbCatalogEntry *entry)
+{
+MdbTableDef *table;
+MdbColumn *col;
+int coln;
+MdbIndex *idx;
+MdbHandle *mdb = entry->mdb;
+unsigned int i, bitn;
+guint32 pgnum;
+
+ table = mdb_read_table(entry);
+ fprintf(stdout,"definition page = %lu\n",entry->table_pg);
+ fprintf(stdout,"number of datarows = %d\n",table->num_rows);
+ fprintf(stdout,"number of columns = %d\n",table->num_cols);
+ fprintf(stdout,"number of indices = %d\n",table->num_real_idxs);
+
+ mdb_read_columns(table);
+ mdb_read_indices(table);
+
+ for (i=0;i<table->num_cols;i++) {
+ col = g_ptr_array_index(table->columns,i);
+
+ fprintf(stdout,"column %d Name: %-20s Type: %s(%d)\n",
+ i, col->name,
+ mdb_get_coltype_string(mdb->default_backend, col->col_type),
+ col->col_size);
+ }
+
+ for (i=0;i<table->num_idxs;i++) {
+ idx = g_ptr_array_index (table->indices, i);
+ mdb_index_dump(table, idx);
+ }
+ if (table->usage_map) {
+ printf("pages reserved by this object\n");
+ printf("usage map pg %" G_GUINT32_FORMAT "\n",
+ table->map_base_pg);
+ printf("free map pg %" G_GUINT32_FORMAT "\n",
+ table->freemap_base_pg);
+ pgnum = mdb_get_int32(table->usage_map,1);
+ /* the first 5 bytes of the usage map mean something */
+ coln = 0;
+ for (i=5;i<table->map_sz;i++) {
+ for (bitn=0;bitn<8;bitn++) {
+ if (table->usage_map[i] & 1 << bitn) {
+ coln++;
+ printf("%6" G_GUINT32_FORMAT, pgnum);
+ if (coln==10) {
+ printf("\n");
+ coln = 0;
+ } else {
+ printf(" ");
+ }
+ }
+ pgnum++;
+ }
+ }
+ printf("\n");
+ }
+}
+
+int mdb_is_user_table(MdbCatalogEntry *entry)
+{
+ return ((entry->object_type == MDB_TABLE)
+ && !(entry->flags & 0x80000002)) ? 1 : 0;
+}
+int mdb_is_system_table(MdbCatalogEntry *entry)
+{
+ return ((entry->object_type == MDB_TABLE)
+ && (entry->flags & 0x80000002)) ? 1 : 0;
+}
diff --git a/navit/data/poi_geodownload/libmdb/worktable.c b/navit/data/poi_geodownload/libmdb/worktable.c
new file mode 100644
index 000000000..6f893dcfd
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/worktable.c
@@ -0,0 +1,99 @@
+/* MDB Tools - A library for reading MS Access database files
+ * Copyright (C) 2004 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+/*
+ * Temp table routines. These are currently used to generate mock results for
+ * commands like "list tables" and "describe table"
+ */
+
+void
+mdb_fill_temp_col(MdbColumn *tcol, char *col_name, int col_size, int col_type, int is_fixed)
+{
+ memset(tcol,0,sizeof(MdbColumn));
+ strcpy(tcol->name, col_name);
+ tcol->col_type = col_type;
+ if ((col_type == MDB_TEXT) || (col_type == MDB_MEMO)) {
+ tcol->col_size = col_size;
+ } else {
+ tcol->col_size = mdb_col_fixed_size(tcol);
+ }
+ tcol->is_fixed = is_fixed;
+}
+void
+mdb_fill_temp_field(MdbField *field, void *value, int siz, int is_fixed, int is_null, int start, int colnum)
+{
+ field->value = value;
+ field->siz = siz;
+ field->is_fixed = is_fixed;
+ field->is_null = is_null;
+ field->start = start;
+ field->colnum = colnum;
+}
+MdbTableDef *
+mdb_create_temp_table(MdbHandle *mdb, char *name)
+{
+ MdbCatalogEntry *entry;
+ MdbTableDef *table;
+
+ /* dummy up a catalog entry */
+ entry = (MdbCatalogEntry *) g_malloc0(sizeof(MdbCatalogEntry));
+ entry->mdb = mdb;
+ entry->object_type = MDB_TABLE;
+ entry->table_pg = 0;
+ strcpy(entry->object_name, name);
+
+ table = mdb_alloc_tabledef(entry);
+ table->columns = g_ptr_array_new();
+ table->is_temp_table = 1;
+ table->temp_table_pages = g_ptr_array_new();
+
+ return table;
+}
+void
+mdb_temp_table_add_col(MdbTableDef *table, MdbColumn *col)
+{
+ col->col_num = table->num_cols;
+ if (!col->is_fixed)
+ col->var_col_num = table->num_var_cols++;
+ g_ptr_array_add(table->columns, g_memdup(col, sizeof(MdbColumn)));
+ table->num_cols++;
+}
+/*
+ * Should be called after setting up all temp table columns
+ */
+void mdb_temp_columns_end(MdbTableDef *table)
+{
+ MdbColumn *col;
+ unsigned int i;
+ unsigned int start = 0;
+
+ for (i=0; i<table->num_cols; i++) {
+ col = g_ptr_array_index(table->columns, i);
+ if (col->is_fixed) {
+ col->fixed_offset = start;
+ start += col->col_size;
+ }
+ }
+}
diff --git a/navit/data/poi_geodownload/libmdb/write.c b/navit/data/poi_geodownload/libmdb/write.c
new file mode 100644
index 000000000..1cff96a4b
--- /dev/null
+++ b/navit/data/poi_geodownload/libmdb/write.c
@@ -0,0 +1,878 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+#include "time.h"
+#include "math.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+
+//static int mdb_copy_index_pg(MdbTableDef *table, MdbIndex *idx, MdbIndexPage *ipg);
+static int mdb_add_row_to_leaf_pg(MdbTableDef *table, MdbIndex *idx, MdbIndexPage *ipg, MdbField *idx_fields);
+
+void
+_mdb_put_int16(unsigned char *buf, guint32 offset, guint32 value)
+{
+ buf[offset] = value % 256;
+ value /= 256;
+ buf[offset+1] = value % 256;
+}
+void
+_mdb_put_int32(unsigned char *buf, guint32 offset, guint32 value)
+{
+ buf[offset] = value % 256;
+ value /= 256;
+ buf[offset+1] = value % 256;
+ value /= 256;
+ buf[offset+2] = value % 256;
+ value /= 256;
+ buf[offset+3] = value % 256;
+}
+ssize_t
+mdb_write_pg(MdbHandle *mdb, unsigned long pg)
+{
+ ssize_t len;
+ struct stat status;
+ off_t offset = pg * mdb->fmt->pg_size;
+
+ fstat(mdb->f->fd, &status);
+ /* is page beyond current size + 1 ? */
+ if (status.st_size < offset + mdb->fmt->pg_size) {
+ fprintf(stderr,"offset %lu is beyond EOF\n",offset);
+ return 0;
+ }
+ lseek(mdb->f->fd, offset, SEEK_SET);
+ len = write(mdb->f->fd,mdb->pg_buf,mdb->fmt->pg_size);
+ if (len==-1) {
+ perror("write");
+ return 0;
+ } else if (len<mdb->fmt->pg_size) {
+ /* fprintf(stderr,"EOF reached %d bytes returned.\n",len, mdb->pg_size); */
+ return 0;
+ }
+ mdb->cur_pos = 0;
+ return len;
+}
+
+static int
+mdb_is_col_indexed(MdbTableDef *table, int colnum)
+{
+ unsigned int i, j;
+ MdbIndex *idx;
+
+ for (i=0;i<table->num_idxs;i++) {
+ idx = g_ptr_array_index (table->indices, i);
+ for (j=0;j<idx->num_keys;j++) {
+ if (idx->key_col_num[j]==colnum) return 1;
+ }
+ }
+ return 0;
+}
+static int
+mdb_crack_row4(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
+{
+ MdbCatalogEntry *entry = table->entry;
+ MdbHandle *mdb = entry->mdb;
+ MdbColumn *col;
+ unsigned char *pg_buf = mdb->pg_buf;
+ unsigned int i;
+ unsigned int row_var_cols=0, row_fixed_cols, row_cols;
+ unsigned int fixed_cols_found;
+ unsigned int col_start;
+ unsigned char *nullmask;
+ unsigned int bitmask_sz;
+ unsigned int byte_num, bit_num;
+ unsigned int *var_col_offsets = NULL;
+
+ if (mdb_get_option(MDB_DEBUG_ROW)) {
+ buffer_dump(pg_buf, row_start, row_end);
+ }
+
+ row_cols = mdb_pg_get_int16(mdb, row_start);
+
+ bitmask_sz = (row_cols + 7) / 8;
+ nullmask = &pg_buf[row_end - bitmask_sz + 1];
+
+ /* read table of variable column locations */
+ if (table->num_var_cols > 0) {
+ row_var_cols = mdb_pg_get_int16(mdb, row_end - bitmask_sz - 1);
+ var_col_offsets = (int *)g_malloc((row_var_cols+1)*sizeof(int));
+ for (i=0; i<row_var_cols+1; i++) {
+ var_col_offsets[i] = mdb_pg_get_int16(mdb,
+ row_end - bitmask_sz - 3 - (i*2));
+ }
+ }
+ fixed_cols_found = 0;
+ row_fixed_cols = row_cols - row_var_cols;
+
+ /* read information into fields[] */
+ for (i=0;i<table->num_cols;i++) {
+ col = g_ptr_array_index(table->columns,i);
+ fields[i].colnum = i;
+ fields[i].is_fixed = (mdb_is_fixed_col(col)) ? 1 : 0;
+ byte_num = col->col_num / 8;
+ bit_num = col->col_num % 8;
+ /* logic on nulls is reverse, 1 is not null, 0 is null */
+ fields[i].is_null = nullmask[byte_num] & (1 << bit_num) ? 0 : 1;
+
+ if ((fields[i].is_fixed)
+ && (fixed_cols_found < row_fixed_cols)) {
+ col_start = col->fixed_offset + 2;
+ fields[i].start = row_start + col_start;
+ fields[i].value = &pg_buf[row_start + col_start];
+ fields[i].siz = col->col_size;
+ fixed_cols_found++;
+ /* Use col->var_col_num because a deleted column is still
+ * present in the variable column offsets table for the row */
+ } else if ((!fields[i].is_fixed)
+ && (col->var_col_num < row_var_cols)) {
+ col_start = var_col_offsets[col->var_col_num];
+ fields[i].start = row_start + col_start;
+ fields[i].value = &pg_buf[row_start + col_start];
+ fields[i].siz = var_col_offsets[(col->var_col_num)+1] -
+ col_start;
+ } else {
+ fields[i].start = 0;
+ fields[i].value = NULL;
+ fields[i].siz = 0;
+ fields[i].is_null = 1;
+ }
+ }
+ g_free(var_col_offsets);
+
+ return row_cols;
+}
+static int
+mdb_crack_row3(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
+{
+ MdbCatalogEntry *entry = table->entry;
+ MdbHandle *mdb = entry->mdb;
+ MdbColumn *col;
+ unsigned char *pg_buf = mdb->pg_buf;
+ unsigned int i;
+ unsigned int row_var_cols = 0, row_fixed_cols, row_cols;
+ unsigned int fixed_cols_found, var_cols_found;
+ unsigned int col_start;
+ unsigned char *nullmask;
+ unsigned int bitmask_sz;
+ unsigned int byte_num, bit_num;
+ unsigned int *var_col_offsets = NULL;
+ unsigned int num_jumps = 0, jumps_used = 0;
+ unsigned int col_ptr, row_len;
+
+ if (mdb_get_option(MDB_DEBUG_ROW)) {
+ buffer_dump(pg_buf, row_start, row_end);
+ }
+
+ row_cols = pg_buf[row_start];
+
+ bitmask_sz = (row_cols + 7) / 8;
+ nullmask = &pg_buf[row_end - bitmask_sz + 1];
+
+ /* read table of variable column locations */
+ if (table->num_var_cols > 0) {
+ row_var_cols = pg_buf[row_end - bitmask_sz];
+ row_len = row_end - row_start + 1;
+ num_jumps = (row_len - 1) / 256;
+ col_ptr = row_end - bitmask_sz - num_jumps - 1;
+ /* If last jump is a dummy value, ignore it */
+ if ((col_ptr-row_start-row_var_cols)/256 < num_jumps)
+ num_jumps--;
+
+ var_col_offsets = (int *)g_malloc((row_var_cols+1)*sizeof(int));
+ jumps_used = 0;
+ for (i=0; i<row_var_cols+1; i++) {
+ if ((jumps_used < num_jumps)
+ && (i == pg_buf[row_end-bitmask_sz-jumps_used-1])) {
+ jumps_used++;
+ }
+ var_col_offsets[i] = pg_buf[col_ptr-i]+(jumps_used*256);
+ }
+ }
+ fixed_cols_found = 0;
+ var_cols_found = 0;
+ row_fixed_cols = row_cols - row_var_cols;
+
+ if (mdb_get_option(MDB_DEBUG_ROW)) {
+ fprintf(stdout,"bitmask_sz %d num_jumps %d\n",bitmask_sz, num_jumps);
+ fprintf(stdout,"row_var_cols %d\n", row_var_cols);
+ fprintf(stdout,"row_fixed_cols %d\n", row_fixed_cols);
+ }
+
+ /* read information into fields[] */
+ for (i=0;i<table->num_cols;i++) {
+ col = g_ptr_array_index (table->columns, i);
+ fields[i].colnum = i;
+ fields[i].is_fixed = (mdb_is_fixed_col(col)) ? 1 : 0;
+ byte_num = col->col_num / 8;
+ bit_num = col->col_num % 8;
+ /* logic on nulls is reverse, 1 is not null, 0 is null */
+ fields[i].is_null = nullmask[byte_num] & (1 << bit_num) ? 0 : 1;
+
+ if ((fields[i].is_fixed)
+ && (fixed_cols_found < row_fixed_cols)) {
+ col_start = col->fixed_offset + 1;
+ fields[i].start = row_start + col_start;
+ fields[i].value = &pg_buf[row_start + col_start];
+ fields[i].siz = col->col_size;
+ fixed_cols_found++;
+ } else if ((!fields[i].is_fixed)
+ && (var_cols_found < row_var_cols)) {
+ col_start = var_col_offsets[var_cols_found];
+ fields[i].start = row_start + col_start;
+ fields[i].value = &pg_buf[row_start + col_start];
+ fields[i].siz = var_col_offsets[var_cols_found+1] -
+ col_start;
+ var_cols_found++;
+ } else {
+ fields[i].start = 0;
+ fields[i].value = NULL;
+ fields[i].siz = 0;
+ fields[i].is_null = 1;
+ }
+ }
+ g_free(var_col_offsets);
+
+ return row_cols;
+}
+/**
+ * mdb_crack_row:
+ * @table: Table that the row belongs to
+ * @row_start: offset to start of row on current page
+ * @row_end: offset to end of row on current page
+ * @fields: pointer to MdbField array to be popluated by mdb_crack_row
+ *
+ * Cracks a row buffer apart into its component fields.
+ *
+ * A row buffer is that portion of a data page which contains the values for
+ * that row. Its beginning and end can be found in the row offset table.
+ *
+ * The resulting MdbField array contains pointers into the row for each field
+ * present. Be aware that by modifying field[]->value, you would be modifying
+ * the row buffer itself, not a copy.
+ *
+ * This routine is mostly used internally by mdb_fetch_row() but may have some
+ * applicability for advanced application programs.
+ *
+ * Return value: number of fields present.
+ */
+int
+mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
+{
+MdbCatalogEntry *entry = table->entry;
+MdbHandle *mdb = entry->mdb;
+
+ if (IS_JET4(mdb)) {
+ return mdb_crack_row4(table, row_start, row_end, fields);
+ } else {
+ return mdb_crack_row3(table, row_start, row_end, fields);
+ }
+}
+
+static int
+mdb_pack_null_mask(unsigned char *buffer, int num_fields, MdbField *fields)
+{
+ int pos = 0, bit = 0, byte = 0;
+ int i;
+
+ /* 'Not null' bitmap */
+ for (i=0; i<num_fields; i++) {
+ /* column is null if bit is clear (0) */
+ if (!fields[i].is_null) {
+ byte |= 1 << bit;
+ //printf("%d %d %d %d\n", i, bit, 1 << bit, byte);
+ }
+ bit++;
+ if (bit==8) {
+ buffer[pos++] = byte;
+ bit = byte = 0;
+ }
+ }
+ /* if we've written any bits to the current byte, flush it */
+ if (bit)
+ buffer[pos++] = byte;
+
+ return pos;
+}
+/* fields must be ordered with fixed columns first, then vars, subsorted by
+ * column number */
+static int
+mdb_pack_row4(MdbTableDef *table, unsigned char *row_buffer, unsigned int num_fields, MdbField *fields)
+{
+ unsigned int pos = 0;
+ unsigned int var_cols = 0;
+ unsigned int i;
+
+ row_buffer[pos++] = num_fields & 0xff;
+ row_buffer[pos++] = (num_fields >> 8) & 0xff;
+
+ /* Fixed length columns */
+ for (i=0;i<num_fields;i++) {
+ if (fields[i].is_fixed) {
+ fields[i].offset = pos;
+ if (!fields[i].is_null) {
+ memcpy(&row_buffer[pos], fields[i].value, fields[i].siz);
+ }
+ pos += fields[i].siz;
+ }
+ }
+ /* For tables without variable-length columns */
+ if (table->num_var_cols == 0) {
+ pos += mdb_pack_null_mask(&row_buffer[pos], num_fields, fields);
+ return pos;
+ }
+ /* Variable length columns */
+ for (i=0;i<num_fields;i++) {
+ if (!fields[i].is_fixed) {
+ var_cols++;
+ fields[i].offset = pos;
+ if (! fields[i].is_null) {
+ memcpy(&row_buffer[pos], fields[i].value, fields[i].siz);
+ pos += fields[i].siz;
+ }
+ }
+ }
+ /* EOD */
+ row_buffer[pos] = pos & 0xff;
+ row_buffer[pos+1] = (pos >> 8) & 0xff;
+ pos += 2;
+
+ /* Offsets of the variable-length columns */
+ for (i=num_fields; i>0; i--) {
+ if (!fields[i-1].is_fixed) {
+ row_buffer[pos++] = fields[i-1].offset & 0xff;
+ row_buffer[pos++] = (fields[i-1].offset >> 8) & 0xff;
+ }
+ }
+ /* Number of variable-length columns */
+ row_buffer[pos++] = var_cols & 0xff;
+ row_buffer[pos++] = (var_cols >> 8) & 0xff;
+
+ pos += mdb_pack_null_mask(&row_buffer[pos], num_fields, fields);
+ return pos;
+}
+
+static int
+mdb_pack_row3(MdbTableDef *table, unsigned char *row_buffer, unsigned int num_fields, MdbField *fields)
+{
+ unsigned int pos = 0;
+ unsigned int var_cols = 0;
+ unsigned int i, j;
+ unsigned char *offset_high;
+
+ row_buffer[pos++] = num_fields;
+
+ /* Fixed length columns */
+ for (i=0;i<num_fields;i++) {
+ if (fields[i].is_fixed) {
+ fields[i].offset = pos;
+ if (!fields[i].is_null) {
+ memcpy(&row_buffer[pos], fields[i].value, fields[i].siz);
+ }
+ pos += fields[i].siz;
+ }
+ }
+ /* For tables without variable-length columns */
+ if (table->num_var_cols == 0) {
+ pos += mdb_pack_null_mask(&row_buffer[pos], num_fields, fields);
+ return pos;
+ }
+ /* Variable length columns */
+ for (i=0;i<num_fields;i++) {
+ if (!fields[i].is_fixed) {
+ var_cols++;
+ fields[i].offset = pos;
+ if (! fields[i].is_null) {
+ memcpy(&row_buffer[pos], fields[i].value, fields[i].siz);
+ pos += fields[i].siz;
+ }
+ }
+ }
+
+ offset_high = (unsigned char *) g_malloc(var_cols+1);
+ offset_high[0] = (pos << 8) & 0xff;
+ j = 1;
+
+ /* EOD */
+ row_buffer[pos] = pos & 0xff;
+ pos++;
+
+ /* Variable length column offsets */
+ for (i=num_fields; i>0; i--) {
+ if (!fields[i-1].is_fixed) {
+ row_buffer[pos++] = fields[i-1].offset & 0xff;
+ offset_high[j++] = (fields[i-1].offset << 8) & 0xff;
+ }
+ }
+
+ /* Dummy jump table entry */
+ if (offset_high[0] < (pos+(num_fields+7)/8-1)/255) {
+ row_buffer[pos++] = 0xff;
+ }
+ /* Jump table */
+ for (i=0; i<var_cols; i++) {
+ if (offset_high[i] > offset_high[i+1]) {
+ row_buffer[pos++] = var_cols-i;
+ }
+ }
+ g_free(offset_high);
+
+ row_buffer[pos++] = var_cols;
+
+ pos += mdb_pack_null_mask(&row_buffer[pos], num_fields, fields);
+ return pos;
+}
+int
+mdb_pack_row(MdbTableDef *table, unsigned char *row_buffer, int unsigned num_fields, MdbField *fields)
+{
+ if (table->is_temp_table) {
+ unsigned int i;
+ for (i=0; i<num_fields; i++) {
+ MdbColumn *c = g_ptr_array_index(table->columns, i);
+ fields[i].is_null = (fields[i].value) ? 0 : 1;
+ fields[i].colnum = i;
+ fields[i].is_fixed = c->is_fixed;
+ if ((c->col_type != MDB_TEXT)
+ && (c->col_type != MDB_MEMO)) {
+ fields[i].siz = c->col_size;
+ }
+ }
+ }
+ if (IS_JET4(table->entry->mdb)) {
+ return mdb_pack_row4(table, row_buffer, num_fields, fields);
+ } else {
+ return mdb_pack_row3(table, row_buffer, num_fields, fields);
+ }
+}
+int
+mdb_pg_get_freespace(MdbHandle *mdb)
+{
+ int rows, free_start, free_end;
+ int row_count_offset = mdb->fmt->row_count_offset;
+
+ rows = mdb_pg_get_int16(mdb, row_count_offset);
+ free_start = row_count_offset + 2 + (rows * 2);
+ free_end = mdb_pg_get_int16(mdb, row_count_offset + (rows * 2));
+ mdb_debug(MDB_DEBUG_WRITE,"free space left on page = %d", free_end - free_start);
+ return (free_end - free_start);
+}
+unsigned char *
+mdb_new_leaf_pg(MdbCatalogEntry *entry)
+{
+ MdbHandle *mdb = entry->mdb;
+ unsigned char *new_pg;
+
+ new_pg = (unsigned char *) g_malloc0(mdb->fmt->pg_size);
+
+ new_pg[0]=0x04;
+ new_pg[1]=0x01;
+ _mdb_put_int32(new_pg, 4, entry->table_pg);
+
+ return new_pg;
+}
+unsigned char *
+mdb_new_data_pg(MdbCatalogEntry *entry)
+{
+ MdbFormatConstants *fmt = entry->mdb->fmt;
+ unsigned char *new_pg;
+
+ new_pg = (unsigned char *) g_malloc0(fmt->pg_size);
+
+ new_pg[0]=0x01;
+ new_pg[1]=0x01;
+ _mdb_put_int16(new_pg, 2, fmt->pg_size - fmt->row_count_offset - 2);
+ _mdb_put_int32(new_pg, 4, entry->table_pg);
+
+ return new_pg;
+}
+
+int
+mdb_update_indexes(MdbTableDef *table, int num_fields, MdbField *fields, guint32 pgnum, guint16 rownum)
+{
+ unsigned int i;
+ MdbIndex *idx;
+
+ for (i=0;i<table->num_idxs;i++) {
+ idx = g_ptr_array_index (table->indices, i);
+ mdb_debug(MDB_DEBUG_WRITE,"Updating %s (%d).", idx->name, idx->index_type);
+ if (idx->index_type==1) {
+ mdb_update_index(table, idx, num_fields, fields, pgnum, rownum);
+ }
+ }
+ return 1;
+}
+
+int
+mdb_init_index_chain(MdbTableDef *table, MdbIndex *idx)
+{
+ MdbCatalogEntry *entry = table->entry;
+ MdbHandle *mdb = entry->mdb;
+
+ table->scan_idx = idx;
+ table->chain = g_malloc0(sizeof(MdbIndexChain));
+ table->mdbidx = mdb_clone_handle(mdb);
+ mdb_read_pg(table->mdbidx, table->scan_idx->first_pg);
+
+ return 1;
+}
+
+int
+mdb_update_index(MdbTableDef *table, MdbIndex *idx, unsigned int num_fields, MdbField *fields, guint32 pgnum, guint16 rownum)
+{
+ MdbCatalogEntry *entry = table->entry;
+ MdbHandle *mdb = entry->mdb;
+ int idx_xref[16];
+ unsigned int i, j;
+ MdbIndexChain *chain;
+ MdbField idx_fields[10];
+
+ for (i = 0; i < idx->num_keys; i++) {
+ for (j = 0; j < num_fields; j++) {
+ // key_col_num is 1 based, can't remember why though
+ if (fields[j].colnum == idx->key_col_num[i]-1) {
+ idx_xref[i] = j;
+ idx_fields[i] = fields[j];
+ }
+ }
+ }
+ for (i = 0; i < idx->num_keys; i++) {
+ fprintf(stdout, "key col %d (%d) is mapped to field %d (%d %d)\n",
+ i, idx->key_col_num[i], idx_xref[i], fields[idx_xref[i]].colnum,
+ fields[idx_xref[i]].siz);
+ }
+ for (i = 0; i < num_fields; i++) {
+ fprintf(stdout, "%d (%d %d)\n",
+ i, fields[i].colnum,
+ fields[i].siz);
+ }
+
+ chain = g_malloc0(sizeof(MdbIndexChain));
+
+ mdb_index_find_row(mdb, idx, chain, pgnum, rownum);
+ printf("chain depth = %d\n", chain->cur_depth);
+ printf("pg = %" G_GUINT32_FORMAT "\n",
+ chain->pages[chain->cur_depth-1].pg);
+ //mdb_copy_index_pg(table, idx, &chain->pages[chain->cur_depth-1]);
+ mdb_add_row_to_leaf_pg(table, idx, &chain->pages[chain->cur_depth-1], idx_fields);
+
+ return 1;
+}
+
+int
+mdb_insert_row(MdbTableDef *table, int num_fields, MdbField *fields)
+{
+ int new_row_size;
+ unsigned char row_buffer[4096];
+ MdbCatalogEntry *entry = table->entry;
+ MdbHandle *mdb = entry->mdb;
+ MdbFormatConstants *fmt = mdb->fmt;
+ guint32 pgnum;
+ guint16 rownum;
+
+ if (!mdb->f->writable) {
+ fprintf(stderr, "File is not open for writing\n");
+ return 0;
+ }
+ new_row_size = mdb_pack_row(table, row_buffer, num_fields, fields);
+ if (mdb_get_option(MDB_DEBUG_WRITE)) {
+ buffer_dump(row_buffer, 0, new_row_size-1);
+ }
+ pgnum = mdb_map_find_next_freepage(table, new_row_size);
+ if (!pgnum) {
+ fprintf(stderr, "Unable to allocate new page.\n");
+ return 0;
+ }
+
+ rownum = mdb_add_row_to_pg(table, row_buffer, new_row_size);
+
+ if (mdb_get_option(MDB_DEBUG_WRITE)) {
+ buffer_dump(mdb->pg_buf, 0, 39);
+ buffer_dump(mdb->pg_buf, fmt->pg_size - 160, fmt->pg_size-1);
+ }
+ mdb_debug(MDB_DEBUG_WRITE, "writing page %d", pgnum);
+ if (!mdb_write_pg(mdb, pgnum)) {
+ fprintf(stderr, "write failed! exiting...\n");
+ exit(1);
+ }
+
+ mdb_update_indexes(table, num_fields, fields, pgnum, rownum);
+
+ return 1;
+}
+/*
+ * Assumes caller has verfied space is available on page and adds the new
+ * row to the current pg_buf.
+ */
+guint16
+mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_size)
+{
+ unsigned char *new_pg;
+ int num_rows, i, pos, row_start, row_end, row_size;
+ MdbCatalogEntry *entry = table->entry;
+ MdbHandle *mdb = entry->mdb;
+ MdbFormatConstants *fmt = mdb->fmt;
+
+ if (table->is_temp_table) {
+ GPtrArray *pages = table->temp_table_pages;
+ if (pages->len == 0) {
+ new_pg = mdb_new_data_pg(entry);
+ g_ptr_array_add(pages, new_pg);
+ } else {
+ new_pg = g_ptr_array_index(pages, pages->len - 1);
+ if (mdb_get_int16(new_pg, 2) < new_row_size + 2) {
+ new_pg = mdb_new_data_pg(entry);
+ g_ptr_array_add(pages, new_pg);
+ }
+ }
+
+ num_rows = mdb_get_int16(new_pg, fmt->row_count_offset);
+ pos = (num_rows == 0) ? fmt->pg_size :
+ mdb_get_int16(new_pg, fmt->row_count_offset + (num_rows*2));
+ } else { /* is not a temp table */
+ new_pg = mdb_new_data_pg(entry);
+
+ num_rows = mdb_pg_get_int16(mdb, fmt->row_count_offset);
+ pos = fmt->pg_size;
+
+ /* copy existing rows */
+ for (i=0;i<num_rows;i++) {
+ row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (i*2));
+ row_end = mdb_find_end_of_row(mdb, i);
+ row_size = row_end - row_start + 1;
+ pos -= row_size;
+ memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
+ _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (i*2), pos);
+ }
+ }
+
+ /* add our new row */
+ pos -= new_row_size;
+ memcpy(&new_pg[pos], row_buffer, new_row_size);
+ /* add row to the row offset table */
+ _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (num_rows*2), pos);
+
+ /* update number rows on this page */
+ num_rows++;
+ _mdb_put_int16(new_pg, fmt->row_count_offset, num_rows);
+
+ /* update the freespace */
+ _mdb_put_int16(new_pg,2,pos - fmt->row_count_offset - 2 - (num_rows*2));
+
+ /* copy new page over old */
+ if (!table->is_temp_table) {
+ memcpy(mdb->pg_buf, new_pg, fmt->pg_size);
+ g_free(new_pg);
+ }
+
+ return num_rows;
+}
+int
+mdb_update_row(MdbTableDef *table)
+{
+int row_start, row_end;
+unsigned int i;
+MdbColumn *col;
+MdbCatalogEntry *entry = table->entry;
+MdbHandle *mdb = entry->mdb;
+MdbFormatConstants *fmt = mdb->fmt;
+MdbField fields[256];
+unsigned char row_buffer[4096];
+int old_row_size, new_row_size, delta;
+unsigned int num_fields;
+
+ if (!mdb->f->writable) {
+ fprintf(stderr, "File is not open for writing\n");
+ return 0;
+ }
+ row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + ((table->cur_row-1)*2));
+ row_end = mdb_find_end_of_row(mdb, table->cur_row-1);
+ old_row_size = row_end - row_start;
+
+ row_start &= 0x0FFF; /* remove flags */
+
+ mdb_debug(MDB_DEBUG_WRITE,"page %lu row %d start %d end %d", (unsigned long) table->cur_phys_pg, table->cur_row-1, row_start, row_end);
+ if (mdb_get_option(MDB_DEBUG_LIKE))
+ buffer_dump(mdb->pg_buf, row_start, row_end);
+
+ for (i=0;i<table->num_cols;i++) {
+ col = g_ptr_array_index(table->columns,i);
+ if (col->bind_ptr && mdb_is_col_indexed(table,i)) {
+ fprintf(stderr, "Attempting to update column that is part of an index\n");
+ return 0;
+ }
+ }
+ num_fields = mdb_crack_row(table, row_start, row_end, fields);
+
+ if (mdb_get_option(MDB_DEBUG_WRITE)) {
+ for (i=0;i<num_fields;i++) {
+ printf("col %d %d start %d siz %d\n", i, fields[i].colnum, fields[i].start, fields[i].siz);
+ }
+ }
+ for (i=0;i<table->num_cols;i++) {
+ col = g_ptr_array_index(table->columns,i);
+ if (col->bind_ptr) {
+ printf("yes\n");
+ fields[i].value = col->bind_ptr;
+ fields[i].siz = *(col->len_ptr);
+ }
+ }
+
+ new_row_size = mdb_pack_row(table, row_buffer, num_fields, fields);
+ if (mdb_get_option(MDB_DEBUG_WRITE))
+ buffer_dump(row_buffer, 0, new_row_size-1);
+ delta = new_row_size - old_row_size;
+ if ((mdb_pg_get_freespace(mdb) - delta) < 0) {
+ fprintf(stderr, "No space left on this page, update will not occur\n");
+ return 0;
+ }
+ /* do it! */
+ mdb_replace_row(table, table->cur_row-1, row_buffer, new_row_size);
+ return 0;
+}
+int
+mdb_replace_row(MdbTableDef *table, int row, unsigned char *new_row, int new_row_size)
+{
+MdbCatalogEntry *entry = table->entry;
+MdbHandle *mdb = entry->mdb;
+MdbFormatConstants *fmt = mdb->fmt;
+unsigned char *new_pg;
+guint16 num_rows;
+int row_start, row_end, row_size;
+int i, pos;
+
+ if (mdb_get_option(MDB_DEBUG_WRITE)) {
+ buffer_dump(mdb->pg_buf, 0, 39);
+ buffer_dump(mdb->pg_buf, fmt->pg_size - 160, fmt->pg_size-1);
+ }
+ mdb_debug(MDB_DEBUG_WRITE,"updating row %d on page %lu", row, (unsigned long) table->cur_phys_pg);
+ new_pg = mdb_new_data_pg(entry);
+
+ num_rows = mdb_pg_get_int16(mdb, fmt->row_count_offset);
+ _mdb_put_int16(new_pg, fmt->row_count_offset, num_rows);
+
+ pos = mdb->fmt->pg_size;
+
+ /* rows before */
+ for (i=0;i<row;i++) {
+ row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (i*2));
+ row_end = mdb_find_end_of_row(mdb, i);
+ row_size = row_end - row_start + 1;
+ pos -= row_size;
+ memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
+ _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (i*2), pos);
+ }
+
+ /* our row */
+ pos -= new_row_size;
+ memcpy(&new_pg[pos], new_row, new_row_size);
+ _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (row*2), pos);
+
+ /* rows after */
+ for (i=row+1;i<num_rows;i++) {
+ row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (i*2));
+ row_end = mdb_find_end_of_row(mdb, i);
+ row_size = row_end - row_start + 1;
+ pos -= row_size;
+ memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
+ _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (i*2), pos);
+ }
+
+ /* almost done, copy page over current */
+ memcpy(mdb->pg_buf, new_pg, fmt->pg_size);
+
+ g_free(new_pg);
+
+ _mdb_put_int16(mdb->pg_buf, 2, mdb_pg_get_freespace(mdb));
+ if (mdb_get_option(MDB_DEBUG_WRITE)) {
+ buffer_dump(mdb->pg_buf, 0, 39);
+ buffer_dump(mdb->pg_buf, fmt->pg_size - 160, fmt->pg_size-1);
+ }
+ /* drum roll, please */
+ if (!mdb_write_pg(mdb, table->cur_phys_pg)) {
+ fprintf(stderr, "write failed! exiting...\n");
+ exit(1);
+ }
+ return 0;
+}
+static int
+mdb_add_row_to_leaf_pg(MdbTableDef *table, MdbIndex *idx, MdbIndexPage *ipg, MdbField *idx_fields)
+/*, guint32 pgnum, guint16 rownum)
+static int
+mdb_copy_index_pg(MdbTableDef *table, MdbIndex *idx, MdbIndexPage *ipg)
+*/
+{
+ MdbCatalogEntry *entry = table->entry;
+ MdbHandle *mdb = entry->mdb;
+ MdbColumn *col;
+ guint32 pg;
+ guint16 row;
+ unsigned char *new_pg;
+ unsigned char key_hash[256];
+ unsigned char iflag;
+ int keycol;
+
+ new_pg = mdb_new_leaf_pg(entry);
+
+ mdb_index_page_reset(ipg);
+ mdb_read_pg(mdb, ipg->pg);
+
+ /* do we support this index type yet? */
+ if (idx->num_keys > 1) {
+ fprintf(stderr,"multikey indexes not yet supported, aborting\n");
+ return 0;
+ }
+ keycol = idx->key_col_num[0];
+ col = g_ptr_array_index (table->columns, keycol - 1);
+ printf("keycol = %d (%s)\n", keycol, col->name);
+ if (!mdb_is_fixed_col(col)) {
+ fprintf(stderr,"variable length key columns not yet supported, aborting\n");
+ return 0;
+ }
+ printf("col size = %d\n", col->col_size);
+
+ while (mdb_index_find_next_on_page(mdb, ipg)) {
+
+ /* check for compressed indexes. */
+ if (ipg->len < col->col_size + 1) {
+ fprintf(stderr,"compressed indexes not yet supported, aborting\n");
+ return 0;
+ }
+
+ pg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 4);
+ row = mdb->pg_buf[ipg->offset + ipg->len - 1];
+ iflag = mdb->pg_buf[ipg->offset];
+ mdb_index_swap_n(&mdb->pg_buf[ipg->offset + 1], col->col_size, key_hash);
+ key_hash[col->col_size - 1] &= 0x7f;
+ printf("length = %d\n", ipg->len);
+ printf("iflag = %d pg = %" G_GUINT32_FORMAT
+ " row = %" G_GUINT16_FORMAT "\n", iflag, pg, row);
+ buffer_dump(mdb->pg_buf, ipg->offset, ipg->offset + ipg->len - 1);
+ buffer_dump(mdb->pg_buf, ipg->offset + 1, ipg->offset + col->col_size);
+ buffer_dump(key_hash, 0, col->col_size - 1);
+ ipg->offset += ipg->len;
+ ipg->len = 0;
+ row++;
+ }
+ g_free(new_pg);
+
+ return ipg->len;
+}
diff --git a/navit/data/poi_geodownload/poi_geodownload.c b/navit/data/poi_geodownload/poi_geodownload.c
new file mode 100644
index 000000000..229457b68
--- /dev/null
+++ b/navit/data/poi_geodownload/poi_geodownload.c
@@ -0,0 +1,756 @@
+#include <mdbtools.h>
+#include "config.h"
+#include "debug.h"
+#include "coord.h"
+#include "projection.h"
+#include "map.h"
+#include "item.h"
+#include "plugin.h"
+
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+struct map_priv
+{
+ char *filename;
+ MdbHandle *h;
+ MdbHandle *h_idx;
+ MdbTableDef *table;
+ GPtrArray *table_col;
+ MdbColumn **cols;
+ MdbIndex *idx;
+ int idx_size;
+ enum item_type type;
+ int name_col;
+};
+
+struct map_rect_priv
+{
+ struct item item;
+ struct map_priv *m;
+ enum attr_type attr_next;
+ int cidx;
+ char buffer[4096];
+};
+
+#if 0
+struct index_data {
+ unsigned char data[15];
+};
+struct poi {
+ char filename[1024];
+ char icon[1024];
+ long pos;
+ MdbHandle *h;
+ MdbHandle *h_idx;
+ MdbTableDef *table;
+ GPtrArray *table_col;
+ MdbColumn **cols;
+ MdbIndex *idx;
+ int idx_size;
+ struct index_data index_data;
+ MdbIndexChain chain;
+ struct poi *next;
+} *poi_list;
+
+struct poi_data {
+ struct poi *poi;
+ int page;
+ int row;
+};
+
+ char poipath[256];
+ char poibmp[256];
+
+
+#endif
+
+static void
+print_col(MdbHandle *h, MdbColumn *col, char *buffer, int hex)
+{
+ char *s;
+ dbg(1,"type=%d\n", col->col_type);
+ switch (col->col_type) {
+ case MDB_BOOL:
+ strcpy(buffer, mdb_pg_get_byte(h, col->cur_value_start) ? "True" : "False");
+ break;
+ case MDB_BYTE:
+ sprintf(buffer, "%d", mdb_pg_get_byte(h, col->cur_value_start));
+ break;
+ case MDB_LONGINT:
+ if (hex)
+ sprintf(buffer, "0x%lx", mdb_pg_get_int32(h, col->cur_value_start));
+ else
+ sprintf(buffer, "%ld", mdb_pg_get_int32(h, col->cur_value_start));
+ break;
+ case MDB_DOUBLE:
+ sprintf(buffer, "%f", mdb_pg_get_double(h, col->cur_value_start));
+ break;
+ case MDB_TEXT:
+ dbg(1,"pg_buf %p start %d len %d\n", h->pg_buf, col->cur_value_start, col->cur_value_len);
+ if (col->cur_value_len) {
+ s=mdb_col_to_string (h, h->pg_buf, col->cur_value_start, col->col_type, col->cur_value_len);
+ dbg(1,"s=%p\n", s);
+ sprintf(buffer, "%s", s);
+ }
+ break;
+ default:
+ sprintf(buffer, "unknown (%d)", col->col_type);
+ }
+}
+
+#if 0
+
+static void
+setup_idx_data(struct index_data *idx, struct coord *c, unsigned int geoflags, int size)
+{
+ /* 7f 80 1c 91 0a 7f 80 5c f5 41 7f 80 00 00 05 */
+ idx->data[0]=0x7f;
+ idx->data[1]=(c->x >> 24) ^ 0x80;
+ idx->data[2]=c->x >> 16;
+ idx->data[3]=c->x >> 8;
+ idx->data[4]=c->x;
+ idx->data[5]=0x7f;
+ idx->data[6]=(c->y >> 24) ^ 0x80;
+ idx->data[7]=c->y >> 16;
+ idx->data[8]=c->y >> 8;
+ idx->data[9]=c->y;
+ idx->data[10]=0x7f;
+ if (size > 12) {
+ idx->data[11]=0x80 | (geoflags >> 24);
+ idx->data[12]=geoflags >> 16;
+ idx->data[13]=geoflags >> 8;
+ idx->data[14]=geoflags;
+ } else {
+ idx->data[11]=geoflags;
+ }
+}
+
+static void
+setup_idx_rect(struct coord *rect, struct index_data *idx, int size)
+{
+ struct coord r[2];
+ r[0].x=rect[0].x;
+ r[0].y=rect[1].y;
+ r[1].x=rect[1].x;
+ r[1].y=rect[0].y;
+#if 0
+ printf("low 0x%x 0%x\n", r[0].x, r[0].y);
+ printf("high 0x%x 0%x\n", r[1].x, r[1].y);
+#endif
+ setup_idx_data(idx, r, 0, size);
+ setup_idx_data(idx+1, r+1, 0xffffffff, size);
+}
+
+#endif
+
+static int
+load_row(struct map_priv *poi, int pg, int row)
+{
+ int row_start, row_end, offset;
+ unsigned int num_fields, i;
+ MdbField fields[256];
+ MdbFormatConstants *fmt;
+ int debug=0;
+
+ fmt=poi->h->fmt;
+ mdb_read_pg(poi->h, pg);
+ dbg(1, "enter poi=%p pg=%d row=%d\n", poi, pg, row);
+ dbg(1,"Page Type %d row_count_offset %d\n",poi->h->pg_buf[0], fmt->row_count_offset);
+ for (i = 0; i <= row; i++) {
+ offset=(fmt->row_count_offset + 2) + i * 2;
+ dbg(1,"row %d %d 0x%x\n", i, offset, mdb_pg_get_int16(poi->h, offset));
+ }
+ row_start = mdb_pg_get_int16(poi->h, (fmt->row_count_offset + 2) + row * 2);
+ if (row_start & 0x4000)
+ return 1;
+ row_end = mdb_find_end_of_row(poi->h, row);
+ if (debug) {
+ printf("start=0x%x end=0x%x\n", row_start, row_end);
+ buffer_dump(poi->h->pg_buf, row_start, row_end);
+ }
+
+ poi->h->cur_pos=row_start & 0x1fff;
+ poi->table->cur_row=row;
+ num_fields = mdb_crack_row(poi->table, row_start & 0x1fff, row_end, fields);
+ dbg(1,"num_fields=%d\n", num_fields);
+ for (i = 0; i < num_fields; i++) {
+ dbg(1,"i=%d/%d\n", i, num_fields);
+ poi->cols[i]->cur_value_start=fields[i].start;
+ poi->cols[i]->cur_value_len=fields[i].siz;
+ }
+ return 0;
+}
+
+#if 0
+
+static MdbIndexPage *
+index_next_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
+{
+ MdbIndexPage *ipg;
+
+ ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
+ if (!mdb_index_find_next_on_page(mdb, ipg)) {
+#if 0
+ printf("no next\n");
+#endif
+ if (!chain->clean_up_mode) {
+#if 0
+ printf("no cleanup\n");
+#endif
+ if (!(ipg = mdb_index_unwind(mdb, idx, chain)))
+ chain->clean_up_mode = 1;
+ }
+ if (chain->clean_up_mode) {
+#if 0
+ printf("cleanup\n");
+#endif
+ //fprintf(stdout,"in cleanup mode\n");
+
+ if (!chain->last_leaf_found) {
+ printf("no last_leaf_found\n");
+ return NULL;
+ }
+ mdb_read_pg(mdb, chain->last_leaf_found);
+ chain->last_leaf_found =
+ mdb_pg_get_int24(mdb, 0x0c);
+ //printf("next leaf %lu\n", chain->last_leaf_found);
+ mdb_read_pg(mdb, chain->last_leaf_found);
+ /* reuse the chain for cleanup mode */
+ chain->cur_depth = 1;
+ ipg = &chain->pages[0];
+ mdb_index_page_init(ipg);
+ ipg->pg = chain->last_leaf_found;
+ //printf("next on page %d\n",
+ if (!mdb_index_find_next_on_page(mdb, ipg)) {
+#if 0
+ printf("no find_next_on_page\n");
+#endif
+ return NULL;
+ }
+ }
+ }
+ return ipg;
+}
+
+static int
+index_next(struct poi *poi, struct index_data *idx)
+{
+ MdbIndexPage *ipg;
+ MdbIndexChain *chain = &poi->chain;
+ int row;
+ int pg;
+ int offset;
+ char *cmp, *low, *high;
+ int debug=0;
+
+
+ for(;;) {
+ for(;;) {
+ ipg=index_next_row(poi->h_idx, poi->idx, chain);
+ if (! ipg)
+ return 0;
+ row = poi->h_idx->pg_buf[ipg->offset + ipg->len - 1];
+ pg = mdb_pg_get_int24_msb(poi->h_idx, ipg->offset + ipg->len - 4);
+
+ offset=poi->idx_size+4-ipg->len;
+ memcpy(poi->index_data.data+offset, poi->h_idx->pg_buf+ipg->offset, ipg->len - 4);
+ cmp=poi->index_data.data;
+ low=idx[0].data;
+ high=idx[1].data;
+ if (debug > 1) {
+ buffer_dump(low, 0, poi->idx_size-1);
+ buffer_dump(cmp, 0, poi->idx_size-1);
+ buffer_dump(high, 0, poi->idx_size-1);
+ printf("%d %d %d\n", memcmp(cmp, low, poi->idx_size), memcmp(cmp, high, poi->idx_size), offset);
+ }
+#if 0
+ buffer_dump(poi->h_idx->pg_buf, ipg->offset, ipg->offset+ipg->len-1);
+#endif
+ ipg->offset += ipg->len;
+ if (memcmp(cmp, low, poi->idx_size) >= 0) {
+ if (memcmp(cmp, high, poi->idx_size) <=0 ) {
+ if (debug) {
+ printf("match\n");
+ buffer_dump(low, 0, poi->idx_size-1);
+ buffer_dump(cmp, 0, poi->idx_size-1);
+ buffer_dump(high, 0, poi->idx_size-1);
+ printf("%d %d %d\n", memcmp(cmp, low, poi->idx_size), memcmp(cmp, high, poi->idx_size), offset);
+ }
+ break;
+ } else {
+ return 0;
+ }
+ }
+ if (debug > 1)
+ printf("row=0x%x pg=0x%x len=%d\n", row, pg, ipg->len);
+ }
+ if (debug)
+ printf("match: row=0x%x pg=0x%x len=%d\n", row, pg, ipg->len);
+ if (!load_row(poi, pg, row))
+ break;
+ }
+ return 1;
+}
+
+#endif
+
+static int
+load_poi_table(struct map_priv *m, MdbCatalogEntry *entry)
+{
+ int j;
+ MdbIndex *idx;
+
+ m->h_idx=NULL;
+ m->table = mdb_read_table(entry);
+ m->table_col = mdb_read_columns(m->table);
+ mdb_read_indices(m->table);
+ m->cols = (MdbColumn **) (m->table_col->pdata);
+ if (m->table_col->len < 4 || strcasecmp(m->cols[0]->name, "X") ||
+ strcasecmp(m->cols[1]->name, "Y") || strcasecmp(m->cols[3]->name, "GEOFLAGS"))
+ return 1;
+ m->name_col=-1;
+ for (j = 0; j < m->table_col->len ; j++) {
+ if (!strcasecmp(m->cols[j]->name, "NAME"))
+ m->name_col=j;
+ }
+ for (j = 0; j < m->table->num_idxs; j++) {
+ idx = m->table->indices->pdata[j];
+ if (idx->num_keys == 3 && idx->key_col_num[0] == 1 &&
+ idx->key_col_num[1] == 2 && idx->key_col_num[2] == 4) {
+ m->idx = idx;
+ m->idx_size=3+m->cols[0]->col_size+m->cols[1]->col_size+m->cols[3]->col_size;
+ m->h_idx=mdb_clone_handle(m->h);
+ }
+ }
+ return 0;
+}
+
+#if 0
+
+static void
+load_poi(char *filename, char *icon, int type)
+{
+ int i;
+ MdbCatalogEntry *entry;
+ GPtrArray *catalog;
+ struct poi *new = g_new0(struct poi, 1);
+
+ FILE *fp = fopen(filename,"r");
+ if( fp ) {
+ fclose(fp);
+ } else {
+ printf("ERR : POI file %s does not exists!\n",filename);
+ exit(0);
+ return -1;
+ }
+
+
+ fp = fopen(icon,"r");
+ if( fp ) {
+ fclose(fp);
+ } else {
+ printf("ERR : WARNING INCORRECT PICTURE! %s!\n",icon);
+ exit(0);
+ return -1;
+ }
+
+ strcpy(new->filename,filename);
+ strcpy(new->icon,icon);
+ new->type = type;
+
+
+ if (type == 0) {
+ new->h = mdb_open(filename, MDB_NOFLAGS);
+ catalog = mdb_read_catalog(new->h, MDB_TABLE);
+ for (i = 0; i < catalog->len; i++) {
+ entry = catalog->pdata[i];
+ if (!strcasecmp(entry->object_name, "_INDEXDATA")) {
+ if (load_poi_table(new, entry)) {
+ printf("%s invalid\n", filename);
+ g_free(new);
+ new=NULL;
+ }
+ }
+ }
+ g_ptr_array_free(catalog, 1);
+ }
+ if (new) {
+ new->next = poi_list;
+ poi_list = new;
+ }
+}
+
+static void
+get_coord(struct poi *p, struct coord *c)
+{
+ c->x=mdb_pg_get_int32(p->h, p->cols[0]->cur_value_start);
+ c->y=mdb_pg_get_int32(p->h, p->cols[1]->cur_value_start);
+}
+
+static void
+poi_info(struct display_list *list, struct popup_item **popup)
+{
+ struct poi_data *data=list->data;
+ struct poi *poi=data->poi;
+ struct popup_item *popup_last, *popup_val_last;
+ char *text,buffer[4096];
+ int j;
+ MdbColumn *col;
+ char *v;
+
+ popup_last = *popup;
+
+ popup_val_last = NULL;
+ sprintf(buffer,"File:%s", poi->filename);
+ popup_item_new_text(&popup_val_last, buffer, 1);
+ sprintf(buffer,"Icon:%s", poi->icon);
+ popup_item_new_text(&popup_val_last, buffer, 2);
+ if (poi->type == 0) {
+ printf("poi_info pg=%d row=%d\n", data->page, data->row);
+ load_row(poi, data->page, data->row);
+ sprintf(buffer,"Page:%d", data->page);
+ popup_item_new_text(&popup_val_last, buffer, 3);
+ sprintf(buffer,"Row:%d", data->row);
+ popup_item_new_text(&popup_val_last, buffer, 4);
+ for (j = 0; j < poi->table_col->len; j++) {
+ col = poi->table_col->pdata[j];
+ #if 0
+ printf("start: %d type:%d\n", col->cur_value_start, col->col_type);
+ #endif
+ sprintf(buffer, "%s:", col->name);
+ v = buffer + strlen(buffer);
+ if (!strcasecmp(col->name,"X") || !strcasecmp(col->name,"Y"))
+ print_col(poi->h, col, v, 1);
+ else
+ print_col(poi->h, col, v, 0);
+ #if 0
+ printf("%s\n", buffer);
+ #endif
+ text=g_convert(buffer,-1,"utf-8","iso8859-1",NULL,NULL,NULL);
+ popup_item_new_text(&popup_val_last, buffer, j+10);
+ g_free(text);
+ }
+ }
+ popup_item_new_text(&popup_last, "POI", 20)->submenu = popup_val_last;
+ *popup=popup_last;
+}
+
+static void
+draw_poi(struct poi *p, struct container *co, struct point *pnt)
+{
+ struct poi_data data;
+ data.poi=p;
+ if (p->type == 0) {
+ data.page=p->h->cur_pg;
+ data.row=p->table->cur_row-1;
+ }
+ if (p->type == 1) {
+ data.row=p->pos;
+ }
+ display_add(&co->disp[display_poi], 5, 0, p->icon, 1, pnt, poi_info, &data, sizeof(data));
+}
+
+static void
+plugin_draw(struct container *co)
+{
+ struct coord c;
+ struct point pnt;
+ struct poi *p;
+ struct index_data idx[2];
+ int use_index=0;
+ int debug=1;
+
+ p = poi_list;
+
+ if (co->trans->scale > 1024)
+ return;
+ if (debug) {
+ printf("scale=%ld\n", co->trans->scale);
+ printf("rect 0x%lx,0%lx-0x%lx,0x%lx\n", co->trans->rect[0].x, co->trans->rect[0].y, co->trans->rect[1].x, co->trans->rect[1].y);
+ }
+ while (p) {
+ if (p->type == 0) {
+ if (use_index)
+ setup_idx_rect(co->trans->rect, idx, p->idx_size);
+ if (! use_index) {
+ printf("rewind %s %p\n", p->filename, p->table);
+ mdb_rewind_table(p->table);
+ while (mdb_fetch_row(p->table)) {
+ get_coord(p, &c);
+ if (transform(co->trans, &c, &pnt)) {
+ if (debug)
+ printf("coord 0x%lx,0x%lx pg %d row %d\n", c.x, c.y, p->h->cur_pg, p->table->cur_row);
+ draw_poi(p, co, &pnt);
+ }
+ }
+ } else {
+ memset(&p->chain, 0, sizeof(p->chain));
+ while (index_next(p, idx)) {
+ get_coord(p, &c);
+ if (transform(co->trans, &c, &pnt)) {
+ if (debug)
+ printf("coord 0x%lx,0x%lx pg %d row %d\n", c.x, c.y, p->h->cur_pg, p->table->cur_row);
+ draw_poi(p, co, &pnt);
+ }
+ }
+ }
+ }
+ if (p->type == 1) {
+ FILE *f;
+ char line[1024];
+ struct text_poi tpoi;
+ if(!(f=fopen(p->filename, "r"))){
+ printf("can't open poi file for drawing!\n");
+ exit(0);
+ }
+#if 0
+ printf("opened poi file %s for drawing!\n",p->filename);
+#endif
+ p->pos=ftell(f);
+ fgets(line, 1024, f);
+ while (!feof(f)) {
+ if (strlen(line)) {
+ line[strlen(line)-1]='\0';
+ }
+ if (parse_text_poi(line, &tpoi)) {
+ transform_mercator(&tpoi.lat,&tpoi.lng,&c);
+// printf("%ld %ld\n", c.x, c.y);
+ if (transform(co->trans, &c, &pnt)) {
+ draw_poi(p, co, &pnt);
+ }
+ }
+ p->pos=ftell(f);
+ fgets(line, 1024, f);
+ }
+ fclose(f);
+ }
+ p = p->next;
+ }
+
+}
+
+#endif
+
+static void
+map_destroy_poi_geodownload(struct map_priv *m)
+{
+ dbg(1,"enter\n");
+ g_free(m);
+}
+
+static void
+poi_geodownload_coord_rewind(void *priv_data)
+{
+ struct map_rect_priv *mr=priv_data;
+ mr->cidx=0;
+}
+
+
+static int
+poi_geodownload_coord_get(void *priv_data, struct coord *c, int count)
+{
+ struct map_rect_priv *mr=priv_data;
+ dbg(1,"enter\n");
+ if (mr->cidx || !count)
+ return 0;
+ c->x=mdb_pg_get_int32(mr->m->h, mr->m->cols[0]->cur_value_start);
+ c->y=mdb_pg_get_int32(mr->m->h, mr->m->cols[1]->cur_value_start);
+ dbg(1,"x=0x%x y=0x%x\n", c->x, c->y);
+ return 1;
+}
+
+static void
+poi_geodownload_attr_rewind(void *priv_data)
+{
+ struct map_rect_priv *mr=priv_data;
+ mr->attr_next=attr_label;
+}
+
+static int
+poi_geodownload_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+ struct map_rect_priv *mr=priv_data;
+ struct map_priv *m=mr->m;
+ MdbColumn *col;
+ char *v;
+ int j;
+
+ dbg(1,"enter\n");
+ attr->type=attr_type;
+ switch (attr_type) {
+ case attr_any:
+ while (mr->attr_next != attr_none) {
+ if (poi_geodownload_attr_get(mr, mr->attr_next, attr))
+ return 1;
+ }
+ return 0;
+ case attr_label:
+ mr->attr_next=attr_debug;
+ if (m->name_col == -1)
+ return 0;
+ col=m->cols[m->name_col];
+ if (col->cur_value_len)
+ attr->u.str=mdb_col_to_string (m->h, m->h->pg_buf, col->cur_value_start, col->col_type, col->cur_value_len);
+ else
+ attr->u.str="";
+ return 1;
+ case attr_debug:
+ mr->attr_next=attr_none;
+ v=mr->buffer;
+ *v='\0';
+ for (j = 0; j < mr->m->table_col->len; j++) {
+ col = mr->m->table_col->pdata[j];
+ printf("start: %d type:%d\n", col->cur_value_start, col->col_type);
+ sprintf(v, "%s:", col->name);
+ v += strlen(v);
+ if (!strcasecmp(col->name,"X") || !strcasecmp(col->name,"Y"))
+ print_col(mr->m->h, col, v, 1);
+ else
+ print_col(mr->m->h, col, v, 0);
+ v += strlen(v);
+ *v++='\n';
+ *v='\0';
+ }
+ attr->u.str=mr->buffer;
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static struct item_methods methods_poi_geodownload = {
+ poi_geodownload_coord_rewind,
+ poi_geodownload_coord_get,
+ poi_geodownload_attr_rewind,
+ poi_geodownload_attr_get,
+};
+
+
+static struct map_rect_priv *
+map_rect_new_poi_geodownload(struct map_priv *map, struct map_selection *sel)
+{
+ struct map_rect_priv *mr;
+
+ dbg(1,"enter\n");
+ mr=g_new0(struct map_rect_priv, 1);
+ mr->item.meth=&methods_poi_geodownload;
+ mr->item.id_hi=0;
+ mr->item.id_lo=0;
+ mr->item.priv_data=mr;
+ mr->item.type=map->type;
+ mr->m=map;
+ mdb_rewind_table(map->table);
+ return mr;
+}
+
+
+static void
+map_rect_destroy_poi_geodownload(struct map_rect_priv *mr)
+{
+ g_free(mr);
+}
+
+static struct item *
+map_rect_get_item_poi_geodownload(struct map_rect_priv *mr)
+{
+ dbg(1,"enter\n");
+ if (mdb_fetch_row(mr->m->table)) {
+ mr->item.id_hi=mr->m->table->cur_phys_pg;
+ mr->item.id_lo=mr->m->table->cur_row-1;
+ poi_geodownload_attr_rewind(mr);
+ return &mr->item;
+ }
+ return NULL;
+}
+
+static struct item *
+map_rect_get_item_byid_poi_geodownload(struct map_rect_priv *mr, int id_hi, int id_lo)
+{
+ char *v, buffer[4096];
+ int j;
+ MdbColumn *col;
+
+ dbg(1,"enter\n");
+ load_row(mr->m, id_hi, id_lo);
+ for (j = 0; j < mr->m->table_col->len; j++) {
+ col = mr->m->table_col->pdata[j];
+ printf("start: %d type:%d\n", col->cur_value_start, col->col_type);
+ sprintf(buffer, "%s:", col->name);
+ v = buffer + strlen(buffer);
+ if (!strcasecmp(col->name,"X") || !strcasecmp(col->name,"Y"))
+ print_col(mr->m->h, col, v, 1);
+ else
+ print_col(mr->m->h, col, v, 0);
+ printf("%s\n", buffer);
+ }
+ dbg(1,"ret=%p\n", &mr->item);
+ poi_geodownload_attr_rewind(mr);
+ return &mr->item;
+}
+
+
+static struct map_methods map_methods_poi_geodownload = {
+ projection_mg,
+ "iso8859-1",
+ map_destroy_poi_geodownload,
+ map_rect_new_poi_geodownload,
+ map_rect_destroy_poi_geodownload,
+ map_rect_get_item_poi_geodownload,
+ map_rect_get_item_byid_poi_geodownload,
+};
+
+static struct map_priv *
+map_new_poi_geodownload(struct map_methods *meth, struct attr **attrs)
+{
+ struct map_priv *m;
+ MdbCatalogEntry *entry;
+ GPtrArray *catalog;
+ int i;
+ struct attr *attr;
+ struct attr *data=attr_search(attrs, NULL, attr_data);
+ char *filename;
+ if (! data)
+ return NULL;
+ filename=data->u.str;
+ dbg(1,"filename %s\n",filename);
+ *meth=map_methods_poi_geodownload;
+
+ m=g_new(struct map_priv, 1);
+ m->filename=g_strdup(filename);
+ m->h = mdb_open(m->filename, MDB_NOFLAGS);
+ m->type=type_none;
+ dbg(1,"attr_search\n");
+ attr=attr_search(attrs, NULL, attr_item_type);
+ dbg(1,"attr_search result %p\n", attr);
+ if (attr)
+ m->type=attr->u.item_type;
+
+
+ catalog = mdb_read_catalog(m->h, MDB_TABLE);
+ for (i = 0; i < catalog->len; i++) {
+ entry = catalog->pdata[i];
+ dbg(1,"object name '%s'\n", entry->object_name);
+ if (!strcasecmp(entry->object_name, "_INDEXDATA")) {
+ if (load_poi_table(m, entry)) {
+ printf("%s invalid\n", filename);
+ g_free(m);
+ m=NULL;
+ }
+ }
+ }
+ g_ptr_array_free(catalog, 1);
+ return m;
+}
+
+void
+plugin_init(void)
+{
+ dbg(1,"plugin_init\n");
+ plugin_register_map_type("poi_geodownload", map_new_poi_geodownload);
+ mdb_init();
+}
+
diff --git a/navit/data/textfile/Makefile.am b/navit/data/textfile/Makefile.am
new file mode 100644
index 000000000..afbc47d29
--- /dev/null
+++ b/navit/data/textfile/Makefile.am
@@ -0,0 +1,4 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=data_textfile
+moduledata_LTLIBRARIES = libdata_textfile.la
+libdata_textfile_la_SOURCES = textfile.c textfile.h
diff --git a/navit/data/textfile/textfile.c b/navit/data/textfile/textfile.c
new file mode 100644
index 000000000..da0ead4ad
--- /dev/null
+++ b/navit/data/textfile/textfile.c
@@ -0,0 +1,376 @@
+#include <glib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "config.h"
+#include "debug.h"
+#include "plugin.h"
+#include "projection.h"
+#include "map.h"
+#include "maptype.h"
+#include "item.h"
+#include "attr.h"
+#include "transform.h"
+#include "file.h"
+
+#include "textfile.h"
+
+static int map_id;
+
+static int
+get_tag(char *line, char *name, int *pos, char *ret, char *name_ret)
+{
+ int len=0,quoted;
+ char *p,*e,*n;
+
+ dbg(1,"get_tag %s from %s\n", name, line);
+ if (name)
+ len=strlen(name);
+ if (pos)
+ p=line+*pos;
+ else
+ p=line;
+ for(;;) {
+ while (*p == ' ') {
+ p++;
+ }
+ if (! *p)
+ return 0;
+ n=p;
+ e=index(p,'=');
+ if (! e)
+ return 0;
+ p=e+1;
+ quoted=0;
+ while (*p) {
+ if (*p == ' ' && !quoted)
+ break;
+ if (*p == '"')
+ quoted=1-quoted;
+ p++;
+ }
+ if (name == NULL || (e-n == len && !strncmp(n, name, len))) {
+ if (name_ret) {
+ len=e-n;
+ strncpy(name_ret, n, len);
+ name_ret[len]='\0';
+ }
+ e++;
+ len=p-e;
+ if (e[0] == '"') {
+ e++;
+ len-=2;
+ }
+ strncpy(ret, e, len);
+ ret[len]='\0';
+ if (pos)
+ *pos=p-line;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void
+get_line(struct map_rect_priv *mr)
+{
+ if(mr->f) {
+ mr->pos=ftell(mr->f);
+ fgets(mr->line, SIZE, mr->f);
+ if (strlen(mr->line) >= SIZE-1)
+ printf("line too long\n");
+ }
+}
+
+static void
+map_destroy_textfile(struct map_priv *m)
+{
+ dbg(1,"map_destroy_textfile\n");
+ g_free(m);
+}
+
+static void
+textfile_coord_rewind(void *priv_data)
+{
+}
+
+static int
+parse_line(struct map_rect_priv *mr, int attr)
+{
+ int pos;
+
+ pos=coord_parse(mr->line, projection_mg, &mr->c);
+ if (pos < strlen(mr->line) && attr) {
+ strcpy(mr->attrs, mr->line+pos);
+ }
+ return pos;
+}
+
+static int
+textfile_coord_get(void *priv_data, struct coord *c, int count)
+{
+ struct map_rect_priv *mr=priv_data;
+ int ret=0;
+ dbg(1,"textfile_coord_get %d\n",count);
+ while (count--) {
+ if (mr->f && !feof(mr->f) && (!mr->item.id_hi || !mr->eoc) && parse_line(mr, mr->item.id_hi)) {
+ *c=mr->c;
+ dbg(1,"c=0x%x,0x%x\n", c->x, c->y);
+ c++;
+ ret++;
+ get_line(mr);
+ if (mr->item.id_hi)
+ mr->eoc=1;
+ } else {
+ mr->more=0;
+ break;
+ }
+ }
+ return ret;
+}
+
+static void
+textfile_attr_rewind(void *priv_data)
+{
+}
+
+static void
+textfile_encode_attr(char *attr_val, enum attr_type attr_type, struct attr *attr)
+{
+ if (attr_type >= attr_type_int_begin && attr_type <= attr_type_int_end)
+ attr->u.num=atoi(attr_val);
+ else
+ attr->u.str=attr_val;
+}
+
+static int
+textfile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+ struct map_rect_priv *mr=priv_data;
+ char *str=NULL;
+ dbg(1,"textfile_attr_get mr=%p attrs='%s' ", mr, mr->attrs);
+ if (attr_type != mr->attr_last) {
+ dbg(1,"reset attr_pos\n");
+ mr->attr_pos=0;
+ mr->attr_last=attr_type;
+ }
+ if (attr_type == attr_any) {
+ dbg(1,"attr_any");
+ if (get_tag(mr->attrs,NULL,&mr->attr_pos,mr->attr, mr->attr_name)) {
+ attr_type=attr_from_name(mr->attr_name);
+ dbg(1,"found attr '%s' 0x%x\n", mr->attr_name, attr_type);
+ attr->type=attr_type;
+ textfile_encode_attr(mr->attr, attr_type, attr);
+ return 1;
+ }
+ } else {
+ str=attr_to_name(attr_type);
+ dbg(1,"attr='%s' ",str);
+ if (get_tag(mr->attrs,str,&mr->attr_pos,mr->attr, NULL)) {
+ textfile_encode_attr(mr->attr, attr_type, attr);
+ dbg(1,"found\n");
+ return 1;
+ }
+ }
+ dbg(1,"not found\n");
+ return 0;
+}
+
+static struct item_methods methods_textfile = {
+ textfile_coord_rewind,
+ textfile_coord_get,
+ textfile_attr_rewind,
+ textfile_attr_get,
+};
+
+static struct map_rect_priv *
+map_rect_new_textfile(struct map_priv *map, struct map_selection *sel)
+{
+ struct map_rect_priv *mr;
+
+ dbg(1,"map_rect_new_textfile\n");
+ mr=g_new0(struct map_rect_priv, 1);
+ mr->m=map;
+ mr->sel=sel;
+ mr->item.id_hi=0;
+ mr->item.id_lo=0;
+ mr->item.meth=&methods_textfile;
+ mr->item.priv_data=mr;
+ if (map->is_pipe) {
+ char *oargs,*args=g_strdup(map->filename),*sep=" ";
+ enum layer_type lay;
+ g_free(mr->args);
+ while (sel) {
+ oargs=args;
+ args=g_strdup_printf("%s 0x%x 0x%x 0x%x 0x%x", oargs, sel->u.c_rect.lu.x, sel->u.c_rect.lu.y, sel->u.c_rect.rl.x, sel->u.c_rect.rl.y);
+ g_free(oargs);
+ for (lay=layer_town ; lay < layer_end ; lay++) {
+ oargs=args;
+ args=g_strdup_printf("%s%s%d", oargs, sep, sel->order[lay]);
+ g_free(oargs);
+ sep=",";
+ }
+ sel=sel->next;
+ }
+ dbg(1,"popen args %s\n", args);
+ mr->args=args;
+ mr->f=popen(mr->args, "r");
+ } else {
+ mr->f=fopen(map->filename, "r");
+ }
+ if(!mr->f) {
+ printf("map_rect_new_textfile unable to open textfile %s\n",map->filename);
+ }
+ get_line(mr);
+ return mr;
+}
+
+
+static void
+map_rect_destroy_textfile(struct map_rect_priv *mr)
+{
+ if (mr->f) {
+ if (mr->m->is_pipe)
+ pclose(mr->f);
+ else
+ fclose(mr->f);
+ }
+ g_free(mr);
+}
+
+static struct item *
+map_rect_get_item_textfile(struct map_rect_priv *mr)
+{
+ char *p,type[SIZE];
+ dbg(1,"map_rect_get_item_textfile id_hi=%d line=%s", mr->item.id_hi, mr->line);
+ if (!mr->f) {
+ return NULL;
+ }
+ while (mr->more) {
+ struct coord c;
+ textfile_coord_get(mr, &c, 1);
+ }
+ for(;;) {
+ if (feof(mr->f)) {
+ dbg(1,"map_rect_get_item_textfile: eof\n");
+ if (mr->item.id_hi) {
+ return NULL;
+ }
+ mr->item.id_hi++;
+ if (mr->m->is_pipe) {
+ pclose(mr->f);
+ mr->f=popen(mr->args, "r");
+ } else
+ fseek(mr->f, 0, SEEK_SET);
+ get_line(mr);
+ }
+ if ((p=index(mr->line,'\n')))
+ *p='\0';
+ if (mr->item.id_hi) {
+ mr->attrs[0]='\0';
+ if (!parse_line(mr, 1)) {
+ get_line(mr);
+ continue;
+ }
+ dbg(1,"map_rect_get_item_textfile: point found\n");
+ mr->eoc=0;
+ mr->item.id_lo=mr->pos;
+ } else {
+ if (parse_line(mr, 1)) {
+ get_line(mr);
+ continue;
+ }
+ dbg(1,"map_rect_get_item_textfile: line found\n");
+ if (! mr->line[0]) {
+ get_line(mr);
+ continue;
+ }
+ mr->item.id_lo=mr->pos;
+ strcpy(mr->attrs, mr->line);
+ get_line(mr);
+ dbg(1,"mr=%p attrs=%s\n", mr, mr->attrs);
+ }
+ dbg(1,"get_attrs %s\n", mr->attrs);
+ if (get_tag(mr->attrs,"type",NULL,type,NULL)) {
+ dbg(1,"type='%s'\n", type);
+ mr->item.type=item_from_name(type);
+ if (mr->item.type == type_none)
+ printf("Warning: type '%s' unknown\n", type);
+ } else {
+ get_line(mr);
+ continue;
+ }
+ mr->attr_last=attr_none;
+ mr->more=1;
+ dbg(1,"return attr='%s'\n", mr->attrs);
+ return &mr->item;
+ }
+}
+
+static struct item *
+map_rect_get_item_byid_textfile(struct map_rect_priv *mr, int id_hi, int id_lo)
+{
+ if (mr->m->is_pipe) {
+ pclose(mr->f);
+ mr->f=popen(mr->args, "r");
+ } else
+ fseek(mr->f, id_lo, SEEK_SET);
+ get_line(mr);
+ mr->item.id_hi=id_hi;
+ return map_rect_get_item_textfile(mr);
+}
+
+static struct map_methods map_methods_textfile = {
+ projection_mg,
+ "iso8859-1",
+ map_destroy_textfile,
+ map_rect_new_textfile,
+ map_rect_destroy_textfile,
+ map_rect_get_item_textfile,
+ map_rect_get_item_byid_textfile,
+};
+
+static struct map_priv *
+map_new_textfile(struct map_methods *meth, struct attr **attrs)
+{
+ struct map_priv *m;
+ struct attr *data=attr_search(attrs, NULL, attr_data);
+ struct attr *charset=attr_search(attrs, NULL, attr_charset);
+ struct file_wordexp *wexp;
+ int len,is_pipe=0;
+ char *wdata;
+ char **wexp_data;
+ if (! data)
+ return NULL;
+ dbg(0,"map_new_textfile %s\n", data->u.str);
+ wdata=g_strdup_printf(data->u.str);
+ len=strlen(wdata);
+ if (len && wdata[len-1] == '|') {
+ wdata[len-1]='\0';
+ is_pipe=1;
+ }
+ wexp=file_wordexp_new(wdata);
+ wexp_data=file_wordexp_get_array(wexp);
+ *meth=map_methods_textfile;
+
+ m=g_new0(struct map_priv, 1);
+ m->id=++map_id;
+ m->filename=g_strdup(wexp_data[0]);
+ m->is_pipe=is_pipe;
+ dbg(1,"map_new_textfile %s %s\n", m->filename, wdata);
+ if (charset) {
+ m->charset=g_strdup(charset->u.str);
+ meth->charset=m->charset;
+ }
+ file_wordexp_destroy(wexp);
+ return m;
+}
+
+void
+plugin_init(void)
+{
+ dbg(1,"textfile: plugin_init\n");
+ plugin_register_map_type("textfile", map_new_textfile);
+}
+
diff --git a/navit/data/textfile/textfile.h b/navit/data/textfile/textfile.h
new file mode 100644
index 000000000..3167e8bf3
--- /dev/null
+++ b/navit/data/textfile/textfile.h
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include "attr.h"
+#include "coord.h"
+struct map_priv {
+ int id;
+ char *filename;
+ char *charset;
+ int is_pipe;
+};
+
+#define SIZE 512
+
+struct map_rect_priv {
+ struct map_selection *sel;
+
+ FILE *f;
+ long pos;
+ char line[SIZE];
+ int attr_pos;
+ enum attr_type attr_last;
+ char attrs[SIZE];
+ char attr[SIZE];
+ char attr_name[SIZE];
+ struct coord c;
+ int eoc;
+ int more;
+ struct map_priv *m;
+ struct item item;
+ char *args;
+};
+
diff --git a/navit/data_window.c b/navit/data_window.c
new file mode 100644
index 000000000..fa67710f1
--- /dev/null
+++ b/navit/data_window.c
@@ -0,0 +1,22 @@
+#include <glib.h>
+#include "data_window.h"
+
+void
+datawindow_mode(struct datawindow *win, int start)
+{
+ win->meth.mode(win->priv, start);
+}
+
+void
+datawindow_add(struct datawindow *win, struct param_list *param, int count)
+{
+ win->meth.add(win->priv, param, count);
+}
+
+void
+datawindow_destroy(struct datawindow *win)
+{
+ win->meth.destroy(win->priv);
+ g_free(win);
+}
+
diff --git a/navit/data_window.h b/navit/data_window.h
new file mode 100644
index 000000000..103697dbe
--- /dev/null
+++ b/navit/data_window.h
@@ -0,0 +1,25 @@
+#ifndef NAVIT_DATA_WINDOW_H
+#define NAVIT_DATA_WINDOW_H
+
+struct datawindow;
+struct param_list;
+struct datawindow_priv;
+
+struct datawindow_methods {
+ void (*destroy)(struct datawindow_priv *win);
+ void (*add)(struct datawindow_priv *win, struct param_list *param, int count);
+ void (*mode)(struct datawindow_priv *win, int start);
+};
+
+struct datawindow {
+ struct datawindow_priv *priv;
+ struct datawindow_methods meth;
+};
+
+
+void datawindow_destroy(struct datawindow *win);
+void datawindow_add(struct datawindow *win, struct param_list *param, int count);
+void datawindow_mode(struct datawindow *win, int start);
+
+#endif
+
diff --git a/navit/data_window_int.h b/navit/data_window_int.h
new file mode 100644
index 000000000..f455a3a35
--- /dev/null
+++ b/navit/data_window_int.h
@@ -0,0 +1,12 @@
+#ifndef NAVIT_DATA_WINDOW_INT_H
+#define NAVIT_DATA_WINDOW_INT_H
+
+struct data_window {
+ GtkWidget *window;
+ GtkWidget *scrolled_window;
+ GtkWidget *treeview;
+ void(*callback)(struct data_window *, char **cols);
+};
+
+#endif
+
diff --git a/navit/debug.c b/navit/debug.c
new file mode 100644
index 000000000..401c4a516
--- /dev/null
+++ b/navit/debug.c
@@ -0,0 +1,87 @@
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <glib.h>
+#include "file.h"
+#include "debug.h"
+
+
+int debug_level=0,segv_level=0;
+static GHashTable *debug_hash;
+static char *gdb_program;
+
+static void sigsegv(int sig)
+{
+ char buffer[256];
+ if (segv_level > 1)
+ sprintf(buffer, "gdb -ex bt %s %d", gdb_program, getpid());
+ else
+ sprintf(buffer, "gdb -ex bt -ex detach -ex quit %s %d", gdb_program, getpid());
+ system(buffer);
+ exit(1);
+}
+
+void
+debug_init(const char *program_name)
+{
+ gdb_program=program_name;
+ signal(SIGSEGV, sigsegv);
+ debug_hash=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+}
+
+
+static void
+debug_update_level(gpointer key, gpointer value, gpointer user_data)
+{
+ if (debug_level < (int) value)
+ debug_level=(int) value;
+}
+
+void
+debug_level_set(const char *name, int level)
+{
+ debug_level=0;
+ if (strcmp(name,"segv")) {
+ g_hash_table_insert(debug_hash, g_strdup(name), (gpointer) level);
+ g_hash_table_foreach(debug_hash, debug_update_level, NULL);
+ } else {
+ segv_level=level;
+ if (segv_level)
+ signal(SIGSEGV, sigsegv);
+ else
+ signal(SIGSEGV, NULL);
+ }
+}
+
+int
+debug_level_get(const char *name)
+{
+ return (int)(g_hash_table_lookup(debug_hash, name));
+}
+
+void
+debug_vprintf(int level, const char *module, const int mlen, const char *function, const int flen, int prefix, const char *fmt, va_list ap)
+{
+ char buffer[mlen+flen+3];
+
+ sprintf(buffer, "%s:%s", module, function);
+ if (debug_level_get(module) >= level || debug_level_get(buffer) >= level) {
+ if (prefix)
+ fprintf(stderr,"%s:",buffer);
+ vfprintf(stderr,fmt, ap);
+ }
+}
+
+void
+debug_printf(int level, const char *module, const int mlen,const char *function, const int flen, int prefix, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ debug_vprintf(level, module, mlen, function, flen, prefix, fmt, ap);
+ va_end(ap);
+}
+
+
diff --git a/navit/debug.h b/navit/debug.h
new file mode 100644
index 000000000..7e8971291
--- /dev/null
+++ b/navit/debug.h
@@ -0,0 +1,28 @@
+#ifndef NAVIT_DEBUG_H
+#define NAVIT_DEBUG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdarg.h>
+extern int debug_level;
+#define dbg_str2(x) #x
+#define dbg_str1(x) dbg_str2(x)
+#define dbg_module dbg_str1(MODULE)
+#define dbg(level,fmt...) ({ if (debug_level >= level) debug_printf(level,dbg_module,strlen(dbg_module),__PRETTY_FUNCTION__, strlen(__PRETTY_FUNCTION__),1,fmt); })
+
+/* prototypes */
+void debug_init(const char *program_name);
+void debug_level_set(const char *name, int level);
+int debug_level_get(const char *name);
+void debug_vprintf(int level, const char *module, const int mlen, const char *function, const int flen, int prefix, const char *fmt, va_list ap);
+void debug_printf(int level, const char *module, const int mlen, const char *function, const int flen, int prefix, const char *fmt, ...);
+/* end of prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/navit/destination.h b/navit/destination.h
new file mode 100644
index 000000000..b019fc066
--- /dev/null
+++ b/navit/destination.h
@@ -0,0 +1,10 @@
+#ifndef NAVIT_DESTINATION_H
+#define NAVIT_DESTINATION_H
+
+/* prototypes */
+struct navit;
+int destination_address(struct navit *nav);
+/* end of prototypes */
+
+#endif
+
diff --git a/navit/draw_info.h b/navit/draw_info.h
new file mode 100644
index 000000000..863b00175
--- /dev/null
+++ b/navit/draw_info.h
@@ -0,0 +1,11 @@
+#ifndef NAVIT_DRAW_INFO_H
+#define NAVIT_DRAW_INFO_H
+
+struct draw_info {
+ struct container *co;
+ int display;
+ int limit;
+};
+
+#endif
+
diff --git a/navit/endianess.h b/navit/endianess.h
new file mode 100644
index 000000000..5cd58b8d1
--- /dev/null
+++ b/navit/endianess.h
@@ -0,0 +1,34 @@
+#ifndef __ENDIANESS_HANDLER__
+
+#include <endian.h>
+
+/* Get machine dependent optimized versions of byte swapping functions. */
+#include <byteswap.h>
+
+#ifdef __OPTIMIZE__
+/* We can optimize calls to the conversion functions. Either nothing has
+ to be done or we are using directly the byte-swapping functions which
+ often can be inlined. */
+
+ #if __BYTE_ORDER == __BIG_ENDIAN
+ #define le16_to_cpu(x) __bswap_16 (x)
+ #define le32_to_cpu(x) __bswap_32 (x)
+ #define le64_to_cpu(x) __bswap_64 (x)
+ #define cpu_to_le16(x) __bswap_16 (x)
+ #define cpu_to_le32(x) __bswap_32 (x)
+ #define cpu_to_le64(x) __bswap_64 (x)
+ #else
+ #if __BYTE_ORDER == __LITTLE_ENDIAN
+ #define le16_to_cpu(x) (x)
+ #define le32_to_cpu(x) (x)
+ #define cpu_to_le16(x) (x)
+ #define cpu_to_le16(x) (x)
+ #else
+ #error "Unknown endianess"
+ #endif
+ #endif
+#endif
+
+#define __ENDIANESS_HANDLER__
+#endif
+
diff --git a/navit/event.c b/navit/event.c
new file mode 100644
index 000000000..8fe594905
--- /dev/null
+++ b/navit/event.c
@@ -0,0 +1,19 @@
+#include <glib.h>
+#include "event.h"
+
+static GMainLoop *loop;
+
+void event_main_loop_run(void)
+{
+ loop = g_main_loop_new (NULL, TRUE);
+ if (g_main_loop_is_running (loop))
+ {
+ g_main_loop_run (loop);
+ }
+}
+
+void event_main_loop_quit(void)
+{
+ if (loop)
+ g_main_loop_quit(loop);
+}
diff --git a/navit/event.h b/navit/event.h
new file mode 100644
index 000000000..23c07ebff
--- /dev/null
+++ b/navit/event.h
@@ -0,0 +1,2 @@
+void event_main_loop_run(void);
+void event_main_loop_quit(void);
diff --git a/navit/fib-1.1/Makefile.am b/navit/fib-1.1/Makefile.am
new file mode 100644
index 000000000..7c7b2a130
--- /dev/null
+++ b/navit/fib-1.1/Makefile.am
@@ -0,0 +1,3 @@
+noinst_LTLIBRARIES = libfib.la
+libfib_la_SOURCES = fib.c fib.h fibpriv.h
+EXTRA_DIST=README configure.in fh_extractmin.3 fh_makeheap.3 fh_makekeyheap.3 fibtest.c fibtest2.c tt.c use.c
diff --git a/navit/fib-1.1/README b/navit/fib-1.1/README
new file mode 100644
index 000000000..eabcd5f86
--- /dev/null
+++ b/navit/fib-1.1/README
@@ -0,0 +1,26 @@
+Version 1.1 now supports increasing the key using the fh_replace*
+functions. Previously it would simply return NULL when you tried to
+increase the key. It also improves performance slightly by only calling
+checkcons when we are about to use it, at extract, instead of calling it
+on every insert.
+
+I have now fixed fh_union and it properly updates the minimum.
+
+Thanks to Ryan Earl for pointing out that in fh_consolidate, it is VERY
+time consuming to constantly malloc/free an array of pointers. The array
+is small enough that simply reallocating when more pointers are needed
+is ok.
+
+Thanks to Thomas Eschbach and Wolfgang Guenther who have pointed out bugs
+with my code. Wolfgang Guenther provided a fix which put in on the correct
+track for where the bug was. They have also provided a few test programs
+that exhibited other bugs which I have now integrated into my source so
+that you can easily regress test the library.
+
+I have reciently completed a review of the code. I have made a number
+of improvements with a few minor interface changes. There is another
+improvement to the rh_replace* family of functions to help eliminate
+redundant code.
+
+I'm still planning on writing a type safe memory allocator for use with
+the code instead of using malloc to hopefully improve performance slightly.
diff --git a/navit/fib-1.1/configure b/navit/fib-1.1/configure
new file mode 100755
index 000000000..62eaa3d01
--- /dev/null
+++ b/navit/fib-1.1/configure
@@ -0,0 +1,1045 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=fib.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:529: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 544 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:550: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 561 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:567: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 578 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:584: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:609: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 614 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:622: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 639 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 657 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 678 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:689: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+for ac_hdr in limits.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:716: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 721 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:726: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:754: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 761 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:768: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@CPP@%$CPP%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/navit/fib-1.1/configure.in b/navit/fib-1.1/configure.in
new file mode 100644
index 000000000..827015270
--- /dev/null
+++ b/navit/fib-1.1/configure.in
@@ -0,0 +1,17 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(fib.c)
+
+dnl Checks for programs.
+
+dnl Checks for libraries.
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS(limits.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_INLINE
+
+dnl Checks for library functions.
+
+AC_OUTPUT(Makefile)
diff --git a/navit/fib-1.1/fh_extractmin.3 b/navit/fib-1.1/fh_extractmin.3
new file mode 100644
index 000000000..e1492b400
--- /dev/null
+++ b/navit/fib-1.1/fh_extractmin.3
@@ -0,0 +1,97 @@
+.TH FH_EXTRACTMIN 3 "29 Mar 2000" "libfib"
+.SH NAME
+fh_extractmin \- extract minimum element from a Fibonacci Heap
+.SH SYNOPSIS
+#include <fib.h>
+.PP
+void *
+.PD 0
+.HP 8
+.BR fh_extractmin "(struct fibheap *heap)"
+.PD
+.PP
+void *
+.PD 0
+.HP 8
+.BR fh_min "(struct fibheap *heap)"
+.PD
+.PP
+void *
+.PD 0
+.HP 8
+.BR fh_replacedata "(struct fibheap *heap, struct fibheap_el *elem, void *data)"
+.PD
+.PP
+void *
+.PD 0
+.HP 8
+.BR fh_delete "(struct fibheap *heap, struct fibheap_el *elem)"
+.PD
+.PP
+void
+.PD 0
+.HP 8
+.BR fh_deleteheap "(struct fibheap *heap)"
+.PD
+.PP
+struct fibheap *
+.PD 0
+.HP 8
+.BR fh_union "(struct fibheap *heapa, struct fibheap *heapb)"
+.PD
+.SH DESCRIPTION
+These functions are shared between both key heaps and normal heaps.
+.PP
+Once a
+.B elem
+pointer has been passed to
+.BR fh_delete (3)
+that
+.B elem
+pointer may be reused to store another datum.
+You should make sure that you destroy any copies of the pointer.
+.SH RETURN VALUES
+The
+.B fh_extractmin
+function returns the value of
+.B data
+that is the minimum element and removes it from the heap.
+.PP
+The
+.B fh_min
+function returns the current minimum element but does
+.I not
+remove it from the heap.
+.PP
+The
+.B fh_replacedata
+replaces the data in
+.B elem
+and returns the old data.
+.PP
+The
+.B fh_delete
+function removes
+.B elem
+from the heap, and returns the
+.B data
+that was stored in the element.
+.PP
+The
+.B fh_deleteheap
+complete destroys the heap. It does not free any user supplied
+.B data
+elements stored in the heap.
+.PP
+The
+.B fh_union
+function returns the union of the two heaps
+.B heapa
+and
+.BR heapb .
+.SH SEE ALSO
+.BR fh_makeheap (3),
+.BR fh_makekeyheap (3)
+.SH AUTHORS
+This library and man page was writen by John-Mark Gurney <gurney_j@efn.org>.
+.SH BUGS
diff --git a/navit/fib-1.1/fh_makeheap.3 b/navit/fib-1.1/fh_makeheap.3
new file mode 100644
index 000000000..bd867cd09
--- /dev/null
+++ b/navit/fib-1.1/fh_makeheap.3
@@ -0,0 +1,17 @@
+.TH FH_MAKEHEAP 3 "29 Mar 2000" "libfib"
+.SH NAME
+fh_makeheap \- make a Fibonacci Heap
+.SH SYNOPSIS
+.nf
+#include <fib.h>
+.PP
+struct fibheap *
+.BR fh_makeheap (void)
+.fi
+.SH DESCRIPTION
+.SH RETURN VALUES
+.SH FILES
+.SH SEE ALSO
+.SH AUTHORS
+This library and man page was writen by John-Mark Gurney <gurney_j@efn.org>.
+.SH BUGS
diff --git a/navit/fib-1.1/fh_makekeyheap.3 b/navit/fib-1.1/fh_makekeyheap.3
new file mode 100644
index 000000000..f55d43072
--- /dev/null
+++ b/navit/fib-1.1/fh_makekeyheap.3
@@ -0,0 +1,84 @@
+.TH FH_MAKEKEYHEAP 3 "29 Mar 2000" "libfib"
+.SH NAME
+fh_makekeyheap \- make a Fibonacci key Heap
+.SH SYNOPSIS
+#include <fib.h>
+.PP
+struct fibheap *
+.PD 0
+.HP 8
+.BR fh_makekeyheap (void)
+.PD
+.PP
+struct fibheap_el *
+.PD 0
+.HP 8
+.BR fh_insertkey "(struct fibheap *heap, int key, void *data)"
+.PD
+.PP
+int
+.PD 0
+.HP 8
+.BR fh_minkey "(struct fibheap *heap)"
+.PD
+.PP
+void *
+.PD 0
+.HP 8
+.BR fh_replacekey "(struct fibheap *heap, struct fibheap_el *elem, int key)"
+.PD
+.PP
+void *
+.PD 0
+.HP 8
+.BR fh_replacekeydata "(struct fibheap *heap, struct fibheap_el *elem, int key, void *data)"
+.PD
+.SH DESCRIPTION
+The
+.B fh_makekeyheap
+function makes a Fibonacci heap which does ordering based on an
+integer key that is given in addition to the data.
+This menthod is useful so that you can eliminate the need to call
+a comparision function to order the data in the heap.
+.PP
+The pointer to the structure
+.B fibheap
+returned by
+.B fh_makekeyheap
+is an opaque structure. The the pointer can only be passed to other
+functions in the
+.B libfib
+library.
+.PP
+The
+.B fh_insertkey
+function inserts the
+.B data
+element into the heap with a value of
+.BR key .
+The pointer returned can be used in calls to functions like
+.BR fh_delete (3)
+to delete the key from the heap before it gets extracted via
+.BR fh_extractmin (3).
+.SH RETURN VALUES
+The
+.B fh_makekeyheap
+function returns a pointer to a heap structure used to insert and extract
+data elements.
+.PP
+The
+.B fh_insertkey
+functions returns a pointer to a heap element structure which can be used
+to manimulate that data element in the heap.
+.PP
+The
+.B fh_minkey
+function returns the integer key of the data at the top of the heap. If you would like to view the data, see
+.BR fh_min (3).
+.SH SEE ALSO
+.BR fh_extractmin (3)
+.SH AUTHORS
+This library and man page was writen by John-Mark Gurney <gurney_j@efn.org>.
+.SH BUGS
+A key heap does not provide a way for handling key collitions and deffering
+decission to a user provided function to resolve colissions.
diff --git a/navit/fib-1.1/fib.c b/navit/fib-1.1/fib.c
new file mode 100644
index 000000000..276b6bd37
--- /dev/null
+++ b/navit/fib-1.1/fib.c
@@ -0,0 +1,699 @@
+/*-
+ * Copyright 1997-2003 John-Mark Gurney.
+ * 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 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 AUTHOR 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.
+ *
+ * $Id: fib.c,v 1.2 2007-07-04 22:44:39 martin-s Exp $
+ *
+ */
+
+#include <fib.h>
+#include <fibpriv.h>
+
+#include <limits.h>
+#include <stdlib.h>
+
+#define swap(type, a, b) \
+ do { \
+ type c; \
+ c = a; \
+ a = b; \
+ b = c; \
+ } while (0) \
+
+#define INT_BITS (sizeof(int) * 8)
+static inline int
+ceillog2(unsigned int a)
+{
+ int oa;
+ int i;
+ int b;
+
+ oa = a;
+ b = INT_BITS / 2;
+ i = 0;
+ while (b) {
+ i = (i << 1);
+ if (a >= (1 << b)) {
+ a /= (1 << b);
+ i = i | 1;
+ } else
+ a &= (1 << b) - 1;
+ b /= 2;
+ }
+ if ((1 << i) == oa)
+ return i;
+ else
+ return i + 1;
+}
+
+/*
+ * Private Heap Functions
+ */
+static void
+fh_deleteel(struct fibheap *h, struct fibheap_el *x)
+{
+ void *data;
+ int key;
+
+ data = x->fhe_data;
+ key = x->fhe_key;
+
+ if (!h->fh_keys)
+ fh_replacedata(h, x, h->fh_neginf);
+ else
+ fh_replacekey(h, x, INT_MIN);
+ if (fh_extractminel(h) != x) {
+ /*
+ * XXX - This should never happen as fh_replace should set it
+ * to min.
+ */
+ abort();
+ }
+
+ x->fhe_data = data;
+ x->fhe_key = key;
+}
+
+static void
+fh_initheap(struct fibheap *new)
+{
+ new->fh_cmp_fnct = NULL;
+ new->fh_neginf = NULL;
+ new->fh_n = 0;
+ new->fh_Dl = -1;
+ new->fh_cons = NULL;
+ new->fh_min = NULL;
+ new->fh_root = NULL;
+ new->fh_keys = 0;
+#ifdef FH_STATS
+ new->fh_maxn = 0;
+ new->fh_ninserts = 0;
+ new->fh_nextracts = 0;
+#endif
+}
+
+static void
+fh_destroyheap(struct fibheap *h)
+{
+ h->fh_cmp_fnct = NULL;
+ h->fh_neginf = NULL;
+ if (h->fh_cons != NULL)
+ free(h->fh_cons);
+ h->fh_cons = NULL;
+ free(h);
+}
+
+/*
+ * Public Heap Functions
+ */
+struct fibheap *
+fh_makekeyheap()
+{
+ struct fibheap *n;
+
+ if ((n = malloc(sizeof *n)) == NULL)
+ return NULL;
+
+ fh_initheap(n);
+ n->fh_keys = 1;
+
+ return n;
+}
+
+struct fibheap *
+fh_makeheap()
+{
+ struct fibheap *n;
+
+ if ((n = malloc(sizeof *n)) == NULL)
+ return NULL;
+
+ fh_initheap(n);
+
+ return n;
+}
+
+voidcmp
+fh_setcmp(struct fibheap *h, voidcmp fnct)
+{
+ voidcmp oldfnct;
+
+ oldfnct = h->fh_cmp_fnct;
+ h->fh_cmp_fnct = fnct;
+
+ return oldfnct;
+}
+
+void *
+fh_setneginf(struct fibheap *h, void *data)
+{
+ void *old;
+
+ old = h->fh_neginf;
+ h->fh_neginf = data;
+
+ return old;
+}
+
+struct fibheap *
+fh_union(struct fibheap *ha, struct fibheap *hb)
+{
+ struct fibheap_el *x;
+
+ if (ha->fh_root == NULL || hb->fh_root == NULL) {
+ /* either one or both are empty */
+ if (ha->fh_root == NULL) {
+ fh_destroyheap(ha);
+ return hb;
+ } else {
+ fh_destroyheap(hb);
+ return ha;
+ }
+ }
+ ha->fh_root->fhe_left->fhe_right = hb->fh_root;
+ hb->fh_root->fhe_left->fhe_right = ha->fh_root;
+ x = ha->fh_root->fhe_left;
+ ha->fh_root->fhe_left = hb->fh_root->fhe_left;
+ hb->fh_root->fhe_left = x;
+ ha->fh_n += hb->fh_n;
+ /*
+ * we probably should also keep stats on number of unions
+ */
+
+ /* set fh_min if necessary */
+ if (fh_compare(ha, hb->fh_min, ha->fh_min) < 0)
+ ha->fh_min = hb->fh_min;
+
+ fh_destroyheap(hb);
+ return ha;
+}
+
+void
+fh_deleteheap(struct fibheap *h)
+{
+ /*
+ * We could do this even faster by walking each binomial tree, but
+ * this is simpler to code.
+ */
+ while (h->fh_min != NULL)
+ fhe_destroy(fh_extractminel(h));
+
+ fh_destroyheap(h);
+}
+
+/*
+ * Public Key Heap Functions
+ */
+struct fibheap_el *
+fh_insertkey(struct fibheap *h, int key, void *data)
+{
+ struct fibheap_el *x;
+
+ if ((x = fhe_newelem()) == NULL)
+ return NULL;
+
+ /* just insert on root list, and make sure it's not the new min */
+ x->fhe_data = data;
+ x->fhe_key = key;
+
+ fh_insertel(h, x);
+
+ return x;
+}
+
+int
+fh_minkey(struct fibheap *h)
+{
+ if (h->fh_min == NULL)
+ return INT_MIN;
+ return h->fh_min->fhe_key;
+}
+
+int
+fh_replacekey(struct fibheap *h, struct fibheap_el *x, int key)
+{
+ int ret;
+
+ ret = x->fhe_key;
+ (void)fh_replacekeydata(h, x, key, x->fhe_data);
+
+ return ret;
+}
+
+#include <stdio.h>
+
+void *
+fh_replacekeydata(struct fibheap *h, struct fibheap_el *x, int key, void *data)
+{
+ void *odata;
+ int okey;
+ struct fibheap_el *y;
+ int r;
+
+ odata = x->fhe_data;
+ okey = x->fhe_key;
+
+ /*
+ * we can increase a key by deleting and reinserting, that
+ * requires O(lgn) time.
+ */
+ if ((r = fh_comparedata(h, key, data, x)) > 0) {
+ printf("fh_comparedata r=%d key=%d data=%p\n", r, key, data);
+ /* XXX - bad code! */
+ abort();
+ fh_deleteel(h, x);
+
+ x->fhe_data = data;
+ x->fhe_key = key;
+
+ fh_insertel(h, x);
+
+ return odata;
+ }
+
+ x->fhe_data = data;
+ x->fhe_key = key;
+
+ /* because they are equal, we don't have to do anything */
+ if (r == 0)
+ return odata;
+
+ y = x->fhe_p;
+
+ if (h->fh_keys && okey == key)
+ return odata;
+
+ if (y != NULL && fh_compare(h, x, y) <= 0) {
+ fh_cut(h, x, y);
+ fh_cascading_cut(h, y);
+ }
+
+ /*
+ * the = is so that the call from fh_delete will delete the proper
+ * element.
+ */
+ if (fh_compare(h, x, h->fh_min) <= 0)
+ h->fh_min = x;
+
+ return odata;
+}
+
+/*
+ * Public void * Heap Functions
+ */
+/*
+ * this will return these values:
+ * NULL failed for some reason
+ * ptr token to use for manipulation of data
+ */
+struct fibheap_el *
+fh_insert(struct fibheap *h, void *data)
+{
+ struct fibheap_el *x;
+
+ if ((x = fhe_newelem()) == NULL)
+ return NULL;
+
+ /* just insert on root list, and make sure it's not the new min */
+ x->fhe_data = data;
+
+ fh_insertel(h, x);
+
+ return x;
+}
+
+void *
+fh_min(struct fibheap *h)
+{
+ if (h->fh_min == NULL)
+ return NULL;
+ return h->fh_min->fhe_data;
+}
+
+void *
+fh_extractmin(struct fibheap *h)
+{
+ struct fibheap_el *z;
+ void *ret;
+
+ ret = NULL;
+
+ if (h->fh_min != NULL) {
+ z = fh_extractminel(h);
+ ret = z->fhe_data;
+#ifndef NO_FREE
+ fhe_destroy(z);
+#endif
+
+ }
+
+ return ret;
+}
+
+void *
+fh_replacedata(struct fibheap *h, struct fibheap_el *x, void *data)
+{
+ return fh_replacekeydata(h, x, x->fhe_key, data);
+}
+
+void *
+fh_delete(struct fibheap *h, struct fibheap_el *x)
+{
+ void *k;
+
+ k = x->fhe_data;
+ if (!h->fh_keys)
+ fh_replacedata(h, x, h->fh_neginf);
+ else
+ fh_replacekey(h, x, INT_MIN);
+ fh_extractmin(h);
+
+ return k;
+}
+
+/*
+ * Statistics Functions
+ */
+#ifdef FH_STATS
+int
+fh_maxn(struct fibheap *h)
+{
+ return h->fh_maxn;
+}
+
+int
+fh_ninserts(struct fibheap *h)
+{
+ return h->fh_ninserts;
+}
+
+int
+fh_nextracts(struct fibheap *h)
+{
+ return h->fh_nextracts;
+}
+#endif
+
+/*
+ * begin of private element fuctions
+ */
+static struct fibheap_el *
+fh_extractminel(struct fibheap *h)
+{
+ struct fibheap_el *ret;
+ struct fibheap_el *x, *y, *orig;
+
+ ret = h->fh_min;
+
+ orig = NULL;
+ /* put all the children on the root list */
+ /* for true consistancy, we should use fhe_remove */
+ for(x = ret->fhe_child; x != orig && x != NULL;) {
+ if (orig == NULL)
+ orig = x;
+ y = x->fhe_right;
+ x->fhe_p = NULL;
+ fh_insertrootlist(h, x);
+ x = y;
+ }
+ /* remove minimum from root list */
+ fh_removerootlist(h, ret);
+ h->fh_n--;
+
+ /* if we aren't empty, consolidate the heap */
+ if (h->fh_n == 0)
+ h->fh_min = NULL;
+ else {
+ h->fh_min = ret->fhe_right;
+ fh_consolidate(h);
+ }
+
+#ifdef FH_STATS
+ h->fh_nextracts++;
+#endif
+
+ return ret;
+}
+
+static void
+fh_insertrootlist(struct fibheap *h, struct fibheap_el *x)
+{
+ if (h->fh_root == NULL) {
+ h->fh_root = x;
+ x->fhe_left = x;
+ x->fhe_right = x;
+ return;
+ }
+
+ fhe_insertafter(h->fh_root, x);
+}
+
+static void
+fh_removerootlist(struct fibheap *h, struct fibheap_el *x)
+{
+ if (x->fhe_left == x)
+ h->fh_root = NULL;
+ else
+ h->fh_root = fhe_remove(x);
+}
+
+static void
+fh_consolidate(struct fibheap *h)
+{
+ struct fibheap_el **a;
+ struct fibheap_el *w;
+ struct fibheap_el *y;
+ struct fibheap_el *x;
+ int i;
+ int d;
+ int D;
+
+ fh_checkcons(h);
+
+ /* assign a the value of h->fh_cons so I don't have to rewrite code */
+ D = h->fh_Dl + 1;
+ a = h->fh_cons;
+
+ for (i = 0; i < D; i++)
+ a[i] = NULL;
+
+ while ((w = h->fh_root) != NULL) {
+ x = w;
+ fh_removerootlist(h, w);
+ d = x->fhe_degree;
+ /* XXX - assert that d < D */
+ while(a[d] != NULL) {
+ y = a[d];
+ if (fh_compare(h, x, y) > 0)
+ swap(struct fibheap_el *, x, y);
+ fh_heaplink(h, y, x);
+ a[d] = NULL;
+ d++;
+ }
+ a[d] = x;
+ }
+ h->fh_min = NULL;
+ for (i = 0; i < D; i++)
+ if (a[i] != NULL) {
+ fh_insertrootlist(h, a[i]);
+ if (h->fh_min == NULL || fh_compare(h, a[i],
+ h->fh_min) < 0)
+ h->fh_min = a[i];
+ }
+}
+
+static void
+fh_heaplink(struct fibheap *h, struct fibheap_el *y, struct fibheap_el *x)
+{
+ /* make y a child of x */
+ if (x->fhe_child == NULL)
+ x->fhe_child = y;
+ else
+ fhe_insertbefore(x->fhe_child, y);
+ y->fhe_p = x;
+ x->fhe_degree++;
+ y->fhe_mark = 0;
+}
+
+static void
+fh_cut(struct fibheap *h, struct fibheap_el *x, struct fibheap_el *y)
+{
+ fhe_remove(x);
+ y->fhe_degree--;
+ fh_insertrootlist(h, x);
+ x->fhe_p = NULL;
+ x->fhe_mark = 0;
+}
+
+static void
+fh_cascading_cut(struct fibheap *h, struct fibheap_el *y)
+{
+ struct fibheap_el *z;
+
+ while ((z = y->fhe_p) != NULL) {
+ if (y->fhe_mark == 0) {
+ y->fhe_mark = 1;
+ return;
+ } else {
+ fh_cut(h, y, z);
+ y = z;
+ }
+ }
+}
+
+/*
+ * begining of handling elements of fibheap
+ */
+static struct fibheap_el *
+fhe_newelem()
+{
+ struct fibheap_el *e;
+
+ if ((e = malloc(sizeof *e)) == NULL)
+ return NULL;
+
+ fhe_initelem(e);
+
+ return e;
+}
+
+static void
+fhe_initelem(struct fibheap_el *e)
+{
+ e->fhe_degree = 0;
+ e->fhe_mark = 0;
+ e->fhe_p = NULL;
+ e->fhe_child = NULL;
+ e->fhe_left = e;
+ e->fhe_right = e;
+ e->fhe_data = NULL;
+}
+
+static void
+fhe_insertafter(struct fibheap_el *a, struct fibheap_el *b)
+{
+ if (a == a->fhe_right) {
+ a->fhe_right = b;
+ a->fhe_left = b;
+ b->fhe_right = a;
+ b->fhe_left = a;
+ } else {
+ b->fhe_right = a->fhe_right;
+ a->fhe_right->fhe_left = b;
+ a->fhe_right = b;
+ b->fhe_left = a;
+ }
+}
+
+static inline void
+fhe_insertbefore(struct fibheap_el *a, struct fibheap_el *b)
+{
+ fhe_insertafter(a->fhe_left, b);
+}
+
+static struct fibheap_el *
+fhe_remove(struct fibheap_el *x)
+{
+ struct fibheap_el *ret;
+
+ if (x == x->fhe_left)
+ ret = NULL;
+ else
+ ret = x->fhe_left;
+
+ /* fix the parent pointer */
+ if (x->fhe_p != NULL && x->fhe_p->fhe_child == x)
+ x->fhe_p->fhe_child = ret;
+
+ x->fhe_right->fhe_left = x->fhe_left;
+ x->fhe_left->fhe_right = x->fhe_right;
+
+ /* clear out hanging pointers */
+ x->fhe_p = NULL;
+ x->fhe_left = x;
+ x->fhe_right = x;
+
+ return ret;
+}
+
+static void
+fh_checkcons(struct fibheap *h)
+{
+ int oDl;
+
+ /* make sure we have enough memory allocated to "reorganize" */
+ if (h->fh_Dl == -1 || h->fh_n > (1 << h->fh_Dl)) {
+ oDl = h->fh_Dl;
+ if ((h->fh_Dl = ceillog2(h->fh_n) + 1) < 8)
+ h->fh_Dl = 8;
+ if (oDl != h->fh_Dl)
+ h->fh_cons = (struct fibheap_el **)realloc(h->fh_cons,
+ sizeof *h->fh_cons * (h->fh_Dl + 1));
+ if (h->fh_cons == NULL)
+ abort();
+ }
+}
+
+static int
+fh_compare(struct fibheap *h, struct fibheap_el *a, struct fibheap_el *b)
+{
+ if (h->fh_keys) {
+ if (a->fhe_key < b->fhe_key)
+ return -1;
+ if (a->fhe_key == b->fhe_key)
+ return 0;
+ return 1;
+ } else
+ return h->fh_cmp_fnct(a->fhe_data, b->fhe_data);
+}
+
+static int
+fh_comparedata(struct fibheap *h, int key, void *data, struct fibheap_el *b)
+{
+ struct fibheap_el a;
+
+ a.fhe_key = key;
+ a.fhe_data = data;
+
+ return fh_compare(h, &a, b);
+}
+
+static void
+fh_insertel(struct fibheap *h, struct fibheap_el *x)
+{
+ fh_insertrootlist(h, x);
+
+ if (h->fh_min == NULL || (h->fh_keys ? x->fhe_key < h->fh_min->fhe_key
+ : h->fh_cmp_fnct(x->fhe_data, h->fh_min->fhe_data) < 0))
+ h->fh_min = x;
+
+ h->fh_n++;
+
+#ifdef FH_STATS
+ if (h->fh_n > h->fh_maxn)
+ h->fh_maxn = h->fh_n;
+ h->fh_ninserts++;
+#endif
+
+}
diff --git a/navit/fib-1.1/fib.h b/navit/fib-1.1/fib.h
new file mode 100644
index 000000000..d8564d3c7
--- /dev/null
+++ b/navit/fib-1.1/fib.h
@@ -0,0 +1,64 @@
+/*-
+ * Copyright 1997, 1998-2003 John-Mark Gurney.
+ * 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 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 AUTHOR 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.
+ *
+ * $Id: fib.h,v 1.1 2005-12-02 10:41:56 martin-s Exp $
+ *
+ */
+
+#ifndef _FIB_H_
+#define _FIB_H_
+
+struct fibheap;
+struct fibheap_el;
+typedef int (*voidcmp)(void *, void *);
+
+/* functions for key heaps */
+struct fibheap *fh_makekeyheap(void);
+struct fibheap_el *fh_insertkey(struct fibheap *, int, void *);
+int fh_minkey(struct fibheap *);
+int fh_replacekey(struct fibheap *, struct fibheap_el *, int);
+void *fh_replacekeydata(struct fibheap *, struct fibheap_el *, int, void *);
+
+/* functions for void * heaps */
+struct fibheap *fh_makeheap(void);
+voidcmp fh_setcmp(struct fibheap *, voidcmp);
+void *fh_setneginf(struct fibheap *, void *);
+struct fibheap_el *fh_insert(struct fibheap *, void *);
+
+/* shared functions */
+void *fh_extractmin(struct fibheap *);
+void *fh_min(struct fibheap *);
+void *fh_replacedata(struct fibheap *, struct fibheap_el *, void *);
+void *fh_delete(struct fibheap *, struct fibheap_el *);
+void fh_deleteheap(struct fibheap *);
+struct fibheap *fh_union(struct fibheap *, struct fibheap *);
+
+#ifdef FH_STATS
+int fh_maxn(struct fibheap *);
+int fh_ninserts(struct fibheap *);
+int fh_nextracts(struct fibheap *);
+#endif
+
+#endif /* _FIB_H_ */
diff --git a/navit/fib-1.1/fibpriv.h b/navit/fib-1.1/fibpriv.h
new file mode 100644
index 000000000..3984b261e
--- /dev/null
+++ b/navit/fib-1.1/fibpriv.h
@@ -0,0 +1,98 @@
+/*-
+ * Copyright 1997, 1999-2003 John-Mark Gurney.
+ * 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 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 AUTHOR 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.
+ *
+ * $Id: fibpriv.h,v 1.1 2005-12-02 10:41:56 martin-s Exp $
+ *
+ */
+
+#ifndef _FIBPRIV_H_
+#define _FIBPRIV_H_
+
+struct fibheap_el;
+
+/*
+ * global heap operations
+ */
+struct fibheap {
+ int (*fh_cmp_fnct)(void *, void *);
+ int fh_n;
+ int fh_Dl;
+ struct fibheap_el **fh_cons;
+ struct fibheap_el *fh_min;
+ struct fibheap_el *fh_root;
+ void *fh_neginf;
+ int fh_keys : 1;
+#ifdef FH_STATS
+ int fh_maxn;
+ int fh_ninserts;
+ int fh_nextracts;
+#endif
+};
+
+static void fh_initheap(struct fibheap *);
+static void fh_insertrootlist(struct fibheap *, struct fibheap_el *);
+static void fh_removerootlist(struct fibheap *, struct fibheap_el *);
+static void fh_consolidate(struct fibheap *);
+static void fh_heaplink(struct fibheap *h, struct fibheap_el *y,
+ struct fibheap_el *x);
+static void fh_cut(struct fibheap *, struct fibheap_el *, struct fibheap_el *);
+static void fh_cascading_cut(struct fibheap *, struct fibheap_el *);
+static struct fibheap_el *fh_extractminel(struct fibheap *);
+static void fh_checkcons(struct fibheap *h);
+static void fh_destroyheap(struct fibheap *h);
+static int fh_compare(struct fibheap *h, struct fibheap_el *a,
+ struct fibheap_el *b);
+static int fh_comparedata(struct fibheap *h, int key, void *data,
+ struct fibheap_el *b);
+static void fh_insertel(struct fibheap *h, struct fibheap_el *x);
+static void fh_deleteel(struct fibheap *h, struct fibheap_el *x);
+
+/*
+ * specific node operations
+ */
+struct fibheap_el {
+ int fhe_degree;
+ int fhe_mark;
+ struct fibheap_el *fhe_p;
+ struct fibheap_el *fhe_child;
+ struct fibheap_el *fhe_left;
+ struct fibheap_el *fhe_right;
+ int fhe_key;
+ void *fhe_data;
+};
+
+static struct fibheap_el *fhe_newelem(void);
+static void fhe_initelem(struct fibheap_el *);
+static void fhe_insertafter(struct fibheap_el *a, struct fibheap_el *b);
+static inline void fhe_insertbefore(struct fibheap_el *a, struct fibheap_el *b);
+static struct fibheap_el *fhe_remove(struct fibheap_el *a);
+#define fhe_destroy(x) free((x))
+
+/*
+ * general functions
+ */
+static inline int ceillog2(unsigned int a);
+
+#endif /* _FIBPRIV_H_ */
diff --git a/navit/fib-1.1/fibtest.c b/navit/fib-1.1/fibtest.c
new file mode 100644
index 000000000..c7be1e9c0
--- /dev/null
+++ b/navit/fib-1.1/fibtest.c
@@ -0,0 +1,80 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "fib.h"
+
+int main(void)
+{
+ struct fibheap *a;
+ void *arr[10];
+ int i;
+
+ a = fh_makekeyheap();
+
+ for (i=1 ; i < 10 ; i++)
+ {
+ arr[i]= fh_insertkey(a,0,(void *)i);
+ printf("adding: 0 %d \n",i);
+ }
+
+ printf(" \n");
+ fh_replacekey(a, arr[1],-1);
+ fh_replacekey(a, arr[6],-1);
+ fh_replacekey(a, arr[4],-1);
+ fh_replacekey(a, arr[2],-1);
+ fh_replacekey(a, arr[8],-1);
+
+ printf("value(minkey) %d\n",fh_minkey(a));
+ printf("id: %d\n\n", (int)fh_extractmin(a));
+
+ fh_replacekey(a, arr[7],-33);
+/* -> node 7 becomes root node, but is still pointed to by node 6 */
+ fh_replacekey(a, arr[4],-36);
+ fh_replacekey(a, arr[3],-1);
+ fh_replacekey(a, arr[9],-81);
+
+ printf("value(minkey) %d\n",fh_minkey(a));
+ printf("id: %d\n\n", (int)fh_extractmin(a));
+
+ fh_replacekey(a, arr[6],-68);
+ fh_replacekey(a, arr[2],-69);
+
+ printf("value(minkey) %d\n",fh_minkey(a));
+ printf("id: %d\n\n", (int)fh_extractmin(a));
+
+ fh_replacekey(a, arr[1],-52);
+ fh_replacekey(a, arr[3],-2);
+ fh_replacekey(a, arr[4],-120);
+ fh_replacekey(a, arr[5],-48);
+
+ printf("value(minkey) %d\n",fh_minkey(a));
+ printf("id: %d\n\n", (int)fh_extractmin(a));
+
+ fh_replacekey(a, arr[3],-3);
+ fh_replacekey(a, arr[5],-63);
+
+ printf("value(minkey) %d\n",fh_minkey(a));
+ printf("id: %d\n\n", (int)fh_extractmin(a));
+
+ fh_replacekey(a, arr[5],-110);
+ fh_replacekey(a, arr[7],-115);
+
+ printf("value(minkey) %d\n",fh_minkey(a));
+ printf("id: %d\n\n", (int)fh_extractmin(a));
+
+ fh_replacekey(a, arr[5],-188);
+
+ printf("value(minkey) %d\n",fh_minkey(a));
+ printf("id: %d\n\n", (int)fh_extractmin(a));
+
+ fh_replacekey(a, arr[3],-4);
+
+ printf("value(minkey) %d\n",fh_minkey(a));
+ printf("id: %d\n\n", (int)fh_extractmin(a));
+
+ printf("value(minkey) %d\n",fh_minkey(a));
+ printf("id: %d\n\n", (int)fh_extractmin(a));
+
+ fh_deleteheap(a);
+
+ return 0;
+}
diff --git a/navit/fib-1.1/fibtest.out b/navit/fib-1.1/fibtest.out
new file mode 100644
index 000000000..285bd26bb
--- /dev/null
+++ b/navit/fib-1.1/fibtest.out
@@ -0,0 +1,37 @@
+adding: 0 1
+adding: 0 2
+adding: 0 3
+adding: 0 4
+adding: 0 5
+adding: 0 6
+adding: 0 7
+adding: 0 8
+adding: 0 9
+
+value(minkey) -1
+id: 8
+
+value(minkey) -81
+id: 9
+
+value(minkey) -69
+id: 2
+
+value(minkey) -120
+id: 4
+
+value(minkey) -68
+id: 6
+
+value(minkey) -115
+id: 7
+
+value(minkey) -188
+id: 5
+
+value(minkey) -52
+id: 1
+
+value(minkey) -4
+id: 3
+
diff --git a/navit/fib-1.1/fibtest2.c b/navit/fib-1.1/fibtest2.c
new file mode 100644
index 000000000..8a623b634
--- /dev/null
+++ b/navit/fib-1.1/fibtest2.c
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "fib.h"
+
+int
+main(void) {
+ struct fibheap *a;
+ void *arr[10];
+ int i;
+ a = fh_makekeyheap();
+
+ for (i=1 ; i < 10 ; i++)
+ {
+ arr[i]= fh_insertkey(a,0,(void *)i);
+ printf("adding: 0 %d \n",i);
+ }
+
+ printf(" \n");
+ fh_replacekey(a, arr[1],-38);
+ fh_replacekey(a, arr[7],-34);
+
+ printf("wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+ fh_replacekey(a, arr[2],-55);
+ fh_replacekey(a, arr[5],-56);
+ printf("Wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+
+ fh_replacekey(a, arr[4],-1);
+ fh_replacekey(a, arr[2],-102);
+ fh_replacekey(a, arr[6],-1);
+ fh_replacekey(a, arr[9],-1);
+ fh_replacekey(a, arr[8],-4);
+ printf("Wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+ fh_replacekey(a, arr[3],-74);
+ fh_replacekey(a, arr[8],-55);
+ fh_replacekey(a, arr[4],-2);
+
+ printf("Wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+ fh_replacekey(a, arr[4],-3);
+ fh_replacekey(a, arr[6],-2);
+ fh_replacekey(a, arr[7],-99);
+ printf("Wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+ fh_replacekey(a, arr[6],-3);
+ fh_replacekey(a, arr[4],-4);
+ fh_replacekey(a, arr[8],-94);
+ fh_replacekey(a, arr[9],-2);
+ printf("Wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+ fh_replacekey(a, arr[6],-4);
+
+ printf("Wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+
+ printf("Wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+ /*fh_replacekey(a, arr[9],-3);*/
+ printf("Wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+
+ /*fh_replacekey(a, arr[9],-49);*/
+
+ fh_deleteheap(a);
+
+ return 0;
+}
diff --git a/navit/fib-1.1/fibtest2.out b/navit/fib-1.1/fibtest2.out
new file mode 100644
index 000000000..e9d1704f8
--- /dev/null
+++ b/navit/fib-1.1/fibtest2.out
@@ -0,0 +1,37 @@
+adding: 0 1
+adding: 0 2
+adding: 0 3
+adding: 0 4
+adding: 0 5
+adding: 0 6
+adding: 0 7
+adding: 0 8
+adding: 0 9
+
+wert(minkey) -38
+Knoten: 1
+
+Wert(minkey) -56
+Knoten: 5
+
+Wert(minkey) -102
+Knoten: 2
+
+Wert(minkey) -74
+Knoten: 3
+
+Wert(minkey) -99
+Knoten: 7
+
+Wert(minkey) -94
+Knoten: 8
+
+Wert(minkey) -4
+Knoten: 6
+
+Wert(minkey) -4
+Knoten: 4
+
+Wert(minkey) -2
+Knoten: 9
+
diff --git a/navit/fib-1.1/tt.c b/navit/fib-1.1/tt.c
new file mode 100644
index 000000000..26db1d2c3
--- /dev/null
+++ b/navit/fib-1.1/tt.c
@@ -0,0 +1,64 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "fib.h"
+
+int main(void)
+{
+
+ struct fibheap *a;
+ void *arr[10];
+ int i;
+
+ a = fh_makekeyheap();
+
+ for (i=1 ; i < 8 ; i++)
+ {
+ arr[i]= fh_insertkey(a,0,(void *)i);
+ printf("adding: 0 %d \n",i);
+ }
+
+ printf(" \n");
+
+ fh_replacekey(a, arr[1],-2);
+ fh_replacekey(a, arr[4],-3);
+ fh_replacekey(a, arr[7],-5);
+
+ printf("Wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+
+ fh_replacekey(a, arr[3],-2);
+ fh_replacekey(a, arr[6],-1);
+
+ printf("Wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+
+ fh_replacekey(a, arr[1],-9);
+ fh_replacekey(a, arr[5],-3);
+
+ printf("Wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+
+ fh_replacekey(a, arr[2],-4);
+ fh_replacekey(a, arr[5],-5);
+ fh_replacekey(a, arr[6],-3);
+
+ printf("Wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+
+ fh_replacekey(a, arr[2],-6);
+ fh_replacekey(a, arr[6],-6);
+
+ printf("Wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+
+ printf("Wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+
+ printf("Wert(minkey) %d\n",fh_minkey(a));
+ printf("Knoten: %d\n\n", (int)fh_extractmin(a));
+
+ fh_deleteheap(a);
+
+ return 0;
+}
+
diff --git a/navit/fib-1.1/tt.out b/navit/fib-1.1/tt.out
new file mode 100644
index 000000000..37a8a47c1
--- /dev/null
+++ b/navit/fib-1.1/tt.out
@@ -0,0 +1,29 @@
+adding: 0 1
+adding: 0 2
+adding: 0 3
+adding: 0 4
+adding: 0 5
+adding: 0 6
+adding: 0 7
+
+Wert(minkey) -5
+Knoten: 7
+
+Wert(minkey) -3
+Knoten: 4
+
+Wert(minkey) -9
+Knoten: 1
+
+Wert(minkey) -5
+Knoten: 5
+
+Wert(minkey) -6
+Knoten: 6
+
+Wert(minkey) -6
+Knoten: 2
+
+Wert(minkey) -2
+Knoten: 3
+
diff --git a/navit/fib-1.1/use.c b/navit/fib-1.1/use.c
new file mode 100644
index 000000000..e8db32792
--- /dev/null
+++ b/navit/fib-1.1/use.c
@@ -0,0 +1,126 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "fib.h"
+
+#define TESTCASE 1
+
+#define COUNT 100000
+#define DIF 1000
+#define MAXEXT 10
+#define VERBOSE 1
+
+int cmp(void *, void *);
+
+int
+cmp(void *x, void *y)
+{
+ int a, b;
+ a = (int)x;
+ b = (int)y;
+
+ if (a < b)
+ return -1;
+ if (a == b)
+ return 0;
+ return 1;
+}
+
+int
+main(void)
+{
+#if !TESTCASE
+ struct fibheap_el *w;
+#else
+ int e, j, k;
+#endif
+ struct fibheap *a;
+ int i, x;
+
+ a = fh_makeheap();
+ fh_setcmp(a, cmp);
+
+ srandom(time(NULL));
+#if TESTCASE
+#if VERBOSE
+ printf("inserting: ");
+#endif
+ e = 0;
+ for (i = 0; i < COUNT; i++) {
+#if VERBOSE
+ if (i)
+ printf(", ");
+#endif
+ fh_insert(a, (void *)(x = random()/10));
+#if VERBOSE
+ printf("%d", x);
+#endif
+ if (i - e > DIF) {
+ k = random() % MAXEXT;
+ for (j = 0; j < k; j++, e++)
+ printf("throwing: %d\n", (int)fh_extractmin(a));
+ }
+ }
+
+#if VERBOSE
+ printf("\nremaining: %d\n", COUNT - e);
+ printf("extracting: ");
+#endif
+ for (i = 0; i < COUNT - e; i++) {
+#if VERBOSE
+ if (i)
+ printf(", ");
+ printf("%d", (int)fh_extractmin(a));
+#else
+ fh_extractmin(a);
+#endif
+ }
+#if VERBOSE
+ printf("\n");
+#endif
+ if ((int)fh_extractmin(a) == 0)
+ printf("heap empty!\n");
+ else {
+ printf("heap not empty! ERROR!\n");
+ exit(1);
+ }
+#else
+ w = fh_insert(a, (void *)6);
+ printf("adding: %d\n", 6);
+ fh_insert(a, (void *)9);
+ printf("adding: %d\n", 9);
+ fh_insert(a, (void *)1);
+ printf("adding: %d\n", 1);
+ for(i = 0; i < 5; i++) {
+ x = random()/10000;
+ printf("adding: %d\n", x);
+ fh_insert(a, (void *)x);
+ }
+ fh_insert(a, (void *)4);
+ printf("adding: %d\n", 4);
+ fh_insert(a, (void *)8);
+ printf("adding: %d\n", 8);
+ printf("first: %d\n", (int)fh_extractmin(a));
+ printf("deleting: %d\n", (int)fh_delete(a, w));
+ printf("first: %d\n", (int)fh_extractmin(a));
+ printf("first: %d\n", (int)fh_extractmin(a));
+ printf("first: %d\n", (int)fh_extractmin(a));
+ printf("first: %d\n", (int)fh_extractmin(a));
+ printf("first: %d\n", (int)fh_extractmin(a));
+ for(i = 0; i < 5; i++) {
+ x = random()/10000;
+ printf("adding: %d\n", x);
+ fh_insert(a, (void *)x);
+ }
+ printf("first: %d\n", (int)fh_extractmin(a));
+ printf("first: %d\n", (int)fh_extractmin(a));
+ printf("first: %d\n", (int)fh_extractmin(a));
+ printf("first: %d\n", (int)fh_extractmin(a));
+ printf("first: %d\n", (int)fh_extractmin(a));
+#endif
+
+ fh_deleteheap(a);
+
+ return 0;
+}
diff --git a/navit/file.c b/navit/file.c
new file mode 100644
index 000000000..9fadf4555
--- /dev/null
+++ b/navit/file.c
@@ -0,0 +1,316 @@
+#define _FILE_OFFSET_BITS 64
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <wordexp.h>
+#include <glib.h>
+#include <zlib.h>
+#include "debug.h"
+#include "file.h"
+#include "config.h"
+
+#ifndef O_LARGEFILE
+#define O_LARGEFILE 0
+#endif
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+static struct file *file_list;
+
+struct file *
+file_create(char *name)
+{
+ struct stat stat;
+ struct file *file= g_new0(struct file,1);
+
+ if (! file)
+ return file;
+ file->fd=open(name, O_RDONLY|O_LARGEFILE | O_BINARY);
+ if (file->fd < 0) {
+ g_free(file);
+ return NULL;
+ }
+ fstat(file->fd, &stat);
+ file->size=stat.st_size;
+ file->name = g_strdup(name);
+ g_assert(file != NULL);
+ file->next=file_list;
+ file_list=file;
+ return file;
+}
+
+int
+file_mmap(struct file *file)
+{
+#ifdef _WIN32
+ file->begin = (char*)mmap_readonly_win32( file->name, &file->map_handle, &file->map_file );
+#else
+ file->begin=mmap(NULL, file->size, PROT_READ|PROT_WRITE, MAP_PRIVATE, file->fd, 0);
+ g_assert(file->begin != NULL);
+ if (file->begin == (void *)0xffffffff) {
+ perror("mmap");
+ return 0;
+ }
+#endif
+ g_assert(file->begin != (void *)0xffffffff);
+ file->end=file->begin+file->size;
+
+ return 1;
+}
+
+unsigned char *
+file_data_read(struct file *file, long long offset, int size)
+{
+ void *ret;
+ if (file->begin)
+ return file->begin+offset;
+ ret=g_malloc(size);
+ lseek(file->fd, offset, SEEK_SET);
+ if (read(file->fd, ret, size) != size) {
+ g_free(ret);
+ ret=NULL;
+ }
+ return ret;
+
+}
+
+static int
+uncompress_int(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+
+ err = inflateInit2(&stream, -MAX_WBITS);
+ if (err != Z_OK) return err;
+
+ err = inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ inflateEnd(&stream);
+ if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
+ return Z_DATA_ERROR;
+ return err;
+ }
+ *destLen = stream.total_out;
+
+ err = inflateEnd(&stream);
+ return err;
+}
+
+unsigned char *
+file_data_read_compressed(struct file *file, long long offset, int size, int size_uncomp)
+{
+ void *ret;
+ char buffer[size];
+ uLongf destLen=size_uncomp;
+
+ ret=g_malloc(size_uncomp);
+ lseek(file->fd, offset, SEEK_SET);
+ if (read(file->fd, buffer, size) != size) {
+ g_free(ret);
+ ret=NULL;
+ } else {
+ if (uncompress_int(ret, &destLen, (Bytef *)buffer, size) != Z_OK) {
+ dbg(0,"uncompress failed\n");
+ g_free(ret);
+ ret=NULL;
+ }
+ }
+ return ret;
+}
+
+void
+file_data_free(struct file *file, unsigned char *data)
+{
+ if (file->begin && data >= file->begin && data < file->end)
+ return;
+ g_free(data);
+}
+
+int
+file_exists(char *name)
+{
+ struct stat buf;
+ if (! stat(name, &buf))
+ return 1;
+ return 0;
+}
+
+void
+file_remap_readonly(struct file *f)
+{
+#ifdef _WIN32
+#else
+ void *begin;
+ munmap(f->begin, f->size);
+ begin=mmap(f->begin, f->size, PROT_READ, MAP_PRIVATE, f->fd, 0);
+ if (f->begin != begin)
+ printf("remap failed\n");
+#endif
+}
+
+void
+file_remap_readonly_all(void)
+{
+ struct file *f=file_list;
+ int limit=1000;
+
+ while (f && limit-- > 0) {
+ file_remap_readonly(f);
+ f=f->next;
+ }
+}
+
+void
+file_unmap(struct file *f)
+{
+#ifdef _WIN32
+ mmap_unmap_win32( f->begin, f->map_handle , f->map_file );
+#else
+ munmap(f->begin, f->size);
+#endif
+}
+
+void
+file_unmap_all(void)
+{
+ struct file *f=file_list;
+ int limit=1000;
+
+ while (f && limit-- > 0) {
+ file_unmap(f);
+ f=f->next;
+ }
+}
+
+
+
+void *
+file_opendir(char *dir)
+{
+ return opendir(dir);
+}
+
+char *
+file_readdir(void *hnd)
+{
+ struct dirent *ent;
+
+ ent=readdir(hnd);
+ if (! ent)
+ return NULL;
+ return ent->d_name;
+}
+
+void
+file_closedir(void *hnd)
+{
+ closedir(hnd);
+}
+
+struct file *
+file_create_caseinsensitive(char *name)
+{
+ char dirname[strlen(name)+1];
+ char *filename;
+ char *p;
+ void *d;
+ struct file *ret;
+
+ ret=file_create(name);
+ if (ret)
+ return ret;
+
+ strcpy(dirname, name);
+ p=dirname+strlen(name);
+ while (p > dirname) {
+ if (*p == '/')
+ break;
+ p--;
+ }
+ *p=0;
+ d=file_opendir(dirname);
+ if (d) {
+ *p++='/';
+ while ((filename=file_readdir(d))) {
+ if (!strcasecmp(filename, p)) {
+ strcpy(p, filename);
+ ret=file_create(dirname);
+ if (ret)
+ break;
+ }
+ }
+ file_closedir(d);
+ }
+ return ret;
+}
+
+void
+file_destroy(struct file *f)
+{
+ close(f->fd);
+
+ if ( f->begin != NULL )
+ {
+ file_unmap( f );
+ }
+
+ g_free(f->name);
+ g_free(f);
+}
+
+struct file_wordexp {
+ wordexp_t we;
+};
+
+struct file_wordexp *
+file_wordexp_new(const char *pattern)
+{
+ struct file_wordexp *ret=g_new(struct file_wordexp, 1);
+ wordexp(pattern, &ret->we, 0);
+ return ret;
+}
+
+int
+file_wordexp_get_count(struct file_wordexp *wexp)
+{
+ return wexp->we.we_wordc;
+}
+
+char **
+file_wordexp_get_array(struct file_wordexp *wexp)
+{
+ return wexp->we.we_wordv;
+}
+
+void
+file_wordexp_destroy(struct file_wordexp *wexp)
+{
+ wordfree(&wexp->we);
+ g_free(wexp);
+}
+
+
+int
+file_get_param(struct file *file, struct param_list *param, int count)
+{
+ int i=count;
+ param_add_string("Filename", file->name, &param, &count);
+ param_add_hex("Size", file->size, &param, &count);
+ return i-count;
+}
diff --git a/navit/file.h b/navit/file.h
new file mode 100644
index 000000000..475777b08
--- /dev/null
+++ b/navit/file.h
@@ -0,0 +1,46 @@
+#ifndef NAVIT_FILE_H
+#define NAVIT_FILE_H
+
+#include "param.h"
+
+struct file {
+ unsigned char *begin;
+ unsigned char *end;
+ long long size;
+ char *name;
+ int fd;
+#ifdef _WIN32
+ long map_handle;
+ long map_file;
+#endif
+ struct file *next;
+};
+
+/* prototypes */
+struct file;
+struct file_wordexp;
+struct param_list;
+struct file *file_create(char *name);
+int file_mmap(struct file *file);
+unsigned char *file_data_read(struct file *file, long long offset, int size);
+unsigned char *file_data_read_compressed(struct file *file, long long offset, int size, int size_uncomp);
+void file_data_free(struct file *file, unsigned char *data);
+int file_exists(char *name);
+void file_remap_readonly(struct file *f);
+void file_remap_readonly_all(void);
+void file_unmap(struct file *f);
+void file_unmap_all(void);
+void *file_opendir(char *dir);
+char *file_readdir(void *hnd);
+void file_closedir(void *hnd);
+struct file *file_create_caseinsensitive(char *name);
+void file_destroy(struct file *f);
+struct file_wordexp *file_wordexp_new(const char *pattern);
+int file_wordexp_get_count(struct file_wordexp *wexp);
+char **file_wordexp_get_array(struct file_wordexp *wexp);
+void file_wordexp_destroy(struct file_wordexp *wexp);
+int file_get_param(struct file *file, struct param_list *param, int count);
+/* end of prototypes */
+
+#endif
+
diff --git a/navit/graphics.c b/navit/graphics.c
new file mode 100644
index 000000000..75a1f9465
--- /dev/null
+++ b/navit/graphics.c
@@ -0,0 +1,1021 @@
+//##############################################################################################################
+//#
+//# File: graphics.c
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//#
+//##############################################################################################################
+
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "debug.h"
+#include "string.h"
+#include "draw_info.h"
+#include "point.h"
+#include "graphics.h"
+#include "projection.h"
+#include "map.h"
+#include "coord.h"
+#include "transform.h"
+#include "plugin.h"
+#include "profile.h"
+#include "mapset.h"
+#include "layout.h"
+#include "route.h"
+#include "util.h"
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct graphics
+{
+ struct graphics_priv *priv;
+ struct graphics_methods meth;
+ struct graphics_font *font[16];
+ struct graphics_gc *gc[3];
+ struct attr **attrs;
+ int ready;
+};
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct displaylist {
+ GHashTable *dl;
+};
+//##############################################################################################################
+//# Description: Creates a new graphics object
+//# Comment: attr type required
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct graphics * graphics_new(struct attr *parent, struct attr **attrs)
+{
+ struct graphics *this_;
+ struct attr *type_attr;
+ struct graphics_priv * (*graphicstype_new)(struct graphics_methods *meth, struct attr **attrs);
+
+ if (! (type_attr=attr_search(attrs, NULL, attr_type))) {
+ return NULL;
+ }
+
+ graphicstype_new=plugin_get_graphics_type(type_attr->u.str);
+ if (! graphicstype_new)
+ return NULL;
+ this_=g_new0(struct graphics, 1);
+ this_->priv=(*graphicstype_new)(&this_->meth, attrs);
+ this_->attrs=attr_list_dup(attrs);
+ return this_;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+int graphics_get_attr(struct graphics *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
+{
+ return attr_generic_get_attr(this_->attrs, type, attr, iter);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct graphics * graphics_overlay_new(struct graphics *parent, struct point *p, int w, int h)
+{
+ struct graphics *this_;
+ this_=g_new0(struct graphics, 1);
+ this_->priv=parent->meth.overlay_new(parent->priv, &this_->meth, p, w, h);
+ return this_;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_init(struct graphics *this_)
+{
+ this_->gc[0]=graphics_gc_new(this_);
+ graphics_gc_set_background(this_->gc[0], &(struct color) { 0xffff, 0xefef, 0xb7b7 });
+ graphics_gc_set_foreground(this_->gc[0], &(struct color) { 0xffff, 0xefef, 0xb7b7 });
+ this_->gc[1]=graphics_gc_new(this_);
+ graphics_gc_set_background(this_->gc[1], &(struct color) { 0x0000, 0x0000, 0x0000 });
+ graphics_gc_set_foreground(this_->gc[1], &(struct color) { 0xffff, 0xffff, 0xffff });
+ this_->gc[2]=graphics_gc_new(this_);
+ graphics_gc_set_background(this_->gc[2], &(struct color) { 0xffff, 0xffff, 0xffff });
+ graphics_gc_set_foreground(this_->gc[2], &(struct color) { 0xffff, 0xffff, 0xffff });
+ this_->meth.background_gc(this_->priv, this_->gc[0]->priv);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void * graphics_get_data(struct graphics *this_, char *type)
+{
+ return (this_->meth.get_data(this_->priv, type));
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_register_resize_callback(struct graphics *this_, void (*callback)(void *data, int w, int h), void *data)
+{
+ this_->meth.register_resize_callback(this_->priv, callback, data);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment: Called in navit.c
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_register_button_callback(struct graphics *this_, void (*callback)(void *data, int pressed, int button, struct point *p), void *data)
+{
+ this_->meth.register_button_callback(this_->priv, callback, data);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_register_motion_callback(struct graphics *this_, void (*callback)(void *data, struct point *p), void *data)
+{
+ this_->meth.register_motion_callback(this_->priv, callback, data);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct graphics_font * graphics_font_new(struct graphics *gra, int size, int flags)
+{
+ struct graphics_font *this_;
+
+ this_=g_new0(struct graphics_font,1);
+ this_->priv=gra->meth.font_new(gra->priv, &this_->meth, size, flags);
+ return this_;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct graphics_gc * graphics_gc_new(struct graphics *gra)
+{
+ struct graphics_gc *this_;
+
+ this_=g_new0(struct graphics_gc,1);
+ this_->priv=gra->meth.gc_new(gra->priv, &this_->meth);
+ return this_;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_gc_destroy(struct graphics_gc *gc)
+{
+ gc->meth.gc_destroy(gc->priv);
+ g_free(gc);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_gc_set_foreground(struct graphics_gc *gc, struct color *c)
+{
+ gc->meth.gc_set_foreground(gc->priv, c);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_gc_set_background(struct graphics_gc *gc, struct color *c)
+{
+ gc->meth.gc_set_background(gc->priv, c);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_gc_set_linewidth(struct graphics_gc *gc, int width)
+{
+ gc->meth.gc_set_linewidth(gc->priv, width);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_gc_set_dashes(struct graphics_gc *gc, int width, int offset, unsigned char dash_list[], int n)
+{
+ if (gc->meth.gc_set_dashes)
+ gc->meth.gc_set_dashes(gc->priv, width, offset, dash_list, n);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct graphics_image * graphics_image_new(struct graphics *gra, char *path)
+{
+ struct graphics_image *this_;
+
+ this_=g_new0(struct graphics_image,1);
+ this_->priv=gra->meth.image_new(gra->priv, &this_->meth, path, &this_->width, &this_->height, &this_->hot);
+ if (! this_->priv) {
+ g_free(this_);
+ this_=NULL;
+ }
+ return this_;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_image_free(struct graphics *gra, struct graphics_image *img)
+{
+ if (gra->meth.image_free)
+ gra->meth.image_free(gra->priv, img->priv);
+ g_free(img);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_draw_restore(struct graphics *this_, struct point *p, int w, int h)
+{
+ this_->meth.draw_restore(this_->priv, p, w, h);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_draw_mode(struct graphics *this_, enum draw_mode_num mode)
+{
+ this_->meth.draw_mode(this_->priv, mode);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_draw_lines(struct graphics *this_, struct graphics_gc *gc, struct point *p, int count)
+{
+ this_->meth.draw_lines(this_->priv, gc->priv, p, count);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_draw_circle(struct graphics *this_, struct graphics_gc *gc, struct point *p, int r)
+{
+ this_->meth.draw_circle(this_->priv, gc->priv, p, r);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_draw_rectangle(struct graphics *this_, struct graphics_gc *gc, struct point *p, int w, int h)
+{
+ this_->meth.draw_rectangle(this_->priv, gc->priv, p, w, h);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_draw_text(struct graphics *this_, struct graphics_gc *gc1, struct graphics_gc *gc2, struct graphics_font *font, char *text, struct point *p, int dx, int dy)
+{
+ this_->meth.draw_text(this_->priv, gc1->priv, gc2 ? gc2->priv : NULL, font->priv, text, p, dx, dy);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_draw_image(struct graphics *this_, struct graphics_gc *gc, struct point *p, struct graphics_image *img)
+{
+ this_->meth.draw_image(this_->priv, gc->priv, p, img->priv);
+}
+
+#include "attr.h"
+#include "popup.h"
+#include <stdio.h>
+
+
+#if 0
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void popup_view_html(struct popup_item *item, char *file)
+{
+ char command[1024];
+ sprintf(command,"firefox %s", file);
+ system(command);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void graphics_popup(struct display_list *list, struct popup_item **popup)
+{
+ struct item *item;
+ struct attr attr;
+ struct map_rect *mr;
+ struct coord c;
+ struct popup_item *curr_item,*last=NULL;
+ item=list->data;
+ mr=map_rect_new(item->map, NULL, NULL, 0);
+ printf("id hi=0x%x lo=0x%x\n", item->id_hi, item->id_lo);
+ item=map_rect_get_item_byid(mr, item->id_hi, item->id_lo);
+ if (item) {
+ if (item_attr_get(item, attr_name, &attr)) {
+ curr_item=popup_item_new_text(popup,attr.u.str,1);
+ if (item_attr_get(item, attr_info_html, &attr)) {
+ popup_item_new_func(&last,"HTML Info",1, popup_view_html, g_strdup(attr.u.str));
+ }
+ if (item_attr_get(item, attr_price_html, &attr)) {
+ popup_item_new_func(&last,"HTML Preis",2, popup_view_html, g_strdup(attr.u.str));
+ }
+ curr_item->submenu=last;
+ }
+ }
+ map_rect_destroy(mr);
+}
+#endif
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct displayitem {
+ struct item item;
+ char *label;
+ int displayed;
+ int count;
+ struct point pnt[0];
+};
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static int xdisplay_free_list(gpointer key, gpointer value, gpointer user_data)
+{
+ GList *h, *l;
+ h=value;
+ l=h;
+ while (l) {
+ struct displayitem *di=l->data;
+ if (! di->displayed && di->item.type < type_line)
+ dbg(1,"warning: item '%s' not displayed\n", item_to_name(di->item.type));
+ g_free(l->data);
+ l=g_list_next(l);
+ }
+ g_list_free(h);
+ return TRUE;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void xdisplay_free(GHashTable *display_list)
+{
+ g_hash_table_foreach_remove(display_list, xdisplay_free_list, NULL);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void display_add(struct displaylist *displaylist, struct item *item, int count, struct point *pnt, char *label)
+{
+ struct displayitem *di;
+ int len;
+ GList *l;
+ char *p;
+
+ len=sizeof(*di)+count*sizeof(*pnt);
+ if (label)
+ len+=strlen(label)+1;
+
+ p=g_malloc(len);
+
+ di=(struct displayitem *)p;
+ di->displayed=0;
+ p+=sizeof(*di)+count*sizeof(*pnt);
+ di->item=*item;
+ if (label) {
+ di->label=p;
+ strcpy(di->label, label);
+ } else
+ di->label=NULL;
+ di->count=count;
+ memcpy(di->pnt, pnt, count*sizeof(*pnt));
+
+ l=g_hash_table_lookup(displaylist->dl, GINT_TO_POINTER(item->type));
+ l=g_list_prepend(l, di);
+ g_hash_table_insert(displaylist->dl, GINT_TO_POINTER(item->type), l);
+}
+
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void label_line(struct graphics *gra, struct graphics_gc *fg, struct graphics_gc *bg, struct graphics_font *font, struct point *p, int count, char *label)
+{
+ int i,x,y,tl;
+ double dx,dy,l;
+ struct point p_t;
+
+ tl=strlen(label)*400;
+ for (i = 0 ; i < count-1 ; i++) {
+ dx=p[i+1].x-p[i].x;
+ dx*=100;
+ dy=p[i+1].y-p[i].y;
+ dy*=100;
+ l=(int)sqrt((float)(dx*dx+dy*dy));
+ if (l > tl) {
+ x=p[i].x;
+ y=p[i].y;
+ if (dx < 0) {
+ dx=-dx;
+ dy=-dy;
+ x=p[i+1].x;
+ y=p[i+1].y;
+ }
+ x+=(l-tl)*dx/l/200;
+ y+=(l-tl)*dy/l/200;
+ x-=dy*45/l/10;
+ y+=dx*45/l/10;
+ p_t.x=x;
+ p_t.y=y;
+ #if 0
+ printf("display_text: '%s', %d, %d, %d, %d %d\n", label, x, y, dx*0x10000/l, dy*0x10000/l, l);
+ #endif
+ gra->meth.draw_text(gra->priv, fg->priv, bg->priv, font->priv, label, &p_t, dx*0x10000/l, dy*0x10000/l);
+ }
+ }
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void xdisplay_draw_elements(struct graphics *gra, GHashTable *display_list, struct itemtype *itm)
+{
+ struct element *e;
+ GList *l,*ls,*es,*types;
+ enum item_type type;
+ struct graphics_gc *gc = NULL;
+ struct graphics_image *img;
+ struct point p;
+
+ es=itm->elements;
+ while (es) {
+ e=es->data;
+ types=itm->type;
+ while (types) {
+ type=GPOINTER_TO_INT(types->data);
+ ls=g_hash_table_lookup(display_list, GINT_TO_POINTER(type));
+ l=ls;
+ if (gc)
+ graphics_gc_destroy(gc);
+ gc=NULL;
+ img=NULL;
+ while (l) {
+ struct displayitem *di;
+ di=l->data;
+ di->displayed=1;
+ if (! gc) {
+ gc=graphics_gc_new(gra);
+ gc->meth.gc_set_foreground(gc->priv, &e->color);
+ }
+ switch (e->type) {
+ case element_polygon:
+ gra->meth.draw_polygon(gra->priv, gc->priv, di->pnt, di->count);
+ break;
+ case element_polyline:
+ if (e->u.polyline.width > 1)
+ gc->meth.gc_set_linewidth(gc->priv, e->u.polyline.width);
+ if (e->u.polyline.width > 0 && e->u.polyline.dash_num > 0)
+ graphics_gc_set_dashes(gc, e->u.polyline.width, 0,
+ e->u.polyline.dash_table,
+ e->u.polyline.dash_num);
+ gra->meth.draw_lines(gra->priv, gc->priv, di->pnt, di->count);
+ break;
+ case element_circle:
+ if (e->u.circle.width > 1)
+ gc->meth.gc_set_linewidth(gc->priv, e->u.polyline.width);
+ gra->meth.draw_circle(gra->priv, gc->priv, &di->pnt[0], e->u.circle.radius);
+ if (di->label && e->label_size) {
+ p.x=di->pnt[0].x+3;
+ p.y=di->pnt[0].y+10;
+ if (! gra->font[e->label_size])
+ gra->font[e->label_size]=graphics_font_new(gra, e->label_size*20, 0);
+ gra->meth.draw_text(gra->priv, gra->gc[2]->priv, gra->gc[1]->priv, gra->font[e->label_size]->priv, di->label, &p, 0x10000, 0);
+ }
+ break;
+ case element_label:
+ if (di->label) {
+ if (! gra->font[e->label_size])
+ gra->font[e->label_size]=graphics_font_new(gra, e->label_size*20, 0);
+ label_line(gra, gra->gc[2], gra->gc[1], gra->font[e->label_size], di->pnt, di->count, di->label);
+ }
+ break;
+ case element_icon:
+ if (!img) {
+ char *icon=g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/xpm/", e->u.icon.src, NULL);
+ img=graphics_image_new(gra, icon);
+ g_free(icon);
+ if (! img)
+ g_warning("failed to load icon '%s'\n", e->u.icon.src);
+ }
+ if (img) {
+ p.x=di->pnt[0].x - img->hot.x;
+ p.y=di->pnt[0].y - img->hot.y;
+ gra->meth.draw_image(gra->priv, gra->gc[0]->priv, &p, img->priv);
+ graphics_image_free(gra, img);
+ img = NULL;
+ }
+ break;
+ case element_image:
+ dbg(1,"image: '%s'\n", di->label);
+ if (gra->meth.draw_image_warp)
+ gra->meth.draw_image_warp(gra->priv, gra->gc[0]->priv, di->pnt, di->count, di->label);
+ else
+ dbg(0,"draw_image_warp not supported by graphics driver drawing '%s'\n", di->label);
+ break;
+ default:
+ printf("Unhandled element type %d\n", e->type);
+
+ }
+ l=g_list_next(l);
+ }
+ types=g_list_next(types);
+ }
+ es=g_list_next(es);
+ }
+ if (gc)
+ graphics_gc_destroy(gc);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void xdisplay_draw_layer(GHashTable *display_list, struct graphics *gra, struct layer *lay, int order)
+{
+ GList *itms;
+ struct itemtype *itm;
+
+ itms=lay->itemtypes;
+ while (itms) {
+ itm=itms->data;
+ if (order >= itm->order_min && order <= itm->order_max)
+ xdisplay_draw_elements(gra, display_list, itm);
+ itms=g_list_next(itms);
+ }
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void xdisplay_draw(GHashTable *display_list, struct graphics *gra, struct layout *l, int order)
+{
+ GList *lays;
+ struct layer *lay;
+
+ lays=l->layers;
+ while (lays) {
+ lay=lays->data;
+ xdisplay_draw_layer(display_list, gra, lay, order);
+ lays=g_list_next(lays);
+ }
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+extern void *route_selection;
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void do_draw_map(struct displaylist *displaylist, struct transformation *t, struct map *m, int order)
+{
+ enum projection pro;
+ struct map_rect *mr;
+ struct item *item;
+ int conv,count,max=16384;
+ struct point pnt[max];
+ struct coord ca[max];
+ struct attr attr;
+ struct map_selection *sel;
+
+ pro=map_projection(m);
+ conv=map_requires_conversion(m);
+ sel=transform_get_selection(t, pro, order);
+ if (route_selection)
+ mr=map_rect_new(m, route_selection);
+ else
+ mr=map_rect_new(m, sel);
+ if (! mr) {
+ map_selection_destroy(sel);
+ return;
+ }
+ while ((item=map_rect_get_item(mr))) {
+ count=item_coord_get(item, ca, item->type < type_line ? 1: max);
+ if (item->type >= type_line && count < 2) {
+ dbg(1,"poly from map has only %d points\n", count);
+ continue;
+ }
+ if (item->type < type_line) {
+ if (! map_selection_contains_point(sel, &ca[0])) {
+ dbg(1,"point not visible\n");
+ continue;
+ }
+ } else if (item->type < type_area) {
+ if (! map_selection_contains_polyline(sel, ca, count)) {
+ dbg(1,"polyline not visible\n");
+ continue;
+ }
+ } else {
+ if (! map_selection_contains_polygon(sel, ca, count)) {
+ dbg(1,"polygon not visible\n");
+ continue;
+ }
+ }
+ if (count == max)
+ dbg(0,"point count overflow\n", count);
+ count=transform(t, pro, ca, pnt, count, 1);
+ if (item->type >= type_line && count < 2) {
+ dbg(1,"poly from transform has only %d points\n", count);
+ continue;
+ }
+ if (!item_attr_get(item, attr_label, &attr))
+ attr.u.str=NULL;
+ if (conv && attr.u.str && attr.u.str[0]) {
+ char *str=map_convert_string(m, attr.u.str);
+ display_add(displaylist, item, count, pnt, str);
+ map_convert_free(str);
+ } else
+ display_add(displaylist, item, count, pnt, attr.u.str);
+ }
+ map_rect_destroy(mr);
+ map_selection_destroy(sel);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void do_draw(struct displaylist *displaylist, struct transformation *t, GList *mapsets, int order)
+{
+ struct mapset *ms;
+ struct map *m;
+ struct mapset_handle *h;
+
+ if (! mapsets)
+ return;
+ ms=mapsets->data;
+ h=mapset_open(ms);
+ while ((m=mapset_next(h, 1))) {
+ do_draw_map(displaylist, t, m, order);
+ }
+ mapset_close(h);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+int graphics_ready(struct graphics *this_)
+{
+ return this_->ready;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_displaylist_draw(struct graphics *gra, struct displaylist *displaylist, struct transformation *trans, struct layout *l)
+{
+ int order=transform_get_order(trans);
+ struct point p;
+ p.x=0;
+ p.y=0;
+ // FIXME find a better place to set the background color
+ graphics_gc_set_background(gra->gc[0], l->color);
+ graphics_gc_set_foreground(gra->gc[0], l->color);
+ gra->meth.background_gc(gra->priv, gra->gc[0]->priv);
+ gra->meth.draw_mode(gra->priv, draw_mode_begin);
+ gra->meth.draw_rectangle(gra->priv, gra->gc[0]->priv, &p, 32767, 32767);
+ xdisplay_draw(displaylist->dl, gra, l, order);
+ gra->meth.draw_mode(gra->priv, draw_mode_end);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_displaylist_move(struct displaylist *displaylist, int dx, int dy)
+{
+ struct displaylist_handle *dlh;
+ struct displayitem *di;
+ int i;
+
+ dlh=graphics_displaylist_open(displaylist);
+ while ((di=graphics_displaylist_next(dlh))) {
+ for (i = 0 ; i < di->count ; i++) {
+ di->pnt[i].x+=dx;
+ di->pnt[i].y+=dy;
+ }
+ }
+ graphics_displaylist_close(dlh);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_draw(struct graphics *gra, struct displaylist *displaylist, GList *mapsets, struct transformation *trans, struct layout *l)
+{
+ int order=transform_get_order(trans);
+
+ dbg(1,"enter");
+
+#if 0
+ printf("scale=%d center=0x%x,0x%x mercator scale=%f\n", scale, co->trans->center.x, co->trans->center.y, transform_scale(co->trans->center.y));
+#endif
+
+ xdisplay_free(displaylist->dl);
+ dbg(1,"order=%d\n", order);
+
+
+#if 0
+ for (i = 0 ; i < data_window_type_end; i++) {
+ data_window_begin(co->data_window[i]);
+ }
+#endif
+ profile(0,NULL);
+ do_draw(displaylist, trans, mapsets, order);
+// profile(1,"do_draw");
+ graphics_displaylist_draw(gra, displaylist, trans, l);
+ profile(1,"xdisplay_draw");
+ profile(0,"end");
+
+#if 0
+ for (i = 0 ; i < data_window_type_end; i++) {
+ data_window_end(co->data_window[i]);
+ }
+#endif
+ gra->ready=1;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct displaylist_handle {
+ GList *hl_head,*hl,*l;
+};
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct displaylist_handle * graphics_displaylist_open(struct displaylist *displaylist)
+{
+ struct displaylist_handle *ret;
+
+ ret=g_new0(struct displaylist_handle, 1);
+ ret->hl_head=ret->hl=g_hash_to_list(displaylist->dl);
+
+ return ret;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct displayitem * graphics_displaylist_next(struct displaylist_handle *dlh)
+{
+ struct displayitem *ret;
+ if (! dlh->l) {
+ if (!dlh->hl)
+ return NULL;
+ dlh->l=dlh->hl->data;
+ dlh->hl=g_list_next(dlh->hl);
+ }
+ ret=dlh->l->data;
+ dlh->l=g_list_next(dlh->l);
+ return ret;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_displaylist_close(struct displaylist_handle *dlh)
+{
+ g_list_free(dlh->hl_head);
+ g_free(dlh);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct displaylist * graphics_displaylist_new(void)
+{
+ struct displaylist *ret=g_new(struct displaylist, 1);
+
+ ret->dl=g_hash_table_new(NULL,NULL);
+
+ return ret;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct item * graphics_displayitem_get_item(struct displayitem *di)
+{
+ return &di->item;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+char * graphics_displayitem_get_label(struct displayitem *di)
+{
+ return di->label;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static int within_dist_point(struct point *p0, struct point *p1, int dist)
+{
+ if (p0->x == 32767 || p0->y == 32767 || p1->x == 32767 || p1->y == 32767)
+ return 0;
+ if (p0->x == -32768 || p0->y == -32768 || p1->x == -32768 || p1->y == -32768)
+ return 0;
+ if ((p0->x-p1->x)*(p0->x-p1->x) + (p0->y-p1->y)*(p0->y-p1->y) <= dist*dist) {
+ return 1;
+ }
+ return 0;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static int within_dist_line(struct point *p, struct point *line_p0, struct point *line_p1, int dist)
+{
+ int vx,vy,wx,wy;
+ int c1,c2;
+ struct point line_p;
+
+ vx=line_p1->x-line_p0->x;
+ vy=line_p1->y-line_p0->y;
+ wx=p->x-line_p0->x;
+ wy=p->y-line_p0->y;
+
+ c1=vx*wx+vy*wy;
+ if ( c1 <= 0 )
+ return within_dist_point(p, line_p0, dist);
+ c2=vx*vx+vy*vy;
+ if ( c2 <= c1 )
+ return within_dist_point(p, line_p1, dist);
+
+ line_p.x=line_p0->x+vx*c1/c2;
+ line_p.y=line_p0->y+vy*c1/c2;
+ return within_dist_point(p, &line_p, dist);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static int within_dist_polyline(struct point *p, struct point *line_pnt, int count, int dist, int close)
+{
+ int i;
+ for (i = 0 ; i < count-1 ; i++) {
+ if (within_dist_line(p,line_pnt+i,line_pnt+i+1,dist)) {
+ return 1;
+ }
+ }
+ if (close)
+ return (within_dist_line(p,line_pnt,line_pnt+count-1,dist));
+ return 0;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static int within_dist_polygon(struct point *p, struct point *poly_pnt, int count, int dist)
+{
+ int i, j, c = 0;
+ for (i = 0, j = count-1; i < count; j = i++) {
+ if ((((poly_pnt[i].y <= p->y) && ( p->y < poly_pnt[j].y )) ||
+ ((poly_pnt[j].y <= p->y) && ( p->y < poly_pnt[i].y))) &&
+ (p->x < (poly_pnt[j].x - poly_pnt[i].x) * (p->y - poly_pnt[i].y) / (poly_pnt[j].y - poly_pnt[i].y) + poly_pnt[i].x))
+ c = !c;
+ }
+ if (! c)
+ return within_dist_polyline(p, poly_pnt, count, dist, 1);
+ return c;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+int graphics_displayitem_within_dist(struct displayitem *di, struct point *p, int dist)
+{
+ if (di->item.type < type_line) {
+ return within_dist_point(p, &di->pnt[0], dist);
+ }
+ if (di->item.type < type_area) {
+ return within_dist_polyline(p, di->pnt, di->count, dist, 0);
+ }
+ return within_dist_polygon(p, di->pnt, di->count, dist);
+}
diff --git a/navit/graphics.h b/navit/graphics.h
new file mode 100644
index 000000000..7983c4b87
--- /dev/null
+++ b/navit/graphics.h
@@ -0,0 +1,146 @@
+#ifndef NAVIT_GRAPHICS_H
+#define NAVIT_GRAPHICS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+struct point;
+struct container;
+struct color;
+struct graphics;
+struct graphics_gc;
+struct graphics_font;
+struct graphics_image;
+struct transformation;
+struct display_list;
+
+enum draw_mode_num {
+ draw_mode_begin, draw_mode_end, draw_mode_cursor
+};
+
+struct graphics_priv;
+struct graphics_font_priv;
+struct graphics_image_priv;
+struct graphics_gc_priv;
+struct graphics_font_methods;
+struct graphics_gc_methods;
+struct graphics_image_methods;
+
+struct graphics_methods {
+ void (*graphics_destroy)(struct graphics_priv *gr);
+ void (*draw_mode)(struct graphics_priv *gr, enum draw_mode_num mode);
+ void (*draw_lines)(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count);
+ void (*draw_polygon)(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count);
+ void (*draw_rectangle)(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int w, int h);
+ void (*draw_circle)(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int r);
+ void (*draw_text)(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct graphics_gc_priv *bg, struct graphics_font_priv *font, char *text, struct point *p, int dx, int dy);
+ void (*draw_image)(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, struct graphics_image_priv *img);
+ void (*draw_image_warp)(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, int count, char *data);
+ void (*draw_restore)(struct graphics_priv *gr, struct point *p, int w, int h);
+ struct graphics_font_priv *(*font_new)(struct graphics_priv *gr, struct graphics_font_methods *meth, int size, int flags);
+ struct graphics_gc_priv *(*gc_new)(struct graphics_priv *gr, struct graphics_gc_methods *meth);
+ void (*background_gc)(struct graphics_priv *gr, struct graphics_gc_priv *gc);
+ struct graphics_priv *(*overlay_new)(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h);
+ struct graphics_image_priv *(*image_new)(struct graphics_priv *gr, struct graphics_image_methods *meth, char *path, int *w, int *h, struct point *hot);
+ void *(*get_data)(struct graphics_priv *gr, char *type);
+ void (*register_resize_callback)(struct graphics_priv *gr, void (*callback)(void *data, int w, int h), void *data);
+ void (*register_button_callback)(struct graphics_priv *gr, void (*callback)(void *data, int pressed, int button, struct point *p), void *data);
+ void (*register_motion_callback)(struct graphics_priv *gr, void (*callback)(void *data, struct point *p), void *data);
+ void (*image_free)(struct graphics_priv *gr, struct graphics_image_priv *priv);
+};
+
+
+struct graphics_font_methods {
+ void (*font_destroy)(struct graphics_font_priv *font);
+};
+
+struct graphics_font {
+ struct graphics_font_priv *priv;
+ struct graphics_font_methods meth;
+};
+
+struct graphics_gc_methods {
+ void (*gc_destroy)(struct graphics_gc_priv *gc);
+ void (*gc_set_linewidth)(struct graphics_gc_priv *gc, int width);
+ void (*gc_set_dashes)(struct graphics_gc_priv *gc, int width, int offset, unsigned char dash_list[], int n);
+ void (*gc_set_foreground)(struct graphics_gc_priv *gc, struct color *c);
+ void (*gc_set_background)(struct graphics_gc_priv *gc, struct color *c);
+};
+
+struct graphics_gc {
+ struct graphics_gc_priv *priv;
+ struct graphics_gc_methods meth;
+};
+
+struct graphics_image_methods {
+ void (*image_destroy)(struct graphics_image_priv *img);
+};
+
+struct graphics_image {
+ struct graphics_image_priv *priv;
+ struct graphics_image_methods meth;
+ int width;
+ int height;
+ struct point hot;
+};
+
+/* prototypes */
+enum attr_type;
+enum draw_mode_num;
+struct attr;
+struct attr_iter;
+struct color;
+struct displayitem;
+struct displaylist;
+struct displaylist_handle;
+struct graphics;
+struct graphics_font;
+struct graphics_gc;
+struct graphics_image;
+struct item;
+struct layout;
+struct point;
+struct transformation;
+struct graphics *graphics_new(struct attr *parent, struct attr **attrs);
+int graphics_get_attr(struct graphics *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter);
+struct graphics *graphics_overlay_new(struct graphics *parent, struct point *p, int w, int h);
+void graphics_init(struct graphics *this_);
+void *graphics_get_data(struct graphics *this_, char *type);
+void graphics_register_resize_callback(struct graphics *this_, void (*callback)(void *data, int w, int h), void *data);
+void graphics_register_button_callback(struct graphics *this_, void (*callback)(void *data, int pressed, int button, struct point *p), void *data);
+void graphics_register_motion_callback(struct graphics *this_, void (*callback)(void *data, struct point *p), void *data);
+struct graphics_font *graphics_font_new(struct graphics *gra, int size, int flags);
+struct graphics_gc *graphics_gc_new(struct graphics *gra);
+void graphics_gc_destroy(struct graphics_gc *gc);
+void graphics_gc_set_foreground(struct graphics_gc *gc, struct color *c);
+void graphics_gc_set_background(struct graphics_gc *gc, struct color *c);
+void graphics_gc_set_linewidth(struct graphics_gc *gc, int width);
+void graphics_gc_set_dashes(struct graphics_gc *gc, int width, int offset, unsigned char dash_list[], int n);
+struct graphics_image *graphics_image_new(struct graphics *gra, char *path);
+void graphics_image_free(struct graphics *gra, struct graphics_image *img);
+void graphics_draw_restore(struct graphics *this_, struct point *p, int w, int h);
+void graphics_draw_mode(struct graphics *this_, enum draw_mode_num mode);
+void graphics_draw_lines(struct graphics *this_, struct graphics_gc *gc, struct point *p, int count);
+void graphics_draw_circle(struct graphics *this_, struct graphics_gc *gc, struct point *p, int r);
+void graphics_draw_rectangle(struct graphics *this_, struct graphics_gc *gc, struct point *p, int w, int h);
+void graphics_draw_text(struct graphics *this_, struct graphics_gc *gc1, struct graphics_gc *gc2, struct graphics_font *font, char *text, struct point *p, int dx, int dy);
+void graphics_draw_image(struct graphics *this_, struct graphics_gc *gc, struct point *p, struct graphics_image *img);
+void display_add(struct displaylist *displaylist, struct item *item, int count, struct point *pnt, char *label);
+int graphics_ready(struct graphics *this_);
+void graphics_displaylist_draw(struct graphics *gra, struct displaylist *displaylist, struct transformation *trans, struct layout *l);
+void graphics_displaylist_move(struct displaylist *displaylist, int dx, int dy);
+void graphics_draw(struct graphics *gra, struct displaylist *displaylist, GList *mapsets, struct transformation *trans, struct layout *l);
+struct displaylist_handle *graphics_displaylist_open(struct displaylist *displaylist);
+struct displayitem *graphics_displaylist_next(struct displaylist_handle *dlh);
+void graphics_displaylist_close(struct displaylist_handle *dlh);
+struct displaylist *graphics_displaylist_new(void);
+struct item *graphics_displayitem_get_item(struct displayitem *di);
+char *graphics_displayitem_get_label(struct displayitem *di);
+int graphics_displayitem_within_dist(struct displayitem *di, struct point *p, int dist);
+/* end of prototypes */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/navit/graphics/Makefile.am b/navit/graphics/Makefile.am
new file mode 100644
index 000000000..22bbc6ef2
--- /dev/null
+++ b/navit/graphics/Makefile.am
@@ -0,0 +1,10 @@
+SUBDIRS=null
+if GRAPHICS_GTK_DRAWING_AREA
+ SUBDIRS+=gtk_drawing_area
+endif
+if GRAPHICS_OPENGL
+ SUBDIRS+=opengl
+endif
+if USE_GRAPHICS_QT_QPAINTER
+ SUBDIRS+=qt_qpainter
+endif
diff --git a/navit/graphics/gtk_drawing_area/Makefile.am b/navit/graphics/gtk_drawing_area/Makefile.am
new file mode 100644
index 000000000..bb0ef0972
--- /dev/null
+++ b/navit/graphics/gtk_drawing_area/Makefile.am
@@ -0,0 +1,5 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @GTK2_CFLAGS@ @FREETYPE2_CFLAGS@ @FONTCONFIG_CFLAGS@ -I$(top_srcdir)/src -DMODULE=graphics_gtk_drawing_area
+modulegraphics_LTLIBRARIES = libgraphics_gtk_drawing_area.la
+libgraphics_gtk_drawing_area_la_SOURCES = graphics_gtk_drawing_area.c
+libgraphics_gtk_drawing_area_la_LDFLAGS = @GTK2_LIBS@ @FREETYPE2_LIBS@ @FONTCONFIG_LIBS@ @IMLIB2_LIBS@
diff --git a/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c b/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c
new file mode 100644
index 000000000..90d7ddd6c
--- /dev/null
+++ b/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c
@@ -0,0 +1,916 @@
+#define GDK_ENABLE_BROKEN
+#include "config.h"
+#include <gtk/gtk.h>
+#include <fontconfig/fontconfig.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#ifdef HAVE_IMLIB2
+#include <Imlib2.h>
+#endif
+
+#ifndef _WIN32
+#include <gdk/gdkx.h>
+#endif
+#include "debug.h"
+#include "point.h"
+#include "graphics.h"
+#include "color.h"
+#include "plugin.h"
+
+struct graphics_priv {
+ GdkEventButton button_event;
+ int button_timeout;
+ GtkWidget *widget;
+ GtkWidget *win;
+ GdkDrawable *drawable;
+ GdkDrawable *background;
+ int background_ready;
+ GdkColormap *colormap;
+ FT_Library library;
+ struct point p;
+ int width;
+ int height;
+ int library_init;
+ int visible;
+ struct graphics_priv *parent;
+ struct graphics_priv *overlays;
+ struct graphics_priv *next;
+ struct graphics_gc_priv *background_gc;
+ enum draw_mode_num mode;
+ void (*resize_callback)(void *data, int w, int h);
+ void *resize_callback_data;
+ void (*motion_callback)(void *data, struct point *p);
+ void *motion_callback_data;
+ void (*button_callback)(void *data, int press, int button, struct point *p);
+ void *button_callback_data;
+};
+
+struct graphics_font_priv {
+ FT_Face face;
+};
+
+struct graphics_gc_priv {
+ GdkGC *gc;
+ struct graphics_priv *gr;
+};
+
+struct graphics_image_priv {
+ GdkPixbuf *pixbuf;
+ int w;
+ int h;
+};
+
+static void
+graphics_destroy(struct graphics_priv *gr)
+{
+ FcFini();
+}
+
+/**
+ * List of font families to use, in order of preference
+ */
+static char *fontfamilies[]={
+ "Liberation Mono",
+ "Arial",
+ "DejaVu Sans",
+ "NcrBI4nh",
+ "luximbi",
+ "FreeSans",
+ NULL,
+};
+
+static void font_destroy(struct graphics_font_priv *font)
+{
+ g_free(font);
+ /* TODO: free font->face */
+}
+
+static struct graphics_font_methods font_methods = {
+ font_destroy
+};
+
+/**
+ * Load a new font using the fontconfig library.
+ * First search for each of the font families and require and exact match on family
+ * If no font found, let fontconfig pick the best match
+ */
+static struct graphics_font_priv *font_new(struct graphics_priv *gr, struct graphics_font_methods *meth, int size, int flags)
+{
+ struct graphics_font_priv *font=g_new(struct graphics_font_priv, 1);
+
+ *meth=font_methods;
+ int exact, found;
+ char **family;
+
+ if (!gr->library_init) {
+ FT_Init_FreeType( &gr->library );
+ gr->library_init=1;
+ }
+ found=0;
+ for (exact=1;!found && exact>=0;exact--) {
+ family=fontfamilies;
+ while (*family && !found) {
+ dbg(1, "Looking for font family %s. exact=%d\n", *family, exact);
+ FcPattern *required = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, *family, NULL);
+ if (flags)
+ FcPatternAddInteger(required,FC_WEIGHT,FC_WEIGHT_BOLD);
+ FcConfigSubstitute(FcConfigGetCurrent(), required, FcMatchFont);
+ FcDefaultSubstitute(required);
+ FcResult result;
+ FcPattern *matched = FcFontMatch(FcConfigGetCurrent(), required, &result);
+ if (matched) {
+ FcValue v1, v2;
+ FcChar8 *fontfile;
+ int fontindex;
+ FcPatternGet(required, FC_FAMILY, 0, &v1);
+ FcPatternGet(matched, FC_FAMILY, 0, &v2);
+ FcResult r1 = FcPatternGetString(matched, FC_FILE, 0, &fontfile);
+ FcResult r2 = FcPatternGetInteger(matched, FC_INDEX, 0, &fontindex);
+ if ((r1 == FcResultMatch) && (r2 == FcResultMatch) && (FcValueEqual(v1,v2) || !exact)) {
+ dbg(2, "About to load font from file %s index %d\n", fontfile, fontindex);
+ FT_New_Face( gr->library, (char *)fontfile, fontindex, &font->face );
+ found=1;
+ }
+ FcPatternDestroy(matched);
+ }
+ FcPatternDestroy(required);
+ family++;
+ }
+ }
+ if (!found) {
+ g_warning("Failed to load font, no labelling");
+ g_free(font);
+ return NULL;
+ }
+ FT_Set_Char_Size(font->face, 0, size, 300, 300);
+ FT_Select_Charmap(font->face, FT_ENCODING_UNICODE);
+ return font;
+}
+
+static void
+gc_destroy(struct graphics_gc_priv *gc)
+{
+ g_object_unref(gc->gc);
+ g_free(gc);
+}
+
+static void
+gc_set_linewidth(struct graphics_gc_priv *gc, int w)
+{
+ gdk_gc_set_line_attributes(gc->gc, w, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+}
+
+static void
+gc_set_dashes(struct graphics_gc_priv *gc, int w, int offset, unsigned char *dash_list, int n)
+{
+ gdk_gc_set_dashes(gc->gc, offset, (gint8 *)dash_list, n);
+ gdk_gc_set_line_attributes(gc->gc, w, GDK_LINE_ON_OFF_DASH, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+}
+
+static void
+gc_set_color(struct graphics_gc_priv *gc, struct color *c, int fg)
+{
+ GdkColor gdkc;
+ gdkc.pixel=0;
+ gdkc.red=c->r;
+ gdkc.green=c->g;
+ gdkc.blue=c->b;
+ gdk_colormap_alloc_color(gc->gr->colormap, &gdkc, FALSE, TRUE);
+ if (fg)
+ gdk_gc_set_foreground(gc->gc, &gdkc);
+ else
+ gdk_gc_set_background(gc->gc, &gdkc);
+}
+
+static void
+gc_set_foreground(struct graphics_gc_priv *gc, struct color *c)
+{
+ gc_set_color(gc, c, 1);
+}
+
+static void
+gc_set_background(struct graphics_gc_priv *gc, struct color *c)
+{
+ gc_set_color(gc, c, 0);
+}
+
+static struct graphics_gc_methods gc_methods = {
+ gc_destroy,
+ gc_set_linewidth,
+ gc_set_dashes,
+ gc_set_foreground,
+ gc_set_background
+};
+
+static struct graphics_gc_priv *gc_new(struct graphics_priv *gr, struct graphics_gc_methods *meth)
+{
+ struct graphics_gc_priv *gc=g_new(struct graphics_gc_priv, 1);
+
+ *meth=gc_methods;
+ gc->gc=gdk_gc_new(gr->widget->window);
+ gc->gr=gr;
+ return gc;
+}
+
+
+static struct graphics_image_priv *
+image_new(struct graphics_priv *gr, struct graphics_image_methods *meth, char *name, int *w, int *h, struct point *hot)
+{
+ GdkPixbuf *pixbuf;
+ struct graphics_image_priv *ret;
+ const char *option;
+
+ pixbuf=gdk_pixbuf_new_from_file(name, NULL);
+ if (! pixbuf)
+ return NULL;
+ ret=g_new0(struct graphics_image_priv, 1);
+ ret->pixbuf=pixbuf;
+ ret->w=gdk_pixbuf_get_width(pixbuf);
+ ret->h=gdk_pixbuf_get_height(pixbuf);
+ *w=ret->w;
+ *h=ret->h;
+ if (hot) {
+ option=gdk_pixbuf_get_option(pixbuf, "x_hot");
+ if (option)
+ hot->x=atoi(option);
+ else
+ hot->x=ret->w/2-1;
+ option=gdk_pixbuf_get_option(pixbuf, "y_hot");
+ if (option)
+ hot->y=atoi(option);
+ else
+ hot->y=ret->h/2-1;
+ }
+ return ret;
+}
+
+static void
+image_free(struct graphics_priv *gr, struct graphics_image_priv *priv)
+{
+ if (priv->pixbuf)
+ g_object_unref(priv->pixbuf);
+ g_free(priv);
+}
+
+static void
+draw_lines(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
+{
+ if (gr->mode == draw_mode_begin || gr->mode == draw_mode_end)
+ gdk_draw_lines(gr->drawable, gc->gc, (GdkPoint *)p, count);
+ if (gr->mode == draw_mode_end || gr->mode == draw_mode_cursor)
+ gdk_draw_lines(gr->widget->window, gc->gc, (GdkPoint *)p, count);
+}
+
+static void
+draw_polygon(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
+{
+ if (gr->mode == draw_mode_begin || gr->mode == draw_mode_end)
+ gdk_draw_polygon(gr->drawable, gc->gc, TRUE, (GdkPoint *)p, count);
+ if (gr->mode == draw_mode_end || gr->mode == draw_mode_cursor)
+ gdk_draw_polygon(gr->widget->window, gc->gc, TRUE, (GdkPoint *)p, count);
+}
+
+static void
+draw_rectangle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int w, int h)
+{
+ gdk_draw_rectangle(gr->drawable, gc->gc, TRUE, p->x, p->y, w, h);
+}
+
+static void
+draw_circle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int r)
+{
+ if (gr->mode == draw_mode_begin || gr->mode == draw_mode_end)
+ gdk_draw_arc(gr->drawable, gc->gc, FALSE, p->x-r/2, p->y-r/2, r, r, 0, 64*360);
+ if (gr->mode == draw_mode_end || gr->mode == draw_mode_cursor)
+ gdk_draw_arc(gr->widget->window, gc->gc, FALSE, p->x-r/2, p->y-r/2, r, r, 0, 64*360);
+}
+
+
+struct text_glyph {
+ int x,y,w,h;
+ GdkImage *shadow;
+ unsigned char pixmap[0];
+};
+
+struct text_render {
+ int x1,y1;
+ int x2,y2;
+ int x3,y3;
+ int x4,y4;
+ int glyph_count;
+ struct text_glyph *glyph[0];
+};
+
+#ifndef _WIN32
+static GdkImage *
+display_text_render_shadow(struct text_glyph *g)
+{
+ int mask0, mask1, mask2, x, y, w=g->w, h=g->h;
+ int str=(g->w+9)/8;
+ unsigned char *shadow;
+ unsigned char *p, *pm=g->pixmap;
+ GdkImage *ret;
+
+ shadow=malloc(str*(g->h+2)); /* do not use g_malloc() here */
+ memset(shadow, 0, str*(g->h+2));
+ for (y = 0 ; y < h ; y++) {
+ p=shadow+str*y;
+ mask0=0x4000;
+ mask1=0xe000;
+ mask2=0x4000;
+ for (x = 0 ; x < w ; x++) {
+ if (pm[x+y*w]) {
+ p[0]|=(mask0 >> 8);
+ if (mask0 & 0xff)
+ p[1]|=mask0;
+
+ p[str]|=(mask1 >> 8);
+ if (mask1 & 0xff)
+ p[str+1]|=mask1;
+ p[str*2]|=(mask2 >> 8);
+ if (mask2 & 0xff)
+ p[str*2+1]|=mask2;
+ }
+ mask0 >>= 1;
+ mask1 >>= 1;
+ mask2 >>= 1;
+ if (!((mask0 >> 8) | (mask1 >> 8) | (mask2 >> 8))) {
+ mask0<<=8;
+ mask1<<=8;
+ mask2<<=8;
+ p++;
+ }
+ }
+ }
+ ret=gdk_image_new_bitmap(gdk_visual_get_system(), shadow, g->w+2, g->h+2);
+ return ret;
+}
+#else
+static GdkImage *
+display_text_render_shadow(struct text_glyph *g)
+{
+ int mask0, mask1, mask2, x, y, w=g->w, h=g->h;
+ int str=(g->w+9)/8;
+ unsigned char *p, *pm=g->pixmap;
+ GdkImage *ret;
+
+ ret=gdk_image_new( GDK_IMAGE_NORMAL , gdk_visual_get_system(), w+2, h+2);
+
+ for (y = 0 ; y < h ; y++) {
+ p=ret->mem+str*y;
+
+ mask0=0x4000;
+ mask1=0xe000;
+ mask2=0x4000;
+ for (x = 0 ; x < w ; x++) {
+ if (pm[x+y*w]) {
+ p[0]|=(mask0 >> 8);
+ if (mask0 & 0xff)
+ p[1]|=mask0;
+
+ p[str]|=(mask1 >> 8);
+ if (mask1 & 0xff)
+ p[str+1]|=mask1;
+ p[str*2]|=(mask2 >> 8);
+ if (mask2 & 0xff)
+ p[str*2+1]|=mask2;
+ }
+ mask0 >>= 1;
+ mask1 >>= 1;
+ mask2 >>= 1;
+ if (!((mask0 >> 8) | (mask1 >> 8) | (mask2 >> 8))) {
+ mask0<<=8;
+ mask1<<=8;
+ mask2<<=8;
+ }
+ }
+ }
+ return ret;
+}
+#endif
+
+static struct text_render *
+display_text_render(char *text, struct graphics_font_priv *font, int dx, int dy, int x, int y)
+{
+ FT_GlyphSlot slot = font->face->glyph; // a small shortcut
+ FT_Matrix matrix;
+ FT_Vector pen;
+ FT_UInt glyph_index;
+ int n,len;
+ struct text_render *ret;
+ struct text_glyph *curr;
+ char *p=text;
+
+ len=g_utf8_strlen(text, -1);
+ ret=g_malloc(sizeof(*ret)+len*sizeof(struct text_glyph *));
+ ret->glyph_count=len;
+
+ matrix.xx = dx;
+ matrix.xy = dy;
+ matrix.yx = -dy;
+ matrix.yy = dx;
+
+ pen.x = 0 * 64;
+ pen.y = 0 * 64;
+ x <<= 6;
+ y <<= 6;
+ FT_Set_Transform( font->face, &matrix, &pen );
+
+ for ( n = 0; n < len; n++ )
+ {
+
+ glyph_index = FT_Get_Char_Index(font->face, g_utf8_get_char(p));
+ FT_Load_Glyph(font->face, glyph_index, FT_LOAD_DEFAULT );
+ FT_Render_Glyph(font->face->glyph, ft_render_mode_normal );
+
+ curr=g_malloc(sizeof(*curr)+slot->bitmap.rows*slot->bitmap.pitch);
+ ret->glyph[n]=curr;
+
+ curr->x=(x>>6)+slot->bitmap_left;
+ curr->y=(y>>6)-slot->bitmap_top;
+ curr->w=slot->bitmap.width;
+ curr->h=slot->bitmap.rows;
+ if (slot->bitmap.width && slot->bitmap.rows) {
+ memcpy(curr->pixmap, slot->bitmap.buffer, slot->bitmap.rows*slot->bitmap.pitch);
+ curr->shadow=display_text_render_shadow(curr);
+ }
+ else
+ curr->shadow=NULL;
+#if 0
+ printf("height=%d\n", slot->metrics.height);
+ printf("height2=%d\n", face->height);
+ printf("bbox %d %d %d %d\n", face->bbox.xMin, face->bbox.yMin, face->bbox.xMax, face->bbox.yMax);
+#endif
+ x += slot->advance.x;
+ y -= slot->advance.y;
+ p=g_utf8_next_char(p);
+ }
+ return ret;
+}
+
+static void
+display_text_draw(struct text_render *text, struct graphics_priv *gr, struct graphics_gc_priv *fg, struct graphics_gc_priv *bg)
+{
+ int i;
+ struct text_glyph *g, **gp;
+
+ gp=text->glyph;
+ i=text->glyph_count;
+ while (i-- > 0)
+ {
+ g=*gp++;
+ if (g->shadow && bg)
+ gdk_draw_image(gr->drawable, bg->gc, g->shadow, 0, 0, g->x-1, g->y-1, g->w+2, g->h+2);
+ }
+ gp=text->glyph;
+ i=text->glyph_count;
+ while (i-- > 0)
+ {
+ g=*gp++;
+ if (g->w && g->h)
+ gdk_draw_gray_image(gr->drawable, fg->gc, g->x, g->y, g->w, g->h, GDK_RGB_DITHER_NONE, g->pixmap, g->w);
+ }
+}
+
+static void
+display_text_free(struct text_render *text)
+{
+ int i;
+ struct text_glyph **gp;
+
+ gp=text->glyph;
+ i=text->glyph_count;
+ while (i-- > 0) {
+ if ((*gp)->shadow) {
+ g_object_unref((*gp)->shadow);
+ }
+ g_free(*gp++);
+ }
+ g_free(text);
+}
+
+static void
+draw_text(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct graphics_gc_priv *bg, struct graphics_font_priv *font, char *text, struct point *p, int dx, int dy)
+{
+ struct text_render *t;
+
+ if (! font)
+ return;
+ if (bg) {
+ gdk_gc_set_function(fg->gc, GDK_AND_INVERT);
+ gdk_gc_set_function(bg->gc, GDK_OR);
+ }
+
+ t=display_text_render(text, font, dx, dy, p->x, p->y);
+ display_text_draw(t, gr, fg, bg);
+ display_text_free(t);
+ if (bg) {
+ gdk_gc_set_function(fg->gc, GDK_COPY);
+ gdk_gc_set_function(bg->gc, GDK_COPY);
+ }
+}
+
+static void
+draw_image(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, struct graphics_image_priv *img)
+{
+ gdk_draw_pixbuf(gr->drawable, fg->gc, img->pixbuf, 0, 0, p->x, p->y,
+ img->w, img->h, GDK_RGB_DITHER_NONE, 0, 0);
+}
+
+#ifdef HAVE_IMLIB2
+static void
+draw_image_warp(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, int count, char *data)
+{
+ void *image;
+ int w,h;
+ dbg(1,"draw_image_warp data=%s\n", data);
+ image = imlib_load_image(data);
+ imlib_context_set_display(gdk_x11_drawable_get_xdisplay(gr->widget->window));
+ imlib_context_set_colormap(gdk_x11_colormap_get_xcolormap(gtk_widget_get_colormap(gr->widget)));
+ imlib_context_set_visual(gdk_x11_visual_get_xvisual(gtk_widget_get_visual(gr->widget)));
+ imlib_context_set_drawable(gdk_x11_drawable_get_xid(gr->drawable));
+ imlib_context_set_image(image);
+ w = imlib_image_get_width();
+ h = imlib_image_get_height();
+ if (count == 3) {
+ /* 0 1
+ 2 */
+ imlib_render_image_on_drawable_skewed(0, 0, w, h, p[0].x, p[0].y, p[1].x-p[0].x, p[1].y-p[0].y, p[2].x-p[0].x, p[2].y-p[0].y);
+ }
+ if (count == 2) {
+ /* 0
+ 1 */
+ imlib_render_image_on_drawable_skewed(0, 0, w, h, p[0].x, p[0].y, p[1].x-p[0].x, 0, 0, p[1].y-p[0].y);
+ }
+ if (count == 1) {
+ /*
+ 0
+ */
+ imlib_render_image_on_drawable_skewed(0, 0, w, h, p[0].x-w/2, p[0].y-h/2, w, 0, 0, h);
+ }
+}
+#endif
+
+static void
+overlay_draw(struct graphics_priv *parent, struct graphics_priv *overlay, int window)
+{
+ GdkPixbuf *pixbuf,*pixbuf2;
+ GtkWidget *widget=parent->widget;
+ guchar *pixels1, *pixels2, *p1, *p2;
+ int x,y,w,h;
+ int rowstride1,rowstride2;
+ int n_channels1,n_channels2;
+
+ if (! parent->drawable)
+ return;
+
+ w=overlay->width;
+ if (w < 0)
+ w+=parent->width;
+ h=overlay->height;
+ if (h < 0)
+ h+=parent->height;
+ pixbuf=gdk_pixbuf_get_from_drawable(NULL, overlay->drawable, NULL, 0, 0, 0, 0, w, h);
+ pixbuf2=gdk_pixbuf_new(gdk_pixbuf_get_colorspace(pixbuf), TRUE, gdk_pixbuf_get_bits_per_sample(pixbuf),
+ gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf));
+
+ rowstride1 = gdk_pixbuf_get_rowstride (pixbuf);
+ rowstride2 = gdk_pixbuf_get_rowstride (pixbuf2);
+ pixels1=gdk_pixbuf_get_pixels (pixbuf);
+ pixels2=gdk_pixbuf_get_pixels (pixbuf2);
+ n_channels1 = gdk_pixbuf_get_n_channels (pixbuf);
+ n_channels2 = gdk_pixbuf_get_n_channels (pixbuf2);
+ for (y = 0 ; y < h ; y++) {
+ for (x = 0 ; x < w ; x++) {
+ p1 = pixels1 + y * rowstride1 + x * n_channels1;
+ p2 = pixels2 + y * rowstride2 + x * n_channels2;
+ p2[0]=p1[0];
+ p2[1]=p1[1];
+ p2[2]=p1[2];
+ p2[3]=127;
+ }
+ }
+ x=overlay->p.x;
+ if (x < 0)
+ x+=parent->width;
+ y=overlay->p.y;
+ if (y < 0)
+ y+=parent->height;
+ if (window) {
+ if (overlay->background_ready)
+ gdk_draw_drawable(parent->drawable, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], overlay->background, 0, 0, x, y, w, h);
+ }
+ else {
+ gdk_draw_drawable(overlay->background, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], parent->drawable, x, y, 0, 0, w, h);
+ overlay->background_ready=1;
+ }
+ gdk_draw_pixbuf(parent->drawable, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], pixbuf2, 0, 0, x, y, w, h, GDK_RGB_DITHER_NONE, 0, 0);
+ if (window)
+ gdk_draw_drawable(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], parent->drawable, x, y, x, y, w, h);
+ g_object_unref(pixbuf);
+ g_object_unref(pixbuf2);
+#if 0
+ gdk_draw_drawable(gr->gra->drawable,
+ gr->gra->widget->style->fg_gc[GTK_WIDGET_STATE(gr->gra->widget)],
+ img->gra->drawable,
+ 0, 0, p->x, p->y, img->gra->width, img->gra->height);
+#endif
+}
+
+static void
+draw_restore(struct graphics_priv *gr, struct point *p, int w, int h)
+{
+ GtkWidget *widget=gr->widget;
+ gdk_draw_drawable(widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+ gr->drawable,
+ p->x, p->y, p->x, p->y, w, h);
+
+}
+
+static void
+background_gc(struct graphics_priv *gr, struct graphics_gc_priv *gc)
+{
+ gr->background_gc=gc;
+}
+
+static void
+draw_mode(struct graphics_priv *gr, enum draw_mode_num mode)
+{
+ struct graphics_priv *overlay;
+ GtkWidget *widget=gr->widget;
+
+#if 0
+ if (mode == draw_mode_begin) {
+ if (! gr->parent && gr->background_gc)
+ gdk_draw_rectangle(gr->drawable, gr->background_gc->gc, TRUE, 0, 0, gr->width, gr->height);
+ }
+#endif
+ if (mode == draw_mode_end && gr->mode == draw_mode_begin) {
+ if (gr->parent) {
+ overlay_draw(gr->parent, gr, 1);
+ } else {
+ overlay=gr->overlays;
+ while (overlay) {
+ overlay_draw(gr, overlay, 0);
+ overlay=overlay->next;
+ }
+ gdk_draw_drawable(widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+ gr->drawable,
+ 0, 0, 0, 0, gr->width, gr->height);
+ }
+ }
+ gr->mode=mode;
+}
+
+/* Events */
+
+static gint
+configure(GtkWidget * widget, GdkEventConfigure * event, gpointer user_data)
+{
+ struct graphics_priv *gra=user_data;
+ if (! gra->visible)
+ return TRUE;
+ if (gra->drawable != NULL) {
+ g_object_unref(gra->drawable);
+ }
+ gra->width=widget->allocation.width;
+ gra->height=widget->allocation.height;
+ gra->drawable = gdk_pixmap_new(widget->window, gra->width, gra->height, -1);
+ if (gra->resize_callback)
+ (*gra->resize_callback)(gra->resize_callback_data, gra->width, gra->height);
+ return TRUE;
+}
+
+static gint
+expose(GtkWidget * widget, GdkEventExpose * event, gpointer user_data)
+{
+ struct graphics_priv *gra=user_data;
+
+ gra->visible=1;
+ if (! gra->drawable)
+ configure(widget, NULL, user_data);
+ gdk_draw_drawable(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+ gra->drawable, event->area.x, event->area.y,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
+
+ return FALSE;
+}
+
+#if 0
+static gint
+button_timeout(gpointer user_data)
+{
+#if 0
+ struct container *co=user_data;
+ int x=co->gra->gra->button_event.x;
+ int y=co->gra->gra->button_event.y;
+ int button=co->gra->gra->button_event.button;
+
+ co->gra->gra->button_timeout=0;
+ popup(co, x, y, button);
+
+ return FALSE;
+#endif
+}
+#endif
+
+static gint
+button_press(GtkWidget * widget, GdkEventButton * event, gpointer user_data)
+{
+ struct graphics_priv *this=user_data;
+ struct point p;
+
+ p.x=event->x;
+ p.y=event->y;
+ if (this->button_callback)
+ (*this->button_callback)(this->button_callback_data, 1, event->button, &p);
+ return FALSE;
+}
+
+static gint
+button_release(GtkWidget * widget, GdkEventButton * event, gpointer user_data)
+{
+ struct graphics_priv *this=user_data;
+ struct point p;
+
+ p.x=event->x;
+ p.y=event->y;
+ if (this->button_callback)
+ (*this->button_callback)(this->button_callback_data, 0, event->button, &p);
+ return FALSE;
+}
+
+static gint
+scroll(GtkWidget * widget, GdkEventScroll * event, gpointer user_data)
+{
+ struct graphics_priv *this=user_data;
+ struct point p;
+ int button;
+
+ p.x=event->x;
+ p.y=event->y;
+ if (this->button_callback) {
+ switch (event->direction) {
+ case GDK_SCROLL_UP:
+ button=4;
+ break;
+ case GDK_SCROLL_DOWN:
+ button=5;
+ break;
+ default:
+ button=-1;
+ break;
+ }
+ if (button != -1) {
+ (*this->button_callback)(this->button_callback_data, 1, button, &p);
+ (*this->button_callback)(this->button_callback_data, 0, button, &p);
+ }
+ }
+ return FALSE;
+}
+
+static gint
+motion_notify(GtkWidget * widget, GdkEventMotion * event, gpointer user_data)
+{
+ struct graphics_priv *this=user_data;
+ struct point p;
+
+ p.x=event->x;
+ p.y=event->y;
+ if (this->motion_callback)
+ (*this->motion_callback)(this->motion_callback_data, &p);
+ return FALSE;
+}
+
+static struct graphics_priv *graphics_gtk_drawing_area_new_helper(struct graphics_methods *meth);
+
+static struct graphics_priv *
+overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h)
+{
+ struct graphics_priv *this=graphics_gtk_drawing_area_new_helper(meth);
+ this->drawable=gdk_pixmap_new(gr->widget->window, w, h, -1);
+ this->colormap=gr->colormap;
+ this->widget=gr->widget;
+ this->p=*p;
+ this->width=w;
+ this->height=h;
+ this->parent=gr;
+ this->background=gdk_pixmap_new(gr->widget->window, w, h, -1);
+ this->next=gr->overlays;
+ gr->overlays=this;
+ return this;
+}
+
+static int gtk_argc;
+static char **gtk_argv={NULL};
+
+
+static void *
+get_data(struct graphics_priv *this, char *type)
+{
+ if (!strcmp(type,"gtk_widget"))
+ return this->widget;
+ if (!strcmp(type,"window")) {
+ gtk_init(&gtk_argc, &gtk_argv);
+ gtk_set_locale();
+ this->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_default_size(GTK_WINDOW(this->win), 792, 547);
+ gtk_window_set_title(GTK_WINDOW(this->win), "Navit");
+ gtk_widget_realize(this->win);
+ gtk_container_add(GTK_CONTAINER(this->win), this->widget);
+ gtk_widget_show_all(this->win);
+ return this->win;
+ }
+ return NULL;
+}
+
+static void
+register_resize_callback(struct graphics_priv *this, void (*callback)(void *data, int w, int h), void *data)
+{
+ this->resize_callback=callback;
+ this->resize_callback_data=data;
+}
+
+static void
+register_motion_callback(struct graphics_priv *this, void (*callback)(void *data, struct point *p), void *data)
+{
+ this->motion_callback=callback;
+ this->motion_callback_data=data;
+}
+
+static void
+register_button_callback(struct graphics_priv *this, void (*callback)(void *data, int press, int button, struct point *p), void *data)
+{
+ this->button_callback=callback;
+ this->button_callback_data=data;
+}
+
+static struct graphics_methods graphics_methods = {
+ graphics_destroy,
+ draw_mode,
+ draw_lines,
+ draw_polygon,
+ draw_rectangle,
+ draw_circle,
+ draw_text,
+ draw_image,
+#ifdef HAVE_IMLIB2
+ draw_image_warp,
+#else
+ NULL,
+#endif
+ draw_restore,
+ font_new,
+ gc_new,
+ background_gc,
+ overlay_new,
+ image_new,
+ get_data,
+ register_resize_callback,
+ register_button_callback,
+ register_motion_callback,
+ image_free,
+};
+
+static struct graphics_priv *
+graphics_gtk_drawing_area_new_helper(struct graphics_methods *meth)
+{
+ struct graphics_priv *this=g_new0(struct graphics_priv,1);
+ *meth=graphics_methods;
+
+ return this;
+}
+
+static struct graphics_priv *
+graphics_gtk_drawing_area_new(struct graphics_methods *meth, struct attr **attrs)
+{
+ GtkWidget *draw;
+
+ draw=gtk_drawing_area_new();
+ struct graphics_priv *this=graphics_gtk_drawing_area_new_helper(meth);
+ this->widget=draw;
+
+ this->colormap=gdk_colormap_new(gdk_visual_get_system(),FALSE);
+ gtk_widget_set_events(draw, GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK|GDK_POINTER_MOTION_MASK|GDK_KEY_PRESS_MASK);
+ g_signal_connect(G_OBJECT(draw), "expose_event", G_CALLBACK(expose), this);
+ g_signal_connect(G_OBJECT(draw), "configure_event", G_CALLBACK(configure), this);
+#if 0
+ g_signal_connect(G_OBJECT(draw), "realize_event", G_CALLBACK(realize), co);
+#endif
+ g_signal_connect(G_OBJECT(draw), "button_press_event", G_CALLBACK(button_press), this);
+ g_signal_connect(G_OBJECT(draw), "button_release_event", G_CALLBACK(button_release), this);
+ g_signal_connect(G_OBJECT(draw), "scroll_event", G_CALLBACK(scroll), this);
+ g_signal_connect(G_OBJECT(draw), "motion_notify_event", G_CALLBACK(motion_notify), this);
+ if (FcInit() != FcTrue)
+ dbg(0, "Failed to init fontconfig");
+ return this;
+}
+
+void
+plugin_init(void)
+{
+ plugin_register_graphics_type("gtk_drawing_area", graphics_gtk_drawing_area_new);
+}
diff --git a/navit/graphics/gtk_gl_ext/graphics_gtk_gl_ext.c b/navit/graphics/gtk_gl_ext/graphics_gtk_gl_ext.c
new file mode 100644
index 000000000..c91e94c63
--- /dev/null
+++ b/navit/graphics/gtk_gl_ext/graphics_gtk_gl_ext.c
@@ -0,0 +1,333 @@
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <gtk/gtkgl.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include "point.h"
+#include "graphics.h"
+#include "container.h"
+
+
+struct graphics_gra {
+ GtkWidget *widget;
+ int width;
+ int height;
+ int library_init;
+ int visible;
+ int buffer;
+};
+
+struct graphics_font {
+};
+
+struct graphics_gc {
+ double fr,fg,fb;
+ double br,bg,bb;
+ double width;
+ struct graphics_gra *gra;
+};
+
+static struct graphics_font *font_new(struct graphics *gr, int size)
+{
+ struct graphics_font *font=g_new(struct graphics_font, 1);
+ return font;
+}
+
+static struct graphics_gc *gc_new(struct graphics *gr)
+{
+ struct graphics_gc *gc=g_new(struct graphics_gc, 1);
+
+ gc->fr=1;
+ gc->fg=1;
+ gc->fb=1;
+ gc->br=0;
+ gc->bg=0;
+ gc->bb=0;
+ gc->width=1;
+ gc->gra=gr->gra;
+ return gc;
+}
+
+static void
+gc_set_linewidth(struct graphics_gc *gc, int w)
+{
+ gc->width=w;
+}
+
+static void
+gc_set_foreground(struct graphics_gc *gc, int r, int g, int b)
+{
+ gc->fr=r/65535.0;
+ gc->fg=g/65535.0;
+ gc->fb=b/65535.0;
+}
+
+static void
+gc_set_background(struct graphics_gc *gc, int r, int g, int b)
+{
+ gc->br=r/65535.0;
+ gc->bg=g/65535.0;
+ gc->bb=b/65535.0;
+}
+
+static void
+vertex(struct point *p)
+{
+ double x,y;
+ x=p->x;
+ y=p->y;
+ x/=792;
+ y/=469;
+ x-=0.5;
+ y=0.5-y;
+ glVertex3f(x,y,0);
+}
+
+static void
+draw_lines(struct graphics *gr, struct graphics_gc *gc, struct point *p, int count)
+{
+ int i;
+
+ glLineWidth(gc->width);
+ glColor3f(gc->fr, gc->fg, gc->fb);
+ glBegin(GL_LINE_STRIP);
+ for (i=0 ; i < count ; i++)
+ vertex(p++);
+ glEnd();
+}
+
+static void
+draw_polygon(struct graphics *gr, struct graphics_gc *gc, struct point *p, int count)
+{
+ int i;
+ double x,y;
+ glColor3f(gc->fr, gc->fg, gc->fb);
+ glBegin(GL_POLYGON);
+ for (i=0 ; i < count ; i++)
+ vertex(p++);
+ glEnd();
+}
+
+
+static void
+draw_circle(struct graphics *gr, struct graphics_gc *gc, struct point *p, int r)
+{
+
+}
+
+static void
+draw_text(struct graphics *gr, struct graphics_gc *fg, struct graphics_gc *bg, struct graphics_font *font, unsigned char *text, int x, int y, int dx, int dy)
+{
+}
+
+static void
+draw_begin(struct graphics *gr)
+{
+ printf("draw_begin\n");
+ glClearColor(gr->gc[0]->br, gr->gc[0]->bg, gr->gc[0]->bb, 0);
+ glNewList(1, GL_COMPILE);
+ gr->gra->buffer=1;
+}
+
+static void
+draw_end(struct graphics *gr)
+{
+ printf("draw_end\n");
+ glEndList();
+ gr->gra->buffer=0;
+}
+
+static void realize(GtkWidget * widget, gpointer data)
+{
+ GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
+ GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
+
+ GLUquadricObj *qobj;
+ static GLfloat light_diffuse[] = { 1.0, 0.0, 0.0, 1.0 };
+ static GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
+
+ /*** OpenGL BEGIN ***/
+ if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext))
+ return;
+
+ qobj = gluNewQuadric();
+ gluQuadricDrawStyle(qobj, GLU_FILL);
+#if 0
+ glNewList(1, GL_COMPILE);
+ gluSphere(qobj, 1.0, 20, 20);
+ glBegin(GL_LINE_STRIP);
+ glVertex3f(0.0,0.1,0.0);
+ glVertex3f(0.1,0.1,0.0);
+ glVertex3f(0.1,0.2,0.0);
+ glVertex3f(0.2,0.2,0.0);
+ glEnd();
+ glEndList();
+#endif
+
+#if 0
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+ glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+#endif
+
+ glClearColor(1.0, 1.0, 1.0, 1.0);
+ glClearDepth(1.0);
+
+ glViewport(0, 0,
+ widget->allocation.width, widget->allocation.height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(19.0, 1.0, 1.0, 10.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ gluLookAt(0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
+ glTranslatef(0.0, 0.0, 0.0);
+
+ gdk_gl_drawable_gl_end(gldrawable);
+ /*** OpenGL END ***/
+}
+
+static gboolean
+configure(GtkWidget * widget, GdkEventConfigure * event, gpointer user_data)
+{
+ GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
+ GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
+ struct container *co=user_data;
+ struct graphics_gra *gra=co->gra->gra;
+
+
+ printf("configure %d %d\n",gra->width, gra->height);
+ gra->width=widget->allocation.width;
+ gra->height=widget->allocation.height;
+
+ /*** OpenGL BEGIN ***/
+ if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext))
+ return FALSE;
+
+ glViewport(0, 0,
+ widget->allocation.width, widget->allocation.height);
+
+ gdk_gl_drawable_gl_end(gldrawable);
+ /*** OpenGL END ***/
+ if (gra->visible)
+ graphics_resize(co, gra->width, gra->height);
+
+ return TRUE;
+}
+
+static gboolean
+expose(GtkWidget * widget, GdkEventExpose * event, gpointer user_data)
+{
+ GdkGLContext *glcontext = gtk_widget_get_gl_context(widget);
+ GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(widget);
+ struct container *co=user_data;
+ struct graphics_gra *gra=co->gra->gra;
+
+ printf("expose\n");
+ if (! gra->visible) {
+ gra->visible=1;
+ configure(widget, NULL, user_data);
+ }
+ /*** OpenGL BEGIN ***/
+ if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext))
+ return FALSE;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glCallList(1);
+
+ if (gdk_gl_drawable_is_double_buffered(gldrawable))
+ gdk_gl_drawable_swap_buffers(gldrawable);
+ else
+ glFlush();
+
+ gdk_gl_drawable_gl_end(gldrawable);
+ /*** OpenGL END ***/
+
+ return TRUE;
+}
+
+
+struct graphics *
+graphics_gtk_gl_area_new(struct container *co, GtkWidget **widget)
+{
+ GdkGLConfig *glconfig;
+ gint major, minor;
+ GtkWidget *drawing_area;
+
+ struct graphics *this=g_new0(struct graphics,1);
+ this->draw_lines=draw_lines;
+ this->draw_polygon=draw_polygon;
+ this->draw_circle=draw_circle;
+ this->draw_text=draw_text;
+#if 0
+ this->draw_begin=draw_begin;
+ this->draw_end=draw_end;
+#endif
+ this->gc_new=gc_new;
+ this->gc_set_linewidth=gc_set_linewidth;
+ this->gc_set_foreground=gc_set_foreground;
+ this->gc_set_background=gc_set_background;
+ this->font_new=font_new;
+ this->gra=g_new0(struct graphics_gra, 1);
+
+ /*
+ * Init GtkGLExt.
+ */
+
+ gtk_gl_init(NULL, NULL);
+
+ /*
+ * Query OpenGL extension version.
+ */
+
+ gdk_gl_query_version(&major, &minor);
+ g_print("OpenGL extension version - %d.%d\n", major, minor);
+
+ /*
+ * Configure OpenGL-capable visual.
+ */
+
+ /* Try double-buffered visual */
+ glconfig = gdk_gl_config_new_by_mode(GDK_GL_MODE_RGB |
+ GDK_GL_MODE_DEPTH |
+ GDK_GL_MODE_DOUBLE);
+ if (glconfig == NULL) {
+ g_print("*** Cannot find the double-buffered visual.\n");
+ g_print("*** Trying single-buffered visual.\n");
+
+ /* Try single-buffered visual */
+ glconfig = gdk_gl_config_new_by_mode(GDK_GL_MODE_RGB |
+ GDK_GL_MODE_DEPTH);
+ if (glconfig == NULL) {
+ g_print
+ ("*** No appropriate OpenGL-capable visual found.\n");
+ exit(1);
+ }
+ }
+
+
+ drawing_area = gtk_drawing_area_new();
+
+ /* Set OpenGL-capability to the widget. */
+ gtk_widget_set_gl_capability(drawing_area,
+ glconfig,
+ NULL, TRUE, GDK_GL_RGBA_TYPE);
+
+ g_signal_connect_after(G_OBJECT(drawing_area), "realize",
+ G_CALLBACK(realize), NULL);
+ g_signal_connect(G_OBJECT(drawing_area), "configure_event",
+ G_CALLBACK(configure), co);
+ g_signal_connect(G_OBJECT(drawing_area), "expose_event",
+ G_CALLBACK(expose), co);
+
+ *widget=drawing_area;
+ this->gra->widget=drawing_area;
+ return this;
+}
+
+
diff --git a/navit/graphics/null/Makefile.am b/navit/graphics/null/Makefile.am
new file mode 100644
index 000000000..c1e93de0a
--- /dev/null
+++ b/navit/graphics/null/Makefile.am
@@ -0,0 +1,4 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=graphics_null
+modulegraphics_LTLIBRARIES = libgraphics_null.la
+libgraphics_null_la_SOURCES = graphics_null.c
diff --git a/navit/graphics/null/graphics_null.c b/navit/graphics/null/graphics_null.c
new file mode 100644
index 000000000..8b87e22c3
--- /dev/null
+++ b/navit/graphics/null/graphics_null.c
@@ -0,0 +1,208 @@
+#include <glib.h>
+#include "config.h"
+#include "point.h"
+#include "graphics.h"
+#include "color.h"
+#include "plugin.h"
+
+static int dummy;
+static struct graphics_priv {
+ int dummy;
+} graphics_priv;
+
+static struct graphics_font_priv {
+ int dummy;
+} graphics_font_priv;
+
+static struct graphics_gc_priv {
+ int dummy;
+} graphics_gc_priv;
+
+static struct graphics_image_priv {
+ int dummy;
+} graphics_image_priv;
+
+static void
+graphics_destroy(struct graphics_priv *gr)
+{
+}
+
+static void font_destroy(struct graphics_font_priv *font)
+{
+
+}
+
+static struct graphics_font_methods font_methods = {
+ font_destroy
+};
+
+static struct graphics_font_priv *font_new(struct graphics_priv *gr, struct graphics_font_methods *meth, int size)
+{
+ *meth=font_methods;
+ return &graphics_font_priv;
+}
+
+static void
+gc_destroy(struct graphics_gc_priv *gc)
+{
+}
+
+static void
+gc_set_linewidth(struct graphics_gc_priv *gc, int w)
+{
+}
+
+static void
+gc_set_dashes(struct graphics_gc_priv *gc, int w, int offset, unsigned char *dash_list, int n)
+{
+}
+
+static void
+gc_set_foreground(struct graphics_gc_priv *gc, struct color *c)
+{
+}
+
+static void
+gc_set_background(struct graphics_gc_priv *gc, struct color *c)
+{
+}
+
+static struct graphics_gc_methods gc_methods = {
+ gc_destroy,
+ gc_set_linewidth,
+ gc_set_dashes,
+ gc_set_foreground,
+ gc_set_background
+};
+
+static struct graphics_gc_priv *gc_new(struct graphics_priv *gr, struct graphics_gc_methods *meth)
+{
+ *meth=gc_methods;
+ return &graphics_gc_priv;
+}
+
+
+static struct graphics_image_priv *
+image_new(struct graphics_priv *gr, struct graphics_image_methods *meth, char *name, int *w, int *h)
+{
+ return &graphics_image_priv;
+}
+
+static void
+draw_lines(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
+{
+}
+
+static void
+draw_polygon(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
+{
+}
+
+static void
+draw_rectangle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int w, int h)
+{
+}
+
+static void
+draw_circle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int r)
+{
+}
+
+
+static void
+draw_text(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct graphics_gc_priv *bg, struct graphics_font_priv *font, char *text, struct point *p, int dx, int dy)
+{
+}
+
+static void
+draw_image(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, struct graphics_image_priv *img)
+{
+}
+
+static void
+draw_image_warp(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, int count, char *data)
+{
+}
+
+static void
+draw_restore(struct graphics_priv *gr, struct point *p, int w, int h)
+{
+}
+
+static void
+background_gc(struct graphics_priv *gr, struct graphics_gc_priv *gc)
+{
+}
+
+static void
+draw_mode(struct graphics_priv *gr, enum draw_mode_num mode)
+{
+}
+
+static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h);
+
+static void *
+get_data(struct graphics_priv *this, char *type)
+{
+ return &dummy;
+}
+
+
+
+static void
+register_resize_callback(struct graphics_priv *this, void (*callback)(void *data, int w, int h), void *data)
+{
+}
+
+static void
+register_motion_callback(struct graphics_priv *this, void (*callback)(void *data, struct point *p), void *data)
+{
+}
+
+static void
+register_button_callback(struct graphics_priv *this, void (*callback)(void *data, int press, int button, struct point *p), void *data)
+{
+}
+
+static struct graphics_methods graphics_methods = {
+ graphics_destroy,
+ draw_mode,
+ draw_lines,
+ draw_polygon,
+ draw_rectangle,
+ draw_circle,
+ draw_text,
+ draw_image,
+ draw_image_warp,
+ draw_restore,
+ font_new,
+ gc_new,
+ background_gc,
+ overlay_new,
+ image_new,
+ get_data,
+ register_resize_callback,
+ register_button_callback,
+ register_motion_callback,
+};
+
+static struct graphics_priv *
+overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h)
+{
+ *meth=graphics_methods;
+ return &graphics_priv;
+}
+
+
+static struct graphics_priv *
+graphics_null_new(struct graphics_methods *meth, struct attr **attrs)
+{
+ *meth=graphics_methods;
+ return &graphics_priv;
+}
+
+void
+plugin_init(void)
+{
+ plugin_register_graphics_type("null", graphics_null_new);
+}
diff --git a/navit/graphics/opengl/Makefile.am b/navit/graphics/opengl/Makefile.am
new file mode 100644
index 000000000..a44535703
--- /dev/null
+++ b/navit/graphics/opengl/Makefile.am
@@ -0,0 +1,5 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ @OPENGL_CFLAGS@ @GLC_CFLAGS@ -I$(top_srcdir)/src -DMODULE=graphics_opengl
+modulegraphics_LTLIBRARIES = libgraphics_opengl.la
+libgraphics_opengl_la_SOURCES = graphics_opengl.c
+libgraphics_opengl_la_LIBADD = @OPENGL_LIBS@ @GLC_LIBS@
diff --git a/navit/graphics/opengl/graphics_opengl.c b/navit/graphics/opengl/graphics_opengl.c
new file mode 100644
index 000000000..fce72f491
--- /dev/null
+++ b/navit/graphics/opengl/graphics_opengl.c
@@ -0,0 +1,826 @@
+#include <math.h>
+#include <glib.h>
+#include "config.h"
+#include <GL/glc.h>
+#include "point.h"
+#include "graphics.h"
+#include "color.h"
+#include "plugin.h"
+
+#include "debug.h"
+
+#include <GL/glut.h>
+
+
+void CALLBACK tessBeginCB(GLenum which);
+void CALLBACK tessEndCB();
+void CALLBACK tessErrorCB(GLenum errorCode);
+void CALLBACK tessVertexCB(const GLvoid *data);
+void CALLBACK tessVertexCB2(const GLvoid *data);
+void CALLBACK tessCombineCB(const GLdouble newVertex[3], const GLdouble *neighborVertex[4],
+ const GLfloat neighborWeight[4], GLdouble **outData);
+
+
+struct graphics_priv {
+ int button_timeout;
+ struct point p;
+ int width;
+ int height;
+ int library_init;
+ int visible;
+ struct graphics_priv *parent;
+ struct graphics_priv *overlays;
+ struct graphics_priv *next;
+ struct graphics_gc_priv *background_gc;
+ enum draw_mode_num mode;
+ void (*resize_callback)(void *data, int w, int h);
+ void *resize_callback_data;
+ void (*motion_callback)(void *data, struct point *p);
+ void *motion_callback_data;
+ void (*button_callback)(void *data, int press, int button, struct point *p);
+ void *button_callback_data;
+ GLuint DLid;
+};
+
+struct graphics_font_priv {
+#if 0
+ FT_Face face;
+#endif
+};
+
+struct graphics_gc_priv {
+ struct graphics_priv *gr;
+ float fr,fg,fb,fa;
+ float br,bg,bb,ba;
+ int linewidth;
+};
+
+struct graphics_image_priv {
+ int w;
+ int h;
+};
+
+static void
+graphics_destroy(struct graphics_priv *gr)
+{
+}
+
+int frame=0;
+
+// http://quesoglc.sourceforge.net/tutorial.php
+
+
+static void font_destroy(struct graphics_font_priv *font)
+{
+ g_free(font);
+ /* TODO: free font->face */
+}
+
+static struct graphics_font_methods font_methods = {
+ font_destroy
+};
+
+static struct graphics_font_priv *font_new(struct graphics_priv *gr, struct graphics_font_methods *meth, int size)
+{
+#if 0
+ char **filename=fontlist;
+ struct graphics_font_priv *font=g_new(struct graphics_font_priv, 1);
+
+ *meth=font_methods;
+
+ if (!gr->library_init) {
+ FT_Init_FreeType( &gr->library );
+ gr->library_init=1;
+ }
+
+ while (*filename) {
+ if (!FT_New_Face( gr->library, *filename, 0, &font->face ))
+ break;
+ filename++;
+ }
+ if (! *filename) {
+ g_warning("Failed to load font, no labelling");
+ g_free(font);
+ return NULL;
+ }
+ FT_Set_Char_Size(font->face, 0, size, 300, 300);
+ FT_Select_Charmap(font->face, FT_ENCODING_UNICODE);
+ return font;
+#endif
+ return NULL;
+}
+
+static void
+gc_destroy(struct graphics_gc_priv *gc)
+{
+ g_free(gc);
+}
+
+static void
+gc_set_linewidth(struct graphics_gc_priv *gc, int w)
+{
+ gc->linewidth=w;
+}
+
+static void
+gc_set_dashes(struct graphics_gc_priv *gc, int width, int offset, unsigned char *dash_list, int n)
+{
+#if 0
+ gdk_gc_set_dashes(gc->gc, offset, (gint8 *)dash_list, n);
+ gdk_gc_set_line_attributes(gc->gc, width, GDK_LINE_ON_OFF_DASH, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+#endif
+}
+
+
+static void
+gc_set_foreground(struct graphics_gc_priv *gc, struct color *c)
+{
+ gc->fr=c->r/65535.0;
+ gc->fg=c->g/65535.0;
+ gc->fb=c->b/65535.0;
+ gc->fa=c->a/65535.0;
+// printf("new alpha : %i\n",c->a);
+}
+
+static void
+gc_set_background(struct graphics_gc_priv *gc, struct color *c)
+{
+ gc->br=c->r/65535.0;
+ gc->bg=c->g/65535.0;
+ gc->bb=c->b/65535.0;
+ gc->ba=c->a/65535.0;
+}
+
+static struct graphics_gc_methods gc_methods = {
+ gc_destroy,
+ gc_set_linewidth,
+ gc_set_dashes,
+ gc_set_foreground,
+ gc_set_background
+};
+
+static struct graphics_gc_priv *gc_new(struct graphics_priv *gr, struct graphics_gc_methods *meth)
+{
+ struct graphics_gc_priv *gc=g_new(struct graphics_gc_priv, 1);
+
+ *meth=gc_methods;
+ gc->gr=gr;
+ gc->linewidth=1;
+ return gc;
+}
+
+
+static struct graphics_image_priv *
+image_new(struct graphics_priv *gr, struct graphics_image_methods *meth, char *name, int *w, int *h)
+{
+#if 0
+ GdkPixbuf *pixbuf;
+ struct graphics_image_priv *ret;
+
+ pixbuf=gdk_pixbuf_new_from_file(name, NULL);
+ if (! pixbuf)
+ return NULL;
+ ret=g_new0(struct graphics_image_priv, 1);
+ ret->pixbuf=pixbuf;
+ ret->w=gdk_pixbuf_get_width(pixbuf);
+ ret->h=gdk_pixbuf_get_height(pixbuf);
+ *w=ret->w;
+ *h=ret->h;
+ return ret;
+#endif
+ return NULL;
+}
+
+static void
+draw_lines(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
+{
+ int i;
+/*
+ if (gr->mode == draw_mode_begin || gr->mode == draw_mode_end)
+ gdk_draw_lines(gr->drawable, gc->gc, (GdkPoint *)p, count);
+ if (gr->mode == draw_mode_end || gr->mode == draw_mode_cursor)
+ gdk_draw_lines(gr->widget->window, gc->gc, (GdkPoint *)p, count);
+*/
+ /*
+ if(gr->mode == draw_mode_begin){
+ printf("B");
+ } else if (gr->mode == draw_mode_end){
+ printf("E");
+ } else {
+ printf("x");
+ }
+*/
+
+ for (i = 0 ; i < count-1 ; i++) {
+
+// glEnable( GL_POLYGON_SMOOTH );
+// glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+// glEnable( GL_BLEND );
+
+ float dx=p[i+1].x-p[i].x;
+ float dy=p[i+1].y-p[i].y;
+
+ float cx=(p[i+1].x+p[i].x)/2;
+ float cy=(p[i+1].y+p[i].y)/2;
+// printf("(%lx,%lx) -> (%lx,%lx) : (%lx,%lx)\n",p[i].x,p[i].y,p[i+1].x,p[i+1].y,dx,dy);
+
+ int w=round(sqrt(pow((dx),2)+pow((dy),2)));
+
+ float angle=atan (dy/dx) * 180 / M_PI;
+
+ glPushMatrix();
+ glTranslatef(cx,cy,1);
+ // glColor4f( 0,0,0,1);
+ // glRasterPos2f( 1,1 );
+ glRotatef(angle,0.0,0.0,1.0);
+
+ glColor4f( gc->fr, gc->fg, gc->fb, gc->fa);
+
+ int linewidth=gc->linewidth;
+
+ glBegin( GL_POLYGON );
+ glVertex2f( -w/2,-linewidth/2 );
+ glVertex2f( -w/2-4,0 );
+ glVertex2f( -w/2,+linewidth/2 );
+ glVertex2f( +w/2,+linewidth/2 );
+ glVertex2f( +w/2+4,0 );
+ glVertex2f( +w/2,-linewidth/2 );
+ glVertex2f( -w/2,+linewidth/2 );
+ glEnd();
+
+
+ // FIXME Roads label can maybe be drawn here, avoid the display_label loop, when playing with Z axis position.
+ /*
+ if(attr==1){
+ glcRenderStyle(GLC_TEXTURE);
+ glColor3f(0., 0., 0.);
+ glScalef(12, 12, 0.);
+ glcRenderString(">>");
+ } else if(attr==-1){
+ glcRenderStyle(GLC_TEXTURE);
+ glColor3f(0., 0., 0.);
+ glScalef(12, 12, 0.);
+ glcRenderString("<<");
+ }
+
+ */
+ glPopMatrix();
+ }
+// glDisable( GL_BLEND );
+// glDisable( GL_POLYGON_SMOOTH );
+
+/*
+ if(label){
+ if((strlen(label)*6)<w){
+ SDL_print(label,cx, cy,-angle);
+ }
+ }
+*/
+}
+
+
+const char* getPrimitiveType(GLenum type)
+{
+ switch(type)
+ {
+ case 0x0000:
+ return "GL_POINTS";
+ break;
+ case 0x0001:
+ return "GL_LINES";
+ break;
+ case 0x0002:
+ return "GL_LINE_LOOP";
+ break;
+ case 0x0003:
+ return "GL_LINE_STRIP";
+ break;
+ case 0x0004:
+ return "GL_TRIANGLES";
+ break;
+ case 0x0005:
+ return "GL_TRIANGLE_STRIP";
+ break;
+ case 0x0006:
+ return "GL_TRIANGLE_FAN";
+ break;
+ case 0x0007:
+ return "GL_QUADS";
+ break;
+ case 0x0008:
+ return "GL_QUAD_STRIP";
+ break;
+ case 0x0009:
+ return "GL_POLYGON";
+ break;
+ }
+}
+
+void CALLBACK tessBeginCB(GLenum which)
+{
+ glBegin(which);
+
+ dbg(1,"glBegin( %s );\n",getPrimitiveType(which));
+}
+
+
+
+void CALLBACK tessEndCB()
+{
+ glEnd();
+
+ dbg(1,"glEnd();\n");
+}
+
+
+
+void CALLBACK tessVertexCB(const GLvoid *data)
+{
+ // cast back to double type
+ const GLdouble *ptr = (const GLdouble*)data;
+
+ glVertex3dv(ptr);
+
+ dbg(1," glVertex3d();\n");
+}
+
+
+static void
+draw_polygon(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
+{
+ int i;
+
+ GLUtesselator *tess = gluNewTess(); // create a tessellator
+ if(!tess) return 0; // failed to create tessellation object, return 0
+
+ GLdouble quad1[count][3];
+ for (i = 0 ; i < count ; i++) {
+ quad1[i][0]=(GLdouble)(p[i].x);
+ quad1[i][1]=(GLdouble)(p[i].y);
+ quad1[i][2]=0;
+ }
+
+
+ // register callback functions
+ gluTessCallback(tess, GLU_TESS_BEGIN, (void (*)(void))tessBeginCB);
+ gluTessCallback(tess, GLU_TESS_END, (void (*)(void))tessEndCB);
+ // gluTessCallback(tess, GLU_TESS_ERROR, (void (*)(void))tessErrorCB);
+ gluTessCallback(tess, GLU_TESS_VERTEX, (void (*)(void))tessVertexCB);
+
+ // tessellate and compile a concave quad into display list
+ // gluTessVertex() takes 3 params: tess object, pointer to vertex coords,
+ // and pointer to vertex data to be passed to vertex callback.
+ // The second param is used only to perform tessellation, and the third
+ // param is the actual vertex data to draw. It is usually same as the second
+ // param, but It can be more than vertex coord, for example, color, normal
+ // and UV coords which are needed for actual drawing.
+ // Here, we are looking at only vertex coods, so the 2nd and 3rd params are
+ // pointing same address.
+ glColor4f( gc->fr, gc->fg, gc->fb, gc->fa);
+ gluTessBeginPolygon(tess, 0); // with NULL data
+ gluTessBeginContour(tess);
+ for (i = 0 ; i < count ; i++) {
+ gluTessVertex(tess, quad1[i], quad1[i]);
+ }
+ gluTessEndContour(tess);
+ gluTessEndPolygon(tess);
+
+ gluDeleteTess(tess); // delete after tessellation
+
+}
+
+static void
+draw_rectangle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int w, int h)
+{
+#if 0
+ gdk_draw_rectangle(gr->drawable, gc->gc, TRUE, p->x, p->y, w, h);
+#endif
+}
+
+static void
+draw_circle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int r)
+{
+#if 0
+ if (gr->mode == draw_mode_begin || gr->mode == draw_mode_end)
+ gdk_draw_arc(gr->drawable, gc->gc, FALSE, p->x-r/2, p->y-r/2, r, r, 0, 64*360);
+ if (gr->mode == draw_mode_end || gr->mode == draw_mode_cursor)
+ gdk_draw_arc(gr->widget->window, gc->gc, FALSE, p->x-r/2, p->y-r/2, r, r, 0, 64*360);
+#endif
+}
+
+
+
+void SDL_print(char * label,int x, int y, double angle)
+{
+ glPushMatrix();
+ glcRenderStyle(GLC_TEXTURE);
+ glColor4f(0,0,0,1);
+ glTranslatef(x, y, 1);
+ glRotatef(180,1,0,0);
+ glRotatef(angle,0,0,1);
+
+ glScalef(14, 14, 14);
+ // FIXME : add some error checking : glcGetError()
+ glcRenderString(label);
+ glPopMatrix();
+
+}
+
+static void
+draw_text(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct graphics_gc_priv *bg, struct graphics_font_priv *font, char *text, struct point *p, int dx, int dy)
+{
+// dbg(0,"%s : %i,%i, %f\n",text,dx,dy,(180*atan2(dx,dy)/3.14));
+ SDL_print(text,p->x,p->y,(180*atan2(dx,dy)/3.14)-90);
+}
+
+static void
+draw_image(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, struct graphics_image_priv *img)
+{
+#if 0
+ gdk_draw_pixbuf(gr->drawable, fg->gc, img->pixbuf, 0, 0, p->x, p->y,
+ img->w, img->h, GDK_RGB_DITHER_NONE, 0, 0);
+#endif
+}
+
+#ifdef HAVE_IMLIB2
+static void
+draw_image_warp(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, int count, char *data)
+{
+#if 0
+ void *image;
+ int w,h;
+ printf("draw_image_warp data=%s\n", data);
+ image = imlib_load_image(data);
+ imlib_context_set_display(gdk_x11_drawable_get_xdisplay(gr->widget->window));
+ imlib_context_set_colormap(gdk_x11_colormap_get_xcolormap(gtk_widget_get_colormap(gr->widget)));
+ imlib_context_set_visual(gdk_x11_visual_get_xvisual(gtk_widget_get_visual(gr->widget)));
+ imlib_context_set_drawable(gdk_x11_drawable_get_xid(gr->drawable));
+ imlib_context_set_image(image);
+ w = imlib_image_get_width();
+ h = imlib_image_get_height();
+ if (count == 3) {
+ imlib_render_image_on_drawable_skewed(0, 0, w, h, p[0].x, p[0].y, p[1].x-p[0].x, p[1].y-p[0].y, p[2].x-p[0].x, p[2].y-p[0].y);
+ }
+ if (count == 2) {
+ imlib_render_image_on_drawable_skewed(0, 0, w, h, p[0].x, p[0].y, p[1].x-p[0].x, 0, 0, p[1].y-p[0].y);
+ }
+#endif
+}
+#endif
+
+static void
+overlay_draw(struct graphics_priv *parent, struct graphics_priv *overlay, int window)
+{
+#if 0
+ GdkPixbuf *pixbuf,*pixbuf2;
+ GtkWidget *widget=parent->widget;
+ guchar *pixels1, *pixels2, *p1, *p2;
+ int x,y;
+ int rowstride1,rowstride2;
+ int n_channels1,n_channels2;
+
+ if (! parent->drawable)
+ return;
+
+ pixbuf=gdk_pixbuf_get_from_drawable(NULL, overlay->drawable, NULL, 0, 0, 0, 0, overlay->width, overlay->height);
+ pixbuf2=gdk_pixbuf_new(gdk_pixbuf_get_colorspace(pixbuf), TRUE, gdk_pixbuf_get_bits_per_sample(pixbuf),
+ gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf));
+
+ rowstride1 = gdk_pixbuf_get_rowstride (pixbuf);
+ rowstride2 = gdk_pixbuf_get_rowstride (pixbuf2);
+ pixels1=gdk_pixbuf_get_pixels (pixbuf);
+ pixels2=gdk_pixbuf_get_pixels (pixbuf2);
+ n_channels1 = gdk_pixbuf_get_n_channels (pixbuf);
+ n_channels2 = gdk_pixbuf_get_n_channels (pixbuf2);
+ for (y = 0 ; y < overlay->height ; y++) {
+ for (x = 0 ; x < overlay->width ; x++) {
+ p1 = pixels1 + y * rowstride1 + x * n_channels1;
+ p2 = pixels2 + y * rowstride2 + x * n_channels2;
+ p2[0]=p1[0];
+ p2[1]=p1[1];
+ p2[2]=p1[2];
+ p2[3]=127;
+ }
+ }
+ if (window)
+ gdk_draw_pixmap(parent->drawable, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], overlay->background, 0, 0, overlay->p.x, overlay->p.y, overlay->width, overlay->height);
+ else
+ gdk_draw_pixmap(overlay->background, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], parent->drawable, overlay->p.x, overlay->p.y, 0, 0, overlay->width, overlay->height);
+ gdk_draw_pixbuf(parent->drawable, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], pixbuf2, 0, 0, overlay->p.x, overlay->p.y, overlay->width, overlay->height, GDK_RGB_DITHER_NONE, 0, 0);
+ if (window)
+ gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], parent->drawable, overlay->p.x, overlay->p.y, overlay->p.x, overlay->p.y, overlay->width, overlay->height);
+#if 0
+ gdk_draw_pixmap(gr->gra->drawable,
+ gr->gra->widget->style->fg_gc[GTK_WIDGET_STATE(gr->gra->widget)],
+ img->gra->drawable,
+ 0, 0, p->x, p->y, img->gra->width, img->gra->height);
+#endif
+#endif
+}
+
+static void
+draw_restore(struct graphics_priv *gr, struct point *p, int w, int h)
+{
+#if 0
+ GtkWidget *widget=gr->widget;
+ gdk_draw_pixmap(widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+ gr->drawable,
+ p->x, p->y, p->x, p->y, w, h);
+#endif
+
+}
+
+static void
+background_gc(struct graphics_priv *gr, struct graphics_gc_priv *gc)
+{
+ gr->background_gc=gc;
+}
+
+static void
+draw_mode(struct graphics_priv *gr, enum draw_mode_num mode)
+{
+ if (gr->DLid) {
+ if (mode == draw_mode_begin)
+ glNewList(gr->DLid,GL_COMPILE);
+ if (mode == draw_mode_end)
+ glEndList();
+ }
+
+#if 0
+ struct graphics_priv *overlay;
+ GtkWidget *widget=gr->widget;
+
+ if (mode == draw_mode_begin) {
+ if (! gr->parent && gr->background_gc)
+ gdk_draw_rectangle(gr->drawable, gr->background_gc->gc, TRUE, 0, 0, gr->width, gr->height);
+ }
+ if (mode == draw_mode_end && gr->mode == draw_mode_begin) {
+ if (gr->parent) {
+ overlay_draw(gr->parent, gr, 1);
+ } else {
+ overlay=gr->overlays;
+ while (overlay) {
+ overlay_draw(gr, overlay, 0);
+ overlay=overlay->next;
+ }
+ gdk_draw_pixmap(widget->window,
+ widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+ gr->drawable,
+ 0, 0, 0, 0, gr->width, gr->height);
+ }
+ }
+ gr->mode=mode;
+#endif
+}
+
+#if 0
+/* Events */
+
+static gint
+configure(GtkWidget * widget, GdkEventConfigure * event, gpointer user_data)
+{
+ struct graphics_priv *gra=user_data;
+ if (! gra->visible)
+ return TRUE;
+ if (gra->drawable != NULL) {
+ gdk_pixmap_unref(gra->drawable);
+ }
+ gra->width=widget->allocation.width;
+ gra->height=widget->allocation.height;
+ gra->drawable = gdk_pixmap_new(widget->window, gra->width, gra->height, -1);
+ if (gra->resize_callback)
+ (*gra->resize_callback)(gra->resize_callback_data, gra->width, gra->height);
+ return TRUE;
+}
+
+static gint
+expose(GtkWidget * widget, GdkEventExpose * event, gpointer user_data)
+{
+ struct graphics_priv *gra=user_data;
+
+ gra->visible=1;
+ if (! gra->drawable)
+ configure(widget, NULL, user_data);
+ gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+ gra->drawable, event->area.x, event->area.y,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
+
+ return FALSE;
+}
+
+#if 0
+static gint
+button_timeout(gpointer user_data)
+{
+#if 0
+ struct container *co=user_data;
+ int x=co->gra->gra->button_event.x;
+ int y=co->gra->gra->button_event.y;
+ int button=co->gra->gra->button_event.button;
+
+ co->gra->gra->button_timeout=0;
+ popup(co, x, y, button);
+
+ return FALSE;
+#endif
+}
+#endif
+
+static gint
+button_press(GtkWidget * widget, GdkEventButton * event, gpointer user_data)
+{
+ struct graphics_priv *this=user_data;
+ struct point p;
+
+ p.x=event->x;
+ p.y=event->y;
+ if (this->button_callback)
+ (*this->button_callback)(this->button_callback_data, 1, event->button, &p);
+ return FALSE;
+}
+
+static gint
+button_release(GtkWidget * widget, GdkEventButton * event, gpointer user_data)
+{
+ struct graphics_priv *this=user_data;
+ struct point p;
+
+ p.x=event->x;
+ p.y=event->y;
+ if (this->button_callback)
+ (*this->button_callback)(this->button_callback_data, 0, event->button, &p);
+ return FALSE;
+}
+
+static gint
+scroll(GtkWidget * widget, GdkEventScroll * event, gpointer user_data)
+{
+ struct graphics_priv *this=user_data;
+ struct point p;
+ int button;
+
+ p.x=event->x;
+ p.y=event->y;
+ if (this->button_callback) {
+ switch (event->direction) {
+ case GDK_SCROLL_UP:
+ button=4;
+ break;
+ case GDK_SCROLL_DOWN:
+ button=5;
+ break;
+ default:
+ button=-1;
+ break;
+ }
+ if (button != -1) {
+ (*this->button_callback)(this->button_callback_data, 1, button, &p);
+ (*this->button_callback)(this->button_callback_data, 0, button, &p);
+ }
+ }
+ return FALSE;
+}
+
+static gint
+motion_notify(GtkWidget * widget, GdkEventMotion * event, gpointer user_data)
+{
+ struct graphics_priv *this=user_data;
+ struct point p;
+
+ p.x=event->x;
+ p.y=event->y;
+ if (this->motion_callback)
+ (*this->motion_callback)(this->motion_callback_data, &p);
+ return FALSE;
+}
+
+#endif
+
+
+static struct graphics_priv *
+overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h)
+{
+#if 0
+ struct graphics_priv *this=graphics_gtk_drawing_area_new_helper(meth);
+ this->drawable=gdk_pixmap_new(gr->widget->window, w, h, -1);
+ this->colormap=gr->colormap;
+ this->widget=gr->widget;
+ this->p=*p;
+ this->width=w;
+ this->height=h;
+ this->parent=gr;
+ this->background=gdk_pixmap_new(gr->widget->window, w, h, -1);
+ this->next=gr->overlays;
+ gr->overlays=this;
+ return this;
+#endif
+ return NULL;
+}
+
+static void *
+get_data(struct graphics_priv *this, char *type)
+{
+ if (strcmp(type,"opengl_displaylist"))
+ return NULL;
+#if 0
+ dbg(1,"Creating the DL from driver\n");
+ this->DLid = glGenLists(1);
+#endif
+ return &this->DLid;
+}
+
+static void
+register_resize_callback(struct graphics_priv *this, void (*callback)(void *data, int w, int h), void *data)
+{
+ this->resize_callback=callback;
+ this->resize_callback_data=data;
+}
+
+static void
+register_motion_callback(struct graphics_priv *this, void (*callback)(void *data, struct point *p), void *data)
+{
+ this->motion_callback=callback;
+ this->motion_callback_data=data;
+}
+
+static void
+register_button_callback(struct graphics_priv *this, void (*callback)(void *data, int press, int button, struct point *p), void *data)
+{
+ this->button_callback=callback;
+ this->button_callback_data=data;
+}
+
+static struct graphics_methods graphics_methods = {
+ graphics_destroy,
+ draw_mode,
+ draw_lines,
+ draw_polygon,
+ draw_rectangle,
+ draw_circle,
+ draw_text,
+ draw_image,
+#ifdef HAVE_IMLIB2
+ draw_image_warp,
+#else
+ NULL,
+#endif
+ draw_restore,
+ font_new,
+ gc_new,
+ background_gc,
+ overlay_new,
+ image_new,
+ get_data,
+ register_resize_callback,
+ register_button_callback,
+ register_motion_callback,
+ NULL, // image_free
+};
+
+static struct graphics_priv *
+graphics_opengl_new(struct graphics_methods *meth, struct attr **attrs)
+{
+ struct graphics_priv *this=g_new0(struct graphics_priv,1);
+ *meth=graphics_methods;
+
+// GtkWidget *draw;
+
+// draw=gtk_drawnig_area_new();
+
+
+ // Initialize the fonts
+ int ctx = 0;
+ int font = 0;
+ ctx = glcGenContext();
+ glcContext(ctx);
+ font = glcNewFontFromFamily(glcGenFontID(), "Verdana");
+ glcFont(font);
+ glcStringType(GLC_UTF8_QSO);
+// glcFontFace(font, "Italic");
+
+
+/*
+ this->widget=draw;
+
+ this->colormap=gdk_colormap_new(gdk_visual_get_system(),FALSE);
+ gtk_widget_set_events(draw, GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK|GDK_POINTER_MOTION_MASK|GDK_KEY_PRESS_MASK);
+ g_signal_connect(G_OBJECT(draw), "expose_event", G_CALLBACK(expose), this);
+ g_signal_connect(G_OBJECT(draw), "configure_event", G_CALLBACK(configure), this);
+#if 0
+ g_signal_connect(G_OBJECT(draw), "realize_event", G_CALLBACK(realize), co);
+#endif
+ g_signal_connect(G_OBJECT(draw), "button_press_event", G_CALLBACK(button_press), this);
+ g_signal_connect(G_OBJECT(draw), "button_release_event", G_CALLBACK(button_release), this);
+ g_signal_connect(G_OBJECT(draw), "scroll_event", G_CALLBACK(scroll), this);
+ g_signal_connect(G_OBJECT(draw), "motion_notify_event", G_CALLBACK(motion_notify), this);
+ */
+ return this;
+}
+
+void
+plugin_init(void)
+{
+ plugin_register_graphics_type("opengl", graphics_opengl_new);
+}
diff --git a/navit/graphics/qt_qpainter/Makefile.am b/navit/graphics/qt_qpainter/Makefile.am
new file mode 100644
index 000000000..228236d58
--- /dev/null
+++ b/navit/graphics/qt_qpainter/Makefile.am
@@ -0,0 +1,5 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @QT_GUI_CFLAGS@ @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=graphics_qt_qpainter
+modulegraphics_LTLIBRARIES = libgraphics_qt_qpainter.la
+libgraphics_qt_qpainter_la_SOURCES = graphics_qt_qpainter.cpp
+libgraphics_qt_qpainter_la_LDFLAGS = @QT_GUI_LIBS@
diff --git a/navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp b/navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp
new file mode 100644
index 000000000..c0f59bc23
--- /dev/null
+++ b/navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp
@@ -0,0 +1,682 @@
+//##############################################################################################################
+//#
+//# File: graphics_qt_qpainter.cpp
+//# Description: Graphics interface for internal GUI using Qt (Trolltech.com)
+//# Comment:
+//# Authors: Martin Schaller (04/2008), Stefan Klumpp (04/2008)
+//#
+//##############################################################################################################
+
+
+#include <glib.h>
+#include "config.h"
+#include "point.h"
+#include "item.h"
+#include "graphics.h"
+#include "color.h"
+#include "debug.h"
+#include "plugin.h"
+
+#if 0
+#define QWS
+#define NO_DEBUG
+#endif
+
+#include <qglobal.h>
+
+#if QT_VERSION < 0x040000
+#include <qwidget.h>
+#include <qapplication.h>
+#include <qpainter.h>
+#include <qpen.h>
+#include <qbrush.h>
+#include <qimage.h>
+#include <qpixmap.h>
+#include <qlistview.h>
+#else
+#include <QApplication>
+#include <QGraphicsScene>
+#include <QGraphicsView>
+#include <QPainter>
+#include <QPen>
+#include <QBrush>
+#include <QPixmap>
+#include <QWidget>
+#include <QPolygonF>
+#include <QtGui>
+#endif
+
+//##############################################################################################################
+//# Description: RenderArea (QWidget) class for the main window (map, menu, ...)
+//# Comment:
+//# Authors: Martin Schaller (04/2008), Stefan Klumpp (04/2008)
+//##############################################################################################################
+class RenderArea : public QWidget
+ {
+ public:
+ RenderArea(QWidget *parent = 0);
+ QPixmap *pixmap;
+ void (*resize_callback)(void *data, int w, int h);
+ void *resize_callback_data;
+ void (*motion_callback)(void *data, struct point *p);
+ void *motion_callback_data;
+ void (*button_callback)(void *data, int press, int button, struct point *p);
+ void *button_callback_data; // struct navit *
+
+
+ protected:
+ QSize sizeHint() const;
+ void paintEvent(QPaintEvent *event);
+ void resizeEvent(QResizeEvent *event);
+ void mouseEvent(int pressed, QMouseEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void wheelEvent(QWheelEvent *event);
+
+ };
+
+//##############################################################################################################
+//# Description: Constructor
+//# Comment: Using a QPixmap for rendering the graphics
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+RenderArea::RenderArea(QWidget *parent)
+ : QWidget(parent)
+{
+ pixmap = new QPixmap(800, 600);
+}
+
+//##############################################################################################################
+//# Description: QWidget:sizeHint
+//# Comment: This property holds the recommended size for the widget
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+QSize RenderArea::sizeHint() const
+{
+ return QSize(800, 600);
+}
+
+//##############################################################################################################
+//# Description: QWidget:paintEvent
+//# Comment: A paint event is a request to repaint all or part of the widget.
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void RenderArea::paintEvent(QPaintEvent * event)
+{
+ QPainter painter(this);
+ painter.drawPixmap(0, 0, *pixmap);
+}
+
+
+//##############################################################################################################
+//# Description: QWidget::resizeEvent()
+//# Comment: When resizeEvent() is called, the widget already has its new geometry.
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void RenderArea::resizeEvent(QResizeEvent * event)
+{
+ QSize size=event->size();
+ delete pixmap;
+ pixmap = new QPixmap(size);
+ if (this->resize_callback)
+ (this->resize_callback)(this->resize_callback_data, size.width(), size.height());
+}
+
+//##############################################################################################################
+//# Description: Method to handle mouse clicks
+//# Comment: Delegate of QWidget::mousePressEvent and QWidget::mouseReleaseEvent (see below)
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void RenderArea::mouseEvent(int pressed, QMouseEvent *event)
+{
+ struct point p;
+ if (!this->button_callback)
+ return;
+ p.x=event->x();
+ p.y=event->y();
+ switch (event->button()) {
+ case Qt::LeftButton:
+ (this->button_callback)(this->button_callback_data, pressed, 1, &p); // calls navit_button() in navit.c
+ break;
+ case Qt::MidButton:
+ (this->button_callback)(this->button_callback_data, pressed, 2, &p);
+ break;
+ case Qt::RightButton:
+ (this->button_callback)(this->button_callback_data, pressed, 3, &p);
+ break;
+ default:
+ break;
+ }
+}
+
+void RenderArea::mousePressEvent(QMouseEvent *event)
+{
+ mouseEvent(1, event);
+}
+
+void RenderArea::mouseReleaseEvent(QMouseEvent *event)
+{
+ mouseEvent(0, event);
+}
+
+//##############################################################################################################
+//# Description: QWidget::mouseMoveEvent
+//# Comment: If mouse tracking is switched on, mouse move events occur even if no mouse button is pressed.
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void RenderArea::mouseMoveEvent(QMouseEvent *event)
+{
+ struct point p;
+ if (!this->motion_callback)
+ return;
+ p.x=event->x();
+ p.y=event->y();
+ (this->motion_callback)(this->motion_callback_data, &p);
+}
+
+
+//##############################################################################################################
+//# Description: Qt Event :: Zoom in/out with the mouse's scrollwheel
+//# Comment:
+//# Authors: Stefan Klumpp (04/2008)
+//##############################################################################################################
+void RenderArea::wheelEvent(QWheelEvent *event)
+{
+ struct point p;
+ int button;
+
+ if (!this->button_callback)
+ return;
+ p.x=event->x(); // xy-coordinates of the mouse pointer
+ p.y=event->y();
+
+ if (event->delta() > 0) // wheel movement away from the person
+ button=4;
+ else if (event->delta() < 0) // wheel movement towards the person
+ button=5;
+ else
+ button=-1;
+
+ if (button != -1) {
+ (*this->button_callback)(this->button_callback_data, 1, button, &p);
+ (*this->button_callback)(this->button_callback_data, 0, button, &p);
+ }
+
+ event->accept();
+}
+
+//##############################################################################################################
+// General comments:
+// -----------------
+// gr = graphics = draw area
+// gc = graphics context = pen to paint on the draw area
+//##############################################################################################################
+
+static int dummy;
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct graphics_priv {
+ QApplication *app;
+ RenderArea *widget;
+ QPainter *painter;
+ struct graphics_gc_priv *background_gc;
+ enum draw_mode_num mode;
+};
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static struct graphics_font_priv {
+ int dummy;
+} graphics_font_priv;
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static struct graphics_gc_priv {
+ QPen *pen;
+ QBrush *brush;
+} graphics_gc_priv;
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static struct graphics_image_priv {
+ QImage *image;
+} graphics_image_priv;
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void graphics_destroy(struct graphics_priv *gr)
+{
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void font_destroy(struct graphics_font_priv *font)
+{
+
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static struct graphics_font_methods font_methods = {
+ font_destroy
+};
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static struct graphics_font_priv *font_new(struct graphics_priv *gr, struct graphics_font_methods *meth, int size, int flags)
+{
+ *meth=font_methods;
+ return &graphics_font_priv;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void gc_destroy(struct graphics_gc_priv *gc)
+{
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void gc_set_linewidth(struct graphics_gc_priv *gc, int w)
+{
+ gc->pen->setWidth(w);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void gc_set_dashes(struct graphics_gc_priv *gc, int w, int offset, unsigned char *dash_list, int n)
+{
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void gc_set_foreground(struct graphics_gc_priv *gc, struct color *c)
+{
+#if QT_VERSION >= 0x040000
+ QColor col(c->r >> 8, c->g >> 8, c->b >> 8, c->a >> 8);
+#else
+ QColor col(c->r >> 8, c->g >> 8, c->b >> 8);
+#endif
+ gc->pen->setColor(col);
+ gc->brush->setColor(col);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void gc_set_background(struct graphics_gc_priv *gc, struct color *c)
+{
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static struct graphics_gc_methods gc_methods = {
+ gc_destroy,
+ gc_set_linewidth,
+ gc_set_dashes,
+ gc_set_foreground,
+ gc_set_background
+};
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static struct graphics_gc_priv *gc_new(struct graphics_priv *gr, struct graphics_gc_methods *meth)
+{
+ *meth=gc_methods;
+ struct graphics_gc_priv *ret=g_new0(struct graphics_gc_priv, 1);
+ ret->pen=new QPen();
+ ret->brush=new QBrush(Qt::SolidPattern);
+ return ret;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static struct graphics_image_priv * image_new(struct graphics_priv *gr, struct graphics_image_methods *meth, char *path, int *w, int *h, struct point *hot)
+{
+ struct graphics_image_priv *ret=g_new0(struct graphics_image_priv, 1);
+
+ ret->image=new QImage(path);
+ *w=ret->image->width();
+ *h=ret->image->height();
+ if (hot) {
+ hot->x=*w/2;
+ hot->y=*h/2;
+ }
+ return ret;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void draw_lines(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
+{
+ int i;
+#if QT_VERSION >= 0x040000
+ QPolygon polygon;
+#else
+ QPointArray polygon;
+#endif
+
+ for (i = 0 ; i < count ; i++)
+ polygon.putPoints(i, 1, p[i].x, p[i].y);
+ gr->painter->setPen(*gc->pen);
+ gr->painter->drawPolyline(polygon);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void draw_polygon(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)
+{
+ int i;
+#if QT_VERSION >= 0x040000
+ QPolygon polygon;
+#else
+ QPointArray polygon;
+#endif
+
+ for (i = 0 ; i < count ; i++)
+ polygon.putPoints(i, 1, p[i].x, p[i].y);
+ gr->painter->setPen(*gc->pen);
+ gr->painter->setBrush(*gc->brush);
+ gr->painter->drawPolygon(polygon);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void draw_rectangle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int w, int h)
+{
+ gr->painter->fillRect(p->x,p->y, w, h, *gc->brush);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void draw_circle(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int r)
+{
+ gr->painter->setPen(*gc->pen);
+ gr->painter->drawArc(p->x-r, p->y-r, r*2, r*2, 0, 360*16);
+
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void draw_text(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct graphics_gc_priv *bg, struct graphics_font_priv *font, char *text, struct point *p, int dx, int dy)
+{
+ QString tmp = text;
+ gr->painter->drawText(p->x, p->y, tmp);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void draw_image(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, struct graphics_image_priv *img)
+{
+ gr->painter->drawImage(p->x, p->y, *img->image);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void draw_image_warp(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, int count, char *data)
+{
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void draw_restore(struct graphics_priv *gr, struct point *p, int w, int h)
+{
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void background_gc(struct graphics_priv *gr, struct graphics_gc_priv *gc)
+{
+ gr->background_gc=gc;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void draw_mode(struct graphics_priv *gr, enum draw_mode_num mode)
+{
+ dbg(0,"mode=%d\n", mode);
+ if (mode == draw_mode_begin) {
+ gr->painter->begin(gr->widget->pixmap);
+#if 0
+ gr->painter->fillRect(QRect(QPoint(0,0), gr->widget->size()), *gr->background_gc->brush);
+#endif
+ }
+#if QT_VERSION < 0x040000
+ if (mode == draw_mode_cursor) {
+ gr->painter->begin(gr->widget);
+ }
+#endif
+ if (mode == draw_mode_end) {
+ if (gr->mode == draw_mode_begin) {
+ gr->painter->end();
+ gr->widget->update();
+ } else {
+#if QT_VERSION < 0x040000
+ gr->painter->end();
+#endif
+ }
+ }
+ gr->mode=mode;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h);
+
+static int argc=1;
+static char *argv[]={"navit",NULL};
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void * get_data(struct graphics_priv *this_, char *type)
+{
+ if (strcmp(type, "window"))
+ return NULL;
+ this_->painter=new QPainter;
+ this_->widget->show();
+ return &dummy;
+}
+
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void register_resize_callback(struct graphics_priv *this_, void (*callback)(void *data, int w, int h), void *data)
+{
+ this_->widget->resize_callback=callback;
+ this_->widget->resize_callback_data=data;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void register_motion_callback(struct graphics_priv *this_, void (*callback)(void *data, struct point *p), void *data)
+{
+ this_->widget->motion_callback=callback;
+ this_->widget->motion_callback_data=data;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void register_button_callback(struct graphics_priv *this_, void (*callback)(void *data, int press, int button, struct point *p), void *data)
+{
+ this_->widget->button_callback=callback;
+ this_->widget->button_callback_data=data;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static struct graphics_methods graphics_methods = {
+ graphics_destroy,
+ draw_mode,
+ draw_lines,
+ draw_polygon,
+ draw_rectangle,
+ draw_circle,
+ draw_text,
+ draw_image,
+ draw_image_warp,
+ draw_restore,
+ font_new,
+ gc_new,
+ background_gc,
+ overlay_new,
+ image_new,
+ get_data,
+ register_resize_callback,
+ register_button_callback,
+ register_motion_callback,
+};
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static struct graphics_priv * overlay_new(struct graphics_priv *gr, struct graphics_methods *meth, struct point *p, int w, int h)
+{
+ *meth=graphics_methods;
+ return NULL;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+#if QT_VERSION < 0x040000
+static gboolean graphics_qt_qpainter_idle(void *data)
+{
+ struct graphics_priv *gr=(struct graphics_priv *)data;
+ gr->app->processOneEvent();
+ return TRUE;
+}
+#endif
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static struct graphics_priv * graphics_qt_qpainter_new(struct graphics_methods *meth, struct attr **attrs)
+{
+ struct graphics_priv *ret=g_new0(struct graphics_priv, 1);
+ *meth=graphics_methods;
+ ret->app = new QApplication(argc, argv);
+ ret->widget= new RenderArea();
+#if QT_VERSION < 0x040000
+ g_idle_add(graphics_qt_qpainter_idle, ret);
+#endif
+
+ return ret;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void plugin_init(void)
+{
+ plugin_register_graphics_type("qt_qpainter", graphics_qt_qpainter_new);
+}
+
+
+
+
+// *** EOF ***
diff --git a/navit/gtkext.h b/navit/gtkext.h
new file mode 100644
index 000000000..572057bab
--- /dev/null
+++ b/navit/gtkext.h
@@ -0,0 +1,6 @@
+#ifndef NAVIT_GTKEXT_H
+#define NAVIT_GTKEXT_H
+
+void gdk_gc_set_fill_rule(GdkGC *gc, GdkFillRule fill_rule);
+
+#endif
diff --git a/navit/gui.c b/navit/gui.c
new file mode 100644
index 000000000..cc854e2bd
--- /dev/null
+++ b/navit/gui.c
@@ -0,0 +1,123 @@
+#include <glib.h>
+#include <string.h>
+#include "debug.h"
+#include "gui.h"
+#include "menu.h"
+#include "data_window.h"
+#include "item.h"
+#include "plugin.h"
+
+struct gui {
+ struct gui_methods meth;
+ struct gui_priv *priv;
+ struct attr **attrs;
+};
+
+struct gui *
+gui_new(struct attr *parent, struct attr **attrs)
+{
+ struct gui *this_;
+ struct attr *type_attr;
+ struct gui_priv *(*guitype_new)(struct navit *nav, struct gui_methods *meth, struct attr **attrs);
+ if (! (type_attr=attr_search(attrs, NULL, attr_type))) {
+ return NULL;
+ }
+
+ guitype_new=plugin_get_gui_type(type_attr->u.str);
+ if (! guitype_new)
+ return NULL;
+
+ this_=g_new0(struct gui, 1);
+ this_->priv=guitype_new(parent->u.navit, &this_->meth, attrs);
+ this_->attrs=attr_list_dup(attrs);
+ return this_;
+}
+
+int
+gui_get_attr(struct gui *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
+{
+ return attr_generic_get_attr(this_->attrs, type, attr, iter);
+}
+
+struct menu *
+gui_menubar_new(struct gui *gui)
+{
+ struct menu *this_;
+ if (! gui->meth.menubar_new)
+ return NULL;
+ this_=g_new0(struct menu, 1);
+ this_->priv=gui->meth.menubar_new(gui->priv, &this_->meth);
+ if (! this_->priv) {
+ g_free(this_);
+ return NULL;
+ }
+ return this_;
+}
+
+struct menu *
+gui_popup_new(struct gui *gui)
+{
+ struct menu *this_;
+ if (! gui->meth.popup_new)
+ return NULL;
+ this_=g_new0(struct menu, 1);
+ this_->priv=gui->meth.popup_new(gui->priv, &this_->meth);
+ if (! this_->priv) {
+ g_free(this_);
+ return NULL;
+ }
+ return this_;
+}
+
+struct datawindow *
+gui_datawindow_new(struct gui *gui, char *name, struct callback *click, struct callback *close)
+{
+ struct datawindow *this_;
+ if (! gui->meth.datawindow_new)
+ return NULL;
+ this_=g_new0(struct datawindow, 1);
+ this_->priv=gui->meth.datawindow_new(gui->priv, name, click, close, &this_->meth);
+ if (! this_->priv) {
+ g_free(this_);
+ return NULL;
+ }
+ return this_;
+}
+
+int
+gui_add_bookmark(struct gui *gui, struct pcoord *c, char *description)
+{
+ int ret;
+ dbg(2,"enter\n");
+ if (! gui->meth.add_bookmark)
+ return 0;
+ ret=gui->meth.add_bookmark(gui->priv, c, description);
+
+ dbg(2,"ret=%d\n", ret);
+ return ret;
+}
+
+int
+gui_set_graphics(struct gui *this_, struct graphics *gra)
+{
+ if (! this_->meth.set_graphics)
+ return 1;
+ return this_->meth.set_graphics(this_->priv, gra);
+}
+
+int
+gui_has_main_loop(struct gui *this_)
+{
+ if (! this_->meth.run_main_loop)
+ return 0;
+ return 1;
+}
+
+int
+gui_run_main_loop(struct gui *this_)
+{
+ if (! gui_has_main_loop(this_))
+ return 1;
+ return this_->meth.run_main_loop(this_->priv);
+}
+
diff --git a/navit/gui.h b/navit/gui.h
new file mode 100644
index 000000000..9f170f760
--- /dev/null
+++ b/navit/gui.h
@@ -0,0 +1,46 @@
+#ifndef NAVIT_GUI_H
+#define NAVIT_GUI_H
+
+struct navit;
+struct gui_priv;
+struct menu_methods;
+struct datawindow_methods;
+struct callback;
+struct graphics;
+struct coord;
+struct pcoord;
+
+struct gui_methods {
+ struct menu_priv *(*menubar_new)(struct gui_priv *priv, struct menu_methods *meth);
+ struct menu_priv *(*popup_new)(struct gui_priv *priv, struct menu_methods *meth);
+ int (*set_graphics)(struct gui_priv *priv, struct graphics *gra);
+ int (*run_main_loop)(struct gui_priv *priv);
+ struct datawindow_priv *(*datawindow_new)(struct gui_priv *priv, char *name, struct callback *click, struct callback *close, struct datawindow_methods *meth);
+ int (*add_bookmark)(struct gui_priv *priv, struct pcoord *c, char *description);
+};
+
+
+/* prototypes */
+enum attr_type;
+struct attr;
+struct attr_iter;
+struct callback;
+struct datawindow;
+struct graphics;
+struct gui;
+struct menu;
+struct navit;
+struct pcoord;
+struct gui *gui_new(struct attr *parent, struct attr **attrs);
+int gui_get_attr(struct gui *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter);
+struct menu *gui_menubar_new(struct gui *gui);
+struct menu *gui_popup_new(struct gui *gui);
+struct datawindow *gui_datawindow_new(struct gui *gui, char *name, struct callback *click, struct callback *close);
+int gui_add_bookmark(struct gui *gui, struct pcoord *c, char *description);
+int gui_set_graphics(struct gui *this_, struct graphics *gra);
+int gui_has_main_loop(struct gui *this_);
+int gui_run_main_loop(struct gui *this_);
+/* end of prototypes */
+
+#endif
+
diff --git a/navit/gui/Makefile.am b/navit/gui/Makefile.am
new file mode 100644
index 000000000..1f368df61
--- /dev/null
+++ b/navit/gui/Makefile.am
@@ -0,0 +1,8 @@
+SUBDIRS=internal
+if GUI_GTK
+ SUBDIRS += gtk
+endif
+if GUI_SDL
+ SUBDIRS += sdl
+endif
+
diff --git a/navit/gui/gtk/Makefile.am b/navit/gui/gtk/Makefile.am
new file mode 100644
index 000000000..128a3fb79
--- /dev/null
+++ b/navit/gui/gtk/Makefile.am
@@ -0,0 +1,5 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = -I$(top_srcdir)/src @NAVIT_CFLAGS@ @GTK2_CFLAGS@ -DMODULE=gui_gtk
+modulegui_LTLIBRARIES = libgui_gtk.la
+libgui_gtk_la_SOURCES = datawindow.c destination.c gui_gtk_statusbar.c gui_gtk_action.c gui_gtk_window.c gui_gtk.h
+libgui_gtk_la_LIBADD = @GTK2_LIBS@
diff --git a/navit/gui/gtk/datawindow.c b/navit/gui/gtk/datawindow.c
new file mode 100644
index 000000000..d9452ac48
--- /dev/null
+++ b/navit/gui/gtk/datawindow.c
@@ -0,0 +1,171 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+#include "debug.h"
+#include "callback.h"
+#include "param.h"
+#include "data_window.h"
+#include "gui_gtk.h"
+
+struct datawindow_priv {
+ GtkWidget *window;
+ GtkWidget *scrolled_window;
+ GtkWidget *treeview;
+ GtkListStore *liststore;
+ GtkTreeModel *sortmodel;
+ struct callback *click, *close;
+};
+
+static void
+gui_gtk_datawindow_destroy(struct datawindow_priv *win)
+{
+ return;
+}
+
+static GValue value;
+static void
+select_row(GtkTreeView *tree, GtkTreePath *path, GtkTreeViewColumn *column, struct datawindow_priv *win)
+{
+ char *cols[20];
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ int i;
+
+ dbg(0,"win=%p\n", win);
+
+ model=gtk_tree_view_get_model(tree);
+ gtk_tree_model_get_iter(model, &iter, path);
+
+ for (i=0;i<gtk_tree_model_get_n_columns(model);i++) {
+ gtk_tree_model_get_value(model, &iter, i, &value);
+ cols[i]=g_strdup_value_contents(&value)+1;
+ cols[i][strlen(cols[i])-1]='\0';
+ g_value_unset(&value);
+ }
+ callback_call_1(win->click, cols);
+}
+
+static void
+gui_gtk_datawindow_add(struct datawindow_priv *win, struct param_list *param, int count)
+{
+ int i;
+ GtkCellRenderer *cell;
+ GtkTreeIter iter;
+ GType types[count];
+
+ if (! win->treeview) {
+ win->treeview=gtk_tree_view_new();
+ gtk_tree_view_set_model (GTK_TREE_VIEW (win->treeview), NULL);
+ gtk_container_add(GTK_CONTAINER(win->scrolled_window), win->treeview);
+ gtk_widget_show_all(GTK_WIDGET(win->window));
+ gtk_widget_grab_focus(GTK_WIDGET(win->treeview));
+
+ /* add column names to treeview */
+ for(i=0;i<count;i++) {
+ if (param[i].name) {
+ cell=gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (win->treeview),-1,param[i].name,
+ cell,"text",i, NULL);
+ }
+ }
+#if 0
+ g_signal_connect(G_OBJECT(win->treeview), "click-column", G_CALLBACK(click_column), NULL);
+#endif
+ g_signal_connect(G_OBJECT(win->treeview), "row-activated", G_CALLBACK(select_row), win);
+ }
+
+ /* find data storage and create a new one if none is there */
+ if (gtk_tree_view_get_model(GTK_TREE_VIEW (win->treeview)) == NULL) {
+ for(i=0;i<count;i++) {
+ if (param[i].name && !strcmp(param[i].name, "Distance"))
+ types[i]=G_TYPE_INT;
+ else
+ types[i]=G_TYPE_STRING;
+ }
+ win->liststore=gtk_list_store_newv(count,types);
+ if (! strcmp(param[0].name, "Distance")) {
+ win->sortmodel=gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(win->liststore));
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (win->sortmodel), 0, GTK_SORT_ASCENDING);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (win->treeview), GTK_TREE_MODEL(win->sortmodel));
+ } else
+ gtk_tree_view_set_model (GTK_TREE_VIEW (win->treeview), GTK_TREE_MODEL(win->liststore));
+ }
+
+ gtk_list_store_append(win->liststore,&iter);
+
+ /* add data to data storage */
+ for(i=0;i<count;i++) {
+ if (param[i].name && !strcmp(param[i].name, "Distance")) {
+ gtk_list_store_set(win->liststore,&iter,i,atoi(param[i].value),-1);
+ } else {
+ gtk_list_store_set(win->liststore,&iter,i,param[i].value,-1);
+ }
+ }
+}
+
+static void
+gui_gtk_datawindow_mode(struct datawindow_priv *win, int start)
+{
+ if (start) {
+ if (win && win->treeview) {
+ gtk_tree_view_set_model (GTK_TREE_VIEW (win->treeview), NULL);
+ }
+ }
+}
+
+static gboolean
+gui_gtk_datawindow_delete(GtkWidget *widget, GdkEvent *event, struct datawindow_priv *win)
+{
+ callback_call_0(win->close);
+
+ return FALSE;
+}
+
+static gboolean
+keypress(GtkWidget *widget, GdkEventKey *event, struct datawindow_priv *win)
+{
+ if (event->type != GDK_KEY_PRESS)
+ return FALSE;
+ if (event->keyval == GDK_Cancel) {
+ gui_gtk_datawindow_delete(widget, event, win);
+ gtk_widget_destroy(win->window);
+ }
+ return FALSE;
+}
+
+
+static struct datawindow_methods gui_gtk_datawindow_meth = {
+ gui_gtk_datawindow_destroy,
+ gui_gtk_datawindow_add,
+ gui_gtk_datawindow_mode,
+};
+
+struct datawindow_priv *
+gui_gtk_datawindow_new(struct gui_priv *gui, char *name, struct callback *click, struct callback *close, struct datawindow_methods *meth)
+{
+ struct datawindow_priv *win;
+
+ *meth=gui_gtk_datawindow_meth;
+ win=g_new0(struct datawindow_priv, 1);
+ win->window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_default_size(GTK_WINDOW(win->window), 320, 200);
+ gtk_window_set_title(GTK_WINDOW(win->window), name);
+
+ win->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (win->scrolled_window),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add(GTK_CONTAINER(win->window), win->scrolled_window);
+ g_signal_connect(G_OBJECT(win->window), "key-press-event", G_CALLBACK(keypress), win);
+ win->treeview=NULL;
+ win->click=click;
+ win->close=close;
+ if (gui)
+ gtk_window_set_transient_for(GTK_WINDOW((GtkWidget *)(win->window)), GTK_WINDOW(gui->win));
+ g_signal_connect(G_OBJECT(win->window), "delete-event", G_CALLBACK(gui_gtk_datawindow_delete), win);
+ gtk_widget_show_all(win->window);
+ return win;
+ return NULL;
+}
+
diff --git a/navit/gui/gtk/destination.c b/navit/gui/gtk/destination.c
new file mode 100644
index 000000000..05f178e8f
--- /dev/null
+++ b/navit/gui/gtk/destination.c
@@ -0,0 +1,505 @@
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <libintl.h>
+#include <gtk/gtk.h>
+#include "debug.h"
+#include "destination.h"
+#include "navit.h"
+#include "item.h"
+#include "coord.h"
+#include "track.h"
+#include "country.h"
+#include "search.h"
+#include "projection.h"
+
+#define COL_COUNT 8
+
+#define gettext_noop(String) String
+#define _(STRING) gettext(STRING)
+#define _n(STRING) gettext_noop(STRING)
+
+static struct search_param {
+ struct navit *nav;
+ struct mapset *ms;
+ struct search_list *sl;
+ struct attr attr;
+ int partial;
+ GtkWidget *entry_country, *entry_postal, *entry_city, *entry_district;
+ GtkWidget *entry_street, *entry_number;
+ GtkWidget *listbox;
+ GtkWidget *treeview;
+ GtkListStore *liststore;
+ GtkTreeModel *liststore2;
+} search_param;
+
+static void button_map(GtkWidget *widget, struct search_param *search)
+{
+ struct pcoord *c=NULL;
+ GtkTreeIter iter;
+ if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (search->liststore2), &iter))
+ return;
+ gtk_tree_model_get (GTK_TREE_MODEL (search->liststore2), &iter, COL_COUNT, &c, -1);
+ if (c) {
+ navit_set_center(search->nav, c);
+ }
+}
+
+static char *description(struct search_param *search, GtkTreeIter *iter)
+{
+ char *desc,*car,*postal,*town,*street;
+ gtk_tree_model_get (GTK_TREE_MODEL (search->liststore2), iter, 0, &car, -1);
+ gtk_tree_model_get (GTK_TREE_MODEL (search->liststore2), iter, 1, &postal, -1);
+ gtk_tree_model_get (GTK_TREE_MODEL (search->liststore2), iter, 2, &town, -1);
+ gtk_tree_model_get (GTK_TREE_MODEL (search->liststore2), iter, 4, &street, -1);
+ if (search->attr.type == attr_town_name)
+ desc=g_strdup_printf("%s-%s %s", car, postal, town);
+ else
+ desc=g_strdup_printf("%s-%s %s, %s", car, postal, town, street);
+ return desc;
+}
+
+static void button_destination(GtkWidget *widget, struct search_param *search)
+{
+ struct pcoord *c=NULL;
+ GtkTreeIter iter;
+ char *desc;
+
+ if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (search->liststore2), &iter))
+ return;
+ gtk_tree_model_get (GTK_TREE_MODEL (search->liststore2), &iter, COL_COUNT, &c, -1);
+ if (c) {
+ desc=description(search, &iter);
+ navit_set_destination(search->nav, c, desc);
+ g_free(desc);
+ }
+}
+
+static void button_bookmark(GtkWidget *widget, struct search_param *search)
+{
+ struct pcoord *c=NULL;
+ GtkTreeIter iter;
+ char *desc;
+
+ if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (search->liststore2), &iter))
+ return;
+ gtk_tree_model_get (GTK_TREE_MODEL (search->liststore2), &iter, COL_COUNT, &c, -1);
+ if (c) {
+ desc=description(search, &iter);
+ navit_add_bookmark(search->nav, c, desc);
+ g_free(desc);
+ }
+}
+
+
+char **columns_text[] = {
+ (char *[]){_n("Car"),_n("Iso2"),_n("Iso3"),_n("Country"),NULL},
+ (char *[]){_n("Car"),_n("Postal"),_n("Town"),_n("District"),NULL},
+ (char *[]){_n("Car"),_n("Postal"),_n("Town"),_n("District"),_n("Street"),NULL},
+ (char *[]){_n("Car"),_n("Postal"),_n("Town"),_n("District"),_n("Street"),_n("Number"),NULL},
+};
+
+static void set_columns(struct search_param *param, int mode)
+{
+ GList *columns_list,*columns;
+ char **column_text=columns_text[mode];
+ int i=0;
+
+ columns_list=gtk_tree_view_get_columns(GTK_TREE_VIEW(param->treeview));
+ columns=columns_list;
+ while (columns) {
+ gtk_tree_view_remove_column(GTK_TREE_VIEW(param->treeview), columns->data);
+ columns=g_list_next(columns);
+ }
+ g_list_free(columns_list);
+ while (*column_text) {
+ printf("column_text=%p\n", column_text);
+ printf("*column_text=%s\n", *column_text);
+ GtkCellRenderer *cell=gtk_cell_renderer_text_new();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (param->treeview),-1, gettext(*column_text), cell, "text", i, NULL);
+ i++;
+ column_text++;
+ }
+
+}
+
+static void row_activated(GtkWidget *widget, GtkTreePath *p1, GtkTreeViewColumn *c, struct search_param *search)
+{
+ GtkTreePath *path;
+ GtkTreeViewColumn *focus_column;
+ GtkTreeIter iter;
+ GtkWidget *entry_widget;
+ char *str;
+ int column;
+
+ dbg(0,"enter\n");
+ gtk_tree_view_get_cursor(GTK_TREE_VIEW(search->treeview), &path, &focus_column);
+ gtk_tree_model_get_iter(search->liststore2, &iter, path);
+ switch(search->attr.type) {
+ case attr_country_all:
+ entry_widget=search->entry_country;
+ column=3;
+ break;
+ case attr_town_name:
+ entry_widget=search->entry_city;
+ column=2;
+ break;
+ case attr_street_name:
+ entry_widget=search->entry_street;
+ column=4;
+ break;
+ default:
+ dbg(0,"Unknown mode\n");
+ return;
+ }
+ gtk_tree_model_get(search->liststore2, &iter, column, &str, -1);
+ dbg(0,"str=%s\n", str);
+ search->partial=0;
+ gtk_entry_set_text(GTK_ENTRY(entry_widget), str);
+}
+
+static void tree_view_button_release(GtkWidget *widget, GdkEventButton *event, struct search_param *search)
+{
+ GtkTreePath *path;
+ GtkTreeViewColumn *column;
+ gtk_tree_view_get_cursor(GTK_TREE_VIEW(search->treeview), &path, &column);
+ gtk_tree_view_row_activated(GTK_TREE_VIEW(search->treeview), path, column);
+
+}
+static void
+next_focus(struct search_param *search, GtkWidget *widget)
+{
+ if (widget == search->entry_country)
+ gtk_widget_grab_focus(search->entry_city);
+ if (widget == search->entry_city)
+ gtk_widget_grab_focus(search->entry_street);
+ if (widget == search->entry_street)
+ gtk_widget_grab_focus(search->entry_number);
+
+}
+
+static void changed(GtkWidget *widget, struct search_param *search)
+{
+ struct search_list_result *res;
+ GtkTreeIter iter;
+
+ search->attr.u.str=(char *)gtk_entry_get_text(GTK_ENTRY(widget));
+ printf("changed %s partial %d\n", search->attr.u.str, search->partial);
+ if (widget == search->entry_country) {
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (search->liststore2), 3, GTK_SORT_ASCENDING);
+ dbg(0,"country\n");
+ search->attr.type=attr_country_all;
+ set_columns(search, 0);
+ }
+ if (widget == search->entry_postal) {
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (search->liststore2), 1, GTK_SORT_ASCENDING);
+ dbg(0,"postal\n");
+ search->attr.type=attr_town_postal;
+ if (strlen(search->attr.u.str) < 2)
+ return;
+ set_columns(search, 1);
+ }
+ if (widget == search->entry_city) {
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (search->liststore2), 2, GTK_SORT_ASCENDING);
+ dbg(0,"town\n");
+ search->attr.type=attr_town_name;
+ if (strlen(search->attr.u.str) < 3)
+ return;
+ set_columns(search, 1);
+ }
+ if (widget == search->entry_street) {
+ dbg(0,"street\n");
+ search->attr.type=attr_street_name;
+ set_columns(search, 2);
+ }
+
+
+ search_list_search(search->sl, &search->attr, search->partial);
+ gtk_list_store_clear(search->liststore);
+ while((res=search_list_get_result(search->sl))) {
+ gtk_list_store_append(search->liststore,&iter);
+ gtk_list_store_set(search->liststore,&iter,COL_COUNT,res->c,-1);
+ if (widget == search->entry_country) {
+ if (res->country) {
+ gtk_list_store_set(search->liststore,&iter,0,res->country->car,-1);
+ gtk_list_store_set(search->liststore,&iter,1,res->country->iso3,-1);
+ gtk_list_store_set(search->liststore,&iter,2,res->country->iso2,-1);
+ gtk_list_store_set(search->liststore,&iter,3,res->country->name,-1);
+ }
+ } else {
+ if (res->country)
+ gtk_list_store_set(search->liststore,&iter,0,res->country->car,-1);
+ else
+ gtk_list_store_set(search->liststore,&iter,0,"",-1);
+ if (res->town) {
+ gtk_list_store_set(search->liststore,&iter,1,res->town->postal,-1);
+ gtk_list_store_set(search->liststore,&iter,2,res->town->name,-1);
+ gtk_list_store_set(search->liststore,&iter,3,res->town->district,-1);
+ } else {
+ gtk_list_store_set(search->liststore,&iter,1,"",-1);
+ gtk_list_store_set(search->liststore,&iter,2,"",-1);
+ gtk_list_store_set(search->liststore,&iter,3,"",-1);
+ }
+ if (res->street)
+ gtk_list_store_set(search->liststore,&iter,4,res->street->name,-1);
+ else
+ gtk_list_store_set(search->liststore,&iter,4,"",-1);
+
+ }
+ }
+ if (! search->partial)
+ next_focus(search, widget);
+ search->partial=1;
+}
+
+/* borrowed from gpe-login */
+
+
+#define MAX_ARGS 8
+
+static void
+parse_xkbd_args (const char *cmd, char **argv)
+{
+ const char *p = cmd;
+ char buf[strlen (cmd) + 1], *bufp = buf;
+ int nargs = 0;
+ int escape = 0, squote = 0, dquote = 0;
+
+ while (*p)
+ {
+ if (escape)
+ {
+ *bufp++ = *p;
+ escape = 0;
+ }
+ else
+ {
+ switch (*p)
+ {
+ case '\\':
+ escape = 1;
+ break;
+ case '"':
+ if (squote)
+ *bufp++ = *p;
+ else
+ dquote = !dquote;
+ break;
+ case '\'':
+ if (dquote)
+ *bufp++ = *p;
+ else
+ squote = !squote;
+ break;
+ case ' ':
+ if (!squote && !dquote)
+ {
+ *bufp = 0;
+ if (nargs < MAX_ARGS)
+ argv[nargs++] = strdup (buf);
+ bufp = buf;
+ break;
+ }
+ default:
+ *bufp++ = *p;
+ break;
+ }
+ }
+ p++;
+ }
+
+ if (bufp != buf)
+ {
+ *bufp = 0;
+ if (nargs < MAX_ARGS)
+ argv[nargs++] = strdup (buf);
+ }
+ argv[nargs] = NULL;
+}
+
+int kbd_pid;
+
+static int
+spawn_xkbd (char *xkbd_path, char *xkbd_str)
+{
+#ifdef _WIN32 // AF FIXME for WIN32
+ #ifndef F_SETFD
+ #define F_SETFD 2
+ #endif
+#else
+ char *xkbd_args[MAX_ARGS + 1];
+ int fd[2];
+ char buf[256];
+ char c;
+ int a = 0;
+ size_t n;
+
+ pipe (fd);
+ kbd_pid = fork ();
+ if (kbd_pid == 0)
+ {
+ close (fd[0]);
+ if (dup2 (fd[1], 1) < 0)
+ perror ("dup2");
+ close (fd[1]);
+ if (fcntl (1, F_SETFD, 0))
+ perror ("fcntl");
+ xkbd_args[0] = (char *)xkbd_path;
+ xkbd_args[1] = "-xid";
+ if (xkbd_str)
+ parse_xkbd_args (xkbd_str, xkbd_args + 2);
+ else
+ xkbd_args[2] = NULL;
+ execvp (xkbd_path, xkbd_args);
+ perror (xkbd_path);
+ _exit (1);
+ }
+ close (fd[1]);
+ do {
+ n = read (fd[0], &c, 1);
+ if (n)
+ {
+ buf[a++] = c;
+ }
+ } while (n && (c != 10) && (a < (sizeof (buf) - 1)));
+
+ if (a)
+ {
+ buf[a] = 0;
+ return atoi (buf);
+ }
+#endif
+ return 0;
+}
+
+int destination_address(struct navit *nav)
+{
+
+ GtkWidget *window2, *keyboard, *vbox, *table;
+ GtkWidget *label_country;
+ GtkWidget *label_postal, *label_city, *label_district;
+ GtkWidget *label_street, *label_number;
+ GtkWidget *hseparator1,*hseparator2;
+ GtkWidget *button1,*button2,*button3;
+ int i;
+ struct search_param *search=&search_param;
+ struct attr search_attr, country_name, *country_attr;
+ struct tracking *tracking;
+ struct country_search *cs;
+ struct item *item;
+
+
+ search->nav=nav;
+ search->ms=navit_get_mapset(nav);
+ search->sl=search_list_new(search->ms);
+
+ window2 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(window2),_("Enter Destination"));
+ vbox = gtk_vbox_new(FALSE, 0);
+ table = gtk_table_new(3, 8, FALSE);
+
+ search->entry_country = gtk_entry_new();
+ label_country = gtk_label_new(_("Country"));
+ search->entry_postal = gtk_entry_new();
+ label_postal = gtk_label_new(_("Zip Code"));
+ search->entry_city = gtk_entry_new();
+ label_city = gtk_label_new(_("City"));
+ search->entry_district = gtk_entry_new();
+ label_district = gtk_label_new(_("District/Township"));
+ hseparator1 = gtk_vseparator_new();
+ search->entry_street = gtk_entry_new();
+ label_street = gtk_label_new(_("Street"));
+ search->entry_number = gtk_entry_new();
+ label_number = gtk_label_new(_("Number"));
+ search->treeview=gtk_tree_view_new();
+ search->listbox = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (search->listbox),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (search->treeview), NULL);
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(search->listbox),search->treeview);
+ {
+ GType types[COL_COUNT+1];
+ for(i=0;i<COL_COUNT;i++)
+ types[i]=G_TYPE_STRING;
+ types[i]=G_TYPE_POINTER;
+ search->liststore=gtk_list_store_newv(COL_COUNT+1,types);
+ search->liststore2=gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(search->liststore));
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (search->liststore2), 3, GTK_SORT_ASCENDING);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (search->treeview), GTK_TREE_MODEL(search->liststore2));
+ }
+
+
+
+
+ hseparator2 = gtk_vseparator_new();
+ button1 = gtk_button_new_with_label(_("Map"));
+ button2 = gtk_button_new_with_label(_("Bookmark"));
+ button3 = gtk_button_new_with_label(_("Destination"));
+
+ gtk_table_attach(GTK_TABLE(table), label_country, 0, 1, 0, 1, 0, GTK_FILL, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), label_postal, 1, 2, 0, 1, 0, GTK_FILL, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), label_city, 2, 3, 0, 1, 0, GTK_FILL, 0, 0);
+
+ gtk_table_attach(GTK_TABLE(table), search->entry_country, 0, 1, 1, 2, 0, GTK_FILL, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), search->entry_postal, 1, 2, 1, 2, 0, GTK_FILL, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), search->entry_city, 2, 3, 1, 2, 0, GTK_FILL, 0, 0);
+
+ gtk_table_attach(GTK_TABLE(table), label_district, 0, 1, 2, 3, 0, GTK_FILL, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), label_street, 1, 2, 2, 3, 0, GTK_FILL, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), label_number, 2, 3, 2, 3, 0, GTK_FILL, 0, 0);
+
+ gtk_table_attach(GTK_TABLE(table), search->entry_district, 0, 1, 3, 4, 0, GTK_FILL, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), search->entry_street, 1, 2, 3, 4, 0, GTK_FILL, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), search->entry_number, 2, 3, 3, 4, 0, GTK_FILL, 0, 0);
+
+ gtk_table_attach(GTK_TABLE(table), search->listbox, 0, 3, 4, 5, GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
+
+ gtk_table_attach(GTK_TABLE(table), button1, 0, 1, 5, 6, GTK_FILL, GTK_FILL, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), button2, 1, 2, 5, 6, GTK_FILL, GTK_FILL, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), button3, 2, 3, 5, 6, GTK_FILL, GTK_FILL, 0, 0);
+
+ g_signal_connect(G_OBJECT(search->entry_country), "changed", G_CALLBACK(changed), search);
+ g_signal_connect(G_OBJECT(search->entry_postal), "changed", G_CALLBACK(changed), search);
+ g_signal_connect(G_OBJECT(search->entry_city), "changed", G_CALLBACK(changed), search);
+ g_signal_connect(G_OBJECT(search->entry_district), "changed", G_CALLBACK(changed), search);
+ g_signal_connect(G_OBJECT(search->entry_street), "changed", G_CALLBACK(changed), search);
+ g_signal_connect(G_OBJECT(search->entry_number), "changed", G_CALLBACK(changed), search);
+ g_signal_connect(G_OBJECT(button1), "clicked", G_CALLBACK(button_map), search);
+ g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK(button_bookmark), search);
+ g_signal_connect(G_OBJECT(button3), "clicked", G_CALLBACK(button_destination), search);
+ g_signal_connect(G_OBJECT(search->treeview), "button-release-event", G_CALLBACK(tree_view_button_release), search);
+ g_signal_connect(G_OBJECT(search->treeview), "row_activated", G_CALLBACK(row_activated), search);
+
+ gtk_widget_grab_focus(search->entry_city);
+
+ gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
+ keyboard=gtk_socket_new();
+ gtk_box_pack_end(GTK_BOX(vbox), keyboard, FALSE, FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(window2), vbox);
+#if 0
+ g_signal_connect(G_OBJECT(listbox), "select-row", G_CALLBACK(select_row), NULL);
+#endif
+ gtk_widget_show_all(window2);
+
+#ifndef _WIN32
+ gtk_socket_steal(GTK_SOCKET(keyboard), spawn_xkbd("xkbd","-geometry 200x100"));
+#endif
+
+ country_attr=country_default();
+ tracking=navit_get_tracking(nav);
+ if (tracking && tracking_get_current_attr(tracking, attr_country_id, &search_attr))
+ country_attr=&search_attr;
+ if (country_attr) {
+ cs=country_search_new(country_attr, 0);
+ item=country_search_get_item(cs);
+ if (item && item_attr_get(item, attr_country_name, &country_name))
+ gtk_entry_set_text(GTK_ENTRY(search->entry_country), country_name.u.str);
+ country_search_destroy(cs);
+ } else {
+ dbg(0,"warning: no default country found\n");
+ }
+ search->partial=1;
+ return 0;
+}
diff --git a/navit/gui/gtk/gui_gtk.h b/navit/gui/gtk/gui_gtk.h
new file mode 100644
index 000000000..ddf8e7f2e
--- /dev/null
+++ b/navit/gui/gtk/gui_gtk.h
@@ -0,0 +1,36 @@
+#include "coord.h"
+
+struct menu_methods;
+struct datawindow_methods;
+struct navit;
+struct callback;
+struct statusbar_priv;
+
+struct gui_priv {
+ struct navit *nav;
+ GtkWidget *win;
+ GtkWidget *dialog_win;
+ GtkWidget *dialog_entry;
+ struct pcoord dialog_coord;
+ GtkWidget *vbox;
+ GtkWidget *menubar;
+ GtkActionGroup *base_group;
+ GtkActionGroup *debug_group;
+ GtkActionGroup *dyn_group;
+ GtkUIManager *ui_manager;
+ GSList *layout_group;
+ GSList *projection_group;
+ GSList *vehicle_group;
+ GtkUIManager *menu_manager; // old
+ struct statusbar_priv *statusbar;
+ int menubar_enable;
+ int toolbar_enable;
+ int statusbar_enable;
+ int dyn_counter;
+};
+
+void gui_gtk_ui_init(struct gui_priv *this);
+struct menu_priv *gui_gtk_menubar_new(struct gui_priv *gui, struct menu_methods *meth);
+struct statusbar_priv *gui_gtk_statusbar_new(struct gui_priv *gui);
+struct menu_priv *gui_gtk_popup_new(struct gui_priv *gui, struct menu_methods *meth);
+struct datawindow_priv *gui_gtk_datawindow_new(struct gui_priv *gui, char *name, struct callback *click, struct callback *close, struct datawindow_methods *meth);
diff --git a/navit/gui/gtk/gui_gtk_action.c b/navit/gui/gtk/gui_gtk_action.c
new file mode 100644
index 000000000..3feb08cae
--- /dev/null
+++ b/navit/gui/gtk/gui_gtk_action.c
@@ -0,0 +1,569 @@
+#include <string.h>
+#include <gtk/gtk.h>
+#include "navit.h"
+#include "gui_gtk.h"
+#include "menu.h"
+#include "coord.h"
+#include "item.h"
+#include "attr.h"
+#include "callback.h"
+#include "debug.h"
+#include "destination.h"
+
+#define gettext_noop(String) String
+#define _(STRING) gettext(STRING)
+#define _n(STRING) gettext_noop(STRING)
+
+struct menu_priv {
+ char *path;
+ GtkAction *action;
+ struct gui_priv *gui;
+ enum menu_type type;
+ struct callback *cb;
+ struct menu_priv *child;
+ struct menu_priv *sibling;
+ gulong handler_id;
+ guint merge_id;
+ GtkWidget *widget;
+};
+
+/* Create callbacks that implement our Actions */
+
+static void
+zoom_in_action(GtkWidget *w, struct gui_priv *gui, void *dummy)
+{
+ navit_zoom_in(gui->nav, 2, NULL);
+}
+
+static void
+zoom_out_action(GtkWidget *w, struct gui_priv *gui, void *dummy)
+{
+ navit_zoom_out(gui->nav, 2, NULL);
+}
+
+static void
+refresh_action(GtkWidget *w, struct gui_priv *gui, void *dummy)
+{
+ navit_draw(gui->nav);
+}
+
+static void
+roadbook_action(GtkWidget *w, struct gui_priv *gui, void *dummy)
+{
+ navit_window_roadbook_new(gui->nav);
+}
+
+static void
+cursor_action(GtkWidget *w, struct gui_priv *gui, void *dummy)
+{
+ struct attr attr;
+
+ attr.type=attr_cursor;
+ attr.u.num=gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(w));
+ if(!navit_set_attr(gui->nav, &attr)) {
+ dbg(0, "Failed to set attr_cursor\n");
+ }
+}
+
+static void
+tracking_action(GtkWidget *w, struct gui_priv *gui, void *dummy)
+{
+ struct attr attr;
+
+ attr.type=attr_tracking;
+ attr.u.num=gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(w));
+ if(!navit_set_attr(gui->nav, &attr)) {
+ dbg(0, "Failed to set attr_tracking\n");
+ }
+}
+
+static void
+orient_north_action(GtkWidget *w, struct gui_priv *gui, void *dummy)
+{
+ struct attr attr;
+
+ attr.type=attr_orientation;
+ attr.u.num=gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(w));
+ if(!navit_set_attr(gui->nav, &attr)) {
+ dbg(0, "Failed to set attr_orientation\n");
+ }
+}
+
+static void
+window_fullscreen_action(GtkWidget *w, struct gui_priv *gui, void *dummy)
+{
+ if(gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(w)))
+ gtk_window_fullscreen(GTK_WINDOW(gui->win));
+ else
+ gtk_window_unfullscreen(GTK_WINDOW(gui->win));
+}
+
+#include <stdlib.h>
+#include "point.h"
+#include "transform.h"
+
+static void
+info_action(GtkWidget *w, struct gui_priv *gui, void *dummy)
+{
+ char buffer[512];
+ int mw,mh;
+ struct coord lt, rb;
+ struct point p;
+ struct transformation *t;
+
+ t=navit_get_trans(gui->nav);
+ transform_get_size(t, &mw, &mh);
+ p.x=0;
+ p.y=0;
+ transform_reverse(t, &p, &lt);
+ p.x=mw;
+ p.y=mh;
+ transform_reverse(t, &p, &rb);
+
+ sprintf(buffer,"./info.sh %d,%d 0x%x,0x%x 0x%x,0x%x", mw, mh, lt.x, lt.y, rb.x, rb.y);
+ system(buffer);
+
+}
+
+
+static void
+route_clear_action(GtkWidget *w, struct gui_priv *gui, void *dummy)
+{
+ navit_set_destination(gui->nav, NULL, NULL);
+}
+
+static void
+destination_action(GtkWidget *w, struct gui_priv *gui, void *dummy)
+{
+ destination_address(gui->nav);
+}
+
+static void
+quit_action (GtkWidget *w, struct gui_priv *gui, void *dummy)
+{
+ navit_destroy(gui->nav);
+}
+
+static GtkActionEntry entries[] =
+{
+ { "DisplayMenuAction", NULL, _n("Display") },
+ { "RouteMenuAction", NULL, _n("Route") },
+ { "FormerDestinationMenuAction", NULL, _n("Former Destinations") },
+ { "BookmarkMenuAction", NULL, _n("Bookmarks") },
+ { "MapMenuAction", NULL, _n("Map") },
+ { "LayoutMenuAction", NULL, _n("Layout") },
+ { "ProjectionMenuAction", NULL, _n("Projection") },
+ { "VehicleMenuAction", NULL, _n("Vehicle") },
+ { "ZoomOutAction", GTK_STOCK_ZOOM_OUT, _n("ZoomOut"), NULL, NULL, G_CALLBACK(zoom_out_action) },
+ { "ZoomInAction", GTK_STOCK_ZOOM_IN, _n("ZoomIn"), NULL, NULL, G_CALLBACK(zoom_in_action) },
+ { "RefreshAction", GTK_STOCK_REFRESH, _n("Refresh"), NULL, NULL, G_CALLBACK(refresh_action) },
+ { "RoadbookAction", GTK_STOCK_JUSTIFY_FILL, _n("Roadbook"), NULL, NULL, G_CALLBACK(roadbook_action) },
+#ifdef GTK_STOCK_INFO
+ { "InfoAction", GTK_STOCK_INFO, _n("Info"), NULL, NULL, G_CALLBACK(info_action) },
+#else
+ { "InfoAction", NULL, _n("Info"), NULL, NULL, G_CALLBACK(info_action) },
+#endif /*GTK_STOCK_INFO*/
+ { "DestinationAction", "flag_icon", _n("Destination"), NULL, NULL, G_CALLBACK(destination_action) },
+ { "RouteClearAction", NULL, _n("Clear"), NULL, NULL, G_CALLBACK(route_clear_action) },
+ { "Test", NULL, _n("Test"), NULL, NULL, G_CALLBACK(destination_action) },
+ { "QuitAction", GTK_STOCK_QUIT, _n("_Quit"), "<control>Q",NULL, G_CALLBACK (quit_action) }
+};
+
+static guint n_entries = G_N_ELEMENTS (entries);
+
+static GtkToggleActionEntry toggleentries[] =
+{
+ { "CursorAction", "cursor_icon",_n("Cursor"), NULL, NULL, G_CALLBACK(cursor_action),TRUE },
+ { "TrackingAction", NULL ,_n("Tracking"), NULL, NULL, G_CALLBACK(tracking_action),TRUE },
+ { "OrientationAction", "orientation_icon", _n("Orientation"), NULL, NULL, G_CALLBACK(orient_north_action),FALSE },
+#ifdef GTK_STOCK_FULLSCREEN
+ { "FullscreenAction",GTK_STOCK_FULLSCREEN, _n("Fullscreen"), NULL, NULL, G_CALLBACK(window_fullscreen_action), FALSE }
+#else
+ { "FullscreenAction", NULL, _n("Fullscreen"), NULL, NULL, G_CALLBACK(window_fullscreen_action), FALSE }
+#endif /*GTK_STOCK_FULLSCREEN*/
+};
+
+static guint n_toggleentries = G_N_ELEMENTS (toggleentries);
+
+static GtkActionEntry debug_entries[] =
+{
+ { "DataMenuAction", NULL, _n("Data") },
+};
+
+static guint n_debug_entries = G_N_ELEMENTS (debug_entries);
+
+
+static const char * cursor_xpm[] = {
+"22 22 2 1",
+" c None",
+". c #0000FF",
+" ",
+" ",
+" ",
+" .. ",
+" .. .. ",
+" .. .. ",
+" . . ",
+" . . ",
+" . ... . ",
+" . ... . . ",
+" . ... . . ",
+" . .. . . ",
+" . . . ",
+" . . . ",
+" . . . ",
+" . . . ",
+" .. .. ",
+" .. .. ",
+" .. ",
+" ",
+" ",
+" "};
+
+
+static const char * north_xpm[] = {
+"22 22 2 1",
+" c None",
+". c #000000",
+" ",
+" ",
+" . ",
+" ... ",
+" . . . ",
+" . . . ",
+" . ",
+" .... . .... ",
+" .... . .... ",
+" .... . .. ",
+" .. .. .. ",
+" .. .. .. ",
+" .. .. .. ",
+" .. .. .. ",
+" .. . .... ",
+" .... . .... ",
+" .... . .... ",
+" . ",
+" . ",
+" . ",
+" ",
+" "};
+
+
+static const char * flag_xpm[] = {
+"22 22 2 1",
+" c None",
+"+ c #000000",
+"+++++++ ",
+"+ +++++++++ ",
+"+ +++ +++++++++ ",
+"+ +++ +++ +++ ",
+"++++ +++ +++ ",
+"++++ +++ +++ ",
+"++++ +++ +++ + ",
+"+ ++++++ +++ + ",
+"+ +++ ++++++ + ",
+"+ +++ +++ +++ ",
+"++++ +++ +++ ",
+"++++ +++ +++ ",
+"++++++++++ +++ + ",
+"+ +++++++++ + ",
+"+ ++++++ ",
+"+ ",
+"+ ",
+"+ ",
+"+ ",
+"+ ",
+"+ ",
+"+ "};
+
+
+
+static struct {
+ gchar *stockid;
+ const char **icon_xpm;
+} stock_icons[] = {
+ {"cursor_icon", cursor_xpm },
+ {"orientation_icon", north_xpm },
+ {"flag_icon", flag_xpm }
+};
+
+
+static gint n_stock_icons = G_N_ELEMENTS (stock_icons);
+
+
+static void
+register_my_stock_icons (void)
+{
+ GtkIconFactory *icon_factory;
+ GtkIconSet *icon_set;
+ GdkPixbuf *pixbuf;
+ gint i;
+
+ icon_factory = gtk_icon_factory_new ();
+
+ for (i = 0; i < n_stock_icons; i++)
+ {
+ pixbuf = gdk_pixbuf_new_from_xpm_data(stock_icons[i].icon_xpm);
+ icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
+ g_object_unref(pixbuf);
+ gtk_icon_factory_add (icon_factory, stock_icons[i].stockid, icon_set);
+ gtk_icon_set_unref (icon_set);
+ }
+
+ gtk_icon_factory_add_default(icon_factory);
+
+ g_object_unref(icon_factory);
+}
+
+
+static char layout[] =
+ "<ui>\
+ <menubar name=\"MenuBar\">\
+ <menu name=\"Display\" action=\"DisplayMenuAction\">\
+ <menuitem name=\"Zoom in\" action=\"ZoomInAction\" />\
+ <menuitem name=\"Zoom out\" action=\"ZoomOutAction\" />\
+ <menuitem name=\"Cursor\" action=\"CursorAction\"/>\
+ <menuitem name=\"Tracking\" action=\"TrackingAction\"/>\
+ <menuitem name=\"Orientation\" action=\"OrientationAction\"/>\
+ <menuitem name=\"Roadbook\" action=\"RoadbookAction\"/>\
+ <menuitem name=\"Fullscreen\" action=\"FullscreenAction\"/>\
+ <menuitem name=\"Quit\" action=\"QuitAction\" />\
+ <placeholder name=\"RouteMenuAdditions\" />\
+ </menu>\
+ <menu name=\"Data\" action=\"DataMenuAction\">\
+ <placeholder name=\"DataMenuAdditions\" />\
+ </menu>\
+ <menu name=\"Route\" action=\"RouteMenuAction\">\
+ <menuitem name=\"Refresh\" action=\"RefreshAction\" />\
+ <menuitem name=\"Destination\" action=\"DestinationAction\" />\
+ <menuitem name=\"Clear\" action=\"RouteClearAction\" />\
+ <menu name=\"FormerDestinations\" action=\"FormerDestinationMenuAction\">\
+ <placeholder name=\"FormerDestinationMenuAdditions\" />\
+ </menu>\
+ <menu name=\"Bookmarks\" action=\"BookmarkMenuAction\">\
+ <placeholder name=\"BookmarkMenuAdditions\" />\
+ </menu>\
+ <placeholder name=\"RouteMenuAdditions\" />\
+ </menu>\
+ <menu name=\"Map\" action=\"MapMenuAction\">\
+ <menu name=\"Layout\" action=\"LayoutMenuAction\">\
+ <placeholder name=\"LayoutMenuAdditions\" />\
+ </menu>\
+ <menu name=\"Projection\" action=\"ProjectionMenuAction\">\
+ <placeholder name=\"ProjectionMenuAdditions\" />\
+ </menu>\
+ <menu name=\"Vehicle\" action=\"VehicleMenuAction\">\
+ <placeholder name=\"VehicleMenuAdditions\" />\
+ </menu>\
+ <placeholder name=\"MapMenuAdditions\" />\
+ </menu>\
+ </menubar>\
+ <toolbar name=\"ToolBar\" action=\"BaseToolbar\" action=\"BaseToolbarAction\">\
+ <placeholder name=\"ToolItems\">\
+ <separator/>\
+ <toolitem name=\"Zoom in\" action=\"ZoomInAction\"/>\
+ <toolitem name=\"Zoom out\" action=\"ZoomOutAction\"/>\
+ <toolitem name=\"Refresh\" action=\"RefreshAction\"/>\
+ <toolitem name=\"Cursor\" action=\"CursorAction\"/>\
+ <toolitem name=\"Orientation\" action=\"OrientationAction\"/>\
+ <toolitem name=\"Destination\" action=\"DestinationAction\"/>\
+ <!-- <toolitem name=\"Info\" action=\"InfoAction\"/> -->\
+ <toolitem name=\"Roadbook\" action=\"RoadbookAction\"/>\
+ <toolitem name=\"Quit\" action=\"QuitAction\"/>\
+ <separator/>\
+ </placeholder>\
+ </toolbar>\
+ <popup name=\"PopUp\">\
+ </popup>\
+ </ui>";
+
+
+static void
+activate(void *dummy, struct menu_priv *menu)
+{
+ if (menu->cb)
+ callback_call_0(menu->cb);
+}
+
+static struct menu_methods menu_methods;
+
+static struct menu_priv *
+add_menu(struct menu_priv *menu, struct menu_methods *meth, char *name, enum menu_type type, struct callback *cb)
+{
+ struct menu_priv *ret;
+ char *dynname;
+
+ ret=g_new0(struct menu_priv, 1);
+ *meth=menu_methods;
+ if (! strcmp(menu->path, "/ui/MenuBar") && !strcmp(name,"Route")) {
+ dynname=g_strdup("Route");
+ } else if (! strcmp(menu->path, "/ui/MenuBar") && !strcmp(name,"Data")) {
+ dynname=g_strdup("Data");
+ } else {
+ dynname=g_strdup_printf("%d", menu->gui->dyn_counter++);
+ if (type == menu_type_toggle)
+ ret->action=GTK_ACTION(gtk_toggle_action_new(dynname, name, NULL, NULL));
+ else
+ ret->action=gtk_action_new(dynname, name, NULL, NULL);
+ if (cb)
+ ret->handler_id=g_signal_connect(ret->action, "activate", G_CALLBACK(activate), ret);
+ gtk_action_group_add_action(menu->gui->dyn_group, ret->action);
+ ret->merge_id=gtk_ui_manager_new_merge_id(menu->gui->ui_manager);
+ gtk_ui_manager_add_ui( menu->gui->ui_manager, ret->merge_id, menu->path, dynname, dynname, type == menu_type_submenu ? GTK_UI_MANAGER_MENU : GTK_UI_MANAGER_MENUITEM, FALSE);
+ }
+ ret->gui=menu->gui;
+ ret->path=g_strdup_printf("%s/%s", menu->path, dynname);
+ ret->type=type;
+ ret->cb=cb;
+ ret->sibling=menu->child;
+ menu->child=ret;
+ g_free(dynname);
+ return ret;
+
+}
+
+static void
+remove_menu(struct menu_priv *item, int recursive)
+{
+
+ if (recursive) {
+ struct menu_priv *next,*child=item->child;
+ while (child) {
+ next=child->sibling;
+ remove_menu(child, recursive);
+ child=next;
+ }
+ }
+ if (item->action) {
+ gtk_ui_manager_remove_ui(item->gui->ui_manager, item->merge_id);
+ gtk_action_group_remove_action(item->gui->dyn_group, item->action);
+#if 0
+ if (item->callback)
+ g_signal_handler_disconnect(item->action, item->handler_id);
+#endif
+ g_object_unref(item->action);
+ }
+ g_free(item->path);
+ g_free(item);
+}
+
+static void
+set_toggle(struct menu_priv *menu, int active)
+{
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(menu->action), active);
+}
+
+static int
+get_toggle(struct menu_priv *menu)
+{
+ return gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(menu->action));
+}
+
+static struct menu_methods menu_methods = {
+#if 1
+ add_menu,
+ set_toggle,
+ get_toggle,
+#else
+ NULL,
+ NULL,
+ NULL
+#endif
+};
+
+
+static void
+popup_deactivate(GtkWidget *widget, struct menu_priv *menu)
+{
+ g_signal_handler_disconnect(widget, menu->handler_id);
+ remove_menu(menu, 1);
+}
+
+static void
+popup_activate(struct menu_priv *menu)
+{
+#ifdef _WIN32
+ menu->widget=gtk_ui_manager_get_widget(menu->gui->ui_manager, menu->path );
+#endif
+ gtk_menu_popup(GTK_MENU(menu->widget), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ());
+ menu->handler_id=g_signal_connect(menu->widget, "selection-done", G_CALLBACK(popup_deactivate), menu);
+}
+
+void
+gui_gtk_ui_init(struct gui_priv *this)
+{
+ GError *error = NULL;
+ struct attr attr;
+ GtkToggleAction *toggle_action;
+
+ this->base_group = gtk_action_group_new ("BaseActions");
+ this->debug_group = gtk_action_group_new ("DebugActions");
+ this->dyn_group = gtk_action_group_new ("DynamicActions");
+ register_my_stock_icons();
+ this->ui_manager = gtk_ui_manager_new ();
+ gtk_action_group_set_translation_domain(this->base_group,"navit");
+ gtk_action_group_set_translation_domain(this->debug_group,"navit");
+ gtk_action_group_set_translation_domain(this->dyn_group,"navit");
+ gtk_action_group_add_actions (this->base_group, entries, n_entries, this);
+ gtk_action_group_add_toggle_actions (this->base_group, toggleentries, n_toggleentries, this);
+ gtk_ui_manager_insert_action_group (this->ui_manager, this->base_group, 0);
+ gtk_action_group_add_actions (this->debug_group, debug_entries, n_debug_entries, this);
+ gtk_ui_manager_insert_action_group (this->ui_manager, this->debug_group, 0);
+ gtk_ui_manager_add_ui_from_string (this->ui_manager, layout, strlen(layout), &error);
+ gtk_ui_manager_insert_action_group (this->ui_manager, this->dyn_group, 0);
+ if (error) {
+ g_message ("building menus failed: %s", error->message);
+ g_error_free (error);
+ }
+ if (navit_get_attr(this->nav, attr_cursor, &attr, NULL)) {
+ toggle_action = GTK_TOGGLE_ACTION(gtk_action_group_get_action(this->base_group, "CursorAction"));
+ gtk_toggle_action_set_active(toggle_action, attr.u.num);
+ }
+ if (navit_get_attr(this->nav, attr_orientation, &attr, NULL)) {
+ toggle_action = GTK_TOGGLE_ACTION(gtk_action_group_get_action(this->base_group, "OrientationAction"));
+ gtk_toggle_action_set_active(toggle_action, attr.u.num);
+ }
+ if (navit_get_attr(this->nav, attr_tracking, &attr, NULL)) {
+ toggle_action = GTK_TOGGLE_ACTION(gtk_action_group_get_action(this->base_group, "TrackingAction"));
+ gtk_toggle_action_set_active(toggle_action, attr.u.num);
+ }
+}
+
+static struct menu_priv *
+gui_gtk_ui_new (struct gui_priv *this, struct menu_methods *meth, char *path, int popup, GtkWidget **widget_ret)
+{
+ struct menu_priv *ret;
+ GtkWidget *widget;
+
+ *meth=menu_methods;
+ ret=g_new0(struct menu_priv, 1);
+ ret->path=g_strdup(path);
+ ret->gui=this;
+
+ widget=gtk_ui_manager_get_widget(this->ui_manager, path);
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_FOCUS);
+ if (widget_ret)
+ *widget_ret=widget;
+ if (! popup) {
+ gtk_box_pack_start (GTK_BOX(this->vbox), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+ } else {
+ ret->widget=widget;
+ meth->popup=popup_activate;
+ }
+ return ret;
+}
+
+#if 0
+struct menu_priv *
+gui_gtk_menubar_new(struct gui_priv *this, struct menu_methods *meth)
+{
+ return gui_gtk_ui_new(this, meth, "/ui/MenuBar", 0, &this->menubar);
+}
+#endif
+
+struct menu_priv *
+gui_gtk_popup_new(struct gui_priv *this, struct menu_methods *meth)
+{
+ return gui_gtk_ui_new(this, meth, "/ui/PopUp", 1, NULL);
+}
diff --git a/navit/gui/gtk/gui_gtk_statusbar.c b/navit/gui/gtk/gui_gtk_statusbar.c
new file mode 100644
index 000000000..f029e0848
--- /dev/null
+++ b/navit/gui/gtk/gui_gtk_statusbar.c
@@ -0,0 +1,162 @@
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <math.h>
+#include <gtk/gtk.h>
+#include <libintl.h>
+#include "item.h"
+#include "coord.h"
+#include "debug.h"
+#include "vehicle.h"
+#include "callback.h"
+#include "route.h"
+#include "transform.h"
+#include "navit.h"
+#include "map.h"
+#include "navigation.h"
+#include "gui_gtk.h"
+
+
+#define _(STRING) gettext(STRING)
+
+struct statusbar_priv {
+ struct gui_priv *gui;
+ GtkWidget *hbox;
+ char gps_text[128];
+ GtkWidget *gps;
+ char route_text[128];
+ GtkWidget *route;
+ struct callback *vehicle_cb;
+};
+
+
+
+
+static void
+statusbar_destroy(struct statusbar_priv *this)
+{
+ g_free(this);
+}
+
+static void
+statusbar_gps_update(struct statusbar_priv *this, int sats, int qual, double lng, double lat, double height, double direction, double speed)
+{
+ char lat_c='N';
+ char lng_c='E';
+ char *dirs[]={_("N"),_("NE"),_("E"),_("SE"),_("S"),_("SW"),_("W"),_("NW"),_("N")};
+ char *dir;
+ int dir_idx;
+
+ if (lng < 0) {
+ lng=-lng;
+ lng_c='W';
+ }
+ if (lat < 0) {
+ lat=-lat;
+ lat_c='S';
+ }
+ dir_idx=(direction+22.5)/45;
+ dir=dirs[dir_idx];
+ sprintf(this->gps_text, "GPS %2d/%1d %02.0f%07.4f%c %03.0f%07.4f%c %4.0fm %3.0f°%-2s %3.0fkm/h", sats, qual, floor(lat), fmod(lat*60,60), lat_c, floor(lng), fmod(lng*60,60), lng_c, height, direction, dir, speed);
+ gtk_label_set_text(GTK_LABEL(this->gps), this->gps_text);
+
+}
+
+static void
+statusbar_route_update(struct statusbar_priv *this, struct navit *navit, struct vehicle *v)
+{
+ struct navigation *nav=NULL;
+ struct map *map=NULL;
+ struct map_rect *mr=NULL;
+ struct item *item=NULL;
+ struct attr attr;
+ double route_len=0;
+ time_t eta;
+ struct tm *eta_tm=NULL;
+ char buffer[128];
+ double lng, lat, direction=0, height=0, speed=0;
+ int sats=0, qual=0;
+ char lat_c='N';
+ char lng_c='E';
+ char *dirs[]={_("N"),_("NE"),_("E"),_("SE"),_("S"),_("SW"),_("W"),_("NW"),_("N")};
+ char *dir;
+ int dir_idx;
+
+ if (navit)
+ nav=navit_get_navigation(navit);
+ if (nav)
+ map=navigation_get_map(nav);
+ if (map)
+ mr=map_rect_new(map, NULL);
+ if (mr)
+ item=map_rect_get_item(mr);
+ if (item) {
+ if (item_attr_get(item, attr_destination_length, &attr))
+ route_len=attr.u.num;
+ if (item_attr_get(item, attr_destination_time, &attr)) {
+ eta=time(NULL)+attr.u.num/10;
+ eta_tm=localtime(&eta);
+ }
+ }
+ if (mr)
+ map_rect_destroy(mr);
+ sprintf(buffer,_("Route %4.0fkm %02d:%02d ETA" ),route_len/1000, eta_tm ? eta_tm->tm_hour : 0 , eta_tm ? eta_tm->tm_min : 0);
+ if (strcmp(buffer, this->route_text)) {
+ strcpy(this->route_text, buffer);
+ gtk_label_set_text(GTK_LABEL(this->route), this->route_text);
+ }
+ if (!vehicle_get_attr(v, attr_position_coord_geo, &attr))
+ return;
+ lng=attr.u.coord_geo->lng;
+ lat=attr.u.coord_geo->lat;
+ if (lng < 0) {
+ lng=-lng;
+ lng_c='W';
+ }
+ if (lat < 0) {
+ lat=-lat;
+ lat_c='S';
+ }
+ if (vehicle_get_attr(v, attr_position_direction, &attr))
+ direction=*(attr.u.numd);
+ direction=fmod(direction,360);
+ if (direction < 0)
+ direction+=360;
+ dir_idx=(direction+22.5)/45;
+ dir=dirs[dir_idx];
+ if (vehicle_get_attr(v, attr_position_height, &attr))
+ height=*(attr.u.numd);
+ if (vehicle_get_attr(v, attr_position_speed, &attr))
+ speed=*(attr.u.numd);
+ if (vehicle_get_attr(v, attr_position_sats_used, &attr))
+ sats=attr.u.num;
+ if (vehicle_get_attr(v, attr_position_qual, &attr))
+ qual=attr.u.num;
+ sprintf(this->gps_text,"GPS %2d/%1d %02.0f%07.4f%c %03.0f%07.4f%c %4.0fm %3.0f°%-2s %3.0fkm/h", sats, qual, floor(lat), fmod(lat*60,60), lat_c, floor(lng), fmod(lng*60,60), lng_c, height, direction, dir, speed);
+ gtk_label_set_text(GTK_LABEL(this->gps), this->gps_text);
+}
+
+struct statusbar_priv *
+gui_gtk_statusbar_new(struct gui_priv *gui)
+{
+ struct statusbar_priv *this=g_new0(struct statusbar_priv, 1);
+
+ this->gui=gui;
+ this->hbox=gtk_hbox_new(FALSE, 1);
+ this->gps=gtk_label_new( "GPS 00/0 0000.0000N 00000.0000E 0000m 000°NO 000km/h" );
+ gtk_label_set_justify(GTK_LABEL(this->gps), GTK_JUSTIFY_LEFT);
+ this->route=gtk_label_new( _( "Route 0000km 0+00:00 ETA" ) );
+ gtk_label_set_justify(GTK_LABEL(this->route), GTK_JUSTIFY_LEFT);
+ gtk_box_pack_start(GTK_BOX(this->hbox), this->gps, TRUE, TRUE, 2);
+ gtk_box_pack_start(GTK_BOX(this->hbox), gtk_vseparator_new(), TRUE, TRUE, 2);
+ gtk_box_pack_start(GTK_BOX(this->hbox), this->route, TRUE, TRUE, 2);
+ GTK_WIDGET_UNSET_FLAGS (this->hbox, GTK_CAN_FOCUS);
+
+ gtk_box_pack_end(GTK_BOX(gui->vbox), this->hbox, FALSE, FALSE, 0);
+ gtk_widget_show_all(this->hbox);
+ /* add a callback for position updates */
+ this->vehicle_cb=callback_new_attr_1(callback_cast(statusbar_route_update), attr_position_coord_geo, this);
+ navit_add_callback(gui->nav, this->vehicle_cb);
+ return this;
+}
+
diff --git a/navit/gui/gtk/gui_gtk_window.c b/navit/gui/gtk/gui_gtk_window.c
new file mode 100644
index 000000000..2cda180f5
--- /dev/null
+++ b/navit/gui/gtk/gui_gtk_window.c
@@ -0,0 +1,564 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <gdk/gdkkeysyms.h>
+#if !defined(GDK_Book) || !defined(GDK_Calendar)
+#include <X11/XF86keysym.h>
+#endif
+#include <libintl.h>
+#include <gtk/gtk.h>
+#include "config.h"
+#include "item.h"
+#include "navit.h"
+#include "debug.h"
+#include "gui.h"
+#include "coord.h"
+#include "point.h"
+#include "plugin.h"
+#include "graphics.h"
+#include "gui_gtk.h"
+#include "transform.h"
+#include "config.h"
+#include "callback.h"
+#include "layout.h"
+#include "vehicle.h"
+#include "map.h"
+#include "coord.h"
+
+#ifdef USE_HILDON
+#include "hildon-widgets/hildon-defines.h"
+#define KEY_ZOOM_IN HILDON_HARDKEY_INCREASE
+#define KEY_ZOOM_OUT HILDON_HARDKEY_DECREASE
+#define KEY_UP HILDON_HARDKEY_UP
+#define KEY_DOWN HILDON_HARDKEY_DOWN
+#define KEY_LEFT HILDON_HARDKEY_LEFT
+#define KEY_RIGHT HILDON_HARDKEY_RIGHT
+#else
+#ifndef GDK_Book
+#define GDK_Book XF86XK_Book
+#endif
+#ifndef GDK_Calendar
+#define GDK_Calendar XF86XK_Calendar
+#endif
+#define KEY_ZOOM_IN GDK_Book
+#define KEY_ZOOM_OUT GDK_Calendar
+#define KEY_UP GDK_Up
+#define KEY_DOWN GDK_Down
+#define KEY_LEFT GDK_Left
+#define KEY_RIGHT GDK_Right
+#endif
+
+#define _(text) gettext(text)
+
+static gboolean
+keypress(GtkWidget *widget, GdkEventKey *event, struct gui_priv *this)
+{
+ int w,h;
+ #ifdef USE_HILDON
+ GtkToggleAction *action;
+ gboolean *fullscreen;
+ #endif /*HILDON*/
+ struct point p;
+ if (event->type != GDK_KEY_PRESS)
+ return FALSE;
+ dbg(1,"keypress 0x%x\n", event->keyval);
+ transform_get_size(navit_get_trans(this->nav), &w, &h);
+ switch (event->keyval) {
+ case GDK_KP_Enter:
+ gtk_menu_shell_select_first(GTK_MENU_SHELL(this->menubar), TRUE);
+ break;
+ case KEY_UP:
+ p.x=w/2;
+ p.y=0;
+ navit_set_center_screen(this->nav, &p);
+ break;
+ case KEY_DOWN:
+ p.x=w/2;
+ p.y=h;
+ navit_set_center_screen(this->nav, &p);
+ break;
+ case KEY_LEFT:
+ p.x=0;
+ p.y=h/2;
+ navit_set_center_screen(this->nav, &p);
+ break;
+ case KEY_RIGHT:
+ p.x=w;
+ p.y=h/2;
+ navit_set_center_screen(this->nav, &p);
+ break;
+ case KEY_ZOOM_IN:
+ navit_zoom_in(this->nav, 2, NULL);
+ break;
+ case KEY_ZOOM_OUT:
+ navit_zoom_out(this->nav, 2, NULL);
+ break;
+ #ifdef USE_HILDON
+ case HILDON_HARDKEY_FULLSCREEN:
+ action = GTK_TOGGLE_ACTION (gtk_action_group_get_action (this->base_group, "FullscreenAction"));
+
+ if ( gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)))
+ {
+ fullscreen = 0;
+ } else {
+ fullscreen = 1;
+ }
+ gtk_toggle_action_set_active (action, fullscreen);
+ break;
+ #endif /*HILDON*/
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static int
+gui_gtk_set_graphics(struct gui_priv *this, struct graphics *gra)
+{
+ GtkWidget *graphics;
+
+ graphics=graphics_get_data(gra, "gtk_widget");
+ if (! graphics)
+ return 1;
+ GTK_WIDGET_SET_FLAGS (graphics, GTK_CAN_FOCUS);
+ gtk_widget_set_sensitive(graphics, TRUE);
+ g_signal_connect(G_OBJECT(graphics), "key-press-event", G_CALLBACK(keypress), this);
+ gtk_box_pack_end(GTK_BOX(this->vbox), graphics, TRUE, TRUE, 0);
+ gtk_widget_show_all(graphics);
+ gtk_widget_grab_focus(graphics);
+
+ return 0;
+}
+
+static void
+gui_gtk_add_bookmark_do(struct gui_priv *gui)
+{
+ navit_add_bookmark(gui->nav, &gui->dialog_coord, gtk_entry_get_text(GTK_ENTRY(gui->dialog_entry)));
+ gtk_widget_destroy(gui->dialog_win);
+}
+
+static int
+gui_gtk_add_bookmark(struct gui_priv *gui, struct pcoord *c, char *description)
+{
+ GtkWidget *button_ok,*button_cancel,*label,*vbox,*hbox;
+
+ gui->dialog_coord=*c;
+ gui->dialog_win=gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ vbox=gtk_vbox_new(FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (gui->dialog_win), vbox);
+ gtk_window_set_title(GTK_WINDOW(gui->dialog_win),_("Add Bookmark"));
+ gtk_window_set_transient_for(GTK_WINDOW(gui->dialog_win), GTK_WINDOW(gui->win));
+ gtk_window_set_modal(GTK_WINDOW(gui->dialog_win), TRUE);
+ label=gtk_label_new(_("Name"));
+ gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
+ gui->dialog_entry=gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(gui->dialog_entry), description);
+ gtk_box_pack_start(GTK_BOX(vbox), gui->dialog_entry, TRUE, TRUE, 0);
+ hbox=gtk_hbox_new(FALSE, 0);
+ button_ok = gtk_button_new_from_stock (GTK_STOCK_OK);
+ gtk_box_pack_start(GTK_BOX(hbox), button_ok, TRUE, TRUE, 10);
+ button_cancel = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+ gtk_box_pack_start(GTK_BOX(hbox), button_cancel, TRUE, TRUE, 10);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 10);
+ gtk_widget_show_all(gui->dialog_win);
+ GTK_WIDGET_SET_FLAGS (button_ok, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(button_ok);
+ g_signal_connect_swapped (G_OBJECT (button_cancel), "clicked", G_CALLBACK (gtk_widget_destroy), G_OBJECT (gui->dialog_win));
+ g_signal_connect_swapped (G_OBJECT (gui->dialog_entry), "activate", G_CALLBACK (gui_gtk_add_bookmark_do), gui);
+
+ g_signal_connect_swapped(G_OBJECT (button_ok), "clicked", G_CALLBACK (gui_gtk_add_bookmark_do), gui);
+
+ return 1;
+}
+
+struct gui_methods gui_gtk_methods = {
+ NULL,
+ gui_gtk_popup_new,
+ gui_gtk_set_graphics,
+ NULL,
+ gui_gtk_datawindow_new,
+ gui_gtk_add_bookmark,
+};
+
+static gboolean
+gui_gtk_delete(GtkWidget *widget, GdkEvent *event, struct navit *nav)
+{
+ /* FIXME remove attr_navit callback */
+ navit_destroy(nav);
+
+ return TRUE;
+}
+
+static void
+gui_gtk_toggle_init(struct gui_priv *this)
+{
+ struct attr attr;
+ GtkToggleAction *toggle_action;
+
+ if (navit_get_attr(this->nav, attr_cursor, &attr, NULL)) {
+ toggle_action = GTK_TOGGLE_ACTION(gtk_action_group_get_action(this->base_group, "CursorAction"));
+ gtk_toggle_action_set_active(toggle_action, attr.u.num);
+ } else {
+ dbg(0, "Unable to locate CursorAction\n");
+ }
+ if (navit_get_attr(this->nav, attr_orientation, &attr, NULL)) {
+ toggle_action = GTK_TOGGLE_ACTION(gtk_action_group_get_action(this->base_group, "OrientationAction"));
+ gtk_toggle_action_set_active(toggle_action, attr.u.num);
+ } else {
+ dbg(0, "Unable to locate OrientationAction\n");
+ }
+ if (navit_get_attr(this->nav, attr_tracking, &attr, NULL)) {
+ toggle_action = GTK_TOGGLE_ACTION(gtk_action_group_get_action(this->base_group, "TrackingAction"));
+ gtk_toggle_action_set_active(toggle_action, attr.u.num);
+ } else {
+ dbg(0, "Unable to locate TrackingAction\n");
+ }
+}
+
+struct action_cb_data {
+ struct gui_priv *gui;
+ struct attr attr;
+};
+
+static void
+gui_gtk_action_activate(GtkAction *action, struct action_cb_data *data)
+{
+ if(data->attr.type == attr_destination) {
+ char * label;
+ g_object_get(G_OBJECT(action), "label", &label,NULL);
+ navit_set_destination(data->gui->nav, data->attr.u.pcoord, label);
+ g_free(label);
+ }
+}
+static void
+gui_gtk_add_menu(struct gui_priv *this, char *name, char *label, char *path, int submenu, struct action_cb_data *data)
+{
+ GtkAction *action;
+ guint merge_id;
+
+ action=gtk_action_new(name, label, NULL, NULL);
+ if (data)
+ g_signal_connect(action, "activate", G_CALLBACK(gui_gtk_action_activate), data);
+ gtk_action_group_add_action(this->dyn_group, action);
+ merge_id=gtk_ui_manager_new_merge_id(this->ui_manager);
+ gtk_ui_manager_add_ui(this->ui_manager, merge_id, path, name, name, submenu ? GTK_UI_MANAGER_MENU : GTK_UI_MANAGER_MENUITEM, FALSE);
+}
+
+static void
+gui_gtk_action_toggled(GtkToggleAction *action, struct action_cb_data *data)
+{
+ map_set_active(data->attr.u.map, gtk_toggle_action_get_active(action));
+ navit_draw(data->gui->nav);
+}
+
+static void
+gui_gtk_add_toggle_menu(struct gui_priv *this, char *name, char *label, char *path, struct action_cb_data *data, gboolean active)
+{
+ GtkToggleAction *toggle_action;
+ guint merge_id;
+
+ toggle_action=gtk_toggle_action_new(name, label, NULL, NULL);
+ gtk_toggle_action_set_active(toggle_action, active);
+ g_signal_connect(GTK_ACTION(toggle_action), "toggled", G_CALLBACK(gui_gtk_action_toggled), data);
+ gtk_action_group_add_action(this->dyn_group, GTK_ACTION(toggle_action));
+ merge_id=gtk_ui_manager_new_merge_id(this->ui_manager);
+ gtk_ui_manager_add_ui(this->ui_manager, merge_id, path, name, name, GTK_UI_MANAGER_MENUITEM, FALSE);
+}
+
+static void
+gui_gtk_action_changed(GtkRadioAction *action, GtkRadioAction *current, struct action_cb_data *data)
+{
+ if (action == current) {
+ navit_set_attr(data->gui->nav, &data->attr);
+ }
+}
+
+static void
+gui_gtk_add_radio_menu(struct gui_priv *this, char *name, char *label, char *path, struct action_cb_data *data, GSList **g)
+{
+ GtkRadioAction *radio_action;
+ guint merge_id;
+
+ radio_action=gtk_radio_action_new(name, label, NULL, NULL, 0);
+ gtk_radio_action_set_group(radio_action, *g);
+ *g=gtk_radio_action_get_group(radio_action);
+ g_signal_connect(GTK_ACTION(radio_action), "changed", G_CALLBACK(gui_gtk_action_changed), data);
+ gtk_action_group_add_action(this->dyn_group, GTK_ACTION(radio_action));
+ merge_id=gtk_ui_manager_new_merge_id(this->ui_manager);
+ gtk_ui_manager_add_ui(this->ui_manager, merge_id, path, name, name, GTK_UI_MANAGER_MENUITEM, FALSE);
+}
+
+static void
+gui_gtk_layouts_init(struct gui_priv *this)
+{
+ struct attr_iter *iter;
+ struct attr attr;
+ struct action_cb_data *data;
+ int count=0;
+ char *name;
+
+ iter=navit_attr_iter_new();
+ while(navit_get_attr(this->nav, attr_layout, &attr, iter)) {
+ name=g_strdup_printf("Layout %d", count++);
+ data=g_new(struct action_cb_data, 1);
+ data->gui=this;
+ data->attr.type=attr_layout;
+ data->attr.u.layout=attr.u.layout;
+ gui_gtk_add_radio_menu(this, name, attr.u.layout->name, "/ui/MenuBar/Map/Layout/LayoutMenuAdditions", data, &this->layout_group);
+ g_free(name);
+ }
+ navit_attr_iter_destroy(iter);
+}
+
+static void
+gui_gtk_projections_init(struct gui_priv *this)
+{
+ struct action_cb_data *data;
+
+ data=g_new(struct action_cb_data, 1);
+ data->gui=this;
+ data->attr.type=attr_projection;
+ data->attr.u.projection=projection_mg;
+ gui_gtk_add_radio_menu(this, "Projection mg", "Map & Guide", "/ui/MenuBar/Map/Projection/ProjectionMenuAdditions", data, &this->projection_group);
+
+ data=g_new(struct action_cb_data, 1);
+ data->gui=this;
+ data->attr.type=attr_projection;
+ data->attr.u.projection=projection_garmin;
+ gui_gtk_add_radio_menu(this, "Projection garmin", "Garmin", "/ui/MenuBar/Map/Projection/ProjectionMenuAdditions", data, &this->projection_group);
+}
+
+static void
+gui_gtk_vehicles_init(struct gui_priv *this)
+{
+ struct attr_iter *iter;
+ struct attr attr,vattr;
+ struct action_cb_data *data;
+ int count=0;
+ char *name;
+
+ iter=navit_attr_iter_new();
+ while(navit_get_attr(this->nav, attr_vehicle, &attr, iter)) {
+ vehicle_get_attr(attr.u.vehicle, attr_name, &vattr);
+ name=g_strdup_printf("Vehicle %d", count++);
+ data=g_new(struct action_cb_data, 1);
+ data->gui=this;
+ data->attr.type=attr_vehicle;
+ data->attr.u.vehicle=attr.u.vehicle;
+ gui_gtk_add_radio_menu(this, name, vattr.u.str, "/ui/MenuBar/Map/Vehicle/VehicleMenuAdditions", data, &this->vehicle_group);
+ g_free(name);
+ }
+ navit_attr_iter_destroy(iter);
+}
+
+static void
+gui_gtk_maps_init(struct gui_priv *this)
+{
+ struct attr_iter *iter;
+ struct attr attr;
+ struct action_cb_data *data;
+ int count=0;
+ char *name, *label;
+
+ iter=navit_attr_iter_new();
+ while(navit_get_attr(this->nav, attr_map, &attr, iter)) {
+ name=g_strdup_printf("Map %d", count++);
+ label=g_strdup_printf("%s:%s", map_get_type(attr.u.map), map_get_filename(attr.u.map));
+ data=g_new(struct action_cb_data, 1);
+ data->gui=this;
+ data->attr.type=attr_map;
+ data->attr.u.map=attr.u.map;
+ gui_gtk_add_toggle_menu(this, name, label, "/ui/MenuBar/Map/MapMenuAdditions", data, map_get_active(attr.u.map));
+ g_free(name);
+ g_free(label);
+ }
+ navit_attr_iter_destroy(iter);
+
+}
+
+static void
+gui_gtk_destinations_init(struct gui_priv *this)
+{
+ struct attr attr;
+ struct action_cb_data *data;
+ struct map_rect *mr=NULL;
+ struct item *item;
+ struct coord c;
+ int count=0;
+ char *name, *label;
+
+ if(navit_get_attr(this->nav, attr_former_destination_map, &attr, NULL) && attr.u.map && (mr=map_rect_new(attr.u.map, NULL))) {
+ while ((item=map_rect_get_item(mr))) {
+ if (item->type != type_former_destination) continue;
+ name=g_strdup_printf("Destination %d", count++);
+ item_attr_get(item, attr_label, &attr);
+ label=attr.u.str;
+ item_coord_get(item, &c, 1);
+ data=g_new(struct action_cb_data, 1);
+ data->gui=this;
+ data->attr.type=attr_destination;
+ data->attr.u.pcoord=g_new(struct pcoord, 1);
+ data->attr.u.pcoord->pro=projection_mg;
+ data->attr.u.pcoord->x=c.x;
+ data->attr.u.pcoord->y=c.y;
+ gui_gtk_add_menu(this, name, label, "/ui/MenuBar/Route/FormerDestinations/FormerDestinationMenuAdditions",0,data);
+ g_free(name);
+ }
+ map_rect_destroy(mr);
+ }
+}
+
+static void
+gui_gtk_bookmarks_init(struct gui_priv *this)
+{
+ struct attr attr;
+ struct action_cb_data *data;
+ struct map_rect *mr=NULL;
+ struct item *item;
+ struct coord c;
+ int count=0;
+ char *parent, *name, *label, *label_full, *menu_label, *tmp_parent, *s;
+ GHashTable *hash;
+
+ if(navit_get_attr(this->nav, attr_bookmark_map, &attr, NULL) && attr.u.map && (mr=map_rect_new(attr.u.map, NULL))) {
+ hash=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+ while ((item=map_rect_get_item(mr))) {
+ if (item->type != type_bookmark) continue;
+ item_attr_get(item, attr_label, &attr);
+ label_full=attr.u.str;
+ item_coord_get(item, &c, 1);
+ menu_label=g_malloc(strlen(label_full)+1);
+ label=label_full;
+ parent=g_strdup("/ui/MenuBar/Route/Bookmarks/BookmarkMenuAdditions");
+ while ((s=strchr(label, '/'))) {
+ strcpy(menu_label, label_full);
+ menu_label[s-label_full]='\0';
+ if ((tmp_parent=g_hash_table_lookup(hash, menu_label))) {
+ tmp_parent=g_strdup(tmp_parent);
+ } else {
+ name=g_strdup_printf("Bookmark %d", count++);
+ gui_gtk_add_menu(this, name, menu_label+(label-label_full),parent,1,NULL);
+ tmp_parent=g_strdup_printf("%s/%s", parent, name);
+ g_hash_table_insert(hash, g_strdup(menu_label), g_strdup(tmp_parent));
+ g_free(name);
+ }
+ g_free(parent);
+ parent=tmp_parent;
+ label=s+1;
+ }
+ g_free(menu_label);
+ data=g_new(struct action_cb_data, 1);
+ data->gui=this;
+ data->attr.type=attr_destination;
+ data->attr.u.pcoord=g_new(struct pcoord, 1);
+ data->attr.u.pcoord->pro=projection_mg;
+ data->attr.u.pcoord->x=c.x;
+ data->attr.u.pcoord->y=c.y;
+ name=g_strdup_printf("Bookmark %d", count++);
+ gui_gtk_add_menu(this, name, label, parent,0,data);
+ g_free(name);
+ g_free(parent);
+ }
+ g_hash_table_destroy(hash);
+ }
+}
+
+static void
+gui_gtk_init(struct gui_priv *this, struct navit *nav)
+{
+
+
+ gui_gtk_toggle_init(this);
+ gui_gtk_layouts_init(this);
+ gui_gtk_projections_init(this);
+ gui_gtk_vehicles_init(this);
+ gui_gtk_maps_init(this);
+ gui_gtk_destinations_init(this);
+ gui_gtk_bookmarks_init(this);
+}
+
+static struct gui_priv *
+gui_gtk_new(struct navit *nav, struct gui_methods *meth, struct attr **attrs)
+{
+ struct gui_priv *this;
+ int w=792, h=547;
+ char *cp = getenv("NAVIT_XID");
+ unsigned xid = 0;
+ struct attr *attr;
+ GtkWidget *widget;
+
+ if (cp) {
+ xid = strtol(cp, NULL, 0);
+ }
+
+ this=g_new0(struct gui_priv, 1);
+ this->nav=nav;
+
+ attr = attr_search(attrs, NULL, attr_menubar);
+ if (attr) {
+ this->menubar_enable=attr->u.num;
+ } else {
+ this->menubar_enable=1;
+ }
+ attr=attr_search(attrs, NULL, attr_toolbar);
+ if (attr) {
+ this->toolbar_enable=attr->u.num;
+ } else {
+ this->toolbar_enable=1;
+ }
+ attr=attr_search(attrs, NULL, attr_statusbar);
+ if (attr) {
+ this->statusbar_enable=attr->u.num;
+ } else {
+ this->statusbar_enable=1;
+ }
+
+ *meth=gui_gtk_methods;
+
+ if (!xid)
+ this->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ else
+ this->win = gtk_plug_new(xid);
+
+ g_signal_connect(G_OBJECT(this->win), "delete-event", G_CALLBACK(gui_gtk_delete), nav);
+ this->vbox = gtk_vbox_new(FALSE, 0);
+ gtk_window_set_default_size(GTK_WINDOW(this->win), w, h);
+ gtk_window_set_title(GTK_WINDOW(this->win), "Navit");
+ gtk_widget_realize(this->win);
+ gui_gtk_ui_init(this);
+ if (this->menubar_enable) {
+ widget=gtk_ui_manager_get_widget(this->ui_manager, "/ui/MenuBar");
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_FOCUS);
+ gtk_box_pack_start (GTK_BOX(this->vbox), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+ this->menubar=widget;
+ }
+ if (this->toolbar_enable) {
+ widget=gtk_ui_manager_get_widget(this->ui_manager, "/ui/ToolBar");
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_CAN_FOCUS);
+ gtk_box_pack_start (GTK_BOX(this->vbox), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+ }
+ if (this->statusbar_enable) {
+ this->statusbar=gui_gtk_statusbar_new(this);
+ }
+ gtk_container_add(GTK_CONTAINER(this->win), this->vbox);
+ gtk_widget_show_all(this->win);
+
+
+ navit_add_callback(nav, callback_new_attr_1(callback_cast(gui_gtk_init), attr_navit, this));
+ return this;
+}
+
+static int gtk_argc;
+static char **gtk_argv={NULL};
+
+void
+plugin_init(void)
+{
+ gtk_init(&gtk_argc, &gtk_argv);
+ gtk_set_locale();
+
+
+ plugin_register_gui_type("gtk", gui_gtk_new);
+}
diff --git a/navit/gui/internal/Makefile.am b/navit/gui/internal/Makefile.am
new file mode 100644
index 000000000..3108056d3
--- /dev/null
+++ b/navit/gui/internal/Makefile.am
@@ -0,0 +1,5 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = -I$(top_srcdir)/src @NAVIT_CFLAGS@ @GTK2_CFLAGS@ -DMODULE=gui_internal
+modulegui_LTLIBRARIES = libgui_internal.la
+libgui_internal_la_SOURCES = gui_internal.c
+libgui_internal_la_LIBADD = @GTK2_LIBS@
diff --git a/navit/gui/internal/gui_internal.c b/navit/gui/internal/gui_internal.c
new file mode 100644
index 000000000..c08a5ebd0
--- /dev/null
+++ b/navit/gui/internal/gui_internal.c
@@ -0,0 +1,407 @@
+//##############################################################################################################
+//#
+//# File: gui_internal.c
+//# Description: New "internal" GUI for use with any graphics library
+//# Comment: Trying to make a touchscreen friendly GUI
+//# Authors: Martin Schaller (04/2008), Stefan Klumpp (04/2008)
+//#
+//##############################################################################################################
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libintl.h>
+#include <glib.h>
+#include "config.h"
+#include "item.h"
+#include "navit.h"
+#include "debug.h"
+#include "gui.h"
+#include "coord.h"
+#include "point.h"
+#include "plugin.h"
+#include "graphics.h"
+#include "transform.h"
+#include "color.h"
+#include "config.h"
+
+#define STATE_VISIBLE 1
+#define STATE_SELECTED 2
+#define STATE_HIGHLIGHTED 4
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct gui_priv {
+ struct navit *nav;
+ struct graphics *gra;
+ struct graphics_gc *background;
+ struct graphics_gc *highlight_background;
+ struct graphics_gc *foreground;
+ struct graphics_font *font;
+ int w,h;
+ int menu;
+ struct widget *widgets;
+ int widgets_count;
+};
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct widget {
+ int type;
+ char *text;
+ char *icon;
+ void (*func)(struct gui_priv *priv, struct widget *widget);
+ void *data;
+ int state;
+ struct point p;
+ int w,h;
+};
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void action_return(struct gui_priv *this, struct widget *wi)
+{
+ this->menu=0;
+ wi->state &= ~STATE_HIGHLIGHTED;
+ navit_draw_displaylist(this->nav);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void action_zoom_in(struct gui_priv *this, struct widget *wi)
+{
+ this->menu=0;
+ wi->state &= ~STATE_HIGHLIGHTED;
+ navit_zoom_in(this->nav,2,NULL);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void action_zoom_out(struct gui_priv *this, struct widget *wi)
+{
+ this->menu=0;
+ wi->state &= ~STATE_HIGHLIGHTED;
+ navit_zoom_out(this->nav,2,NULL);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct widget main_menu[] = {
+ {0, "Return", "xpm/unknown.xpm",action_return},
+ {0, "Destination", "xpm/flag_bk_wh.xpm"},
+ {0, "Tour", "xpm/unknown.xpm" },
+ {0, "Vehicle", "xpm/cursor.xpm"},
+ {0, "Map point?", "xpm/unknown.xpm" }, // cp15: What do you mean with "Kartenpunkt"?
+ {0, "Map", "xpm/unknown.xpm",NULL,NULL,STATE_SELECTED},
+ {0, "Road map", "xpm/unknown.xpm" },
+ {0, "Zoom in", "xpm/unknown.xpm",action_zoom_in},
+ {0, "Zoom out", "xpm/unknown.xpm",action_zoom_out},
+};
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void gui_internal_draw_button(struct gui_priv *this, struct widget *wi)
+{
+ struct point pnt[5];
+ struct graphics_image *img;
+ int th=10,tw=40,b=5;
+ pnt[0]=wi->p;
+ pnt[0].x+=1;
+ pnt[0].y+=1;
+ if (wi->state & STATE_HIGHLIGHTED)
+ graphics_draw_rectangle(this->gra, this->highlight_background, &pnt, wi->w-1, wi->h-1);
+ else
+ graphics_draw_rectangle(this->gra, this->background, &pnt, wi->w-1, wi->h-1);
+ pnt[0]=wi->p;
+ pnt[0].x+=(wi->w-tw)/2;
+ pnt[0].y+=wi->h-th-b;
+ graphics_draw_text(this->gra, this->foreground, NULL, this->font, wi->text, &pnt[0], 0x10000, 0);
+
+ img=graphics_image_new(this->gra, wi->icon);
+ if (img) {
+ pnt[0]=wi->p;
+ pnt[0].x+=wi->w/2-img->hot.x;
+ pnt[0].y+=(wi->h-th-b)/2-img->hot.y;
+ graphics_draw_image(this->gra, this->foreground, &pnt[0], img);
+ graphics_image_free(this->gra, img);
+ }
+
+ pnt[0]=wi->p;
+ pnt[1].x=pnt[0].x+wi->w;
+ pnt[1].y=pnt[0].y;
+ pnt[2].x=pnt[0].x+wi->w;
+ pnt[2].y=pnt[0].y+wi->h;
+ pnt[3].x=pnt[0].x;
+ pnt[3].y=pnt[0].y+wi->h;
+ pnt[4]=pnt[0];
+ if (wi->state & STATE_SELECTED) {
+ graphics_gc_set_linewidth(this->foreground, 4);
+ b=2;
+ pnt[0].x+=b;
+ pnt[0].y+=b;
+ pnt[1].x-=b-1;
+ pnt[1].y+=b;
+ pnt[2].x-=b-1;
+ pnt[2].y-=b-1;
+ pnt[3].x+=b;
+ pnt[3].y-=b-1;
+ pnt[4].x+=b;
+ pnt[4].y+=b;
+ }
+ graphics_draw_lines(this->gra, this->foreground, pnt, 5);
+ if (wi->state & STATE_SELECTED)
+ graphics_gc_set_linewidth(this->foreground, 1);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void gui_internal_clear(struct gui_priv *this)
+{
+ struct graphics *gra=this->gra;
+ struct point pnt;
+ pnt.x=0;
+ pnt.y=0;
+ dbg(0,"w=%d h=%d\n", this->w, this->h);
+ graphics_draw_rectangle(gra, this->background, &pnt, this->w, this->h);
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void gui_internal_render_menu(struct gui_priv *this, int offset, struct widget *wi, int count)
+{
+ struct graphics *gra=this->gra;
+ struct point pnt;
+ int w,h,x,y,i;
+
+ dbg(0,"menu\n");
+ w=this->w/4;
+ h=this->h/4;
+ for (i = 0 ; i < count ; i++)
+ wi[i].state&=~STATE_VISIBLE;
+ i=offset;
+ for (y = 0 ; y < this->h ; y+=h) {
+ for (x = 0 ; x < this->w ; x+=w) {
+ if (i < count) {
+ wi[i].p.x=x;
+ wi[i].p.y=y;
+ wi[i].w=w;
+ wi[i].h=h;
+ wi[i].state|=STATE_VISIBLE;
+ gui_internal_draw_button(this, &wi[i]);
+ }
+ i++;
+ }
+ }
+ this->widgets=wi;
+ this->widgets_count=count;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void gui_internal_highlight(struct gui_priv *this, struct point *p)
+{
+ struct widget *wi,*found=NULL;
+ int i;
+
+ for (i = 0 ; i < this->widgets_count ; i++) {
+ wi=&this->widgets[i];
+ if (p && wi->state & STATE_VISIBLE && wi->p.x < p->x && wi->p.y < p->y && wi->p.x + wi->w > p->x && wi->p.y + wi->h > p->y)
+ found=wi;
+ else
+ if (wi->state & STATE_HIGHLIGHTED) {
+ wi->state &= ~STATE_HIGHLIGHTED;
+ gui_internal_draw_button(this, wi);
+ }
+ }
+ if (! found)
+ return;
+ if (! (found->state & STATE_HIGHLIGHTED)) {
+ found->state |= STATE_HIGHLIGHTED;
+ gui_internal_draw_button(this, found);
+ }
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void gui_internal_call_highlighted(struct gui_priv *this)
+{
+ struct widget *wi;
+ int i;
+
+ for (i = 0 ; i < this->widgets_count ; i++) {
+ wi=&this->widgets[i];
+ if (wi->state & STATE_HIGHLIGHTED) {
+ if (wi->func)
+ wi->func(this, wi);
+ }
+ }
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void gui_internal_motion(struct gui_priv *this, struct point *p)
+{
+ if (!this->menu)
+ navit_handle_motion(this->nav, p);
+}
+
+//##############################################################################################################
+//# Description: Function to handle mouse clicks and scroll wheel movement
+//# Comment:
+//# Authors: Martin Schaller (04/2008), Stefan Klumpp (04/2008)
+//##############################################################################################################
+static void gui_internal_button(struct gui_priv *this, int pressed, int button, struct point *p)
+{
+ struct graphics *gra=this->gra;
+ struct point pnt;
+
+ // if still on the map (not in the menu, yet):
+ if (!this->menu) {
+ // check whether the position of the mouse changed during press/release OR if it is the scrollwheel
+ if (!navit_handle_button(this->nav, pressed, button, p, NULL) || button >=4) // Maybe there's a better way to do this
+ return;
+ // draw menu
+ this->menu++;
+ graphics_draw_mode(gra, draw_mode_begin);
+ gui_internal_clear(this);
+ gui_internal_render_menu(this, 0, main_menu, sizeof(main_menu)/sizeof(struct widget));
+ graphics_draw_mode(gra, draw_mode_end);
+ return;
+ }
+
+ // if already in the menu:
+ if (pressed) {
+ graphics_draw_mode(gra, draw_mode_begin);
+ gui_internal_highlight(this, p);
+ graphics_draw_mode(gra, draw_mode_end);
+ } else {
+ graphics_draw_mode(gra, draw_mode_begin);
+ gui_internal_highlight(this, p);
+ graphics_draw_mode(gra, draw_mode_end);
+ gui_internal_call_highlighted(this);
+ if (this->menu) {
+ graphics_draw_mode(gra, draw_mode_begin);
+ gui_internal_highlight(this, NULL);
+ graphics_draw_mode(gra, draw_mode_end);
+ }
+ }
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static void gui_internal_resize(struct gui_priv *this, int w, int h)
+{
+ this->w=w;
+ this->h=h;
+ dbg(0,"w=%d h=%d\n", w, h);
+ if (!this->menu)
+ navit_resize(this->nav, w, h);
+}
+
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static int gui_internal_set_graphics(struct gui_priv *this, struct graphics *gra)
+{
+ void *graphics;
+ struct color cb={0x7fff,0x7fff,0x7fff,0xffff};
+ struct color cbh={0x9fff,0x9fff,0x9fff,0xffff};
+ struct color cf={0xbfff,0xbfff,0xbfff,0xffff};
+ struct transformation *trans=navit_get_trans(this->nav);
+
+ dbg(0,"enter\n");
+ graphics=graphics_get_data(gra, "window");
+ if (! graphics)
+ return 1;
+ this->gra=gra;
+ transform_get_size(trans, &this->w, &this->h);
+ graphics_register_resize_callback(gra, gui_internal_resize, this);
+ graphics_register_button_callback(gra, gui_internal_button, this);
+ graphics_register_motion_callback(gra, gui_internal_motion, this);
+ this->background=graphics_gc_new(gra);
+ graphics_gc_set_foreground(this->background, &cb);
+ this->highlight_background=graphics_gc_new(gra);
+ graphics_gc_set_foreground(this->highlight_background, &cbh);
+ this->foreground=graphics_gc_new(gra);
+ graphics_gc_set_foreground(this->foreground, &cf);
+ this->font=graphics_font_new(gra, 200, 1);
+ return 0;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+struct gui_methods gui_internal_methods = {
+ NULL,
+ NULL,
+ gui_internal_set_graphics,
+};
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+static struct gui_priv * gui_internal_new(struct navit *nav, struct gui_methods *meth, struct attr **attrs)
+{
+ struct gui_priv *this;
+ *meth=gui_internal_methods;
+ this=g_new0(struct gui_priv, 1);
+ this->nav=nav;
+
+ return this;
+}
+
+//##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void plugin_init(void)
+{
+ plugin_register_gui_type("internal", gui_internal_new);
+}
diff --git a/navit/gui/sdl/Makefile.am b/navit/gui/sdl/Makefile.am
new file mode 100644
index 000000000..795e35ef3
--- /dev/null
+++ b/navit/gui/sdl/Makefile.am
@@ -0,0 +1,6 @@
+include $(top_srcdir)/Makefile.inc
+SUBDIRS=datafiles
+AM_CPPFLAGS = @NAVIT_CFLAGS@ @CEGUI_CFLAGS@ @GLC_CFLAGS@ -I$(top_srcdir)/src -DMODULE=gui_sdl
+modulegui_LTLIBRARIES = libgui_sdl.la
+libgui_sdl_la_SOURCES = gui_sdl_window.cpp sdl_events.cpp gui_sdl.h sdl_events.h wmcontrol.c wmcontrol.h cegui_keyboard.cpp cegui_keyboard.h
+libgui_sdl_la_LIBADD = @SDL_LIBS@ @CEGUI_LIBS@ @OPENGL_LIBS@ @GLC_LIBS@
diff --git a/navit/gui/sdl/cegui_keyboard.cpp b/navit/gui/sdl/cegui_keyboard.cpp
new file mode 100644
index 000000000..3bf0888fd
--- /dev/null
+++ b/navit/gui/sdl/cegui_keyboard.cpp
@@ -0,0 +1,94 @@
+#include "CEGUI.h"
+#include "sdl_events.h"
+
+
+bool ShowKeyboard(const CEGUI::EventArgs& event){
+ CEGUI::WindowManager::getSingleton().getWindow("Navit/Keyboard/Input")->setText("");
+ CEGUI::WindowManager::getSingleton().getWindow("Navit/Keyboard")->show();
+}
+
+
+
+void Add_KeyBoard_key(CEGUI::String key,int x,int y,int w){
+
+ using namespace CEGUI;
+// char button_name [5];
+// sprintf(button_name,"%s",key);
+ FrameWindow* wnd = (FrameWindow*)WindowManager::getSingleton().createWindow("TaharezLook/Button", key);
+ CEGUI::WindowManager::getSingleton().getWindow("Navit/Keyboard")->addChildWindow(wnd);
+ wnd->setPosition(UVector2(cegui_absdim(x), cegui_absdim( y)));
+ wnd->setSize(UVector2(cegui_absdim(w), cegui_absdim( 40)));
+ wnd->setText(key);
+ wnd->subscribeEvent(PushButton::EventClicked, Event::Subscriber(Handle_Virtual_Key_Down));
+
+}
+
+
+void BuildKeyboard(){
+ int w=55;
+ int offset_x=10;
+ int count_x=0;
+
+ int y=25;
+ Add_KeyBoard_key("A",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("Z",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("E",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("R",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("T",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("Y",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("U",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("I",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("O",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("P",offset_x+(count_x++)*w,y,w);
+ count_x++;
+ Add_KeyBoard_key("7",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("8",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("9",offset_x+(count_x++)*w,y,w);
+
+ y=70;
+ count_x=0;
+ Add_KeyBoard_key("Q",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("S",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("D",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("F",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("G",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("H",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("J",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("K",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("L",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("M",offset_x+(count_x++)*w,y,w);
+ count_x++;
+ Add_KeyBoard_key("4",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("5",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("6",offset_x+(count_x++)*w,y,w);
+
+ y=115;
+ count_x=0;
+
+ Add_KeyBoard_key("W",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("X",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("C",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("V",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("B",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("N",offset_x+(count_x++)*w,y,w);
+
+ Add_KeyBoard_key(" ",offset_x+(count_x++)*w,y,w*2);
+ count_x++;
+
+ Add_KeyBoard_key("BACK",offset_x+(count_x++)*w,y,w*2);
+ count_x+=2;
+
+ Add_KeyBoard_key("1",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("2",offset_x+(count_x++)*w,y,w);
+ Add_KeyBoard_key("3",offset_x+(count_x++)*w,y,w);
+
+ y=160;
+ count_x=11;
+ Add_KeyBoard_key("0",offset_x+(count_x++)*w,y,w);
+
+ Add_KeyBoard_key("OK",offset_x+(count_x++)*w,y,w*2);
+
+
+}
+
+
diff --git a/navit/gui/sdl/cegui_keyboard.h b/navit/gui/sdl/cegui_keyboard.h
new file mode 100644
index 000000000..bb329499c
--- /dev/null
+++ b/navit/gui/sdl/cegui_keyboard.h
@@ -0,0 +1,5 @@
+bool ShowKeyboard(const CEGUI::EventArgs& event);
+void Add_KeyBoard_key(CEGUI::String key,int x,int y,int w);
+void BuildKeyboard();
+bool Handle_Virtual_Key_Down(const CEGUI::EventArgs& event);
+
diff --git a/navit/gui/sdl/datafiles/Makefile.am b/navit/gui/sdl/datafiles/Makefile.am
new file mode 100644
index 000000000..0a1e19bfd
--- /dev/null
+++ b/navit/gui/sdl/datafiles/Makefile.am
@@ -0,0 +1,20 @@
+# include $(top_srcdir)/Makefile.inc
+
+CEGUIFONTSdir=$(pkgdatadir)/datafiles/fonts
+# CEGUIFONTS_DATA = fonts/DejaVuSans-10.font fonts/DejaVuSans-14.font fonts/DejaVuSans-18.font fonts/DejaVuSans.ttf fonts/Font.xsd
+CEGUIFONTS_DATA = fonts/DejaVuSans-10.font fonts/DejaVuSans-12.font fonts/DejaVuSans-14.font fonts/DejaVuSans.ttf fonts/Font.xsd
+
+CEGUILAYOUTdir=$(pkgdatadir)/datafiles/layouts
+CEGUILAYOUT_DATA = layouts/GUILayout.xsd layouts/Mineque.layout layouts/TaharezLook.layout
+
+CEGUIIMAGESETSdir=$(pkgdatadir)/datafiles/imagesets
+CEGUIIMAGESETS_DATA = imagesets/Imageset.xsd imagesets/Mineque-Black.imageset imagesets/navit-skin-black-imageset.tga \
+ imagesets/TaharezLook.imageset imagesets/TaharezLook.tga
+
+CEGUILOOKNFEELdir=$(pkgdatadir)/datafiles/looknfeel
+CEGUILOOKNFEEL_DATA = looknfeel/Falagard.xsd looknfeel/Mineque.looknfeel looknfeel/TaharezLook.looknfeel
+
+CEGUISCHEMESdir=$(pkgdatadir)/datafiles/schemes
+CEGUISCHEMES_DATA = schemes/GUIScheme.xsd schemes/Mineque.scheme schemes/TaharezLook.scheme
+
+EXTRA_DIST = $(CEGUIFONTS_DATA) $(CEGUILAYOUT_DATA) $(CEGUIIMAGESETS_DATA) $(CEGUILOOKNFEEL_DATA) $(CEGUISCHEMES_DATA)
diff --git a/navit/gui/sdl/datafiles/fonts/DejaVuSans-10.font b/navit/gui/sdl/datafiles/fonts/DejaVuSans-10.font
new file mode 100755
index 000000000..25e51b2cf
--- /dev/null
+++ b/navit/gui/sdl/datafiles/fonts/DejaVuSans-10.font
@@ -0,0 +1,2 @@
+<?xml version="1.0" ?>
+<Font Name="DejaVuSans-10" Filename="DejaVuSans.ttf" Type="FreeType" Size="10" NativeHorzRes="800" NativeVertRes="600" AutoScaled="true"/>
diff --git a/navit/gui/sdl/datafiles/fonts/DejaVuSans-12.font b/navit/gui/sdl/datafiles/fonts/DejaVuSans-12.font
new file mode 100755
index 000000000..56f65a24e
--- /dev/null
+++ b/navit/gui/sdl/datafiles/fonts/DejaVuSans-12.font
@@ -0,0 +1,2 @@
+<?xml version="1.0" ?>
+<Font Name="DejaVuSans-12" Filename="DejaVuSans.ttf" Type="FreeType" Size="12" NativeHorzRes="800" NativeVertRes="600" AutoScaled="true"/>
diff --git a/navit/gui/sdl/datafiles/fonts/DejaVuSans-14.font b/navit/gui/sdl/datafiles/fonts/DejaVuSans-14.font
new file mode 100755
index 000000000..ddddd46db
--- /dev/null
+++ b/navit/gui/sdl/datafiles/fonts/DejaVuSans-14.font
@@ -0,0 +1,2 @@
+<?xml version="1.0" ?>
+<Font Name="DejaVuSans-14" Filename="DejaVuSans.ttf" Type="FreeType" Size="14" NativeHorzRes="800" NativeVertRes="600" AutoScaled="true"/>
diff --git a/navit/gui/sdl/datafiles/fonts/DejaVuSans.ttf b/navit/gui/sdl/datafiles/fonts/DejaVuSans.ttf
new file mode 100755
index 000000000..7e96e8ec9
--- /dev/null
+++ b/navit/gui/sdl/datafiles/fonts/DejaVuSans.ttf
Binary files differ
diff --git a/navit/gui/sdl/datafiles/fonts/Font.xsd b/navit/gui/sdl/datafiles/fonts/Font.xsd
new file mode 100644
index 000000000..5ab529cd7
--- /dev/null
+++ b/navit/gui/sdl/datafiles/fonts/Font.xsd
@@ -0,0 +1,34 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+ <xsd:element name="Font" type="FontType" />
+
+ <xsd:complexType name="FontType">
+ <xsd:sequence>
+ <xsd:element name="Mapping" type="MapType" maxOccurs="unbounded" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attributeGroup ref="FontAttrs" />
+ </xsd:complexType>
+ <xsd:complexType name="MapType">
+ <xsd:attribute name="Codepoint" type="xsd:nonNegativeInteger" use="required" />
+ <xsd:attribute name="Image" type="xsd:string" use="required" />
+ <xsd:attribute name="HorzAdvance" type="xsd:integer" use="optional" default="-1" />
+ </xsd:complexType>
+ <xsd:attributeGroup name="FontAttrs">
+ <xsd:attribute name="Name" type="xsd:string" use="required" />
+ <xsd:attribute name="Filename" type="xsd:string" use="required" />
+ <xsd:attribute name="ResourceGroup" type="xsd:string" use="optional" default="" />
+ <xsd:attribute name="Type" use="required">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="FreeType" />
+ <xsd:enumeration value="Pixmap" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="Size" type="xsd:nonNegativeInteger" use="optional" default="12" />
+ <xsd:attribute name="NativeHorzRes" type="xsd:nonNegativeInteger" use="optional" default="640" />
+ <xsd:attribute name="NativeVertRes" type="xsd:nonNegativeInteger" use="optional" default="480" />
+ <xsd:attribute name="AutoScaled" type="xsd:boolean" use="optional" default="false" />
+ <xsd:attribute name="AntiAlias" type="xsd:boolean" use="optional" default="true" />
+ </xsd:attributeGroup>
+</xsd:schema>
diff --git a/navit/gui/sdl/datafiles/imagesets/Imageset.xsd b/navit/gui/sdl/datafiles/imagesets/Imageset.xsd
new file mode 100644
index 000000000..49ced132a
--- /dev/null
+++ b/navit/gui/sdl/datafiles/imagesets/Imageset.xsd
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+
+ <xsd:element name="Imageset" type="ImagesetType"/>
+
+ <xsd:complexType name="ImagesetType">
+ <xsd:sequence>
+ <xsd:element name="Image" type="ImageType" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="Imagefile" type="xsd:string" use="required"/>
+ <xsd:attribute name="ResourceGroup" type="xsd:string" use="optional" default="" />
+ <xsd:attribute name="Name" type="xsd:string" use="required"/>
+ <xsd:attribute name="NativeHorzRes" type="xsd:nonNegativeInteger" use="optional" default="640" />
+ <xsd:attribute name="NativeVertRes" type="xsd:nonNegativeInteger" use="optional" default="480" />
+ <xsd:attribute name="AutoScaled" type="xsd:boolean" use="optional" default="false" />
+ </xsd:complexType>
+
+ <xsd:complexType name="ImageType">
+ <xsd:attribute name="Name" type="xsd:string" use="required"/>
+ <xsd:attribute name="XPos" type="xsd:nonNegativeInteger" use="required"/>
+ <xsd:attribute name="YPos" type="xsd:nonNegativeInteger" use="required"/>
+ <xsd:attribute name="Width" type="xsd:nonNegativeInteger" use="required"/>
+ <xsd:attribute name="Height" type="xsd:nonNegativeInteger" use="required"/>
+ <xsd:attribute name="XOffset" type="xsd:integer" use="optional" default="0"/>
+ <xsd:attribute name="YOffset" type="xsd:integer" use="optional" default="0"/>
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/navit/gui/sdl/datafiles/imagesets/Mineque-Black.imageset b/navit/gui/sdl/datafiles/imagesets/Mineque-Black.imageset
new file mode 100644
index 000000000..ef19947e1
--- /dev/null
+++ b/navit/gui/sdl/datafiles/imagesets/Mineque-Black.imageset
@@ -0,0 +1,37 @@
+<?xml version="1.0" ?>
+<Imageset Name="Mineque-Black" Imagefile="navit-skin-black-imageset.tga" NativeHorzRes="800" NativeVertRes="730" AutoScaled="true">
+<!--
+Imagefile - file with all textures inside
+NativeHorzRes, NativeVertRes - image size in pixels
+Image Name - name of texture we will further use in layout and looknfeel files
+XPos, YPos - position (X,Y) of texture parts in image file it's count for "d" corner as below
+ d____e
+ | |
+ |____|
+ f g
+-->
+<!-- Round panel parts -->
+ <Image Name="ZoomOutButton" XPos="0" YPos="260" Width="62" Height="93" />
+ <Image Name="ZoomInButton" XPos="0" YPos="360" Width="92" Height="62" />
+ <Image Name="ViewModeSwitchButton" XPos="0" YPos="153" Width="98" Height="98" />
+<!-- Top panel parts -->
+ <Image Name="QuitButton" XPos="0" YPos="450" Width="29" Height="30" />
+ <Image Name="RouteButton" XPos="35" YPos="450" Width="36" Height="36" />
+ <Image Name="OptionsButton" XPos="75" YPos="450" Width="37" Height="25" />
+ <Image Name="SpeakerOffButton" XPos="115" YPos="450" Width="28" Height="36" />
+ <Image Name="SpeakerOnButton" XPos="145" YPos="450" Width="28" Height="36" />
+ <Image Name="SateliteImage" XPos="230" YPos="450" Width="30" Height="38" />
+ <Image Name="SateliteStrenghBarOn" XPos="180" YPos="450" Width="17" Height="32" />
+ <Image Name="SateliteStrenghBarOff" XPos="200" YPos="450" Width="17" Height="32" />
+ <Image Name="TopPanel" XPos="0" YPos="53" Width="800" Height="64" />
+ <Image Name="NavitAboutButton" XPos="0" YPos="500" Width="82" Height="25" />
+<!-- Right panel parts -->
+ <Image Name="RightPanel" XPos="635" YPos="127" Width="165" Height="600" />
+<!-- Navigation area -->
+ <Image Name="ArrowLeft" XPos="258" YPos="450" Width="39" Height="34" />
+ <Image Name="ArrowTop" XPos="316" YPos="450" Width="34" Height="39" />
+ <Image Name="ArrowRight" XPos="435" YPos="450" Width="39" Height="34" />
+ <Image Name="ArrowDown" XPos="275" YPos="450" Width="34" Height="39" />
+<!-- Bottom street panel part -->
+ <Image Name="BottomStreetPanel" XPos="0" YPos="0" Width="800" Height="50" />
+</Imageset>
diff --git a/navit/gui/sdl/datafiles/imagesets/TaharezLook.imageset b/navit/gui/sdl/datafiles/imagesets/TaharezLook.imageset
new file mode 100755
index 000000000..e5aef9813
--- /dev/null
+++ b/navit/gui/sdl/datafiles/imagesets/TaharezLook.imageset
@@ -0,0 +1,242 @@
+<?xml version="1.0" ?>
+<Imageset Name="TaharezLook" Imagefile="TaharezLook.tga" NativeHorzRes="800" NativeVertRes="600" AutoScaled="true">
+ <Image Name="ClientBrush" XPos="2" YPos="2" Width="64" Height="64" />
+ <Image Name="WindowLeftEdge" XPos="6" YPos="95" Width="1" Height="22" XOffset="4" />
+ <Image Name="WindowRightEdge" XPos="34" YPos="95" Width="1" Height="22" XOffset="-5" />
+ <Image Name="WindowTopEdge" XPos="9" YPos="68" Width="23" Height="1" />
+ <Image Name="WindowBottomEdge" XPos="9" YPos="143" Width="23" Height="1" />
+ <Image Name="WindowTopLeft" XPos="2" YPos="68" Width="5" Height="24" />
+ <Image Name="WindowTopRight" XPos="34" YPos="68" Width="5" Height="24" />
+ <Image Name="WindowBottomLeft" XPos="2" YPos="120" Width="5" Height="24" />
+ <Image Name="WindowBottomRight" XPos="34" YPos="120" Width="5" Height="24" />
+ <Image Name="ButtonLeftNormal" XPos="68" YPos="20" Width="12" Height="16" />
+ <Image Name="ButtonMiddleNormal" XPos="82" YPos="20" Width="12" Height="16" />
+ <Image Name="ButtonRightNormal" XPos="96" YPos="20" Width="12" Height="16" />
+ <Image Name="ButtonLeftPushed" XPos="68" YPos="38" Width="12" Height="16" />
+ <Image Name="ButtonMiddlePushed" XPos="82" YPos="38" Width="12" Height="16" />
+ <Image Name="ButtonRightPushed" XPos="96" YPos="38" Width="12" Height="16" />
+ <Image Name="ButtonLeftHighlight" XPos="68" YPos="56" Width="12" Height="16" />
+ <Image Name="ButtonMiddleHighlight" XPos="82" YPos="56" Width="12" Height="16" />
+ <Image Name="ButtonRightHighlight" XPos="96" YPos="56" Width="12" Height="16" />
+ <Image Name="CheckboxNormal" XPos="110" YPos="2" Width="12" Height="12" />
+ <Image Name="CheckboxHover" XPos="110" YPos="30" Width="12" Height="12" />
+ <Image Name="CheckboxMark" XPos="110" YPos="16" Width="12" Height="12" />
+ <Image Name="RadioButtonNormal" XPos="124" YPos="2" Width="12" Height="12" />
+ <Image Name="RadioButtonHover" XPos="124" YPos="30" Width="12" Height="12" />
+ <Image Name="RadioButtonMark" XPos="124" YPos="16" Width="12" Height="12" />
+ <Image Name="TitlebarLeft" XPos="68" YPos="2" Width="8" Height="16" />
+ <Image Name="TitlebarMiddle" XPos="78" YPos="2" Width="8" Height="16" />
+ <Image Name="TitlebarRight" XPos="88" YPos="2" Width="8" Height="16" />
+ <Image Name="NewTitlebarLeft" XPos="61" YPos="127" Width="13" Height="16" />
+ <Image Name="NewTitlebarMiddle" XPos="77" YPos="127" Width="12" Height="16" />
+ <Image Name="NewTitlebarRight" XPos="92" YPos="127" Width="12" Height="16" />
+ <Image Name="SysAreaMiddle" XPos="107" YPos="127" Width="12" Height="16" />
+ <Image Name="SysAreaRight" XPos="122" YPos="127" Width="13" Height="16" />
+ <Image Name="StaticLeft" XPos="41" YPos="89" Width="6" Height="6" />
+ <Image Name="StaticRight" XPos="63" YPos="89" Width="6" Height="6" />
+ <Image Name="StaticTop" XPos="52" YPos="78" Width="6" Height="6" />
+ <Image Name="StaticBottom" XPos="52" YPos="100" Width="6" Height="6" />
+ <Image Name="StaticTopLeft" XPos="41" YPos="78" Width="6" Height="6" />
+ <Image Name="StaticTopRight" XPos="63" YPos="78" Width="6" Height="6" />
+ <Image Name="StaticBottomLeft" XPos="41" YPos="100" Width="6" Height="6" />
+ <Image Name="StaticBottomRight" XPos="63" YPos="100" Width="6" Height="6" />
+ <Image Name="StaticBackdrop" XPos="52" YPos="89" Width="6" Height="6" />
+ <Image Name="ProgressBarLeft" XPos="71" YPos="74" Width="7" Height="12" />
+ <Image Name="ProgressBarMiddle" XPos="80" YPos="74" Width="6" Height="12" />
+ <Image Name="ProgressBarRight" XPos="88" YPos="74" Width="6" Height="12" />
+ <Image Name="ProgressBarDimSegment" XPos="96" YPos="74" Width="8" Height="12" />
+ <Image Name="ProgressBarLitSegment" XPos="106" YPos="74" Width="8" Height="12" />
+ <Image Name="EditBoxLeft" XPos="41" YPos="108" Width="4" Height="18" />
+ <Image Name="EditBoxMiddle" XPos="47" YPos="108" Width="4" Height="18" />
+ <Image Name="EditBoxRight" XPos="53" YPos="108" Width="4" Height="18" />
+ <Image Name="EditBoxCarat" XPos="60" YPos="108" Width="4" Height="18" />
+ <Image Name="SpinnerUpNormal" XPos="68" YPos="110" Width="10" Height="6" />
+ <Image Name="SpinnerDownNormal" XPos="68" YPos="118" Width="10" Height="6" />
+ <Image Name="SpinnerUpHover" XPos="82" YPos="110" Width="10" Height="6" />
+ <Image Name="SpinnerDownHover" XPos="82" YPos="118" Width="10" Height="6" />
+ <Image Name="TextSelectionBrush" XPos="8" YPos="70" Width="16" Height="16" />
+ <Image Name="VertScrollTop" XPos="182" YPos="2" Width="20" Height="8" />
+ <Image Name="VertScrollMiddle" XPos="182" YPos="12" Width="20" Height="8" />
+ <Image Name="VertScrollBottom" XPos="182" YPos="22" Width="20" Height="8" />
+ <Image Name="VertScrollBarSegment" XPos="206" YPos="2" Width="4" Height="10" />
+ <Image Name="VertScrollThumbNormal" XPos="214" YPos="2" Width="8" Height="24" />
+ <Image Name="VertScrollThumbHover" XPos="224" YPos="2" Width="8" Height="24" />
+ <Image Name="VertScrollUpNormal" XPos="196" YPos="32" Width="12" Height="12" />
+ <Image Name="VertScrollDownNormal" XPos="182" YPos="32" Width="12" Height="12" />
+ <Image Name="VertScrollUpHover" XPos="196" YPos="46" Width="12" Height="12" />
+ <Image Name="VertScrollDownHover" XPos="182" YPos="46" Width="12" Height="12" />
+ <Image Name="MiniVertScrollBarSegment" XPos="207" YPos="60" Width="4" Height="10" />
+ <Image Name="MiniVertScrollThumbNormal" XPos="214" YPos="59" Width="7" Height="22" />
+ <Image Name="MiniVertScrollThumbTopNormal" XPos="214" YPos="59" Width="7" Height="5" />
+ <Image Name="MiniVertScrollThumbMiddleNormal" XPos="214" YPos="65" Width="7" Height="5" />
+ <Image Name="MiniVertScrollThumbBottomNormal" XPos="214" YPos="76" Width="7" Height="5" />
+ <Image Name="MiniVertScrollThumbTopHover" XPos="223" YPos="59" Width="7" Height="5" />
+ <Image Name="MiniVertScrollThumbMiddleHover" XPos="223" YPos="65" Width="7" Height="5" />
+ <Image Name="MiniVertScrollThumbBottomHover" XPos="223" YPos="76" Width="7" Height="5" />
+ <Image Name="MiniVertScrollThumbHover" XPos="223" YPos="59" Width="7" Height="22" />
+ <Image Name="MiniVertScrollUpNormal" XPos="194" YPos="60" Width="10" Height="9" />
+ <Image Name="MiniVertScrollDownNormal" XPos="182" YPos="59" Width="10" Height="9" />
+ <Image Name="MiniVertScrollUpHover" XPos="194" YPos="70" Width="10" Height="9" />
+ <Image Name="MiniVertScrollDownHover" XPos="182" YPos="69" Width="10" Height="9" />
+ <Image Name="VertSliderBody" XPos="234" YPos="2" Width="9" Height="48" />
+ <Image Name="VertSliderThumbNormal" XPos="217" YPos="28" Width="15" Height="6" />
+ <Image Name="VertSliderThumbHover" XPos="217" YPos="36" Width="15" Height="6" />
+ <Image Name="MiniHorzScrollBarSegment" XPos="244" YPos="80" Width="10" Height="4" />
+ <Image Name="MiniHorzScrollThumbNormal" XPos="233" YPos="87" Width="22" Height="7" />
+ <Image Name="MiniHorzScrollThumbLeftNormal" XPos="233" YPos="87" Width="5" Height="7" />
+ <Image Name="MiniHorzScrollThumbMiddleNormal" XPos="239" YPos="87" Width="5" Height="7" />
+ <Image Name="MiniHorzScrollThumbRightNormal" XPos="250" YPos="87" Width="5" Height="7" />
+ <Image Name="MiniHorzScrollThumbHover" XPos="233" YPos="96" Width="22" Height="7" />
+ <Image Name="MiniHorzScrollThumbLeftHover" XPos="233" YPos="96" Width="5" Height="7" />
+ <Image Name="MiniHorzScrollThumbMiddleHover" XPos="239" YPos="96" Width="5" Height="7" />
+ <Image Name="MiniHorzScrollThumbRightHover" XPos="250" YPos="96" Width="5" Height="7" />
+ <Image Name="MiniHorzScrollLeftNormal" XPos="246" YPos="55" Width="9" Height="10" />
+ <Image Name="MiniHorzScrollRightNormal" XPos="245" YPos="67" Width="9" Height="10" />
+ <Image Name="MiniHorzScrollLeftHover" XPos="236" YPos="55" Width="9" Height="10" />
+ <Image Name="MiniHorzScrollRightHover" XPos="235" YPos="67" Width="9" Height="10" />
+ <Image Name="ListboxLeft" XPos="41" YPos="89" Width="7" Height="6" />
+ <Image Name="ListboxRight" XPos="62" YPos="89" Width="7" Height="6" />
+ <Image Name="ListboxTop" XPos="52" YPos="78" Width="6" Height="7" />
+ <Image Name="ListboxBottom" XPos="52" YPos="99" Width="6" Height="7" />
+ <Image Name="ListboxTopLeft" XPos="41" YPos="78" Width="7" Height="7" />
+ <Image Name="ListboxTopRight" XPos="62" YPos="78" Width="7" Height="7" />
+ <Image Name="ListboxBottomLeft" XPos="41" YPos="99" Width="7" Height="7" />
+ <Image Name="ListboxBottomRight" XPos="62" YPos="99" Width="7" Height="7" />
+ <Image Name="ListboxBackdrop" XPos="52" YPos="89" Width="6" Height="6" />
+ <Image Name="ListboxSelectionBrush" XPos="8" YPos="70" Width="16" Height="16" />
+ <Image Name="ComboboxEditLeft" XPos="138" YPos="2" Width="8" Height="16" />
+ <Image Name="ComboboxEditMiddle" XPos="148" YPos="2" Width="8" Height="16" />
+ <Image Name="ComboboxListButtonNormal" XPos="158" YPos="2" Width="16" Height="16" />
+ <Image Name="ComboboxListButtonHover" XPos="158" YPos="20" Width="16" Height="16" />
+ <Image Name="ComboboxListLeft" XPos="138" YPos="48" Width="8" Height="8" />
+ <Image Name="ComboboxListRight" XPos="158" YPos="48" Width="8" Height="8" />
+ <Image Name="ComboboxListTop" XPos="148" YPos="48" Width="8" Height="8" />
+ <Image Name="ComboboxListBottom" XPos="148" YPos="58" Width="8" Height="8" />
+ <Image Name="ComboboxListTopLeft" XPos="138" YPos="38" Width="8" Height="8" />
+ <Image Name="ComboboxListTopRight" XPos="158" YPos="38" Width="8" Height="8" />
+ <Image Name="ComboboxListBottomLeft" XPos="138" YPos="58" Width="8" Height="8" />
+ <Image Name="ComboboxListBottomRight" XPos="158" YPos="58" Width="8" Height="8" />
+ <Image Name="ComboboxListBackdrop" XPos="148" YPos="48" Width="8" Height="8" />
+ <Image Name="ComboboxSelectionBrush" XPos="8" YPos="70" Width="16" Height="16" />
+ <Image Name="ComboboxDividerLeft" XPos="138" YPos="68" Width="14" Height="1" />
+ <Image Name="ComboboxDividerMiddle" XPos="154" YPos="68" Width="8" Height="1" />
+ <Image Name="ComboboxDividerRight" XPos="164" YPos="68" Width="14" Height="1" />
+ <Image Name="HeaderBarBackdropNormal" XPos="230" YPos="163" Width="10" Height="12" />
+ <Image Name="HeaderBarBackdropHover" XPos="230" YPos="163" Width="10" Height="12" />
+ <Image Name="HeaderBarSplitterNormal" XPos="225" YPos="92" Width="3" Height="16" />
+ <Image Name="HeaderBarSplitterHover" XPos="200" YPos="92" Width="3" Height="16" />
+ <Image Name="HeaderBarSortUp" XPos="233" YPos="178" Width="8" Height="8" />
+ <Image Name="HeaderBarSortDown" XPos="244" YPos="178" Width="8" Height="8" />
+ <Image Name="MultiListLeft" XPos="170" YPos="92" Width="7" Height="6" />
+ <Image Name="MultiListRight" XPos="191" YPos="92" Width="7" Height="6" />
+ <Image Name="MultiListTop" XPos="181" YPos="81" Width="6" Height="7" />
+ <Image Name="MultiListBottom" XPos="181" YPos="102" Width="6" Height="7" />
+ <Image Name="MultiListTopLeft" XPos="170" YPos="81" Width="7" Height="7" />
+ <Image Name="MultiListTopRight" XPos="191" YPos="81" Width="7" Height="7" />
+ <Image Name="MultiListBottomLeft" XPos="170" YPos="102" Width="7" Height="7" />
+ <Image Name="MultiListBottomRight" XPos="191" YPos="102" Width="7" Height="7" />
+ <Image Name="MultiListBackdrop" XPos="181" YPos="92" Width="6" Height="6" />
+ <Image Name="MultiListSelectionBrush" XPos="9" YPos="71" Width="14" Height="14" />
+ <Image Name="AltProgressLeft" XPos="71" YPos="88" Width="8" Height="12" />
+ <Image Name="AltProgressMiddle" XPos="81" YPos="88" Width="8" Height="12" />
+ <Image Name="AltProgressRight" XPos="91" YPos="88" Width="8" Height="12" />
+ <Image Name="AltProgressQuarter" XPos="102" YPos="89" Width="3" Height="4" />
+ <Image Name="AltProgressHalf" XPos="109" YPos="89" Width="4" Height="5" />
+ <Image Name="AltProgressLight1" XPos="100" YPos="97" Width="4" Height="8" />
+ <Image Name="AltProgressLight2" XPos="106" YPos="97" Width="4" Height="8" />
+ <Image Name="AltProgressLight3" XPos="112" YPos="97" Width="4" Height="8" />
+ <Image Name="AltProgressLight4" XPos="118" YPos="97" Width="4" Height="8" />
+ <Image Name="AltProgressLight5" XPos="124" YPos="97" Width="4" Height="8" />
+ <Image Name="AltProgressLight6" XPos="130" YPos="97" Width="4" Height="8" />
+ <Image Name="AltProgressLight7" XPos="136" YPos="97" Width="4" Height="8" />
+ <Image Name="AltProgressLight8" XPos="142" YPos="97" Width="4" Height="8" />
+ <Image Name="AltProgressLight9" XPos="148" YPos="97" Width="4" Height="8" />
+ <Image Name="AltProgressLight10" XPos="154" YPos="97" Width="4" Height="8" />
+ <Image Name="CloseButtonNormal" XPos="41" YPos="128" Width="16" Height="16" />
+ <Image Name="CloseButtonHover" XPos="41" YPos="146" Width="16" Height="16" />
+ <Image Name="CloseButtonPressed" XPos="41" YPos="164" Width="16" Height="16" />
+ <Image Name="NewCloseButtonNormal" XPos="90" YPos="146" Width="10" Height="10" />
+ <Image Name="NewCloseButtonHover" XPos="90" YPos="146" Width="10" Height="10" />
+ <Image Name="NewCloseButtonPressed" XPos="90" YPos="146" Width="10" Height="10" />
+ <Image Name="MultiLineEditboxLeft" XPos="41" YPos="89" Width="6" Height="6" />
+ <Image Name="MultiLineEditboxRight" XPos="63" YPos="89" Width="6" Height="6" />
+ <Image Name="MultiLineEditboxTop" XPos="52" YPos="78" Width="6" Height="6" />
+ <Image Name="MultiLineEditboxBottom" XPos="52" YPos="100" Width="6" Height="6" />
+ <Image Name="MultiLineEditboxTopLeft" XPos="41" YPos="78" Width="6" Height="6" />
+ <Image Name="MultiLineEditboxTopRight" XPos="63" YPos="78" Width="6" Height="6" />
+ <Image Name="MultiLineEditboxBottomLeft" XPos="41" YPos="100" Width="6" Height="6" />
+ <Image Name="MultiLineEditboxBottomRight" XPos="63" YPos="100" Width="6" Height="6" />
+ <Image Name="MultiLineEditboxBackdrop" XPos="52" YPos="89" Width="6" Height="6" />
+ <Image Name="MultiLineEditboxSelectionBrush" XPos="9" YPos="71" Width="14" Height="14" />
+ <Image Name="MouseTarget" XPos="182" YPos="127" Width="17" Height="17" XOffset="-8" YOffset="-8" />
+ <Image Name="MouseArrow" XPos="138" YPos="127" Width="31" Height="25" XOffset="0" YOffset="0" />
+ <Image Name="MouseMoveCursor" XPos="201" YPos="127" Width="18" Height="18" XOffset="-8" YOffset="-8" />
+ <Image Name="MouseNoSoCursor" XPos="221" YPos="127" Width="8" Height="18" XOffset="-3" YOffset="-8" />
+ <Image Name="MouseEsWeCursor" XPos="182" YPos="150" Width="18" Height="8" XOffset="-8" YOffset="-3" />
+ <Image Name="MouseNeSwCursor" XPos="201" YPos="147" Width="14" Height="14" XOffset="-7" YOffset="-7" />
+ <Image Name="MouseNwSeCursor" XPos="230" YPos="126" Width="14" Height="14" XOffset="-7" YOffset="-7" />
+ <Image Name="MouseTextBar" XPos="173" YPos="127" Width="7" Height="18" XOffset="-2" YOffset="-9" />
+ <Image Name="TabHorizontalFiller" XPos="197" YPos="201" Width="7" Height="1" />
+ <Image Name="TabContentPaneUpperLeft" XPos="41" YPos="78" Width="7" Height="7" />
+ <Image Name="TabContentPaneUpper" XPos="52" YPos="78" Width="6" Height="7" />
+ <Image Name="TabContentPaneUpperRight" XPos="62" YPos="78" Width="7" Height="7" />
+ <Image Name="TabContentPaneLeft" XPos="41" YPos="89" Width="7" Height="6" />
+ <Image Name="TabContentPaneRight" XPos="62" YPos="89" Width="7" Height="6" />
+ <Image Name="TabContentPaneLower" XPos="52" YPos="99" Width="6" Height="7" />
+ <Image Name="TabContentPaneLowerLeft" XPos="41" YPos="99" Width="7" Height="7" />
+ <Image Name="TabContentPaneLowerRight" XPos="62" YPos="99" Width="7" Height="7" />
+ <Image Name="TabContentPaneMiddle" XPos="52" YPos="89" Width="6" Height="6" />
+ <Image Name="TabButtonScrollLeftNormal" XPos="97" YPos="108" Width="16" Height="17" />
+ <Image Name="TabButtonScrollRightNormal" XPos="112" YPos="108" Width="16" Height="17" />
+ <Image Name="TabButtonScrollLeftHover" XPos="127" YPos="108" Width="16" Height="17" />
+ <Image Name="TabButtonScrollRightHover" XPos="142" YPos="108" Width="16" Height="17" />
+ <Image Name="TabButtonLeftNormal" XPos="41" YPos="89" Width="7" Height="6" />
+ <Image Name="TabButtonRightNormal" XPos="62" YPos="89" Width="7" Height="6" />
+ <Image Name="TabButtonUpperNormal" XPos="52" YPos="78" Width="6" Height="7" />
+ <Image Name="TabButtonLowerNormal" XPos="52" YPos="99" Width="6" Height="7" />
+ <Image Name="TabButtonUpperLeftNormal" XPos="41" YPos="78" Width="7" Height="7" />
+ <Image Name="TabButtonUpperLeft2Normal" XPos="186" YPos="164" Width="7" Height="7" />
+ <Image Name="TabButtonUpperRightNormal" XPos="62" YPos="78" Width="7" Height="7" />
+ <Image Name="TabButtonLowerLeftNormal" XPos="41" YPos="99" Width="7" Height="7" />
+ <Image Name="TabButtonLowerRightNormal" XPos="62" YPos="99" Width="7" Height="7" />
+ <Image Name="TabButtonLowerRight2Normal" XPos="187" YPos="195" Width="7" Height="7" />
+ <Image Name="TabButtonMiddleNormal" XPos="52" YPos="89" Width="6" Height="6" />
+ <Image Name="TabButtonLeftSelected" XPos="41" YPos="89" Width="7" Height="6" />
+ <Image Name="TabButtonRightSelected" XPos="62" YPos="89" Width="7" Height="6" />
+ <Image Name="TabButtonUpperSelected" XPos="52" YPos="78" Width="6" Height="7" />
+ <Image Name="TabButtonLowerSelected" XPos="52" YPos="89" Width="6" Height="6" />
+ <Image Name="TabButtonUpperLeftSelected" XPos="41" YPos="78" Width="7" Height="7" />
+ <Image Name="TabButtonUpperRightSelected" XPos="62" YPos="78" Width="7" Height="7" />
+ <Image Name="TabButtonLowerLeftSelected" XPos="41" YPos="99" Width="7" Height="7" />
+ <Image Name="TabButtonLowerRightSelected" XPos="62" YPos="99" Width="7" Height="7" />
+ <Image Name="TabButtonMiddleSelected" XPos="52" YPos="89" Width="6" Height="6" />
+ <Image Name="TooltipTopLeft" XPos="61" YPos="160" Width="4" Height="4" />
+ <Image Name="TooltipTopRight" XPos="85" YPos="160" Width="5" Height="4" />
+ <Image Name="TooltipBottomLeft" XPos="61" YPos="184" Width="4" Height="5" />
+ <Image Name="TooltipBottomRight" XPos="85" YPos="184" Width="5" Height="5" />
+ <Image Name="TooltipLeftEdge" XPos="61" YPos="171" Width="4" Height="6" />
+ <Image Name="TooltipRightEdge" XPos="85" YPos="171" Width="5" Height="6" />
+ <Image Name="TooltipTopEdge" XPos="72" YPos="160" Width="6" Height="4" />
+ <Image Name="TooltipBottomEdge" XPos="72" YPos="184" Width="6" Height="5" />
+ <Image Name="TooltipMiddle" XPos="72" YPos="171" Width="6" Height="6" />
+ <Image Name="MenuTopLeft" XPos="166" YPos="204" Width="2" Height="2" />
+ <Image Name="MenuTopRight" XPos="175" YPos="204" Width="3" Height="2" />
+ <Image Name="MenuBottomLeft" XPos="166" YPos="213" Width="2" Height="3" />
+ <Image Name="MenuBottomRight" XPos="175" YPos="213" Width="3" Height="3" />
+ <Image Name="MenuLeft" XPos="166" YPos="209" Width="2" Height="1" />
+ <Image Name="MenuRight" XPos="175" YPos="209" Width="3" Height="1" />
+ <Image Name="MenuTop" XPos="171" YPos="204" Width="1" Height="2" />
+ <Image Name="MenuBottom" XPos="171" YPos="213" Width="1" Height="3" />
+ <Image Name="MenuMiddle" XPos="171" YPos="209" Width="1" Height="1" />
+ <Image Name="PopupMenuFrameTopLeft" XPos="186" YPos="204" Width="2" Height="2" />
+ <Image Name="PopupMenuFrameTopRight" XPos="195" YPos="204" Width="4" Height="2" />
+ <Image Name="PopupMenuFrameBottomLeft" XPos="186" YPos="213" Width="2" Height="4" />
+ <Image Name="PopupMenuFrameBottomRight" XPos="195" YPos="213" Width="4" Height="4" />
+ <Image Name="PopupMenuFrameLeft" XPos="186" YPos="209" Width="2" Height="1" />
+ <Image Name="PopupMenuFrameRight" XPos="195" YPos="209" Width="4" Height="1" />
+ <Image Name="PopupMenuFrameTop" XPos="191" YPos="204" Width="1" Height="2" />
+ <Image Name="PopupMenuFrameBottom" XPos="191" YPos="213" Width="1" Height="4" />
+ <Image Name="PopupMenuMiddle" XPos="191" YPos="209" Width="1" Height="1" />
+ <Image Name="PopupMenuArrowRight" XPos="179" YPos="204" Width="5" Height="5" />
+ <Image Name="PopupMenuArrowLeft" XPos="179" YPos="210" Width="5" Height="5" />
+</Imageset>
diff --git a/navit/gui/sdl/datafiles/imagesets/TaharezLook.tga b/navit/gui/sdl/datafiles/imagesets/TaharezLook.tga
new file mode 100755
index 000000000..9659b7fba
--- /dev/null
+++ b/navit/gui/sdl/datafiles/imagesets/TaharezLook.tga
Binary files differ
diff --git a/navit/gui/sdl/datafiles/imagesets/navit-skin-black-imageset.tga b/navit/gui/sdl/datafiles/imagesets/navit-skin-black-imageset.tga
new file mode 100644
index 000000000..f617b78d9
--- /dev/null
+++ b/navit/gui/sdl/datafiles/imagesets/navit-skin-black-imageset.tga
Binary files differ
diff --git a/navit/gui/sdl/datafiles/layouts/GUILayout.xsd b/navit/gui/sdl/datafiles/layouts/GUILayout.xsd
new file mode 100644
index 000000000..0a3a5b9cf
--- /dev/null
+++ b/navit/gui/sdl/datafiles/layouts/GUILayout.xsd
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+
+ <xsd:element name="GUILayout" type="GUILayoutType"/>
+
+ <xsd:complexType name="GUILayoutType">
+ <xsd:sequence>
+ <xsd:element name="Window" type="WindowType" />
+ </xsd:sequence>
+ <xsd:attribute name="Parent" type="xsd:string" use="optional" default=""/>
+ </xsd:complexType>
+
+ <xsd:complexType name="WindowType">
+ <xsd:sequence>
+ <xsd:element name="LayoutImport" type="LayoutImportType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="Property" type="PropertyType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="Event" type="EventType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="Window" type="WindowType" />
+ <xsd:element name="AutoWindow" type="AutoWindowType" />
+ </xsd:choice>
+ <xsd:element name="Property" type="PropertyType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="Type" type="xsd:string" use="required"/>
+ <xsd:attribute name="Name" type="xsd:string" use="optional" default="" />
+ </xsd:complexType>
+
+ <xsd:complexType name="AutoWindowType">
+ <xsd:sequence>
+ <xsd:element name="LayoutImport" type="LayoutImportType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="Property" type="PropertyType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="Event" type="EventType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="Window" type="WindowType" />
+ <xsd:element name="AutoWindow" type="AutoWindowType" />
+ </xsd:choice>
+ <xsd:element name="Property" type="PropertyType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="NameSuffix" type="xsd:string" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="PropertyType">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="Name" type="xsd:string" use="required"/>
+ <xsd:attribute name="Value" type="xsd:string" use="optional"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="LayoutImportType">
+ <xsd:attribute name="Filename" type="xsd:string" use="required"/>
+ <xsd:attribute name="Prefix" type="xsd:string" use="optional" default="" />
+ <xsd:attribute name="ResourceGroup" type="xsd:string" use="optional" default="" />
+ </xsd:complexType>
+
+ <xsd:complexType name="EventType">
+ <xsd:attribute name="Name" type="xsd:string" use="required"/>
+ <xsd:attribute name="Function" type="xsd:string" use="required"/>
+ </xsd:complexType>
+
+</xsd:schema>
+
diff --git a/navit/gui/sdl/datafiles/layouts/Mineque.layout b/navit/gui/sdl/datafiles/layouts/Mineque.layout
new file mode 100644
index 000000000..58f6e0739
--- /dev/null
+++ b/navit/gui/sdl/datafiles/layouts/Mineque.layout
@@ -0,0 +1,258 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+ <!-- The main window. Everything has to be a child of it. -->
+ <Window Type="DefaultWindow" Name="Navit" >
+ <Property Name="InheritsAlpha" Value="False" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+
+ <!-- Items for the Bottom Panel -->
+ <Window Type="NavitGrey/StaticImage" Name="BottomPanel" >
+ <Property Name="Image" Value="set:Mineque-Black image:BottomStreetPanel" />
+ <Property Name="UnifiedAreaRect" Value="{{0,1},{0,550},{0,660},{0,600}}" />
+ <Property Name="ZOrderChangeEnabled" value="False" />
+ </Window>
+ <Window Type="NavitGrey/StaticText" Name="Navit/Routing/Tips" >
+ <Property Name="Font" Value="DejaVuSans-14" />
+ <Property Name="Visible" Value="True" />
+ <Property Name="HorzFormatting" Value="WordWrapCentred" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0,60},{0,565},{0,600},{0,598}}" />
+ </Window>
+
+ <!-- Items for the Right Panel -->
+ <Window Type="NavitGrey/StaticImage" Name="RightPanel" >
+ <Property Name="Image" Value="set:Mineque-Black image:RightPanel" />
+ <Property Name="UnifiedAreaRect" Value="{{0,635},{0,0},{0,800},{0,600}}" />
+ <Property Name="ZOrderChangeEnabled" value="False" />
+ </Window>
+
+ <Window Type="NavitGrey/ViewModeSwitchButton" Name="OSD/ViewMode" >
+ <Property Name="UnifiedAreaRect" Value="{{0,702},{0,502},{0,800},{0,600}}" />
+ <Property Name="ZOrderChangeEnabled" value="False" />
+ </Window>
+ <Window Type="NavitGrey/ZoomInButton" Name="ZoomInButton" >
+ <Property Name="UnifiedAreaRect" Value="{{0,707},{0,469},{0,800},{0,532}}" />
+ <Property Name="ZOrderChangeEnabled" value="False" />
+ </Window>
+ <Window Type="NavitGrey/ZoomOutButton" Name="ZoomOutButton" >
+ <Property Name="UnifiedAreaRect" Value="{{0,669},{0,507},{0,731},{0,600}}" />
+ <Property Name="ZOrderChangeEnabled" value="False" />
+ </Window>
+
+ <Window Type="NavitGrey/StaticText" Name="OSD/SpeedoMeterLabel" >
+ <Property Name="Font" Value="DejaVuSans-12" />
+ <Property Name="Text" Value="Speed" />
+ <Property Name="HorzFormatting" Value="WordWrapCentred" />
+ <Property Name="UnifiedAreaRect" Value="{{0,670},{0,100},{0,800},{0,128}}" />
+ </Window>
+ <Window Type="NavitGrey/StaticText" Name="OSD/SpeedoMeter" >
+ <Property Name="Font" Value="DejaVuSans-14" />
+ <Property Name="HorzFormatting" Value="WordWrapCentred" />
+ <Property Name="UnifiedAreaRect" Value="{{0,670},{0,120},{0,800},{0,150}}" />
+ </Window>
+ <Window Type="NavitGrey/StaticText" Name="OSD/AltimeterLabel" >
+ <Property Name="Font" Value="DejaVuSans-12" />
+ <Property Name="Text" Value="Alt." />
+ <Property Name="HorzFormatting" Value="WordWrapCentred" />
+ <Property Name="UnifiedAreaRect" Value="{{0,670},{0,148},{0,800},{0,176}}" />
+ </Window>
+ <Window Type="NavitGrey/StaticText" Name="OSD/Altimeter" >
+ <Property Name="Font" Value="DejaVuSans-14" />
+ <Property Name="HorzFormatting" Value="WordWrapCentred" />
+ <Property Name="UnifiedAreaRect" Value="{{0,670},{0,164},{0,800},{0,194}}" />
+ </Window>
+ <Window Type="NavitGrey/StaticText" Name="OSD/Satellites" >
+ <Property Name="Font" Value="DejaVuSans-12" />
+ <Property Name="HorzFormatting" Value="WordWrapCentred" />
+ <Property Name="UnifiedAreaRect" Value="{{0,670},{0,196},{0,800},{0,226}}" />
+ </Window>
+
+
+
+ <Window Type="TaharezLook/LargeVerticalScrollbar" Name="OSD/Scrollbar1" >
+ <Property Name="PageSize" Value="0" />
+ <Property Name="OverlapSize" Value="0" />
+ <Property Name="StepSize" Value="200" />
+ <Property Name="DocumentSize" Value="2000" />
+ <Property Name="ScrollPosition" Value="400" />
+ <Property Name="UnifiedMaxSize" Value="{{0.03,0},{1,0}}" />
+ <Property Name="UnifiedMinSize" Value="{{0.01,0},{0.1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0,770},{0,300},{0,790},{0,450}}" />
+ </Window>
+
+
+ <!-- Items for the Top Panel -->
+ <Window Type="NavitGrey/StaticImage" Name="TopPanel" >
+ <Property Name="Image" Value="set:Mineque-Black image:TopPanel" />
+ <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{0,800},{0,64}}" />
+ <Property Name="ZOrderChangeEnabled" value="False" />
+ </Window>
+ <Window Type="NavitGrey/QuitButton" Name="OSD/Quit" >
+ <Property Name="UnifiedAreaRect" Value="{{0,8},{0,4},{0,37},{0,34}}" />
+ <Property Name="ZOrderChangeEnabled" value="False" />
+ </Window>
+ <Window Type="NavitGrey/RouteButton" Name="DestinationButton" >
+ <Property Name="UnifiedAreaRect" Value="{{0,152},{0,1},{0,188},{0,36}}" />
+ <Property Name="ZOrderChangeEnabled" value="False" />
+ </Window>
+ <Window Type="NavitGrey/StaticImage" Name="SateliteImage" >
+ <Property Name="Image" Value="set:Mineque-Black image:SateliteImage" />
+ <Property Name="UnifiedAreaRect" Value="{{0,672},{0,7},{0,702},{0,45}}" />
+ <Property Name="ZOrderChangeEnabled" value="False" />
+ </Window>
+
+ <Window Type="NavitGrey/OptionsButton" Name="OptionsButton" >
+ <Property Name="ZOrderChangeEnabled" value="False" />
+ <Property Name="UnifiedAreaRect" Value="{{0,79},{0,5},{0,116},{0,30}}" />
+ </Window>
+
+
+ <Window Type="NavitGrey/SpeakerButton" Name="OSD/nGhostButton" >
+ <Property Name="ZOrderChangeEnabled" value="False" />
+ <Property Name="UnifiedAreaRect" Value="{{0,632},{0,9},{0,660},{0,45}}" />
+ </Window>
+ <Window Type="NavitGrey/StaticImage" Name="SateliteStrenghBar1" >
+ <Property Name="Image" Value="set:Mineque-Black image:SateliteStrenghBarOff" />
+ <Property Name="UnifiedAreaRect" Value="{{0,707},{0,12},{0,724},{0,44}}" />
+ </Window>
+ <Window Type="NavitGrey/StaticImage" Name="SateliteStrenghBar2" >
+ <Property Name="Image" Value="set:Mineque-Black image:SateliteStrenghBarOff" />
+ <Property Name="UnifiedAreaRect" Value="{{0,722},{0,12},{0,739},{0,44}}" />
+ </Window>
+ <Window Type="NavitGrey/StaticImage" Name="SateliteStrenghBar3" >
+ <Property Name="Image" Value="set:Mineque-Black image:SateliteStrenghBarOff" />
+ <Property Name="UnifiedAreaRect" Value="{{0,737},{0,12},{0,754},{0,44}}" />
+ </Window>
+ <Window Type="NavitGrey/StaticImage" Name="SateliteStrenghBar4" >
+ <Property Name="Image" Value="set:Mineque-Black image:SateliteStrenghBarOff" />
+ <Property Name="UnifiedAreaRect" Value="{{0,752},{0,12},{0,769},{0,44}}" />
+ </Window>
+ <Window Type="NavitGrey/StaticImage" Name="SateliteStrenghBar5" >
+ <Property Name="Image" Value="set:Mineque-Black image:SateliteStrenghBarOff" />
+ <Property Name="UnifiedAreaRect" Value="{{0,767},{0,12},{0,784},{0,44}}" />
+ </Window>
+<!-- <Window Type="NavitGrey/NavitAboutButton" Name="NavitAboutButton"> -->
+ <Window Type="NavitGrey/NavitAboutButton" Name="OSD/RoadbookButton">
+ <Property Name="ZOrderChangeEnabled" value="False" />
+ <Property Name="UnifiedAreaRect" Value="{{0,361},{0,13},{0,443},{0,38}}" />
+ </Window>
+
+
+ <!-- The Destination window and its controls -->
+ <Window Type="TaharezLook/FrameWindow" Name="DestinationWindow" >
+ <Property Name="Text" Value="Choose your destination" />
+ <Property Name="Visible" Value="False" />
+ <Property Name="Alpha" Value="0.7" />
+ <Property Name="TitlebarEnabled" Value="True" />
+ <Property Name="UnifiedAreaRect" Value="{{0.001,0},{0.07,0},{0.8,0},{0.9,0}}" />
+ <Window Type="TaharezLook/StaticText" Name="DestinationWindow/Country" >
+ <Property Name="Text" Value="Country :" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.05,0},{0.271871,0},{0.1,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Editbox" Name="DestinationWindow/CountryEditbox" >
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.3,0},{0.05,0},{0.9,0},{0.1,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="DestinationWindow/Town" >
+ <Property Name="Text" Value="Town : " />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.11,0},{0.275,0},{0.16,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Editbox" Name="DestinationWindow/TownEditbox" >
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.3,0},{0.11,0},{0.9,0},{0.16,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="DestinationWindow/Street" >
+ <Property Name="Text" Value="Street : " />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.17,0},{0.275,0},{0.22,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Editbox" Name="DestinationWindow/StreetEditbox" >
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.3,0},{0.17,0},{0.9,0},{0.22,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="DestinationWindow/Label1" >
+ <Property Name="Text" Value="Pick your choice :" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.23,0},{0.9,0},{0.28,0}}" />
+ </Window>
+ <Window Type="TaharezLook/MultiColumnList" Name="DestinationWindow/Listbox" >
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.29,0},{0.945,0},{0.905842,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Button" Name="DestinationWindow/KB" >
+ <Property Name="Text" Value="Keyboard" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.54,0},{0.92,0},{0.70,0},{0.98,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Button" Name="DestinationWindow/GO" >
+ <Property Name="Text" Value="Go!" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.72,0},{0.92,0},{0.97,0},{0.98,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="DestinationWindow/Dest_x" >
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.92,0},{0.12,0},{0.98,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="DestinationWindow/Dest_y" >
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.12,0},{0.92,0},{0.23,0},{0.98,0}}" />
+ </Window>
+
+ </Window>
+
+ <!-- The RoadBook window, which use the old skin -->
+ <Window Type="TaharezLook/FrameWindow" Name="Navit/RoadBook" >
+ <Property Name="Alpha" Value="0.85" />
+ <Property Name="Visible" Value="False" />
+ <Property Name="AlwaysOnTop" Value="True" />
+ <Property Name="Text" Value="Road Book" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.02,0},{0.99,0},{0.87,0}}" />
+ <Window Type="TaharezLook/MultiColumnList" Name="Roadbook" >
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.05,0},{0.99,0},{0.93,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="RoadBook/ETA" >
+ <Property Name="Font" Value="DejaVuSans-12" />
+ <Property Name="HorzFormatting" Value="WordWrapCentred" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.1,0},{0.94,0},{0.7,0},{0.99,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Button" Name="OSD/RoadbookButton2" >
+ <Property Name="Text" Value="Close" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.8,0},{0.94,0},{0.99,0},{0.99,0}}" />
+ </Window>
+ </Window>
+ <Window Type="TaharezLook/FrameWindow" Name="Navit/Keyboard" >
+ <Property Name="Alpha" Value="0.85" />
+ <Property Name="Visible" Value="False" />
+ <Property Name="AlwaysOnTop" Value="True" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.5,0},{0.99,0},{0.87,0}}" />
+ <Window Type="TaharezLook/StaticText" Name="Navit/Keyboard/Input" >
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.80,0},{0.7,0},{0.95,0}}" />
+ </Window>
+ </Window>
+
+ <!-- These arrows will be used later, to move the map
+ <Window Type="NavitGrey/ArrowLeft" Name="ArrowLeft" >
+ <Property Name="UnifiedAreaRect" Value="{{0,},{0,0},{0,39},{0,34}}" />
+ </Window>
+ <Window Type="NavitGrey/ArrowTop" Name="ArrowTop" >
+ <Property Name="UnifiedAreaRect" Value="{{0,},{0,0},{0,34},{0,39}}" />
+ </Window>
+ <Window Type="NavitGrey/ArrowRight" Name="ArrowRight" >
+ <Property Name="UnifiedAreaRect" Value="{{0,},{0,0},{0,39},{0,34}}" />
+ </Window>
+ <Window Type="NavitGrey/ArrowDown" Name="ArrowDown" >
+ <Property Name="TitlebarEnabled" Value="False" />
+ <Property Name="UnifiedAreaRect" Value="{{0,},{0,0},{0,34},{0,39}}" />
+ </Window>
+ -->
+
+
+ </Window> <!-- Navit window -->
+</GUILayout>
diff --git a/navit/gui/sdl/datafiles/layouts/TaharezLook.layout b/navit/gui/sdl/datafiles/layouts/TaharezLook.layout
new file mode 100755
index 000000000..351dfbed0
--- /dev/null
+++ b/navit/gui/sdl/datafiles/layouts/TaharezLook.layout
@@ -0,0 +1,260 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+ <Window Type="DefaultWindow" Name="Navit" >
+ <Property Name="InheritsAlpha" Value="False" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+
+ <Window Type="TaharezLook/FrameWindow" Name="DestinationChoose" >
+ <Property Name="Text" Value="Choose your destination" />
+ <Property Name="Visible" Value="False" />
+ <Property Name="Alpha" Value="0.7" />
+ <Property Name="TitlebarEnabled" Value="True" />
+ <Property Name="UnifiedAreaRect" Value="{{0.001,0},{0.1,0},{0.8,0},{0.4,0}}" />
+ <Window Type="TaharezLook/Button" Name="DestinationWindow/Address" >
+ <Property Name="Text" Value="Search Address" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.02,0},{0.2,0},{0.26,0},{0.8,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Button" Name="DestinationWindow/Bookmark" >
+ <Property Name="Text" Value="Bookmark" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.32,0},{0.2,0},{0.57,0},{0.8,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Button" Name="DestinationWindow/FormerDest" >
+ <Property Name="Text" Value="FormerDest" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.62,0},{0.2,0},{0.87,0},{0.8,0}}" />
+ </Window>
+
+ </Window>
+
+
+ <Window Type="TaharezLook/FrameWindow" Name="BookmarkSelection" >
+ <Property Name="Text" Value="Choose your destination" />
+ <Property Name="Visible" Value="False" />
+ <Property Name="Alpha" Value="0.7" />
+ <Property Name="TitlebarEnabled" Value="True" />
+ <Property Name="UnifiedAreaRect" Value="{{0.001,0},{0.07,0},{0.8,0},{0.9,0}}" />
+ <Window Type="TaharezLook/MultiColumnList" Name="Bookmarks/Listbox" >
+ <Property Name="Font" Value="DejaVuSans-14" />
+ <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.15,0},{0.95,0},{0.9,0}}" />
+ </Window>
+ </Window>
+
+ <Window Type="TaharezLook/FrameWindow" Name="FormerDestSelection" >
+ <Property Name="Text" Value="Choose your destination" />
+ <Property Name="Visible" Value="False" />
+ <Property Name="Alpha" Value="0.7" />
+ <Property Name="TitlebarEnabled" Value="True" />
+ <Property Name="UnifiedAreaRect" Value="{{0.001,0},{0.07,0},{0.8,0},{0.9,0}}" />
+ <Window Type="TaharezLook/MultiColumnList" Name="FormerDests/Listbox" >
+ <Property Name="Font" Value="DejaVuSans-14" />
+ <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.15,0},{0.95,0},{0.9,0}}" />
+ </Window>
+ </Window>
+
+ <Window Type="TaharezLook/FrameWindow" Name="AdressSearchWindow" >
+ <Property Name="Text" Value="Choose your destination" />
+ <Property Name="Visible" Value="False" />
+ <Property Name="Alpha" Value="0.7" />
+ <Property Name="TitlebarEnabled" Value="True" />
+ <Property Name="UnifiedAreaRect" Value="{{0.001,0},{0.07,0},{0.8,0},{0.9,0}}" />
+ <Window Type="TaharezLook/StaticText" Name="AdressSearch/Country" >
+ <Property Name="Text" Value="Country :" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.05,0},{0.271871,0},{0.1,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Editbox" Name="AdressSearch/CountryEditbox" >
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.3,0},{0.05,0},{0.9,0},{0.1,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="AdressSearch/Town" >
+ <Property Name="Text" Value="Town : " />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.11,0},{0.275,0},{0.16,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Editbox" Name="AdressSearch/TownEditbox" >
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.3,0},{0.11,0},{0.9,0},{0.16,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="AdressSearch/Street" >
+ <Property Name="Text" Value="Street : " />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.17,0},{0.275,0},{0.22,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Editbox" Name="AdressSearch/StreetEditbox" >
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.3,0},{0.17,0},{0.9,0},{0.22,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="AdressSearch/Label1" >
+ <Property Name="Text" Value="Pick your choice :" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.23,0},{0.9,0},{0.28,0}}" />
+ </Window>
+ <Window Type="TaharezLook/MultiColumnList" Name="AdressSearch/Listbox" >
+ <Property Name="Font" Value="DejaVuSans-14" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.29,0},{0.945,0},{0.905842,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Button" Name="AdressSearch/KB" >
+ <Property Name="Text" Value="Keyboard" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.54,0},{0.92,0},{0.70,0},{0.98,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Button" Name="AdressSearch/GO" >
+ <Property Name="Text" Value="Go!" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.72,0},{0.92,0},{0.97,0},{0.98,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="AdressSearch/Dest_x" >
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.92,0},{0.12,0},{0.98,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="AdressSearch/Dest_y" >
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.12,0},{0.92,0},{0.23,0},{0.98,0}}" />
+ </Window>
+ </Window>
+
+ <Window Type="TaharezLook/StaticText" Name="Navit/Routing/Tips" >
+ <Property Name="Font" Value="DejaVuSans-14" />
+ <Property Name="Text" Value="No destination set." />
+ <Property Name="Alpha" Value="0.7" />
+ <Property Name="Visible" Value="False" />
+ <Property Name="HorzFormatting" Value="WordWrapCentred" />
+ <Property Name="UnifiedAreaRect" Value="{{0.02,0},{0.88,0},{0.77,0},{0.98,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="Navit/Routing/CurrentRoadName" >
+ <Property Name="Font" Value="DejaVuSans-14" />
+ <Property Name="Alpha" Value="0.7" />
+ <Property Name="HorzFormatting" Value="WordWrapCentred" />
+ <Property Name="UnifiedAreaRect" Value="{{0.02,0},{0.001,0},{0.77,0},{0.07,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Button" Name="DestinationButton" >
+ <Property Name="Text" Value="Destination" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.8,0},{0.01,0},{0.99,0},{0.06,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="OSD/SpeedoMeter" >
+ <Property Name="Font" Value="DejaVuSans-14" />
+ <Property Name="HorzFormatting" Value="WordWrapCentred" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.8,0},{0.06,0},{0.99,0},{0.11,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="OSD/Altimeter" >
+ <Property Name="Font" Value="DejaVuSans-14" />
+ <Property Name="HorzFormatting" Value="WordWrapCentred" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.8,0},{0.11,0},{0.99,0},{0.16,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="OSD/Satellites" >
+ <Property Name="Font" Value="DejaVuSans-12" />
+ <Property Name="HorzFormatting" Value="WordWrapCentred" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.8,0},{0.16,0},{0.99,0},{0.21,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="OSD/Coords" >
+ <Property Name="Font" Value="DejaVuSans-12" />
+ <Property Name="HorzFormatting" Value="WordWrapCentred" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.8,0},{0.21,0},{0.99,0},{0.26,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Button" Name="ZoomInButton" >
+ <Property Name="Text" Value="ZoomIn" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.8,0},{0.26,0},{0.99,0},{0.31,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Button" Name="ZoomOutButton" >
+ <Property Name="Text" Value="ZoomOut" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.8,0},{0.31,0},{0.99,0},{0.36,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Button" Name="OSD/RoadbookButton" >
+ <Property Name="Text" Value="RoadBook" />
+ <Property Name="Visible" Value="False" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.8,0},{0.36,0},{0.99,0},{0.41,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="OSD/ETA" >
+ <Property Name="Font" Value="DejaVuSans-12" />
+ <Property Name="Visible" Value="False" />
+ <Property Name="HorzFormatting" Value="WordWrapCentred" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.8,0},{0.41,0},{0.99,0},{0.51,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Button" Name="OSD/nGhostButton" >
+ <Property Name="Text" Value="Media" />
+ <Property Name="Visible" Value="True" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.8,0},{0.51,0},{0.99,0},{0.56,0}}" />
+ </Window>
+
+ <Window Type="TaharezLook/LargeVerticalScrollbar" Name="OSD/Scrollbar1" >
+ <Property Name="PageSize" Value="0" />
+ <Property Name="OverlapSize" Value="0" />
+ <Property Name="DocumentSize" Value="2000" />
+ <Property Name="ScrollPosition" Value="400" />
+ <Property Name="UnifiedMaxSize" Value="{{0.03,0},{1,0}}" />
+ <Property Name="UnifiedMinSize" Value="{{0.01,0},{0.1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.94,0},{0.58,0},{0.99,0},{0.85,0}}" />
+ </Window>
+
+
+ <Window Type="TaharezLook/Button" Name="OSD/ViewMode" >
+ <Property Name="Text" Value="3D" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.8,0},{0.87,0},{0.99,0},{0.93,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Button" Name="OSD/Quit" >
+ <Property Name="Text" Value="Quit" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.8,0},{0.93,0},{0.99,0},{0.99,0}}" />
+ </Window>
+ <Window Type="TaharezLook/FrameWindow" Name="Navit/ProgressWindow" >
+ <Property Name="Text" Value="Calculating the route" />
+ <Property Name="Visible" Value="False" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="TitlebarEnabled" Value="True" />
+ <Property Name="UnifiedAreaRect" Value="{{0.137865,0},{0.775,0},{0.729668,0},{0.888333,0}}" />
+ <Window Type="TaharezLook/ProgressBar" Name="Navit/ProgressWindow/Bar" >
+ <Property Name="StepSize" Value="0.01" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="CurrentProgress" Value="0" />
+ <Property Name="UnifiedAreaRect" Value="{{0.0920548,0},{0.513128,0},{0.872384,0},{0.921541,0}}" />
+ </Window>
+ </Window>
+ <Window Type="TaharezLook/FrameWindow" Name="Navit/RoadBook" >
+ <Property Name="Alpha" Value="0.85" />
+ <Property Name="Visible" Value="False" />
+ <Property Name="AlwaysOnTop" Value="True" />
+ <Property Name="Text" Value="Road Book" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.02,0},{0.99,0},{0.87,0}}" />
+ <Window Type="TaharezLook/MultiColumnList" Name="Roadbook" >
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.05,0},{0.99,0},{0.93,0}}" />
+ </Window>
+ <Window Type="TaharezLook/StaticText" Name="RoadBook/ETA" >
+ <Property Name="Font" Value="DejaVuSans-12" />
+ <Property Name="HorzFormatting" Value="WordWrapCentred" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.1,0},{0.94,0},{0.7,0},{0.99,0}}" />
+ </Window>
+ <Window Type="TaharezLook/Button" Name="OSD/RoadbookButton2" >
+ <Property Name="Text" Value="Close" />
+ <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+ <Property Name="UnifiedAreaRect" Value="{{0.8,0},{0.94,0},{0.99,0},{0.99,0}}" />
+ </Window>
+ </Window>
+ <Window Type="TaharezLook/FrameWindow" Name="Navit/Keyboard" >
+ <Property Name="Alpha" Value="0.85" />
+ <Property Name="Visible" Value="False" />
+ <Property Name="AlwaysOnTop" Value="True" />
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.5,0},{0.99,0},{0.87,0}}" />
+ <Window Type="TaharezLook/StaticText" Name="Navit/Keyboard/Input" >
+ <Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.80,0},{0.7,0},{0.95,0}}" />
+ </Window>
+ </Window>
+ </Window>
+</GUILayout>
diff --git a/navit/gui/sdl/datafiles/looknfeel/Falagard.xsd b/navit/gui/sdl/datafiles/looknfeel/Falagard.xsd
new file mode 100644
index 000000000..590de6bc9
--- /dev/null
+++ b/navit/gui/sdl/datafiles/looknfeel/Falagard.xsd
@@ -0,0 +1,399 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+ <xsd:element name="Falagard" type="falagardSpecificationType" />
+ <xsd:complexType name="falagardSpecificationType">
+ <xsd:sequence>
+ <xsd:element name="WidgetLook" type="widgetLookType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="widgetLookType">
+ <xsd:sequence>
+ <xsd:element name="PropertyDefinition" type="propertyDefinitionType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="PropertyLinkDefinition" type="propertyLinkDefinitionType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="Property" type="propertyType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="NamedArea" type="namedAreaType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="Child" type="widgetComponentType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="ImagerySection" type="imagerySectionType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="StateImagery" type="stateType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="propertyDefinitionType">
+ <xsd:attribute name="type" type="propertyTypeEnum" use="optional" default="Generic" />
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ <xsd:attribute name="initialValue" type="xsd:string" use="optional" default="" />
+ <xsd:attribute name="layoutOnWrite" type="xsd:boolean" use="optional" default="false" />
+ <xsd:attribute name="redrawOnWrite" type="xsd:boolean" use="optional" default="false" />
+ </xsd:complexType>
+ <xsd:complexType name="propertyLinkDefinitionType">
+ <xsd:attribute name="type" type="propertyTypeEnum" use="optional" default="Generic" />
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ <xsd:attribute name="widget" type="xsd:string" use="required" />
+ <xsd:attribute name="targetProperty" type="xsd:string" use="optional" default="" />
+ <xsd:attribute name="initialValue" type="xsd:string" use="optional" default="" />
+ <xsd:attribute name="layoutOnWrite" type="xsd:boolean" use="optional" default="false" />
+ <xsd:attribute name="redrawOnWrite" type="xsd:boolean" use="optional" default="false" />
+ </xsd:complexType>
+ <xsd:complexType name="namedAreaType">
+ <xsd:sequence>
+ <xsd:element name="Area" type="componentAreaType" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="stateType">
+ <xsd:sequence>
+ <xsd:element name="Layer" type="layerType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ <xsd:attribute name="clipped" type="xsd:boolean" use="optional" default="true" />
+ </xsd:complexType>
+ <xsd:complexType name="layerType">
+ <xsd:sequence>
+ <xsd:element name="Section" type="sectionSpecType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="priority" type="xsd:integer" use="optional" default="0" />
+ </xsd:complexType>
+ <xsd:complexType name="sectionSpecType">
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element name="Colour" type="colourType" />
+ <xsd:element name="Colours" type="colourRectType" />
+ <xsd:element name="ColourProperty" type="settingByPropertyType" />
+ <xsd:element name="ColourRectProperty" type="settingByPropertyType" />
+ </xsd:choice>
+ <xsd:attribute name="look" type="xsd:string" use="optional" default="" />
+ <xsd:attribute name="section" type="xsd:string" use="required" />
+ <xsd:attribute name="controlProperty" type="xsd:string" use="optional" default="" />
+ </xsd:complexType>
+ <xsd:complexType name="imagerySectionType">
+ <xsd:sequence>
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element name="Colour" type="colourType" />
+ <xsd:element name="Colours" type="colourRectType" />
+ <xsd:element name="ColourProperty" type="settingByPropertyType" />
+ <xsd:element name="ColourRectProperty" type="settingByPropertyType" />
+ </xsd:choice>
+ <xsd:element name="FrameComponent" type="frameComponentType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="ImageryComponent" type="imageryComponentType" minOccurs="0" maxOccurs="unbounded" />
+ <xsd:element name="TextComponent" type="textComponentType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="frameComponentType">
+ <xsd:sequence>
+ <xsd:element name="Area" type="componentAreaType" />
+ <xsd:element name="Image" type="frameImageType" minOccurs="0" maxOccurs="9" />
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element name="Colour" type="colourType" />
+ <xsd:element name="Colours" type="colourRectType" />
+ <xsd:element name="ColourProperty" type="settingByPropertyType" />
+ <xsd:element name="ColourRectProperty" type="settingByPropertyType" />
+ </xsd:choice>
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element name="VertFormat" type="vertFormatType" />
+ <xsd:element name="VertFormatProperty" type="settingByPropertyType" />
+ </xsd:choice>
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element name="HorzFormat" type="horzFormatType" />
+ <xsd:element name="HorzFormatProperty" type="settingByPropertyType" />
+ </xsd:choice>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="textComponentType">
+ <xsd:sequence>
+ <xsd:element name="Area" type="componentAreaType" />
+ <xsd:element name="Text" type="textStringType" minOccurs="0" maxOccurs="1" />
+ <xsd:element name="TextProperty" type="textPropertyType" minOccurs="0" maxOccurs="1" />
+ <xsd:element name="FontProperty" type="fontPropertyType" minOccurs="0" maxOccurs="1" />
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element name="Colour" type="colourType" />
+ <xsd:element name="Colours" type="colourRectType" />
+ <xsd:element name="ColourProperty" type="settingByPropertyType" />
+ <xsd:element name="ColourRectProperty" type="settingByPropertyType" />
+ </xsd:choice>
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element name="VertFormat" type="vertTextFormatType" />
+ <xsd:element name="VertFormatProperty" type="settingByPropertyType" />
+ </xsd:choice>
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element name="HorzFormat" type="horzTextFormatType" />
+ <xsd:element name="HorzFormatProperty" type="settingByPropertyType" />
+ </xsd:choice>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="imageryComponentType">
+ <xsd:sequence>
+ <xsd:element name="Area" type="componentAreaType" />
+ <xsd:choice>
+ <xsd:element name="Image" type="imageType" />
+ <xsd:element name="ImageProperty" type="settingByPropertyType" />
+ </xsd:choice>
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element name="Colour" type="colourType" />
+ <xsd:element name="Colours" type="colourRectType" />
+ <xsd:element name="ColourProperty" type="settingByPropertyType" />
+ <xsd:element name="ColourRectProperty" type="settingByPropertyType" />
+ </xsd:choice>
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element name="VertFormat" type="vertFormatType" />
+ <xsd:element name="VertFormatProperty" type="settingByPropertyType" />
+ </xsd:choice>
+ <xsd:choice minOccurs="0" maxOccurs="1">
+ <xsd:element name="HorzFormat" type="horzFormatType" />
+ <xsd:element name="HorzFormatProperty" type="settingByPropertyType" />
+ </xsd:choice>
+ </xsd:sequence>
+ </xsd:complexType>
+ <xsd:complexType name="widgetComponentType">
+ <xsd:sequence>
+ <xsd:element name="Area" type="componentAreaType" />
+ <xsd:element name="VertAlignment" type="vertAlignmentType" minOccurs="0" maxOccurs="1" />
+ <xsd:element name="HorzAlignment" type="horzAlignmentType" minOccurs="0" maxOccurs="1" />
+ <xsd:element name="Property" type="propertyType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="type" type="xsd:string" use="required" />
+ <xsd:attribute name="nameSuffix" type="xsd:string" use="required" />
+ <xsd:attribute name="renderer" type="xsd:string" use="optional" default="" />
+ <xsd:attribute name="look" type="xsd:string" use="optional" default="" />
+ </xsd:complexType>
+ <xsd:complexType name="horzFormatType">
+ <xsd:attribute name="type" type="horzFormatEnum" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="vertFormatType">
+ <xsd:attribute name="type" type="vertFormatEnum" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="horzTextFormatType">
+ <xsd:attribute name="type" type="horzTextFormatEnum" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="vertTextFormatType">
+ <xsd:attribute name="type" type="vertTextFormatEnum" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="horzAlignmentType">
+ <xsd:attribute name="type" type="horzAlignmentEnum" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="vertAlignmentType">
+ <xsd:attribute name="type" type="vertAlignmentEnum" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="propertyType">
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ <xsd:attribute name="value" type="xsd:string" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="imageType">
+ <xsd:attribute name="imageset" type="xsd:string" use="required" />
+ <xsd:attribute name="image" type="xsd:string" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="frameImageType">
+ <xsd:attribute name="type" type="frameImageComponentEnum" use="required" />
+ <xsd:attribute name="imageset" type="xsd:string" use="required" />
+ <xsd:attribute name="image" type="xsd:string" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="componentAreaType">
+ <xsd:choice>
+ <xsd:sequence>
+ <xsd:element name="Dim" type="dimensionType" minOccurs="4" maxOccurs="4" />
+ </xsd:sequence>
+ <xsd:element name="AreaProperty" type="settingByPropertyType" />
+ </xsd:choice>
+ </xsd:complexType>
+ <xsd:complexType name="dimensionType">
+ <xsd:choice>
+ <xsd:element name="UnifiedDim" type="unifiedDimType" />
+ <xsd:element name="AbsoluteDim" type="absoluteDimType" />
+ <xsd:element name="ImageDim" type="imageDimType" />
+ <xsd:element name="WidgetDim" type="widgetDimType" />
+ <xsd:element name="FontDim" type="fontDimType" />
+ <xsd:element name="PropertyDim" type="propertyDimType" />
+ </xsd:choice>
+ <xsd:attribute name="type" type="dimensionTypeEnum" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="fontDimType">
+ <xsd:sequence>
+ <xsd:element name="DimOperator" type="dimensionOperatorType" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="widget" type="xsd:string" use="optional" default="" />
+ <xsd:attribute name="font" type="xsd:string" use="optional" default="" />
+ <xsd:attribute name="string" type="xsd:string" use="optional" default="" />
+ <xsd:attribute name="type" type="fontMetricTypeEnum" use="required" />
+ <xsd:attribute name="padding" type="xsd:decimal" use="optional" default="0" />
+ </xsd:complexType>
+ <xsd:complexType name="propertyDimType">
+ <xsd:sequence>
+ <xsd:element name="DimOperator" type="dimensionOperatorType" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="widget" type="xsd:string" use="optional" default="" />
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ <xsd:attribute name="type" type="propertyDimensionTypeEnum" use="optional" default="" />
+ </xsd:complexType>
+ <xsd:complexType name="unifiedDimType">
+ <xsd:sequence>
+ <xsd:element name="DimOperator" type="dimensionOperatorType" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="scale" type="xsd:decimal" use="optional" default="0" />
+ <xsd:attribute name="offset" type="xsd:integer" use="optional" default="0" />
+ <xsd:attribute name="type" type="dimensionTypeEnum" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="absoluteDimType">
+ <xsd:sequence>
+ <xsd:element name="DimOperator" type="dimensionOperatorType" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="value" type="xsd:decimal" use="optional" default="0" />
+ </xsd:complexType>
+ <xsd:complexType name="imageDimType">
+ <xsd:sequence>
+ <xsd:element name="DimOperator" type="dimensionOperatorType" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="imageset" type="xsd:string" use="required" />
+ <xsd:attribute name="image" type="xsd:string" use="required" />
+ <xsd:attribute name="dimension" type="dimensionTypeEnum" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="widgetDimType">
+ <xsd:sequence>
+ <xsd:element name="DimOperator" type="dimensionOperatorType" minOccurs="0" maxOccurs="1" />
+ </xsd:sequence>
+ <xsd:attribute name="widget" type="xsd:string" use="optional" default="" />
+ <xsd:attribute name="dimension" type="dimensionTypeEnum" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="settingByPropertyType">
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="colourRectType">
+ <xsd:attribute name="topLeft" type="colourValType" use="required" />
+ <xsd:attribute name="topRight" type="colourValType" use="required" />
+ <xsd:attribute name="bottomLeft" type="colourValType" use="required" />
+ <xsd:attribute name="bottomRight" type="colourValType" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="colourType">
+ <xsd:attribute name="colour" type="colourValType" use="required" />
+ </xsd:complexType>
+ <xsd:simpleType name="colourValType">
+ <xsd:restriction base="xsd:string">
+ <xsd:pattern value="[a-fA-F0-9]{8}" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:complexType name="textStringType">
+ <xsd:attribute name="string" type="xsd:string" use="optional" default="" />
+ <xsd:attribute name="font" type="xsd:string" use="optional" default="" />
+ </xsd:complexType>
+ <xsd:complexType name="textPropertyType">
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="fontPropertyType">
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="dimensionOperatorType">
+ <xsd:choice>
+ <xsd:element name="UnifiedDim" type="unifiedDimType" />
+ <xsd:element name="AbsoluteDim" type="absoluteDimType" />
+ <xsd:element name="ImageDim" type="imageDimType" />
+ <xsd:element name="WidgetDim" type="widgetDimType" />
+ <xsd:element name="FontDim" type="fontDimType" />
+ <xsd:element name="PropertyDim" type="propertyDimType" />
+ </xsd:choice>
+ <xsd:attribute name="op" type="dimensionOperatorEnum" use="required" />
+ </xsd:complexType>
+ <xsd:simpleType name="propertyDimensionTypeEnum">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="" />
+ <xsd:enumeration value="Width" />
+ <xsd:enumeration value="Height" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="dimensionTypeEnum">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="LeftEdge" />
+ <xsd:enumeration value="TopEdge" />
+ <xsd:enumeration value="RightEdge" />
+ <xsd:enumeration value="BottomEdge" />
+ <xsd:enumeration value="XPosition" />
+ <xsd:enumeration value="YPosition" />
+ <xsd:enumeration value="Width" />
+ <xsd:enumeration value="Height" />
+ <xsd:enumeration value="XOffset" />
+ <xsd:enumeration value="YOffset" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="vertFormatEnum">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="TopAligned" />
+ <xsd:enumeration value="CentreAligned" />
+ <xsd:enumeration value="BottomAligned" />
+ <xsd:enumeration value="Stretched" />
+ <xsd:enumeration value="Tiled" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="horzFormatEnum">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="LeftAligned" />
+ <xsd:enumeration value="CentreAligned" />
+ <xsd:enumeration value="RightAligned" />
+ <xsd:enumeration value="Stretched" />
+ <xsd:enumeration value="Tiled" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="vertAlignmentEnum">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="TopAligned" />
+ <xsd:enumeration value="CentreAligned" />
+ <xsd:enumeration value="BottomAligned" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="horzAlignmentEnum">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="LeftAligned" />
+ <xsd:enumeration value="CentreAligned" />
+ <xsd:enumeration value="RightAligned" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="horzTextFormatEnum">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="LeftAligned" />
+ <xsd:enumeration value="RightAligned" />
+ <xsd:enumeration value="CentreAligned" />
+ <xsd:enumeration value="Justified" />
+ <xsd:enumeration value="WordWrapLeftAligned" />
+ <xsd:enumeration value="WordWrapRightAligned" />
+ <xsd:enumeration value="WordWrapCentreAligned" />
+ <xsd:enumeration value="WordWrapJustified" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="vertTextFormatEnum">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="TopAligned" />
+ <xsd:enumeration value="BottomAligned" />
+ <xsd:enumeration value="CentreAligned" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="propertyTypeEnum">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="Generic" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="fontMetricTypeEnum">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="LineSpacing" />
+ <xsd:enumeration value="Baseline" />
+ <xsd:enumeration value="HorzExtent" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="dimensionOperatorEnum">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="Noop" />
+ <xsd:enumeration value="Add" />
+ <xsd:enumeration value="Subtract" />
+ <xsd:enumeration value="Multiply" />
+ <xsd:enumeration value="Divide" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ <xsd:simpleType name="frameImageComponentEnum">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="Background" />
+ <xsd:enumeration value="TopLeftCorner" />
+ <xsd:enumeration value="TopRightCorner" />
+ <xsd:enumeration value="BottomLeftCorner" />
+ <xsd:enumeration value="BottomRightCorner" />
+ <xsd:enumeration value="LeftEdge" />
+ <xsd:enumeration value="RightEdge" />
+ <xsd:enumeration value="TopEdge" />
+ <xsd:enumeration value="BottomEdge" />
+ </xsd:restriction>
+ </xsd:simpleType>
+</xsd:schema>
diff --git a/navit/gui/sdl/datafiles/looknfeel/Mineque.looknfeel b/navit/gui/sdl/datafiles/looknfeel/Mineque.looknfeel
new file mode 100755
index 000000000..dc649600d
--- /dev/null
+++ b/navit/gui/sdl/datafiles/looknfeel/Mineque.looknfeel
@@ -0,0 +1,1476 @@
+<?xml version="1.0" ?>
+<Falagard>
+
+ <WidgetLook name="NavitGrey/StaticShared">
+ <ImagerySection name="frame">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+<!-- <Image type="TopLeftCorner" imageset="TaharezLook" image="StaticTopLeft" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="StaticTopRight" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="StaticBottomLeft" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="StaticBottomRight" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="StaticLeft" />
+ <Image type="RightEdge" imageset="TaharezLook" image="StaticRight" />
+ <Image type="TopEdge" imageset="TaharezLook" image="StaticTop" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="StaticBottom" />-->
+ <ColourRectProperty name="FrameColours" />
+ </FrameComponent>
+ </ImagerySection>
+
+ <ImagerySection name="background">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+<!-- <Image imageset="TaharezLook" image="StaticBackdrop" /> -->
+ <!--<ColourRectProperty name="BackgroundColours" />-->
+<!-- <Colours topLeft="FFFFFFFF" topRight="FFFFFFFF" bottomLeft="FFFFFFFF" bottomRight="FFFFFFFF" /> -->
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+
+
+ <ImagerySection name="background_noframe">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+<!-- <Dim type="RightEdge"><UnifiedDim scale="1" type="RightEdge" /></Dim> -->
+<!-- <Dim type="BottomEdge"><UnifiedDim scale="1" type="BottomEdge" /></Dim> -->
+ <Dim type="RightEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="BottomEdge"><AbsoluteDim value="0" /></Dim>
+ </Area>
+<!-- <Image imageset="TaharezLook" image="StaticBackdrop" />
+ <ColourRectProperty name="BackgroundColours" /> -->
+ <Colours topLeft="FFFFFFFF" topRight="FFFFFFFF" bottomLeft="FFFFFFFF" bottomRight="FFFFFFFF" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/StaticImage
+ ***************************************************
+ -->
+ <WidgetLook name="NavitGrey/StaticImage">
+ <PropertyDefinition name="ImageColours" initialValue="tl:FFFFFFFF tr:FFFFFFFF bl:FFFFFFFF br:FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="FrameColours" initialValue="tl:FFFFFFFF tr:FFFFFFFF bl:FFFFFFFF br:FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="BackgroundColours" initialValue="tl:FFFFFFFF tr:FFFFFFFF bl:FFFFFFFF br:FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="VertFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <PropertyDefinition name="HorzFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <Property name="BackgroundEnabled" value="True" />
+ <Property name="FrameEnabled" value="False" />
+ <ImagerySection name="image_withframe">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="StaticLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="StaticTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="StaticRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="StaticBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ <ImageProperty name="Image" />
+ <ColourRectProperty name="ImageColours" />
+ <VertFormatProperty name="VertFormatting" />
+ <HorzFormatProperty name="HorzFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="image_noframe">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="Image" />
+ <ColourRectProperty name="ImageColours" />
+ <VertFormatProperty name="VertFormatting" />
+ <HorzFormatProperty name="HorzFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled" />
+ <StateImagery name="Disabled" />
+ <StateImagery name="EnabledFrame">
+ <Layer>
+ <Section look="NavitGrey/StaticShared" section="frame" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DisabledFrame">
+ <Layer>
+ <Section look="NavitGrey/StaticShared" section="frame" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="WithFrameEnabledBackground">
+ <Layer>
+ <Section look="NavitGrey/StaticShared" section="background" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="WithFrameDisabledBackground">
+ <Layer>
+ <Section look="NavitGrey/StaticShared" section="background" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="NoFrameEnabledBackground">
+ <Layer>
+ <Section look="NavitGrey/StaticShared" section="background_noframe" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="NoFrameDisabledBackground">
+ <Layer>
+ <Section look="NavitGrey/StaticShared" section="background_noframe" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="WithFrameImage">
+ <Layer>
+ <Section section="image_withframe" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="NoFrameImage">
+ <Layer>
+ <Section section="image_noframe" />
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <WidgetLook name="NavitGrey/ViewModeSwitchButton">
+ <PropertyDefinition name="NormalImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="VertImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <PropertyDefinition name="HorzImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <ImagerySection name="normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width"><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height"><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="ViewModeSwitchButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightNormal" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleNormal" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="NormalImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="ViewModeSwitchButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightHighlight" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleHighlight" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="HoverImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="pushed">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="ViewModeSwitchButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightPushed" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddlePushed" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="PushedImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Pushed">
+ <Layer>
+ <Section section="pushed" />
+ <Section section="label">
+ <ColourProperty name="PushedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="PushedOff">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <WidgetLook name="NavitGrey/ZoomInButton">
+ <PropertyDefinition name="NormalImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="VertImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <PropertyDefinition name="HorzImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <ImagerySection name="normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width"><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height"><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="ZoomInButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightNormal" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleNormal" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="NormalImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="ZoomInButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightHighlight" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleHighlight" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="HoverImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="pushed">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="ZoomInButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightPushed" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddlePushed" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="PushedImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Pushed">
+ <Layer>
+ <Section section="pushed" />
+ <Section section="label">
+ <ColourProperty name="PushedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="PushedOff">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <WidgetLook name="NavitGrey/ZoomOutButton">
+ <PropertyDefinition name="NormalImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="VertImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <PropertyDefinition name="HorzImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <ImagerySection name="normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width"><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height"><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="ZoomOutButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightNormal" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleNormal" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="NormalImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="ZoomOutButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightHighlight" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleHighlight" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="HoverImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="pushed">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="ZoomOutButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightPushed" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddlePushed" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="PushedImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Pushed">
+ <Layer>
+ <Section section="pushed" />
+ <Section section="label">
+ <ColourProperty name="PushedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="PushedOff">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <WidgetLook name="NavitGrey/SpeakerOffButton">
+ <PropertyDefinition name="NormalImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="VertImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <PropertyDefinition name="HorzImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <ImagerySection name="normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width"><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height"><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="TaharezLook" image="SpeakerOffButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightNormal" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleNormal" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="NormalImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="SpeakerOffButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightHighlight" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleHighlight" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="HoverImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="pushed">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="LeftEdge" imageset="Mineque-Black" image="ViewModeSwitchButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightPushed" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddlePushed" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="PushedImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Pushed">
+ <Layer>
+ <Section section="pushed" />
+ <Section section="label">
+ <ColourProperty name="PushedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="PushedOff">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <WidgetLook name="NavitGrey/QuitButton">
+ <PropertyDefinition name="NormalTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledTextColour" initialValue="FF7F7F7F" redrawOnWrite="true" />
+ <PropertyDefinition name="VertLabelFormatting" initialValue="CentreAligned" />
+ <PropertyDefinition name="HorzLabelFormatting" initialValue="CentreAligned" />
+ <PropertyDefinition name="NormalImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="VertImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <PropertyDefinition name="HorzImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <ImagerySection name="label">
+ <TextComponent>
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width"><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height"><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <VertFormatProperty name="VertLabelFormatting" />
+ <HorzFormatProperty name="HorzLabelFormatting" />
+ </TextComponent>
+ </ImagerySection>
+ <ImagerySection name="normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width"><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height"><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="QuitButton" />
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="NormalImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="QuitButton" />
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="HoverImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="pushed">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+<!-- <Image type="LeftEdge" imageset="TaharezLook" image="ButtonLeftPushed" /> -->
+<!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightPushed" /> -->
+ <Image type="Background" imageset="Mineque-Black" image="QuitButton" />
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="PushedImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Pushed">
+ <Layer>
+ <Section section="pushed" />
+ <Section section="label">
+ <ColourProperty name="PushedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="PushedOff">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+
+ <WidgetLook name="NavitGrey/RouteButton">
+ <PropertyDefinition name="NormalImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="VertImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <PropertyDefinition name="HorzImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <ImagerySection name="normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width"><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height"><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="RouteButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightNormal" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleNormal" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="NormalImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="RouteButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightHighlight" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleHighlight" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="HoverImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="pushed">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="RouteButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightPushed" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddlePushed" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="PushedImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Pushed">
+ <Layer>
+ <Section section="pushed" />
+ <Section section="label">
+ <ColourProperty name="PushedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="PushedOff">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+
+ <WidgetLook name="NavitGrey/OptionsButton">
+ <PropertyDefinition name="NormalImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="VertImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <PropertyDefinition name="HorzImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <ImagerySection name="normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width"><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height"><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="OptionsButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightNormal" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleNormal" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="NormalImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="OptionsButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightHighlight" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleHighlight" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="HoverImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="pushed">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="OptionsButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightPushed" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddlePushed" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="PushedImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Pushed">
+ <Layer>
+ <Section section="pushed" />
+ <Section section="label">
+ <ColourProperty name="PushedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="PushedOff">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <WidgetLook name="NavitGrey/NavitAboutButton">
+ <PropertyDefinition name="NormalImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="VertImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <PropertyDefinition name="HorzImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <ImagerySection name="normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width"><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height"><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="NavitAboutButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightNormal" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleNormal" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="NormalImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="NavitAboutButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightHighlight" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleHighlight" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="HoverImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="pushed">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="NavitAboutButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightPushed" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddlePushed" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="PushedImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Pushed">
+ <Layer>
+ <Section section="pushed" />
+ <Section section="label">
+ <ColourProperty name="PushedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="PushedOff">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <WidgetLook name="NavitGrey/SpeakerButton">
+ <PropertyDefinition name="NormalImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="VertImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <PropertyDefinition name="HorzImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <ImagerySection name="normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width"><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height"><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="SpeakerOnButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightNormal" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleNormal" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="NormalImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="SpeakerOnButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightHighlight" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddleHighlight" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="HoverImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="pushed">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="Background" imageset="Mineque-Black" image="SpeakerOnButton" />
+ <!-- <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightPushed" /> -->
+ <!-- <Image type="Background" imageset="TaharezLook" image="ButtonMiddlePushed" /> -->
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="PushedImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Pushed">
+ <Layer>
+ <Section section="pushed" />
+ <Section section="label">
+ <ColourProperty name="PushedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="PushedOff">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!-- this widget needs cleanup -->
+ <WidgetLook name="NavitGrey/StaticText">
+ <PropertyDefinition name="FrameColours" initialValue="tl:FFFFFFFF tr:FFFFFFFF bl:FFFFFFFF br:FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="BackgroundColours" initialValue="tl:FFFFFFFF tr:FFFFFFFF bl:FFFFFFFF br:FFFFFFFF" redrawOnWrite="true" />
+ <Property name="FrameEnabled" value="True" />
+ <Property name="BackgroundEnabled" value="True" />
+ <NamedArea name="WithFrameTextRenderArea">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="StaticLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="StaticTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="StaticRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="StaticBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="WithFrameTextRenderAreaHScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="StaticLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="StaticTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="StaticRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="WithFrameTextRenderAreaVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="StaticLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="StaticTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="StaticBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="WithFrameTextRenderAreaHVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="StaticLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="StaticTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="NoFrameTextRenderArea">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1" type="BottomEdge" /></Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="NoFrameTextRenderAreaHScroll">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="NoFrameTextRenderAreaVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1" type="BottomEdge" /></Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="NoFrameTextRenderAreaHVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <Child type="TaharezLook/HorizontalScrollbar" nameSuffix="__auto_hscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" offset="-12" type="Width" /></Dim>
+ <Dim type="Height" ><AbsoluteDim value="12" /></Dim>
+ </Area>
+ <VertAlignment type="BottomAligned" />
+ </Child>
+ <Child type="TaharezLook/VerticalScrollbar" nameSuffix="__auto_vscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><AbsoluteDim value="12" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" offset="-12" type="Height" /></Dim>
+ </Area>
+ <HorzAlignment type="RightAligned" />
+ </Child>
+ <StateImagery name="Enabled" />
+ <StateImagery name="Disabled" />
+ <StateImagery name="EnabledFrame">
+ <Layer>
+ <Section look="NavitGrey/StaticShared" section="frame" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DisabledFrame">
+ <Layer>
+ <Section look="NavitGrey/StaticShared" section="frame" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="WithFrameEnabledBackground">
+ <Layer>
+ <Section look="NavitGrey/StaticShared" section="background" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="WithFrameDisabledBackground">
+ <Layer>
+ <Section look="TaharezLook/StaticShared" section="background" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="NoFrameEnabledBackground">
+ <Layer>
+ <Section look="TaharezLook/StaticShared" section="background_noframe" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="NoFrameDisabledBackground">
+ <Layer>
+ <Section look="TaharezLook/StaticShared" section="background_noframe" />
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+</Falagard>
+
diff --git a/navit/gui/sdl/datafiles/looknfeel/TaharezLook.looknfeel b/navit/gui/sdl/datafiles/looknfeel/TaharezLook.looknfeel
new file mode 100755
index 000000000..795aed437
--- /dev/null
+++ b/navit/gui/sdl/datafiles/looknfeel/TaharezLook.looknfeel
@@ -0,0 +1,4534 @@
+<?xml version="1.0" ?>
+<Falagard>
+ <!--
+ ***************************************************
+ TaharezLook/Button
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/Button">
+ <PropertyDefinition name="NormalTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledTextColour" initialValue="FF7F7F7F" redrawOnWrite="true" />
+ <PropertyDefinition name="VertLabelFormatting" initialValue="CentreAligned" />
+ <PropertyDefinition name="HorzLabelFormatting" initialValue="CentreAligned" />
+ <PropertyDefinition name="NormalImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="VertImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <PropertyDefinition name="HorzImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <ImagerySection name="label">
+ <TextComponent>
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width"><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height"><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <VertFormatProperty name="VertLabelFormatting" />
+ <HorzFormatProperty name="HorzLabelFormatting" />
+ </TextComponent>
+ </ImagerySection>
+ <ImagerySection name="normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width"><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height"><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="LeftEdge" imageset="TaharezLook" image="ButtonLeftNormal" />
+ <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightNormal" />
+ <Image type="Background" imageset="TaharezLook" image="ButtonMiddleNormal" />
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="NormalImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="LeftEdge" imageset="TaharezLook" image="ButtonLeftHighlight" />
+ <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightHighlight" />
+ <Image type="Background" imageset="TaharezLook" image="ButtonMiddleHighlight" />
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="HoverImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="pushed">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="LeftEdge" imageset="TaharezLook" image="ButtonLeftPushed" />
+ <Image type="RightEdge" imageset="TaharezLook" image="ButtonRightPushed" />
+ <Image type="Background" imageset="TaharezLook" image="ButtonMiddlePushed" />
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="PushedImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Pushed">
+ <Layer>
+ <Section section="pushed" />
+ <Section section="label">
+ <ColourProperty name="PushedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="PushedOff">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/RadioButton
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/RadioButton">
+ <PropertyDefinition name="NormalTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledTextColour" initialValue="FF7F7F7F" redrawOnWrite="true" />
+ <ImagerySection name="label">
+ <TextComponent>
+ <Area>
+ <Dim type="LeftEdge" >
+ <ImageDim imageset="TaharezLook" image="RadioButtonNormal" dimension="Width">
+ <DimOperator op="Add">
+ <AbsoluteDim value="3" />
+ </DimOperator>
+ </ImageDim>
+ </Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <VertFormat type="CentreAligned" />
+ <HorzFormat type="LeftAligned" />
+ </TextComponent>
+ </ImagerySection>
+ <ImagerySection name="normal">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="RadioButtonNormal" />
+ <VertFormat type="CentreAligned" />
+ <HorzFormat type="LeftAligned" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="RadioButtonHover" />
+ <VertFormat type="CentreAligned" />
+ <HorzFormat type="LeftAligned" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="select_mark">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="RadioButtonMark" />
+ <VertFormat type="CentreAligned" />
+ <HorzFormat type="LeftAligned" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="SelectedNormal">
+ <Layer>
+ <Section section="normal" />
+ <Section section="select_mark" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="SelectedHover">
+ <Layer>
+ <Section section="hover" />
+ <Section section="select_mark" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="SelectedDisabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="select_mark">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/Checkbox
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/Checkbox">
+ <PropertyDefinition name="NormalTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledTextColour" initialValue="FF7F7F7F" redrawOnWrite="true" />
+ <ImagerySection name="label">
+ <TextComponent>
+ <Area>
+ <Dim type="LeftEdge" >
+ <ImageDim imageset="TaharezLook" image="CheckboxNormal" dimension="Width">
+ <DimOperator op="Add">
+ <AbsoluteDim value="3" />
+ </DimOperator>
+ </ImageDim>
+ </Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <VertFormat type="CentreAligned" />
+ <HorzFormat type="LeftAligned" />
+ </TextComponent>
+ </ImagerySection>
+ <ImagerySection name="normal">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="CheckboxNormal" />
+ <VertFormat type="CentreAligned" />
+ <HorzFormat type="LeftAligned" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="CheckboxHover" />
+ <VertFormat type="CentreAligned" />
+ <HorzFormat type="LeftAligned" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="select_mark">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="CheckboxMark" />
+ <VertFormat type="CentreAligned" />
+ <HorzFormat type="LeftAligned" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="SelectedNormal">
+ <Layer>
+ <Section section="normal" />
+ <Section section="select_mark" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="SelectedHover">
+ <Layer>
+ <Section section="hover" />
+ <Section section="select_mark" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="SelectedDisabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="select_mark">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/Editbox
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/Editbox">
+ <PropertyDefinition name="NormalTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="SelectedTextColour" initialValue="FF000000" redrawOnWrite="true" />
+ <PropertyDefinition name="ActiveSelectionColour" initialValue="FF607FFF" redrawOnWrite="true" />
+ <PropertyDefinition name="InactiveSelectionColour" initialValue="FF808080" redrawOnWrite="true" />
+ <Property name="MouseCursorImage" value="set:TaharezLook image:MouseTextBar" />
+ <NamedArea name="TextArea">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="5" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="5" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1.0" offset="-5" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1.0" offset="-5" type="BottomEdge" /></Dim>
+ </Area>
+ </NamedArea>
+ <ImagerySection name="container_normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="LeftEdge" imageset="TaharezLook" image="EditBoxLeft" />
+ <Image type="RightEdge" imageset="TaharezLook" image="EditBoxRight" />
+ <Image type="Background" imageset="TaharezLook" image="EditBoxMiddle" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="selection">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1.0" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1.0" type="BottomEdge" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="TextSelectionBrush" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="Carat">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><ImageDim imageset="TaharezLook" image="EditBoxCarat" dimension="Width" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1.0" type="BottomEdge" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="EditBoxCarat" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="container_normal" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="ReadOnly">
+ <Layer>
+ <Section section="container_normal" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="container_normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="ActiveSelection">
+ <Layer>
+ <Section section="selection">
+ <ColourProperty name="ActiveSelectionColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="InactiveSelection">
+ <Layer>
+ <Section section="selection">
+ <ColourProperty name="InactiveSelectionColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/Titlebar
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/Titlebar">
+ <PropertyDefinition name="CaptionColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <ImagerySection name="main">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1.0" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1.0" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="NewTitlebarLeft" />
+ <VertFormat type="Stretched" />
+ </ImageryComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="SysAreaRight" dimension="Width">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="SysAreaMiddle" dimension="Width" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="Height" ><UnifiedDim scale="1.0" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="NewTitlebarRight" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="RightAligned" />
+ </ImageryComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="SysAreaRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="Height" ><UnifiedDim scale="1.0" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="SysAreaMiddle" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="RightAligned" />
+ </ImageryComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1.0" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1.0" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="SysAreaRight" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="RightAligned" />
+ </ImageryComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="NewTitlebarLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="SysAreaRight" dimension="Width">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="SysAreaMiddle" dimension="Width">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="NewTitlebarRight" dimension="Width" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="Height" ><UnifiedDim scale="1.0" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="NewTitlebarMiddle" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="caption">
+ <TextComponent>
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="NewTitlebarLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" offset="-75" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ColourProperty name="CaptionColour" />
+ <VertFormat type="CentreAligned" />
+ </TextComponent>
+ </ImagerySection>
+ <StateImagery name="Active">
+ <Layer>
+ <Section section="main" />
+ <Section section="caption" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Inactive">
+ <Layer>
+ <Section section="main" />
+ <Section section="caption" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="main">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="caption">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/FrameWindow
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/FrameWindow">
+ <PropertyLinkDefinition name="CaptionColour" widget="__auto_titlebar__" targetProperty="CaptionColour" initialValue="FFFFFFFF" />
+ <PropertyLinkDefinition name="TitlebarFont" widget="__auto_titlebar__" targetProperty="Font" />
+ <Property name="NSSizingCursorImage" value="set:TaharezLook image:MouseNoSoCursor" />
+ <Property name="EWSizingCursorImage" value="set:TaharezLook image:MouseEsWeCursor" />
+ <Property name="NWSESizingCursorImage" value="set:TaharezLook image:MouseNwSeCursor" />
+ <Property name="NESWSizingCursorImage" value="set:TaharezLook image:MouseNeSwCursor" />
+ <NamedArea name="ClientWithTitleWithFrame">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="WindowTopLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><WidgetDim widget="__auto_titlebar__" dimension="BottomEdge" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="WindowTopRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="WindowBottomEdge" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ClientWithTitleNoFrame">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><WidgetDim widget="__auto_titlebar__" dimension="BottomEdge" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="BottomEdge" ><WidgetDim dimension="BottomEdge" /></Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ClientNoTitleWithFrame">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="WindowTopLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="WindowTopEdge" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="WindowTopRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="WindowBottomEdge" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ClientNoTitleNoFrame">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ </NamedArea>
+ <Child type="TaharezLook/Titlebar" nameSuffix="__auto_titlebar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><FontDim type="LineSpacing" padding="8" /></Dim>
+ </Area>
+ <Property name="AlwaysOnTop" value="False" />
+ </Child>
+ <Child type="TaharezLook/SystemButton" nameSuffix="__auto_closebutton__">
+ <Area>
+ <Dim type="LeftEdge" >
+ <UnifiedDim scale="1" type="LeftEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="SysAreaRight" dimension="Width">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="SysAreaMiddle" dimension="Width" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="TopEdge" >
+ <AbsoluteDim value="0.5">
+ <DimOperator op="Multiply">
+ <WidgetDim widget="__auto_titlebar__" dimension="Height">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="NewCloseButtonNormal" dimension="Width" />
+ </DimOperator>
+ </WidgetDim>
+ </DimOperator>
+ </AbsoluteDim>
+ </Dim>
+ <Dim type="Width" ><ImageDim imageset="TaharezLook" image="NewCloseButtonNormal" dimension="Width" /></Dim>
+ <Dim type="Height" ><ImageDim imageset="TaharezLook" image="NewCloseButtonNormal" dimension="Width" /></Dim>
+ </Area>
+ <Property name="AlwaysOnTop" value="True" />
+ <Property name="NormalImage" value="set:TaharezLook image:NewCloseButtonNormal" />
+ <Property name="HoverImage" value="set:TaharezLook image:NewCloseButtonHover" />
+ <Property name="PushedImage" value="set:TaharezLook image:NewCloseButtonPressed" />
+ </Child>
+ <ImagerySection name="withtitle_frame">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><WidgetDim widget="__auto_titlebar__" dimension="BottomEdge" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1" type="BottomEdge" /></Dim>
+ </Area>
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="WindowBottomLeft" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="WindowBottomRight" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="WindowLeftEdge" />
+ <Image type="RightEdge" imageset="TaharezLook" image="WindowRightEdge" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="WindowBottomEdge" />
+ <Image type="Background" imageset="TaharezLook" image="ClientBrush" />
+ <VertFormat type="Tiled" />
+ <HorzFormat type="Tiled" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="notitle_frame">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="WindowTopLeft" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="WindowTopRight" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="WindowBottomLeft" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="WindowBottomRight" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="WindowLeftEdge" />
+ <Image type="RightEdge" imageset="TaharezLook" image="WindowRightEdge" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="WindowBottomEdge" />
+ <Image type="Background" imageset="TaharezLook" image="ClientBrush" />
+ <VertFormat type="Tiled" />
+ <HorzFormat type="Tiled" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="withtitle_noframe_client_area">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><WidgetDim widget="__auto_titlebar__" dimension="Height" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1" type="BottomEdge" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="ClientBrush" />
+ <VertFormat type="Tiled" />
+ <HorzFormat type="Tiled" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="notitle_noframe_client_area">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="ClientBrush" />
+ <VertFormat type="Tiled" />
+ <HorzFormat type="Tiled" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="ActiveWithTitleWithFrame">
+ <Layer>
+ <Section section="withtitle_frame" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="InactiveWithTitleWithFrame">
+ <Layer>
+ <Section section="withtitle_frame" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DisabledWithTitleWithFrame">
+ <Layer>
+ <Section section="withtitle_frame">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="ActiveWithTitleNoFrame">
+ <Layer>
+ <Section section="withtitle_noframe_client_area" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="InactiveWithTitleNoFrame">
+ <Layer>
+ <Section section="withtitle_noframe_client_area" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DisabledWithTitleNoFrame">
+ <Layer>
+ <Section section="withtitle_noframe_client_area">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="ActiveNoTitleWithFrame">
+ <Layer>
+ <Section section="notitle_frame" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="InactiveNoTitleWithFrame">
+ <Layer>
+ <Section section="notitle_frame" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DisabledNoTitleWithFrame">
+ <Layer>
+ <Section section="notitle_frame">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="ActiveNoTitleNoFrame">
+ <Layer>
+ <Section section="notitle_noframe_client_area" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="InactiveNoTitleNoFrame">
+ <Layer>
+ <Section section="notitle_noframe_client_area" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DisabledNoTitleNoFrame">
+ <Layer>
+ <Section section="notitle_noframe_client_area">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/ProgressBar
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/ProgressBar">
+ <NamedArea name="ProgressArea">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="ProgressBarLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="ProgressBarRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ </NamedArea>
+ <ImagerySection name="frame">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="LeftEdge" imageset="TaharezLook" image="ProgressBarLeft" />
+ <Image type="RightEdge" imageset="TaharezLook" image="ProgressBarRight" />
+ <Image type="Background" imageset="TaharezLook" image="ProgressBarMiddle" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="progress_lights" >
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="ProgressBarLitSegment" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Tiled" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="frame" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="frame">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="EnabledProgress">
+ <Layer>
+ <Section section="progress_lights" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DisabledProgress">
+ <Layer>
+ <Section section="progress_lights">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/AlternateProgressBar
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/AltProgressBar">
+ <NamedArea name="ProgressArea">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="AltProgressLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="2" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="AltProgressRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" offset="-4" type="Height" /></Dim>
+ </Area>
+ </NamedArea>
+ <ImagerySection name="frame">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="LeftEdge" imageset="TaharezLook" image="AltProgressLeft" />
+ <Image type="RightEdge" imageset="TaharezLook" image="AltProgressRight" />
+ <Image type="Background" imageset="TaharezLook" image="AltProgressMiddle" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="progress_lights" >
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="0.1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="AltProgressLight1" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Tiled" />
+ </ImageryComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0.1" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="0.1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="AltProgressLight2" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Tiled" />
+ </ImageryComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0.2" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="0.1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="AltProgressLight3" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Tiled" />
+ </ImageryComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0.3" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="0.1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="AltProgressLight4" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Tiled" />
+ </ImageryComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0.4" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="0.1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="AltProgressLight5" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Tiled" />
+ </ImageryComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0.5" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="0.1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="AltProgressLight6" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Tiled" />
+ </ImageryComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0.6" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="0.1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="AltProgressLight7" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Tiled" />
+ </ImageryComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0.7" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="0.1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="AltProgressLight8" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Tiled" />
+ </ImageryComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0.8" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="0.1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="AltProgressLight9" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Tiled" />
+ </ImageryComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0.9" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="0.1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="AltProgressLight10" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Tiled" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="frame" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="frame">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="EnabledProgress">
+ <Layer>
+ <Section section="progress_lights" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DisabledProgress">
+ <Layer>
+ <Section section="progress_lights">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/VUMeter (progress bar)
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/VUMeter">
+ <Property name="VerticalProgress" value="True" />
+ <NamedArea name="ProgressArea">
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" ><UnifiedDim scale="0" type="TopEdge" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ </NamedArea>
+ <ImagerySection name="progress_lights" >
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" ><UnifiedDim scale="0.5" type="TopEdge" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="0.5" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="TextSelectionBrush" />
+ <Colours topLeft="FF00FF00" topRight="FF00FF00" bottomLeft="FF00FF00" bottomRight="FF00FF00" />
+ <VertFormat type="Tiled" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" ><UnifiedDim scale="0.2" type="TopEdge" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="0.3" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="TextSelectionBrush" />
+ <Colours topLeft="FFFFFF00" topRight="FFFFFF00" bottomLeft="FFFFFF00" bottomRight="FFFFFF00" />
+ <VertFormat type="Tiled" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" ><UnifiedDim scale="0" type="TopEdge" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="0.2" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="TextSelectionBrush" />
+ <Colours topLeft="FFFF0000" topRight="FFFF0000" bottomLeft="FFFF0000" bottomRight="FFFF0000" />
+ <VertFormat type="Tiled" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ </StateImagery>
+ <StateImagery name="Disabled">
+ </StateImagery>
+ <StateImagery name="EnabledProgress">
+ <Layer>
+ <Section section="progress_lights" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DisabledProgress">
+ <Layer>
+ <Section section="progress_lights">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/SliderThumb
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/SliderThumb">
+ <Property name="VertFree" value="True" />
+ <ImagerySection name="normal">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1.0" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1.0" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="VertSliderThumbNormal" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1.0" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1.0" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="VertSliderThumbHover" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Pushed">
+ <Layer>
+ <Section section="hover" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/Slider
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/Slider">
+ <Property name="VerticalSlider" value="True" />
+ <Property name="MouseButtonDownAutoRepeat" value="True" />
+ <Property name="WantsMultiClickEvents" value="False" />
+ <NamedArea name="ThumbTrackArea">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1.0" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1.0" type="BottomEdge" /></Dim>
+ </Area>
+ </NamedArea>
+ <Child type="TaharezLook/SliderThumb" nameSuffix="__auto_thumb__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1.0" type="Width" /></Dim>
+ <Dim type="Height" ><ImageDim imageset="TaharezLook" image="VertSliderThumbNormal" dimension="Height" /></Dim>
+ </Area>
+ </Child>
+ <ImagerySection name="main">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="3" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1.0" offset="-6" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1.0" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="VertSliderBody" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="main" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="main">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/HorizontalScrollbarThumb
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/HorizontalScrollbarThumb">
+ <Property name="HorzFree" value="True" />
+ <ImagerySection name="normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1.0" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1.0" type="Height" /></Dim>
+ </Area>
+ <Image type="LeftEdge" imageset="TaharezLook" image="MiniHorzScrollThumbLeftNormal" />
+ <Image type="RightEdge" imageset="TaharezLook" image="MiniHorzScrollThumbRightNormal" />
+ <Image type="Background" imageset="TaharezLook" image="MiniHorzScrollThumbMiddleNormal" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1.0" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1.0" type="Height" /></Dim>
+ </Area>
+ <Image type="LeftEdge" imageset="TaharezLook" image="MiniHorzScrollThumbLeftHover" />
+ <Image type="RightEdge" imageset="TaharezLook" image="MiniHorzScrollThumbRightHover" />
+ <Image type="Background" imageset="TaharezLook" image="MiniHorzScrollThumbMiddleHover" />
+ </FrameComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Pushed">
+ <Layer>
+ <Section section="normal" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/HorizontalScrollbar
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/HorizontalScrollbar">
+ <NamedArea name="ThumbTrackArea">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="MiniHorzScrollLeftNormal" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1.0" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="MiniHorzScrollRightNormal" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1.0" type="BottomEdge" /></Dim>
+ </Area>
+ </NamedArea>
+ <Child type="TaharezLook/ImageButton" nameSuffix="__auto_incbtn__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><ImageDim imageset="TaharezLook" image="MiniHorzScrollRightNormal" dimension="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <HorzAlignment type="RightAligned" />
+ <Property name="NormalImage" value="set:TaharezLook image:MiniHorzScrollRightNormal" />
+ <Property name="HoverImage" value="set:TaharezLook image:MiniHorzScrollRightHover" />
+ <Property name="PushedImage" value="set:TaharezLook image:MiniHorzScrollRightNormal" />
+ </Child>
+ <Child type="TaharezLook/ImageButton" nameSuffix="__auto_decbtn__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><ImageDim imageset="TaharezLook" image="MiniHorzScrollLeftNormal" dimension="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Property name="NormalImage" value="set:TaharezLook image:MiniHorzScrollLeftNormal" />
+ <Property name="HoverImage" value="set:TaharezLook image:MiniHorzScrollLeftHover" />
+ <Property name="PushedImage" value="set:TaharezLook image:MiniHorzScrollLeftNormal" />
+ </Child>
+ <Child type="TaharezLook/HorizontalScrollbarThumb" nameSuffix="__auto_thumb__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="0.1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Property name="UnifiedMinSize" value="{{0,25},{0,0}}" />
+ </Child>
+ <ImagerySection name="main">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="MiniHorzScrollLeftNormal" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1.0" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="MiniHorzScrollRightNormal" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1.0" type="BottomEdge" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="MiniHorzScrollBarSegment" />
+ <VertFormat type="CentreAligned" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="main" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="main">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/VerticalScrollbarThumb
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/VerticalScrollbarThumb">
+ <Property name="VertFree" value="True" />
+ <ImagerySection name="normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1.0" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1.0" type="Height" /></Dim>
+ </Area>
+ <Image type="TopEdge" imageset="TaharezLook" image="MiniVertScrollThumbTopNormal" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="MiniVertScrollThumbBottomNormal" />
+ <Image type="Background" imageset="TaharezLook" image="MiniVertScrollThumbMiddleNormal" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1.0" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1.0" type="Height" /></Dim>
+ </Area>
+ <Image type="TopEdge" imageset="TaharezLook" image="MiniVertScrollThumbTopHover" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="MiniVertScrollThumbBottomHover" />
+ <Image type="Background" imageset="TaharezLook" image="MiniVertScrollThumbMiddleHover" />
+ </FrameComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Pushed">
+ <Layer>
+ <Section section="normal" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/VerticalScrollbar
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/VerticalScrollbar">
+ <Property name="VerticalScrollbar" value="True" />
+ <NamedArea name="ThumbTrackArea">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="MiniVertScrollUpNormal" dimension="Height" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1.0" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1.0" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="MiniVertScrollDownNormal" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <Child type="TaharezLook/ImageButton" nameSuffix="__auto_incbtn__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><ImageDim imageset="TaharezLook" image="MiniVertScrollDownNormal" dimension="Height" /></Dim>
+ </Area>
+ <VertAlignment type="BottomAligned" />
+ <Property name="NormalImage" value="set:TaharezLook image:MiniVertScrollDownNormal" />
+ <Property name="HoverImage" value="set:TaharezLook image:MiniVertScrollDownHover" />
+ <Property name="PushedImage" value="set:TaharezLook image:MiniVertScrollDownNormal" />
+ </Child>
+ <Child type="TaharezLook/ImageButton" nameSuffix="__auto_decbtn__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><ImageDim imageset="TaharezLook" image="MiniVertScrollUpNormal" dimension="Height" /></Dim>
+ </Area>
+ <Property name="NormalImage" value="set:TaharezLook image:MiniVertScrollUpNormal" />
+ <Property name="HoverImage" value="set:TaharezLook image:MiniVertScrollUpHover" />
+ <Property name="PushedImage" value="set:TaharezLook image:MiniVertScrollUpNormal" />
+ </Child>
+ <Child type="TaharezLook/VerticalScrollbarThumb" nameSuffix="__auto_thumb__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="0.1" type="Height" /></Dim>
+ </Area>
+ <Property name="UnifiedMinSize" value="{{0,0},{0,25}}" />
+ </Child>
+ <ImagerySection name="main">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="MiniVertScrollUpNormal" dimension="Height" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1.0" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1.0" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="MiniVertScrollDownNormal" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="MiniVertScrollBarSegment" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="CentreAligned" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="main" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="main">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/Listbox
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/Listbox">
+ <NamedArea name="ItemRenderingArea">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="ListboxLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="ListboxTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="ListboxRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="ListboxBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ItemRenderingAreaHScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="ListboxLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="ListboxTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="ListboxRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ItemRenderingAreaVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="ListboxLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="ListboxTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="ListboxBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ItemRenderingAreaHVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="ListboxLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="ListboxTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <Child type="TaharezLook/HorizontalScrollbar" nameSuffix="__auto_hscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" offset="-12" type="Width" /></Dim>
+ <Dim type="Height" ><AbsoluteDim value="12" /></Dim>
+ </Area>
+ <VertAlignment type="BottomAligned" />
+ </Child>
+ <Child type="TaharezLook/VerticalScrollbar" nameSuffix="__auto_vscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><AbsoluteDim value="12" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" offset="-12" type="Height" /></Dim>
+ </Area>
+ <HorzAlignment type="RightAligned" />
+ </Child>
+ <ImagerySection name="main">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="ListboxTopLeft" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="ListboxTopRight" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="ListboxBottomLeft" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="ListboxBottomRight" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="ListboxLeft" />
+ <Image type="RightEdge" imageset="TaharezLook" image="ListboxRight" />
+ <Image type="TopEdge" imageset="TaharezLook" image="ListboxTop" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="ListboxBottom" />
+ <Image type="Background" imageset="TaharezLook" image="ListboxBackdrop" />
+ </FrameComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="main" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="main">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/ComboDropList
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/ComboDropList">
+ <NamedArea name="ItemRenderingArea">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="ComboboxListLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="ComboboxListTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="ComboboxListRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="ComboboxListBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ItemRenderingAreaHScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="ComboboxListLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="ComboboxListTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="ComboboxListRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ItemRenderingAreaVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="ComboboxListLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="ComboboxListTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="ComboboxListBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ItemRenderingAreaHVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="ComboboxListLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="ComboboxListTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <Child type="TaharezLook/HorizontalScrollbar" nameSuffix="__auto_hscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" offset="-12" type="Width" /></Dim>
+ <Dim type="Height" ><AbsoluteDim value="12" /></Dim>
+ </Area>
+ <VertAlignment type="BottomAligned" />
+ </Child>
+ <Child type="TaharezLook/VerticalScrollbar" nameSuffix="__auto_vscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><AbsoluteDim value="12" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" offset="-12" type="Height" /></Dim>
+ </Area>
+ <HorzAlignment type="RightAligned" />
+ </Child>
+ <ImagerySection name="main">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="ComboboxListTopLeft" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="ComboboxListTopRight" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="ComboboxListBottomLeft" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="ComboboxListBottomRight" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="ComboboxListLeft" />
+ <Image type="RightEdge" imageset="TaharezLook" image="ComboboxListRight" />
+ <Image type="TopEdge" imageset="TaharezLook" image="ComboboxListTop" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="ComboboxListBottom" />
+ <Image type="Background" imageset="TaharezLook" image="ComboboxListBackdrop" />
+ </FrameComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="main" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="main">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/ComboEditbox
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/ComboEditbox">
+ <PropertyDefinition name="NormalTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="SelectedTextColour" initialValue="FF000000" redrawOnWrite="true" />
+ <PropertyDefinition name="ActiveSelectionColour" initialValue="FF607FFF" redrawOnWrite="true" />
+ <PropertyDefinition name="InactiveSelectionColour" initialValue="FF808080" redrawOnWrite="true" />
+ <Property name="MouseCursorImage" value="set:TaharezLook image:MouseTextBar" />
+ <NamedArea name="TextArea">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="5" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="5" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1.0" offset="-5" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1.0" offset="-5" type="BottomEdge" /></Dim>
+ </Area>
+ </NamedArea>
+ <ImagerySection name="container_normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1.0" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1.0" type="Height" /></Dim>
+ </Area>
+ <Image type="LeftEdge" imageset="TaharezLook" image="ComboboxEditLeft" />
+ <Image type="Background" imageset="TaharezLook" image="ComboboxEditMiddle" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="selection">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1.0" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1.0" type="BottomEdge" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="TextSelectionBrush" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="Carat">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><ImageDim imageset="TaharezLook" image="EditBoxCarat" dimension="Width" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1.0" type="BottomEdge" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="EditBoxCarat" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="container_normal" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="ReadOnly">
+ <Layer>
+ <Section section="container_normal" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="container_normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="ActiveSelection">
+ <Layer>
+ <Section section="selection">
+ <ColourProperty name="ActiveSelectionColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="InactiveSelection">
+ <Layer>
+ <Section section="selection">
+ <ColourProperty name="InactiveSelectionColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/Combobox
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/Combobox">
+ <PropertyLinkDefinition name="NormalEditTextColour" widget="__auto_editbox__" targetProperty="NormalTextColour" initialValue="FFFFFFFF" />
+ <PropertyLinkDefinition name="SelectedEditTextColour" widget="__auto_editbox__" targetProperty="SelectedTextColour" initialValue="FF000000" />
+ <PropertyLinkDefinition name="ActiveEditSelectionColour" widget="__auto_editbox__" targetProperty="ActiveSelectionColour" initialValue="FF6060FF" />
+ <PropertyLinkDefinition name="InactiveEditSelectionColour" widget="__auto_editbox__" targetProperty="InactiveSelectionColour" initialValue="FF808080" />
+ <Child type="TaharezLook/ComboEditbox" nameSuffix="__auto_editbox__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <FontDim type="LineSpacing">
+ <DimOperator op="Multiply">
+ <AbsoluteDim value="1.5" />
+ </DimOperator>
+ </FontDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="Height" >
+ <FontDim type="LineSpacing">
+ <DimOperator op="Multiply">
+ <AbsoluteDim value="1.5" />
+ </DimOperator>
+ </FontDim>
+ </Dim>
+ </Area>
+ </Child>
+ <Child type="TaharezLook/ComboDropList" nameSuffix="__auto_droplist__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><WidgetDim widget="__auto_editbox__" dimension="BottomEdge" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1" type="BottomEdge" /></Dim>
+ </Area>
+ </Child>
+ <Child type="TaharezLook/ImageButton" nameSuffix="__auto_button__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><WidgetDim widget="__auto_editbox__" dimension="Height" /></Dim>
+ <Dim type="Height" ><WidgetDim widget="__auto_editbox__" dimension="Height" /></Dim>
+ </Area>
+ <HorzAlignment type="RightAligned" />
+ <Property name="NormalImage" value="set:TaharezLook image:ComboboxListButtonNormal" />
+ <Property name="HoverImage" value="set:TaharezLook image:ComboboxListButtonHover" />
+ <Property name="PushedImage" value="set:TaharezLook image:ComboboxListButtonNormal" />
+ </Child>
+ <StateImagery name="Enabled" />
+ <StateImagery name="Disabled" />
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/Spinner
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/Spinner">
+ <Child type="TaharezLook/Editbox" nameSuffix="__auto_editbox__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="VertScrollUpNormal" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ </Child>
+ <Child type="TaharezLook/ImageButton" nameSuffix="__auto_incbtn__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><ImageDim imageset="TaharezLook" image="VertScrollUpNormal" dimension="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="0.5" type="Height" /></Dim>
+ </Area>
+ <HorzAlignment type="RightAligned" />
+ <Property name="NormalImage" value="set:TaharezLook image:VertScrollUpNormal" />
+ <Property name="HoverImage" value="set:TaharezLook image:VertScrollUpHover" />
+ <Property name="PushedImage" value="set:TaharezLook image:VertScrollUpNormal" />
+ </Child>
+ <Child type="TaharezLook/ImageButton" nameSuffix="__auto_decbtn__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><UnifiedDim scale="0.5" type="TopEdge" /></Dim>
+ <Dim type="Width" ><ImageDim imageset="TaharezLook" image="VertScrollUpNormal" dimension="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="0.5" type="Height" /></Dim>
+ </Area>
+ <HorzAlignment type="RightAligned" />
+ <Property name="NormalImage" value="set:TaharezLook image:VertScrollDownNormal" />
+ <Property name="HoverImage" value="set:TaharezLook image:VertScrollDownHover" />
+ <Property name="PushedImage" value="set:TaharezLook image:VertScrollDownNormal" />
+ </Child>
+ <StateImagery name="Enabled" />
+ <StateImagery name="Disabled" />
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/StaticShared
+ (Shared imagery components for static widgets)
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/StaticShared">
+ <ImagerySection name="frame">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="StaticTopLeft" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="StaticTopRight" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="StaticBottomLeft" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="StaticBottomRight" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="StaticLeft" />
+ <Image type="RightEdge" imageset="TaharezLook" image="StaticRight" />
+ <Image type="TopEdge" imageset="TaharezLook" image="StaticTop" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="StaticBottom" />
+ <ColourRectProperty name="FrameColours" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="background">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="StaticLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="StaticTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="StaticRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="StaticBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="StaticBackdrop" />
+ <!--<ColourRectProperty name="BackgroundColours" />-->
+ <Colours topLeft="FFFFFFFF" topRight="FFFFFFFF" bottomLeft="FFFFFFFF" bottomRight="FFFFFFFF" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="background_noframe">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge"><UnifiedDim scale="1" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge"><UnifiedDim scale="1" type="BottomEdge" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="StaticBackdrop" />
+ <!--<ColourRectProperty name="BackgroundColours" />-->
+ <Colours topLeft="FFFFFFFF" topRight="FFFFFFFF" bottomLeft="FFFFFFFF" bottomRight="FFFFFFFF" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/StaticImage
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/StaticImage">
+ <PropertyDefinition name="ImageColours" initialValue="tl:FFFFFFFF tr:FFFFFFFF bl:FFFFFFFF br:FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="FrameColours" initialValue="tl:FFFFFFFF tr:FFFFFFFF bl:FFFFFFFF br:FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="BackgroundColours" initialValue="tl:FFFFFFFF tr:FFFFFFFF bl:FFFFFFFF br:FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="VertFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <PropertyDefinition name="HorzFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <Property name="BackgroundEnabled" value="True" />
+ <Property name="FrameEnabled" value="True" />
+ <ImagerySection name="image_withframe">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="StaticLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="StaticTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="StaticRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="StaticBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ <ImageProperty name="Image" />
+ <ColourRectProperty name="ImageColours" />
+ <VertFormatProperty name="VertFormatting" />
+ <HorzFormatProperty name="HorzFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="image_noframe">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="Image" />
+ <ColourRectProperty name="ImageColours" />
+ <VertFormatProperty name="VertFormatting" />
+ <HorzFormatProperty name="HorzFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled" />
+ <StateImagery name="Disabled" />
+ <StateImagery name="EnabledFrame">
+ <Layer>
+ <Section look="TaharezLook/StaticShared" section="frame" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DisabledFrame">
+ <Layer>
+ <Section look="TaharezLook/StaticShared" section="frame" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="WithFrameEnabledBackground">
+ <Layer>
+ <Section look="TaharezLook/StaticShared" section="background" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="WithFrameDisabledBackground">
+ <Layer>
+ <Section look="TaharezLook/StaticShared" section="background" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="NoFrameEnabledBackground">
+ <Layer>
+ <Section look="TaharezLook/StaticShared" section="background_noframe" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="NoFrameDisabledBackground">
+ <Layer>
+ <Section look="TaharezLook/StaticShared" section="background_noframe" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="WithFrameImage">
+ <Layer>
+ <Section section="image_withframe" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="NoFrameImage">
+ <Layer>
+ <Section section="image_noframe" />
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/StaticText
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/StaticText">
+ <PropertyDefinition name="FrameColours" initialValue="tl:FFFFFFFF tr:FFFFFFFF bl:FFFFFFFF br:FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="BackgroundColours" initialValue="tl:FFFFFFFF tr:FFFFFFFF bl:FFFFFFFF br:FFFFFFFF" redrawOnWrite="true" />
+ <Property name="FrameEnabled" value="True" />
+ <Property name="BackgroundEnabled" value="True" />
+ <NamedArea name="WithFrameTextRenderArea">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="StaticLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="StaticTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="StaticRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="StaticBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="WithFrameTextRenderAreaHScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="StaticLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="StaticTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="StaticRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="WithFrameTextRenderAreaVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="StaticLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="StaticTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="StaticBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="WithFrameTextRenderAreaHVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="StaticLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="StaticTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="NoFrameTextRenderArea">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1" type="BottomEdge" /></Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="NoFrameTextRenderAreaHScroll">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="NoFrameTextRenderAreaVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1" type="BottomEdge" /></Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="NoFrameTextRenderAreaHVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <Child type="TaharezLook/HorizontalScrollbar" nameSuffix="__auto_hscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" offset="-12" type="Width" /></Dim>
+ <Dim type="Height" ><AbsoluteDim value="12" /></Dim>
+ </Area>
+ <VertAlignment type="BottomAligned" />
+ </Child>
+ <Child type="TaharezLook/VerticalScrollbar" nameSuffix="__auto_vscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><AbsoluteDim value="12" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" offset="-12" type="Height" /></Dim>
+ </Area>
+ <HorzAlignment type="RightAligned" />
+ </Child>
+ <StateImagery name="Enabled" />
+ <StateImagery name="Disabled" />
+ <StateImagery name="EnabledFrame">
+ <Layer>
+ <Section look="TaharezLook/StaticShared" section="frame" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DisabledFrame">
+ <Layer>
+ <Section look="TaharezLook/StaticShared" section="frame" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="WithFrameEnabledBackground">
+ <Layer>
+ <Section look="TaharezLook/StaticShared" section="background" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="WithFrameDisabledBackground">
+ <Layer>
+ <Section look="TaharezLook/StaticShared" section="background" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="NoFrameEnabledBackground">
+ <Layer>
+ <Section look="TaharezLook/StaticShared" section="background_noframe" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="NoFrameDisabledBackground">
+ <Layer>
+ <Section look="TaharezLook/StaticShared" section="background_noframe" />
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/ListHeaderSegment
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/ListHeaderSegment">
+ <Property name="SizingCursorImage" value="set:TaharezLook image:MouseEsWeCursor" />
+ <Property name="MovingCursorImage" value="set:TaharezLook image:MouseMoveCursor" />
+ <ImagerySection name="segment_normal">
+ <Colours topLeft="FFDDDDDD" topRight="FFDDDDDD" bottomLeft="FFDDDDDD" bottomRight="FFDDDDDD" />
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="HeaderBarSplitterNormal" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="HeaderBarBackdropNormal" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="segment_hover">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="HeaderBarSplitterNormal" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="HeaderBarBackdropHover" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="splitter_normal">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="HeaderBarSplitterNormal" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="RightAligned" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="splitter_hover">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="HeaderBarSplitterHover" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="RightAligned" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="ascend_icon">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="3" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="3" /></Dim>
+ <Dim type="Width" ><ImageDim imageset="TaharezLook" image="HeaderBarSortUp" dimension="Width" /></Dim>
+ <Dim type="Height" ><ImageDim imageset="TaharezLook" image="HeaderBarSortUp" dimension="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="HeaderBarSortUp" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="descend_icon">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="3" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="3" /></Dim>
+ <Dim type="Width" ><ImageDim imageset="TaharezLook" image="HeaderBarSortDown" dimension="Width" /></Dim>
+ <Dim type="Height" ><ImageDim imageset="TaharezLook" image="HeaderBarSortDown" dimension="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="HeaderBarSortDown" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="label">
+ <TextComponent>
+ <Area>
+ <Dim type="LeftEdge" >
+ <ImageDim imageset="TaharezLook" image="HeaderBarSortUp" dimension="Width">
+ <DimOperator op="Add">
+ <AbsoluteDim value="5" />
+ </DimOperator>
+ </ImageDim>
+ </Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1" type="RightEdge" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <VertFormat type="CentreAligned" />
+ </TextComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="segment_normal" />
+ <Section section="splitter_normal" />
+ <Section section="label" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="segment_hover" />
+ <Section section="splitter_normal" />
+ <Section section="label" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="SplitterHover">
+ <Layer>
+ <Section section="segment_normal" />
+ <Section section="splitter_hover" />
+ <Section section="label" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DragGhost" clipped="false" >
+ <Layer priority="1" >
+ <Section section="segment_normal">
+ <Colours topLeft="90FFFFFF" topRight="90FFFFFF" bottomLeft="90FFFFFF" bottomRight="90FFFFFF" />
+ </Section>
+ <Section section="splitter_normal">
+ <Colours topLeft="90FFFFFF" topRight="90FFFFFF" bottomLeft="90FFFFFF" bottomRight="90FFFFFF" />
+ </Section>
+ <Section section="label">
+ <Colours topLeft="90FFFFFF" topRight="90FFFFFF" bottomLeft="90FFFFFF" bottomRight="90FFFFFF" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="AscendingSortIcon">
+ <Layer>
+ <Section section="ascend_icon" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DescendingSortIcon">
+ <Layer>
+ <Section section="descend_icon" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="GhostAscendingSortIcon" clipped="false">
+ <Layer priority="1" >
+ <Section section="ascend_icon">
+ <Colours topLeft="90FFFFFF" topRight="90FFFFFF" bottomLeft="90FFFFFF" bottomRight="90FFFFFF" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="GhostDescendingSortIcon" clipped="false">
+ <Layer priority="1" >
+ <Section section="descend_icon">
+ <Colours topLeft="90FFFFFF" topRight="90FFFFFF" bottomLeft="90FFFFFF" bottomRight="90FFFFFF" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="segment_normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="splitter_normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/ListHeader
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/ListHeader">
+ <Property name="SegmentWidgetType" value="TaharezLook/ListHeaderSegment" />
+ <StateImagery name="Enabled" />
+ <StateImagery name="Disabled" />
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/MultiColumnList
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/MultiColumnList">
+ <NamedArea name="ItemRenderingArea">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="MultiListLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><WidgetDim widget="__auto_listheader__" dimension="BottomEdge" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="MultiListRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="MultiListBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ItemRenderingAreaHScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="MultiListLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><WidgetDim widget="__auto_listheader__" dimension="BottomEdge" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="MultiListRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ItemRenderingAreaVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="MultiListLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><WidgetDim widget="__auto_listheader__" dimension="BottomEdge" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="MultiListBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ItemRenderingAreaHVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="MultiListLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><WidgetDim widget="__auto_listheader__" dimension="BottomEdge" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <Child type="TaharezLook/ListHeader" nameSuffix="__auto_listheader__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="2" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="2" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1" offset="-2" type="RightEdge" /></Dim>
+ <Dim type="Height" >
+ <FontDim type="LineSpacing">
+ <DimOperator op="Multiply">
+ <AbsoluteDim value="1.5" />
+ </DimOperator>
+ </FontDim>
+ </Dim>
+ </Area>
+ </Child>
+ <Child type="TaharezLook/HorizontalScrollbar" nameSuffix="__auto_hscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" offset="-12" type="Width" /></Dim>
+ <Dim type="Height" ><AbsoluteDim value="12" /></Dim>
+ </Area>
+ <VertAlignment type="BottomAligned" />
+ </Child>
+ <Child type="TaharezLook/VerticalScrollbar" nameSuffix="__auto_vscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><WidgetDim widget="__auto_listheader__" dimension="BottomEdge" /></Dim>
+ <Dim type="Width" ><AbsoluteDim value="12" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1" offset="-12" type="BottomEdge" /></Dim>
+ </Area>
+ <HorzAlignment type="RightAligned" />
+ </Child>
+ <ImagerySection name="main">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="MultiListTopLeft" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="MultiListTopRight" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="MultiListBottomLeft" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="MultiListBottomRight" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="MultiListLeft" />
+ <Image type="RightEdge" imageset="TaharezLook" image="MultiListRight" />
+ <Image type="TopEdge" imageset="TaharezLook" image="MultiListTop" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="MultiListBottom" />
+ <Image type="Background" imageset="TaharezLook" image="MultiListBackdrop" />
+ </FrameComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="main" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="main">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/MultiLineEditbox
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/MultiLineEditbox">
+ <PropertyDefinition name="NormalTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="SelectedTextColour" initialValue="FF000000" redrawOnWrite="true" />
+ <PropertyDefinition name="ActiveSelectionColour" initialValue="FF607FFF" redrawOnWrite="true" />
+ <PropertyDefinition name="InactiveSelectionColour" initialValue="FF808080" redrawOnWrite="true" />
+ <Property name="MouseCursorImage" value="set:TaharezLook image:MouseTextBar" />
+ <Property name="SelectionBrushImage" value="set:TaharezLook image:MultiLineEditboxSelectionBrush" />
+ <NamedArea name="TextArea">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="MultiLineEditboxLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="MultiLineEditboxTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="MultiLineEditboxRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="MultiLineEditboxBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="TextAreaHScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="MultiLineEditboxLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="MultiLineEditboxTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="MultiLineEditboxRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="TextAreaVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="MultiLineEditboxLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="MultiLineEditboxTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="MultiLineEditboxBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="TextAreaHVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="MultiLineEditboxLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="MultiLineEditboxTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <Child type="TaharezLook/HorizontalScrollbar" nameSuffix="__auto_hscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" offset="-12" type="Width" /></Dim>
+ <Dim type="Height" ><AbsoluteDim value="12" /></Dim>
+ </Area>
+ <VertAlignment type="BottomAligned" />
+ </Child>
+ <Child type="TaharezLook/VerticalScrollbar" nameSuffix="__auto_vscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><AbsoluteDim value="12" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" offset="-12" type="Height" /></Dim>
+ </Area>
+ <HorzAlignment type="RightAligned" />
+ </Child>
+ <ImagerySection name="main">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="MultiLineEditboxTopLeft" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="MultiLineEditboxTopRight" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="MultiLineEditboxBottomLeft" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="MultiLineEditboxBottomRight" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="MultiLineEditboxLeft" />
+ <Image type="RightEdge" imageset="TaharezLook" image="MultiLineEditboxRight" />
+ <Image type="TopEdge" imageset="TaharezLook" image="MultiLineEditboxTop" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="MultiLineEditboxBottom" />
+ <Image type="Background" imageset="TaharezLook" image="MultiLineEditboxBackdrop" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="Carat">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><ImageDim imageset="TaharezLook" image="EditBoxCarat" dimension="Width" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1.0" type="BottomEdge" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="EditBoxCarat" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="main" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="ReadOnly">
+ <Layer>
+ <Section section="main" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="main">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/Tooltip
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/Tooltip">
+ <NamedArea name="TextArea">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="TooltipLeftEdge" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="TooltipTopEdge" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="TooltipRightEdge" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="TooltipBottomEdge" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <ImagerySection name="main">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="TooltipTopLeft" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="TooltipTopRight" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="TooltipBottomLeft" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="TooltipBottomRight" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="TooltipLeftEdge" />
+ <Image type="RightEdge" imageset="TaharezLook" image="TooltipRightEdge" />
+ <Image type="TopEdge" imageset="TaharezLook" image="TooltipTopEdge" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="TooltipBottomEdge" />
+ <Image type="Background" imageset="TaharezLook" image="TooltipMiddle" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="label">
+ <TextComponent>
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="TooltipLeftEdge" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="TooltipTopEdge" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="TooltipRightEdge" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="TooltipBottomEdge" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ <Colours topLeft="FF000000" topRight="FF000000" bottomLeft="FF000000" bottomRight="FF000000" />
+ <VertFormat type="CentreAligned" />
+ <HorzFormat type="CentreAligned" />
+ </TextComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="main" />
+ <Section section="label" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="main" />
+ <Section section="label" />
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/ScrollablePane
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/ScrollablePane">
+ <NamedArea name="ViewableArea">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1.0" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1.0" type="BottomEdge" /></Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ViewableAreaHScroll">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1.0" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ViewableAreaVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1.0" type="BottomEdge" /></Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ViewableAreaHVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_vscrollbar__" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_hscrollbar__" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <Child type="TaharezLook/HorizontalScrollbar" nameSuffix="__auto_hscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" offset="-12" type="Width" /></Dim>
+ <Dim type="Height" ><AbsoluteDim value="12" /></Dim>
+ </Area>
+ <VertAlignment type="BottomAligned" />
+ </Child>
+ <Child type="TaharezLook/VerticalScrollbar" nameSuffix="__auto_vscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><AbsoluteDim value="12" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" offset="-12" type="Height" /></Dim>
+ </Area>
+ <HorzAlignment type="RightAligned" />
+ </Child>
+ <StateImagery name="Enabled" />
+ <StateImagery name="Disabled" />
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/TabButton
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/TabButton">
+ <PropertyDefinition name="NormalTextColour" initialValue="FFC0C0C0" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverTextColour" initialValue="FFE0E0E0" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="SelectedTextColour" initialValue="FFE0E0E0" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledTextColour" initialValue="FF7F7F7F" redrawOnWrite="true" />
+ <ImagerySection name="label">
+ <TextComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <VertFormat type="CentreAligned" />
+ <HorzFormat type="CentreAligned" />
+ </TextComponent>
+ </ImagerySection>
+ <ImagerySection name="top_normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="TabButtonUpperLeftNormal" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="TabButtonUpperRightNormal" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="TabButtonLowerLeftNormal" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="TabButtonLowerRight2Normal" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="TabButtonLeftNormal" />
+ <Image type="RightEdge" imageset="TaharezLook" image="TabButtonRightNormal" />
+ <Image type="TopEdge" imageset="TaharezLook" image="TabButtonUpperNormal" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="TabButtonLowerNormal" />
+ <Image type="Background" imageset="TaharezLook" image="TabButtonMiddleNormal" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="bot_normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="TabButtonUpperLeft2Normal" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="TabButtonUpperRightNormal" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="TabButtonLowerLeftNormal" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="TabButtonLowerRightNormal" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="TabButtonLeftNormal" />
+ <Image type="RightEdge" imageset="TaharezLook" image="TabButtonRightNormal" />
+ <Image type="TopEdge" imageset="TaharezLook" image="TabButtonUpperNormal" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="TabButtonLowerNormal" />
+ <Image type="Background" imageset="TaharezLook" image="TabButtonMiddleNormal" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="top_hover">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="TabButtonUpperLeftNormal" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="TabButtonUpperRightNormal" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="TabButtonLowerLeftNormal" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="TabButtonLowerRight2Normal" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="TabButtonLeftNormal" />
+ <Image type="RightEdge" imageset="TaharezLook" image="TabButtonRightNormal" />
+ <Image type="TopEdge" imageset="TaharezLook" image="TabButtonUpperNormal" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="TabButtonLowerNormal" />
+ <Image type="Background" imageset="TaharezLook" image="TabButtonMiddleNormal" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="bot_hover">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="TabButtonUpperLeft2Normal" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="TabButtonUpperRightNormal" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="TabButtonLowerLeftNormal" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="TabButtonLowerRightNormal" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="TabButtonLeftNormal" />
+ <Image type="RightEdge" imageset="TaharezLook" image="TabButtonRightNormal" />
+ <Image type="TopEdge" imageset="TaharezLook" image="TabButtonUpperNormal" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="TabButtonLowerNormal" />
+ <Image type="Background" imageset="TaharezLook" image="TabButtonMiddleNormal" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="top_selected">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="TabButtonUpperLeftSelected" />
+ <Image type="TopEdge" imageset="TaharezLook" image="TabButtonUpperSelected" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="TabButtonUpperRightSelected" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="TabButtonLeftSelected" />
+ <Image type="Background" imageset="TaharezLook" image="TabButtonMiddleSelected" />
+ <Image type="RightEdge" imageset="TaharezLook" image="TabButtonRightSelected" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="bot_selected">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="LeftEdge" imageset="TaharezLook" image="TabButtonLeftSelected" />
+ <Image type="Background" imageset="TaharezLook" image="TabButtonMiddleSelected" />
+ <Image type="RightEdge" imageset="TaharezLook" image="TabButtonRightSelected" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="TabButtonLowerLeftNormal" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="TabButtonLowerNormal" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="TabButtonLowerRightNormal" />
+ </FrameComponent>
+ </ImagerySection>
+ <StateImagery name="TopNormal">
+ <Layer>
+ <Section section="top_normal" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="BottomNormal">
+ <Layer>
+ <Section section="bot_normal" />
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="TopHover">
+ <Layer>
+ <Section section="top_hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="BottomHover">
+ <Layer>
+ <Section section="bot_hover" />
+ <Section section="label">
+ <ColourProperty name="HoverTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="TopSelected">
+ <Layer>
+ <Section section="top_selected" />
+ <Section section="label">
+ <ColourProperty name="SelectedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="BottomSelected">
+ <Layer>
+ <Section section="bot_selected" />
+ <Section section="label">
+ <ColourProperty name="SelectedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="TopPushed">
+ <Layer>
+ <Section section="top_normal" />
+ <Section section="label">
+ <ColourProperty name="PushedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="BottomPushed">
+ <Layer>
+ <Section section="bot_normal" />
+ <Section section="label">
+ <ColourProperty name="PushedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="TopDisabled">
+ <Layer>
+ <Section section="top_normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="BottomDisabled">
+ <Layer>
+ <Section section="bot_normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/TabContentPane
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/TabContentPane">
+ <PropertyDefinition name="EnableTop" initialValue="0" redrawOnWrite="true" layoutOnWrite="true" />
+ <PropertyDefinition name="EnableBottom" initialValue="0" redrawOnWrite="true" layoutOnWrite="true" />
+ <ImagerySection name="normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="BottomEdge" >
+ <ImageDim imageset="TaharezLook" image="TabContentPaneUpperLeft" dimension="Height">
+ <DimOperator op="Multiply">
+ <PropertyDim name="EnableTop" />
+ </DimOperator>
+ </ImageDim>
+ </Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="TabContentPaneUpperLeft" />
+ <Image type="TopEdge" imageset="TaharezLook" image="TabContentPaneUpper" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="TabContentPaneUpperRight" />
+ </FrameComponent>
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" >
+ <ImageDim imageset="TaharezLook" image="TabContentPaneUpperLeft" dimension="Height">
+ <DimOperator op="Multiply">
+ <PropertyDim name="EnableTop" />
+ </DimOperator>
+ </ImageDim>
+ </Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="Height">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="TabContentPaneLowerLeft" dimension="Height">
+ <DimOperator op="Multiply">
+ <PropertyDim name="EnableBottom" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ <Image type="LeftEdge" imageset="TaharezLook" image="TabContentPaneLeft" />
+ <Image type="Background" imageset="TaharezLook" image="TabContentPaneMiddle" />
+ <Image type="RightEdge" imageset="TaharezLook" image="TabContentPaneRight" />
+ </FrameComponent>
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" >
+ <UnifiedDim scale="1" type="Height">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="TabContentPaneLowerLeft" dimension="Height">
+ <DimOperator op="Multiply">
+ <PropertyDim name="EnableBottom" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="TabContentPaneLowerLeft" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="TabContentPaneLower" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="TabContentPaneLowerRight" />
+ </FrameComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="normal" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/TabButtonPane
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/TabButtonPane">
+ <PropertyDefinition name="EnableTop" initialValue="1" redrawOnWrite="true" layoutOnWrite="true" />
+ <PropertyDefinition name="EnableBottom" initialValue="1" redrawOnWrite="true" layoutOnWrite="true" />
+ <ImagerySection name="normal">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="BottomEdge" >
+ <ImageDim imageset="TaharezLook" image="TabHorizontalFiller" dimension="Height">
+ <DimOperator op="Multiply">
+ <PropertyDim name="EnableTop" />
+ </DimOperator>
+ </ImageDim>
+ </Dim>
+ </Area>
+ <Image type="TopEdge" imageset="TaharezLook" image="TabHorizontalFiller" />
+ </FrameComponent>
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" >
+ <ImageDim imageset="TaharezLook" image="TabHorizontalFiller" dimension="Height">
+ <DimOperator op="Multiply">
+ <PropertyDim name="EnableTop" />
+ </DimOperator>
+ </ImageDim>
+ </Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="Height">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="TabHorizontalFiller" dimension="Height">
+ <DimOperator op="Multiply">
+ <PropertyDim name="EnableBottom" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </FrameComponent>
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" >
+ <UnifiedDim scale="1" type="Height">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="TabHorizontalFiller" dimension="Height">
+ <DimOperator op="Multiply">
+ <PropertyDim name="EnableBottom" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="BottomEdge" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="BottomEdge" imageset="TaharezLook" image="TabHorizontalFiller" />
+ </FrameComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="normal" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/TabControl
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/TabControl">
+ <Property name="TabButtonType" value="TaharezLook/TabButton" />
+ <Property name="TabTextPadding" value="{0,6}" />
+ <Child type="TaharezLook/TabContentPane" nameSuffix="__auto_TabPane__">
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge"><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="TopEdge">
+ <PropertyDim widget="__auto_TabPane__" name="EnableBottom">
+ <DimOperator op="Multiply">
+ <PropertyDim name="TabHeight" type="Height" />
+ </DimOperator>
+ </PropertyDim>
+ </Dim>
+ <Dim type="Height">
+ <UnifiedDim scale="1" type="Height">
+ <DimOperator op="Subtract">
+ <PropertyDim name="TabHeight" type="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </Child>
+ <Child type="TaharezLook/TabButtonPane" nameSuffix="__auto_TabPane__Buttons">
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="RightEdge"><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="TopEdge">
+ <PropertyDim widget="__auto_TabPane__Buttons" name="EnableTop">
+ <DimOperator op="Multiply">
+ <UnifiedDim scale="1" type="Height">
+ <DimOperator op="Subtract">
+ <PropertyDim name="TabHeight" type="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </DimOperator>
+ </PropertyDim>
+ </Dim>
+ <Dim type="Height"><PropertyDim name="TabHeight" type="Height" /></Dim>
+ </Area>
+ </Child>
+ <Child type="TaharezLook/SystemButton" nameSuffix="__auto_TabPane__ScrollLeft">
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge">
+ <WidgetDim widget="__auto_TabPane__Buttons" dimension="TopEdge" />
+ </Dim>
+ <Dim type="Width">
+ <WidgetDim widget="__auto_TabPane__Buttons" dimension="Height">
+ <DimOperator op="Multiply">
+ <ImageDim imageset="TaharezLook" image="TabButtonScrollLeftNormal" dimension="Width">
+ <DimOperator op="Divide">
+ <ImageDim imageset="TaharezLook" image="TabButtonScrollLeftNormal" dimension="Height" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </WidgetDim>
+ </Dim>
+ <Dim type="BottomEdge">
+ <WidgetDim widget="__auto_TabPane__Buttons" dimension="BottomEdge" />
+ </Dim>
+ </Area>
+ <Property name="AlwaysOnTop" value="True" />
+ <Property name="NormalImage" value="set:TaharezLook image:TabButtonScrollLeftNormal" />
+ <Property name="HoverImage" value="set:TaharezLook image:TabButtonScrollLeftHover" />
+ <Property name="PushedImage" value="set:TaharezLook image:TabButtonScrollLeftHover" />
+ </Child>
+ <Child type="TaharezLook/SystemButton" nameSuffix="__auto_TabPane__ScrollRight">
+ <Area>
+ <Dim type="Width">
+ <WidgetDim widget="__auto_TabPane__Buttons" dimension="Height">
+ <DimOperator op="Multiply">
+ <ImageDim imageset="TaharezLook" image="TabButtonScrollRightNormal" dimension="Width">
+ <DimOperator op="Divide">
+ <ImageDim imageset="TaharezLook" image="TabButtonScrollRightNormal" dimension="Height" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </WidgetDim>
+ </Dim>
+ <Dim type="LeftEdge">
+ <UnifiedDim scale="1" type="Width">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_TabPane__ScrollRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="TopEdge">
+ <WidgetDim widget="__auto_TabPane__Buttons" dimension="TopEdge" />
+ </Dim>
+ <Dim type="Height">
+ <WidgetDim widget="__auto_TabPane__Buttons" dimension="Height" />
+ </Dim>
+ </Area>
+ <Property name="AlwaysOnTop" value="True" />
+ <Property name="NormalImage" value="set:TaharezLook image:TabButtonScrollRightNormal" />
+ <Property name="HoverImage" value="set:TaharezLook image:TabButtonScrollRightHover" />
+ <Property name="PushedImage" value="set:TaharezLook image:TabButtonScrollRightHover" />
+ </Child>
+ <StateImagery name="Enabled" />
+ <StateImagery name="Disabled" />
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/MenuItem
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/MenuItem">
+ <PropertyDefinition name="NormalTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledTextColour" initialValue="FF7F7F7F" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="OpenedColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <Property name="WantsMultiClickEvents" value="False" />
+ <NamedArea name="ContentSize">
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width">
+ <FontDim type="HorzExtent">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="MenuLeft" dimension="Width">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="MenuRight" dimension="Width" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </FontDim>
+ </Dim>
+ <Dim type="Height">
+ <FontDim type="LineSpacing">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="MenuTop" dimension="Height">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="MenuBottom" dimension="Height" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </FontDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="HasPopupContentSize">
+ <Area>
+ <Dim type="LeftEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width">
+ <FontDim type="HorzExtent">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="MenuLeft" dimension="Width">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="MenuRight" dimension="Width">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="PopupMenuArrowLeft" dimension="Width">
+ <DimOperator op="Multiply">
+ <AbsoluteDim value="3" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </FontDim>
+ </Dim>
+ <Dim type="Height">
+ <FontDim type="LineSpacing">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="MenuTop" dimension="Height">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="MenuBottom" dimension="Height" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </FontDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <ImagerySection name="label">
+ <TextComponent>
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="MenuLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="MenuTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="MenuRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="MenuBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ <VertFormat type="CentreAligned" />
+ <HorzFormat type="LeftAligned" />
+ </TextComponent>
+ </ImagerySection>
+ <ImagerySection name="frame">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="MenuTopLeft" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="MenuTopRight" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="MenuBottomLeft" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="MenuBottomRight" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="MenuLeft" />
+ <Image type="RightEdge" imageset="TaharezLook" image="MenuRight" />
+ <Image type="TopEdge" imageset="TaharezLook" image="MenuTop" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="MenuBottom" />
+ <Image type="Background" imageset="TaharezLook" image="MenuMiddle" />
+ </FrameComponent>
+ </ImagerySection>
+ <ImagerySection name="popup_arrow_right">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" >
+ <UnifiedDim scale="1" type="Width">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="PopupMenuArrowRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="PopupMenuArrowRight" />
+ <VertFormat type="CentreAligned" />
+ <HorzFormat type="RightAligned" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="popup_arrow_left">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" >
+ <UnifiedDim scale="1" type="Width">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="PopupMenuArrowLeft" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="PopupMenuArrowLeft" />
+ <VertFormat type="CentreAligned" />
+ <HorzFormat type="RightAligned" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="EnabledNormal">
+ <Layer>
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="EnabledHover">
+ <Layer>
+ <Section section="frame">
+ <ColourProperty name="HoverColour" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="EnabledPushed">
+ <Layer>
+ <Section section="frame">
+ <ColourProperty name="PushedColour" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="EnabledPopupOpen">
+ <Layer>
+ <Section section="frame">
+ <ColourProperty name="OpenedColour" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="NormalTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DisabledNormal">
+ <Layer>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DisabledHover">
+ <Layer>
+ <Section section="frame">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DisabledPushed">
+ <Layer>
+ <Section section="frame">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="DisabledPopupOpen">
+ <Layer>
+ <Section section="frame">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ <Section section="label">
+ <ColourProperty name="DisabledTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="PopupClosedIcon">
+ <Layer>
+ <Section section="popup_arrow_right" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="PopupOpenIcon">
+ <Layer>
+ <Section section="popup_arrow_left" />
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/PopupMenu
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/PopupMenu">
+ <PropertyDefinition name="BackgroundColours" initialValue="tl:FFFFFFFF tr:FFFFFFFF bl:FFFFFFFF br:FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="BorderWidth" initialValue="0" layoutOnWrite="true" />
+ <NamedArea name="ItemRenderArea">
+ <Area>
+ <Dim type="LeftEdge" >
+ <ImageDim imageset="TaharezLook" image="PopupMenuFrameLeft" dimension="Width">
+ <DimOperator op="Add">
+ <PropertyDim name="BorderWidth" />
+ </DimOperator>
+ </ImageDim>
+ </Dim>
+ <Dim type="TopEdge" >
+ <ImageDim imageset="TaharezLook" image="PopupMenuFrameTop" dimension="Height">
+ <DimOperator op="Add">
+ <PropertyDim name="BorderWidth" />
+ </DimOperator>
+ </ImageDim>
+ </Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="PopupMenuFrameRight" dimension="Width">
+ <DimOperator op="Add">
+ <PropertyDim name="BorderWidth" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="PopupMenuFrameBottom" dimension="Height">
+ <DimOperator op="Add">
+ <PropertyDim name="BorderWidth" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <ImagerySection name="frame">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="PopupMenuFrameTopLeft" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="PopupMenuFrameTopRight" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="PopupMenuFrameBottomLeft" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="PopupMenuFrameBottomRight" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="PopupMenuFrameLeft" />
+ <Image type="RightEdge" imageset="TaharezLook" image="PopupMenuFrameRight" />
+ <Image type="TopEdge" imageset="TaharezLook" image="PopupMenuFrameTop" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="PopupMenuFrameBottom" />
+ <Image type="Background" imageset="TaharezLook" image="PopupMenuMiddle" />
+ </FrameComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="frame">
+ <ColourRectProperty name="BackgroundColours" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="frame">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+
+ <!--
+ ***************************************************
+ TaharezLook/Menubar
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/Menubar">
+ <PropertyDefinition name="BackgroundColours" initialValue="tl:FFFFFFFF tr:FFFFFFFF bl:FFFFFFFF br:FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="BorderWidth" initialValue="5" layoutOnWrite="true" />
+ <NamedArea name="ItemRenderArea">
+ <Area>
+ <Dim type="LeftEdge" >
+ <ImageDim imageset="TaharezLook" image="PopupMenuFrameLeft" dimension="Width">
+ <DimOperator op="Add">
+ <PropertyDim name="BorderWidth" />
+ </DimOperator>
+ </ImageDim>
+ </Dim>
+ <Dim type="TopEdge" >
+ <ImageDim imageset="TaharezLook" image="PopupMenuFrameTop" dimension="Height">
+ <DimOperator op="Add">
+ <PropertyDim name="BorderWidth" />
+ </DimOperator>
+ </ImageDim>
+ </Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="PopupMenuFrameRight" dimension="Width">
+ <DimOperator op="Add">
+ <PropertyDim name="BorderWidth" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="PopupMenuFrameBottom" dimension="Height">
+ <DimOperator op="Add">
+ <PropertyDim name="BorderWidth" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <ImagerySection name="frame">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="PopupMenuFrameTopLeft" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="PopupMenuFrameTopRight" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="PopupMenuFrameBottomLeft" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="PopupMenuFrameBottomRight" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="PopupMenuFrameLeft" />
+ <Image type="RightEdge" imageset="TaharezLook" image="PopupMenuFrameRight" />
+ <Image type="TopEdge" imageset="TaharezLook" image="PopupMenuFrameTop" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="PopupMenuFrameBottom" />
+ <Image type="Background" imageset="TaharezLook" image="PopupMenuMiddle" />
+ </FrameComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="frame">
+ <ColourRectProperty name="BackgroundColours" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="frame">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/LargeVerticalScrollbarThumb
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/LargeVerticalScrollbarThumb">
+ <Property name="VertFree" value="True" />
+ <ImagerySection name="normal">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1.0" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1.0" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="VertScrollThumbNormal" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1.0" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1.0" type="Height" /></Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="VertScrollThumbHover" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Pushed">
+ <Layer>
+ <Section section="normal" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="normal">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/LargeVerticalScrollbar
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/LargeVerticalScrollbar">
+ <Property name="VerticalScrollbar" value="True" />
+ <NamedArea name="ThumbTrackArea">
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0.325" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" >
+ <WidgetDim widget="__auto_decbtn__" dimension="Height">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="VertScrollTop" dimension="Height">
+ <DimOperator op="Multiply">
+ <AbsoluteDim value="0.5" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </WidgetDim>
+ </Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1.0" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1.0" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_decbtn__" dimension="Height">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="VertScrollTop" dimension="Height">
+ <DimOperator op="Multiply">
+ <AbsoluteDim value="0.5" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </WidgetDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <Child type="TaharezLook/ImageButton" nameSuffix="__auto_incbtn__">
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0.25" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" >
+ <AbsoluteDim value="-1">
+ <DimOperator op="Multiply">
+ <ImageDim imageset="TaharezLook" image="VertScrollTop" dimension="Height">
+ <DimOperator op="Multiply">
+ <AbsoluteDim value="0.5" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </AbsoluteDim>
+ </Dim>
+ <Dim type="Width" ><UnifiedDim scale="0.6" type="Width" /></Dim>
+ <Dim type="Height" >
+ <UnifiedDim scale="0.6" type="Width">
+ <DimOperator op="Multiply">
+ <ImageDim imageset="TaharezLook" image="VertScrollUpNormal" dimension="Width">
+ <DimOperator op="Divide">
+ <ImageDim imageset="TaharezLook" image="VertScrollUpNormal" dimension="Height"/>
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ <VertAlignment type="BottomAligned" />
+ <Property name="NormalImage" value="set:TaharezLook image:VertScrollDownNormal" />
+ <Property name="HoverImage" value="set:TaharezLook image:VertScrollDownHover" />
+ <Property name="PushedImage" value="set:TaharezLook image:VertScrollDownNormal" />
+ </Child>
+ <Child type="TaharezLook/ImageButton" nameSuffix="__auto_decbtn__">
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0.25" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge">
+ <ImageDim imageset="TaharezLook" image="VertScrollTop" dimension="Height">
+ <DimOperator op="Multiply">
+ <AbsoluteDim value="0.5" />
+ </DimOperator>
+ </ImageDim>
+ </Dim>
+ <Dim type="Width" ><UnifiedDim scale="0.6" type="Width" /></Dim>
+ <Dim type="Height" >
+ <UnifiedDim scale="0.6" type="Width">
+ <DimOperator op="Multiply">
+ <ImageDim imageset="TaharezLook" image="VertScrollUpNormal" dimension="Width">
+ <DimOperator op="Divide">
+ <ImageDim imageset="TaharezLook" image="VertScrollUpNormal" dimension="Height"/>
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ <Property name="NormalImage" value="set:TaharezLook image:VertScrollUpNormal" />
+ <Property name="HoverImage" value="set:TaharezLook image:VertScrollUpHover" />
+ <Property name="PushedImage" value="set:TaharezLook image:VertScrollUpNormal" />
+ </Child>
+ <Child type="TaharezLook/LargeVerticalScrollbarThumb" nameSuffix="__auto_thumb__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="0.4" type="Width" /></Dim>
+ <Dim type="Height" >
+ <UnifiedDim scale="0.4" type="Width">
+ <DimOperator op="Multiply">
+ <ImageDim imageset="TaharezLook" image="VertScrollThumbNormal" dimension="Height">
+ <DimOperator op="Divide">
+ <ImageDim imageset="TaharezLook" image="VertScrollThumbNormal" dimension="Width"/>
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </Child>
+ <ImagerySection name="main">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopEdge" imageset="TaharezLook" image="VertScrollTop" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="VertScrollBottom" />
+ <Image type="Background" imageset="TaharezLook" image="VertScrollMiddle" />
+ </FrameComponent>
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><UnifiedDim scale="0.45" type="LeftEdge" /></Dim>
+ <Dim type="TopEdge" >
+ <WidgetDim widget="__auto_decbtn__" dimension="Height">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="VertScrollTop" dimension="Height">
+ <DimOperator op="Multiply">
+ <AbsoluteDim value="0.5" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </WidgetDim>
+ </Dim>
+ <Dim type="RightEdge" ><UnifiedDim scale="1.0" type="RightEdge" /></Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1.0" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <WidgetDim widget="__auto_decbtn__" dimension="Height">
+ <DimOperator op="Add">
+ <ImageDim imageset="TaharezLook" image="VertScrollTop" dimension="Height">
+ <DimOperator op="Multiply">
+ <AbsoluteDim value="0.5" />
+ </DimOperator>
+ </ImageDim>
+ </DimOperator>
+ </WidgetDim>
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ <Image imageset="TaharezLook" image="VertScrollBarSegment" />
+ <VertFormat type="Tiled" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="main" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="main">
+ <Colours topLeft="FF7F7F7F" topRight="FF7F7F7F" bottomLeft="FF7F7F7F" bottomRight="FF7F7F7F" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/ImageButton
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/ImageButton">
+ <PropertyDefinition name="NormalImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="HoverImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="PushedImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="DisabledImage" initialValue="" redrawOnWrite="true" />
+ <PropertyDefinition name="VertImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <PropertyDefinition name="HorzImageFormatting" initialValue="Stretched" redrawOnWrite="true" />
+ <ImagerySection name="normal">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="NormalImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="hover">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="HoverImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="pushed">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="PushedImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <ImagerySection name="disabled">
+ <ImageryComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <ImageProperty name="DisabledImage" />
+ <VertFormatProperty name="VertImageFormatting" />
+ <HorzFormatProperty name="HorzImageFormatting" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Normal">
+ <Layer>
+ <Section section="normal" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Hover">
+ <Layer>
+ <Section section="hover" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Pushed">
+ <Layer>
+ <Section section="pushed" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="PushedOff">
+ <Layer>
+ <Section section="hover" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="disabled" />
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+ <!--
+ ***************************************************
+ TaharezLook/ItemListbox
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/ItemListbox">
+ <NamedArea name="ItemRenderArea">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="ListboxLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="ListboxTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="ListboxRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="ListboxBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ItemRenderAreaHScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="ListboxLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="ListboxTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" type="RightEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="ListboxRight" dimension="Width" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" offset="-12" type="BottomEdge" />
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ItemRenderAreaVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="ListboxLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="ListboxTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" offset="-12" type="RightEdge" />
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" type="BottomEdge">
+ <DimOperator op="Subtract">
+ <ImageDim imageset="TaharezLook" image="ListboxBottom" dimension="Height" />
+ </DimOperator>
+ </UnifiedDim>
+ </Dim>
+ </Area>
+ </NamedArea>
+ <NamedArea name="ItemRenderAreaHVScroll">
+ <Area>
+ <Dim type="LeftEdge" ><ImageDim imageset="TaharezLook" image="ListboxLeft" dimension="Width" /></Dim>
+ <Dim type="TopEdge" ><ImageDim imageset="TaharezLook" image="ListboxTop" dimension="Height" /></Dim>
+ <Dim type="RightEdge" >
+ <UnifiedDim scale="1" offset="-12" type="RightEdge" />
+ </Dim>
+ <Dim type="BottomEdge" >
+ <UnifiedDim scale="1" offset="-12" type="BottomEdge" />
+ </Dim>
+ </Area>
+ </NamedArea>
+ <Child type="TaharezLook/HorizontalScrollbar" nameSuffix="__auto_hscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" offset="-12" type="Width" /></Dim>
+ <Dim type="Height" ><AbsoluteDim value="12" /></Dim>
+ </Area>
+ <VertAlignment type="BottomAligned" />
+ </Child>
+ <Child type="TaharezLook/VerticalScrollbar" nameSuffix="__auto_vscrollbar__">
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><AbsoluteDim value="12" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <HorzAlignment type="RightAligned" />
+ </Child>
+ <ImagerySection name="main">
+ <FrameComponent>
+ <Area>
+ <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
+ <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
+ <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
+ </Area>
+ <Image type="TopLeftCorner" imageset="TaharezLook" image="ListboxTopLeft" />
+ <Image type="TopRightCorner" imageset="TaharezLook" image="ListboxTopRight" />
+ <Image type="BottomLeftCorner" imageset="TaharezLook" image="ListboxBottomLeft" />
+ <Image type="BottomRightCorner" imageset="TaharezLook" image="ListboxBottomRight" />
+ <Image type="LeftEdge" imageset="TaharezLook" image="ListboxLeft" />
+ <Image type="RightEdge" imageset="TaharezLook" image="ListboxRight" />
+ <Image type="TopEdge" imageset="TaharezLook" image="ListboxTop" />
+ <Image type="BottomEdge" imageset="TaharezLook" image="ListboxBottom" />
+ <Image type="Background" imageset="TaharezLook" image="ListboxBackdrop" />
+ </FrameComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="main" />
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="main" />
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+
+ <!--
+ ***************************************************
+ TaharezLook/ListboxItem
+ ***************************************************
+ -->
+ <WidgetLook name="TaharezLook/ListboxItem">
+ <PropertyDefinition name="TextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="SelectedTextColour" initialValue="FFFFFFFF" redrawOnWrite="true" />
+ <PropertyDefinition name="SelectionBrush" initialValue="set:TaharezLook image:ListboxSelectionBrush" redrawOnWrite="true" />
+ <PropertyDefinition name="SelectionColour" initialValue="FF4444AA" redrawOnWrite="true" />
+ <Property name="Selectable" value="True" />
+ <NamedArea name="ContentSize">
+ <Area>
+ <Dim type="LeftEdge" >
+ <AbsoluteDim value="0" />
+ </Dim>
+ <Dim type="TopEdge" >
+ <AbsoluteDim value="0" />
+ </Dim>
+ <Dim type="Width" >
+ <FontDim type="HorzExtent" padding="6" />
+ </Dim>
+ <Dim type="Height" >
+ <FontDim type="LineSpacing" />
+ </Dim>
+ </Area>
+ </NamedArea>
+ <ImagerySection name="label">
+ <TextComponent>
+ <Area>
+ <Dim type="TopEdge">
+ <AbsoluteDim value="0" />
+ </Dim>
+ <Dim type="LeftEdge">
+ <AbsoluteDim value="3" />
+ </Dim>
+ <Dim type="RightEdge">
+ <UnifiedDim scale="1" offset="-3" type="RightEdge" />
+ </Dim>
+ <Dim type="BottomEdge">
+ <UnifiedDim scale="1" type="BottomEdge" />
+ </Dim>
+ </Area>
+ </TextComponent>
+ </ImagerySection>
+ <ImagerySection name="selection">
+ <ImageryComponent>
+ <Area>
+ <Dim type="TopEdge">
+ <AbsoluteDim value="0" />
+ </Dim>
+ <Dim type="LeftEdge">
+ <AbsoluteDim value="0" />
+ </Dim>
+ <Dim type="RightEdge">
+ <UnifiedDim scale="1" type="RightEdge" />
+ </Dim>
+ <Dim type="BottomEdge">
+ <UnifiedDim scale="1" type="BottomEdge" />
+ </Dim>
+ </Area>
+ <ImageProperty name="SelectionBrush" />
+ <ColourProperty name="SelectionColour" />
+ <VertFormat type="Stretched" />
+ <HorzFormat type="Stretched" />
+ </ImageryComponent>
+ </ImagerySection>
+ <StateImagery name="Enabled">
+ <Layer>
+ <Section section="label">
+ <ColourProperty name="TextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="Disabled">
+ <Layer>
+ <Section section="label">
+ <ColourProperty name="TextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="SelectedEnabled">
+ <Layer>
+ <Section section="selection" />
+ <Section section="label">
+ <ColourProperty name="SelectedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ <StateImagery name="SelectedDisabled">
+ <Layer>
+ <Section section="selection" />
+ <Section section="label">
+ <ColourProperty name="SelectedTextColour" />
+ </Section>
+ </Layer>
+ </StateImagery>
+ </WidgetLook>
+
+</Falagard>
+
diff --git a/navit/gui/sdl/datafiles/schemes/GUIScheme.xsd b/navit/gui/sdl/datafiles/schemes/GUIScheme.xsd
new file mode 100644
index 000000000..24dba2073
--- /dev/null
+++ b/navit/gui/sdl/datafiles/schemes/GUIScheme.xsd
@@ -0,0 +1,54 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+ <xsd:element name="GUIScheme" type="SchemeType" />
+ <xsd:complexType name="SchemeType">
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="Imageset" type="NamedDataType" />
+ <xsd:element name="ImagesetFromImage" type="NamedDataType" />
+ <xsd:element name="Font" type="NamedDataType" />
+ <xsd:element name="LookNFeel" type="FileDataType" />
+ <xsd:element name="WindowSet" type="WindowSetType" />
+ <xsd:element name="WindowRendererSet" type="WindowRendererSetType" />
+ <xsd:element name="WindowAlias" type="WindowAliasType" />
+ <xsd:element name="FalagardMapping" type="FalagardMapType" />
+ </xsd:choice>
+ <xsd:attribute name="Name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="WindowSetType">
+ <xsd:sequence>
+ <xsd:element name="WindowFactory" type="WindowFactoryType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="Filename" type="xsd:string" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="WindowRendererSetType">
+ <xsd:sequence>
+ <xsd:element name="WindowRendererFactory" type="WindowRendererFactoryType" minOccurs="0" maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:attribute name="Filename" type="xsd:string" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="FileDataType">
+ <xsd:attribute name="Filename" type="xsd:string" use="required" />
+ <xsd:attribute name="ResourceGroup" type="xsd:string" use="optional" default="" />
+ </xsd:complexType>
+ <xsd:complexType name="NamedDataType">
+ <xsd:attribute name="Name" type="xsd:string" use="required" />
+ <xsd:attribute name="Filename" type="xsd:string" use="required" />
+ <xsd:attribute name="ResourceGroup" type="xsd:string" use="optional" default="" />
+ </xsd:complexType>
+ <xsd:complexType name="WindowFactoryType">
+ <xsd:attribute name="Name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="WindowRendererFactoryType">
+ <xsd:attribute name="Name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="WindowAliasType">
+ <xsd:attribute name="Alias" type="xsd:string" use="required" />
+ <xsd:attribute name="Target" type="xsd:string" use="required" />
+ </xsd:complexType>
+ <xsd:complexType name="FalagardMapType">
+ <xsd:attribute name="WindowType" type="xsd:string" use="required" />
+ <xsd:attribute name="TargetType" type="xsd:string" use="required" />
+ <xsd:attribute name="Renderer" type="xsd:string" use="required" />
+ <xsd:attribute name="LookNFeel" type="xsd:string" use="required" />
+ </xsd:complexType>
+</xsd:schema> \ No newline at end of file
diff --git a/navit/gui/sdl/datafiles/schemes/Mineque.scheme b/navit/gui/sdl/datafiles/schemes/Mineque.scheme
new file mode 100755
index 000000000..34101892b
--- /dev/null
+++ b/navit/gui/sdl/datafiles/schemes/Mineque.scheme
@@ -0,0 +1,67 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="TaharezLook">
+ <Imageset Name="TaharezLook" Filename="TaharezLook.imageset" />
+ <Imageset Name="Mineque-Black" Filename="Mineque-Black.imageset" />
+ <LookNFeel Filename="Mineque.looknfeel" />
+ <LookNFeel Filename="TaharezLook.looknfeel" />
+ <WindowRendererSet Filename="CEGUIFalagardWRBase" />
+
+ <FalagardMapping WindowType="NavitGrey/StaticImage" TargetType="DefaultWindow" Renderer="Falagard/StaticImage" LookNFeel="NavitGrey/StaticImage" />
+ <FalagardMapping WindowType="NavitGrey/StaticText" TargetType="DefaultWindow" Renderer="Falagard/StaticText" LookNFeel="NavitGrey/StaticText" />
+
+ <FalagardMapping WindowType="NavitGrey/ZoomInButton" TargetType="CEGUI/PushButton" Renderer="Falagard/Button" LookNFeel="NavitGrey/ZoomInButton" />
+ <FalagardMapping WindowType="NavitGrey/ZoomOutButton" TargetType="CEGUI/PushButton" Renderer="Falagard/Button" LookNFeel="NavitGrey/ZoomOutButton" />
+ <FalagardMapping WindowType="NavitGrey/SpeakerOffButton" TargetType="CEGUI/PushButton" Renderer="Falagard/Button" LookNFeel="NavitGrey/SpeakerOffButton" />
+ <FalagardMapping WindowType="NavitGrey/RouteButton" TargetType="CEGUI/PushButton" Renderer="Falagard/Button" LookNFeel="NavitGrey/RouteButton" />
+ <FalagardMapping WindowType="NavitGrey/OptionsButton" TargetType="CEGUI/PushButton" Renderer="Falagard/Button" LookNFeel="NavitGrey/OptionsButton" />
+ <FalagardMapping WindowType="NavitGrey/QuitButton" TargetType="CEGUI/PushButton" Renderer="Falagard/Button" LookNFeel="NavitGrey/QuitButton" />
+ <FalagardMapping WindowType="NavitGrey/NavitAboutButton" TargetType="CEGUI/PushButton" Renderer="Falagard/Button" LookNFeel="NavitGrey/NavitAboutButton" />
+ <FalagardMapping WindowType="NavitGrey/SpeakerButton" TargetType="CEGUI/PushButton" Renderer="Falagard/Button" LookNFeel="NavitGrey/SpeakerButton" />
+
+
+ <FalagardMapping WindowType="NavitGrey/ModeSwitchButton" TargetType="CEGUI/PushButton" Renderer="Falagard/Button" LookNFeel="NavitGrey/ModeSwitchButton" />
+
+ <FalagardMapping WindowType="NavitGrey/ViewModeSwitchButton" TargetType="CEGUI/PushButton" Renderer="Falagard/Button" LookNFeel="NavitGrey/ViewModeSwitchButton" />
+
+ <FalagardMapping WindowType="TaharezLook/Button" TargetType="CEGUI/PushButton" Renderer="Falagard/Button" LookNFeel="TaharezLook/Button" />
+ <FalagardMapping WindowType="TaharezLook/Checkbox" TargetType="CEGUI/Checkbox" Renderer="Falagard/ToggleButton" LookNFeel="TaharezLook/Checkbox" />
+ <FalagardMapping WindowType="TaharezLook/ImageButton" TargetType="CEGUI/PushButton" Renderer="Falagard/Button" LookNFeel="TaharezLook/ImageButton" />
+ <FalagardMapping WindowType="TaharezLook/RadioButton" TargetType="CEGUI/RadioButton" Renderer="Falagard/ToggleButton" LookNFeel="TaharezLook/RadioButton" />
+ <FalagardMapping WindowType="TaharezLook/FrameWindow" TargetType="CEGUI/FrameWindow" Renderer="Falagard/FrameWindow" LookNFeel="TaharezLook/FrameWindow" />
+ <FalagardMapping WindowType="TaharezLook/Titlebar" TargetType="CEGUI/Titlebar" Renderer="Falagard/Titlebar" LookNFeel="TaharezLook/Titlebar" />
+ <FalagardMapping WindowType="TaharezLook/SystemButton" TargetType="CEGUI/PushButton" Renderer="Falagard/SystemButton" LookNFeel="TaharezLook/Button" />
+ <FalagardMapping WindowType="TaharezLook/Editbox" TargetType="CEGUI/Editbox" Renderer="Falagard/Editbox" LookNFeel="TaharezLook/Editbox" />
+ <FalagardMapping WindowType="TaharezLook/MultiLineEditbox" TargetType="CEGUI/MultiLineEditbox" Renderer="Falagard/MultiLineEditbox" LookNFeel="TaharezLook/MultiLineEditbox" />
+ <FalagardMapping WindowType="TaharezLook/Menubar" TargetType="CEGUI/Menubar" Renderer="Falagard/Menubar" LookNFeel="TaharezLook/Menubar" />
+ <FalagardMapping WindowType="TaharezLook/PopupMenu" TargetType="CEGUI/PopupMenu" Renderer="Falagard/PopupMenu" LookNFeel="TaharezLook/PopupMenu" />
+ <FalagardMapping WindowType="TaharezLook/MenuItem" TargetType="CEGUI/MenuItem" Renderer="Falagard/MenuItem" LookNFeel="TaharezLook/MenuItem" />
+ <FalagardMapping WindowType="TaharezLook/AlternateProgressBar" TargetType="CEGUI/ProgressBar" Renderer="Falagard/ProgressBar" LookNFeel="TaharezLook/AltProgressBar" />
+ <FalagardMapping WindowType="TaharezLook/ProgressBar" TargetType="CEGUI/ProgressBar" Renderer="Falagard/ProgressBar" LookNFeel="TaharezLook/ProgressBar" />
+ <FalagardMapping WindowType="TaharezLook/VUMeter" TargetType="CEGUI/ProgressBar" Renderer="Falagard/ProgressBar" LookNFeel="TaharezLook/VUMeter" />
+ <FalagardMapping WindowType="TaharezLook/VerticalScrollbar" TargetType="CEGUI/Scrollbar" Renderer="Falagard/Scrollbar" LookNFeel="TaharezLook/VerticalScrollbar" />
+ <FalagardMapping WindowType="TaharezLook/HorizontalScrollbar" TargetType="CEGUI/Scrollbar" Renderer="Falagard/Scrollbar" LookNFeel="TaharezLook/HorizontalScrollbar" />
+ <FalagardMapping WindowType="TaharezLook/VerticalScrollbarThumb" TargetType="CEGUI/Thumb" Renderer="Falagard/Button" LookNFeel="TaharezLook/VerticalScrollbarThumb" />
+ <FalagardMapping WindowType="TaharezLook/HorizontalScrollbarThumb" TargetType="CEGUI/Thumb" Renderer="Falagard/Button" LookNFeel="TaharezLook/HorizontalScrollbarThumb" />
+ <FalagardMapping WindowType="TaharezLook/LargeVerticalScrollbar" TargetType="CEGUI/Scrollbar" Renderer="Falagard/Scrollbar" LookNFeel="TaharezLook/LargeVerticalScrollbar" />
+ <FalagardMapping WindowType="TaharezLook/LargeVerticalScrollbarThumb" TargetType="CEGUI/Thumb" Renderer="Falagard/Button" LookNFeel="TaharezLook/LargeVerticalScrollbarThumb" />
+ <FalagardMapping WindowType="TaharezLook/TabButton" TargetType="CEGUI/TabButton" Renderer="Falagard/TabButton" LookNFeel="TaharezLook/TabButton" />
+ <FalagardMapping WindowType="TaharezLook/TabControl" TargetType="CEGUI/TabControl" Renderer="Falagard/TabControl" LookNFeel="TaharezLook/TabControl" />
+ <FalagardMapping WindowType="TaharezLook/TabContentPane" TargetType="DefaultWindow" Renderer="Falagard/Default" LookNFeel="TaharezLook/TabContentPane" />
+ <FalagardMapping WindowType="TaharezLook/TabButtonPane" TargetType="DefaultWindow" Renderer="Falagard/Default" LookNFeel="TaharezLook/TabButtonPane" />
+ <FalagardMapping WindowType="TaharezLook/ComboDropList" TargetType="CEGUI/ComboDropList" Renderer="Falagard/Listbox" LookNFeel="TaharezLook/ComboDropList" />
+ <FalagardMapping WindowType="TaharezLook/ComboEditbox" TargetType="CEGUI/Editbox" Renderer="Falagard/Editbox" LookNFeel="TaharezLook/ComboEditbox" />
+ <FalagardMapping WindowType="TaharezLook/Combobox" TargetType="CEGUI/Combobox" Renderer="Falagard/Default" LookNFeel="TaharezLook/Combobox" />
+ <FalagardMapping WindowType="TaharezLook/Listbox" TargetType="CEGUI/Listbox" Renderer="Falagard/Listbox" LookNFeel="TaharezLook/Listbox" />
+ <FalagardMapping WindowType="TaharezLook/ListHeader" TargetType="CEGUI/ListHeader" Renderer="Falagard/ListHeader" LookNFeel="TaharezLook/ListHeader" />
+ <FalagardMapping WindowType="TaharezLook/ListHeaderSegment" TargetType="CEGUI/ListHeaderSegment" Renderer="Falagard/ListHeaderSegment" LookNFeel="TaharezLook/ListHeaderSegment" />
+ <FalagardMapping WindowType="TaharezLook/MultiColumnList" TargetType="CEGUI/MultiColumnList" Renderer="Falagard/MultiColumnList" LookNFeel="TaharezLook/MultiColumnList" />
+ <FalagardMapping WindowType="TaharezLook/Slider" TargetType="CEGUI/Slider" Renderer="Falagard/Slider" LookNFeel="TaharezLook/Slider" />
+ <FalagardMapping WindowType="TaharezLook/SliderThumb" TargetType="CEGUI/Thumb" Renderer="Falagard/Button" LookNFeel="TaharezLook/SliderThumb" />
+ <FalagardMapping WindowType="TaharezLook/ScrollablePane" TargetType="CEGUI/ScrollablePane" Renderer="Falagard/ScrollablePane" LookNFeel="TaharezLook/ScrollablePane" />
+ <FalagardMapping WindowType="TaharezLook/Spinner" TargetType="CEGUI/Spinner" Renderer="Falagard/Default" LookNFeel="TaharezLook/Spinner" />
+ <FalagardMapping WindowType="TaharezLook/Tooltip" TargetType="CEGUI/Tooltip" Renderer="Falagard/Tooltip" LookNFeel="TaharezLook/Tooltip" />
+ <FalagardMapping WindowType="TaharezLook/StaticImage" TargetType="DefaultWindow" Renderer="Falagard/StaticImage" LookNFeel="TaharezLook/StaticImage" />
+ <FalagardMapping WindowType="TaharezLook/StaticText" TargetType="DefaultWindow" Renderer="Falagard/StaticText" LookNFeel="TaharezLook/StaticText" />
+ <FalagardMapping WindowType="TaharezLook/ItemListbox" TargetType="CEGUI/ItemListbox" Renderer="Falagard/ItemListbox" LookNFeel="TaharezLook/ItemListbox" />
+ <FalagardMapping WindowType="TaharezLook/ListboxItem" TargetType="CEGUI/ItemEntry" Renderer="Falagard/ItemEntry" LookNFeel="TaharezLook/ListboxItem" />
+</GUIScheme>
diff --git a/navit/gui/sdl/datafiles/schemes/TaharezLook.scheme b/navit/gui/sdl/datafiles/schemes/TaharezLook.scheme
new file mode 100755
index 000000000..e48ad4cc5
--- /dev/null
+++ b/navit/gui/sdl/datafiles/schemes/TaharezLook.scheme
@@ -0,0 +1,47 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="TaharezLook">
+ <Imageset Name="TaharezLook" Filename="TaharezLook.imageset" />
+ <LookNFeel Filename="TaharezLook.looknfeel" />
+ <WindowRendererSet Filename="CEGUIFalagardWRBase" />
+ <FalagardMapping WindowType="TaharezLook/Button" TargetType="CEGUI/PushButton" Renderer="Falagard/Button" LookNFeel="TaharezLook/Button" />
+ <FalagardMapping WindowType="TaharezLook/Checkbox" TargetType="CEGUI/Checkbox" Renderer="Falagard/ToggleButton" LookNFeel="TaharezLook/Checkbox" />
+ <FalagardMapping WindowType="TaharezLook/ImageButton" TargetType="CEGUI/PushButton" Renderer="Falagard/Button" LookNFeel="TaharezLook/ImageButton" />
+ <FalagardMapping WindowType="TaharezLook/RadioButton" TargetType="CEGUI/RadioButton" Renderer="Falagard/ToggleButton" LookNFeel="TaharezLook/RadioButton" />
+ <FalagardMapping WindowType="TaharezLook/FrameWindow" TargetType="CEGUI/FrameWindow" Renderer="Falagard/FrameWindow" LookNFeel="TaharezLook/FrameWindow" />
+ <FalagardMapping WindowType="TaharezLook/Titlebar" TargetType="CEGUI/Titlebar" Renderer="Falagard/Titlebar" LookNFeel="TaharezLook/Titlebar" />
+ <FalagardMapping WindowType="TaharezLook/SystemButton" TargetType="CEGUI/PushButton" Renderer="Falagard/SystemButton" LookNFeel="TaharezLook/Button" />
+ <FalagardMapping WindowType="TaharezLook/Editbox" TargetType="CEGUI/Editbox" Renderer="Falagard/Editbox" LookNFeel="TaharezLook/Editbox" />
+ <FalagardMapping WindowType="TaharezLook/MultiLineEditbox" TargetType="CEGUI/MultiLineEditbox" Renderer="Falagard/MultiLineEditbox" LookNFeel="TaharezLook/MultiLineEditbox" />
+ <FalagardMapping WindowType="TaharezLook/Menubar" TargetType="CEGUI/Menubar" Renderer="Falagard/Menubar" LookNFeel="TaharezLook/Menubar" />
+ <FalagardMapping WindowType="TaharezLook/PopupMenu" TargetType="CEGUI/PopupMenu" Renderer="Falagard/PopupMenu" LookNFeel="TaharezLook/PopupMenu" />
+ <FalagardMapping WindowType="TaharezLook/MenuItem" TargetType="CEGUI/MenuItem" Renderer="Falagard/MenuItem" LookNFeel="TaharezLook/MenuItem" />
+ <FalagardMapping WindowType="TaharezLook/AlternateProgressBar" TargetType="CEGUI/ProgressBar" Renderer="Falagard/ProgressBar" LookNFeel="TaharezLook/AltProgressBar" />
+ <FalagardMapping WindowType="TaharezLook/ProgressBar" TargetType="CEGUI/ProgressBar" Renderer="Falagard/ProgressBar" LookNFeel="TaharezLook/ProgressBar" />
+ <FalagardMapping WindowType="TaharezLook/VUMeter" TargetType="CEGUI/ProgressBar" Renderer="Falagard/ProgressBar" LookNFeel="TaharezLook/VUMeter" />
+ <FalagardMapping WindowType="TaharezLook/VerticalScrollbar" TargetType="CEGUI/Scrollbar" Renderer="Falagard/Scrollbar" LookNFeel="TaharezLook/VerticalScrollbar" />
+ <FalagardMapping WindowType="TaharezLook/HorizontalScrollbar" TargetType="CEGUI/Scrollbar" Renderer="Falagard/Scrollbar" LookNFeel="TaharezLook/HorizontalScrollbar" />
+ <FalagardMapping WindowType="TaharezLook/VerticalScrollbarThumb" TargetType="CEGUI/Thumb" Renderer="Falagard/Button" LookNFeel="TaharezLook/VerticalScrollbarThumb" />
+ <FalagardMapping WindowType="TaharezLook/HorizontalScrollbarThumb" TargetType="CEGUI/Thumb" Renderer="Falagard/Button" LookNFeel="TaharezLook/HorizontalScrollbarThumb" />
+ <FalagardMapping WindowType="TaharezLook/LargeVerticalScrollbar" TargetType="CEGUI/Scrollbar" Renderer="Falagard/Scrollbar" LookNFeel="TaharezLook/LargeVerticalScrollbar" />
+ <FalagardMapping WindowType="TaharezLook/LargeVerticalScrollbarThumb" TargetType="CEGUI/Thumb" Renderer="Falagard/Button" LookNFeel="TaharezLook/LargeVerticalScrollbarThumb" />
+ <FalagardMapping WindowType="TaharezLook/TabButton" TargetType="CEGUI/TabButton" Renderer="Falagard/TabButton" LookNFeel="TaharezLook/TabButton" />
+ <FalagardMapping WindowType="TaharezLook/TabControl" TargetType="CEGUI/TabControl" Renderer="Falagard/TabControl" LookNFeel="TaharezLook/TabControl" />
+ <FalagardMapping WindowType="TaharezLook/TabContentPane" TargetType="DefaultWindow" Renderer="Falagard/Default" LookNFeel="TaharezLook/TabContentPane" />
+ <FalagardMapping WindowType="TaharezLook/TabButtonPane" TargetType="DefaultWindow" Renderer="Falagard/Default" LookNFeel="TaharezLook/TabButtonPane" />
+ <FalagardMapping WindowType="TaharezLook/ComboDropList" TargetType="CEGUI/ComboDropList" Renderer="Falagard/Listbox" LookNFeel="TaharezLook/ComboDropList" />
+ <FalagardMapping WindowType="TaharezLook/ComboEditbox" TargetType="CEGUI/Editbox" Renderer="Falagard/Editbox" LookNFeel="TaharezLook/ComboEditbox" />
+ <FalagardMapping WindowType="TaharezLook/Combobox" TargetType="CEGUI/Combobox" Renderer="Falagard/Default" LookNFeel="TaharezLook/Combobox" />
+ <FalagardMapping WindowType="TaharezLook/Listbox" TargetType="CEGUI/Listbox" Renderer="Falagard/Listbox" LookNFeel="TaharezLook/Listbox" />
+ <FalagardMapping WindowType="TaharezLook/ListHeader" TargetType="CEGUI/ListHeader" Renderer="Falagard/ListHeader" LookNFeel="TaharezLook/ListHeader" />
+ <FalagardMapping WindowType="TaharezLook/ListHeaderSegment" TargetType="CEGUI/ListHeaderSegment" Renderer="Falagard/ListHeaderSegment" LookNFeel="TaharezLook/ListHeaderSegment" />
+ <FalagardMapping WindowType="TaharezLook/MultiColumnList" TargetType="CEGUI/MultiColumnList" Renderer="Falagard/MultiColumnList" LookNFeel="TaharezLook/MultiColumnList" />
+ <FalagardMapping WindowType="TaharezLook/Slider" TargetType="CEGUI/Slider" Renderer="Falagard/Slider" LookNFeel="TaharezLook/Slider" />
+ <FalagardMapping WindowType="TaharezLook/SliderThumb" TargetType="CEGUI/Thumb" Renderer="Falagard/Button" LookNFeel="TaharezLook/SliderThumb" />
+ <FalagardMapping WindowType="TaharezLook/ScrollablePane" TargetType="CEGUI/ScrollablePane" Renderer="Falagard/ScrollablePane" LookNFeel="TaharezLook/ScrollablePane" />
+ <FalagardMapping WindowType="TaharezLook/Spinner" TargetType="CEGUI/Spinner" Renderer="Falagard/Default" LookNFeel="TaharezLook/Spinner" />
+ <FalagardMapping WindowType="TaharezLook/Tooltip" TargetType="CEGUI/Tooltip" Renderer="Falagard/Tooltip" LookNFeel="TaharezLook/Tooltip" />
+ <FalagardMapping WindowType="TaharezLook/StaticImage" TargetType="DefaultWindow" Renderer="Falagard/StaticImage" LookNFeel="TaharezLook/StaticImage" />
+ <FalagardMapping WindowType="TaharezLook/StaticText" TargetType="DefaultWindow" Renderer="Falagard/StaticText" LookNFeel="TaharezLook/StaticText" />
+ <FalagardMapping WindowType="TaharezLook/ItemListbox" TargetType="CEGUI/ItemListbox" Renderer="Falagard/ItemListbox" LookNFeel="TaharezLook/ItemListbox" />
+ <FalagardMapping WindowType="TaharezLook/ListboxItem" TargetType="CEGUI/ItemEntry" Renderer="Falagard/ItemEntry" LookNFeel="TaharezLook/ListboxItem" />
+</GUIScheme>
diff --git a/navit/gui/sdl/gui_sdl.h b/navit/gui/sdl/gui_sdl.h
new file mode 100644
index 000000000..877d69e1b
--- /dev/null
+++ b/navit/gui/sdl/gui_sdl.h
@@ -0,0 +1,20 @@
+#include "SDL/SDL.h"
+
+#define XRES 800
+#define YRES 600
+
+
+struct menu_methods;
+struct navit;
+
+extern struct navit *sdl_gui_navit;
+
+
+bool BookmarkGo(const char * name);
+bool FormerDestGo(const char * name);
+
+struct gui_priv {
+ struct navit *nav;
+ int dyn_counter;
+};
+
diff --git a/navit/gui/sdl/gui_sdl_window.cpp b/navit/gui/sdl/gui_sdl_window.cpp
new file mode 100644
index 000000000..4afac7a3d
--- /dev/null
+++ b/navit/gui/sdl/gui_sdl_window.cpp
@@ -0,0 +1,903 @@
+#include "glib.h"
+#include <stdio.h>
+#include <libintl.h>
+
+// FIXME temporary fix for enum
+#include "projection.h"
+
+#include "item.h"
+#include "navit.h"
+#include "vehicle.h"
+#include "profile.h"
+#include "transform.h"
+#include "gui.h"
+#include "coord.h"
+#include "config.h"
+#include "plugin.h"
+#include "callback.h"
+#include "point.h"
+#include "graphics.h"
+#include "gui_sdl.h"
+#include "navigation.h"
+#include "debug.h"
+#include "attr.h"
+#include "track.h"
+#include "menu.h"
+#include "map.h"
+
+
+#include "CEGUI.h"
+
+// FIXME This is for 3d fonts. Needs QuesoGLC. Could probably (and should) be moved to graphics instead
+// since fonts here are handled by CEGUI
+#include "GL/glc.h"
+
+#include "sdl_events.h"
+#include "cegui_keyboard.h"
+#include "wmcontrol.h"
+
+#define VM_2D 0
+#define VM_3D 1
+
+bool VIEW_MODE=VM_3D;
+
+GLdouble eyeX=400;
+GLdouble eyeY=900;
+GLdouble eyeZ=-800;
+GLdouble centerX=400;
+GLdouble centerY=300;
+GLdouble centerZ=0;
+GLdouble upX=0;
+GLdouble upY=-1;
+GLdouble upZ=0;
+
+struct navit *sdl_gui_navit;
+
+#include <CEGUI/RendererModules/OpenGLGUIRenderer/openglrenderer.h>
+#include "CEGUIDefaultResourceProvider.h"
+CEGUI::OpenGLRenderer* renderer;
+
+#undef profile
+#define profile(x,y)
+
+CEGUI::Window* myRoot;
+
+// Temp fix for pluginless mode
+// #define MODULE "gui_sdl"
+GLuint * DLid;
+
+#define _(STRING) gettext(STRING)
+
+char media_window_title[255], media_cmd[255];
+
+struct bookmark{
+ char * name;
+ struct callback *cb;
+ struct bookmark *next;
+} *bookmarks;
+
+struct former_dest{
+ char * name;
+ struct callback *cb;
+ struct former_dest *next;
+} *former_dests;
+
+static int
+gui_sdl_set_graphics(struct gui_priv *this_, struct graphics *gra)
+{
+ dbg(1,"setting up the graphics\n");
+
+ DLid=(GLuint *)graphics_get_data(gra, "opengl_displaylist");
+ if (!DLid)
+ return 1;
+ return 0;
+}
+
+static void
+sdl_update_roadbook(struct navigation *nav)
+{
+
+ using namespace CEGUI;
+
+ struct map *map;
+ struct map_rect *mr;
+
+ if (! nav)
+ return;
+ map=navigation_get_map(nav);
+ if (! map)
+ return;
+ mr=map_rect_new(map, NULL);
+ if (! mr)
+ return;
+
+ // First, ensure the navigation tip is visible. quick workaround for when resuming a destination
+ WindowManager::getSingleton().getWindow("Navit/Routing/Tips")->show();
+
+ // update the 'Navigation Tip' on the main window
+ try {
+ struct attr attr;
+ item_attr_get(map_rect_get_item(mr), attr_navigation_speech, &attr);
+ map_rect_destroy(mr);
+ mr=map_rect_new(map, NULL);
+ WindowManager::getSingleton().getWindow("Navit/Routing/Tips")->setText((CEGUI::utf8*)(attr.u.str));
+ }
+ catch (CEGUI::Exception& e)
+ {
+ fprintf(stderr,"CEGUI Exception occured: \n%s\n", e.getMessage().c_str());
+ printf("Missing control!...\n");
+ }
+
+ // Then, update the whole roadbook
+ try {
+
+ /* Currently we use the 'Navit' text to display the roadbook, until Mineque design a button for that
+ if(! WindowManager::getSingleton().getWindow("OSD/RoadbookButton")->isVisible()){
+ WindowManager::getSingleton().getWindow("OSD/RoadbookButton")->show();
+ }
+ */
+
+ MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("Roadbook"));
+ mcl->resetList();
+
+ item *item;
+ struct attr attr;
+
+ while ((item=map_rect_get_item(mr))) {
+ mcl->addRow();
+ item_attr_get(item, attr_navigation_short, &attr);
+ ListboxTextItem* itemListbox = new ListboxTextItem(attr.u.str);
+ itemListbox->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");
+ mcl->setItem(itemListbox, 0, mcl->getRowCount()-1);
+ }
+ map_rect_destroy(mr);
+ }
+ catch (CEGUI::Exception& e)
+ {
+ dbg(0,"CEGUI Exception occured: \n%s\n", e.getMessage().c_str());
+ dbg(0,"Missing control!\n");
+ }
+
+}
+
+static void show_road_name(){
+ struct tracking *tracking;
+ struct attr road_name_attr;
+ tracking=navit_get_tracking(sdl_gui_navit);
+
+ using namespace CEGUI;
+
+
+ if (tracking && tracking_get_current_attr(tracking, attr_label, &road_name_attr) ) {
+ WindowManager::getSingleton().getWindow("Navit/Routing/CurrentRoadName")->setText((CEGUI::utf8*)(road_name_attr.u.str));
+ }
+
+}
+
+static gboolean gui_timeout_cb(gpointer data)
+{
+ return TRUE;
+}
+
+static int gui_run_main_loop(struct gui_priv *this_)
+{
+ GSource *timeout;
+ using namespace CEGUI;
+ dbg(0,"Entering main loop\n");
+
+ bool must_quit = false;
+
+ // get "run-time" in seconds
+ double last_time_pulse = static_cast<double>(SDL_GetTicks());
+
+ int frames=0;
+ char fps [12];
+
+ struct map_selection sel,sel2;
+
+ memset(&sel, 0, sizeof(sel));
+ memset(&sel2, 0, sizeof(sel2));
+ sel.u.c_rect.rl.x=800;
+ sel.u.c_rect.rl.y=600;
+#if 0
+ sel.next=&sel2;
+ sel2.u.c_rect.rl.x=-200;
+ sel2.u.c_rect.rl.y=0;
+ sel2.u.c_rect.lu.x=1000;
+ sel2.u.c_rect.lu.y=-800;
+ for (int i=0 ; i < layer_end ; i++)
+ sel2.order[i]=-4;
+#endif
+
+ transform_set_screen_selection(navit_get_trans(this_->nav), &sel);
+ navit_draw(this_->nav);
+
+ bool enable_timer=0;
+
+ struct navigation *navig;
+ navig=navit_get_navigation(sdl_gui_navit);
+
+ navigation_register_callback(navig,
+ attr_navigation_long,
+ callback_new_0((void (*)())sdl_update_roadbook)
+ );
+
+ timeout = g_timeout_source_new(100);
+ g_source_set_callback(timeout, gui_timeout_cb, NULL, NULL);
+ g_source_attach(timeout, NULL);
+ while (!must_quit)
+ {
+ if(enable_timer)
+ profile(0,NULL);
+ glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ if(VIEW_MODE==VM_3D){
+ gluLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
+ }
+
+ // FIXME This is to draw a ground. This is ugly and need to be fixed.
+ // Without it, we see the color of sky under the roads.
+ glColor4f(0.0f,0.7f,0.35f,1.0f);
+ glBegin(GL_POLYGON);
+ glVertex3f( -800,-600*3, 0.0f);
+ glVertex3f( -800,600*2, 0.0f);
+ glVertex3f( 1600,600*2, 0.0f);
+ glVertex3f( 1600,-600*3, 0.0f);
+ glEnd();
+
+
+ if(enable_timer)
+ profile(0,"graphics_redraw");
+// if (!g_main_context_iteration (NULL, FALSE))
+ // sleep(1);
+ g_main_context_iteration (NULL, TRUE);
+ // sleep(1);
+ if(enable_timer)
+ profile(0,"main context");
+
+ show_road_name();
+
+ if (DLid && *DLid)
+ glCallList(*DLid);
+ else
+ navit_draw_displaylist(sdl_gui_navit);
+
+ inject_input(must_quit);
+ if(enable_timer)
+ profile(0,"inputs");
+
+ // Render the cursor.
+ int x=400;
+ int y=480;
+ float cursor_size=15.0f;
+ glColor4f(0.0f,1.0f,0.0f,0.75f);
+ glEnable(GL_BLEND);
+ glBegin(GL_TRIANGLES);
+ glVertex3f( x, y-cursor_size, 0.0f);
+ glVertex3f(x-cursor_size,y+cursor_size, 0.0f);
+ glVertex3f( x+cursor_size,y+cursor_size, 0.0f);
+ glEnd();
+ glDisable(GL_BLEND);
+ if(enable_timer)
+ profile(0,"cursor");
+
+ frames++;
+ if(SDL_GetTicks()-last_time_pulse>1000){
+ sprintf(fps,"%i fps",frames); // /(SDL_GetTicks()/1000));
+ frames=0;
+ last_time_pulse = SDL_GetTicks();
+ }
+ WindowManager::getSingleton().getWindow("OSD/Satellites")->setText(fps);
+
+ if(enable_timer)
+ profile(0,"fps");
+
+ CEGUI::System::getSingleton().renderGUI();
+ if(enable_timer)
+ profile(0,"GUI");
+
+ SDL_GL_SwapBuffers();
+ }
+ g_source_destroy(timeout);
+
+}
+
+static struct menu_priv *
+add_menu(struct menu_priv *menu, struct menu_methods *meth, char *name, enum menu_type type, struct callback *cb);
+
+static struct menu_methods menu_methods = {
+ add_menu,
+};
+
+struct menu_priv {
+ char *path;
+// GtkAction *action;
+ struct gui_priv *gui;
+ enum menu_type type;
+ struct callback *cb;
+ struct menu_priv *child;
+ struct menu_priv *sibling;
+ gulong handler_id;
+ guint merge_id;
+};
+
+#define MENU_BOOKMARK 2
+#define MENU_FORMER_DEST 3
+
+static struct menu_priv *
+add_menu(struct menu_priv *menu, struct menu_methods *meth, char *name, enum menu_type type, struct callback *cb)
+{
+ using namespace CEGUI;
+ *meth=menu_methods;
+ dbg(0,"callback : %s\n",name);
+
+ if(menu==(struct menu_priv *)(MENU_BOOKMARK)){
+ dbg(0,"Item is a bookmark\n");
+ MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("Bookmarks/Listbox"));
+
+ ListboxTextItem* itemListbox = new ListboxTextItem((CEGUI::utf8*)(name));
+ itemListbox->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");
+ mcl->addRow(itemListbox,0);
+
+ struct bookmark *newB = g_new0(struct bookmark, 1);
+ newB->name=g_strdup(name);
+ newB->cb=cb;
+ if (newB) {
+ newB->next = bookmarks;
+ bookmarks = newB;
+ }
+
+ }
+
+ if(menu==(struct menu_priv *)(MENU_FORMER_DEST)){
+ dbg(0,"Item is a former destination\n");
+ MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("FormerDests/Listbox"));
+
+ ListboxTextItem* itemListbox = new ListboxTextItem((CEGUI::utf8*)(name));
+ itemListbox->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");
+ mcl->addRow(itemListbox,0);
+
+ struct former_dest *newB = g_new0(struct former_dest, 1);
+ newB->name=g_strdup(name);
+ newB->cb=cb;
+ if (newB) {
+ newB->next = former_dests;
+ former_dests = newB;
+ }
+
+ }
+
+ if(!strcmp(name,"Bookmarks")){
+ dbg(0,"Menu is the bookmark menu!\n");
+ return (struct menu_priv *)MENU_BOOKMARK;
+ } else if(!strcmp(name,"Former Destinations")){
+ dbg(0,"Menu is the Former Destinations menu!\n");
+ return (struct menu_priv *)MENU_FORMER_DEST;
+ } else {
+ return (struct menu_priv *)1;
+ }
+}
+
+bool BookmarkGo(const char * name)
+{
+ dbg(0,"searching for bookmark %s\n",name);
+ bookmark * bookmark_search=bookmarks;
+ while ( bookmark_search ){
+ dbg(0,"-> %s\n",bookmark_search->name);
+ if(!strcmp(bookmark_search->name,name)){
+ dbg(0,"Got it :)\n");
+ callback_call_0(bookmark_search->cb);
+ }
+ bookmark_search=bookmark_search->next;
+ }
+
+}
+
+bool FormerDestGo(const char * name)
+{
+ dbg(0,"searching for former_dest %s\n",name);
+ former_dest * former_dest_search=former_dests;
+ while ( former_dest_search ){
+ dbg(0,"-> %s\n",former_dest_search->name);
+ if(!strcmp(former_dest_search->name,name)){
+ dbg(0,"Got it :)\n");
+ callback_call_0(former_dest_search->cb);
+ }
+ former_dest_search=former_dest_search->next;
+ }
+
+}
+
+static struct menu_priv *
+gui_sdl_menubar_new(struct gui_priv *this_, struct menu_methods *meth)
+{
+ *meth=menu_methods;
+ return (struct menu_priv *) 1; //gui_gtk_ui_new(this_, meth, "/ui/MenuBar", nav, 0);
+}
+
+static struct menu_priv *
+gui_sdl_popup_new(struct gui_priv *this_, struct menu_methods *meth)
+{
+ return NULL; //gui_gtk_ui_new(this_, meth, "/ui/PopUp", nav, 1);
+}
+
+struct gui_methods gui_sdl_methods = {
+ gui_sdl_menubar_new,
+ gui_sdl_popup_new,
+ gui_sdl_set_graphics,
+ gui_run_main_loop,
+};
+
+
+int init_GL() {
+
+ // Blue sky
+ glClearColor(0.3,0.7,1.0,0);
+
+ if(VIEW_MODE==VM_2D){
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity();
+
+ glOrtho( 0, XRES, YRES, 0, -1, 1 );
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ CEGUI::WindowManager::getSingleton().getWindow("OSD/ViewMode")->setText("2D");
+ } else {
+
+ // Dimensions de la fenetre de rendu
+ glViewport(0, 0, XRES, YRES);
+ // Initialisation de la matrice de projection
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(45, 1.0, 0.1, 2800.0);
+ // Rendu avec lissage de Gouraud
+// glShadeModel(GL_SMOOTH);
+ // glEnable(GL_DEPTH_TEST);
+
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+// gluLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
+ CEGUI::WindowManager::getSingleton().getWindow("OSD/ViewMode")->setText("3D");
+ }
+
+ //Display list code
+ // GLuint glGenLists(GLsizei numberOfIDsRequired);
+ // linesDL = glGenLists(1);
+
+ if( glGetError() != GL_NO_ERROR ) {
+ return 0;
+ }
+ return 1;
+}
+
+bool ToggleView(const CEGUI::EventArgs& event)
+{
+ VIEW_MODE=!VIEW_MODE;
+ init_GL();
+}
+
+bool MoveCamera(const CEGUI::EventArgs& event){
+
+ CEGUI::Scrollbar * sb = static_cast<const CEGUI::Scrollbar *>(CEGUI::WindowManager::getSingleton().getWindow("OSD/Scrollbar1"));
+ eyeZ=-sb->getScrollPosition();
+ if (eyeZ>-100){
+ eyeZ=-100;
+ }
+}
+
+
+
+static void init_sdlgui(char * skin_layout,int fullscreen,int tilt, char *image_codec_name)
+{
+ SDL_Surface * screen;
+// atexit (SDL_Quit);
+ SDL_Init (SDL_INIT_VIDEO);
+ int videoFlags;
+ const SDL_VideoInfo *videoInfo;
+ videoInfo = SDL_GetVideoInfo( );
+
+ if ( !videoInfo )
+ {
+ fprintf( stderr, "Video query failed: %s\n",
+ SDL_GetError( ) );
+ }
+
+ /* the flags to pass to SDL_SetVideoMode */
+ videoFlags = SDL_OPENGL; /* Enable OpenGL in SDL */
+ videoFlags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */
+ videoFlags |= SDL_HWPALETTE; /* Store the palette in hardware */
+ videoFlags |= SDL_RESIZABLE; /* Enable window resizing */
+
+ /* This checks to see if surfaces can be stored in memory */
+ if ( videoInfo->hw_available )
+ videoFlags |= SDL_HWSURFACE;
+ else
+ videoFlags |= SDL_SWSURFACE;
+
+ /* This checks if hardware blits can be done */
+ if ( videoInfo->blit_hw )
+ videoFlags |= SDL_HWACCEL;
+
+ /* Sets up OpenGL double buffering */
+ SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+
+ SDL_WM_SetCaption("NavIt - The OpenSource vector based navigation engine", NULL);
+
+ /* get a SDL surface */
+ screen = SDL_SetVideoMode( XRES, YRES, 32,
+ videoFlags );
+
+ if (screen == NULL) {
+ fprintf (stderr, "Can't set SDL: %s\n", SDL_GetError ());
+ exit (1);
+ }
+ if(fullscreen){
+ SDL_WM_ToggleFullScreen(screen);
+ }
+ SDL_ShowCursor (SDL_ENABLE);
+ SDL_EnableUNICODE (1);
+ SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+
+// init_GL();
+
+ try
+ {
+ using namespace CEGUI;
+ if (image_codec_name) {
+ dbg(0, "Using image codec: %s from config\n", image_codec_name);
+ } else {
+#if defined (HAVE_LIBCEGUISILLYIMAGECODEC)
+ image_codec_name = "SILLYImageCodec";
+#elif defined(HAVE_LIBCEGUIDEVILIMAGECODEC)
+ image_codec_name = "DevILImageCodec";
+#elif defined (HAVE_LIBCEGUITGAIMAGECODEC)
+ image_codec_name = "TGAImageCodec";
+#else
+ fprintf (stderr, "No default image codec available. Try setting image_codec in your config\n");
+ exit (1);
+#endif
+ dbg(0, "Using default image codec: %s\n", image_codec_name);
+ }
+ CEGUI::OpenGLRenderer::setDefaultImageCodecName(image_codec_name);
+
+ CEGUI::System::setDefaultXMLParserName(CEGUI::String("TinyXMLParser"));
+ dbg(0, "Using %s as the default CEGUI XML Parser\n", CEGUI::System::getDefaultXMLParserName().c_str());
+ renderer = new CEGUI::OpenGLRenderer(0,XRES,YRES);
+ new CEGUI::System(renderer);
+
+ SDL_ShowCursor(SDL_ENABLE);
+ SDL_EnableUNICODE(1);
+ SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+
+ CEGUI::DefaultResourceProvider* rp = static_cast<CEGUI::DefaultResourceProvider*>
+ (System::getSingleton().getResourceProvider());
+
+
+ char *filename;
+
+ filename=g_strdup_printf("%s/share/navit/datafiles", getenv("NAVIT_PREFIX"));
+
+ if (FILE * file = fopen(filename, "r")){
+ fclose(file);
+ dbg(0,"Ressources can be loaded from %s\n",filename);
+ } else {
+ filename=g_strdup_printf("./gui/sdl/datafiles");
+ dbg(0,"Failling back to %s",filename);
+ }
+
+ dbg(0,"Loading SDL datafiles from %s\n",filename);
+
+ rp->setResourceGroupDirectory("schemes", g_strdup_printf("%s/schemes/",filename));
+ rp->setResourceGroupDirectory("imagesets", g_strdup_printf("%s/imagesets/",filename));
+ rp->setResourceGroupDirectory("fonts", g_strdup_printf("%s/fonts/",filename));
+ rp->setResourceGroupDirectory("layouts", g_strdup_printf("%s/layouts/",filename));
+ rp->setResourceGroupDirectory("looknfeels", g_strdup_printf("%s/looknfeel/",filename));
+ rp->setResourceGroupDirectory("lua_scripts", g_strdup_printf("%s/lua_scripts/",filename));
+ g_free(filename);
+
+
+ CEGUI::Imageset::setDefaultResourceGroup("imagesets");
+ CEGUI::Font::setDefaultResourceGroup("fonts");
+ CEGUI::Scheme::setDefaultResourceGroup("schemes");
+ CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
+ CEGUI::WindowManager::setDefaultResourceGroup("layouts");
+ CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");
+
+ char buffer [50];
+ sprintf (buffer, "%s.scheme", skin_layout);
+ dbg(1,"Loading scheme : %s\n",buffer);
+
+ CEGUI::SchemeManager::getSingleton().loadScheme(buffer);
+
+ CEGUI::FontManager::getSingleton().createFont("DejaVuSans-10.font");
+ CEGUI::FontManager::getSingleton().createFont("DejaVuSans-12.font");
+ CEGUI::FontManager::getSingleton().createFont("DejaVuSans-14.font");
+
+ CEGUI::System::getSingleton().setDefaultFont("DejaVuSans-10");
+
+ CEGUI::WindowManager& wmgr = CEGUI::WindowManager::getSingleton();
+
+ dbg(1,"Loading layout : %s\n",buffer);
+
+ sprintf (buffer, "%s.layout", skin_layout);
+
+ myRoot = CEGUI::WindowManager::getSingleton().loadWindowLayout(buffer);
+
+ CEGUI::System::getSingleton().setGUISheet(myRoot);
+
+ try {
+
+ CEGUI::WindowManager::getSingleton().getWindow("OSD/Quit")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(ButtonQuit));
+// CEGUI::WindowManager::getSingleton().getWindow("OSD/Quit")->setText(_("Quit"));
+
+ CEGUI::WindowManager::getSingleton().getWindow("ZoomInButton")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(ZoomIn));
+// CEGUI::WindowManager::getSingleton().getWindow("ZoomInButton")->setText(_("ZoomIn"));
+
+ CEGUI::WindowManager::getSingleton().getWindow("ZoomOutButton")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(ZoomOut));
+// CEGUI::WindowManager::getSingleton().getWindow("ZoomOutButton")->setText(_("ZoomOut"));
+
+ CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/CountryEditbox")->subscribeEvent(Window::EventKeyUp, Event::Subscriber(DestinationEntryChange));
+ CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/CountryEditbox")->subscribeEvent(Window::EventMouseButtonDown, Event::Subscriber(handleMouseEnters));
+ CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/TownEditbox")->subscribeEvent(Window::EventKeyUp, Event::Subscriber(DestinationEntryChange));
+ CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/TownEditbox")->subscribeEvent(Window::EventMouseButtonDown, Event::Subscriber(handleMouseEnters));
+ CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/StreetEditbox")->subscribeEvent(Window::EventKeyUp, Event::Subscriber(DestinationEntryChange));
+ CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/StreetEditbox")->subscribeEvent(Window::EventMouseButtonDown, Event::Subscriber(handleMouseEnters));
+
+ CEGUI::WindowManager::getSingleton().getWindow("DestinationButton")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(DestinationWindowSwitch));
+ CEGUI::WindowManager::getSingleton().getWindow("DestinationWindow/Address")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(AddressSearchSwitch));
+ CEGUI::WindowManager::getSingleton().getWindow("DestinationWindow/Bookmark")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(BookmarkSelectionSwitch));
+ CEGUI::WindowManager::getSingleton().getWindow("DestinationWindow/FormerDest")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(FormerDestSelectionSwitch));
+
+
+ CEGUI::WindowManager::getSingleton().getWindow("OSD/ViewMode")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(ToggleView));
+
+ CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/GO")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(ButtonGo));
+ CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/KB")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(ShowKeyboard));
+
+ CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/Listbox")->subscribeEvent(MultiColumnList::EventSelectionChanged, Event::Subscriber(ItemSelect));
+ CEGUI::WindowManager::getSingleton().getWindow("Bookmarks/Listbox")->subscribeEvent(MultiColumnList::EventSelectionChanged, Event::Subscriber(BookmarkSelect));
+ CEGUI::WindowManager::getSingleton().getWindow("FormerDests/Listbox")->subscribeEvent(MultiColumnList::EventSelectionChanged, Event::Subscriber(FormerDestSelect));
+
+
+ // Translation for StaticTexts (labels)
+ CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/Country")->setText(_("Country"));
+ CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/Town")->setText(_("City"));
+ CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/Street")->setText(_("Street"));
+
+
+ MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("AdressSearch/Listbox"));
+
+ mcl->setSelectionMode(MultiColumnList::RowSingle) ;
+ mcl->addColumn("Value", 0, cegui_absdim(200.0));
+ mcl->addColumn("ID", 1, cegui_absdim(70.0));
+ mcl->addColumn("Assoc", 2, cegui_absdim(70.0));
+ mcl->addColumn("x", 3, cegui_absdim(70.0));
+ mcl->addColumn("y", 4, cegui_absdim(70.0));
+
+ MultiColumnList* mcl2 = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("Roadbook"));
+
+ mcl2->setSelectionMode(MultiColumnList::RowSingle) ;
+ mcl2->addColumn("Instructions", 0, cegui_absdim(700.0));
+
+ MultiColumnList* mcl3 = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("Bookmarks/Listbox"));
+
+ mcl3->setSelectionMode(MultiColumnList::RowSingle) ;
+ mcl3->addColumn("Name", 0, cegui_absdim(700.0));
+
+ MultiColumnList* mcl4 = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("FormerDests/Listbox"));
+
+ mcl4->setSelectionMode(MultiColumnList::RowSingle) ;
+ mcl4->addColumn("Name", 0, cegui_absdim(700.0));
+
+ BuildKeyboard();
+
+ CEGUI::WindowManager::getSingleton().getWindow("OSD/Scrollbar1")->subscribeEvent(Scrollbar::EventScrollPositionChanged, Event::Subscriber(MoveCamera));
+
+ // FIXME : char (conf) -> int (init) -> char (property) = bad
+ char buffer[4];
+ sprintf (buffer,"%i",tilt);
+ CEGUI::WindowManager::getSingleton().getWindow("OSD/Scrollbar1")->setProperty("ScrollPosition",buffer);
+ eyeZ=-tilt;
+
+ CEGUI::WindowManager::getSingleton().getWindow("OSD/RoadbookButton")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(RoadBookSwitch));
+ CEGUI::WindowManager::getSingleton().getWindow("OSD/RoadbookButton")->setText(_("RoadBook"));
+
+ CEGUI::WindowManager::getSingleton().getWindow("OSD/nGhostButton")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(Switch_to_nGhost));
+ // this one is maybe not needed anymore
+ CEGUI::WindowManager::getSingleton().getWindow("OSD/RoadbookButton2")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(RoadBookSwitch));
+
+ }
+ catch (CEGUI::Exception& e)
+ {
+ fprintf(stderr,"CEGUI Exception occured: \n%s\n", e.getMessage().c_str());
+ printf("Missing control!...\n");
+ }
+
+ }
+ catch (CEGUI::Exception& e)
+ {
+ fprintf(stderr,"CEGUI Exception occured: \n%s\n", e.getMessage().c_str());
+ printf("quiting...\n");
+ exit(1);
+ }
+ init_GL();
+ // Force centering view on cursor
+// navit_toggle_cursor(gui->nav);
+ // Force refresh on gps update
+// navit_toggle_tracking(gui->nav);
+
+}
+
+static void vehicle_callback_handler( struct navit *nav, struct vehicle *v){
+ char buffer [50];
+ struct attr attr;
+ int sats=0, sats_used=0;
+
+ if (vehicle_get_attr(v, attr_position_speed, &attr))
+ sprintf (buffer, "%02.02f km/h", *attr.u.numd);
+ else
+ strcpy (buffer, "N/A");
+ CEGUI::WindowManager::getSingleton().getWindow("OSD/SpeedoMeter")->setText(buffer);
+
+ if (vehicle_get_attr(v, attr_position_height, &attr))
+ sprintf (buffer, "%.f m", *attr.u.numd);
+ else
+ strcpy (buffer, "N/A");
+ CEGUI::WindowManager::getSingleton().getWindow("OSD/Altimeter")->setText(buffer);
+
+ if (vehicle_get_attr(v, attr_position_sats, &attr))
+ sats=attr.u.num;
+ if (vehicle_get_attr(v, attr_position_sats_used, &attr))
+ sats_used=attr.u.num;
+// printf(" sats : %i, used %i: \n",sats,sats_used);
+ // Sat image hardcoded for now. may break the TaharezSkin
+ // setProperty("Image", CEGUI::PropertyHelper::imageToString( yourImageSet->getImage( "yourImageName" ) ) );
+
+ try {
+ if(sats_used>1){
+ CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar1")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOn");
+ } else {
+ CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar1")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOff");
+ }
+
+ if(sats_used>3){
+ CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar2")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOn");
+ } else {
+ CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar2")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOff");
+ }
+
+ if(sats_used>5){
+ CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar3")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOn");
+ } else {
+ CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar3")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOff");
+ }
+
+ if(sats_used>7){
+ CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar4")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOn");
+ } else {
+ CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar4")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOff");
+ }
+
+ if(sats_used>8){
+ CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar5")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOn");
+ } else {
+ CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar5")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOff");
+ }
+ }
+ catch (CEGUI::Exception& e)
+ {
+ dbg(1,"Warning : you skin doesn't have the satellitebars. You should use Mineque's skin.\n");
+ }
+
+}
+
+static struct gui_priv *
+gui_sdl_new(struct navit *nav, struct gui_methods *meth, struct attr **attrs)
+{
+ dbg(1,"Begin SDL init\n");
+ struct gui_priv *this_;
+ sdl_gui_navit=nav;
+
+ if(sdl_gui_navit){
+ dbg(1,"VALID navit instance in gui\n");
+ } else {
+ dbg(1,"Invalid navit instance in gui\n");
+ }
+ if(nav){
+ dbg(1,"VALID source navit instance in gui\n");
+ } else {
+ dbg(1,"Invalid source navit instance in gui\n");
+ }
+
+ *meth=gui_sdl_methods;
+
+ this_=g_new0(struct gui_priv, 1);
+ int fullscreen=0;
+
+ struct attr *fullscreen_setting=attr_search(attrs, NULL, attr_fullscreen);
+ //FIXME currently, we only check if fullscreen is declared, but not its value
+ if(fullscreen_setting){
+ fullscreen=1;
+ printf("fullscreen\n");
+ } else {
+ fullscreen=0;
+ printf("Normal screen\n");
+ }
+
+ int tilt=400;
+ struct attr *tilt_setting=attr_search(attrs, NULL, attr_tilt);
+ if(tilt_setting){
+ if(sscanf(tilt_setting->u.str,"%i",&tilt)){
+ dbg(0,"tilt set to %i\n",tilt);
+ } else {
+ dbg(0,"title was not recognized : %s\n",tilt_setting->u.str);
+ }
+ } else {
+ dbg(0,"tilt is not set\n");
+ }
+
+ struct attr *view_mode_setting=attr_search(attrs, NULL, attr_view_mode);
+ if(view_mode_setting){
+ if(!strcmp(view_mode_setting->u.str,"2D")){
+ dbg(0,"View mode is 2D\n");
+ VIEW_MODE=VM_2D;
+ } else {
+ dbg(0,"view mode is something else : %s\n",view_mode_setting->u.str);
+ }
+
+ } else {
+ dbg(0,"view_mode is not set\n");
+ }
+
+ struct attr *media_cmd_setting=attr_search(attrs, NULL, attr_media_cmd);
+ if(media_cmd_setting){
+ dbg(0,"setting media_cmd to %s\n",media_cmd_setting->u.str);
+ strcpy(media_cmd,media_cmd_setting->u.str);
+ } else {
+// strcpy(media_cmd_setting->u.str,media_window_title);
+ }
+
+ struct attr *media_window_title_setting=attr_search(attrs, NULL, attr_media_window_title);
+ if(media_window_title_setting){
+ strcpy(media_window_title,media_window_title_setting->u.str);
+ } else {
+// strcpy(media_cmd_setting->u.str,media_window_title);
+ }
+
+ struct attr *image_codec_setting=attr_search(attrs, NULL, attr_image_codec);
+ char *image_codec_name=NULL;
+ if (image_codec_setting)
+ image_codec_name=image_codec_setting->u.str;
+ struct attr *skin_setting=attr_search(attrs, NULL, attr_skin);
+ if(skin_setting){
+ init_sdlgui(skin_setting->u.str,fullscreen,tilt, image_codec_name);
+ } else {
+ g_warning("Warning, no skin set for <sdl> in navit.xml. Using default one");
+ init_sdlgui("TaharezLook",fullscreen,tilt, image_codec_name);
+ }
+
+
+ dbg(1,"End SDL init\n");
+
+ //gui_sdl_window.cpp:710: error: invalid conversion from 'void (*)(vehicle*)' to 'void (*)()'
+
+ /* add callback for position updates */
+ struct callback *cb=callback_new_attr_0(callback_cast(vehicle_callback_handler), attr_position_coord_geo);
+
+ navit_add_callback(nav,cb);
+ this_->nav=nav;
+
+ return this_;
+}
+
+void
+plugin_init(void)
+{
+ dbg(1,"registering sdl plugin\n");
+ plugin_register_gui_type("sdl", gui_sdl_new);
+}
diff --git a/navit/gui/sdl/sdl_events.cpp b/navit/gui/sdl/sdl_events.cpp
new file mode 100644
index 000000000..7a121753f
--- /dev/null
+++ b/navit/gui/sdl/sdl_events.cpp
@@ -0,0 +1,810 @@
+#include "CEGUI.h"
+#include "sdl_events.h"
+#include "gui_sdl.h"
+
+#include <CEGUI/RendererModules/OpenGLGUIRenderer/openglrenderer.h>
+
+// FIXME temporary fix for enum
+#include "projection.h"
+#include "item.h"
+#include "navit.h"
+#include "debug.h"
+#include "track.h"
+#include "search.h"
+#include "coord.h"
+#include "country.h"
+#include "string.h"
+
+// Library for window switching (-> nGhost)
+#include "wmcontrol.h"
+
+
+struct sdl_destination{
+ int country;
+ int town;
+ int town_street_assoc;
+ int current_search;
+} SDL_dest;
+
+
+static struct search_param {
+ struct navit *nav;
+ struct mapset *ms;
+ struct search_list *sl;
+ struct attr attr;
+ } search_param;
+
+
+void route_to(int x,int y){
+ struct pcoord pos;
+ pos.x=x;
+ pos.y=y;
+ /* FIXME: Get projection from list like x,y or use pcoord from search directly */
+ pos.pro = projection_mg;
+ using namespace CEGUI;
+ extern struct navit *sdl_gui_navit;
+
+ try {
+ WindowManager::getSingleton().getWindow("AdressSearchWindow")->hide();
+ WindowManager::getSingleton().getWindow("Navit/Routing/Tips")->show();
+
+// WindowManager::getSingleton().getWindow("Navit/ProgressWindow")->show();
+ // route_set_destination(co->route, &pos);
+ // I could have been using search->nav instead of sdl_gui_navit. is it better this way?
+
+// WindowManager::getSingleton().getWindow("Navit/ProgressWindow")->hide();
+// WindowManager::getSingleton().getWindow("OSD/RoadbookButton")->show();
+// WindowManager::getSingleton().getWindow("OSD/ETA")->show();
+ }
+ catch (CEGUI::Exception& e)
+ {
+ fprintf(stderr,"CEGUI Exception occured: \n%s\n", e.getMessage().c_str());
+ printf("Missing control!...\n");
+ }
+ navit_set_destination(sdl_gui_navit, &pos, "FIXME");
+
+}
+
+bool Handle_Virtual_Key_Down(const CEGUI::EventArgs& event){
+
+ using namespace CEGUI;
+
+ const WindowEventArgs& we = static_cast<const CEGUI::WindowEventArgs&>(event);
+ String senderID = we.window->getName();
+
+ Window* editbox = WindowManager::getSingleton().getWindow("Navit/Keyboard/Input");
+ String content=editbox->getText();
+
+
+ if(senderID=="OK"){
+ WindowManager::getSingleton().getWindow("Navit/Keyboard")->hide();
+ return 0;
+ } else if(senderID=="BACK"){
+ content=content.substr(0, content.length()-1);
+ editbox->setText(content);
+ } else {
+ content+=senderID;
+ editbox->setText(content);
+ }
+
+ Window* country_edit = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/CountryEditbox"));
+ Window* town_edit = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/TownEditbox"));
+ Window* street_edit = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/StreetEditbox"));
+
+ switch (SDL_dest.current_search) {
+ case SRCH_COUNTRY:
+ country_edit->setText(content);
+ break;
+ case SRCH_TOWN :
+ town_edit->setText(content);
+ break;
+ case SRCH_STREET :
+ street_edit->setText(content);
+ break;
+ }
+ handle_destination_change();
+}
+
+bool handleItemSelect(int r)
+{
+ using namespace CEGUI;
+
+ MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("AdressSearch/Listbox"));
+
+ ListboxItem * item = mcl->getItemAtGridReference(MCLGridRef(r,0));
+ ListboxItem * itemid = mcl->getItemAtGridReference(MCLGridRef(r,1));
+ ListboxItem * item_assoc = mcl->getItemAtGridReference(MCLGridRef(r,2));
+
+
+ Window* country_edit = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/CountryEditbox"));
+ Window* twn_edit = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/TownEditbox"));
+ Window* street_edit = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/StreetEditbox"));
+
+ if(SDL_dest.current_search==SRCH_COUNTRY){
+ country_edit->setText(item->getText());
+ twn_edit->activate();
+ SDL_dest.current_search=SRCH_TOWN;
+ WindowManager::getSingleton().getWindow("Navit/Keyboard/Input")->setText("");
+
+ } else if(SDL_dest.current_search==SRCH_TOWN){
+ twn_edit->setText(item->getText());
+
+ ListboxItem * itemx = mcl->getItemAtGridReference(MCLGridRef(r,3));
+ ListboxItem * itemy = mcl->getItemAtGridReference(MCLGridRef(r,4));
+
+ Window* Dest_x = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/Dest_x"));
+ Dest_x->setText(itemx->getText().c_str());
+
+ Window* Dest_y = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/Dest_y"));
+ Dest_y->setText(itemy->getText().c_str());
+
+ mcl->resetList();
+
+ SDL_dest.current_search=SRCH_STREET;
+ street_edit->activate();
+ WindowManager::getSingleton().getWindow("Navit/Keyboard/Input")->setText("");
+
+ } else if(SDL_dest.current_search==SRCH_STREET){
+ street_edit->setText(item->getText());
+
+ WindowManager::getSingleton().getWindow("Navit/Keyboard")->hide();
+
+ ListboxItem * itemx = mcl->getItemAtGridReference(MCLGridRef(r,3));
+ ListboxItem * itemy = mcl->getItemAtGridReference(MCLGridRef(r,4));
+
+ Window* Dest_x = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/Dest_x"));
+ Dest_x->setText(itemx->getText().c_str());
+
+ Window* Dest_y = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/Dest_y"));
+ Dest_y->setText(itemy->getText().c_str());
+
+ mcl->resetList();
+
+ SDL_dest.current_search=SRCH_STREET;
+
+ WindowManager::getSingleton().getWindow("Navit/Keyboard/Input")->setText("");
+
+
+ } else if (SDL_dest.current_search==SRCH_NUMBER){
+
+ struct coord pos;
+ ListboxItem * itemx = mcl->getItemAtGridReference(MCLGridRef(r,3));
+ ListboxItem * itemy = mcl->getItemAtGridReference(MCLGridRef(r,4));
+
+ pos.x=atoi(itemx->getText().c_str());
+ pos.y=atoi(itemy->getText().c_str());
+
+ route_to(pos.x,pos.y);
+ }
+
+ return true;
+}
+
+bool route_clear(const CEGUI::EventArgs& event)
+{
+// navit_set_destination(gui->nav, NULL, NULL);
+}
+
+bool ItemSelect(const CEGUI::EventArgs& event)
+{
+ //FIXME maybe merge with handleItemSelect
+ using namespace CEGUI;
+
+ MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("AdressSearch/Listbox"));
+ ListboxItem * item = mcl->getFirstSelectedItem();
+ handleItemSelect(mcl->getItemRowIndex(item));
+}
+
+bool BookmarkSelect(const CEGUI::EventArgs& event)
+{
+ using namespace CEGUI;
+ dbg(0,"1\n");
+ MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("Bookmarks/Listbox"));
+ dbg(0,"2\n");
+ ListboxItem * item = mcl->getFirstSelectedItem();
+ if(item){
+ dbg(0,"item %s is at row %i\n",item->getText().c_str(),mcl->getItemRowIndex(item));
+ BookmarkGo(item->getText().c_str());
+ }
+ WindowManager::getSingleton().getWindow("BookmarkSelection")->hide();
+}
+
+bool FormerDestSelect(const CEGUI::EventArgs& event)
+{
+ using namespace CEGUI;
+ dbg(0,"1\n");
+ MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("FormerDests/Listbox"));
+ dbg(0,"2\n");
+ ListboxItem * item = mcl->getFirstSelectedItem();
+ if(item){
+ dbg(0,"item %s is at row %i\n",item->getText().c_str(),mcl->getItemRowIndex(item));
+ FormerDestGo(item->getText().c_str());
+ }
+ WindowManager::getSingleton().getWindow("FormerDestSelection")->hide();
+ dbg(0,"hided\n");
+}
+
+bool handleMouseEnters(const CEGUI::EventArgs& event)
+{
+ // FIXME this whole function could maybe be removed
+ const CEGUI::WindowEventArgs& we = static_cast<const CEGUI::WindowEventArgs&>(event);
+
+ // FIXME theses variables should be shared
+ extern CEGUI::OpenGLRenderer* renderer;
+
+ using namespace CEGUI;
+ WindowManager::getSingleton().getWindow("Navit/Keyboard/Input")->setText("");
+ MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("AdressSearch/Listbox"));
+
+ String senderID = we.window->getName();
+
+ if (senderID == "AdressSearch/CountryEditbox"){
+ // First, clean off the Street and Town Editbox
+ Window* town_edit = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/TownEditbox"));
+ town_edit->setText("");
+ Window* street_edit = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/StreetEditbox"));
+ street_edit->setText("");
+ SDL_dest.current_search=SRCH_COUNTRY;
+
+ } else if (senderID == "AdressSearch/TownEditbox"){
+ // First, clean off the Street Editbox
+ Window* street_edit = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/StreetEditbox"));
+ street_edit->setText("");
+ SDL_dest.current_search=SRCH_TOWN;
+
+ } else if (senderID == "AdressSearch/StreetEditbox"){
+ // First, make sure the user selected an entry in the town choice. If he hadn't, select the first for him.
+ if(SDL_dest.current_search==SRCH_TOWN){
+ if (mcl->getRowCount()>0)
+ {
+ handleItemSelect(0);
+ }
+ }
+ SDL_dest.current_search=SRCH_STREET;
+
+ }
+}
+
+
+void handle_destination_change(){
+
+ using namespace CEGUI;
+
+ struct search_param *search=&search_param;
+ struct search_list_result *res;
+
+ MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("AdressSearch/Listbox"));
+
+
+ if (SDL_dest.current_search==SRCH_COUNTRY)
+ {
+ Editbox* country_edit = static_cast<Editbox*>(WindowManager::getSingleton().getWindow("AdressSearch/CountryEditbox"));
+ String content=country_edit->getText();
+
+ mcl->resetList();
+ dbg(0,"Starting a country search : %s\n",content.c_str());
+
+ search->attr.type=attr_country_all;
+
+ // FIXME the following codeblock could be shared between country, town and street search
+ search->attr.u.str=(char *)content.c_str();
+
+ search_list_search(search->sl, &search->attr, 1);
+ while((res=search_list_get_result(search->sl))) {
+ ListboxTextItem* itemListbox = new ListboxTextItem((CEGUI::utf8*)(res->country->name));
+ itemListbox->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");
+
+ mcl->addRow(itemListbox,0);
+ }
+
+ } else if (SDL_dest.current_search==SRCH_TOWN)
+ {
+
+ Editbox* town_edit = static_cast<Editbox*>(WindowManager::getSingleton().getWindow("AdressSearch/TownEditbox"));
+ String content=town_edit->getText();
+
+
+ mcl->resetList();
+
+ if(strlen(content.c_str())<4){
+
+ } else {
+ dbg(0,"town searching for %s\n",content.c_str());
+ search->attr.type=attr_town_name;
+ search->attr.u.str=(char *)content.c_str();
+
+ search_list_search(search->sl, &search->attr, 1);
+ while((res=search_list_get_result(search->sl))) {
+ ListboxTextItem* itemListbox = new ListboxTextItem((CEGUI::utf8*)(res->town->name));
+ itemListbox->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");
+
+ mcl->addRow(itemListbox,0);
+
+ char x [256];
+ sprintf(x,"%li",res->c->x);
+ ListboxTextItem* xitem = new ListboxTextItem(x);
+
+ char y [256];
+ sprintf(y,"%li",res->c->y);
+
+ ListboxTextItem* yitem = new ListboxTextItem(y);
+
+ try
+ {
+ mcl->setItem(xitem, 3, mcl->getRowCount()-1);
+ mcl->setItem(yitem, 4, mcl->getRowCount()-1);
+ }
+ // something went wrong, so cleanup the ListboxTextItem.
+ catch (InvalidRequestException)
+ {
+// delete item;
+ }
+
+ }
+
+ }
+
+
+ } else if (SDL_dest.current_search==SRCH_STREET)
+ {
+ Editbox* street_edit = static_cast<Editbox*>(WindowManager::getSingleton().getWindow("AdressSearch/StreetEditbox"));
+
+ String content=street_edit->getText();
+ if(strlen(content.c_str())<1){
+
+ } else {
+ // dbg(1,"street searching for %s\n",content.c_str());
+ search->attr.type=attr_street_name;
+ search->attr.u.str=(char *)content.c_str();
+
+ mcl->resetList();
+
+ search_list_search(search->sl, &search->attr, 1);
+ while((res=search_list_get_result(search->sl))) {
+ ListboxTextItem* itemListbox = new ListboxTextItem((CEGUI::utf8*)(res->street->name));
+ itemListbox->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");
+
+ mcl->addRow(itemListbox,0);
+
+ char x [256];
+ sprintf(x,"%li",res->c->x);
+ ListboxTextItem* xitem = new ListboxTextItem(x);
+
+ char y [256];
+ sprintf(y,"%li",res->c->y);
+
+ ListboxTextItem* yitem = new ListboxTextItem(y);
+
+ try
+ {
+ mcl->setItem(xitem, 3, mcl->getRowCount()-1);
+ mcl->setItem(yitem, 4, mcl->getRowCount()-1);
+ }
+ // something went wrong, so cleanup the ListboxTextItem.
+ catch (InvalidRequestException)
+ {
+// delete item;
+ }
+
+
+ }
+ }
+ }
+
+}
+
+
+bool DestinationEntryChange(const CEGUI::EventArgs& event)
+{
+ handleMouseEnters(event);
+ handle_destination_change();
+
+ return true;
+}
+
+bool DestinationWindowSwitch(const CEGUI::EventArgs& event)
+{
+ using namespace CEGUI;
+
+ WindowManager::getSingleton().getWindow("AdressSearchWindow")->hide();
+ WindowManager::getSingleton().getWindow("BookmarkSelection")->hide();
+ WindowManager::getSingleton().getWindow("FormerDestSelection")->hide();
+
+ if(WindowManager::getSingleton().getWindow("DestinationChoose")->isVisible()){
+ WindowManager::getSingleton().getWindow("DestinationChoose")->hide();
+ } else {
+ WindowManager::getSingleton().getWindow("DestinationChoose")->show();
+ }
+}
+
+bool BookmarkSelectionSwitch(const CEGUI::EventArgs& event)
+{
+ using namespace CEGUI;
+ if(WindowManager::getSingleton().getWindow("BookmarkSelection")->isVisible()){
+ WindowManager::getSingleton().getWindow("BookmarkSelection")->hide();
+ } else {
+ WindowManager::getSingleton().getWindow("DestinationChoose")->hide();
+ WindowManager::getSingleton().getWindow("BookmarkSelection")->show();
+ }
+}
+
+bool FormerDestSelectionSwitch(const CEGUI::EventArgs& event)
+{
+ using namespace CEGUI;
+ if(WindowManager::getSingleton().getWindow("FormerDestSelection")->isVisible()){
+ WindowManager::getSingleton().getWindow("FormerDestSelection")->hide();
+ } else {
+ WindowManager::getSingleton().getWindow("DestinationChoose")->hide();
+ WindowManager::getSingleton().getWindow("FormerDestSelection")->show();
+ }
+}
+
+bool AddressSearchSwitch(const CEGUI::EventArgs& event)
+{
+ using namespace CEGUI;
+ WindowManager::getSingleton().getWindow("DestinationChoose")->hide();
+ WindowManager::getSingleton().getWindow("AdressSearchWindow")->show();
+
+
+ if(sdl_gui_navit){
+ } else {
+ dbg(0,"*** Invalid navit instance in sdl_events\n");
+ }
+ struct search_param *search=&search_param;
+ struct search_list_result *res;
+
+ // dbg(1,"search->nav=sdl_gui_navit;\n");
+ search->nav=sdl_gui_navit;
+ // dbg(1,"search->ms=navit_get_mapset(sdl_gui_navit);\n");
+ search->ms=navit_get_mapset(sdl_gui_navit);
+ // dbg(1,"search->sl=search_list_new(search->ms);\n");
+ search->sl=search_list_new(search->ms);
+
+
+ const CEGUI::WindowEventArgs& we = static_cast<const CEGUI::WindowEventArgs&>(event);
+
+ Window* town_edit = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/TownEditbox"));
+ town_edit->setText("");
+ Window* street_edit = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/StreetEditbox"));
+ street_edit->setText("");
+ town_edit->activate();
+
+ SDL_dest.current_search=SRCH_COUNTRY;
+ MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("AdressSearch/Listbox"));
+ mcl->resetList();
+
+
+ // Code to get the current country and set it by default for the search
+ struct attr search_attr, country_name, *country_attr;
+ struct tracking *tracking;
+ struct country_search *cs;
+ struct item *item;
+
+
+ Editbox* country_edit = static_cast<Editbox*>(WindowManager::getSingleton().getWindow("AdressSearch/CountryEditbox"));
+
+ country_attr=country_default();
+ tracking=navit_get_tracking(sdl_gui_navit);
+ if (tracking && tracking_get_current_attr(tracking, attr_country_id, &search_attr))
+ country_attr=&search_attr;
+ cs=country_search_new(country_attr, 0);
+ item=country_search_get_item(cs);
+ if (item && item_attr_get(item, attr_country_name, &country_name)){
+ country_edit->setText(country_name.u.str);
+ handle_destination_change();
+ }
+ country_search_destroy(cs);
+
+ SDL_dest.current_search=SRCH_TOWN;
+
+ return true;
+}
+
+bool Switch_to_nGhost(const CEGUI::EventArgs& event)
+{
+ extern char media_window_title[255], media_cmd[255];
+ dbg(0,"trying to switch to %s (%s)\n",media_window_title,media_cmd);
+ if (window_switch(media_window_title)==EXIT_FAILURE)
+ {
+ popen(media_cmd,"r");
+ }
+
+}
+
+
+bool RoadBookSwitch(const CEGUI::EventArgs& event)
+{
+ using namespace CEGUI;
+
+// const CEGUI::WindowEventArgs& we = static_cast<const CEGUI::WindowEventArgs&>(event);
+ if(WindowManager::getSingleton().getWindow("Navit/RoadBook")->isVisible()){
+ WindowManager::getSingleton().getWindow("Navit/RoadBook")->hide();
+ WindowManager::getSingleton().getWindow("OSD/RoadbookButton")->show();
+ } else {
+ WindowManager::getSingleton().getWindow("Navit/RoadBook")->show();
+ WindowManager::getSingleton().getWindow("OSD/RoadbookButton")->hide();
+ }
+ return true;
+}
+
+bool ButtonGo(const CEGUI::EventArgs& event)
+{
+ using namespace CEGUI;
+
+ MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("AdressSearch/Listbox"));
+ // First, make sure the user selected an entry in the town choice. If he hadn't, select the first for him.
+ if(SDL_dest.current_search==SRCH_TOWN){
+ if (mcl->getRowCount()>0)
+ {
+ handleItemSelect(0);
+ }
+ }
+
+
+ Window* Dest_x = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/Dest_x"));
+ Window* Dest_y = static_cast<Window*>(WindowManager::getSingleton().getWindow("AdressSearch/Dest_y"));
+
+ extern struct navit *sdl_gui_navit;
+ route_to(atoi(Dest_x->getText().c_str()),atoi(Dest_y->getText().c_str()));
+
+ return true;
+}
+
+
+bool ZoomIn(const CEGUI::EventArgs& event)
+{
+ extern struct navit *sdl_gui_navit;
+ navit_zoom_in(sdl_gui_navit, 2, NULL);
+
+}
+
+bool ZoomOut(const CEGUI::EventArgs& event)
+{
+ extern struct navit *sdl_gui_navit;
+ navit_zoom_out(sdl_gui_navit, 2, NULL);
+}
+
+bool ButtonQuit(const CEGUI::EventArgs& event)
+{
+ exit(0);
+}
+
+
+
+
+// Nothing really interesting below.
+
+void handle_mouse_down(Uint8 button)
+{
+ switch ( button )
+ {
+ // handle real mouse buttons
+ case SDL_BUTTON_LEFT:
+ CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton);
+ break;
+ case SDL_BUTTON_MIDDLE:
+ CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::MiddleButton);
+ break;
+ case SDL_BUTTON_RIGHT:
+ CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::RightButton);
+ break;
+
+ // handle the mouse wheel
+ case SDL_BUTTON_WHEELDOWN:
+ CEGUI::System::getSingleton().injectMouseWheelChange( -1 );
+ break;
+ case SDL_BUTTON_WHEELUP:
+ CEGUI::System::getSingleton().injectMouseWheelChange( +1 );
+ break;
+ }
+}
+
+
+void handle_mouse_up(Uint8 button)
+{
+ switch ( button )
+ {
+ case SDL_BUTTON_LEFT:
+ CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::LeftButton);
+ break;
+ case SDL_BUTTON_MIDDLE:
+ CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::MiddleButton);
+ break;
+ case SDL_BUTTON_RIGHT:
+ CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::RightButton);
+ break;
+ }
+}
+
+void inject_time_pulse(double& last_time_pulse)
+{
+ // get current "run-time" in seconds
+ double t = 0.001*SDL_GetTicks();
+
+ // inject the time that passed since the last call
+ CEGUI::System::getSingleton().injectTimePulse( float(t-last_time_pulse) );
+
+ // store the new time as the last time
+ last_time_pulse = t;
+}
+
+ CEGUI::uint SDLKeyToCEGUIKey(SDLKey key)
+ {
+ using namespace CEGUI;
+ switch (key)
+ {
+ case SDLK_BACKSPACE: return Key::Backspace;
+ case SDLK_TAB: return Key::Tab;
+ case SDLK_RETURN: return Key::Return;
+ case SDLK_PAUSE: return Key::Pause;
+ case SDLK_ESCAPE: return Key::Escape;
+ case SDLK_SPACE: return Key::Space;
+ case SDLK_COMMA: return Key::Comma;
+ case SDLK_MINUS: return Key::Minus;
+ case SDLK_PERIOD: return Key::Period;
+ case SDLK_SLASH: return Key::Slash;
+ case SDLK_0: return Key::Zero;
+ case SDLK_1: return Key::One;
+ case SDLK_2: return Key::Two;
+ case SDLK_3: return Key::Three;
+ case SDLK_4: return Key::Four;
+ case SDLK_5: return Key::Five;
+ case SDLK_6: return Key::Six;
+ case SDLK_7: return Key::Seven;
+ case SDLK_8: return Key::Eight;
+ case SDLK_9: return Key::Nine;
+ case SDLK_COLON: return Key::Colon;
+ case SDLK_SEMICOLON: return Key::Semicolon;
+ case SDLK_EQUALS: return Key::Equals;
+ case SDLK_LEFTBRACKET: return Key::LeftBracket;
+ case SDLK_BACKSLASH: return Key::Backslash;
+ case SDLK_RIGHTBRACKET: return Key::RightBracket;
+ case SDLK_a: return Key::A;
+ case SDLK_b: return Key::B;
+ case SDLK_c: return Key::C;
+ case SDLK_d: return Key::D;
+ case SDLK_e: return Key::E;
+ case SDLK_f: return Key::F;
+ case SDLK_g: return Key::G;
+ case SDLK_h: return Key::H;
+ case SDLK_i: return Key::I;
+ case SDLK_j: return Key::J;
+ case SDLK_k: return Key::K;
+ case SDLK_l: return Key::L;
+ case SDLK_m: return Key::M;
+ case SDLK_n: return Key::N;
+ case SDLK_o: return Key::O;
+ case SDLK_p: return Key::P;
+ case SDLK_q: return Key::Q;
+ case SDLK_r: return Key::R;
+ case SDLK_s: return Key::S;
+ case SDLK_t: return Key::T;
+ case SDLK_u: return Key::U;
+ case SDLK_v: return Key::V;
+ case SDLK_w: return Key::W;
+ case SDLK_x: return Key::X;
+ case SDLK_y: return Key::Y;
+ case SDLK_z: return Key::Z;
+ case SDLK_DELETE: return Key::Delete;
+ case SDLK_KP0: return Key::Numpad0;
+ case SDLK_KP1: return Key::Numpad1;
+ case SDLK_KP2: return Key::Numpad2;
+ case SDLK_KP3: return Key::Numpad3;
+ case SDLK_KP4: return Key::Numpad4;
+ case SDLK_KP5: return Key::Numpad5;
+ case SDLK_KP6: return Key::Numpad6;
+ case SDLK_KP7: return Key::Numpad7;
+ case SDLK_KP8: return Key::Numpad8;
+ case SDLK_KP9: return Key::Numpad9;
+ case SDLK_KP_PERIOD: return Key::Decimal;
+ case SDLK_KP_DIVIDE: return Key::Divide;
+ case SDLK_KP_MULTIPLY: return Key::Multiply;
+ case SDLK_KP_MINUS: return Key::Subtract;
+ case SDLK_KP_PLUS: return Key::Add;
+ case SDLK_KP_ENTER: return Key::NumpadEnter;
+ case SDLK_KP_EQUALS: return Key::NumpadEquals;
+ case SDLK_UP: return Key::ArrowUp;
+ case SDLK_DOWN: return Key::ArrowDown;
+ case SDLK_RIGHT: return Key::ArrowRight;
+ case SDLK_LEFT: return Key::ArrowLeft;
+ case SDLK_INSERT: return Key::Insert;
+ case SDLK_HOME: return Key::Home;
+ case SDLK_END: return Key::End;
+ case SDLK_PAGEUP: return Key::PageUp;
+ case SDLK_PAGEDOWN: return Key::PageDown;
+ case SDLK_F1: return Key::F1;
+ case SDLK_F2: return Key::F2;
+ case SDLK_F3: return Key::F3;
+ case SDLK_F4: return Key::F4;
+ case SDLK_F5: return Key::F5;
+ case SDLK_F6: return Key::F6;
+ case SDLK_F7: return Key::F7;
+ case SDLK_F8: return Key::F8;
+ case SDLK_F9: return Key::F9;
+ case SDLK_F10: return Key::F10;
+ case SDLK_F11: return Key::F11;
+ case SDLK_F12: return Key::F12;
+ case SDLK_F13: return Key::F13;
+ case SDLK_F14: return Key::F14;
+ case SDLK_F15: return Key::F15;
+ case SDLK_NUMLOCK: return Key::NumLock;
+ case SDLK_SCROLLOCK: return Key::ScrollLock;
+ case SDLK_RSHIFT: return Key::RightShift;
+ case SDLK_LSHIFT: return Key::LeftShift;
+ case SDLK_RCTRL: return Key::RightControl;
+ case SDLK_LCTRL: return Key::LeftControl;
+ case SDLK_RALT: return Key::RightAlt;
+ case SDLK_LALT: return Key::LeftAlt;
+ case SDLK_LSUPER: return Key::LeftWindows;
+ case SDLK_RSUPER: return Key::RightWindows;
+ case SDLK_SYSREQ: return Key::SysRq;
+ case SDLK_MENU: return Key::AppMenu;
+ case SDLK_POWER: return Key::Power;
+ default: return 0;
+ }
+ return 0;
+ }
+
+
+void inject_input(bool& must_quit)
+{
+ SDL_Event e;
+
+ // go through all available events
+ while (SDL_PollEvent(&e))
+ {
+ // we use a switch to determine the event type
+ switch (e.type)
+ {
+ // mouse motion handler
+ case SDL_MOUSEMOTION:
+ // we inject the mouse position directly.
+ CEGUI::System::getSingleton().injectMousePosition(
+ static_cast<float>(e.motion.x),
+ static_cast<float>(e.motion.y)
+ );
+ break;
+
+ // mouse down handler
+ case SDL_MOUSEBUTTONDOWN:
+ // let a special function handle the mouse button down event
+ handle_mouse_down(e.button.button);
+ break;
+
+ // mouse up handler
+ case SDL_MOUSEBUTTONUP:
+ // let a special function handle the mouse button up event
+ handle_mouse_up(e.button.button);
+ break;
+
+
+ // key down
+ case SDL_KEYDOWN:
+ // to tell CEGUI that a key was pressed, we inject the scancode, translated from SDL
+ CEGUI::System::getSingleton().injectKeyDown(SDLKeyToCEGUIKey(e.key.keysym.sym));
+
+ // as for the character it's a litte more complicated. we'll use for translated unicode value.
+ // this is described in more detail below.
+ if ((e.key.keysym.unicode & 0xFF80) == 0)
+ {
+ CEGUI::System::getSingleton().injectChar(e.key.keysym.unicode & 0x7F);
+ }
+ break;
+
+ // key up
+ case SDL_KEYUP:
+ // like before we inject the scancode translated from SDL.
+ CEGUI::System::getSingleton().injectKeyUp(SDLKeyToCEGUIKey(e.key.keysym.sym));
+ break;
+
+
+ // WM quit event occured
+ case SDL_QUIT:
+ must_quit = true;
+ break;
+
+ }
+
+ }
+
+}
diff --git a/navit/gui/sdl/sdl_events.h b/navit/gui/sdl/sdl_events.h
new file mode 100644
index 000000000..b4d6e60ae
--- /dev/null
+++ b/navit/gui/sdl/sdl_events.h
@@ -0,0 +1,40 @@
+#include "SDL/SDL.h"
+#include "CEGUI.h"
+
+
+
+#define SRCH_COUNTRY 1
+#define SRCH_TOWN 2
+#define SRCH_STREET 3
+#define SRCH_NUMBER 4
+
+
+
+bool handleItemSelect(int r);
+bool ItemSelect(const CEGUI::EventArgs& event);
+bool handleMouseEnters(const CEGUI::EventArgs& event);
+void handle_destination_change();
+
+bool DestinationEntryChange(const CEGUI::EventArgs& event);
+bool DestinationWindowSwitch(const CEGUI::EventArgs& event);
+bool BookmarkSelectionSwitch(const CEGUI::EventArgs& event);
+bool BookmarkSelect(const CEGUI::EventArgs& event);
+bool FormerDestSelectionSwitch(const CEGUI::EventArgs& event);
+bool FormerDestSelect(const CEGUI::EventArgs& event);
+bool AddressSearchSwitch(const CEGUI::EventArgs& event);
+bool Switch_to_nGhost(const CEGUI::EventArgs& event);
+bool RoadBookSwitch(const CEGUI::EventArgs& event);
+bool ButtonGo(const CEGUI::EventArgs& event);
+bool ZoomIn(const CEGUI::EventArgs& event);
+bool ZoomOut(const CEGUI::EventArgs& event);
+bool ButtonQuit(const CEGUI::EventArgs& event);
+
+void inject_time_pulse(double& last_time_pulse);
+
+bool Handle_Virtual_Key_Down(const CEGUI::EventArgs& event);
+
+CEGUI::uint SDLKeyToCEGUIKey(SDLKey key);
+
+void inject_input(bool& must_quit);
+
+
diff --git a/navit/gui/sdl/wmcontrol.c b/navit/gui/sdl/wmcontrol.c
new file mode 100644
index 000000000..0337ce2dc
--- /dev/null
+++ b/navit/gui/sdl/wmcontrol.c
@@ -0,0 +1,1252 @@
+
+// This is loosely based upon wmctrl 1.07.
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <locale.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/cursorfont.h>
+#include <X11/Xmu/WinUtil.h>
+#include <glib.h>
+
+
+#include "wmcontrol.h"
+
+#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
+#define _NET_WM_STATE_ADD 1 /* add/set property */
+#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
+
+#define MAX_PROPERTY_VALUE_LEN 4096
+#define SELECT_WINDOW_MAGIC ":SELECT:"
+#define ACTIVE_WINDOW_MAGIC ":ACTIVE:"
+
+#define p_verbose(...) if (options.verbose) { \
+ fprintf(stderr, __VA_ARGS__); \
+}
+
+/* declarations of static functions *//*{{{*/
+static gboolean wm_supports (Display *disp, const gchar *prop);
+static Window *get_client_list (Display *disp, unsigned long *size);
+static int client_msg(Display *disp, Window win, char *msg,
+ unsigned long data0, unsigned long data1,
+ unsigned long data2, unsigned long data3,
+ unsigned long data4);
+static int list_windows (Display *disp);
+static int list_desktops (Display *disp);
+static int showing_desktop (Display *disp);
+static int change_viewport (Display *disp);
+static int change_geometry (Display *disp);
+static int change_number_of_desktops (Display *disp);
+static int switch_desktop (Display *disp);
+static int wm_info (Display *disp);
+static gchar *get_output_str (gchar *str, gboolean is_utf8);
+static int action_window (Display *disp, Window win, char mode);
+static int action_window_pid (Display *disp, char mode);
+static int action_window_str (Display *disp, char mode);
+static int activate_window (Display *disp, Window win,
+ gboolean switch_desktop);
+static int close_window (Display *disp, Window win);
+static int longest_str (gchar **strv);
+static int window_to_desktop (Display *disp, Window win, int desktop);
+static void window_set_title (Display *disp, Window win, char *str, char mode);
+static gchar *get_window_title (Display *disp, Window win);
+static gchar *get_window_class (Display *disp, Window win);
+static gchar *get_property (Display *disp, Window win,
+ Atom xa_prop_type, gchar *prop_name, unsigned long *size);
+static void init_charset(void);
+static int window_move_resize (Display *disp, Window win, char *arg);
+static int window_state (Display *disp, Window win, char *arg);
+static Window Select_Window(Display *dpy);
+static Window get_active_window(Display *dpy);
+
+/*}}}*/
+
+static struct {
+ int verbose;
+ int force_utf8;
+ int show_class;
+ int show_pid;
+ int show_geometry;
+ int match_by_id;
+ int match_by_cls;
+ int full_window_title_match;
+ int wa_desktop_titles_invalid_utf8;
+ char *param_window;
+ char *param;
+} options;
+
+static gboolean envir_utf8;
+
+int window_switch(const char *windowName) { /* {{{ */
+ int opt;
+ int ret = EXIT_SUCCESS;
+ int missing_option = 1;
+ Display *disp;
+
+ memset(&options, 0, sizeof(options)); /* just for sure */
+
+ /* necessary to make g_get_charset() and g_locale_*() work */
+ setlocale(LC_ALL, "");
+
+ options.param_window=malloc(strlen(windowName));
+ strncpy(options.param_window,windowName,strlen(windowName));
+
+ init_charset();
+
+ if (! (disp = XOpenDisplay(NULL))) {
+ fputs("Cannot open display.\n", stderr);
+ return EXIT_FAILURE;
+ }
+ if (! options.param_window) {
+ fputs("No window was specified.\n", stderr);
+ return EXIT_FAILURE;
+ }
+ ret = action_window_str(disp, 'a');
+ XCloseDisplay(disp);
+ return ret;
+}
+/* }}} */
+
+static void init_charset (void) {/*{{{*/
+ const gchar *charset; /* unused */
+ gchar *lang = getenv("LANG") ? g_ascii_strup(getenv("LANG"), -1) : NULL;
+ gchar *lc_ctype = getenv("LC_CTYPE") ? g_ascii_strup(getenv("LC_CTYPE"), -1) : NULL;
+
+ /* this glib function doesn't work on my system ... */
+ envir_utf8 = g_get_charset(&charset);
+
+ /* ... therefore we will examine the environment variables */
+ if (lc_ctype && (strstr(lc_ctype, "UTF8") || strstr(lc_ctype, "UTF-8"))) {
+ envir_utf8 = TRUE;
+ }
+ else if (lang && (strstr(lang, "UTF8") || strstr(lang, "UTF-8"))) {
+ envir_utf8 = TRUE;
+ }
+
+ g_free(lang);
+ g_free(lc_ctype);
+
+ if (options.force_utf8) {
+ envir_utf8 = TRUE;
+ }
+ p_verbose("envir_utf8: %d\n", envir_utf8);
+}/*}}}*/
+
+static int client_msg(Display *disp, Window win, char *msg, /* {{{ */
+ unsigned long data0, unsigned long data1,
+ unsigned long data2, unsigned long data3,
+ unsigned long data4) {
+ XEvent event;
+ long mask = SubstructureRedirectMask | SubstructureNotifyMask;
+
+ event.xclient.type = ClientMessage;
+ event.xclient.serial = 0;
+ event.xclient.send_event = True;
+ event.xclient.message_type = XInternAtom(disp, msg, False);
+ event.xclient.window = win;
+ event.xclient.format = 32;
+ event.xclient.data.l[0] = data0;
+ event.xclient.data.l[1] = data1;
+ event.xclient.data.l[2] = data2;
+ event.xclient.data.l[3] = data3;
+ event.xclient.data.l[4] = data4;
+
+ if (XSendEvent(disp, DefaultRootWindow(disp), False, mask, &event)) {
+ return EXIT_SUCCESS;
+ }
+ else {
+ fprintf(stderr, "Cannot send %s event.\n", msg);
+ return EXIT_FAILURE;
+ }
+}/*}}}*/
+
+static gchar *get_output_str (gchar *str, gboolean is_utf8) {/*{{{*/
+ gchar *out;
+
+ if (str == NULL) {
+ return NULL;
+ }
+
+ if (envir_utf8) {
+ if (is_utf8) {
+ out = g_strdup(str);
+ }
+ else {
+ if (! (out = g_locale_to_utf8(str, -1, NULL, NULL, NULL))) {
+ p_verbose("Cannot convert string from locale charset to UTF-8.\n");
+ out = g_strdup(str);
+ }
+ }
+ }
+ else {
+ if (is_utf8) {
+ if (! (out = g_locale_from_utf8(str, -1, NULL, NULL, NULL))) {
+ p_verbose("Cannot convert string from UTF-8 to locale charset.\n");
+ out = g_strdup(str);
+ }
+ }
+ else {
+ out = g_strdup(str);
+ }
+ }
+
+ return out;
+}/*}}}*/
+
+static int wm_info (Display *disp) {/*{{{*/
+ Window *sup_window = NULL;
+ gchar *wm_name = NULL;
+ gchar *wm_class = NULL;
+ unsigned long *wm_pid = NULL;
+ unsigned long *showing_desktop = NULL;
+ gboolean name_is_utf8 = TRUE;
+ gchar *name_out;
+ gchar *class_out;
+
+ if (! (sup_window = (Window *)get_property(disp, DefaultRootWindow(disp),
+ XA_WINDOW, "_NET_SUPPORTING_WM_CHECK", NULL))) {
+ if (! (sup_window = (Window *)get_property(disp, DefaultRootWindow(disp),
+ XA_CARDINAL, "_WIN_SUPPORTING_WM_CHECK", NULL))) {
+ fputs("Cannot get window manager info properties.\n"
+ "(_NET_SUPPORTING_WM_CHECK or _WIN_SUPPORTING_WM_CHECK)\n", stderr);
+ return EXIT_FAILURE;
+ }
+ }
+
+ /* WM_NAME */
+ if (! (wm_name = get_property(disp, *sup_window,
+ XInternAtom(disp, "UTF8_STRING", False), "_NET_WM_NAME", NULL))) {
+ name_is_utf8 = FALSE;
+ if (! (wm_name = get_property(disp, *sup_window,
+ XA_STRING, "_NET_WM_NAME", NULL))) {
+ p_verbose("Cannot get name of the window manager (_NET_WM_NAME).\n");
+ }
+ }
+ name_out = get_output_str(wm_name, name_is_utf8);
+
+ /* WM_CLASS */
+ if (! (wm_class = get_property(disp, *sup_window,
+ XInternAtom(disp, "UTF8_STRING", False), "WM_CLASS", NULL))) {
+ name_is_utf8 = FALSE;
+ if (! (wm_class = get_property(disp, *sup_window,
+ XA_STRING, "WM_CLASS", NULL))) {
+ p_verbose("Cannot get class of the window manager (WM_CLASS).\n");
+ }
+ }
+ class_out = get_output_str(wm_class, name_is_utf8);
+
+
+ /* WM_PID */
+ if (! (wm_pid = (unsigned long *)get_property(disp, *sup_window,
+ XA_CARDINAL, "_NET_WM_PID", NULL))) {
+ p_verbose("Cannot get pid of the window manager (_NET_WM_PID).\n");
+ }
+
+ /* _NET_SHOWING_DESKTOP */
+ if (! (showing_desktop = (unsigned long *)get_property(disp, DefaultRootWindow(disp),
+ XA_CARDINAL, "_NET_SHOWING_DESKTOP", NULL))) {
+ p_verbose("Cannot get the _NET_SHOWING_DESKTOP property.\n");
+ }
+
+ /* print out the info */
+ printf("Name: %s\n", name_out ? name_out : "N/A");
+ printf("Class: %s\n", class_out ? class_out : "N/A");
+
+ if (wm_pid) {
+ printf("PID: %lu\n", *wm_pid);
+ }
+ else {
+ printf("PID: N/A\n");
+ }
+
+ if (showing_desktop) {
+ printf("Window manager's \"showing the desktop\" mode: %s\n",
+ *showing_desktop == 1 ? "ON" : "OFF");
+ }
+ else {
+ printf("Window manager's \"showing the desktop\" mode: N/A\n");
+ }
+
+ g_free(name_out);
+ g_free(sup_window);
+ g_free(wm_name);
+ g_free(wm_class);
+ g_free(wm_pid);
+ g_free(showing_desktop);
+
+ return EXIT_SUCCESS;
+}/*}}}*/
+
+static int showing_desktop (Display *disp) {/*{{{*/
+ unsigned long state;
+
+ if (strcmp(options.param, "on") == 0) {
+ state = 1;
+ }
+ else if (strcmp(options.param, "off") == 0) {
+ state = 0;
+ }
+ else {
+ fputs("The argument to the -k option must be either \"on\" or \"off\"\n", stderr);
+ return EXIT_FAILURE;
+ }
+
+ return client_msg(disp, DefaultRootWindow(disp), "_NET_SHOWING_DESKTOP",
+ state, 0, 0, 0, 0);
+}/*}}}*/
+
+static int change_viewport (Display *disp) {/*{{{*/
+ unsigned long x, y;
+ const char *argerr = "The -o option expects two integers separated with a comma.\n";
+
+ if (sscanf(options.param, "%lu,%lu", &x, &y) == 2) {
+ return client_msg(disp, DefaultRootWindow(disp), "_NET_DESKTOP_VIEWPORT",
+ x, y, 0, 0, 0);
+ }
+ else {
+ fputs(argerr, stderr);
+ return EXIT_FAILURE;
+ }
+}/*}}}*/
+
+static int change_geometry (Display *disp) {/*{{{*/
+ unsigned long x, y;
+ const char *argerr = "The -g option expects two integers separated with a comma.\n";
+
+ if (sscanf(options.param, "%lu,%lu", &x, &y) == 2) {
+ return client_msg(disp, DefaultRootWindow(disp), "_NET_DESKTOP_GEOMETRY",
+ x, y, 0, 0, 0);
+ }
+ else {
+ fputs(argerr, stderr);
+ return EXIT_FAILURE;
+ }
+}/*}}}*/
+
+static int change_number_of_desktops (Display *disp) {/*{{{*/
+ unsigned long n;
+
+ if (sscanf(options.param, "%lu", &n) != 1) {
+ fputs("The -n option expects an integer.\n", stderr);
+ return EXIT_FAILURE;
+ }
+
+ return client_msg(disp, DefaultRootWindow(disp), "_NET_NUMBER_OF_DESKTOPS",
+ n, 0, 0, 0, 0);
+}/*}}}*/
+
+static int switch_desktop (Display *disp) {/*{{{*/
+ int target = -1;
+
+ target = atoi(options.param);
+ if (target == -1) {
+ fputs("Invalid desktop ID.\n", stderr);
+ return EXIT_FAILURE;
+ }
+
+ return client_msg(disp, DefaultRootWindow(disp), "_NET_CURRENT_DESKTOP",
+ (unsigned long)target, 0, 0, 0, 0);
+}/*}}}*/
+
+static void window_set_title (Display *disp, Window win, /* {{{ */
+ char *title, char mode) {
+ gchar *title_utf8;
+ gchar *title_local;
+
+ if (envir_utf8) {
+ title_utf8 = g_strdup(title);
+ title_local = NULL;
+ }
+ else {
+ if (! (title_utf8 = g_locale_to_utf8(title, -1, NULL, NULL, NULL))) {
+ title_utf8 = g_strdup(title);
+ }
+ title_local = g_strdup(title);
+ }
+
+ if (mode == 'T' || mode == 'N') {
+ /* set name */
+ if (title_local) {
+ XChangeProperty(disp, win, XA_WM_NAME, XA_STRING, 8, PropModeReplace,
+ title_local, strlen(title_local));
+ }
+ else {
+ XDeleteProperty(disp, win, XA_WM_NAME);
+ }
+ XChangeProperty(disp, win, XInternAtom(disp, "_NET_WM_NAME", False),
+ XInternAtom(disp, "UTF8_STRING", False), 8, PropModeReplace,
+ title_utf8, strlen(title_utf8));
+ }
+
+ if (mode == 'T' || mode == 'I') {
+ /* set icon name */
+ if (title_local) {
+ XChangeProperty(disp, win, XA_WM_ICON_NAME, XA_STRING, 8, PropModeReplace,
+ title_local, strlen(title_local));
+ }
+ else {
+ XDeleteProperty(disp, win, XA_WM_ICON_NAME);
+ }
+ XChangeProperty(disp, win, XInternAtom(disp, "_NET_WM_ICON_NAME", False),
+ XInternAtom(disp, "UTF8_STRING", False), 8, PropModeReplace,
+ title_utf8, strlen(title_utf8));
+ }
+
+ g_free(title_utf8);
+ g_free(title_local);
+
+}/*}}}*/
+
+static int window_to_desktop (Display *disp, Window win, int desktop) {/*{{{*/
+ unsigned long *cur_desktop = NULL;
+ Window root = DefaultRootWindow(disp);
+
+ if (desktop == -1) {
+ if (! (cur_desktop = (unsigned long *)get_property(disp, root,
+ XA_CARDINAL, "_NET_CURRENT_DESKTOP", NULL))) {
+ if (! (cur_desktop = (unsigned long *)get_property(disp, root,
+ XA_CARDINAL, "_WIN_WORKSPACE", NULL))) {
+ fputs("Cannot get current desktop properties. "
+ "(_NET_CURRENT_DESKTOP or _WIN_WORKSPACE property)"
+ "\n", stderr);
+ return EXIT_FAILURE;
+ }
+ }
+ desktop = *cur_desktop;
+ }
+ g_free(cur_desktop);
+
+ return client_msg(disp, win, "_NET_WM_DESKTOP", (unsigned long)desktop,
+ 0, 0, 0, 0);
+}/*}}}*/
+
+static int activate_window (Display *disp, Window win, /* {{{ */
+ gboolean switch_desktop) {
+ unsigned long *desktop;
+
+
+ printf("sounds good\n");
+ /* desktop ID */
+ if ((desktop = (unsigned long *)get_property(disp, win,
+ XA_CARDINAL, "_NET_WM_DESKTOP", NULL)) == NULL) {
+ if ((desktop = (unsigned long *)get_property(disp, win,
+ XA_CARDINAL, "_WIN_WORKSPACE", NULL)) == NULL) {
+ p_verbose("Cannot find desktop ID of the window.\n");
+ }
+ }
+
+ if (switch_desktop && desktop) {
+ if (client_msg(disp, DefaultRootWindow(disp),
+ "_NET_CURRENT_DESKTOP",
+ *desktop, 0, 0, 0, 0) != EXIT_SUCCESS) {
+ p_verbose("Cannot switch desktop.\n");
+ }
+ g_free(desktop);
+ }
+
+ client_msg(disp, win, "_NET_ACTIVE_WINDOW",
+ 0, 0, 0, 0, 0);
+ XMapRaised(disp, win);
+
+ return EXIT_SUCCESS;
+}/*}}}*/
+
+static int close_window (Display *disp, Window win) {/*{{{*/
+ return client_msg(disp, win, "_NET_CLOSE_WINDOW",
+ 0, 0, 0, 0, 0);
+}/*}}}*/
+
+static int window_state (Display *disp, Window win, char *arg) {/*{{{*/
+ unsigned long action;
+ Atom prop1 = 0;
+ Atom prop2 = 0;
+ char *p1, *p2;
+ const char *argerr = "The -b option expects a list of comma separated parameters: \"(remove|add|toggle),<PROP1>[,<PROP2>]\"\n";
+
+ if (!arg || strlen(arg) == 0) {
+ fputs(argerr, stderr);
+ return EXIT_FAILURE;
+ }
+
+ if ((p1 = strchr(arg, ','))) {
+ gchar *tmp_prop1, *tmp1;
+
+ *p1 = '\0';
+
+ /* action */
+ if (strcmp(arg, "remove") == 0) {
+ action = _NET_WM_STATE_REMOVE;
+ }
+ else if (strcmp(arg, "add") == 0) {
+ action = _NET_WM_STATE_ADD;
+ }
+ else if (strcmp(arg, "toggle") == 0) {
+ action = _NET_WM_STATE_TOGGLE;
+ }
+ else {
+ fputs("Invalid action. Use either remove, add or toggle.\n", stderr);
+ return EXIT_FAILURE;
+ }
+ p1++;
+
+ /* the second property */
+ if ((p2 = strchr(p1, ','))) {
+ gchar *tmp_prop2, *tmp2;
+ *p2 = '\0';
+ p2++;
+ if (strlen(p2) == 0) {
+ fputs("Invalid zero length property.\n", stderr);
+ return EXIT_FAILURE;
+ }
+ tmp_prop2 = g_strdup_printf("_NET_WM_STATE_%s", tmp2 = g_ascii_strup(p2, -1));
+ p_verbose("State 2: %s\n", tmp_prop2);
+ prop2 = XInternAtom(disp, tmp_prop2, False);
+ g_free(tmp2);
+ g_free(tmp_prop2);
+ }
+
+ /* the first property */
+ if (strlen(p1) == 0) {
+ fputs("Invalid zero length property.\n", stderr);
+ return EXIT_FAILURE;
+ }
+ tmp_prop1 = g_strdup_printf("_NET_WM_STATE_%s", tmp1 = g_ascii_strup(p1, -1));
+ p_verbose("State 1: %s\n", tmp_prop1);
+ prop1 = XInternAtom(disp, tmp_prop1, False);
+ g_free(tmp1);
+ g_free(tmp_prop1);
+
+
+ return client_msg(disp, win, "_NET_WM_STATE",
+ action, (unsigned long)prop1, (unsigned long)prop2, 0, 0);
+ }
+ else {
+ fputs(argerr, stderr);
+ return EXIT_FAILURE;
+ }
+}/*}}}*/
+
+static gboolean wm_supports (Display *disp, const gchar *prop) {/*{{{*/
+ Atom xa_prop = XInternAtom(disp, prop, False);
+ Atom *list;
+ unsigned long size;
+ int i;
+
+ if (! (list = (Atom *)get_property(disp, DefaultRootWindow(disp),
+ XA_ATOM, "_NET_SUPPORTED", &size))) {
+ p_verbose("Cannot get _NET_SUPPORTED property.\n");
+ return FALSE;
+ }
+
+ for (i = 0; i < size / sizeof(Atom); i++) {
+ if (list[i] == xa_prop) {
+ g_free(list);
+ return TRUE;
+ }
+ }
+
+ g_free(list);
+ return FALSE;
+}/*}}}*/
+
+static int window_move_resize (Display *disp, Window win, char *arg) {/*{{{*/
+ signed long grav, x, y, w, h;
+ unsigned long grflags;
+ const char *argerr = "The -e option expects a list of comma separated integers: \"gravity,X,Y,width,height\"\n";
+
+ if (!arg || strlen(arg) == 0) {
+ fputs(argerr, stderr);
+ return EXIT_FAILURE;
+ }
+
+ if (sscanf(arg, "%ld,%ld,%ld,%ld,%ld", &grav, &x, &y, &w, &h) != 5) {
+ fputs(argerr, stderr);
+ return EXIT_FAILURE;
+ }
+
+ if (grav < 0) {
+ fputs("Value of gravity mustn't be negative. Use zero to use the default gravity of the window.\n", stderr);
+ return EXIT_FAILURE;
+ }
+
+ grflags = grav;
+ if (x != -1) grflags |= (1 << 8);
+ if (y != -1) grflags |= (1 << 9);
+ if (w != -1) grflags |= (1 << 10);
+ if (h != -1) grflags |= (1 << 11);
+
+ p_verbose("grflags: %lu\n", grflags);
+
+ if (wm_supports(disp, "_NET_MOVERESIZE_WINDOW")){
+ return client_msg(disp, win, "_NET_MOVERESIZE_WINDOW",
+ grflags, (unsigned long)x, (unsigned long)y, (unsigned long)w, (unsigned long)h);
+ }
+ else {
+ p_verbose("WM doesn't support _NET_MOVERESIZE_WINDOW. Gravity will be ignored.\n");
+ if ((w < 1 || h < 1) && (x >= 0 && y >= 0)) {
+ XMoveWindow(disp, win, x, y);
+ }
+ else if ((x < 0 || y < 0) && (w >= 1 && h >= -1)) {
+ XResizeWindow(disp, win, w, h);
+ }
+ else if (x >= 0 && y >= 0 && w >= 1 && h >= 1) {
+ XMoveResizeWindow(disp, win, x, y, w, h);
+ }
+ return EXIT_SUCCESS;
+ }
+}/*}}}*/
+
+static int action_window (Display *disp, Window win, char mode) {/*{{{*/
+ p_verbose("Using window: 0x%.8lx\n", win);
+ switch (mode) {
+ case 'a':
+ return activate_window(disp, win, TRUE);
+
+ case 'c':
+ return close_window(disp, win);
+
+ case 'e':
+ /* resize/move the window around the desktop => -r -e */
+ return window_move_resize(disp, win, options.param);
+
+ case 'b':
+ /* change state of a window => -r -b */
+ return window_state(disp, win, options.param);
+
+ case 't':
+ /* move the window to the specified desktop => -r -t */
+ return window_to_desktop(disp, win, atoi(options.param));
+
+ case 'R':
+ /* move the window to the current desktop and activate it => -r */
+ if (window_to_desktop(disp, win, -1) == EXIT_SUCCESS) {
+ usleep(100000); /* 100 ms - make sure the WM has enough
+ time to move the window, before we activate it */
+ return activate_window(disp, win, FALSE);
+ }
+ else {
+ return EXIT_FAILURE;
+ }
+
+ case 'N': case 'I': case 'T':
+ window_set_title(disp, win, options.param, mode);
+ return EXIT_SUCCESS;
+
+ default:
+ fprintf(stderr, "Unknown action: '%c'\n", mode);
+ return EXIT_FAILURE;
+ }
+}/*}}}*/
+
+static int action_window_pid (Display *disp, char mode) {/*{{{*/
+ unsigned long wid;
+
+ if (sscanf(options.param_window, "0x%lx", &wid) != 1 &&
+ sscanf(options.param_window, "0X%lx", &wid) != 1 &&
+ sscanf(options.param_window, "%lu", &wid) != 1) {
+ fputs("Cannot convert argument to number.\n", stderr);
+ return EXIT_FAILURE;
+ }
+
+ return action_window(disp, (Window)wid, mode);
+}/*}}}*/
+
+static int action_window_str (Display *disp, char mode) {/*{{{*/
+ Window activate = 0;
+ Window *client_list;
+ unsigned long client_list_size;
+ int i;
+
+ if (strcmp(SELECT_WINDOW_MAGIC, options.param_window) == 0) {
+ activate = Select_Window(disp);
+ if (activate) {
+ return action_window(disp, activate, mode);
+ }
+ else {
+ return EXIT_FAILURE;
+ }
+ }
+ if (strcmp(ACTIVE_WINDOW_MAGIC, options.param_window) == 0) {
+ activate = get_active_window(disp);
+ if (activate)
+ {
+ return action_window(disp, activate, mode);
+ }
+ else
+ {
+ return EXIT_FAILURE;
+ }
+ }
+ else {
+ if ((client_list = get_client_list(disp, &client_list_size)) == NULL) {
+ return EXIT_FAILURE;
+ }
+
+ for (i = 0; i < client_list_size / sizeof(Window); i++) {
+ gchar *match_utf8;
+ if (options.show_class) {
+ match_utf8 = get_window_class(disp, client_list[i]); /* UTF8 */
+ }
+ else {
+ match_utf8 = get_window_title(disp, client_list[i]); /* UTF8 */
+ }
+ if (match_utf8) {
+ gchar *match;
+ gchar *match_cf;
+ gchar *match_utf8_cf = NULL;
+ if (envir_utf8) {
+ match = g_strdup(options.param_window);
+ match_cf = g_utf8_casefold(options.param_window, -1);
+ }
+ else {
+ if (! (match = g_locale_to_utf8(options.param_window, -1, NULL, NULL, NULL))) {
+ match = g_strdup(options.param_window);
+ }
+ match_cf = g_utf8_casefold(match, -1);
+ }
+
+ if (!match || !match_cf) {
+ continue;
+ }
+
+ match_utf8_cf = g_utf8_casefold(match_utf8, -1);
+
+ if ((options.full_window_title_match && strcmp(match_utf8, match) == 0) ||
+ (!options.full_window_title_match && strstr(match_utf8_cf, match_cf))) {
+ activate = client_list[i];
+ g_free(match);
+ g_free(match_cf);
+ g_free(match_utf8);
+ g_free(match_utf8_cf);
+ break;
+ }
+ g_free(match);
+ g_free(match_cf);
+ g_free(match_utf8);
+ g_free(match_utf8_cf);
+ }
+ }
+ g_free(client_list);
+
+ if (activate) {
+ return action_window(disp, activate, mode);
+ }
+ else {
+ return EXIT_FAILURE;
+ }
+ }
+}/*}}}*/
+
+static int list_desktops (Display *disp) {/*{{{*/
+ unsigned long *num_desktops = NULL;
+ unsigned long *cur_desktop = NULL;
+ unsigned long desktop_list_size = 0;
+ unsigned long *desktop_geometry = NULL;
+ unsigned long desktop_geometry_size = 0;
+ gchar **desktop_geometry_str = NULL;
+ unsigned long *desktop_viewport = NULL;
+ unsigned long desktop_viewport_size = 0;
+ gchar **desktop_viewport_str = NULL;
+ unsigned long *desktop_workarea = NULL;
+ unsigned long desktop_workarea_size = 0;
+ gchar **desktop_workarea_str = NULL;
+ gchar *list = NULL;
+ int i;
+ int id;
+ Window root = DefaultRootWindow(disp);
+ int ret = EXIT_FAILURE;
+ gchar **names = NULL;
+ gboolean names_are_utf8 = TRUE;
+
+ if (! (num_desktops = (unsigned long *)get_property(disp, root,
+ XA_CARDINAL, "_NET_NUMBER_OF_DESKTOPS", NULL))) {
+ if (! (num_desktops = (unsigned long *)get_property(disp, root,
+ XA_CARDINAL, "_WIN_WORKSPACE_COUNT", NULL))) {
+ fputs("Cannot get number of desktops properties. "
+ "(_NET_NUMBER_OF_DESKTOPS or _WIN_WORKSPACE_COUNT)"
+ "\n", stderr);
+ goto cleanup;
+ }
+ }
+
+ if (! (cur_desktop = (unsigned long *)get_property(disp, root,
+ XA_CARDINAL, "_NET_CURRENT_DESKTOP", NULL))) {
+ if (! (cur_desktop = (unsigned long *)get_property(disp, root,
+ XA_CARDINAL, "_WIN_WORKSPACE", NULL))) {
+ fputs("Cannot get current desktop properties. "
+ "(_NET_CURRENT_DESKTOP or _WIN_WORKSPACE property)"
+ "\n", stderr);
+ goto cleanup;
+ }
+ }
+
+ if (options.wa_desktop_titles_invalid_utf8 ||
+ (list = get_property(disp, root,
+ XInternAtom(disp, "UTF8_STRING", False),
+ "_NET_DESKTOP_NAMES", &desktop_list_size)) == NULL) {
+ names_are_utf8 = FALSE;
+ if ((list = get_property(disp, root,
+ XA_STRING,
+ "_WIN_WORKSPACE_NAMES", &desktop_list_size)) == NULL) {
+ p_verbose("Cannot get desktop names properties. "
+ "(_NET_DESKTOP_NAMES or _WIN_WORKSPACE_NAMES)"
+ "\n");
+ /* ignore the error - list the desktops without names */
+ }
+ }
+
+ /* common size of all desktops */
+ if (! (desktop_geometry = (unsigned long *)get_property(disp, DefaultRootWindow(disp),
+ XA_CARDINAL, "_NET_DESKTOP_GEOMETRY", &desktop_geometry_size))) {
+ p_verbose("Cannot get common size of all desktops (_NET_DESKTOP_GEOMETRY).\n");
+ }
+
+ /* desktop viewport */
+ if (! (desktop_viewport = (unsigned long *)get_property(disp, DefaultRootWindow(disp),
+ XA_CARDINAL, "_NET_DESKTOP_VIEWPORT", &desktop_viewport_size))) {
+ p_verbose("Cannot get common size of all desktops (_NET_DESKTOP_VIEWPORT).\n");
+ }
+
+ /* desktop workarea */
+ if (! (desktop_workarea = (unsigned long *)get_property(disp, DefaultRootWindow(disp),
+ XA_CARDINAL, "_NET_WORKAREA", &desktop_workarea_size))) {
+ if (! (desktop_workarea = (unsigned long *)get_property(disp, DefaultRootWindow(disp),
+ XA_CARDINAL, "_WIN_WORKAREA", &desktop_workarea_size))) {
+ p_verbose("Cannot get _NET_WORKAREA property.\n");
+ }
+ }
+
+ /* prepare the array of desktop names */
+ names = g_malloc0(*num_desktops * sizeof(char *));
+ if (list) {
+ id = 0;
+ names[id++] = list;
+ for (i = 0; i < desktop_list_size; i++) {
+ if (list[i] == '\0') {
+ if (id >= *num_desktops) {
+ break;
+ }
+ names[id++] = list + i + 1;
+ }
+ }
+ }
+
+ /* prepare desktop geometry strings */
+ desktop_geometry_str = g_malloc0((*num_desktops + 1) * sizeof(char *));
+ if (desktop_geometry && desktop_geometry_size > 0) {
+ if (desktop_geometry_size == 2 * sizeof(*desktop_geometry)) {
+ /* only one value - use it for all desktops */
+ p_verbose("WM provides _NET_DESKTOP_GEOMETRY value common for all desktops.\n");
+ for (i = 0; i < *num_desktops; i++) {
+ desktop_geometry_str[i] = g_strdup_printf("%lux%lu",
+ desktop_geometry[0], desktop_geometry[1]);
+ }
+ }
+ else {
+ /* seperate values for desktops of different size */
+ p_verbose("WM provides separate _NET_DESKTOP_GEOMETRY value for each desktop.\n");
+ for (i = 0; i < *num_desktops; i++) {
+ if (i < desktop_geometry_size / sizeof(*desktop_geometry) / 2) {
+ desktop_geometry_str[i] = g_strdup_printf("%lux%lu",
+ desktop_geometry[i*2], desktop_geometry[i*2+1]);
+ }
+ else {
+ desktop_geometry_str[i] = g_strdup("N/A");
+ }
+ }
+ }
+ }
+ else {
+ for (i = 0; i < *num_desktops; i++) {
+ desktop_geometry_str[i] = g_strdup("N/A");
+ }
+ }
+
+ /* prepare desktop viewport strings */
+ desktop_viewport_str = g_malloc0((*num_desktops + 1) * sizeof(char *));
+ if (desktop_viewport && desktop_viewport_size > 0) {
+ if (desktop_viewport_size == 2 * sizeof(*desktop_viewport)) {
+ /* only one value - use it for current desktop */
+ p_verbose("WM provides _NET_DESKTOP_VIEWPORT value only for the current desktop.\n");
+ for (i = 0; i < *num_desktops; i++) {
+ if (i == *cur_desktop) {
+ desktop_viewport_str[i] = g_strdup_printf("%lu,%lu",
+ desktop_viewport[0], desktop_viewport[1]);
+ }
+ else {
+ desktop_viewport_str[i] = g_strdup("N/A");
+ }
+ }
+ }
+ else {
+ /* seperate values for each of desktops */
+ for (i = 0; i < *num_desktops; i++) {
+ if (i < desktop_viewport_size / sizeof(*desktop_viewport) / 2) {
+ desktop_viewport_str[i] = g_strdup_printf("%lu,%lu",
+ desktop_viewport[i*2], desktop_viewport[i*2+1]);
+ }
+ else {
+ desktop_viewport_str[i] = g_strdup("N/A");
+ }
+ }
+ }
+ }
+ else {
+ for (i = 0; i < *num_desktops; i++) {
+ desktop_viewport_str[i] = g_strdup("N/A");
+ }
+ }
+
+ /* prepare desktop workarea strings */
+ desktop_workarea_str = g_malloc0((*num_desktops + 1) * sizeof(char *));
+ if (desktop_workarea && desktop_workarea_size > 0) {
+ if (desktop_workarea_size == 4 * sizeof(*desktop_workarea)) {
+ /* only one value - use it for current desktop */
+ p_verbose("WM provides _NET_WORKAREA value only for the current desktop.\n");
+ for (i = 0; i < *num_desktops; i++) {
+ if (i == *cur_desktop) {
+ desktop_workarea_str[i] = g_strdup_printf("%lu,%lu %lux%lu",
+ desktop_workarea[0], desktop_workarea[1],
+ desktop_workarea[2], desktop_workarea[3]);
+ }
+ else {
+ desktop_workarea_str[i] = g_strdup("N/A");
+ }
+ }
+ }
+ else {
+ /* seperate values for each of desktops */
+ for (i = 0; i < *num_desktops; i++) {
+ if (i < desktop_workarea_size / sizeof(*desktop_workarea) / 4) {
+ desktop_workarea_str[i] = g_strdup_printf("%lu,%lu %lux%lu",
+ desktop_workarea[i*4], desktop_workarea[i*4+1],
+ desktop_workarea[i*4+2], desktop_workarea[i*4+3]);
+ }
+ else {
+ desktop_workarea_str[i] = g_strdup("N/A");
+ }
+ }
+ }
+ }
+ else {
+ for (i = 0; i < *num_desktops; i++) {
+ desktop_workarea_str[i] = g_strdup("N/A");
+ }
+ }
+
+ /* print the list */
+ for (i = 0; i < *num_desktops; i++) {
+ gchar *out = get_output_str(names[i], names_are_utf8);
+ printf("%-2d %c DG: %-*s VP: %-*s WA: %-*s %s\n", i, i == *cur_desktop ? '*' : '-',
+ longest_str(desktop_geometry_str), desktop_geometry_str[i],
+ longest_str(desktop_viewport_str), desktop_viewport_str[i],
+ longest_str(desktop_workarea_str), desktop_workarea_str[i],
+ out ? out : "N/A");
+ g_free(out);
+ }
+
+ p_verbose("Total number of desktops: %lu\n", *num_desktops);
+ p_verbose("Current desktop ID (counted from zero): %lu\n", *cur_desktop);
+
+ ret = EXIT_SUCCESS;
+ goto cleanup;
+
+cleanup:
+ g_free(names);
+ g_free(num_desktops);
+ g_free(cur_desktop);
+ g_free(desktop_geometry);
+ g_strfreev(desktop_geometry_str);
+ g_free(desktop_viewport);
+ g_strfreev(desktop_viewport_str);
+ g_free(desktop_workarea);
+ g_strfreev(desktop_workarea_str);
+ g_free(list);
+
+ return ret;
+}/*}}}*/
+
+static int longest_str (gchar **strv) {/*{{{*/
+ int max = 0;
+ int i = 0;
+
+ while (strv && strv[i]) {
+ if (strlen(strv[i]) > max) {
+ max = strlen(strv[i]);
+ }
+ i++;
+ }
+
+ return max;
+}/*}}}*/
+
+static Window *get_client_list (Display *disp, unsigned long *size) {/*{{{*/
+ Window *client_list;
+
+ if ((client_list = (Window *)get_property(disp, DefaultRootWindow(disp),
+ XA_WINDOW, "_NET_CLIENT_LIST", size)) == NULL) {
+ if ((client_list = (Window *)get_property(disp, DefaultRootWindow(disp),
+ XA_CARDINAL, "_WIN_CLIENT_LIST", size)) == NULL) {
+ fputs("Cannot get client list properties. \n"
+ "(_NET_CLIENT_LIST or _WIN_CLIENT_LIST)"
+ "\n", stderr);
+ return NULL;
+ }
+ }
+
+ return client_list;
+}/*}}}*/
+
+static int list_windows (Display *disp) {/*{{{*/
+ Window *client_list;
+ unsigned long client_list_size;
+ int i;
+ int max_client_machine_len = 0;
+
+ if ((client_list = get_client_list(disp, &client_list_size)) == NULL) {
+ return EXIT_FAILURE;
+ }
+
+ /* find the longest client_machine name */
+ for (i = 0; i < client_list_size / sizeof(Window); i++) {
+ gchar *client_machine;
+ if ((client_machine = get_property(disp, client_list[i],
+ XA_STRING, "WM_CLIENT_MACHINE", NULL))) {
+ max_client_machine_len = strlen(client_machine);
+ }
+ g_free(client_machine);
+ }
+
+ /* print the list */
+ for (i = 0; i < client_list_size / sizeof(Window); i++) {
+ gchar *title_utf8 = get_window_title(disp, client_list[i]); /* UTF8 */
+ gchar *title_out = get_output_str(title_utf8, TRUE);
+ gchar *client_machine;
+ gchar *class_out = get_window_class(disp, client_list[i]); /* UTF8 */
+ unsigned long *pid;
+ unsigned long *desktop;
+ int x, y, junkx, junky;
+ unsigned int wwidth, wheight, bw, depth;
+ Window junkroot;
+
+ /* desktop ID */
+ if ((desktop = (unsigned long *)get_property(disp, client_list[i],
+ XA_CARDINAL, "_NET_WM_DESKTOP", NULL)) == NULL) {
+ desktop = (unsigned long *)get_property(disp, client_list[i],
+ XA_CARDINAL, "_WIN_WORKSPACE", NULL);
+ }
+
+ /* client machine */
+ client_machine = get_property(disp, client_list[i],
+ XA_STRING, "WM_CLIENT_MACHINE", NULL);
+
+ /* pid */
+ pid = (unsigned long *)get_property(disp, client_list[i],
+ XA_CARDINAL, "_NET_WM_PID", NULL);
+
+ /* geometry */
+ XGetGeometry (disp, client_list[i], &junkroot, &junkx, &junky,
+ &wwidth, &wheight, &bw, &depth);
+ XTranslateCoordinates (disp, client_list[i], junkroot, junkx, junky,
+ &x, &y, &junkroot);
+
+ /* special desktop ID -1 means "all desktops", so we
+ have to convert the desktop value to signed long */
+ printf("0x%.8lx %2ld", client_list[i],
+ desktop ? (signed long)*desktop : 0);
+ if (options.show_pid) {
+ printf(" %-6lu", pid ? *pid : 0);
+ }
+ if (options.show_geometry) {
+ printf(" %-4d %-4d %-4d %-4d", x, y, wwidth, wheight);
+ }
+ if (options.show_class) {
+ printf(" %-20s ", class_out ? class_out : "N/A");
+ }
+
+ printf(" %*s %s\n",
+ max_client_machine_len,
+ client_machine ? client_machine : "N/A",
+ title_out ? title_out : "N/A"
+ );
+ g_free(title_utf8);
+ g_free(title_out);
+ g_free(desktop);
+ g_free(client_machine);
+ g_free(class_out);
+ g_free(pid);
+ }
+ g_free(client_list);
+
+ return EXIT_SUCCESS;
+}/*}}}*/
+
+static gchar *get_window_class (Display *disp, Window win) {/*{{{*/
+ gchar *class_utf8;
+ gchar *wm_class;
+ unsigned long size;
+
+ wm_class = get_property(disp, win, XA_STRING, "WM_CLASS", &size);
+ if (wm_class) {
+ gchar *p_0 = strchr(wm_class, '\0');
+ if (wm_class + size - 1 > p_0) {
+ *(p_0) = '.';
+ }
+ class_utf8 = g_locale_to_utf8(wm_class, -1, NULL, NULL, NULL);
+ }
+ else {
+ class_utf8 = NULL;
+ }
+
+ g_free(wm_class);
+
+ return class_utf8;
+}/*}}}*/
+
+static gchar *get_window_title (Display *disp, Window win) {/*{{{*/
+ gchar *title_utf8;
+ gchar *wm_name;
+ gchar *net_wm_name;
+
+ wm_name = get_property(disp, win, XA_STRING, "WM_NAME", NULL);
+ net_wm_name = get_property(disp, win,
+ XInternAtom(disp, "UTF8_STRING", False), "_NET_WM_NAME", NULL);
+
+ if (net_wm_name) {
+ title_utf8 = g_strdup(net_wm_name);
+ }
+ else {
+ if (wm_name) {
+ title_utf8 = g_locale_to_utf8(wm_name, -1, NULL, NULL, NULL);
+ }
+ else {
+ title_utf8 = NULL;
+ }
+ }
+
+ g_free(wm_name);
+ g_free(net_wm_name);
+
+ return title_utf8;
+}/*}}}*/
+
+static gchar *get_property (Display *disp, Window win, /*{{{*/
+ Atom xa_prop_type, gchar *prop_name, unsigned long *size) {
+ Atom xa_prop_name;
+ Atom xa_ret_type;
+ int ret_format;
+ unsigned long ret_nitems;
+ unsigned long ret_bytes_after;
+ unsigned long tmp_size;
+ unsigned char *ret_prop;
+ gchar *ret;
+
+ xa_prop_name = XInternAtom(disp, prop_name, False);
+
+ /* MAX_PROPERTY_VALUE_LEN / 4 explanation (XGetWindowProperty manpage):
+ *
+ * long_length = Specifies the length in 32-bit multiples of the
+ * data to be retrieved.
+ */
+ if (XGetWindowProperty(disp, win, xa_prop_name, 0, MAX_PROPERTY_VALUE_LEN / 4, False,
+ xa_prop_type, &xa_ret_type, &ret_format,
+ &ret_nitems, &ret_bytes_after, &ret_prop) != Success) {
+ p_verbose("Cannot get %s property.\n", prop_name);
+ return NULL;
+ }
+
+ if (xa_ret_type != xa_prop_type) {
+ p_verbose("Invalid type of %s property.\n", prop_name);
+ XFree(ret_prop);
+ return NULL;
+ }
+
+ /* null terminate the result to make string handling easier */
+ tmp_size = (ret_format / 8) * ret_nitems;
+ ret = g_malloc(tmp_size + 1);
+ memcpy(ret, ret_prop, tmp_size);
+ ret[tmp_size] = '\0';
+
+ if (size) {
+ *size = tmp_size;
+ }
+
+ XFree(ret_prop);
+ return ret;
+}/*}}}*/
+
+static Window Select_Window(Display *dpy) {/*{{{*/
+ /*
+ * Routine to let user select a window using the mouse
+ * Taken from xfree86.
+ */
+
+ int status;
+ Cursor cursor;
+ XEvent event;
+ Window target_win = None, root = DefaultRootWindow(dpy);
+ int buttons = 0;
+ int dummyi;
+ unsigned int dummy;
+
+ /* Make the target cursor */
+ cursor = XCreateFontCursor(dpy, XC_crosshair);
+
+ /* Grab the pointer using target cursor, letting it room all over */
+ status = XGrabPointer(dpy, root, False,
+ ButtonPressMask|ButtonReleaseMask, GrabModeSync,
+ GrabModeAsync, root, cursor, CurrentTime);
+ if (status != GrabSuccess) {
+ fputs("ERROR: Cannot grab mouse.\n", stderr);
+ return 0;
+ }
+
+ /* Let the user select a window... */
+ while ((target_win == None) || (buttons != 0)) {
+ /* allow one more event */
+ XAllowEvents(dpy, SyncPointer, CurrentTime);
+ XWindowEvent(dpy, root, ButtonPressMask|ButtonReleaseMask, &event);
+ switch (event.type) {
+ case ButtonPress:
+ if (target_win == None) {
+ target_win = event.xbutton.subwindow; /* window selected */
+ if (target_win == None) target_win = root;
+ }
+ buttons++;
+ break;
+ case ButtonRelease:
+ if (buttons > 0) /* there may have been some down before we started */
+ buttons--;
+ break;
+ }
+ }
+
+ XUngrabPointer(dpy, CurrentTime); /* Done with pointer */
+
+ if (XGetGeometry (dpy, target_win, &root, &dummyi, &dummyi,
+ &dummy, &dummy, &dummy, &dummy) && target_win != root) {
+ target_win = XmuClientWindow (dpy, target_win);
+ }
+
+ return(target_win);
+}/*}}}*/
+
+static Window get_active_window(Display *disp) {/*{{{*/
+ char *prop;
+ unsigned long size;
+ Window ret = (Window)0;
+
+ prop = get_property(disp, DefaultRootWindow(disp), XA_WINDOW,
+ "_NET_ACTIVE_WINDOW", &size);
+ if (prop) {
+ ret = *((Window*)prop);
+ g_free(prop);
+ }
+
+ return(ret);
+}/*}}}*/
+
+
diff --git a/navit/gui/sdl/wmcontrol.h b/navit/gui/sdl/wmcontrol.h
new file mode 100644
index 000000000..224dae56e
--- /dev/null
+++ b/navit/gui/sdl/wmcontrol.h
@@ -0,0 +1,7 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+int window_switch(const char *windowName);
+#ifdef __cplusplus
+}
+#endif
diff --git a/navit/item.c b/navit/item.c
new file mode 100644
index 000000000..52b6a2389
--- /dev/null
+++ b/navit/item.c
@@ -0,0 +1,153 @@
+#include <string.h>
+#include <glib.h>
+#include "coord.h"
+#include "debug.h"
+#include "item.h"
+
+struct item_name {
+ enum item_type item;
+ char *name;
+};
+
+
+struct item_name item_names[]={
+#define ITEM2(x,y) ITEM(y)
+#define ITEM(x) { type_##x, #x },
+#include "item_def.h"
+#undef ITEM2
+#undef ITEM
+};
+
+void
+item_coord_rewind(struct item *it)
+{
+ it->meth->item_coord_rewind(it->priv_data);
+}
+
+int
+item_coord_get(struct item *it, struct coord *c, int count)
+{
+ return it->meth->item_coord_get(it->priv_data, c, count);
+}
+
+int
+item_coord_is_segment(struct item *it)
+{
+ if (it->meth->item_coord_is_segment)
+ return it->meth->item_coord_is_segment(it->priv_data);
+ return 0;
+}
+
+void
+item_attr_rewind(struct item *it)
+{
+ it->meth->item_attr_rewind(it->priv_data);
+}
+int
+item_attr_get(struct item *it, enum attr_type attr_type, struct attr *attr)
+{
+ return it->meth->item_attr_get(it->priv_data, attr_type, attr);
+}
+
+struct item * item_new(char *type, int zoom)
+{
+ struct item * it;
+
+ it = g_new0(struct item, 1);
+
+ /* FIXME evaluate arguments */
+
+ return it;
+}
+
+enum item_type
+item_from_name(const char *name)
+{
+ int i;
+
+ for (i=0 ; i < sizeof(item_names)/sizeof(struct item_name) ; i++) {
+ if (! strcmp(item_names[i].name, name))
+ return item_names[i].item;
+ }
+ return type_none;
+}
+
+char *
+item_to_name(enum item_type item)
+{
+ int i;
+
+ for (i=0 ; i < sizeof(item_names)/sizeof(struct item_name) ; i++) {
+ if (item_names[i].item == item)
+ return item_names[i].name;
+ }
+ return NULL;
+}
+
+struct item_hash {
+ GHashTable *h;
+};
+
+static guint
+item_hash_hash(gconstpointer key)
+{
+ const struct item *itm=key;
+ gconstpointer hashkey=(gconstpointer)(itm->id_hi^itm->id_lo^((int) itm->map));
+ return g_direct_hash(hashkey);
+}
+
+static gboolean
+item_hash_equal(gconstpointer a, gconstpointer b)
+{
+ const struct item *itm_a=a;
+ const struct item *itm_b=b;
+ if (item_is_equal(*itm_a, *itm_b))
+ return TRUE;
+ return FALSE;
+}
+
+
+
+struct item_hash *
+item_hash_new(void)
+{
+ struct item_hash *ret=g_new(struct item_hash, 1);
+
+ ret->h=g_hash_table_new_full(item_hash_hash, item_hash_equal, g_free, NULL);
+ return ret;
+}
+
+void
+item_hash_insert(struct item_hash *h, struct item *item, void *val)
+{
+ struct item *hitem=g_new(struct item, 1);
+ *hitem=*item;
+ dbg(2,"inserting (0x%x,0x%x) into %p\n", item->id_hi, item->id_lo, h->h);
+ g_hash_table_insert(h->h, hitem, val);
+}
+
+int
+item_hash_remove(struct item_hash *h, struct item *item)
+{
+ int ret;
+
+ dbg(2,"removing (0x%x,0x%x) from %p\n", item->id_hi, item->id_lo, h->h);
+ ret=g_hash_table_remove(h->h, item);
+ dbg(2,"ret=%d\n", ret);
+
+ return ret;
+}
+
+void *
+item_hash_lookup(struct item_hash *h, struct item *item)
+{
+ return g_hash_table_lookup(h->h, item);
+}
+
+
+void
+item_hash_destroy(struct item_hash *h)
+{
+ g_hash_table_destroy(h->h);
+ g_free(h);
+}
diff --git a/navit/item.h b/navit/item.h
new file mode 100644
index 000000000..448df2ecf
--- /dev/null
+++ b/navit/item.h
@@ -0,0 +1,70 @@
+#ifndef NAVIT_ITEM_H
+#define NAVIT_ITEM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum item_type {
+#define ITEM2(x,y) type_##y=x,
+#define ITEM(x) type_##x,
+#include "item_def.h"
+#undef ITEM2
+#undef ITEM
+};
+
+#include "attr.h"
+
+#define item_is_equal_id(a,b) ((a).id_hi == (b).id_hi && (a).id_lo == (b).id_lo)
+#define item_is_equal(a,b) (item_is_equal_id(a,b) && (a).map == (b).map)
+
+struct coord;
+
+struct item_methods {
+ void (*item_coord_rewind)(void *priv_data);
+ int (*item_coord_get)(void *priv_data, struct coord *c, int count);
+ void (*item_attr_rewind)(void *priv_data);
+ int (*item_attr_get)(void *priv_data, enum attr_type attr_type, struct attr *attr);
+ int (*item_coord_is_segment)(void *priv_data);
+};
+
+struct item {
+ enum item_type type;
+ int id_hi;
+ int id_lo;
+ struct map *map;
+ struct item_methods *meth;
+ void *priv_data;
+};
+
+/* prototypes */
+enum attr_type;
+enum item_type;
+struct attr;
+struct coord;
+struct item;
+struct item_hash;
+void item_coord_rewind(struct item *it);
+int item_coord_get(struct item *it, struct coord *c, int count);
+/* does the next returned coordinate mark a segment */
+int item_coord_is_segment(struct item *it);
+void item_attr_rewind(struct item *it);
+int item_attr_get(struct item *it, enum attr_type attr_type, struct attr *attr);
+struct item *item_new(char *type, int zoom);
+enum item_type item_from_name(const char *name);
+char *item_to_name(enum item_type item);
+struct item_hash *item_hash_new(void);
+void item_hash_insert(struct item_hash *h, struct item *item, void *val);
+int item_hash_remove(struct item_hash *h, struct item *item);
+void *item_hash_lookup(struct item_hash *h, struct item *item);
+void item_hash_destroy(struct item_hash *h);
+/* end of prototypes */
+
+
+#ifdef __cplusplus
+}
+/* __cplusplus */
+#endif
+
+/* NAVIT_ITEM_H */
+#endif
diff --git a/navit/item_def.h b/navit/item_def.h
new file mode 100644
index 000000000..add503407
--- /dev/null
+++ b/navit/item_def.h
@@ -0,0 +1,406 @@
+/* This file is generated from http://wiki.navit-project.org/index.php/Item_def.h, do not edit it, edit the wiki page instead */
+ITEM2(0x00000000,none)
+ITEM2(0x00000001,point_unspecified)
+ITEM(town_streets)
+ITEM(street_name)
+ITEM(street_name_numbers)
+ITEM(street_number)
+/* Point */
+ITEM2(0x00010000,town_label)
+ITEM2(0x00010001,town_label_0e0)
+ITEM2(0x00010002,town_label_1e0)
+ITEM2(0x00010003,town_label_2e0)
+ITEM2(0x00010004,town_label_5e0)
+ITEM2(0x00010005,town_label_1e1)
+ITEM2(0x00010006,town_label_2e1)
+ITEM2(0x00010007,town_label_5e1)
+ITEM2(0x00010008,town_label_1e2)
+ITEM2(0x00010009,town_label_2e2)
+ITEM2(0x0001000a,town_label_5e2)
+ITEM2(0x0001000b,town_label_1e3)
+ITEM2(0x0001000c,town_label_2e3)
+ITEM2(0x0001000d,town_label_5e3)
+ITEM2(0x0001000e,town_label_1e4)
+ITEM2(0x0001000f,town_label_2e4)
+ITEM2(0x00010010,town_label_5e4)
+ITEM2(0x00010011,town_label_1e5)
+ITEM2(0x00010012,town_label_2e5)
+ITEM2(0x00010013,town_label_5e5)
+ITEM2(0x00010014,town_label_1e6)
+ITEM2(0x00010015,town_label_2e6)
+ITEM2(0x00010016,town_label_5e6)
+ITEM2(0x00010017,town_label_1e7)
+ITEM2(0x00010100,district_label)
+ITEM2(0x00010101,district_label_0e0)
+ITEM2(0x00010102,district_label_1e0)
+ITEM2(0x00010103,district_label_2e0)
+ITEM2(0x00010104,district_label_5e0)
+ITEM2(0x00010105,district_label_1e1)
+ITEM2(0x00010106,district_label_2e1)
+ITEM2(0x00010107,district_label_5e1)
+ITEM2(0x00010108,district_label_1e2)
+ITEM2(0x00010109,district_label_2e2)
+ITEM2(0x0001010a,district_label_5e2)
+ITEM2(0x0001010b,district_label_1e3)
+ITEM2(0x0001010c,district_label_2e3)
+ITEM2(0x0001010d,district_label_5e3)
+ITEM2(0x0001010e,district_label_1e4)
+ITEM2(0x0001010f,district_label_2e4)
+ITEM2(0x00010110,district_label_5e4)
+ITEM2(0x00010111,district_label_1e5)
+ITEM2(0x00010112,district_label_2e5)
+ITEM2(0x00010113,district_label_5e5)
+ITEM2(0x00010114,district_label_1e6)
+ITEM2(0x00010115,district_label_2e6)
+ITEM2(0x00010116,district_label_5e6)
+ITEM2(0x00010117,district_label_1e7)
+ITEM(country_label)
+ITEM(town_ghost)
+ITEM(highway_exit_label)
+ITEM(port_label)
+ITEM(label_unkn)
+ITEM(highway_exit)
+ITEM(poi_lake)
+ITEM(poi_island)
+ITEM(poi)
+ITEM(waypoint)
+ITEM(trackpoint)
+ITEM(bookmark)
+ITEM(former_destination)
+ITEM(poi_land_feature)
+ITEM(poi_cape)
+ITEM(poi_rock)
+ITEM(poi_airport)
+ITEM(poi_toll_booth)
+ITEM(poi_fuel)
+ITEM(poi_hotel)
+ITEM(poi_camp_rv)
+ITEM(poi_marina)
+ITEM(poi_attraction)
+ITEM(poi_museum_history)
+ITEM(poi_shopping)
+ITEM(poi_car_dealer_parts)
+ITEM(poi_car_parking)
+ITEM(poi_wreck)
+ITEM(poi_building)
+ITEM(poi_bridge)
+ITEM(poi_park)
+ITEM(poi_water_feature)
+ITEM(poi_bar)
+ITEM(poi_picnic)
+ITEM(poi_hospital)
+ITEM(poi_camping)
+ITEM(poi_public_utilities)
+ITEM(poi_burgerking)
+ITEM(poi_kfc)
+ITEM(poi_mcdonalds)
+ITEM(poi_wienerwald)
+ITEM(poi_dining)
+ITEM(poi_fastfood)
+ITEM(poi_police)
+ITEM(poi_auto_club)
+ITEM(poi_autoservice)
+ITEM(poi_bank)
+ITEM(poi_bay)
+ITEM(poi_bend)
+ITEM(poi_boat_ramp)
+ITEM(poi_border_station)
+ITEM(poi_bowling)
+ITEM(poi_bus_station)
+ITEM(poi_bus_stop)
+ITEM(poi_bussines_service)
+ITEM(poi_car_rent)
+ITEM(poi_car_wash)
+ITEM(poi_casino)
+ITEM(poi_cemetery)
+ITEM(poi_church)
+ITEM(poi_cinema)
+ITEM(poi_civil)
+ITEM(poi_communication)
+ITEM(poi_concert)
+ITEM(poi_cove)
+ITEM(poi_crossing)
+ITEM(poi_dam)
+ITEM(poi_danger_area)
+ITEM(poi_dangerous)
+ITEM(poi_daymark)
+ITEM(poi_diving)
+ITEM(poi_drinking_water)
+ITEM(poi_emergency)
+ITEM(poi_fair)
+ITEM(poi_firebrigade)
+ITEM(poi_fish)
+ITEM(poi_forbiden_area)
+ITEM(poi_garmin)
+ITEM(poi_golf)
+ITEM(poi_goverment_building)
+ITEM(poi_height)
+ITEM(poi_heliport)
+ITEM(poi_hotspring)
+ITEM(poi_icesport)
+ITEM(poi_information)
+ITEM(poi_justice)
+ITEM(poi_landmark)
+ITEM(poi_levee)
+ITEM(poi_library)
+ITEM(poi_locale)
+ITEM(poi_loudspeaker)
+ITEM(poi_mall)
+ITEM(poi_manmade_feature)
+ITEM(poi_marine)
+ITEM(poi_marine_type)
+ITEM(poi_mark)
+ITEM(poi_military)
+ITEM(poi_mine)
+ITEM(poi_nondangerous)
+ITEM(poi_oil_field)
+ITEM(poi_personal_service)
+ITEM(poi_pharmacy)
+ITEM(poi_post)
+ITEM(poi_public_office)
+ITEM(poi_repair_service)
+ITEM(poi_resort)
+ITEM(poi_rest_room)
+ITEM(poi_restaurant)
+ITEM(poi_restricted_area)
+ITEM(poi_restroom)
+ITEM(poi_sailing)
+ITEM(poi_scenic_area)
+ITEM(poi_school)
+ITEM(poi_service)
+ITEM(poi_shop_apparel)
+ITEM(poi_shop_computer)
+ITEM(poi_shop_department)
+ITEM(poi_shop_furnish)
+ITEM(poi_shop_grocery)
+ITEM(poi_shop_handg)
+ITEM(poi_shop_merchandise)
+ITEM(poi_shop_retail)
+ITEM(poi_shower)
+ITEM(poi_skiing)
+ITEM(poi_social_service)
+ITEM(poi_sounding)
+ITEM(poi_sport)
+ITEM(poi_stadium)
+ITEM(poi_subdivision)
+ITEM(poi_swimming)
+ITEM(poi_telephone)
+ITEM(poi_theater)
+ITEM(poi_tide)
+ITEM(poi_tower)
+ITEM(poi_trail)
+ITEM(poi_truck_stop)
+ITEM(poi_tunnel)
+ITEM(poi_wine)
+ITEM(poi_worship)
+ITEM(poi_wrecker)
+ITEM(poi_zoo)
+ITEM(rg_point)
+ITEM(point_unkn)
+ITEM(traffic_signals)
+ITEM(poi_gc_multi)
+ITEM(poi_gc_tradi)
+ITEM(poi_gc_event)
+ITEM(poi_gc_mystery)
+ITEM(poi_gc_question)
+ITEM(poi_gc_stages)
+ITEM(poi_gc_reference)
+ITEM(poi_gc_webcam)
+ITEM(poi_cafe)
+ITEM(nav_straight)
+ITEM(nav_turnaround)
+ITEM(nav_right_1)
+ITEM(nav_right_2)
+ITEM(nav_right_3)
+ITEM(nav_left_1)
+ITEM(nav_left_2)
+ITEM(nav_left_3)
+ITEM(nav_roundabout_r1)
+ITEM(nav_roundabout_r2)
+ITEM(nav_roundabout_r3)
+ITEM(nav_roundabout_r4)
+ITEM(nav_roundabout_r5)
+ITEM(nav_roundabout_r6)
+ITEM(nav_roundabout_r7)
+ITEM(nav_roundabout_r8)
+ITEM(nav_roundabout_l1)
+ITEM(nav_roundabout_l2)
+ITEM(nav_roundabout_l3)
+ITEM(nav_roundabout_l4)
+ITEM(nav_roundabout_l5)
+ITEM(nav_roundabout_l6)
+ITEM(nav_roundabout_l7)
+ITEM(nav_roundabout_l8)
+ITEM(poi_peak)
+ITEM(poi_rail_station)
+ITEM(poi_image)
+ITEM(mini_roundabout)
+ITEM(turning_circle)
+ITEM(poi_townhall)
+ITEM(poi_level_crossing)
+ITEM(poi_rail_halt)
+ITEM(poi_rail_tram_stop)
+/* Line */
+ITEM2(0x80000000,line)
+ITEM2(0x80000001,line_unspecified)
+ITEM(border_country)
+ITEM(border_state)
+ITEM(rail)
+ITEM(water_line)
+ITEM(street_nopass)
+ITEM(street_0)
+ITEM(street_1_city)
+ITEM(street_2_city)
+ITEM(street_3_city)
+ITEM(street_4_city)
+ITEM(highway_city)
+ITEM(street_1_land)
+ITEM(street_2_land)
+ITEM(street_3_land)
+ITEM(street_4_land)
+ITEM(street_n_lanes)
+ITEM(highway_land)
+ITEM(ramp)
+ITEM(ferry)
+ITEM(roadbook)
+ITEM(street_unkn)
+ITEM(street_route)
+ITEM(height_line_1)
+ITEM(height_line_2)
+ITEM(track)
+ITEM(height_line_3)
+ITEM(depth_line_1)
+ITEM(depth_line_2)
+ITEM(depth_line_3)
+ITEM(powerline)
+ITEM(pipeline)
+ITEM(time_zone)
+ITEM(marine_boundary)
+ITEM(marine_hazard)
+ITEM(roundabout)
+ITEM(rg_segment)
+ITEM(aeroway_runway)
+ITEM(aeroway_taxiway)
+ITEM(street_service)
+ITEM(coverage)
+ITEM(street_pedestrian)
+ITEM(bridge)
+ITEM(tunnel)
+ITEM(bridleway)
+ITEM(cycleway)
+ITEM(footway)
+ITEM(steps)
+ITEM(track_paved)
+ITEM(track_gravelled)
+ITEM(track_unpaved)
+ITEM(track_ground)
+ITEM(track_grass)
+ITEM(rail_narrow_gauge)
+ITEM(rail_light)
+ITEM(rail_subway)
+ITEM(rail_mono)
+ITEM(rail_tram)
+ITEM(rail_preserved)
+ITEM(rail_disused)
+ITEM(rail_abandoned)
+ITEM(lift_cable_car)
+ITEM(lift_chair)
+ITEM(lift_drag)
+ITEM(living_street)
+ITEM(bus_guideway)
+ITEM(street_construction)
+ITEM(border_civil)
+ITEM(border_political)
+ITEM(border_national_park)
+ITEM(water_river)
+ITEM(water_canal)
+ITEM(water_stream)
+ITEM(water_drain)
+/* Area */
+ITEM2(0xc0000000,area)
+ITEM2(0xc0000001,area_unspecified)
+ITEM(poly_wood)
+ITEM(poly_water)
+ITEM(poly_town)
+ITEM(poly_cemetery)
+ITEM(poly_car_parking)
+ITEM(poly_industry)
+ITEM(poly_airport)
+ITEM(poly_hospital)
+ITEM(poly_park)
+ITEM(poly_sport)
+ITEM(poly_museum)
+ITEM(image)
+ITEM(image_path)
+ITEM(poly_commercial_center)
+ITEM(poly_golf_course)
+ITEM(poly_university)
+ITEM(poly_national_park)
+ITEM(poly_nature_park)
+ITEM(poly_flats)
+ITEM(poly_scrub)
+ITEM(poly_military_zone)
+ITEM(poly_marine)
+ITEM(plantation)
+ITEM(tundra)
+ITEM(tile)
+ITEM(submap)
+ITEM(poly_building)
+ITEM(poly_place)
+ITEM(poly_station)
+ITEM(poly_farm)
+ITEM(poly_sport_tennis)
+ITEM(poly_apron)
+ITEM(poly_terminal)
+ITEM(countryindex)
+ITEM(poly_sports_centre)
+ITEM(poly_sports_stadium)
+ITEM(poly_sports_track)
+ITEM(poly_sports_pitch)
+ITEM(poly_water_park)
+ITEM(poly_marina)
+ITEM(poly_fishing)
+ITEM(poly_theme_park)
+ITEM(poly_attraction)
+ITEM(poly_ruins)
+ITEM(poly_archaeological_site)
+ITEM(poly_artwork)
+ITEM(poly_zoo)
+ITEM(poly_camp_site)
+ITEM(poly_caravan_site)
+ITEM(poly_picnic_site)
+ITEM(poly_playground)
+ITEM(poly_allotments)
+ITEM(poly_village_green)
+ITEM(poly_recreation_ground)
+ITEM(poly_common)
+ITEM(poly_garden)
+ITEM(poly_nature_reserve)
+ITEM(poly_glacier)
+ITEM(poly_scree)
+ITEM(poly_fell)
+ITEM(poly_heath)
+ITEM(poly_marsh)
+ITEM(poly_mud)
+ITEM(poly_land)
+ITEM(poly_beach)
+ITEM(poly_quarry)
+ITEM(poly_landfill)
+ITEM(poly_retail)
+ITEM(poly_commercial)
+ITEM(poly_brownfield)
+ITEM(poly_greenfield)
+ITEM(poly_construction)
+ITEM(poly_railway)
+ITEM(poly_military)
+ITEM(poly_airfield)
+ITEM(poly_barracks)
+ITEM(poly_danger_area)
+ITEM(poly_range)
+ITEM(poly_naval_base)
+ITEM(poly_basin)
+ITEM(poly_reservoir)
+ITEM(poly_college)
+ITEM(poly_battlefield)
+ITEM(poly_pedestrian)
+ITEM(poly_plaza)
diff --git a/navit/layer.h b/navit/layer.h
new file mode 100644
index 000000000..4d602126f
--- /dev/null
+++ b/navit/layer.h
@@ -0,0 +1,12 @@
+#ifndef NAVIT_LAYER_H
+#define NAVIT_LAYER_H
+
+enum layer_type {
+ layer_town=0,
+ layer_street,
+ layer_poly,
+ layer_end,
+};
+
+#endif
+
diff --git a/navit/layout.c b/navit/layout.c
new file mode 100644
index 000000000..4b3d85cd8
--- /dev/null
+++ b/navit/layout.c
@@ -0,0 +1,139 @@
+#include <glib.h>
+#include <string.h>
+#include "layout.h"
+
+struct layout * layout_new(const char *name, struct color *color)
+{
+ struct layout *l;
+
+ l = g_new0(struct layout, 1);
+ l->name = g_strdup(name);
+ l->color = g_new0(struct color,1);
+ *(l->color) = *color;
+ return l;
+}
+
+
+struct layer * layer_new(const char *name, int details)
+{
+ struct layer *l;
+
+ l = g_new0(struct layer, 1);
+ l->name = g_strdup(name);
+ l->details = details;
+ return l;
+}
+
+void layout_add_layer(struct layout *layout, struct layer *layer)
+{
+ layout->layers = g_list_append(layout->layers, layer);
+}
+
+struct itemtype * itemtype_new(int order_min, int order_max)
+{
+ struct itemtype *itm;
+
+ itm = g_new0(struct itemtype, 1);
+ itm->order_min=order_min;
+ itm->order_max=order_max;
+ return itm;
+}
+
+void itemtype_add_type(struct itemtype *this, enum item_type type)
+{
+ this->type = g_list_append(this->type, GINT_TO_POINTER(type));
+}
+
+
+void layer_add_itemtype(struct layer *layer, struct itemtype * itemtype)
+{
+ layer->itemtypes = g_list_append(layer->itemtypes, itemtype);
+
+}
+
+void itemtype_add_element(struct itemtype *itemtype, struct element *element)
+{
+ itemtype->elements = g_list_append(itemtype->elements, element);
+}
+
+struct element *
+polygon_new(struct color *color)
+{
+ struct element *e;
+ e = g_new0(struct element, 1);
+ e->type=element_polygon;
+ e->color=*color;
+
+ return e;
+}
+
+struct element *
+polyline_new(struct color *color, int width, int directed,
+ int *dash_table, int dash_num)
+{
+ struct element *e;
+ int i;
+
+ e = g_new0(struct element, 1);
+ e->type=element_polyline;
+ e->color=*color;
+ e->u.polyline.width=width;
+ e->u.polyline.directed=directed;
+ e->u.polyline.dash_num=dash_num;
+ for (i=0; i<dash_num; i++)
+ e->u.polyline.dash_table[i] = dash_table[i];
+
+ return e;
+}
+
+struct element *
+circle_new(struct color *color, int radius, int width, int label_size)
+{
+ struct element *e;
+
+ e = g_new0(struct element, 1);
+ e->type=element_circle;
+ e->color=*color;
+ e->label_size=label_size;
+ e->u.circle.width=width;
+ e->u.circle.radius=radius;
+
+ return e;
+}
+
+struct element *
+label_new(int label_size)
+{
+ struct element *e;
+
+ e = g_new0(struct element, 1);
+ e->type=element_label;
+ e->label_size=label_size;
+
+ return e;
+}
+
+struct element *
+icon_new(const char *src)
+{
+ struct element *e;
+
+ e = g_malloc0(sizeof(*e)+strlen(src)+1);
+ e->type=element_icon;
+ e->u.icon.src=(char *)(e+1);
+ strcpy(e->u.icon.src,src);
+
+ return e;
+}
+
+struct element *
+image_new(void)
+{
+ struct element *e;
+
+ e = g_malloc0(sizeof(*e));
+ e->type=element_image;
+
+ return e;
+}
+
diff --git a/navit/layout.h b/navit/layout.h
new file mode 100644
index 000000000..87831004c
--- /dev/null
+++ b/navit/layout.h
@@ -0,0 +1,70 @@
+#ifndef NAVIT_LAYOUT_H
+#define NAVIT_LAYOUT_H
+
+#include "item.h"
+#include "color.h"
+
+struct element_line;
+struct element_text;
+
+struct element {
+ enum { element_point, element_polyline, element_polygon, element_circle, element_label, element_icon, element_image } type;
+ struct color color;
+ int label_size;
+ union {
+ struct element_point {
+ } point;
+ struct element_polyline {
+ int width;
+ int directed;
+ int dash_num;
+ unsigned char dash_table[4];
+ } polyline;
+ struct element_polygon {
+ } polygon;
+ struct element_circle {
+ int width;
+ int radius;
+ } circle;
+ struct element_icon {
+ char *src;
+ } icon;
+ } u;
+};
+
+
+struct itemtype {
+ int order_min, order_max;
+ GList *type;
+ GList *elements;
+};
+
+struct color;
+
+struct layer { char *name; int details; GList *itemtypes; };
+
+struct layout { char *name; struct color *color; GList *layers; };
+
+/* prototypes */
+enum item_type;
+struct element;
+struct itemtype;
+struct layer;
+struct layout;
+struct layout *layout_new(const char *name, struct color *color);
+struct layer *layer_new(const char *name, int details);
+void layout_add_layer(struct layout *layout, struct layer *layer);
+struct itemtype *itemtype_new(int order_min, int order_max);
+void itemtype_add_type(struct itemtype *this, enum item_type type);
+void layer_add_itemtype(struct layer *layer, struct itemtype *itemtype);
+void itemtype_add_element(struct itemtype *itemtype, struct element *element);
+struct element *polygon_new(struct color *color);
+struct element *polyline_new(struct color *color, int width, int directed,
+ int *dash_table, int dash_num);
+struct element *circle_new(struct color *color, int radius, int width, int label_size);
+struct element *label_new(int label_size);
+struct element *icon_new(const char *src);
+struct element *image_new(void);
+
+#endif
+
diff --git a/navit/locations.txt b/navit/locations.txt
new file mode 100644
index 000000000..739f93b26
--- /dev/null
+++ b/navit/locations.txt
@@ -0,0 +1 @@
+5231.3734 N 01324.8633 E Berlin Alexanderplatz
diff --git a/navit/log.c b/navit/log.c
new file mode 100644
index 000000000..03d7f5981
--- /dev/null
+++ b/navit/log.c
@@ -0,0 +1,235 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+#include <glib.h>
+#include "file.h"
+#include "item.h"
+#include "debug.h"
+#include "log.h"
+
+struct log_data {
+ int len;
+ int max_len;
+ char *data;
+};
+
+struct log {
+ FILE *f;
+ int overwrite;
+ int empty;
+ int flush_size;
+ int flush_time;
+ guint timer;
+ struct timeval last_flush;
+ char *filename;
+ char *filename_ex1;
+ char *filename_ex2;
+ struct log_data header;
+ struct log_data data;
+ struct log_data trailer;
+ struct attr **attrs;
+};
+
+static void
+strftime_localtime(char *buffer, int size, char *fmt)
+{
+ time_t t;
+ struct tm *tm;
+
+ t=time(NULL);
+ tm=localtime(&t);
+ strftime(buffer, 4096, fmt, tm);
+}
+
+static void
+expand_filenames(struct log *this_)
+{
+ char buffer[4096];
+ int i;
+
+ strftime_localtime(buffer, 4096, this_->filename);
+ this_->filename_ex1=g_strdup(buffer);
+ if (strstr(this_->filename_ex1,"%i")) {
+ i=0;
+ do {
+ g_free(this_->filename_ex2);
+ this_->filename_ex2=g_strdup_printf(this_->filename_ex1,i++);
+ } while (file_exists(this_->filename_ex2));
+ } else
+ this_->filename_ex2=g_strdup(this_->filename_ex1);
+}
+
+static void
+log_open(struct log *this_)
+{
+ char *mode;
+ if (this_->overwrite)
+ mode="w";
+ else
+ mode="r+";
+ this_->f=fopen(this_->filename_ex2, mode);
+ if (! this_->f)
+ this_->f=fopen(this_->filename_ex2, "w");
+ if (!this_->overwrite)
+ fseek(this_->f, 0, SEEK_END);
+ this_->empty = !ftell(this_->f);
+}
+
+static void
+log_close(struct log *this_)
+{
+ if (this_->trailer.len)
+ fwrite(this_->trailer.data, 1, this_->trailer.len, this_->f);
+ fflush(this_->f);
+ fclose(this_->f);
+ this_->f=NULL;
+}
+
+static void
+log_flush(struct log *this_)
+{
+ long pos;
+ if (this_->empty) {
+ if (this_->header.len)
+ fwrite(this_->header.data, 1, this_->header.len, this_->f);
+ if (this_->header.len || this_->data.len)
+ this_->empty=0;
+ }
+ fwrite(this_->data.data, 1, this_->data.len, this_->f);
+ if (this_->trailer.len) {
+ pos=ftell(this_->f);
+ if (pos > 0) {
+ fwrite(this_->trailer.data, 1, this_->trailer.len, this_->f);
+ fseek(this_->f, pos, SEEK_SET);
+ }
+ }
+
+ fflush(this_->f);
+ g_free(this_->data.data);
+ this_->data.data=NULL;
+ this_->data.max_len=this_->data.len=0;
+ gettimeofday(&this_->last_flush, NULL);
+}
+
+static int
+log_flush_required(struct log *this_)
+{
+ return this_->data.len > this_->flush_size;
+}
+
+
+static void
+log_change(struct log *this_)
+{
+ log_flush(this_);
+ log_close(this_);
+ log_open(this_);
+}
+
+static int
+log_change_required(struct log *this_)
+{
+ char buffer[4096];
+
+ strftime_localtime(buffer, 4096, this_->filename);
+ return (strcmp(this_->filename_ex1, buffer) != 0);
+}
+
+static gboolean
+log_timer(gpointer data)
+{
+ struct log *this_=data;
+ struct timeval tv;
+ int delta;
+ gettimeofday(&tv, NULL);
+ delta=(tv.tv_sec-this_->last_flush.tv_sec)*1000+(tv.tv_usec-this_->last_flush.tv_usec)/1000;
+ dbg(0,"delta=%d flush_time=%d\n", delta, this_->flush_time);
+ if (this_->flush_time && delta > this_->flush_time*1000)
+ log_flush(this_);
+ return TRUE;
+}
+
+int
+log_get_attr(struct log *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
+{
+ return attr_generic_get_attr(this_->attrs, type, attr, iter);
+}
+
+
+struct log *
+log_new(struct attr **attrs)
+{
+ struct log *ret=g_new0(struct log, 1);
+ struct attr *data,*overwrite,*flush_size,*flush_time;
+
+ dbg(1,"enter\n");
+ data=attr_search(attrs, NULL, attr_data);
+ if (! data)
+ return NULL;
+ ret->filename=g_strdup(data->u.str);
+ overwrite=attr_search(attrs, NULL, attr_overwrite);
+ if (overwrite)
+ ret->overwrite=overwrite->u.num;
+ flush_size=attr_search(attrs, NULL, attr_flush_size);
+ if (flush_size)
+ ret->flush_size=flush_size->u.num;
+ flush_time=attr_search(attrs, NULL, attr_flush_time);
+ if (flush_time)
+ ret->flush_time=flush_time->u.num;
+ if (ret->flush_time) {
+ dbg(0,"interval %d\n", ret->flush_time*1000);
+ ret->timer=g_timeout_add(ret->flush_time*1000, log_timer, ret);
+ }
+ expand_filenames(ret);
+ log_open(ret);
+ gettimeofday(&ret->last_flush, NULL);
+ ret->attrs=attr_list_dup(attrs);
+ return ret;
+}
+
+void
+log_set_header(struct log *this_, char *data, int len)
+{
+ this_->header.data=g_malloc(len);
+ this_->header.max_len=this_->header.len=len;
+ memcpy(this_->header.data, data, len);
+}
+
+void
+log_set_trailer(struct log *this_, char *data, int len)
+{
+ this_->trailer.data=g_malloc(len);
+ this_->trailer.max_len=this_->trailer.len=len;
+ memcpy(this_->trailer.data, data, len);
+}
+
+void
+log_write(struct log *this_, char *data, int len)
+{
+ dbg(1,"enter\n");
+ if (log_change_required(this_))
+ log_change(this_);
+ if (this_->data.len + len > this_->data.max_len) {
+ dbg(2,"overflow\n");
+ this_->data.max_len+=16384;
+ this_->data.data=g_realloc(this_->data.data,this_->data.max_len);
+ }
+ memcpy(this_->data.data+this_->data.len, data, len);
+ this_->data.len+=len;
+ if (log_flush_required(this_))
+ log_flush(this_);
+}
+
+void
+log_destroy(struct log *this_)
+{
+ if (this_->timer)
+ g_source_remove(this_->timer);
+ log_flush(this_);
+ log_close(this_);
+ g_free(this_);
+}
diff --git a/navit/log.h b/navit/log.h
new file mode 100644
index 000000000..e9dabf300
--- /dev/null
+++ b/navit/log.h
@@ -0,0 +1,15 @@
+#ifndef NAVIT_LOG_H
+#define NAVIT_LOG_H
+/* prototypes */
+enum attr_type;
+struct attr;
+struct attr_iter;
+struct log;
+int log_get_attr(struct log *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter);
+struct log *log_new(struct attr **attrs);
+void log_set_header(struct log *this_, char *data, int len);
+void log_set_trailer(struct log *this_, char *data, int len);
+void log_write(struct log *this_, char *data, int len);
+void log_destroy(struct log *this_);
+/* end of prototypes */
+#endif
diff --git a/navit/main.c b/navit/main.c
new file mode 100644
index 000000000..f320ae67e
--- /dev/null
+++ b/navit/main.c
@@ -0,0 +1,246 @@
+#include <locale.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <glib.h>
+#include <sys/types.h>
+
+#ifndef _WIN32
+#include <sys/wait.h>
+#include <signal.h>
+#endif
+
+#include <unistd.h>
+#include <libintl.h>
+#include "config.h"
+#include "file.h"
+#include "debug.h"
+#include "main.h"
+#include "navit.h"
+#include "gui.h"
+#include "xmlconfig.h"
+#include "item.h"
+#include "coord.h"
+#include "route.h"
+#include "navigation.h"
+#include "event.h"
+
+#define _(STRING) gettext(STRING)
+
+struct map_data *map_data_default;
+
+static void sigchld(int sig)
+{
+#ifndef _WIN32
+ int status;
+ while (waitpid(-1, &status, WNOHANG) > 0);
+#endif
+}
+
+
+static gchar *get_home_directory(void)
+{
+ static gchar *homedir = NULL;
+
+ if (homedir) return homedir;
+ homedir = getenv("HOME");
+ if (!homedir)
+ {
+// struct passwd *p;
+
+// p = getpwuid(getuid());
+// if (p) homedir = p->pw_dir;
+ }
+ if (!homedir)
+ {
+ g_warning("Could not find home directory. Using current directory as home directory.");
+ homedir = ".";
+ }
+ return homedir;
+}
+
+static GList *navit;
+
+struct iter {
+ GList *list;
+};
+
+struct iter *
+main_iter_new(void)
+{
+ struct iter *ret=g_new0(struct iter, 1);
+ ret->list=navit;
+ return ret;
+}
+
+void
+main_iter_destroy(struct iter *iter)
+{
+ g_free(iter);
+}
+
+struct navit *
+main_get_navit(struct iter *iter)
+{
+ GList *list;
+ struct navit *ret=NULL;
+ if (iter)
+ list=iter->list;
+ else
+ list=navit;
+ if (list) {
+ ret=(struct navit *)(list->data);
+ if (iter)
+ iter->list=g_list_next(iter->list);
+ }
+ return ret;
+
+}
+void
+main_add_navit(struct navit *nav)
+{
+ navit=g_list_prepend(navit, nav);
+}
+
+void
+main_remove_navit(struct navit *nav)
+{
+ navit=g_list_remove(navit, nav);
+ if (! navit)
+ event_main_loop_quit();
+}
+
+int main(int argc, char **argv)
+{
+ GError *error = NULL;
+ char *config_file = NULL;
+ char *s;
+ int l;
+
+
+#ifndef _WIN32
+ signal(SIGCHLD, sigchld);
+#endif
+
+ setenv("LC_NUMERIC","C",1);
+ setlocale(LC_ALL,"");
+ setlocale(LC_NUMERIC,"C");
+ if (file_exists("navit.c") || file_exists("navit.o")) {
+ char buffer[PATH_MAX];
+ printf(_("Running from source directory\n"));
+ getcwd(buffer, PATH_MAX);
+ setenv("NAVIT_PREFIX", buffer, 0);
+ setenv("NAVIT_LIBDIR", buffer, 0);
+ setenv("NAVIT_SHAREDIR", buffer, 0);
+ setenv("NAVIT_LIBPREFIX", "*/.libs/", 0);
+ s=g_strdup_printf("%s/../locale", buffer);
+ setenv("NAVIT_LOCALEDIR", s, 0);
+ g_free(s);
+ } else {
+ if (!getenv("NAVIT_PREFIX")) {
+ l=strlen(argv[0]);
+ if (l > 10 && !strcmp(argv[0]+l-10,"/bin/navit")) {
+ s=g_strdup(argv[0]);
+ s[l-10]='\0';
+ if (strcmp(s, PREFIX))
+ printf(_("setting '%s' to '%s'\n"), "NAVIT_PREFIX", s);
+ setenv("NAVIT_PREFIX", s, 0);
+ g_free(s);
+ } else
+ setenv("NAVIT_PREFIX", PREFIX, 0);
+ }
+#ifdef _WIN32
+ s=g_strdup_printf("locale");
+#else
+ s=g_strdup_printf("%s/share/locale", getenv("NAVIT_PREFIX"));
+#endif
+ setenv("NAVIT_LOCALEDIR", s, 0);
+ g_free(s);
+#ifdef _WIN32
+ s=g_strdup_printf(".");
+#else
+ s=g_strdup_printf("%s/share/navit", getenv("NAVIT_PREFIX"));
+#endif
+ setenv("NAVIT_SHAREDIR", s, 0);
+ g_free(s);
+ s=g_strdup_printf("%s/lib/navit", getenv("NAVIT_PREFIX"));
+ setenv("NAVIT_LIBDIR", s, 0);
+ g_free(s);
+ }
+ bindtextdomain(PACKAGE, getenv("NAVIT_LOCALEDIR"));
+ bind_textdomain_codeset (PACKAGE, "UTF-8");
+ textdomain(PACKAGE);
+
+ debug_init(argv[0]);
+ if (getenv("LC_ALL"))
+ dbg(0,"Warning: LC_ALL is set, this might lead to problems\n");
+#ifndef USE_PLUGINS
+ extern void builtin_init(void);
+ builtin_init();
+#endif
+#if 0
+ /* handled in gui/gtk */
+ gtk_set_locale();
+ gtk_init(&argc, &argv);
+ gdk_rgb_init();
+#endif
+ s = getenv("NAVIT_WID");
+ if (s) {
+ setenv("SDL_WINDOWID", s, 0);
+ }
+ route_init();
+ navigation_init();
+ config_file=NULL;
+ if (argc > 1)
+ config_file=argv[1];
+ if (! config_file) {
+ config_file=g_strjoin(NULL,get_home_directory(), "/.navit/navit.xml" , NULL);
+ if (!file_exists(config_file)) {
+ g_free(config_file);
+ config_file=NULL;
+ }
+ }
+ if (! config_file) {
+ if (file_exists("navit.xml.local"))
+ config_file="navit.xml.local";
+ }
+ if (! config_file) {
+ if (file_exists("navit.xml"))
+ config_file="navit.xml";
+ }
+ if (! config_file) {
+ config_file=g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/navit.xml.local" , NULL);
+ if (!file_exists(config_file)) {
+ g_free(config_file);
+ config_file=NULL;
+ }
+ }
+ if (! config_file) {
+ config_file=g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/navit.xml" , NULL);
+ if (!file_exists(config_file)) {
+ g_free(config_file);
+ config_file=NULL;
+ }
+ }
+ if (!config_file) {
+ printf(_("No config file navit.xml, navit.xml.local found\n"));
+ exit(1);
+ }
+ if (!config_load(config_file, &error)) {
+ printf(_("Error parsing '%s': %s\n"), config_file, error->message);
+ exit(1);
+ } else {
+ printf(_("Using '%s'\n"), config_file);
+ }
+ if (! navit) {
+ printf(_("No instance has been created, exiting\n"));
+ exit(1);
+ }
+ if (main_loop_gui) {
+ gui_run_main_loop(main_loop_gui);
+ } else
+ event_main_loop_run();
+
+ return 0;
+}
diff --git a/navit/main.h b/navit/main.h
new file mode 100644
index 000000000..4629888d3
--- /dev/null
+++ b/navit/main.h
@@ -0,0 +1,16 @@
+#ifndef NAVIT_MAIN_H
+#define NAVIT_MAIN_H
+
+/* prototypes */
+struct navit;
+struct iter;
+struct iter * main_iter_new(void);
+void main_iter_destroy(struct iter *iter);
+struct navit * main_get_navit(struct iter *iter);
+void main_add_navit(struct navit *nav);
+void main_remove_navit(struct navit *nav);
+int main(int argc, char **argv);
+/* end of prototypes */
+
+#endif
+
diff --git a/navit/map-share.h b/navit/map-share.h
new file mode 100644
index 000000000..2b534a633
--- /dev/null
+++ b/navit/map-share.h
@@ -0,0 +1,8 @@
+#ifndef NAVIT_MAP_SHARE_H
+#define NAVIT_MAP_SHARE_H
+
+void map_srv_start_poa(CORBA_ORB orb, CORBA_Environment * ev);
+CORBA_Object map_srv_start_object(CORBA_Environment * ev, struct container *co);
+
+#endif
+
diff --git a/navit/map.c b/navit/map.c
new file mode 100644
index 000000000..a5198df3a
--- /dev/null
+++ b/navit/map.c
@@ -0,0 +1,250 @@
+#include <glib.h>
+#include <string.h>
+#include "debug.h"
+#include "coord.h"
+#include "projection.h"
+#include "map.h"
+#include "maptype.h"
+#include "transform.h"
+#include "item.h"
+#include "plugin.h"
+#include "country.h"
+
+
+struct map {
+ struct map_methods meth;
+ struct map_priv *priv;
+ char *type;
+ char *filename;
+ int active;
+};
+
+struct map_rect {
+ struct map *m;
+ struct map_rect_priv *priv;
+};
+
+struct map *
+map_new(const char *type, struct attr **attrs)
+{
+ struct map *m;
+ struct map_priv *(*maptype_new)(struct map_methods *meth, struct attr **attrs);
+ struct attr *data=attr_search(attrs, NULL, attr_data);
+
+
+ maptype_new=plugin_get_map_type(type);
+ if (! maptype_new)
+ return NULL;
+
+ m=g_new0(struct map, 1);
+ m->active=1;
+ m->type=g_strdup(type);
+ if (data)
+ m->filename=g_strdup(data->u.str);
+ m->priv=maptype_new(&m->meth, attrs);
+ if (! m->priv) {
+ g_free(m);
+ m=NULL;
+ }
+ return m;
+}
+
+char *
+map_get_filename(struct map *this_)
+{
+ return this_->filename;
+}
+
+char *
+map_get_type(struct map *this_)
+{
+ return this_->type;
+}
+
+int
+map_get_active(struct map *this_)
+{
+ return this_->active;
+}
+
+void
+map_set_active(struct map *this_, int active)
+{
+ this_->active=active;
+}
+
+int
+map_requires_conversion(struct map *this_)
+{
+ return (this_->meth.charset != NULL && strcmp(this_->meth.charset, "utf-8"));
+}
+
+char *
+map_convert_string(struct map *this_, char *str)
+{
+ return g_convert(str, -1,"utf-8",this_->meth.charset,NULL,NULL,NULL);
+}
+
+void
+map_convert_free(char *str)
+{
+ g_free(str);
+}
+
+enum projection
+map_projection(struct map *this_)
+{
+ return this_->meth.pro;
+}
+
+void
+map_set_projection(struct map *this_, enum projection pro)
+{
+ this_->meth.pro=pro;
+}
+
+void
+map_destroy(struct map *m)
+{
+ m->meth.map_destroy(m->priv);
+ g_free(m);
+}
+
+struct map_rect *
+map_rect_new(struct map *m, struct map_selection *sel)
+{
+ struct map_rect *mr;
+
+#if 0
+ printf("map_rect_new 0x%x,0x%x-0x%x,0x%x\n", r->lu.x, r->lu.y, r->rl.x, r->rl.y);
+#endif
+ mr=g_new0(struct map_rect, 1);
+ mr->m=m;
+ mr->priv=m->meth.map_rect_new(m->priv, sel);
+ if (! mr->priv) {
+ g_free(mr);
+ mr=NULL;
+ }
+
+ return mr;
+}
+
+struct item *
+map_rect_get_item(struct map_rect *mr)
+{
+ struct item *ret;
+ g_assert(mr != NULL);
+ g_assert(mr->m != NULL);
+ g_assert(mr->m->meth.map_rect_get_item != NULL);
+ ret=mr->m->meth.map_rect_get_item(mr->priv);
+ if (ret)
+ ret->map=mr->m;
+ return ret;
+}
+
+struct item *
+map_rect_get_item_byid(struct map_rect *mr, int id_hi, int id_lo)
+{
+ struct item *ret=NULL;
+ g_assert(mr != NULL);
+ g_assert(mr->m != NULL);
+ if (mr->m->meth.map_rect_get_item_byid)
+ ret=mr->m->meth.map_rect_get_item_byid(mr->priv, id_hi, id_lo);
+ if (ret)
+ ret->map=mr->m;
+ return ret;
+}
+
+void
+map_rect_destroy(struct map_rect *mr)
+{
+ mr->m->meth.map_rect_destroy(mr->priv);
+ g_free(mr);
+}
+
+struct map_search {
+ struct map *m;
+ struct attr search_attr;
+ void *priv;
+};
+
+struct map_search *
+map_search_new(struct map *m, struct item *item, struct attr *search_attr, int partial)
+{
+ struct map_search *this_;
+ dbg(1,"enter(%p,%p,%p,%d)\n", m, item, search_attr, partial);
+ dbg(1,"0x%x 0x%x 0x%x\n", attr_country_all, search_attr->type, attr_country_name);
+ this_=g_new0(struct map_search,1);
+ this_->m=m;
+ this_->search_attr=*search_attr;
+ if (search_attr->type >= attr_country_all && search_attr->type <= attr_country_name)
+ this_->priv=country_search_new(&this_->search_attr, partial);
+ else {
+ if (m->meth.map_search_new) {
+ if (m->meth.charset)
+ this_->search_attr.u.str=g_convert(this_->search_attr.u.str, -1,m->meth.charset,"utf-8",NULL,NULL,NULL);
+ this_->priv=m->meth.map_search_new(m->priv, item, &this_->search_attr, partial);
+ } else {
+ g_free(this_);
+ this_=NULL;
+ }
+ }
+ return this_;
+}
+
+struct item *
+map_search_get_item(struct map_search *this_)
+{
+ struct item *ret;
+
+ if (! this_)
+ return NULL;
+ if (this_->search_attr.type >= attr_country_all && this_->search_attr.type <= attr_country_name)
+ return country_search_get_item(this_->priv);
+ ret=this_->m->meth.map_search_get_item(this_->priv);
+ if (ret)
+ ret->map=this_->m;
+ return ret;
+}
+
+void
+map_search_destroy(struct map_search *this_)
+{
+ if (! this_)
+ return;
+ if (this_->search_attr.type >= attr_country_all && this_->search_attr.type <= attr_country_name)
+ country_search_destroy(this_->priv);
+ else {
+ if (this_->m->meth.charset)
+ g_free(this_->search_attr.u.str);
+ this_->m->meth.map_search_destroy(this_->priv);
+ }
+ g_free(this_);
+}
+
+struct map_selection *
+map_selection_dup(struct map_selection *sel)
+{
+ struct map_selection *next,**last;
+ struct map_selection *ret=NULL;
+ last=&ret;
+ while (sel) {
+ next = g_new(struct map_selection, 1);
+ *next=*sel;
+ *last=next;
+ last=&next->next;
+ sel = sel->next;
+ }
+ return ret;
+}
+
+void
+map_selection_destroy(struct map_selection *sel)
+{
+ struct map_selection *next;
+ while (sel) {
+ next = sel->next;
+ g_free(sel);
+ sel = next;
+ }
+}
diff --git a/navit/map.h b/navit/map.h
new file mode 100644
index 000000000..1dcc28b17
--- /dev/null
+++ b/navit/map.h
@@ -0,0 +1,157 @@
+#ifndef NAVIT_MAP_H
+#define NAVIT_MAP_H
+
+struct map_priv;
+struct attr;
+#include "coord.h"
+#include "point.h"
+#include "layer.h"
+
+struct map_selection {
+ struct map_selection *next;
+ union {
+ struct coord_rect c_rect;
+ struct point_rect p_rect;
+ } u;
+ int order[layer_end];
+};
+
+struct map_methods {
+ enum projection pro;
+ char *charset;
+ void (*map_destroy)(struct map_priv *priv);
+ struct map_rect_priv * (*map_rect_new)(struct map_priv *map, struct map_selection *sel);
+ void (*map_rect_destroy)(struct map_rect_priv *mr);
+ struct item * (*map_rect_get_item)(struct map_rect_priv *mr);
+ struct item * (*map_rect_get_item_byid)(struct map_rect_priv *mr, int id_hi, int id_lo);
+ struct map_search_priv *(*map_search_new)(struct map_priv *map, struct item *item, struct attr *search, int partial);
+ void (*map_search_destroy)(struct map_search_priv *ms);
+ struct item * (*map_search_get_item)(struct map_search_priv *ms);
+};
+
+static inline int
+map_selection_contains_point(struct map_selection *sel, struct coord *c)
+{
+ struct map_selection *curr=sel;
+ while (curr) {
+ struct coord_rect *r=&curr->u.c_rect;
+ if (c->x >= r->lu.x && c->x <= r->rl.x &&
+ c->y <= r->lu.y && c->y >= r->rl.y)
+ return 1;
+ curr=curr->next;
+ }
+ return sel ? 0:1;
+}
+
+static inline int
+map_selection_contains_polyline(struct map_selection *sel, struct coord *c, int count)
+{
+ int i,x_mi,x_ma,y_mi,y_ma;
+ struct map_selection *curr;
+
+ if (! sel)
+ return 1;
+ for (i = 0 ; i < count-1 ; i++) {
+ x_mi=c[i].x;
+ if (c[i+1].x < x_mi)
+ x_mi=c[i+1].x;
+ x_ma=c[i].x;
+ if (c[i+1].x > x_ma)
+ x_ma=c[i+1].x;
+ y_mi=c[i].y;
+ if (c[i+1].y < y_mi)
+ y_mi=c[i+1].y;
+ y_ma=c[i].y;
+ if (c[i+1].y > y_ma)
+ y_ma=c[i+1].y;
+ curr=sel;
+ while (curr) {
+ struct coord_rect *sr=&curr->u.c_rect;
+ if (x_mi <= sr->rl.x && x_ma >= sr->lu.x &&
+ y_ma >= sr->rl.y && y_mi <= sr->lu.y)
+ return 1;
+ curr=curr->next;
+ }
+ }
+ return 0;
+}
+
+static inline int
+map_selection_contains_rect(struct map_selection *sel, struct coord_rect *r)
+{
+ struct map_selection *curr;
+
+ g_assert(r->lu.x <= r->rl.x);
+ g_assert(r->lu.y >= r->rl.y);
+
+ if (! sel)
+ return 1;
+ curr=sel;
+ while (curr) {
+ struct coord_rect *sr=&curr->u.c_rect;
+ g_assert(sr->lu.x <= sr->rl.x);
+ g_assert(sr->lu.y >= sr->rl.y);
+ if (r->lu.x <= sr->rl.x && r->rl.x >= sr->lu.x &&
+ r->lu.y >= sr->rl.y && r->rl.y <= sr->lu.y)
+ return 1;
+ curr=curr->next;
+ }
+ return 0;
+}
+
+static inline int
+map_selection_contains_polygon(struct map_selection *sel, struct coord *c, int count)
+{
+ struct coord_rect r;
+ int i;
+
+ if (! sel)
+ return 1;
+ if (! count)
+ return 0;
+ r.lu=c[0];
+ r.rl=c[0];
+ for (i = 1 ; i < count ; i++) {
+ if (c[i].x < r.lu.x)
+ r.lu.x=c[i].x;
+ if (c[i].x > r.rl.x)
+ r.rl.x=c[i].x;
+ if (c[i].y < r.rl.y)
+ r.rl.y=c[i].y;
+ if (c[i].y > r.lu.y)
+ r.lu.y=c[i].y;
+ }
+ return map_selection_contains_rect(sel, &r);
+}
+
+/* prototypes */
+enum projection;
+struct attr;
+struct item;
+struct map;
+struct map_rect;
+struct map_search;
+struct map_selection;
+struct map *map_new(const char *type, struct attr **attrs);
+char *map_get_filename(struct map *this_);
+char *map_get_type(struct map *this_);
+int map_get_active(struct map *this_);
+void map_set_active(struct map *this_, int active);
+int map_requires_conversion(struct map *this_);
+char *map_convert_string(struct map *this_, char *str);
+void map_convert_free(char *str);
+enum projection map_projection(struct map *this_);
+void map_set_projection(struct map *this_, enum projection pro);
+void map_destroy(struct map *m);
+struct map_rect *map_rect_new(struct map *m, struct map_selection *sel);
+struct item *map_rect_get_item(struct map_rect *mr);
+struct item *map_rect_get_item_byid(struct map_rect *mr, int id_hi, int id_lo);
+void map_rect_destroy(struct map_rect *mr);
+struct map_search *map_search_new(struct map *m, struct item *item, struct attr *search_attr, int partial);
+struct item *map_search_get_item(struct map_search *this_);
+void map_search_destroy(struct map_search *this_);
+struct map_selection *map_selection_dup(struct map_selection *sel);
+void map_selection_destroy(struct map_selection *sel);
+/* end of prototypes */
+
+#endif
diff --git a/navit/map_data.h b/navit/map_data.h
new file mode 100644
index 000000000..bb2aab9cd
--- /dev/null
+++ b/navit/map_data.h
@@ -0,0 +1,35 @@
+#ifndef NAVIT_MAP_DATA_H
+#define NAVIT_MAP_DATA_H
+
+enum file_index {
+ file_border_ply=0,
+ file_bridge_ply,
+ file_height_ply,
+ file_other_ply,
+ file_rail_ply,
+ file_sea_ply,
+ file_street_bti,
+ file_street_str,
+ file_strname_stn,
+ file_town_twn,
+ file_tunnel_ply,
+ file_water_ply,
+ file_woodland_ply,
+ file_end
+};
+
+struct map_data {
+ struct file *file[file_end];
+ struct map_data *next;
+};
+
+struct map_data *load_maps(char *map);
+
+struct transformation;
+struct block_info;
+
+void map_data_foreach(struct map_data *mdata, int file, struct transformation *t, int limit,
+ void(*func)(struct block_info *, unsigned char *, unsigned char *, void *), void *data);
+
+#endif
+
diff --git a/navit/maps/Makefile.am b/navit/maps/Makefile.am
new file mode 100644
index 000000000..6480eddf4
--- /dev/null
+++ b/navit/maps/Makefile.am
@@ -0,0 +1,23 @@
+include $(top_srcdir)/Makefile.inc
+
+SAMPLE_MAP=osm_bbox_11.3,47.9,11.7,48.2
+
+maps_DATA = $(SAMPLE_MAP).bin $(SAMPLE_MAP).xml
+
+samplemap: $(SAMPLE_MAP).bin
+
+$(SAMPLE_MAP).osm.bz2:
+ echo "Downloading osm sample map"
+ wget -O $(SAMPLE_MAP).osm.bz2.tmp http://navit.sourceforge.net/maps/$(SAMPLE_MAP).osm.bz2
+ mv $(SAMPLE_MAP).osm.bz2.tmp $(SAMPLE_MAP).osm.bz2
+
+$(SAMPLE_MAP).bin $(SAMPLE_MAP).xml: $(SAMPLE_MAP).osm.bz2 $(top_builddir)/navit/osm2navit
+ echo "Converting osm sample map"
+ bzcat $(SAMPLE_MAP).osm.bz2 | $(top_builddir)/navit/osm2navit --attr-debug-level=5 $(SAMPLE_MAP).bin.tmp
+ mv $(SAMPLE_MAP).bin.tmp $(SAMPLE_MAP).bin
+ echo '<map type="binfile" enabled="yes" data="$$NAVIT_SHAREDIR/maps/osm_bbox_11.3,47.9,11.7,48.2.bin"/>' >$(SAMPLE_MAP).xml
+
+distclean-local:
+ rm -f $(SAMPLE_MAP).osm.bz2 $(SAMPLE_MAP).bin $(SAMPLE_MAP).xml
+
+all:
diff --git a/navit/mapset.c b/navit/mapset.c
new file mode 100644
index 000000000..5c805cbb4
--- /dev/null
+++ b/navit/mapset.c
@@ -0,0 +1,120 @@
+#include <string.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+#include "debug.h"
+#include "item.h"
+#include "mapset.h"
+#include "projection.h"
+#include "map.h"
+
+struct mapset {
+ GList *maps;
+};
+
+struct mapset *mapset_new(void)
+{
+ struct mapset *ms;
+
+ ms=g_new0(struct mapset, 1);
+
+ return ms;
+}
+
+void mapset_add(struct mapset *ms, struct map *m)
+{
+ ms->maps=g_list_append(ms->maps, m);
+}
+
+#if 0
+static void mapset_maps_free(struct mapset *ms)
+{
+ /* todo */
+}
+#endif
+
+void mapset_destroy(struct mapset *ms)
+{
+ g_free(ms);
+}
+
+struct mapset_handle {
+ GList *l;
+};
+
+struct mapset_handle *
+mapset_open(struct mapset *ms)
+{
+ struct mapset_handle *ret;
+
+ ret=g_new(struct mapset_handle, 1);
+ ret->l=ms->maps;
+
+ return ret;
+}
+
+struct map * mapset_next(struct mapset_handle *msh, int active)
+{
+ struct map *ret;
+
+ for (;;) {
+ if (!msh->l)
+ return NULL;
+ ret=msh->l->data;
+ msh->l=g_list_next(msh->l);
+ if (!active || map_get_active(ret))
+ return ret;
+ }
+}
+
+void
+mapset_close(struct mapset_handle *msh)
+{
+ g_free(msh);
+}
+
+struct mapset_search {
+ GList *map;
+ struct map_search *ms;
+ struct item *item;
+ struct attr *search_attr;
+ int partial;
+};
+
+struct mapset_search *
+mapset_search_new(struct mapset *ms, struct item *item, struct attr *search_attr, int partial)
+{
+ struct mapset_search *this;
+ dbg(1,"enter(%p,%p,%p,%d)\n", ms, item, search_attr, partial);
+ this=g_new0(struct mapset_search,1);
+ this->map=ms->maps;
+ this->item=item;
+ this->search_attr=search_attr;
+ this->partial=partial;
+ this->ms=map_search_new(this->map->data, item, search_attr, partial);
+ return this;
+}
+
+struct item *
+mapset_search_get_item(struct mapset_search *this)
+{
+ struct item *ret;
+ while (!(ret=map_search_get_item(this->ms))) {
+ if (this->search_attr->type >= attr_country_all && this->search_attr->type <= attr_country_name)
+ break;
+ do {
+ this->map=g_list_next(this->map);
+ } while (this->map && ! map_get_active(this->map->data));
+ if (! this->map)
+ break;
+ map_search_destroy(this->ms);
+ this->ms=map_search_new(this->map->data, this->item, this->search_attr, this->partial);
+ }
+ return ret;
+}
+
+void
+mapset_search_destroy(struct mapset_search *this)
+{
+ map_search_destroy(this->ms);
+ g_free(this);
+}
diff --git a/navit/mapset.h b/navit/mapset.h
new file mode 100644
index 000000000..894dee123
--- /dev/null
+++ b/navit/mapset.h
@@ -0,0 +1,22 @@
+#ifndef NAVIT_MAPSET_H
+#define NAVIT_MAPSET_H
+
+/* prototypes */
+struct attr;
+struct item;
+struct map;
+struct mapset;
+struct mapset_handle;
+struct mapset_search;
+struct mapset *mapset_new(void);
+void mapset_add(struct mapset *ms, struct map *m);
+void mapset_destroy(struct mapset *ms);
+struct mapset_handle *mapset_open(struct mapset *ms);
+struct map *mapset_next(struct mapset_handle *msh, int active);
+void mapset_close(struct mapset_handle *msh);
+struct mapset_search *mapset_search_new(struct mapset *ms, struct item *item, struct attr *search_attr, int partial);
+struct item *mapset_search_get_item(struct mapset_search *this);
+void mapset_search_destroy(struct mapset_search *this);
+
+#endif
+
diff --git a/navit/maptype.c b/navit/maptype.c
new file mode 100644
index 000000000..0c0a26bca
--- /dev/null
+++ b/navit/maptype.c
@@ -0,0 +1,30 @@
+#include <glib.h>
+#include "projection.h"
+#include "map.h"
+#include "maptype.h"
+
+static struct maptype *maptype_root;
+
+void
+maptype_register(char *name, struct map_priv *(*map_new)(struct map_methods *meth, char *data, char **charset, enum projection *pro))
+{
+ struct maptype *mt;
+ mt=g_new(struct maptype, 1);
+ mt->name=g_strdup(name);
+ mt->map_new=map_new;
+ mt->next=maptype_root;
+ maptype_root=mt;
+}
+
+struct maptype *
+maptype_get(const char *name)
+{
+ struct maptype *mt=maptype_root;
+
+ while (mt) {
+ if (!g_ascii_strcasecmp(mt->name, name))
+ return mt;
+ mt=mt->next;
+ }
+ return NULL;
+}
diff --git a/navit/maptype.h b/navit/maptype.h
new file mode 100644
index 000000000..bfaf4e298
--- /dev/null
+++ b/navit/maptype.h
@@ -0,0 +1,21 @@
+#ifndef NAVIT_MAPTYPE_H
+#define NAVIT_MAPTYPE_H
+
+struct map_methods;
+
+struct maptype {
+ char *name;
+ struct map_priv *(*map_new)(struct map_methods *meth, char *data, char **charset, enum projection *pro);
+ struct maptype *next;
+};
+
+/* prototypes */
+enum projection;
+struct map_methods;
+struct map_priv;
+struct maptype;
+void maptype_register(char *name, struct map_priv *(*map_new)(struct map_methods *meth, char *data, char **charset, enum projection *pro));
+struct maptype *maptype_get(const char *name);
+
+#endif
+
diff --git a/navit/menu.c b/navit/menu.c
new file mode 100644
index 000000000..a2f0581fc
--- /dev/null
+++ b/navit/menu.c
@@ -0,0 +1,26 @@
+#include <glib.h>
+#include "menu.h"
+#include "debug.h"
+
+struct menu *
+menu_add(struct menu *menu, char *name, enum menu_type type, struct callback *cb)
+{
+ struct menu *this;
+ this=g_new0(struct menu, 1);
+ this->priv=(*menu->meth.add)(menu->priv, &this->meth, name, type, cb);
+ if (! this->priv) {
+ g_free(this);
+ return NULL;
+ }
+
+ return this;
+}
+
+void
+menu_popup(struct menu *menu)
+{
+ if (! menu || ! menu->meth.popup)
+ return;
+ (*menu->meth.popup)(menu->priv);
+
+}
diff --git a/navit/menu.h b/navit/menu.h
new file mode 100644
index 000000000..a3841943f
--- /dev/null
+++ b/navit/menu.h
@@ -0,0 +1,30 @@
+#ifndef NAVIT_MENU_H
+#define NAVIT_MENU_H
+
+enum menu_type {
+ menu_type_submenu,
+ menu_type_menu,
+ menu_type_toggle,
+};
+
+struct container;
+struct menu;
+struct callback;
+
+struct menu_methods {
+ struct menu_priv *(*add)(struct menu_priv *menu, struct menu_methods *meth, char *name, enum menu_type type, struct callback *cb);
+ void (*set_toggle)(struct menu_priv *menu, int active);
+ int (*get_toggle)(struct menu_priv *menu);
+ void (*popup)(struct menu_priv *menu);
+};
+
+struct menu {
+ struct menu_priv *priv;
+ struct menu_methods meth;
+};
+
+/* prototypes */
+struct menu *menu_add(struct menu *menu, char *name, enum menu_type type, struct callback *cb);
+void menu_popup(struct menu *menu);
+/* end of prototypes */
+#endif
diff --git a/navit/navigation.c b/navit/navigation.c
new file mode 100644
index 000000000..8f3b33031
--- /dev/null
+++ b/navit/navigation.c
@@ -0,0 +1,982 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <glib.h>
+#include <libintl.h>
+#include "debug.h"
+#include "profile.h"
+#include "navigation.h"
+#include "coord.h"
+#include "item.h"
+#include "route.h"
+#include "transform.h"
+#include "mapset.h"
+#include "projection.h"
+#include "map.h"
+#include "navit.h"
+#include "callback.h"
+#include "plugin.h"
+
+#define _(STRING) gettext(STRING)
+
+struct suffix {
+ char *fullname;
+ char *abbrev;
+ int sex;
+} suffixes[]= {
+ {"weg",NULL,1},
+ {"platz","pl.",1},
+ {"ring",NULL,1},
+ {"allee",NULL,2},
+ {"gasse",NULL,2},
+ {"straße","str.",2},
+ {"strasse",NULL,2},
+};
+
+struct navigation {
+ struct map *map;
+ struct item_hash *hash;
+ struct navigation_itm *first;
+ struct navigation_itm *last;
+ struct navigation_command *cmd_first;
+ struct navigation_command *cmd_last;
+ struct callback_list *callback_speech;
+ struct callback_list *callback;
+ int level_last;
+ struct item item_last;
+ int turn_around;
+ int turn_around_limit;
+ int distance_turn;
+ int distance_last;
+ int announce[route_item_last-route_item_first+1][3];
+};
+
+
+struct navigation_command {
+ struct navigation_itm *itm;
+ struct navigation_command *next;
+ int delta;
+};
+
+struct navigation *
+navigation_new(struct attr **attrs)
+{
+ int i,j;
+ struct navigation *ret=g_new0(struct navigation, 1);
+ ret->hash=item_hash_new();
+ ret->callback=callback_list_new();
+ ret->callback_speech=callback_list_new();
+ ret->level_last=-2;
+ ret->distance_last=-2;
+ ret->distance_turn=50;
+ ret->turn_around_limit=3;
+
+ for (j = 0 ; j <= route_item_last-route_item_first ; j++) {
+ for (i = 0 ; i < 3 ; i++) {
+ ret->announce[j][i]=-1;
+ }
+ }
+
+ return ret;
+}
+
+int
+navigation_set_announce(struct navigation *this_, enum item_type type, int *level)
+{
+ int i;
+ if (type < route_item_first || type > route_item_last) {
+ dbg(0,"street type %d out of range [%d,%d]", type, route_item_first, route_item_last);
+ return 0;
+ }
+ for (i = 0 ; i < 3 ; i++)
+ this_->announce[type-route_item_first][i]=level[i];
+ return 1;
+}
+
+static int
+navigation_get_announce_level(struct navigation *this_, enum item_type type, int dist)
+{
+ int i;
+
+ if (type < route_item_first || type > route_item_last)
+ return -1;
+ for (i = 0 ; i < 3 ; i++) {
+ if (dist <= this_->announce[type-route_item_first][i])
+ return i;
+ }
+ return i;
+}
+
+struct navigation_itm {
+ char *name1;
+ char *name2;
+ struct item item;
+ int angle_start;
+ int angle_end;
+ int time;
+ int length;
+ int dest_time;
+ int dest_length;
+ int told;
+ struct navigation_itm *next;
+ struct navigation_itm *prev;
+};
+
+/* 0=N,90=E */
+static int
+road_angle(struct coord *c1, struct coord *c2, int dir)
+{
+ int ret=transform_get_angle_delta(c1, c2, dir);
+ dbg(1, "road_angle(0x%x,0x%x - 0x%x,0x%x)=%d\n", c1->x, c1->y, c2->x, c2->y, ret);
+ return ret;
+}
+
+static int
+round_distance(int dist)
+{
+ if (dist < 100) {
+ dist=(dist+5)/10;
+ return dist*10;
+ }
+ if (dist < 250) {
+ dist=(dist+13)/25;
+ return dist*25;
+ }
+ if (dist < 500) {
+ dist=(dist+25)/50;
+ return dist*50;
+ }
+ if (dist < 1000) {
+ dist=(dist+50)/100;
+ return dist*100;
+ }
+ if (dist < 5000) {
+ dist=(dist+50)/100;
+ return dist*100;
+ }
+ if (dist < 100000) {
+ dist=(dist+500)/1000;
+ return dist*1000;
+ }
+ dist=(dist+5000)/10000;
+ return dist*10000;
+}
+
+static char *
+get_distance(int dist, enum attr_type type, int is_length)
+{
+ if (type == attr_navigation_long) {
+ if (is_length)
+ return g_strdup_printf(_("%d m"), dist);
+ else
+ return g_strdup_printf(_("in %d m"), dist);
+ }
+ if (dist < 1000) {
+ if (is_length)
+ return g_strdup_printf(_("%d meters"), dist);
+ else
+ return g_strdup_printf(_("in %d meters"), dist);
+ }
+ if (dist < 5000) {
+ int rem=(dist/100)%10;
+ if (rem) {
+ if (is_length)
+ return g_strdup_printf(_("%d.%d kilometer"), dist/1000, rem);
+ else
+ return g_strdup_printf(_("in %d.%d kilometers"), dist/1000, rem);
+ }
+ }
+ if (is_length)
+ return g_strdup_printf(ngettext("one kilometer","%d kilometers", dist/1000), dist/1000);
+ else
+ return g_strdup_printf(ngettext("in one kilometer","in %d kilometers", dist/1000), dist/1000);
+}
+
+static void
+navigation_destroy_itms_cmds(struct navigation *this_, struct navigation_itm *end)
+{
+ struct navigation_itm *itm;
+ struct navigation_command *cmd;
+ dbg(2,"enter this_=%p this_->first=%p this_->cmd_first=%p end=%p\n", this_, this_->first, this_->cmd_first, end);
+ if (this_->cmd_first)
+ dbg(2,"this_->cmd_first->itm=%p\n", this_->cmd_first->itm);
+ while (this_->first && this_->first != end) {
+ itm=this_->first;
+ dbg(3,"destroying %p\n", itm);
+ item_hash_remove(this_->hash, &itm->item);
+ this_->first=itm->next;
+ if (this_->first)
+ this_->first->prev=NULL;
+ if (this_->cmd_first && this_->cmd_first->itm == itm->next) {
+ cmd=this_->cmd_first;
+ this_->cmd_first=cmd->next;
+ g_free(cmd);
+ }
+ map_convert_free(itm->name1);
+ map_convert_free(itm->name2);
+ g_free(itm);
+ }
+ if (! this_->first)
+ this_->last=NULL;
+ if (! this_->first && end)
+ dbg(0,"end wrong\n");
+ dbg(2,"ret this_->first=%p this_->cmd_first=%p\n",this_->first, this_->cmd_first);
+}
+
+static void
+navigation_itm_update(struct navigation_itm *itm, struct item *ritem)
+{
+ struct attr length, time;
+ if (! item_attr_get(ritem, attr_length, &length)) {
+ dbg(0,"no length\n");
+ return;
+ }
+ if (! item_attr_get(ritem, attr_time, &time)) {
+ dbg(0,"no time\n");
+ return;
+ }
+ dbg(1,"length=%d time=%d\n", length.u.num, time.u.num);
+ itm->length=length.u.num;
+ itm->time=time.u.num;
+}
+
+static struct navigation_itm *
+navigation_itm_new(struct navigation *this_, struct item *ritem)
+{
+ struct navigation_itm *ret=g_new0(struct navigation_itm, 1);
+ int l,i=0;
+ struct item *sitem;
+ struct attr street_item;
+ struct map_rect *mr;
+ struct attr attr;
+ struct coord c[5];
+
+ if (ritem) {
+ ret->told=0;
+ if (! item_attr_get(ritem, attr_street_item, &street_item)) {
+ dbg(0,"no street item\n");
+ return NULL;
+ }
+ sitem=street_item.u.item;
+ ret->item=*sitem;
+ item_hash_insert(this_->hash, sitem, ret);
+ mr=map_rect_new(sitem->map, NULL);
+ sitem=map_rect_get_item_byid(mr, sitem->id_hi, sitem->id_lo);
+ if (item_attr_get(sitem, attr_street_name, &attr))
+ ret->name1=map_convert_string(sitem->map,attr.u.str);
+ if (item_attr_get(sitem, attr_street_name_systematic, &attr))
+ ret->name2=map_convert_string(sitem->map,attr.u.str);
+ navigation_itm_update(ret, ritem);
+ l=-1;
+ while (item_coord_get(ritem, &c[i], 1)) {
+ dbg(1, "coord %d 0x%x 0x%x\n", i, c[i].x ,c[i].y);
+ l=i;
+ if (i < 4)
+ i++;
+ else {
+ c[2]=c[3];
+ c[3]=c[4];
+ }
+ }
+ dbg(1,"count=%d\n", l);
+ if (l == 4)
+ l=3;
+ ret->angle_start=road_angle(&c[0], &c[1], 0);
+ ret->angle_end=road_angle(&c[l-1], &c[l], 0);
+ dbg(1,"i=%d start %d end %d '%s' '%s'\n", i, ret->angle_start, ret->angle_end, ret->name1, ret->name2);
+ map_rect_destroy(mr);
+ }
+ if (! this_->first)
+ this_->first=ret;
+ if (this_->last) {
+ this_->last->next=ret;
+ ret->prev=this_->last;
+ }
+ dbg(1,"ret=%p\n", ret);
+ this_->last=ret;
+ return ret;
+}
+
+static void
+calculate_dest_distance(struct navigation *this_, int incr)
+{
+ int len=0, time=0;
+ struct navigation_itm *next,*itm=this_->last;
+ dbg(1, "enter this_=%p, incr=%d\n", this_, incr);
+ if (incr) {
+ if (itm)
+ dbg(2, "old values: (%p) time=%d lenght=%d\n", itm, itm->dest_length, itm->dest_time);
+ else
+ dbg(2, "old values: itm is null\n");
+ itm=this_->first;
+ next=itm->next;
+ dbg(2, "itm values: time=%d lenght=%d\n", itm->length, itm->time);
+ dbg(2, "next values: (%p) time=%d lenght=%d\n", next, next->dest_length, next->dest_time);
+ itm->dest_length=next->dest_length+itm->length;
+ itm->dest_time=next->dest_time+itm->time;
+ dbg(2, "new values: time=%d lenght=%d\n", itm->dest_length, itm->dest_time);
+ return;
+ }
+ while (itm) {
+ len+=itm->length;
+ time+=itm->time;
+ itm->dest_length=len;
+ itm->dest_time=time;
+ itm=itm->prev;
+ }
+ dbg(1,"len %d time %d\n", len, time);
+}
+
+static int
+is_same_street2(struct navigation_itm *old, struct navigation_itm *new)
+{
+ if (old->name1 && new->name1 && !strcmp(old->name1, new->name1)) {
+ dbg(1,"is_same_street: '%s' '%s' vs '%s' '%s' yes (1.)\n", old->name2, new->name2, old->name1, new->name1);
+ return 1;
+ }
+ if (old->name2 && new->name2 && !strcmp(old->name2, new->name2)) {
+ dbg(1,"is_same_street: '%s' '%s' vs '%s' '%s' yes (2.)\n", old->name2, new->name2, old->name1, new->name1);
+ return 1;
+ }
+ dbg(1,"is_same_street: '%s' '%s' vs '%s' '%s' no\n", old->name2, new->name2, old->name1, new->name1);
+ return 0;
+}
+
+static int
+maneuver_required2(struct navigation_itm *old, struct navigation_itm *new, int *delta)
+{
+ dbg(1,"enter %p %p %p\n",old, new, delta);
+ if (new->item.type == old->item.type || (new->item.type != type_ramp && old->item.type != type_ramp)) {
+ if (is_same_street2(old, new)) {
+ dbg(1, "maneuver_required: is_same_street: no\n");
+ return 0;
+ }
+ } else
+ dbg(1, "maneuver_required: old or new is ramp\n");
+#if 0
+ if (old->crossings_end == 2) {
+ dbg(1, "maneuver_required: only 2 connections: no\n");
+ return 0;
+ }
+#endif
+ *delta=new->angle_start-old->angle_end;
+ if (*delta < -180)
+ *delta+=360;
+ if (*delta > 180)
+ *delta-=360;
+ dbg(1,"delta=%d-%d=%d\n", new->angle_start, old->angle_end, *delta);
+ if (*delta < 20 && *delta >-20) {
+ dbg(1, "maneuver_required: delta(%d) < 20: no\n", *delta);
+ return 0;
+ }
+ dbg(1, "maneuver_required: delta=%d: yes\n", *delta);
+ return 1;
+}
+
+static struct navigation_command *
+command_new(struct navigation *this_, struct navigation_itm *itm, int delta)
+{
+ struct navigation_command *ret=g_new0(struct navigation_command, 1);
+ dbg(1,"enter this_=%p itm=%p delta=%d\n", this_, itm, delta);
+ ret->delta=delta;
+ ret->itm=itm;
+ if (this_->cmd_last)
+ this_->cmd_last->next=ret;
+ this_->cmd_last=ret;
+
+ if (!this_->cmd_first)
+ this_->cmd_first=ret;
+ return ret;
+}
+
+static void
+make_maneuvers(struct navigation *this_)
+{
+ struct navigation_itm *itm, *last=NULL, *last_itm=NULL;
+ int delta;
+ itm=this_->first;
+ this_->cmd_last=NULL;
+ this_->cmd_first=NULL;
+ while (itm) {
+ if (last) {
+ if (maneuver_required2(last_itm, itm, &delta)) {
+ command_new(this_, itm, delta);
+ }
+ } else
+ last=itm;
+ last_itm=itm;
+ itm=itm->next;
+ }
+}
+
+static int
+contains_suffix(char *name, char *suffix)
+{
+ if (!suffix)
+ return 0;
+ if (strlen(name) < strlen(suffix))
+ return 0;
+ return !strcasecmp(name+strlen(name)-strlen(suffix), suffix);
+}
+
+static char *
+replace_suffix(char *name, char *search, char *replace)
+{
+ int len=strlen(name)-strlen(search);
+ char *ret=g_malloc(len+strlen(replace)+1);
+ strncpy(ret, name, len);
+ strcpy(ret+len, replace);
+
+ return ret;
+}
+
+static char *
+navigation_item_destination(struct navigation_itm *itm, struct navigation_itm *next, char *prefix)
+{
+ char *ret=NULL,*name1,*sep,*name2;
+ int i,sex;
+ if (! prefix)
+ prefix="";
+ if(!itm->name1 && !itm->name2 && itm->item.type == type_ramp) {
+ dbg(1,">> Next is ramp %lx current is %lx \n", itm->item.type, next->item.type);
+
+ if(next->item.type == type_ramp)
+ return NULL;
+ if(itm->item.type == type_highway_city || itm->item.type == type_highway_land )
+ return g_strdup_printf("%s%s",prefix,_("exit"));
+ else
+ return g_strdup_printf("%s%s",prefix,_("ramp"));
+
+ }
+ if (!itm->name1 && !itm->name2)
+ return NULL;
+ if (itm->name1) {
+ sex=-1;
+ name1=NULL;
+ for (i = 0 ; i < sizeof(suffixes)/sizeof(suffixes[0]) ; i++) {
+ if (contains_suffix(itm->name1,suffixes[i].fullname)) {
+ sex=suffixes[i].sex;
+ name1=g_strdup(itm->name1);
+ break;
+ }
+ if (contains_suffix(itm->name1,suffixes[i].abbrev)) {
+ sex=suffixes[i].sex;
+ name1=replace_suffix(itm->name1, suffixes[i].abbrev, suffixes[i].fullname);
+ break;
+ }
+ }
+ if (itm->name2) {
+ name2=itm->name2;
+ sep=" ";
+ } else {
+ name2="";
+ sep="";
+ }
+ switch (sex) {
+ case -1:
+ ret=g_strdup_printf(_("%sinto the street %s%s%s"),prefix,itm->name1, sep, name2);
+ break;
+ case 1:
+ ret=g_strdup_printf(_("%sinto the %s%s%s|male form"),prefix,name1, sep, name2);
+ break;
+ case 2:
+ ret=g_strdup_printf(_("%sinto the %s%s%s|female form"),prefix,name1, sep, name2);
+ break;
+ case 3:
+ ret=g_strdup_printf(_("%sinto the %s%s%s|neutral form"),prefix,name1, sep, name2);
+ break;
+ }
+ g_free(name1);
+
+ } else
+ ret=g_strdup_printf(_("into the %s"),itm->name2);
+ name1=ret;
+ while (*name1) {
+ switch (*name1) {
+ case '|':
+ *name1='\0';
+ break;
+ case '/':
+ *name1++=' ';
+ break;
+ default:
+ name1++;
+ }
+ }
+ return ret;
+}
+
+
+static char *
+show_maneuver(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type)
+{
+ char *dir=_("right"),*strength="";
+ int distance=itm->dest_length-cmd->itm->dest_length;
+ char *d,*ret;
+ int delta=cmd->delta;
+ int level;
+ level=1;
+ if (delta < 0) {
+ dir=_("left");
+ delta=-delta;
+ }
+ if (delta < 45) {
+ strength=_("easily ");
+ } else if (delta < 105) {
+ strength="";
+ } else if (delta < 165) {
+ strength=_("strongly ");
+ } else {
+ dbg(1,"delta=%d\n", delta);
+ strength=_("unknown ");
+ }
+ if (type != attr_navigation_long_exact)
+ distance=round_distance(distance);
+ if (type == attr_navigation_speech) {
+ if (nav->turn_around && nav->turn_around == nav->turn_around_limit)
+ return g_strdup(_("When possible, please turn around"));
+ level=navigation_get_announce_level(nav, itm->item.type, distance);
+ dbg(1,"distance=%d level=%d type=0x%x\n", distance, level, itm->item.type);
+ }
+ switch(level) {
+ case 3:
+ d=get_distance(distance, type, 1);
+ ret=g_strdup_printf(_("Follow the road for the next %s"), d);
+ g_free(d);
+ return ret;
+ case 2:
+ d=g_strdup(_("soon"));
+ break;
+ case 1:
+ d=get_distance(distance, type, 0);
+ break;
+ case 0:
+ d=g_strdup(_("now"));
+ break;
+ default:
+ d=g_strdup(_("error"));
+ }
+ if (cmd->itm->next) {
+ int tellstreetname = 0;
+ char *destination = NULL;
+
+ if(type == attr_navigation_speech) { // In voice mode
+ // In Voice Mode only tell the street name in level 1 or in level 0 if level 1
+ // was skipped
+
+ if (level == 1) { // we are close to the intersection
+ cmd->itm->told = 1; // remeber to be checked when we turn
+ tellstreetname = 1; // Ok so we tell the name of the street
+ }
+
+ if (level == 0) {
+ if(cmd->itm->told == 0) // we are write at the intersection
+ tellstreetname = 1;
+ else
+ cmd->itm->told = 0; // reset just in case we come to the same street again
+ }
+
+ }
+ else
+ tellstreetname = 1;
+
+ if(tellstreetname)
+ destination=navigation_item_destination(cmd->itm, itm, " ");
+ /* TRANSLATORS: The first argument is strength, the second direction, the third distance and the fourth destination Example: 'Turn 'slightly' 'left' in '100 m' 'onto baker street' */
+ ret=g_strdup_printf(_("Turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination:"");
+ g_free(destination);
+ } else
+ ret=g_strdup_printf(_("You have reached your destination %s"), d);
+ g_free(d);
+ return ret;
+}
+
+static void
+navigation_call_callbacks(struct navigation *this_, int force_speech)
+{
+ int distance, level = 0;
+ void *p=this_;
+ if (!this_->cmd_first)
+ return;
+ callback_list_call(this_->callback, 1, &p);
+ dbg(1,"force_speech=%d turn_around=%d turn_around_limit=%d\n", force_speech, this_->turn_around, this_->turn_around_limit);
+ distance=round_distance(this_->first->dest_length-this_->cmd_first->itm->dest_length);
+ if (this_->turn_around_limit && this_->turn_around == this_->turn_around_limit) {
+ dbg(1,"distance=%d distance_turn=%d\n", distance, this_->distance_turn);
+ while (distance > this_->distance_turn) {
+ this_->level_last=4;
+ level=4;
+ force_speech=1;
+ if (this_->distance_turn >= 500)
+ this_->distance_turn*=2;
+ else
+ this_->distance_turn=500;
+ }
+ } else if (!this_->turn_around_limit || this_->turn_around == -this_->turn_around_limit+1) {
+ this_->distance_turn=50;
+ level=navigation_get_announce_level(this_, this_->first->item.type, distance);
+ if (level < this_->level_last) {
+ dbg(1,"level %d < %d\n", level, this_->level_last);
+ this_->level_last=level;
+ force_speech=1;
+ }
+ if (!item_is_equal(this_->cmd_first->itm->item, this_->item_last)) {
+ dbg(1,"item different\n");
+ this_->item_last=this_->cmd_first->itm->item;
+ force_speech=1;
+ }
+ }
+ if (force_speech) {
+ this_->level_last=level;
+ dbg(1,"distance=%d level=%d type=0x%x\n", distance, level, this_->first->item.type);
+ callback_list_call(this_->callback_speech, 1, &p);
+ }
+}
+
+void
+navigation_update(struct navigation *this_, struct route *route)
+{
+ struct map *map;
+ struct map_rect *mr;
+ struct item *ritem,*sitem;
+ struct attr street_item;
+ struct navigation_itm *itm;
+ int incr=0;
+
+ if (! route)
+ return;
+ map=route_get_map(route);
+ if (! map)
+ return;
+ mr=map_rect_new(map, NULL);
+ if (! mr)
+ return;
+ dbg(1,"enter\n");
+ ritem=map_rect_get_item(mr);
+ if (ritem) {
+ if (item_attr_get(ritem, attr_street_item, &street_item)) {
+ sitem=street_item.u.item;
+ dbg(1,"sitem=%p\n", sitem);
+ itm=item_hash_lookup(this_->hash, sitem);
+ dbg(2,"itm for item with id (0x%x,0x%x) is %p\n", sitem->id_hi, sitem->id_lo, itm);
+ navigation_destroy_itms_cmds(this_, itm);
+ if (itm) {
+ incr=1;
+ navigation_itm_update(itm, ritem);
+ } else {
+ dbg(1,"not on track\n");
+ do {
+ dbg(1,"item\n");
+ navigation_itm_new(this_, ritem);
+ ritem=map_rect_get_item(mr);
+ } while (ritem);
+ itm=navigation_itm_new(this_, NULL);
+ make_maneuvers(this_);
+ }
+ } else
+ dbg(0,"no street_item\n");
+ calculate_dest_distance(this_, incr);
+ dbg(2,"destination distance old=%d new=%d\n", this_->distance_last, this_->first->dest_length);
+ if (this_->first->dest_length > this_->distance_last && this_->distance_last >= 0)
+ this_->turn_around++;
+ else
+ this_->turn_around--;
+ if (this_->turn_around > this_->turn_around_limit)
+ this_->turn_around=this_->turn_around_limit;
+ else if (this_->turn_around < -this_->turn_around_limit+1)
+ this_->turn_around=-this_->turn_around_limit+1;
+ dbg(2,"turn_around=%d\n", this_->turn_around);
+ this_->distance_last=this_->first->dest_length;
+ profile(0,"end");
+ navigation_call_callbacks(this_, FALSE);
+ } else
+ navigation_destroy_itms_cmds(this_, NULL);
+ map_rect_destroy(mr);
+
+#if 0
+ struct route_path_handle *rph;
+ struct route_path_segment *s;
+ struct navigation_itm *itm;
+ struct route_info *pos,*dst;
+ struct street_data *sd;
+ int *speedlist;
+ int len,end_flag=0;
+ int incr;
+
+ profile(0,NULL);
+ pos=route_get_pos(route);
+ dst=route_get_dst(route);
+ if (! pos || ! dst)
+ return;
+ speedlist=route_get_speedlist(route);
+ len=route_info_length(pos, dst, 0);
+ dbg(2,"len pos,dst = %d\n", len);
+ if (len == -1) {
+ len=route_info_length(pos, NULL, 0);
+ dbg(2,"len pos = %d\n", len);
+ end_flag=1;
+ }
+ sd=route_info_street(pos);
+ itm=item_hash_lookup(this_->hash, &sd->item);
+ dbg(2,"itm for item with id (0x%x,0x%x) is %p\n", sd->item.id_hi, sd->item.id_lo, itm);
+ navigation_destroy_itms_cmds(this_, itm);
+ if (itm)
+ incr=1;
+ else {
+ itm=navigation_itm_new(this_, &sd->item, route_info_point(pos, -1));
+ incr=0;
+ }
+ itm->length=len;
+ itm->time=route_time(speedlist, &sd->item, len);
+ dbg(2,"%p time = %d\n", itm, itm->time);
+ if (!incr) {
+ printf("not on track\n");
+ rph=route_path_open(route);
+ if (rph) {
+ while((s=route_path_get_segment(rph))) {
+ itm=navigation_itm_new(this_, route_path_segment_get_item(s),route_path_segment_get_start(s));
+ itm->time=route_path_segment_get_time(s);
+ itm->length=route_path_segment_get_length(s);
+ }
+ route_path_close(rph);
+ }
+ if (end_flag) {
+ len=route_info_length(NULL, dst, 0);
+ dbg(1, "end %d\n", len);
+ sd=route_info_street(dst);
+ itm=navigation_itm_new(this_, &sd->item, route_info_point(pos, 2));
+ itm->length=len;
+ itm->time=route_time(speedlist, &sd->item, len);
+ }
+ itm=navigation_itm_new(this_, NULL, NULL);
+ make_maneuvers(this_);
+ }
+ calculate_dest_distance(this_, incr);
+ dbg(2,"destination distance old=%d new=%d\n", this_->distance_last, this_->first->dest_length);
+ if (this_->first->dest_length > this_->distance_last && this_->distance_last >= 0)
+ this_->turn_around=1;
+ else
+ this_->turn_around=0;
+ dbg(2,"turn_around=%d\n", this_->turn_around);
+ this_->distance_last=this_->first->dest_length;
+ profile(0,"end");
+ navigation_call_callbacks(this_, FALSE);
+#endif
+}
+
+void
+navigation_flush(struct navigation *this_)
+{
+ navigation_destroy_itms_cmds(this_, NULL);
+}
+
+
+void
+navigation_destroy(struct navigation *this_)
+{
+ navigation_flush(this_);
+ item_hash_destroy(this_->hash);
+ callback_list_destroy(this_->callback);
+ callback_list_destroy(this_->callback_speech);
+ g_free(this_);
+}
+
+int
+navigation_register_callback(struct navigation *this_, enum attr_type type, struct callback *cb)
+{
+ if (type == attr_navigation_speech)
+ callback_list_add(this_->callback_speech, cb);
+ else
+ callback_list_add(this_->callback, cb);
+ return 1;
+}
+
+void
+navigation_unregister_callback(struct navigation *this_, enum attr_type type, struct callback *cb)
+{
+ if (type == attr_navigation_speech)
+ callback_list_remove_destroy(this_->callback_speech, cb);
+ else
+ callback_list_remove_destroy(this_->callback, cb);
+}
+
+struct map *
+navigation_get_map(struct navigation *this_)
+{
+ struct attr navigation_attr;
+ struct attr data_attr;
+ struct attr *attrs_navigation[]={&navigation_attr, &data_attr, NULL};
+ navigation_attr.type=attr_navigation;
+ navigation_attr.u.navigation=this_;
+ data_attr.type=attr_data;
+ data_attr.u.str="";
+
+ if (! this_->map)
+ this_->map=map_new("navigation",attrs_navigation);
+ return this_->map;
+}
+
+struct map_priv {
+ struct navigation *navigation;
+};
+
+struct map_rect_priv {
+ struct navigation *nav;
+ struct navigation_command *cmd;
+ struct navigation_command *cmd_next;
+ struct navigation_itm *itm;
+ struct navigation_itm *itm_next;
+ struct item item;
+};
+
+static int
+navigation_map_item_coord_get(void *priv_data, struct coord *c, int count)
+{
+ return 0;
+}
+
+static int
+navigation_map_item_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+ struct map_rect_priv *this_=priv_data;
+ attr->type=attr_type;
+ switch(attr_type) {
+ case attr_navigation_short:
+ case attr_navigation_long:
+ case attr_navigation_long_exact:
+ case attr_navigation_speech:
+ attr->u.str=show_maneuver(this_->nav, this_->itm, this_->cmd, attr_type);
+ return 1;
+ case attr_length:
+ attr->u.num=this_->itm->dest_length-this_->cmd->itm->dest_length;
+ return 1;
+ case attr_time:
+ attr->u.num=this_->itm->dest_time-this_->cmd->itm->dest_time;
+ return 1;
+ case attr_destination_length:
+ attr->u.num=this_->itm->dest_length;
+ return 1;
+ case attr_destination_time:
+ attr->u.num=this_->itm->dest_time;
+ return 1;
+ default:
+ attr->type=attr_none;
+ return 0;
+ }
+}
+
+static struct item_methods navigation_map_item_methods = {
+ NULL,
+ navigation_map_item_coord_get,
+ NULL,
+ navigation_map_item_attr_get,
+};
+
+
+static void
+navigation_map_destroy(struct map_priv *priv)
+{
+ g_free(priv);
+}
+
+static struct map_rect_priv *
+navigation_map_rect_new(struct map_priv *priv, struct map_selection *sel)
+{
+ struct navigation *nav=priv->navigation;
+ struct map_rect_priv *ret=g_new0(struct map_rect_priv, 1);
+ ret->nav=nav;
+ ret->cmd_next=nav->cmd_first;
+ ret->itm_next=nav->first;
+ ret->item.meth=&navigation_map_item_methods;
+ ret->item.priv_data=ret;
+ return ret;
+}
+
+static void
+navigation_map_rect_destroy(struct map_rect_priv *priv)
+{
+ g_free(priv);
+}
+
+static struct item *
+navigation_map_get_item(struct map_rect_priv *priv)
+{
+ struct item *ret;
+ int delta;
+ if (!priv->cmd_next)
+ return NULL;
+ ret=&priv->item;
+ priv->cmd=priv->cmd_next;
+ priv->itm=priv->itm_next;
+ priv->itm_next=priv->cmd->itm;
+ priv->cmd_next=priv->cmd->next;
+
+ delta=priv->cmd->delta;
+ dbg(1,"delta=%d\n", delta);
+ if (delta < 0) {
+ delta=-delta;
+ if (delta < 45)
+ ret->type=type_nav_left_1;
+ else if (delta < 105)
+ ret->type=type_nav_left_2;
+ else if (delta < 165)
+ ret->type=type_nav_left_3;
+ else
+ ret->type=type_none;
+ } else {
+ if (delta < 45)
+ ret->type=type_nav_right_1;
+ else if (delta < 105)
+ ret->type=type_nav_right_2;
+ else if (delta < 165)
+ ret->type=type_nav_right_3;
+ else
+ ret->type=type_none;
+ }
+ dbg(1,"type=%d\n", ret->type);
+ return ret;
+}
+
+static struct item *
+navigation_map_get_item_byid(struct map_rect_priv *priv, int id_hi, int id_lo)
+{
+ dbg(0,"stub");
+ return NULL;
+}
+
+static struct map_methods navigation_map_meth = {
+ projection_mg,
+ NULL,
+ navigation_map_destroy,
+ navigation_map_rect_new,
+ navigation_map_rect_destroy,
+ navigation_map_get_item,
+ navigation_map_get_item_byid,
+ NULL,
+ NULL,
+ NULL,
+};
+
+static struct map_priv *
+navigation_map_new(struct map_methods *meth, struct attr **attrs)
+{
+ struct map_priv *ret;
+ struct attr *navigation_attr;
+
+ navigation_attr=attr_search(attrs, NULL, attr_navigation);
+ if (! navigation_attr)
+ return NULL;
+ ret=g_new0(struct map_priv, 1);
+ *meth=navigation_map_meth;
+ ret->navigation=navigation_attr->u.navigation;
+
+ return ret;
+}
+
+
+void
+navigation_init(void)
+{
+ plugin_register_map_type("navigation", navigation_map_new);
+}
diff --git a/navit/navigation.h b/navit/navigation.h
new file mode 100644
index 000000000..fb873ebf3
--- /dev/null
+++ b/navit/navigation.h
@@ -0,0 +1,29 @@
+#ifndef NAVIT_NAVIGATION_H
+#define NAVIT_NAVIGATION_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* prototypes */
+enum attr_type;
+enum item_type;
+struct attr;
+struct callback;
+struct map;
+struct navigation;
+struct route;
+struct navigation *navigation_new(struct attr **attrs);
+int navigation_set_announce(struct navigation *this_, enum item_type type, int *level);
+void navigation_update(struct navigation *this_, struct route *route);
+void navigation_flush(struct navigation *this_);
+void navigation_destroy(struct navigation *this_);
+int navigation_register_callback(struct navigation *this_, enum attr_type type, struct callback *cb);
+void navigation_unregister_callback(struct navigation *this_, enum attr_type type, struct callback *cb);
+struct map *navigation_get_map(struct navigation *this_);
+void navigation_init(void);
+/* end of prototypes */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/navit/navit.c b/navit/navit.c
new file mode 100644
index 000000000..f3efa04d9
--- /dev/null
+++ b/navit/navit.c
@@ -0,0 +1,1583 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <glib.h>
+#include <libintl.h>
+#include <math.h>
+#include "debug.h"
+#include "navit.h"
+#include "callback.h"
+#include "gui.h"
+#include "item.h"
+#include "projection.h"
+#include "map.h"
+#include "mapset.h"
+#include "main.h"
+#include "coord.h"
+#include "point.h"
+#include "transform.h"
+#include "param.h"
+#include "menu.h"
+#include "graphics.h"
+#include "cursor.h"
+#include "popup.h"
+#include "data_window.h"
+#include "route.h"
+#include "navigation.h"
+#include "speech.h"
+#include "track.h"
+#include "vehicle.h"
+#include "color.h"
+#include "layout.h"
+#include "log.h"
+#include "attr.h"
+
+#define _(STRING) gettext(STRING)
+/**
+ * @defgroup navit the navit core instance
+ * @{
+ */
+
+struct navit_vehicle {
+ int update;
+ int update_curr;
+ int follow;
+ int follow_curr;
+ struct coord coord;
+ int dir;
+ int speed;
+ struct color c;
+ struct color *c2;
+ struct cursor *cursor;
+ struct vehicle *vehicle;
+ struct attr callback;
+ int animate_cursor;
+};
+
+struct navit {
+ struct attr self;
+ GList *mapsets;
+ GList *layouts;
+ struct gui *gui;
+ struct layout *layout_current;
+ struct graphics *gra;
+ struct action *action;
+ struct transformation *trans;
+ struct compass *compass;
+ struct route *route;
+ struct navigation *navigation;
+ struct speech *speech;
+ struct tracking *tracking;
+ int ready;
+ struct window *win;
+ struct displaylist *displaylist;
+ int cursor_flag;
+ int tracking_flag;
+ int orient_north_flag;
+ GList *vehicles;
+ GList *windows_items;
+ struct navit_vehicle *vehicle;
+ struct callback_list *attr_cbl;
+ int pid;
+ struct callback *nav_speech_cb;
+ struct callback *roadbook_callback;
+ struct callback *popup_callback;
+ struct datawindow *roadbook_window;
+ struct map *bookmark;
+ struct map *former_destination;
+ struct menu *bookmarks;
+ GHashTable *bookmarks_hash;
+ struct menu *destinations;
+ struct point pressed, last, current;
+ int button_pressed,moved,popped;
+ guint button_timeout, motion_timeout;
+ struct log *textfile_debug_log;
+ struct pcoord destination;
+ int destination_valid;
+};
+
+struct gui *main_loop_gui;
+
+struct attr_iter {
+ union {
+ GList *list;
+ struct mapset_handle *mapset_handle;
+ } u;
+};
+
+static void navit_vehicle_update(struct navit *this_, struct navit_vehicle *nv);
+static void navit_vehicle_draw(struct navit *this_, struct navit_vehicle *nv, struct point *pnt);
+
+void
+navit_add_mapset(struct navit *this_, struct mapset *ms)
+{
+ this_->mapsets = g_list_append(this_->mapsets, ms);
+}
+
+struct mapset *
+navit_get_mapset(struct navit *this_)
+{
+ if(this_->mapsets){
+ return this_->mapsets->data;
+ } else {
+ g_warning("No mapsets enabled! Is it on purpose? Navit can't draw a map. Please check your navit.xml\n");
+ }
+ exit(-1);
+}
+
+struct tracking *
+navit_get_tracking(struct navit *this_)
+{
+ return this_->tracking;
+}
+
+void
+navit_add_layout(struct navit *this_, struct layout *lay)
+{
+ this_->layouts = g_list_append(this_->layouts, lay);
+ if(!this_->layout_current) {
+ this_->layout_current=lay;
+ }
+}
+
+void
+navit_draw(struct navit *this_)
+{
+ GList *l;
+ struct navit_vehicle *nv;
+
+ transform_setup_source_rect(this_->trans);
+ graphics_draw(this_->gra, this_->displaylist, this_->mapsets, this_->trans, this_->layout_current);
+ l=this_->vehicles;
+ while (l) {
+ nv=l->data;
+ navit_vehicle_draw(this_, nv, NULL);
+ l=g_list_next(l);
+ }
+}
+
+void
+navit_draw_displaylist(struct navit *this_)
+{
+ if (this_->ready == 3)
+ graphics_displaylist_draw(this_->gra, this_->displaylist, this_->trans, this_->layout_current);
+}
+
+void
+navit_resize(void *data, int w, int h)
+{
+ struct navit *this_=data;
+ struct map_selection sel;
+ memset(&sel, 0, sizeof(sel));
+ sel.u.p_rect.rl.x=w;
+ sel.u.p_rect.rl.y=h;
+ transform_set_screen_selection(this_->trans, &sel);
+ this_->ready |= 2;
+ if (this_->ready == 3)
+ navit_draw(this_);
+}
+
+static void
+navit_popup(void *data)
+{
+ struct navit *this_=data;
+ popup(this_, 1, &this_->pressed);
+ this_->button_timeout=0;
+ this_->popped=1;
+}
+
+
+static gboolean
+navit_handle_button_timeout(void *data)
+{
+ callback_call_0((struct callback *)data);
+ return FALSE;
+}
+
+
+int
+navit_handle_button(struct navit *this_, int pressed, int button, struct point *p, struct callback *popup_callback)
+{
+ int border=16;
+
+ if (pressed) {
+ this_->pressed=*p;
+ this_->last=*p;
+ if (button == 1) {
+ this_->button_pressed=1;
+ this_->moved=0;
+ this_->popped=0;
+ if (popup_callback)
+ this_->button_timeout=g_timeout_add(500, navit_handle_button_timeout, popup_callback);
+ }
+ if (button == 2)
+ navit_set_center_screen(this_, p);
+ if (button == 3)
+ popup(this_, button, p);
+ if (button == 4)
+ navit_zoom_in(this_, 2, p);
+ if (button == 5)
+ navit_zoom_out(this_, 2, p);
+ } else {
+ this_->button_pressed=0;
+ if (this_->button_timeout) {
+ g_source_remove(this_->button_timeout);
+ this_->button_timeout=0;
+ if (! this_->moved && ! transform_within_border(this_->trans, p, border))
+ navit_set_center_screen(this_, p);
+
+ }
+ if (this_->motion_timeout) {
+ g_source_remove(this_->motion_timeout);
+ this_->motion_timeout=0;
+ }
+ if (this_->moved) {
+ struct point p;
+ transform_get_size(this_->trans, &p.x, &p.y);
+ p.x/=2;
+ p.y/=2;
+ p.x-=this_->last.x-this_->pressed.x;
+ p.y-=this_->last.y-this_->pressed.y;
+ navit_set_center_screen(this_, &p);
+ } else
+ return 1;
+ }
+ return 0;
+}
+
+static void
+navit_button(void *data, int pressed, int button, struct point *p)
+{
+ struct navit *this=data;
+ if (! this->popup_callback)
+ this->popup_callback=callback_new_1(navit_popup, this);
+ navit_handle_button(this, pressed, button, p, this->popup_callback);
+}
+
+
+static gboolean
+navit_motion_timeout(void *data)
+{
+ struct navit *this_=data;
+ int dx, dy;
+
+ dx=(this_->current.x-this_->last.x);
+ dy=(this_->current.y-this_->last.y);
+ if (dx || dy) {
+ this_->last=this_->current;
+ graphics_displaylist_move(this_->displaylist, dx, dy);
+ graphics_displaylist_draw(this_->gra, this_->displaylist, this_->trans, this_->layout_current);
+ this_->moved=1;
+ }
+ this_->motion_timeout=0;
+ return FALSE;
+}
+
+void
+navit_handle_motion(struct navit *this_, struct point *p)
+{
+ int dx, dy;
+
+ if (this_->button_pressed && !this_->popped) {
+ dx=(p->x-this_->pressed.x);
+ dy=(p->y-this_->pressed.y);
+ if (dx < -8 || dx > 8 || dy < -8 || dy > 8) {
+ if (this_->button_timeout) {
+ g_source_remove(this_->button_timeout);
+ this_->button_timeout=0;
+ }
+ this_->current=*p;
+ if (! this_->motion_timeout)
+ this_->motion_timeout=g_timeout_add(100, navit_motion_timeout, this_);
+ }
+ }
+}
+
+static void
+navit_motion(void *data, struct point *p)
+{
+ navit_handle_motion((struct navit *)data, p);
+}
+
+static void
+navit_scale(struct navit *this_, long scale, struct point *p)
+{
+ struct coord c1, c2, *center;
+ if (p)
+ transform_reverse(this_->trans, p, &c1);
+ transform_set_scale(this_->trans, scale);
+ if (p) {
+ transform_reverse(this_->trans, p, &c2);
+ center = transform_center(this_->trans);
+ center->x += c1.x - c2.x;
+ center->y += c1.y - c2.y;
+ }
+ navit_draw(this_);
+}
+
+/**
+ * Change the current zoom level, zooming closer to the ground
+ *
+ * @param navit The navit instance
+ * @param factor The zoom factor, usually 2
+ * @param p The invariant point (if set to NULL, default to center)
+ * @returns nothing
+ */
+void
+navit_zoom_in(struct navit *this_, int factor, struct point *p)
+{
+ long scale=transform_get_scale(this_->trans)/factor;
+ if (scale < 1)
+ scale=1;
+ navit_scale(this_, scale, p);
+}
+
+/**
+ * Change the current zoom level
+ *
+ * @param navit The navit instance
+ * @param factor The zoom factor, usually 2
+ * @param p The invariant point (if set to NULL, default to center)
+ * @returns nothing
+ */
+void
+navit_zoom_out(struct navit *this_, int factor, struct point *p)
+{
+ long scale=transform_get_scale(this_->trans)*factor;
+ navit_scale(this_, scale, p);
+}
+
+struct navit *
+navit_new(struct attr *parent, struct attr **attrs)
+{
+ struct navit *this_=g_new0(struct navit, 1);
+ struct pcoord center;
+ struct coord co;
+ struct coord_geo g;
+ enum projection pro=projection_mg;
+ int zoom = 256;
+ FILE *f;
+ g.lat=53.13;
+ g.lng=11.70;
+
+ main_add_navit(this_);
+ this_->self.type=attr_navit;
+ this_->self.u.navit=this_;
+ this_->attr_cbl=callback_list_new();
+
+ f=popen("pidof /usr/bin/ipaq-sleep","r");
+ if (f) {
+ fscanf(f,"%d",&this_->pid);
+ dbg(1,"ipaq_sleep pid=%d\n", this_->pid);
+ pclose(f);
+ }
+
+ this_->bookmarks_hash=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+
+ this_->cursor_flag=1;
+ this_->orient_north_flag=0;
+ this_->tracking_flag=1;
+
+ for (;*attrs; attrs++) {
+ switch((*attrs)->type) {
+ case attr_zoom:
+ zoom=(*attrs)->u.num;
+ break;
+ case attr_center:
+ g=*((*attrs)->u.coord_geo);
+ break;
+ case attr_cursor:
+ this_->cursor_flag=!!(*attrs)->u.num;
+ break;
+ case attr_orientation:
+ this_->orient_north_flag=!!(*attrs)->u.num;
+ break;
+ case attr_tracking:
+ this_->tracking_flag=!!(*attrs)->u.num;
+ break;
+ default:
+ dbg(0, "Unexpected attribute %x\n",(*attrs)->type);
+ break;
+ }
+ }
+ transform_from_geo(pro, &g, &co);
+ center.x=co.x;
+ center.y=co.y;
+ center.pro = pro;
+
+ this_->trans=transform_new();
+ transform_setup(this_->trans, &center, zoom, 0);
+ this_->displaylist=graphics_displaylist_new();
+ return this_;
+}
+
+static int
+navit_set_gui(struct navit *this_, struct gui *gui)
+{
+ if (this_->gui)
+ return 0;
+ this_->gui=gui;
+ if (gui_has_main_loop(this_->gui)) {
+ if (! main_loop_gui) {
+ main_loop_gui=this_->gui;
+ } else {
+ g_warning("gui with main loop already active, ignoring this instance");
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+navit_set_graphics(struct navit *this_, struct graphics *gra)
+{
+ if (this_->gra)
+ return 0;
+ this_->gra=gra;
+ graphics_register_resize_callback(this_->gra, navit_resize, this_);
+ graphics_register_button_callback(this_->gra, navit_button, this_);
+ graphics_register_motion_callback(this_->gra, navit_motion, this_);
+ return 1;
+}
+
+struct graphics *
+navit_get_graphics(struct navit *this_)
+{
+ return this_->gra;
+}
+
+static void
+navit_projection_set(struct navit *this_, enum projection pro)
+{
+ struct coord_geo g;
+ struct coord *c;
+
+ c=transform_center(this_->trans);
+ transform_to_geo(transform_get_projection(this_->trans), c, &g);
+ transform_set_projection(this_->trans, pro);
+ transform_from_geo(pro, &g, c);
+ navit_draw(this_);
+}
+
+static void
+navit_add_menu_destinations(struct navit *this_, char *name, struct menu *rmen, GHashTable *h, struct callback *cb)
+{
+ char buffer2[2048];
+ char *i,*n;
+ struct menu *men,*nmen;
+
+ if (rmen) {
+ i=name;
+ n=name;
+ men=rmen;
+ while (h && (i=strchr(n, '/'))) {
+ strcpy(buffer2, name);
+ buffer2[i-name]='\0';
+ if (!(nmen=g_hash_table_lookup(h, buffer2))) {
+ nmen=menu_add(men, buffer2+(n-name), menu_type_submenu, NULL);
+ g_hash_table_insert(h, g_strdup(buffer2), nmen);
+ }
+ n=i+1;
+ men=nmen;
+ }
+ menu_add(men, n, menu_type_menu, cb);
+ }
+}
+
+static void
+navit_append_coord(struct navit *this_, char *file, struct pcoord *c, char *type, char *description, struct menu *rmen, GHashTable *h, void (*cb_func)(void))
+{
+ FILE *f;
+ int offset=0;
+ char *buffer;
+ const char *prostr;
+ struct callback *cb;
+
+ f=fopen(file, "a");
+ if (f) {
+ offset=ftell(f);
+ if (c) {
+ prostr = projection_to_name(c->pro);
+ fprintf(f,"%s%s0x%x 0x%x type=%s label=\"%s\"\n",
+ prostr, *prostr ? ":" : "", c->x, c->y, type, description);
+ } else
+ fprintf(f,"\n");
+ fclose(f);
+ }
+ if (c) {
+ buffer=g_strdup(description);
+ cb=callback_new_2(cb_func, this_, (void *)offset);
+ navit_add_menu_destinations(this_, buffer, rmen, h, cb);
+ g_free(buffer);
+ }
+}
+
+static int
+parse_line(FILE *f, char *buffer, char **name, struct pcoord *c)
+{
+ int pos;
+ char *s,*i;
+ struct coord co;
+ char *cp;
+ enum projection pro = projection_mg;
+ *name=NULL;
+ if (! fgets(buffer, 2048, f))
+ return -3;
+ cp = buffer;
+ pos=coord_parse(cp, pro, &co);
+ if (!pos)
+ return -2;
+ if (!cp[pos] || cp[pos] == '\n')
+ return -1;
+ cp[strlen(cp)-1]='\0';
+ s=cp+pos+1;
+ if (!strncmp(s,"type=", 5)) {
+ i=strchr(s, '"');
+ if (i) {
+ s=i+1;
+ i=strchr(s, '"');
+ if (i)
+ *i='\0';
+ }
+ }
+ *name=s;
+ c->x = co.x;
+ c->y = co.y;
+ c->pro = pro;
+ return pos;
+}
+
+
+static void
+navit_set_destination_from_file(struct navit *this_, char *file, int bookmark, int offset)
+{
+ FILE *f;
+ char *name, *description, buffer[2048];
+ struct pcoord c;
+
+ f=fopen(file, "r");
+ if (! f)
+ return;
+ fseek(f, offset, SEEK_SET);
+ if (parse_line(f, buffer, &name, &c) <= 0)
+ return;
+ if (bookmark) {
+ description=g_strdup_printf("Bookmark %s", name);
+ navit_set_destination(this_, &c, description);
+ g_free(description);
+ } else
+ navit_set_destination(this_, &c, name);
+}
+
+static void
+navit_set_destination_from_destination(struct navit *this_, void *offset_p)
+{
+ navit_set_destination_from_file(this_, "destination.txt", 0, (int)offset_p);
+}
+
+static void
+navit_set_destination_from_bookmark(struct navit *this_, void *offset_p)
+{
+ navit_set_destination_from_file(this_, "bookmark.txt", 1, (int)offset_p);
+}
+
+/**
+ * Start the route computing to a given set of coordinates
+ *
+ * @param navit The navit instance
+ * @param c The coordinate to start routing to
+ * @param description A label which allows the user to later identify this destination in the former destinations selection
+ * @returns nothing
+ */
+void
+navit_set_destination(struct navit *this_, struct pcoord *c, char *description)
+{
+ if (c) {
+ this_->destination=*c;
+ this_->destination_valid=1;
+ } else
+ this_->destination_valid=0;
+ navit_append_coord(this_, "destination.txt", c, "former_destination", description, this_->destinations, NULL, callback_cast(navit_set_destination_from_destination));
+ callback_list_call_attr_1(this_->attr_cbl, attr_destination, this_);
+ if (this_->route) {
+ route_set_destination(this_->route, c);
+ if (this_->navigation)
+ navigation_flush(this_->navigation);
+ navit_draw(this_);
+ }
+}
+
+/**
+ * Record the given set of coordinates as a bookmark
+ *
+ * @param navit The navit instance
+ * @param c The coordinate to store
+ * @param description A label which allows the user to later identify this bookmark
+ * @returns nothing
+ */
+void
+navit_add_bookmark(struct navit *this_, struct pcoord *c, const char *description)
+{
+ navit_append_coord(this_,"bookmark.txt", c, "bookmark", description, this_->bookmarks, this_->bookmarks_hash, callback_cast(navit_set_destination_from_bookmark));
+}
+
+struct navit *global_navit;
+
+static void
+navit_add_menu_destinations_from_file(struct navit *this_, char *file, struct menu *rmen, GHashTable *h, struct route *route, void (*cb_func)(void))
+{
+ int pos,flag=0;
+ FILE *f;
+ char buffer[2048];
+ struct pcoord c;
+ char *name;
+ int offset=0;
+ struct callback *cb;
+
+ f=fopen(file, "r");
+ if (f) {
+ while (! feof(f) && (pos=parse_line(f, buffer, &name, &c)) > -3) {
+ if (pos > 0) {
+ cb=callback_new_2(cb_func, this_, (void *)offset);
+ navit_add_menu_destinations(this_, name, rmen, h, cb);
+ flag=1;
+ } else
+ flag=0;
+ offset=ftell(f);
+ }
+ fclose(f);
+ if (route && flag) {
+ this_->destination=c;
+ this_->destination_valid=1;
+ route_set_destination(route, &c);
+ }
+ }
+}
+
+static void
+navit_add_menu_former_destinations(struct navit *this_, struct menu *men, struct route *route)
+{
+ if (men)
+ this_->destinations=menu_add(men, _("Former Destinations"), menu_type_submenu, NULL);
+ else
+ this_->destinations=NULL;
+ navit_add_menu_destinations_from_file(this_, "destination.txt", this_->destinations, NULL, route, callback_cast(navit_set_destination_from_destination));
+}
+
+static void
+navit_add_menu_bookmarks(struct navit *this_, struct menu *men)
+{
+ if (men)
+ this_->bookmarks=menu_add(men, _("Bookmarks"), menu_type_submenu, NULL);
+ else
+ this_->bookmarks=NULL;
+ navit_add_menu_destinations_from_file(this_, "bookmark.txt", this_->bookmarks, this_->bookmarks_hash, NULL, callback_cast(navit_set_destination_from_bookmark));
+}
+
+static void
+navit_add_bookmarks_from_file(struct navit *this_)
+{
+ struct attr type={attr_type, {"textfile"}}, data={attr_data, {"bookmark.txt"}};
+ struct attr *attrs[]={&type, &data, NULL};
+
+ this_->bookmark=map_new("textfile", attrs);
+}
+
+static void
+navit_add_former_destinations_from_file(struct navit *this_)
+{
+ struct attr type={attr_type, {"textfile"}}, data={attr_data, {"destination.txt"}};
+ struct attr *attrs[]={&type, &data, NULL};
+
+ this_->former_destination=map_new("textfile", attrs);
+}
+
+
+static void
+navit_textfile_debug_log(struct navit *this_, const char *fmt, ...)
+{
+ va_list ap;
+ char *str1,*str2;
+ va_start(ap, fmt);
+ if (this_->textfile_debug_log && this_->vehicle) {
+ str1=g_strdup_vprintf(fmt, ap);
+ str2=g_strdup_printf("0x%x 0x%x%s%s\n", this_->vehicle->coord.x, this_->vehicle->coord.y, strlen(str1) ? " " : "", str1);
+ log_write(this_->textfile_debug_log, str2, strlen(str2));
+ g_free(str2);
+ g_free(str1);
+ }
+ va_end(ap);
+}
+
+
+void
+navit_speak(struct navit *this_)
+{
+ struct navigation *nav=this_->navigation;
+ struct map *map=NULL;
+ struct map_rect *mr=NULL;
+ struct item *item;
+ struct attr attr;
+
+ if (nav)
+ map=navigation_get_map(nav);
+ if (map)
+ mr=map_rect_new(map, NULL);
+ if (mr) {
+ item=map_rect_get_item(mr);
+ if (item && item_attr_get(item, attr_navigation_speech, &attr)) {
+ speech_say(this_->speech, attr.u.str);
+ navit_textfile_debug_log(this_, "item=point_debug debug=\"speech_say('%s')\"", attr.u.str);
+ }
+ map_rect_destroy(mr);
+ }
+}
+
+static void
+navit_window_roadbook_update(struct navit *this_)
+{
+ struct navigation *nav=this_->navigation;
+ struct map *map=NULL;
+ struct map_rect *mr=NULL;
+ struct item *item;
+ struct attr attr;
+ struct param_list param[5];
+ int secs;
+
+ dbg(1,"enter\n");
+ datawindow_mode(this_->roadbook_window, 1);
+ if (nav)
+ map=navigation_get_map(nav);
+ if (map)
+ mr=map_rect_new(map, NULL);
+ dbg(0,"nav=%p map=%p mr=%p\n", nav, map, mr);
+ if (mr) {
+ dbg(0,"while loop\n");
+ while ((item=map_rect_get_item(mr))) {
+ dbg(0,"item=%p\n", item);
+ attr.u.str=NULL;
+ item_attr_get(item, attr_navigation_long, &attr);
+ dbg(2, "Command='%s'\n", attr.u.str);
+ param[0].name=_("Command");
+ param[0].value=g_strdup(attr.u.str);
+
+ item_attr_get(item, attr_length, &attr);
+ dbg(2, "Length=%d\n", attr.u.num);
+ param[1].name=_("Length");
+
+ if ( attr.u.num >= 2000 )
+ {
+ param[1].value=g_strdup_printf("%5.1f %s",(float)attr.u.num / 1000, _("km") );
+ }
+ else
+ {
+ param[1].value=g_strdup_printf("%7d %s",attr.u.num, _("m"));
+ }
+
+ item_attr_get(item, attr_time, &attr);
+ dbg(2, "Time=%d\n", attr.u.num);
+ secs=attr.u.num/10;
+ param[2].name=_("Time");
+ if ( secs >= 3600 )
+ {
+ param[2].value=g_strdup_printf("%d:%02d:%02d",secs / 60, ( secs / 60 ) % 60 , secs % 60);
+ }
+ else
+ {
+ param[2].value=g_strdup_printf("%d:%02d",secs / 60, secs % 60);
+ }
+
+ item_attr_get(item, attr_destination_length, &attr);
+ dbg(2, "Destlength=%d\n", attr.u.num);
+ param[3].name=_("Destination Length");
+ if ( attr.u.num >= 2000 )
+ {
+ param[3].value=g_strdup_printf("%5.1f %s",(float)attr.u.num / 1000, _("km") );
+ }
+ else
+ {
+ param[3].value=g_strdup_printf("%d %s",attr.u.num, _("m"));
+ }
+
+ item_attr_get(item, attr_destination_time, &attr);
+ dbg(2, "Desttime=%d\n", attr.u.num);
+ secs=attr.u.num/10;
+ param[4].name=_("Destination Time");
+ if ( secs >= 3600 )
+ {
+ param[4].value=g_strdup_printf("%d:%02d:%02d",secs / 3600, (secs / 60 ) % 60 , secs % 60);
+ }
+ else
+ {
+ param[4].value=g_strdup_printf("%d:%02d",secs / 60, secs % 60);
+ }
+ datawindow_add(this_->roadbook_window, param, 5);
+ }
+ map_rect_destroy(mr);
+ }
+ datawindow_mode(this_->roadbook_window, 0);
+}
+
+void
+navit_window_roadbook_destroy(struct navit *this_)
+{
+ dbg(0, "enter\n");
+ navigation_unregister_callback(this_->navigation, attr_navigation_long, this_->roadbook_callback);
+ this_->roadbook_window=NULL;
+ this_->roadbook_callback=NULL;
+}
+void
+navit_window_roadbook_new(struct navit *this_)
+{
+ this_->roadbook_callback=callback_new_1(callback_cast(navit_window_roadbook_update), this_);
+ navigation_register_callback(this_->navigation, attr_navigation_long, this_->roadbook_callback);
+ this_->roadbook_window=gui_datawindow_new(this_->gui, _("Roadbook"), NULL, callback_new_1(callback_cast(navit_window_roadbook_destroy), this_));
+ navit_window_roadbook_update(this_);
+}
+
+static void
+get_direction(char *buffer, int angle, int mode)
+{
+ angle=angle%360;
+ switch (mode) {
+ case 0:
+ sprintf(buffer,"%d",angle);
+ break;
+ case 1:
+ if (angle < 69 || angle > 291)
+ *buffer++='N';
+ if (angle > 111 && angle < 249)
+ *buffer++='S';
+ if (angle > 22 && angle < 158)
+ *buffer++='E';
+ if (angle > 202 && angle < 338)
+ *buffer++='W';
+ *buffer++='\0';
+ break;
+ case 2:
+ angle=(angle+15)/30;
+ if (! angle)
+ angle=12;
+ sprintf(buffer,"%d H", angle);
+ break;
+ }
+}
+
+struct navit_window_items {
+ struct datawindow *win;
+ struct callback *click;
+ char *name;
+ int distance;
+ GHashTable *hash;
+ GList *list;
+};
+
+static void
+navit_window_items_click(struct navit *this_, struct navit_window_items *nwi, char **col)
+{
+ struct pcoord c;
+ char *description;
+
+ // FIXME
+ dbg(0,"enter col=%s,%s,%s,%s,%s\n", col[0], col[1], col[2], col[3], col[4]);
+ sscanf(col[4], "0x%x,0x%x", &c.x, &c.y);
+ c.pro = projection_mg;
+ dbg(0,"0x%x,0x%x\n", c.x, c.y);
+ description=g_strdup_printf("%s %s", nwi->name, col[3]);
+ navit_set_destination(this_, &c, description);
+ g_free(description);
+}
+
+static void
+navit_window_items_open(struct navit *this_, struct navit_window_items *nwi)
+{
+ struct map_selection sel;
+ struct coord c,*center;
+ struct mapset_handle *h;
+ struct map *m;
+ struct map_rect *mr;
+ struct item *item;
+ struct attr attr;
+ int idist,dist;
+ struct param_list param[5];
+ char distbuf[32];
+ char dirbuf[32];
+ char coordbuf[64];
+
+ dbg(0, "distance=%d\n", nwi->distance);
+ if (nwi->distance == -1)
+ dist=40000000;
+ else
+ dist=nwi->distance*1000;
+ param[0].name="Distance";
+ param[1].name="Direction";
+ param[2].name="Type";
+ param[3].name="Name";
+ param[4].name=NULL;
+ sel.next=NULL;
+#if 0
+ sel.order[layer_town]=18;
+ sel.order[layer_street]=18;
+ sel.order[layer_poly]=18;
+#else
+ sel.order[layer_town]=0;
+ sel.order[layer_street]=0;
+ sel.order[layer_poly]=0;
+#endif
+ center=transform_center(this_->trans);
+ sel.u.c_rect.lu.x=center->x-dist;
+ sel.u.c_rect.lu.y=center->y+dist;
+ sel.u.c_rect.rl.x=center->x+dist;
+ sel.u.c_rect.rl.y=center->y-dist;
+ dbg(2,"0x%x,0x%x - 0x%x,0x%x\n", sel.u.c_rect.lu.x, sel.u.c_rect.lu.y, sel.u.c_rect.rl.x, sel.u.c_rect.rl.y);
+ nwi->click=callback_new_2(callback_cast(navit_window_items_click), this_, nwi);
+ nwi->win=gui_datawindow_new(this_->gui, nwi->name, nwi->click, NULL);
+ h=mapset_open(navit_get_mapset(this_));
+ while ((m=mapset_next(h, 1))) {
+ dbg(2,"m=%p %s\n", m, map_get_filename(m));
+ mr=map_rect_new(m, &sel);
+ dbg(2,"mr=%p\n", mr);
+ while ((item=map_rect_get_item(mr))) {
+ if (item_coord_get(item, &c, 1)) {
+ if (coord_rect_contains(&sel.u.c_rect, &c) && g_hash_table_lookup(nwi->hash, &item->type)) {
+ if (! item_attr_get(item, attr_label, &attr))
+ attr.u.str="";
+ idist=transform_distance(map_projection(item->map), center, &c);
+ if (idist < dist) {
+ get_direction(dirbuf, transform_get_angle_delta(center, &c, 0), 1);
+ param[0].value=distbuf;
+ param[1].value=dirbuf;
+ param[2].value=item_to_name(item->type);
+ sprintf(distbuf,"%d", idist/1000);
+ param[3].value=attr.u.str;
+ sprintf(coordbuf, "0x%x,0x%x", c.x, c.y);
+ param[4].value=coordbuf;
+ datawindow_add(nwi->win, param, 5);
+ }
+ /* printf("gefunden %s %s %d\n",item_to_name(item->type), attr.u.str, idist/1000); */
+ }
+ if (item->type >= type_line)
+ while (item_coord_get(item, &c, 1));
+ }
+ }
+ map_rect_destroy(mr);
+ }
+ mapset_close(h);
+}
+
+struct navit_window_items *
+navit_window_items_new(const char *name, int distance)
+{
+ struct navit_window_items *nwi=g_new0(struct navit_window_items, 1);
+ nwi->name=g_strdup(name);
+ nwi->distance=distance;
+ nwi->hash=g_hash_table_new(g_int_hash, g_int_equal);
+
+ return nwi;
+}
+
+void
+navit_window_items_add_item(struct navit_window_items *nwi, enum item_type type)
+{
+ nwi->list=g_list_prepend(nwi->list, (void *)type);
+ g_hash_table_insert(nwi->hash, &nwi->list->data, (void *)1);
+}
+
+void
+navit_add_window_items(struct navit *this_, struct navit_window_items *nwi)
+{
+ this_->windows_items=g_list_append(this_->windows_items, nwi);
+}
+
+static void
+navit_add_menu_windows_items(struct navit *this_, struct menu *men)
+{
+ struct navit_window_items *nwi;
+ struct callback *cb;
+ GList *l;
+ l=this_->windows_items;
+ while (l) {
+ nwi=l->data;
+ cb=callback_new_2(callback_cast(navit_window_items_open), this_, nwi);
+ menu_add(men, nwi->name, menu_type_menu, cb);
+ l=g_list_next(l);
+ }
+}
+
+void
+navit_init(struct navit *this_)
+{
+ struct mapset *ms;
+ struct map *map;
+ GList *l;
+ struct navit_vehicle *nv;
+
+ if (!this_->gui) {
+ g_warning("no gui\n");
+ navit_destroy(this_);
+ return;
+ }
+ if (!this_->gra) {
+ g_warning("no graphics\n");
+ navit_destroy(this_);
+ return;
+ }
+ if (gui_set_graphics(this_->gui, this_->gra)) {
+ struct attr attr_type_gui, attr_type_graphics;
+ gui_get_attr(this_->gui, attr_type, &attr_type_gui, NULL);
+ graphics_get_attr(this_->gra, attr_type, &attr_type_graphics, NULL);
+ g_warning("failed to connect graphics '%s' to gui '%s'\n", attr_type_graphics.u.str, attr_type_gui.u.str);
+ g_warning(" Please see http://wiki.navit-project.org/index.php/Failed_to_connect_graphics_to_gui\n");
+ g_warning(" for explanations and solutions\n");
+
+ navit_destroy(this_);
+ return;
+ }
+ graphics_init(this_->gra);
+ l=this_->vehicles;
+ while (l) {
+ dbg(1,"parsed one vehicle\n");
+ nv=l->data;
+ nv->cursor=cursor_new(this_->gra, &nv->c, nv->c2, nv->animate_cursor);
+ nv->callback.type=attr_callback;
+ nv->callback.u.callback=callback_new_2(callback_cast(navit_vehicle_update), this_, nv);
+ vehicle_add_attr(nv->vehicle, &nv->callback);
+ vehicle_set_attr(nv->vehicle, &this_->self, NULL);
+ l=g_list_next(l);
+ }
+ if (this_->mapsets) {
+ ms=this_->mapsets->data;
+ if (this_->route) {
+ if ((map=route_get_map(this_->route)))
+ mapset_add(ms, map);
+ if ((map=route_get_graph_map(this_->route))) {
+ mapset_add(ms, map);
+ map_set_active(map, 0);
+ }
+ route_set_mapset(this_->route, ms);
+ }
+ if (this_->tracking)
+ tracking_set_mapset(this_->tracking, ms);
+ if (this_->navigation) {
+ if ((map=navigation_get_map(this_->navigation))) {
+ mapset_add(ms, map);
+ map_set_active(map, 0);
+ }
+ }
+ navit_add_bookmarks_from_file(this_);
+ navit_add_former_destinations_from_file(this_);
+ navit_add_menu_former_destinations(this_, NULL, this_->route);
+ }
+ if (this_->navigation && this_->speech) {
+ this_->nav_speech_cb=callback_new_1(callback_cast(navit_speak), this_);
+ navigation_register_callback(this_->navigation, attr_navigation_speech, this_->nav_speech_cb);
+ }
+#if 0
+ if (this_->menubar) {
+ men=menu_add(this_->menubar, "Data", menu_type_submenu, NULL);
+ if (men) {
+ navit_add_menu_windows_items(this_, men);
+ }
+ }
+#endif
+ global_navit=this_;
+#if 0
+ navit_window_roadbook_new(this_);
+ navit_window_items_new(this_);
+#endif
+ callback_list_call_attr_1(this_->attr_cbl, attr_navit, this_);
+ this_->ready|=1;
+ if (this_->ready == 3)
+ navit_draw(this_);
+}
+
+void
+navit_set_center(struct navit *this_, struct pcoord *center)
+{
+ struct coord *c=transform_center(this_->trans);
+ struct coord c1,c2;
+ enum projection pro = transform_get_projection(this_->trans);
+ if (pro != center->pro) {
+ c1.x = center->x;
+ c1.y = center->y;
+ transform_from_to(&c1, center->pro, &c2, pro);
+ } else {
+ c2.x = center->x;
+ c2.y = center->y;
+ }
+ *c=c2;
+ if (this_->ready == 3)
+ navit_draw(this_);
+}
+
+static void
+navit_set_center_cursor(struct navit *this_, struct coord *cursor, int dir, int xpercent, int ypercent)
+{
+ struct coord *c=transform_center(this_->trans);
+ int width, height;
+ struct point p;
+ struct coord cnew;
+
+ transform_get_size(this_->trans, &width, &height);
+ *c=*cursor;
+ transform_set_angle(this_->trans, dir);
+ p.x=(100-xpercent)*width/100;
+ p.y=(100-ypercent)*height/100;
+ transform_reverse(this_->trans, &p, &cnew);
+ *c=cnew;
+ if (this_->ready == 3)
+ navit_draw(this_);
+}
+
+
+void
+navit_set_center_screen(struct navit *this_, struct point *p)
+{
+ struct coord c;
+ struct pcoord pc;
+ transform_reverse(this_->trans, p, &c);
+ pc.x = c.x;
+ pc.y = c.y;
+ pc.pro = transform_get_projection(this_->trans);
+ navit_set_center(this_, &pc);
+}
+
+int
+navit_set_attr(struct navit *this_, struct attr *attr)
+{
+ int dir=0, orient_old=0, attr_updated=0;
+
+ switch (attr->type) {
+ case attr_cursor:
+ if (this_->cursor_flag != !!attr->u.num) {
+ this_->cursor_flag=!!attr->u.num;
+ attr_updated=1;
+ }
+ break;
+ case attr_layout:
+ if(this_->layout_current!=attr->u.layout) {
+ this_->layout_current=attr->u.layout;
+ navit_draw(this_);
+ attr_updated=1;
+ }
+ break;
+ case attr_orientation:
+ orient_old=this_->orient_north_flag;
+ this_->orient_north_flag=!!attr->u.num;
+ if (this_->orient_north_flag) {
+ dir = 0;
+ } else {
+ if (this_->vehicle) {
+ dir = this_->vehicle->dir;
+ }
+ }
+ transform_set_angle(this_->trans, dir);
+ if (orient_old != this_->orient_north_flag) {
+ navit_draw(this_);
+ attr_updated=1;
+ }
+ break;
+ case attr_projection:
+ if(this_->trans && transform_get_projection(this_->trans) != attr->u.projection) {
+ navit_projection_set(this_, attr->u.projection);
+ attr_updated=1;
+ }
+ break;
+ case attr_tracking:
+ if (this_->tracking_flag != !!attr->u.num) {
+ this_->tracking_flag=!!attr->u.num;
+ attr_updated=1;
+ }
+ break;
+ case attr_vehicle:
+ if (!this_->vehicle || this_->vehicle->vehicle != attr->u.vehicle) {
+ GList *l;
+ l=this_->vehicles;
+ while(l) {
+ if (((struct navit_vehicle *)l->data)->vehicle == attr->u.vehicle) {
+ this_->vehicle=(struct navit_vehicle *)l->data;
+ attr_updated=1;
+ }
+ l=g_list_next(l);
+ }
+ }
+ break;
+ default:
+ return 0;
+ }
+ if (attr_updated) {
+ callback_list_call_attr_2(this_->attr_cbl, attr->type, this_, attr);
+ }
+ return 1;
+}
+
+int
+navit_get_attr(struct navit *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
+{
+ switch (type) {
+ case attr_bookmark_map:
+ attr->u.map=this_->bookmark;
+ break;
+ case attr_cursor:
+ attr->u.num=this_->cursor_flag;
+ break;
+ case attr_destination:
+ if (! this_->destination_valid)
+ return 0;
+ attr->u.pcoord=&this_->destination;
+ break;
+ case attr_former_destination_map:
+ attr->u.map=this_->former_destination;
+ break;
+ case attr_layout:
+ if (iter) {
+ if (iter->u.list) {
+ iter->u.list=g_list_next(iter->u.list);
+ } else {
+ iter->u.list=this_->layouts;
+ }
+ if (!iter->u.list)
+ return 0;
+ attr->u.layout=(struct layout *)iter->u.list->data;
+ } else {
+ attr->u.layout=this_->layout_current;
+ }
+ break;
+ case attr_map:
+ if (iter && this_->mapsets) {
+ if (!iter->u.mapset_handle) {
+ iter->u.mapset_handle=mapset_open((struct mapset *)this_->mapsets->data);
+ }
+ attr->u.map=mapset_next(iter->u.mapset_handle, 0);
+ if(!attr->u.map) {
+ mapset_close(iter->u.mapset_handle);
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+ break;
+ case attr_orientation:
+ attr->u.num=this_->orient_north_flag;
+ break;
+ case attr_projection:
+ if(this_->trans) {
+ attr->u.num=transform_get_projection(this_->trans);
+ } else {
+ return 0;
+ }
+ break;
+ case attr_tracking:
+ attr->u.num=this_->tracking_flag;
+ break;
+ case attr_vehicle:
+ if(iter) {
+ if(iter->u.list) {
+ iter->u.list=g_list_next(iter->u.list);
+ } else {
+ iter->u.list=this_->vehicles;
+ }
+ if(!iter->u.list)
+ return 0;
+ attr->u.vehicle=((struct navit_vehicle*)iter->u.list->data)->vehicle;
+ } else {
+ if(this_->vehicle) {
+ attr->u.vehicle=this_->vehicle->vehicle;
+ } else {
+ return 0;
+ }
+ }
+ break;
+ default:
+ return 0;
+ }
+ attr->type=type;
+ return 1;
+}
+
+static int
+navit_add_log(struct navit *this_, struct log *log)
+{
+ struct attr type_attr;
+ if (!log_get_attr(log, attr_type, &type_attr, NULL))
+ return 0;
+ if (!strcmp(type_attr.u.str, "textfile_debug")) {
+ if (this_->textfile_debug_log)
+ return 0;
+ this_->textfile_debug_log=log;
+ return 1;
+ }
+ return 0;
+}
+
+int
+navit_add_attr(struct navit *this_, struct attr *attr)
+{
+ switch (attr->type) {
+ case attr_log:
+ return navit_add_log(this_, attr->u.log);
+ case attr_gui:
+ return navit_set_gui(this_, attr->u.gui);
+ case attr_graphics:
+ return navit_set_graphics(this_, attr->u.graphics);
+ case attr_route:
+ this_->route=attr->u.route;
+ route_set_projection(this_->route, transform_get_projection(this_->trans));
+ break;
+ case attr_navigation:
+ this_->navigation=attr->u.navigation;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+struct attr_iter *
+navit_attr_iter_new()
+{
+ return g_new0(struct attr_iter, 1);
+}
+
+void
+navit_attr_iter_destroy(struct attr_iter *iter)
+{
+ g_free(iter);
+}
+
+void
+navit_add_callback(struct navit *this_, struct callback *cb)
+{
+ callback_list_add(this_->attr_cbl, cb);
+}
+
+void
+navit_remove_callback(struct navit *this_, struct callback *cb)
+{
+ callback_list_remove(this_->attr_cbl, cb);
+}
+
+/**
+ * Toggle the cursor update : refresh the map each time the cursor has moved (instead of only when it reaches a border)
+ *
+ * @param navit The navit instance
+ * @returns nothing
+ */
+
+static void
+navit_vehicle_draw(struct navit *this_, struct navit_vehicle *nv, struct point *pnt)
+{
+ struct point pnt2;
+ enum projection pro;
+ if (pnt)
+ pnt2=*pnt;
+ else {
+ pro=transform_get_projection(this_->trans);
+ transform(this_->trans, pro, &nv->coord, &pnt2, 1, 0);
+ }
+#if 1
+ cursor_draw(nv->cursor, &pnt2, nv->dir-transform_get_angle(this_->trans, 0), nv->speed > 2, pnt == NULL);
+#else
+ cursor_draw(nv->cursor, &pnt2, nv->dir-transform_get_angle(this_->trans, 0), nv->speed > 2, 1);
+#endif
+}
+
+static void
+navit_vehicle_update(struct navit *this_, struct navit_vehicle *nv)
+{
+ struct attr attr_dir, attr_speed, attr_pos;
+ struct pcoord cursor_pc;
+ struct point cursor_pnt, *pnt=&cursor_pnt;
+ enum projection pro;
+ int border=16;
+ int route_path_set=0;
+
+ if (this_->ready != 3)
+ return;
+
+ if (! vehicle_get_attr(nv->vehicle, attr_position_direction, &attr_dir) ||
+ ! vehicle_get_attr(nv->vehicle, attr_position_speed, &attr_speed) ||
+ ! vehicle_get_attr(nv->vehicle, attr_position_coord_geo, &attr_pos))
+ return;
+ nv->dir=*attr_dir.u.numd;
+ nv->speed=*attr_speed.u.numd;
+ pro=transform_get_projection(this_->trans);
+ transform_from_geo(pro, attr_pos.u.coord_geo, &nv->coord);
+ if (nv != this_->vehicle) {
+ navit_vehicle_draw(this_, nv, NULL);
+ return;
+ }
+ if (this_->route)
+ route_path_set=route_get_path_set(this_->route);
+ if (this_->tracking && this_->tracking_flag) {
+ if (tracking_update(this_->tracking, &nv->coord, nv->dir)) {
+ if (this_->route && nv->update_curr == 1)
+ route_set_position_from_tracking(this_->route, this_->tracking);
+ }
+ } else {
+ if (this_->route && nv->update_curr == 1) {
+ cursor_pc.pro = pro;
+ cursor_pc.x = nv->coord.x;
+ cursor_pc.y = nv->coord.y;
+ route_set_position(this_->route, &cursor_pc);
+ }
+ }
+ transform(this_->trans, pro, &nv->coord, &cursor_pnt, 1, 0);
+ if (!transform_within_border(this_->trans, &cursor_pnt, border)) {
+ if (!this_->cursor_flag)
+ return;
+ if (nv->follow_curr != 1) {
+ if (this_->orient_north_flag)
+ navit_set_center_cursor(this_, &nv->coord, 0, 50 - 30.*sin(M_PI*nv->dir/180.), 50 + 30.*cos(M_PI*nv->dir/180.));
+ else
+ navit_set_center_cursor(this_, &nv->coord, nv->dir, 50, 80);
+ pnt=NULL;
+ }
+ }
+
+#ifndef _WIN32
+ if (this_->pid && nv->speed > 2)
+ kill(this_->pid, SIGWINCH);
+#endif
+ if (this_->route && nv->update_curr == 1)
+ navigation_update(this_->navigation, this_->route);
+ if (this_->cursor_flag && nv->follow_curr == 1) {
+ navit_set_center_cursor(this_, &nv->coord, nv->dir, 50, 80);
+ pnt=NULL;
+ }
+ if (pnt && this_->route && !route_path_set && route_get_path_set(this_->route))
+ navit_draw(this_);
+ if (nv->follow_curr > 1)
+ nv->follow_curr--;
+ else
+ nv->follow_curr=nv->follow;
+ if (nv->update_curr > 1)
+ nv->update_curr--;
+ else
+ nv->update_curr=nv->update;
+ callback_list_call_attr_2(this_->attr_cbl, attr_position_coord_geo, this_, nv->vehicle);
+ if (pnt)
+ navit_vehicle_draw(this_, nv, pnt);
+}
+
+/**
+ * Set the position of the vehicle
+ *
+ * @param navit The navit instance
+ * @param c The coordinate to set as position
+ * @returns nothing
+ */
+
+void
+navit_set_position(struct navit *this_, struct pcoord *c)
+{
+ if (this_->route) {
+ route_set_position(this_->route, c);
+ if (this_->navigation) {
+ navigation_update(this_->navigation, this_->route);
+ }
+ }
+ navit_draw(this_);
+}
+
+/**
+ * Register a new vehicle
+ *
+ * @param navit The navit instance
+ * @param v The vehicle instance
+ * @param name Guess? :)
+ * @param c The color to use for the cursor, currently only used in GTK
+ * @param update Wether to refresh the map each time this vehicle position changes (instead of only when it reaches a border)
+ * @param follow Wether to center the map on this vehicle position
+ * @returns a vehicle instance
+ */
+struct navit_vehicle *
+navit_add_vehicle(struct navit *this_, struct vehicle *v, struct attr **attrs)
+{
+ struct navit_vehicle *nv=g_new0(struct navit_vehicle, 1);
+ struct attr *update,*follow,*color,*active, *color2, *animate;
+ nv->vehicle=v;
+ nv->update=1;
+ nv->follow=0;
+ nv->animate_cursor=0;
+ if ((update=attr_search(attrs, NULL, attr_update)))
+ nv->update=nv->update=update->u.num;
+ if ((follow=attr_search(attrs, NULL, attr_follow)))
+ nv->follow=nv->follow=follow->u.num;
+ if ((color=attr_search(attrs, NULL, attr_color)))
+ nv->c=*(color->u.color);
+ if ((color2=attr_search(attrs, NULL, attr_color2)))
+ nv->c2=color2->u.color;
+ else
+ nv->c2=NULL;
+ nv->update_curr=nv->update;
+ nv->follow_curr=nv->follow;
+ this_->vehicles=g_list_append(this_->vehicles, nv);
+ if ((active=attr_search(attrs, NULL, attr_active)) && active->u.num)
+ navit_set_vehicle(this_, nv);
+ if ((animate=attr_search(attrs, NULL, attr_animate)))
+ nv->animate_cursor=animate->u.num;
+ return nv;
+}
+
+void
+navit_set_vehicle(struct navit *this_, struct navit_vehicle *nv)
+{
+ this_->vehicle=nv;
+}
+
+void
+navit_tracking_add(struct navit *this_, struct tracking *tracking)
+{
+ this_->tracking=tracking;
+}
+
+void
+navit_set_speech(struct navit *this_, struct speech *speech)
+{
+ this_->speech=speech;
+}
+
+
+struct gui *
+navit_get_gui(struct navit *this_)
+{
+ return this_->gui;
+}
+
+struct transformation *
+navit_get_trans(struct navit *this_)
+{
+ return this_->trans;
+}
+
+struct route *
+navit_get_route(struct navit *this_)
+{
+ return this_->route;
+}
+
+struct navigation *
+navit_get_navigation(struct navit *this_)
+{
+ return this_->navigation;
+}
+
+struct displaylist *
+navit_get_displaylist(struct navit *this_)
+{
+ return this_->displaylist;
+}
+
+void
+navit_destroy(struct navit *this_)
+{
+ /* TODO: destroy objects contained in this_ */
+ main_remove_navit(this_);
+ g_free(this_);
+}
+
+/** @} */
diff --git a/navit/navit.dtd b/navit/navit.dtd
new file mode 100644
index 000000000..3102dcf5f
--- /dev/null
+++ b/navit/navit.dtd
@@ -0,0 +1,77 @@
+<!ELEMENT config (plugins,debug*,navit)>
+<!ELEMENT plugins (plugin*)>
+<!ELEMENT plugin EMPTY>
+<!ATTLIST plugin path CDATA #REQUIRED>
+<!ATTLIST plugin active CDATA #IMPLIED>
+<!ELEMENT debug EMPTY>
+<!ATTLIST debug name CDATA #REQUIRED>
+<!ATTLIST debug level CDATA "0">
+<!ELEMENT navit (gui,graphics,vehicle*,tracking,route,navigation,speech,mapset+,layout+)>
+<!ATTLIST navit center CDATA #REQUIRED>
+<!ATTLIST navit zoom CDATA #REQUIRED>
+<!ATTLIST navit tracking CDATA #REQUIRED>
+<!ATTLIST navit cursor CDATA #REQUIRED>
+<!ATTLIST navit orientation CDATA #REQUIRED>
+<!ELEMENT gui EMPTY>
+<!ATTLIST gui type CDATA #REQUIRED>
+<!ATTLIST gui menubar CDATA #IMPLIED>
+<!ATTLIST gui toolbar CDATA #IMPLIED>
+<!ATTLIST gui statusbar CDATA #IMPLIED>
+<!ATTLIST gui skin CDATA #IMPLIED>
+<!ATTLIST gui fullscreen CDATA #IMPLIED>
+<!ELEMENT graphics EMPTY>
+<!ATTLIST graphics type CDATA #REQUIRED>
+<!ELEMENT vehicle EMPTY>
+<!ATTLIST vehicle name CDATA #REQUIRED>
+<!ATTLIST vehicle source CDATA #REQUIRED>
+<!ATTLIST vehicle color CDATA #REQUIRED>
+<!ATTLIST vehicle enabled CDATA #IMPLIED>
+<!ATTLIST vehicle active CDATA #IMPLIED>
+<!ATTLIST vehicle follow CDATA #IMPLIED>
+<!ATTLIST vehicle refresh CDATA #IMPLIED>
+<!ELEMENT tracking ANY>
+<!ELEMENT route (speed+)>
+<!ELEMENT speed EMPTY>
+<!ATTLIST speed type CDATA #REQUIRED>
+<!ATTLIST speed value CDATA #REQUIRED>
+<!ELEMENT navigation (announce+)>
+<!ELEMENT announce EMPTY>
+<!ATTLIST announce type CDATA #REQUIRED>
+<!ATTLIST announce level0 CDATA #IMPLIED>
+<!ATTLIST announce level1 CDATA #IMPLIED>
+<!ATTLIST announce level2 CDATA #IMPLIED>
+<!ATTLIST announce unit CDATA #REQUIRED>
+<!ELEMENT speech EMPTY>
+<!ATTLIST speech type CDATA #REQUIRED>
+<!ATTLIST speech data CDATA #REQUIRED>
+<!ELEMENT mapset (map+)>
+<!ATTLIST mapset enabled CDATA #IMPLIED>
+<!ELEMENT map EMPTY>
+<!ATTLIST map type CDATA #REQUIRED>
+<!ATTLIST map enabled CDATA #IMPLIED>
+<!ATTLIST map active CDATA #IMPLIED>
+<!ATTLIST map data CDATA #REQUIRED>
+<!ATTLIST map debug CDATA #IMPLIED>
+<!ELEMENT layout (layer*)>
+<!ATTLIST layout name CDATA #REQUIRED>
+<!ATTLIST layout color CDATA #IMPLIED>
+<!ELEMENT layer (item+)>
+<!ATTLIST layer name CDATA #REQUIRED>
+<!ATTLIST layer details CDATA #REQUIRED>
+<!ELEMENT item (polygon|polyline|label|circle|icon)*>
+<!ATTLIST item type CDATA #REQUIRED>
+<!ATTLIST item order CDATA #REQUIRED>
+<!ELEMENT polygon EMPTY>
+<!ATTLIST polygon color CDATA #REQUIRED>
+<!ELEMENT polyline EMPTY>
+<!ATTLIST polyline color CDATA #REQUIRED>
+<!ATTLIST polyline width CDATA #IMPLIED>
+<!ELEMENT label EMPTY>
+<!ATTLIST label label_size CDATA #REQUIRED>
+<!ELEMENT circle EMPTY>
+<!ATTLIST circle color CDATA #REQUIRED>
+<!ATTLIST circle radius CDATA #REQUIRED>
+<!ATTLIST circle label_size CDATA #IMPLIED>
+<!ELEMENT icon EMPTY>
+<!ATTLIST icon src CDATA #REQUIRED>
+
diff --git a/navit/navit.h b/navit/navit.h
new file mode 100644
index 000000000..ec76eeee4
--- /dev/null
+++ b/navit/navit.h
@@ -0,0 +1,80 @@
+#ifndef NAVIT_NAVIT_H
+#define NAVIT_NAVIT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern struct gui *main_loop_gui;
+/* prototypes */
+enum attr_type;
+enum item_type;
+struct attr;
+struct attr_iter;
+struct callback;
+struct displaylist;
+struct graphics;
+struct gui;
+struct layout;
+struct mapset;
+struct navigation;
+struct navit;
+struct navit_vehicle;
+struct navit_window_items;
+struct pcoord;
+struct point;
+struct route;
+struct speech;
+struct tracking;
+struct transformation;
+struct vehicle;
+void navit_add_mapset(struct navit *this_, struct mapset *ms);
+struct mapset *navit_get_mapset(struct navit *this_);
+struct tracking *navit_get_tracking(struct navit *this_);
+void navit_add_layout(struct navit *this_, struct layout *lay);
+void navit_draw(struct navit *this_);
+void navit_draw_displaylist(struct navit *this_);
+void navit_resize(void *data, int w, int h);
+int navit_handle_button(struct navit *this_, int pressed, int button, struct point *p, struct callback *popup_callback);
+void navit_handle_motion(struct navit *this_, struct point *p);
+void navit_zoom_in(struct navit *this_, int factor, struct point *p);
+void navit_zoom_out(struct navit *this_, int factor, struct point *p);
+struct navit *navit_new(struct attr *parent, struct attr **attrs);
+struct graphics *navit_get_graphics(struct navit *this_);
+void navit_set_destination(struct navit *this_, struct pcoord *c, char *description);
+void navit_add_bookmark(struct navit *this_, struct pcoord *c, const char *description);
+void navit_speak(struct navit *this_);
+void navit_window_roadbook_destroy(struct navit *this_);
+void navit_window_roadbook_new(struct navit *this_);
+struct navit_window_items *navit_window_items_new(const char *name, int distance);
+void navit_window_items_add_item(struct navit_window_items *nwi, enum item_type type);
+void navit_add_window_items(struct navit *this_, struct navit_window_items *nwi);
+void navit_init(struct navit *this_);
+void navit_set_center(struct navit *this_, struct pcoord *center);
+void navit_set_center_screen(struct navit *this_, struct point *p);
+int navit_set_attr(struct navit *this_, struct attr *attr);
+int navit_get_attr(struct navit *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter);
+int navit_add_attr(struct navit *this_, struct attr *attr);
+struct attr_iter *navit_attr_iter_new(void);
+void navit_attr_iter_destroy(struct attr_iter *iter);
+void navit_add_callback(struct navit *this_, struct callback *cb);
+void navit_remove_callback(struct navit *this_, struct callback *cb);
+void navit_set_position(struct navit *this_, struct pcoord *c);
+struct navit_vehicle *navit_add_vehicle(struct navit *this_, struct vehicle *v, struct attr **attrs);
+void navit_set_vehicle(struct navit *this_, struct navit_vehicle *nv);
+void navit_tracking_add(struct navit *this_, struct tracking *tracking);
+void navit_route_add(struct navit *this_, struct route *route);
+void navit_navigation_add(struct navit *this_, struct navigation *navigation);
+void navit_set_speech(struct navit *this_, struct speech *speech);
+struct gui *navit_get_gui(struct navit *this_);
+struct transformation *navit_get_trans(struct navit *this_);
+struct route *navit_get_route(struct navit *this_);
+struct navigation *navit_get_navigation(struct navit *this_);
+struct displaylist *navit_get_displaylist(struct navit *this_);
+void navit_destroy(struct navit *this_);
+/* end of prototypes */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/navit/navit.xml b/navit/navit.xml
new file mode 100644
index 000000000..dddcfd2ad
--- /dev/null
+++ b/navit/navit.xml
@@ -0,0 +1,2413 @@
+<!--
+For configuration options used in this file, please read
+http://wiki.navit-project.org/index.php/Configuring_NavIt
+-->
+
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE navit SYSTEM "navit.dtd">
+<config xmlns:xi="http://www.w3.org/2001/XInclude">
+<plugins>
+ <plugin path="$NAVIT_LIBDIR/*/${NAVIT_LIBPREFIX}lib*.so"/>
+ <plugin path="$NAVIT_LIBDIR/*/${NAVIT_LIBPREFIX}libgraphics_null.so" active="no" />
+</plugins>
+<debug name="navit:do_draw" level="0" />
+
+<!--
+Center coordinates format:
+[D][D]DMM.ss[S][S]... N/S [D][D]DMM.ss[S][S]... E/W
+[-][D]D.d[d]... [-][D][D]D.d[d]...
+[-]0xX [-]0xX
+Change to your home coordinates.
+-->
+
+
+<!--
+ This line defines which location on the map navit will show after startup.
+ It makes sense to set it to your home coordinates.
+-->
+<navit center="4808 N 1134 E" zoom="256" tracking="1" cursor="1" orientation="0">
+
+
+<!--
+ <osd type="compass" />
+ <osd type="eta" />
+ <osd type="navigation" />
+-->
+
+
+<!--
+ The following line let you select which graphical user interface you'd like to use.
+ The default is GTK:
+-->
+ <gui type="gtk" menubar="1" toolbar="1" statusbar="1" />
+ <graphics type="gtk_drawing_area" />
+
+<!-- For SDL, use rather the following lines
+ <gui type="sdl" />
+ <graphics type="opengl" />
+-->
+
+ <vehicle name="Mine" enabled="yes" active="1" source="gpsd://localhost" gpsd_query="w+xj" color="#0000ff"/>
+ <!-- To improve visibility of the cursor in gtk, you may optionally add:
+ color2="#rrggbb" - draws a second cursor inside the original, in the specified colour
+ animate="1" - animates the cursor, as series of moving dots
+ -->
+ <!-- For SDL, you should add follow="1" refresh="1" to have the view centered on your position
+ <vehicle name="Meins" enabled="yes" source="gpsd://localhost" color="#0000ff" follow="1" refresh="1"/>
+ -->
+
+ <vehicle name="Demo" enabled="no" source="demo://" color="#0000aa"/>
+
+ <tracking>
+ </tracking>
+
+ <route>
+ <speed type="street_0,street_1_city" value="10" />
+ <speed type="street_2_city" value="30" />
+ <speed type="street_3_city" value="40" />
+ <speed type="street_4_city" value="50" />
+ <speed type="highway_city" value="80" />
+ <speed type="street_1_land" value="60" />
+ <speed type="street_2_land" value="65" />
+ <speed type="street_3_land" value="70" />
+ <speed type="street_4_land" value="80" />
+ <speed type="street_n_lanes" value="120" />
+ <speed type="highway_land" value="120" />
+ <speed type="ramp" value="40" />
+ <speed type="ferry" value="40" />
+ </route>
+
+ <navigation>
+ <announce type="street_0,street_1_city" level0="10" level1="100" level2="200" unit="m" />
+ <announce type="street_2_city,street_3_city,street_4_city,ramp" level0="20" level1="200" level2="500" unit="m" />
+ <announce type="highway_city,street_1_land,street_2_land,street_3_land,street_4_land" level0="40" level1="400" level2="1000" unit="m" />
+ <announce type="street_n_lanes,highway_land" level0="100" level1="1000" level2="2000" unit="m" />
+ </navigation>
+
+
+ <!-- Navit provides speech output in text format.
+ If you have a speech synthesizer like festival lite installed, you can get turn by turn directions out of navit.
+ The default is text output to the shell
+ -->
+ <speech type="cmdline" data="echo 'Fix the speech tag in navit.xml to let navit say:' '%s'" />
+ <!--<speech type="cmdline" data="flite -t '%s'" />-->
+
+<!-- If you have the reiseplaner maps installed, set enabled="yes" in the next line -->
+ <mapset enabled="no">
+ <map type="mg" enabled="yes" data="/opt/reiseplaner/travel/DE.map" />
+ <map type="mg" enabled="yes" data="/opt/reiseplaner/travel/DE.map/smp1.smp" />
+ <map type="mg" enabled="yes" data="/opt/reiseplaner/travel/DE.map/smp2.smp" />
+ <map type="mg" enabled="yes" data="/opt/reiseplaner/travel/DE.map/smp3.smp" />
+ <map type="mg" enabled="yes" data="/opt/reiseplaner/travel/DE.map/smp4.smp" />
+ <map type="mg" enabled="yes" data="/opt/reiseplaner/travel/DE.map/smp5.smp" />
+ </mapset>
+
+<!-- If you dont want to use the sample map, either set enabled="no" in the next line or remove the xml file from the maps directory -->
+ <mapset enabled="yes">
+ <xi:include href="$NAVIT_SHAREDIR/maps/*.xml" />
+ </mapset>
+
+<!-- Sample mapset for garmin maps -->
+ <mapset enabled="no">
+ <map type="garmin" enabled="yes" data="/path/to/img" debug="4"/>
+ </mapset>
+
+ <layout name="Car" color= "#ffefb7">
+ <layer name="polygons">
+ <item type="image" order="0-">
+ <image />
+ </item>
+ <item type="poly_wood" order="0-">
+ <polygon color="#8ec78d" />
+ </item>
+ <item type="poly_town" order="0-">
+ <polygon color="#ffc895" />
+ <polyline color="#ebb481" />
+ </item>
+ <item type="poly_water" order="0-">
+ <polygon color="#82c8ea" />
+ <polyline color="#5096b8" />
+ <label label_size="5" />
+ </item>
+ <item type="poly_park" order="0-">
+ <polygon color="#7cc334" />
+ <label label_size="5" />
+ </item>
+ <item type="poly_pedestrian" order="10">
+ <polyline color="#d2d2d2" width="3" />
+ <polyline color="#dddddd" width="1" />
+ <polygon color="#dddddd" />
+ </item>
+ <item type="poly_pedestrian" order="11">
+ <polyline color="#d2d2d2" width="5" />
+ <polyline color="#dddddd" width="3" />
+ <polygon color="#dddddd" />
+ </item>
+ <item type="poly_pedestrian" order="12">
+ <polyline color="#d2d2d2" width="8" />
+ <polyline color="#dddddd" width="6" />
+ <polygon color="#dddddd" />
+ </item>
+ <item type="poly_pedestrian" order="13">
+ <polyline color="#d2d2d2" width="9" />
+ <polyline color="#dddddd" width="7" />
+ <polygon color="#dddddd" />
+ </item>
+ <item type="poly_pedestrian" order="14">
+ <polyline color="#d2d2d2" width="13" />
+ <polyline color="#dddddd" width="9" />
+ <polygon color="#dddddd" />
+ </item>
+ <item type="poly_pedestrian" order="15">
+ <polyline color="#d2d2d2" width="18" />
+ <polyline color="#dddddd" width="14" />
+ <polygon color="#dddddd" />
+ </item>
+ <item type="poly_pedestrian" order="16">
+ <polyline color="#d2d2d2" width="21" />
+ <polyline color="#dddddd" width="17" />
+ <polygon color="#dddddd" />
+ </item>
+ <item type="poly_pedestrian" order="17">
+ <polyline color="#d2d2d2" width="25" />
+ <polyline color="#dddddd" width="21" />
+ <polygon color="#dddddd" />
+ </item>
+ <item type="poly_pedestrian" order="18">
+ <polyline color="#d2d2d2" width="40" />
+ <polyline color="#dddddd" width="34" />
+ <polygon color="#dddddd" />
+ </item>
+ <item type="poly_airport" order="0-">
+ <polygon color="#a0a0a0" />
+ </item>
+ <item type="poly_sport" order="0-">
+ <polygon color="#4af04f" />
+ </item>
+ <item type="poly_industry,poly_place" order="0-">
+ <polygon color="#e6e6e6" />
+ </item>
+ <item type="poly_building" order="0-">
+ <polygon color="#b6a6a6" />
+ </item>
+ <item type="water_line" order="0-">
+ <polyline color="#5096b8" width="1" />
+ <label label_size="5" />
+ </item>
+ <item type="water_river" order="4-5">
+ <polyline color="#82c8ea" width="1" />
+ </item>
+ <item type="water_river" order="6">
+ <polyline color="#82c8ea" width="2" />
+ </item>
+ <item type="water_river" order="7">
+ <polyline color="#82c8ea" width="3" />
+ <label label_size="5" />
+ </item>
+ <item type="water_river" order="8-9">
+ <polyline color="#82c8ea" width="4" />
+ <label label_size="7" />
+ </item>
+ <item type="water_river" order="10-">
+ <polyline color="#82c8ea" width="4" />
+ <label label_size="10" />
+ </item>
+ <item type="water_canal" order="6">
+ <polyline color="#82c8ea" width="1" />
+ </item>
+ <item type="water_canal" order="7">
+ <polyline color="#82c8ea" width="2" />
+ <label label_size="5" />
+ </item>
+ <item type="water_canal" order="8-9">
+ <polyline color="#82c8ea" width="3" />
+ <label label_size="7" />
+ </item>
+ <item type="water_canal" order="10-">
+ <polyline color="#82c8ea" width="3" />
+ <label label_size="10" />
+ </item>
+ <item type="water_stream" order="8-9">
+ <polyline color="#82c8ea" width="1" />
+ </item>
+ <item type="water_stream" order="10-">
+ <polyline color="#82c8ea" width="2" />
+ <label label_size="7" />
+ </item>
+ <item type="water_drain" order="10-">
+ <polyline color="#82c8ea" width="1" />
+ <label label_size="5" />
+ </item>
+ <item type="poly_apron" order="0-">
+ <polygon color="#d0d0d0" />
+ </item>
+ <item type="poly_terminal" order="7-">
+ <polygon color="#e3c6a6" />
+ </item>
+ <item type="poly_cemetery" order="1-">
+ <polygon color="#bde3cb" />
+ </item>
+ <item type="poly_car_parking" order="1-">
+ <polygon color="#e7cf87" />
+ </item>
+ <item type="rail" order="6-">
+ <polyline color="#696969" width="3" />
+ <polyline color="#ffffff" width="1" dash="5,5" />
+ </item>
+ <item type="ferry" order="5-">
+ <polyline color="#000000" width="1" dash="10" />
+ </item>
+ <item type="border_country" order="0-">
+ <polyline color="#b8434e" width="1" dash="10,5,2,5" />
+ </item>
+ <item type="border_state" order="0-">
+ <polyline color="#808080" width="1" />
+ </item>
+ <item type="height_line_1" order="0-">
+ <polyline color="#000000" width="1" />
+ </item>
+ <item type="height_line_2" order="0-">
+ <polyline color="#000000" width="2" />
+ </item>
+ </layer>
+ <layer name="streets">
+ <item type="street_route" order="2">
+ <polyline color="#0000a0" width="4" />
+ </item>
+ <item type="street_route" order="3-5">
+ <polyline color="#0000a0" width="8" />
+ </item>
+ <item type="street_route" order="6">
+ <polyline color="#0000a0" width="10" />
+ </item>
+ <item type="street_route" order="7-8">
+ <polyline color="#0000a0" width="16" />
+ </item>
+ <item type="street_route" order="9-10">
+ <polyline color="#0000a0" width="20" />
+ </item>
+ <item type="street_route" order="11">
+ <polyline color="#0000a0" width="28" />
+ </item>
+ <item type="street_route" order="12">
+ <polyline color="#0000a0" width="32" />
+ </item>
+ <item type="street_route" order="13">
+ <polyline color="#0000a0" width="52" />
+ </item>
+ <item type="street_route" order="14">
+ <polyline color="#0000a0" width="64" />
+ </item>
+ <item type="street_route" order="15">
+ <polyline color="#0000a0" width="68" />
+ </item>
+ <item type="street_route" order="16">
+ <polyline color="#0000a0" width="132" />
+ </item>
+ <item type="street_route" order="17">
+ <polyline color="#0000a0" width="268" />
+ </item>
+ <item type="street_route" order="18">
+ <polyline color="#0000a0" width="530" />
+ </item>
+ <item type="street_nopass" order="10-">
+ <polyline color="#000000" width="1" />
+ </item>
+ <item type="track_paved" order="10-">
+ <polyline color="#000000" width="1" />
+ </item>
+ <item type="track_gravelled" order="10-12">
+ <polyline color="#800000" width="1" dash="3,6" />
+ </item>
+ <item type="track_gravelled" order="13-14">
+ <polyline color="#ffffff" width="4" dash="4,8" />
+ <polyline color="#800000" width="2" dash="4,8" />
+ </item>
+ <item type="track_gravelled" order="15-16">
+ <polyline color="#ffffff" width="5" dash="5,10" />
+ <polyline color="#800000" width="3" dash="5,10" />
+ </item>
+ <item type="track_gravelled" order="17-">
+ <polyline color="#ffffff" width="7" dash="7,15" />
+ <polyline color="#800000" width="5" dash="7,15" />
+ </item>
+ <item type="track_unpaved" order="10-">
+ <polyline color="#000000" width="1" />
+ </item>
+ <item type="bridleway" order="10-">
+ <polyline color="#000000" width="1" />
+ </item>
+ <item type="cycleway" order="10-">
+ <polyline color="#000000" width="1" />
+ </item>
+ <item type="footway" order="10-12">
+ <polyline color="#ff0000" width="1" dash="3,6" />
+ </item>
+ <item type="footway" order="13-14">
+ <polyline color="#ffffff" width="4" dash="4,8" />
+ <polyline color="#ff0000" width="2" dash="4,8" />
+ </item>
+ <item type="footway" order="15-16">
+ <polyline color="#ffffff" width="5" dash="5,10" />
+ <polyline color="#ff0000" width="3" dash="5,10" />
+ </item>
+ <item type="footway" order="17-">
+ <polyline color="#ffffff" width="7" dash="7,15" />
+ <polyline color="#ff0000" width="5" dash="7,15" />
+ </item>
+ <item type="steps" order="10-">
+ <polyline color="#000000" width="1" />
+ </item>
+ <item type="street_pedestrian" order="10">
+ <polyline color="#d2d2d2" width="3" />
+ <polyline color="#dddddd" width="1" />
+ </item>
+ <item type="street_pedestrian" order="11">
+ <polyline color="#d2d2d2" width="5" />
+ <polyline color="#dddddd" width="3" />
+ </item>
+ <item type="street_pedestrian" order="12">
+ <polyline color="#d2d2d2" width="8" />
+ <polyline color="#dddddd" width="6" />
+ </item>
+ <item type="street_pedestrian" order="13">
+ <polyline color="#d2d2d2" width="9" />
+ <polyline color="#dddddd" width="7" />
+ </item>
+ <item type="street_pedestrian" order="14">
+ <polyline color="#d2d2d2" width="13" />
+ <polyline color="#dddddd" width="9" />
+ </item>
+ <item type="street_pedestrian" order="15">
+ <polyline color="#d2d2d2" width="18" />
+ <polyline color="#dddddd" width="14" />
+ </item>
+ <item type="street_pedestrian" order="16">
+ <polyline color="#d2d2d2" width="21" />
+ <polyline color="#dddddd" width="17" />
+ </item>
+ <item type="street_pedestrian" order="17">
+ <polyline color="#d2d2d2" width="25" />
+ <polyline color="#dddddd" width="21" />
+ </item>
+ <item type="street_pedestrian" order="18">
+ <polyline color="#d2d2d2" width="40" />
+ <polyline color="#dddddd" width="34" />
+ </item>
+ <item type="street_service" order="10">
+ <polyline color="#d2d2d2" width="4" />
+ <polyline color="#fefefe" width="2" />
+ </item>
+ <item type="street_service" order="11">
+ <polyline color="#d2d2d2" width="4" />
+ <polyline color="#fefefe" width="2" />
+ </item>
+ <item type="street_service" order="12">
+ <polyline color="#d2d2d2" width="5" />
+ <polyline color="#fefefe" width="3" />
+ </item>
+ <item type="street_service" order="13">
+ <polyline color="#d2d2d2" width="6" />
+ <polyline color="#fefefe" width="4" />
+ </item>
+ <item type="street_service" order="14">
+ <polyline color="#d2d2d2" width="7" />
+ <polyline color="#fefefe" width="5" />
+ </item>
+ <item type="street_service" order="15">
+ <polyline color="#d2d2d2" width="8" />
+ <polyline color="#fefefe" width="6" />
+ </item>
+ <item type="street_service" order="16">
+ <polyline color="#d2d2d2" width="9" />
+ <polyline color="#fefefe" width="7" />
+ </item>
+ <item type="street_service" order="17">
+ <polyline color="#d2d2d2" width="10" />
+ <polyline color="#fefefe" width="8" />
+ </item>
+ <item type="street_service" order="18">
+ <polyline color="#d2d2d2" width="11" />
+ <polyline color="#fefefe" width="9" />
+ </item>
+
+ <item type="street_0,street_1_city,street_1_land" order="10">
+ <polyline color="#d2d2d2" width="4" />
+ <polyline color="#ffffff" width="2" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="11">
+ <polyline color="#d2d2d2" width="6" />
+ <polyline color="#ffffff" width="4" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="12">
+ <polyline color="#d2d2d2" width="10" />
+ <polyline color="#ffffff" width="8" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="13">
+ <polyline color="#d2d2d2" width="12" />
+ <polyline color="#ffffff" width="9" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="14">
+ <polyline color="#d2d2d2" width="15" />
+ <polyline color="#ffffff" width="13" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="15">
+ <polyline color="#d2d2d2" width="17" />
+ <polyline color="#ffffff" width="14" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="16">
+ <polyline color="#d2d2d2" width="33" />
+ <polyline color="#ffffff" width="26" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="17">
+ <polyline color="#d2d2d2" width="69" />
+ <polyline color="#ffffff" width="61" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="18">
+ <polyline color="#d2d2d2" width="132" />
+ <polyline color="#ffffff" width="126" />
+ </item>
+ <item type="street_2_city,street_2_land" order="7-8">
+ <polyline color="#c0c0c0" width="2" />
+ </item>
+ <item type="street_2_city,street_2_land" order="9">
+ <polyline color="#c0c0c0" width="4" />
+ <polyline color="#ffff00" width="2" />
+ </item>
+ <item type="street_2_city,street_2_land" order="10">
+ <polyline color="#c0c0c0" width="6" />
+ <polyline color="#ffff00" width="4" />
+ </item>
+ <item type="street_2_city,street_2_land" order="11">
+ <polyline color="#c0c0c0" width="8" />
+ <polyline color="#ffff00" width="6" />
+ </item>
+ <item type="street_2_city,street_2_land" order="12">
+ <polyline color="#c0c0c0" width="12" />
+ <polyline color="#ffff00" width="9" />
+ </item>
+ <item type="street_2_city,street_2_land" order="13">
+ <polyline color="#c0c0c0" width="15" />
+ <polyline color="#ffff00" width="11" />
+ </item>
+ <item type="street_2_city,street_2_land" order="14">
+ <polyline color="#c0c0c0" width="18" />
+ <polyline color="#ffff00" width="14" />
+ </item>
+ <item type="street_2_city,street_2_land" order="15">
+ <polyline color="#c0c0c0" width="21" />
+ <polyline color="#ffff00" width="17" />
+ </item>
+ <item type="street_2_city,street_2_land" order="16">
+ <polyline color="#c0c0c0" width="35" />
+ <polyline color="#ffff00" width="30" />
+ </item>
+ <item type="street_2_city,street_2_land" order="17">
+ <polyline color="#c0c0c0" width="73" />
+ <polyline color="#ffff00" width="67" />
+ </item>
+ <item type="street_2_city,street_2_land" order="18">
+ <polyline color="#c0c0c0" width="144" />
+ <polyline color="#ffff00" width="138" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="7-8">
+ <polyline color="#a0a0a0" width="3" />
+ <polyline color="#ffff00" width="1" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="9">
+ <polyline color="#a0a0a0" width="5" />
+ <polyline color="#ffff00" width="3" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="10">
+ <polyline color="#a0a0a0" width="8" />
+ <polyline color="#ffff00" width="6" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="11">
+ <polyline color="#a0a0a0" width="9" />
+ <polyline color="#ffff00" width="7" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="12">
+ <polyline color="#a0a0a0" width="13" />
+ <polyline color="#ffff00" width="9" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="13">
+ <polyline color="#a0a0a0" width="18" />
+ <polyline color="#ffff00" width="14" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="14">
+ <polyline color="#a0a0a0" width="21" />
+ <polyline color="#ffff00" width="17" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="15">
+ <polyline color="#a0a0a0" width="25" />
+ <polyline color="#ffff00" width="21" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="16">
+ <polyline color="#a0a0a0" width="40" />
+ <polyline color="#ffff00" width="34" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="17">
+ <polyline color="#a0a0a0" width="79" />
+ <polyline color="#ffff00" width="73" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="18">
+ <polyline color="#a0a0a0" width="156" />
+ <polyline color="#ffff00" width="150" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="2-6">
+ <polyline color="#404040" width="1" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="7-8">
+ <polyline color="#404040" width="3" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="9">
+ <polyline color="#000000" width="5" />
+ <polyline color="#ff0000" width="3" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="10">
+ <polyline color="#000000" width="6" />
+ <polyline color="#ff0000" width="4" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="11">
+ <polyline color="#000000" width="9" />
+ <polyline color="#ff0000" width="7" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="12">
+ <polyline color="#000000" width="13" />
+ <polyline color="#ff0000" width="9" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="13">
+ <polyline color="#000000" width="18" />
+ <polyline color="#ff0000" width="14" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="14">
+ <polyline color="#000000" width="21" />
+ <polyline color="#ff0000" width="17" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="15">
+ <polyline color="#000000" width="24" />
+ <polyline color="#ff0000" width="20" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="16">
+ <polyline color="#000000" width="39" />
+ <polyline color="#ff0000" width="33" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="17">
+ <polyline color="#000000" width="78" />
+ <polyline color="#ff0000" width="72" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="18">
+ <polyline color="#000000" width="156" />
+ <polyline color="#ff0000" width="150" />
+ </item>
+ <item type="highway_city,highway_land" order="2">
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="3-5">
+ <polyline color="#ff0000" width="3" />
+ <polyline color="#ffff00" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="6">
+ <polyline color="#ff0000" width="4" />
+ <polyline color="#ffff00" width="2" />
+ </item>
+ <item type="highway_city,highway_land" order="7-8">
+ <polyline color="#ff0000" width="7" />
+ <polyline color="#ffff00" width="5" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="9-10">
+ <polyline color="#ff0000" width="9" />
+ <polyline color="#ffff00" width="5" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="11">
+ <polyline color="#ff0000" width="13" />
+ <polyline color="#ffff00" width="9" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="12">
+ <polyline color="#ff0000" width="15" />
+ <polyline color="#ffff00" width="10" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="13">
+ <polyline color="#ff0000" width="25" />
+ <polyline color="#ffff00" width="17" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="14">
+ <polyline color="#ff0000" width="31" />
+ <polyline color="#ffff00" width="24" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="15">
+ <polyline color="#ff0000" width="33" />
+ <polyline color="#ffff00" width="27" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="16">
+ <polyline color="#ff0000" width="65" />
+ <polyline color="#ffff00" width="59" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="17">
+ <polyline color="#ff0000" width="133" />
+ <polyline color="#ffff00" width="127" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="18">
+ <polyline color="#ff0000" width="264" />
+ <polyline color="#ffff00" width="258" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="street_unkn" order="0-">
+ <polyline color="#8080ff" width="3" />
+ </item>
+ <item type="highway_exit_label" order="10-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="highway_city,highway_land,street_4_city,street_4_land,street_n_lanes" order="10-18">
+ <label label_size="8" />
+ </item>
+ <item type="street_2_city,street_2_land,street_3_city,street_3_land,ramp" order="11-18">
+ <label label_size="9" />
+ </item>
+ <item type="street_nopass,street_0,street_1_city,street_1_land" order="12-18">
+ <label label_size="9" />
+ </item>
+ </layer>
+ <layer name="polylines">
+ <item type="aeroway_taxiway" order="10">
+ <polyline color="#989994" width="4" />
+ <polyline color="#d3dbbc" width="2" />
+ </item>
+ <item type="aeroway_taxiway" order="11">
+ <polyline color="#989994" width="6" />
+ <polyline color="#d3dbbc" width="4" />
+ </item>
+ <item type="aeroway_taxiway" order="12">
+ <polyline color="#989994" width="10" />
+ <polyline color="#d3dbbc" width="8" />
+ </item>
+ <item type="aeroway_taxiway" order="13">
+ <polyline color="#989994" width="12" />
+ <polyline color="#d3dbbc" width="9" />
+ </item>
+ <item type="aeroway_taxiway" order="14">
+ <polyline color="#989994" width="15" />
+ <polyline color="#d3dbbc" width="13" />
+ </item>
+ <item type="aeroway_taxiway" order="15">
+ <polyline color="#989994" width="17" />
+ <polyline color="#d3dbbc" width="14" />
+ </item>
+ <item type="aeroway_taxiway" order="16">
+ <polyline color="#989994" width="33" />
+ <polyline color="#d3dbbc" width="26" />
+ </item>
+ <item type="aeroway_taxiway" order="17">
+ <polyline color="#989994" width="69" />
+ <polyline color="#d3dbbc" width="61" />
+ </item>
+ <item type="aeroway_taxiway" order="18">
+ <polyline color="#989994" width="132" />
+ <polyline color="#d3dbbc" width="126" />
+ </item>
+ <item type="aeroway_runway" order="2-6">
+ <polyline color="#404040" width="1" />
+ </item>
+ <item type="aeroway_runway" order="7-8">
+ <polyline color="#404040" width="3" />
+ <polyline color="#d3dbbc" width="1" />
+ </item>
+ <item type="aeroway_runway" order="9">
+ <polyline color="#6b6f5f" width="5" />
+ <polyline color="#d3dbbc" width="3" />
+ </item>
+ <item type="aeroway_runway" order="10">
+ <polyline color="#6b6f5f" width="6" />
+ <polyline color="#d3dbbc" width="4" />
+ </item>
+ <item type="aeroway_runway" order="11">
+ <polyline color="#6b6f5f" width="9" />
+ <polyline color="#d3dbbc" width="7" />
+ </item>
+ <item type="aeroway_runway" order="12">
+ <polyline color="#6b6f5f" width="13" />
+ <polyline color="#d3dbbc" width="9" />
+ </item>
+ <item type="aeroway_runway" order="13">
+ <polyline color="#6b6f5f" width="18" />
+ <polyline color="#d3dbbc" width="14" />
+ </item>
+ <item type="aeroway_runway" order="14">
+ <polyline color="#6b6f5f" width="21" />
+ <polyline color="#d3dbbc" width="17" />
+ </item>
+ <item type="aeroway_runway" order="15">
+ <polyline color="#6b6f5f" width="24" />
+ <polyline color="#d3dbbc" width="20" />
+ </item>
+ <item type="aeroway_runway" order="16">
+ <polyline color="#6b6f5f" width="39" />
+ <polyline color="#d3dbbc" width="33" />
+ </item>
+ <item type="aeroway_runway" order="17">
+ <polyline color="#6b6f5f" width="78" />
+ <polyline color="#d3dbbc" width="72" />
+ </item>
+ <item type="aeroway_runway" order="18">
+ <polyline color="#6b6f5f" width="156" />
+ <polyline color="#d3dbbc" width="150" />
+ </item>
+ <item type="rail_tram" order="10-">
+ <polyline color="#606060" width="2" />
+ </item>
+ </layer>
+ <layer name="labels">
+ <item type="town_label,district_label,town_label_0e0,town_label_1e0,town_label_2e0,town_label_5e0,town_label_1e1,town_label_2e1,town_label_5e1,town_label_1e2,town_label_2e2,town_label_5e2,district_label_0e0,district_label_1e0,district_label_2e0,district_label_5e0,district_label_1e1,district_label_2e1,district_label_5e1,district_label_1e2,district_label_2e2,district_label_5e2" order="12-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="district_label_1e3,district_label_2e3,district_label_5e3" order="11-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="town_label_1e3,town_label_2e3,town_label_5e3" order="10-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="district_label_1e4,district_label_2e4,district_label_5e4" order="9-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="town_label_1e4,town_label_2e4,town_label_5e4" order="8-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="district_label_1e5,district_label_2e5,district_label_5e5" order="6-">
+ <circle color="#000000" radius="3" label_size="10" />
+ </item>
+ <item type="town_label_1e5,town_label_2e5,town_label_5e5" order="4-">
+ <circle color="#000000" radius="3" label_size="10" />
+ </item>
+ <item type="district_label_1e6,district_label_2e6,district_label_5e6" order="3-">
+ <circle color="#000000" radius="3" label_size="15" />
+ </item>
+ <item type="town_label_1e6,town_label_2e6,town_label_5e6" order="2-">
+ <circle color="#000000" radius="3" label_size="15" />
+ </item>
+ <item type="town_label_1e7,district_label_1e7" order="1-">
+ <circle color="#000000" radius="3" label_size="15" />
+ </item>
+ </layer>
+ <layer name="points">
+ <item type="mini_roundabout" order="12-">
+ <icon src="mini_roundabout.xpm" />
+ </item>
+ <item type="turning_circle" order="12-">
+ <icon src="mini_roundabout.xpm" />
+ </item>
+ <item type="track" order="3-">
+ <polyline color="#3f3f3f" width="1" />
+ </item>
+
+ <item type="poi_airport" order="5-">
+ <icon src="airport.xpm" />
+ </item>
+ <item type="town_ghost" order="0-">
+ <icon src="ghost_town.xpm" />
+ </item>
+ <item type="poi_hotel" order="12-">
+ <icon src="hotel.xpm" />
+ </item>
+ <item type="poi_car_parking" order="11-">
+ <icon src="parking.xpm" />
+ </item>
+ <item type="poi_car_dealer_parts" order="0-">
+ <icon src="car_dealer.xpm" />
+ </item>
+ <item type="poi_fuel" order="10-">
+ <icon src="fuel.xpm" />
+ </item>
+ <item type="poi_shopping" order="10-">
+ <icon src="shopping.xpm" />
+ </item>
+ <item type="poi_attraction" order="5-">
+ <icon src="attraction.xpm" />
+ </item>
+ <item type="poi_cafe" order="12-">
+ <icon src="cafe.xpm" />
+ </item>
+ <item type="poi_bar" order="12-">
+ <icon src="bar.xpm" />
+ </item>
+ <item type="poi_bridge" order="0-">
+ <icon src="bridge.xpm" />
+ </item>
+ <item type="highway_exit" order="11-">
+ <icon src="exit.xpm" />
+ </item>
+ <item type="poi_camp_rv" order="9-">
+ <icon src="camping.xpm" />
+ </item>
+ <item type="poi_museum_history" order="12-">
+ <icon src="museum.xpm" />
+ </item>
+ <item type="poi_hospital" order="12-">
+ <icon src="hospital.xpm" />
+ </item>
+ <item type="point_unkn" order="0-">
+ <circle color="#8080ff" radius="3" />
+ </item>
+ <item type="poi_dining" order="12-">
+ <icon src="dining.xpm" />
+ </item>
+ <item type="poi_fastfood" order="12-">
+ <icon src="fastfood.xpm" />
+ </item>
+ <item type="poi_police" order="12-">
+ <icon src="police.xpm" />
+ </item>
+ <item type="poi_auto_club" order="0-">
+ <icon src="auto_club.xpm" />
+ </item>
+ <item type="poi_autoservice" order="0-">
+ <icon src="autoservice.xpm" />
+ </item>
+ <item type="poi_bank" order="12-">
+ <icon src="bank.xpm" />
+ </item>
+ <item type="poi_bay" order="0-">
+ <icon src="bay.xpm" />
+ </item>
+ <item type="poi_bend" order="0-">
+ <icon src="bend.xpm" />
+ </item>
+ <item type="poi_boat_ramp" order="0-">
+ <icon src="boat_ramp.xpm" />
+ </item>
+ <item type="poi_border_station" order="0-">
+ <icon src="border_station.xpm" />
+ </item>
+ <item type="poi_bowling" order="0-">
+ <icon src="bowling.xpm" />
+ </item>
+ <item type="poi_bus_station" order="12-">
+ <icon src="bus.xpm" />
+ </item>
+ <item type="poi_bus_stop" order="12-">
+ <icon src="bus.xpm" />
+ </item>
+ <item type="poi_bussines_service" order="0-">
+ <icon src="bussines_service.xpm" />
+ </item>
+ <item type="poi_car_rent" order="0-">
+ <icon src="car_rent.xpm" />
+ </item>
+ <item type="poi_car_wash" order="0-">
+ <icon src="car_wash.xpm" />
+ </item>
+ <item type="poi_casino" order="0-">
+ <icon src="casino.xpm" />
+ </item>
+ <item type="poi_cemetery" order="0-">
+ <icon src="cemetery.xpm" />
+ </item>
+ <item type="poi_church" order="11-">
+ <icon src="church.xpm" />
+ </item>
+ <item type="poi_cinema" order="12-">
+ <icon src="cinema.xpm" />
+ </item>
+ <item type="poi_civil" order="0-">
+ <icon src="civil.xpm" />
+ </item>
+ <item type="poi_communication" order="0-">
+ <icon src="communication.xpm" />
+ </item>
+ <item type="poi_concert" order="0-">
+ <icon src="concert.xpm" />
+ </item>
+ <item type="poi_cove" order="0-">
+ <icon src="cove.xpm" />
+ </item>
+ <item type="poi_crossing" order="0-">
+ <icon src="crossing.xpm" />
+ </item>
+ <item type="poi_dam" order="0-">
+ <icon src="dam.xpm" />
+ </item>
+ <item type="poi_danger_area" order="0-">
+ <icon src="danger_area.xpm" />
+ </item>
+ <item type="poi_dangerous" order="0-">
+ <icon src="dangerous.xpm" />
+ </item>
+ <item type="poi_daymark" order="0-">
+ <icon src="daymark.xpm" />
+ </item>
+ <item type="poi_diving" order="0-">
+ <icon src="diving.xpm" />
+ </item>
+ <item type="poi_drinking_water" order="0-">
+ <icon src="drinking_water.xpm" />
+ </item>
+ <item type="poi_emergency" order="0-">
+ <icon src="emergency.xpm" />
+ </item>
+ <item type="poi_fair" order="0-">
+ <icon src="fair.xpm" />
+ </item>
+ <item type="poi_firebrigade" order="12-">
+ <icon src="firebrigade.xpm" />
+ </item>
+ <item type="poi_fish" order="0-">
+ <icon src="fish.xpm" />
+ </item>
+ <item type="poi_forbiden_area" order="0-">
+ <icon src="forbiden_area.xpm" />
+ </item>
+ <item type="poi_garmin" order="0-">
+ <icon src="garmin.xpm" />
+ </item>
+ <item type="poi_golf" order="12-">
+ <icon src="golf.xpm" />
+ </item>
+ <item type="poi_goverment_building" order="0-">
+ <icon src="goverment_building.xpm" />
+ </item>
+ <item type="poi_height" order="0-">
+ <icon src="height.xpm" />
+ </item>
+ <item type="poi_heliport" order="7-">
+ <icon src="heliport.xpm" />
+ </item>
+ <item type="poi_hotspring" order="0-">
+ <icon src="hotspring.xpm" />
+ </item>
+ <item type="poi_icesport" order="0-">
+ <icon src="icesport.xpm" />
+ </item>
+ <item type="poi_information" order="12-">
+ <icon src="information.xpm" />
+ </item>
+ <item type="poi_justice" order="0-">
+ <icon src="justice.xpm" />
+ </item>
+ <item type="poi_landmark" order="0-">
+ <icon src="landmark.xpm" />
+ </item>
+ <item type="poi_levee" order="0-">
+ <icon src="levee.xpm" />
+ </item>
+ <item type="poi_level_crossing" order="11-">
+ <icon src="level_crossing.xpm" />
+ </item>
+ <item type="poi_library" order="12-">
+ <icon src="library.xpm" />
+ </item>
+ <item type="poi_locale" order="0-">
+ <icon src="locale.xpm" />
+ </item>
+ <item type="poi_loudspeaker" order="0-">
+ <icon src="loudspeaker.xpm" />
+ </item>
+ <item type="poi_mall" order="0-">
+ <icon src="mall.xpm" />
+ </item>
+ <item type="poi_manmade_feature" order="0-">
+ <icon src="manmade_feature.xpm" />
+ </item>
+ <item type="poi_marine" order="0-">
+ <icon src="marine.xpm" />
+ </item>
+ <item type="poi_marine_type" order="0-">
+ <icon src="marine_type.xpm" />
+ </item>
+ <item type="poi_mark" order="0-">
+ <icon src="mark.xpm" />
+ </item>
+ <item type="poi_military" order="0-">
+ <icon src="military.xpm" />
+ </item>
+ <item type="poi_mine" order="0-">
+ <icon src="mine.xpm" />
+ </item>
+ <item type="poi_nondangerous" order="0-">
+ <icon src="nondangerous.xpm" />
+ </item>
+ <item type="poi_oil_field" order="0-">
+ <icon src="oil_field.xpm" />
+ </item>
+ <item type="poi_peak" order="6-">
+ <icon src="peak.xpm" />
+ </item>
+ <item type="poi_personal_service" order="0-">
+ <icon src="personal_service.xpm" />
+ </item>
+ <item type="poi_pharmacy" order="12-">
+ <icon src="pharmacy.xpm" />
+ </item>
+ <item type="poi_post" order="13-">
+ <icon src="post.xpm" />
+ </item>
+ <item type="poi_public_office" order="0-">
+ <icon src="public_office.xpm" />
+ </item>
+ <item type="poi_rail_halt" order="10-">
+ <circle color="#ff0000" radius="3" width="3" />
+ <circle color="#000000" radius="5" width="2" label_size="8" />
+ </item>
+ <item type="poi_rail_station" order="9-">
+ <circle color="#ff0000" radius="3" width="3" />
+ <circle color="#000000" radius="6" width="2" label_size="8" />
+ </item>
+ <item type="poi_rail_tram_stop" order="10-11">
+ <circle color="#ff0000" radius="2" width="2"/>
+ </item>
+ <item type="poi_rail_tram_stop" order="12-">
+ <circle color="#ff0000" radius="3" width="3" />
+ <circle color="#606060" radius="5" width="2" label_size="8" />
+ </item>
+ <item type="poi_repair_service" order="0-">
+ <icon src="repair_service.xpm" />
+ </item>
+ <item type="poi_resort" order="0-">
+ <icon src="resort.xpm" />
+ </item>
+ <item type="poi_rest_room" order="13-">
+ <icon src="rest_room.xpm" />
+ </item>
+ <item type="poi_restaurant" order="12-">
+ <icon src="restaurant.xpm" />
+ </item>
+ <item type="poi_restricted_area" order="0-">
+ <icon src="restricted_area.xpm" />
+ </item>
+ <item type="poi_restroom" order="13-">
+ <icon src="restroom.xpm" />
+ </item>
+ <item type="poi_sailing" order="0-">
+ <icon src="sailing.xpm" />
+ </item>
+ <item type="poi_scenic_area" order="0-">
+ <icon src="scenic_area.xpm" />
+ </item>
+ <item type="poi_school" order="12-">
+ <icon src="school.xpm" />
+ </item>
+ <item type="poi_service" order="0-">
+ <icon src="service.xpm" />
+ </item>
+ <item type="poi_shop_apparel" order="0-">
+ <icon src="shop_apparel.xpm" />
+ </item>
+ <item type="poi_shop_computer" order="0-">
+ <icon src="shop_computer.xpm" />
+ </item>
+ <item type="poi_shop_department" order="0-">
+ <icon src="shop_department.xpm" />
+ </item>
+ <item type="poi_shop_furnish" order="0-">
+ <icon src="shop_furnish.xpm" />
+ </item>
+ <item type="poi_shop_grocery" order="0-">
+ <icon src="shop_grocery.xpm" />
+ </item>
+ <item type="poi_shop_handg" order="0-">
+ <icon src="shop_handg.xpm" />
+ </item>
+ <item type="poi_shop_merchandise" order="0-">
+ <icon src="shop_merchandise.xpm" />
+ </item>
+ <item type="poi_shop_retail" order="0-">
+ <icon src="shop_retail.xpm" />
+ </item>
+ <item type="poi_shower" order="0-">
+ <icon src="shower.xpm" />
+ </item>
+ <item type="poi_skiing" order="12-">
+ <icon src="skiing.xpm" />
+ </item>
+ <item type="poi_social_service" order="0-">
+ <icon src="social_service.xpm" />
+ </item>
+ <item type="poi_sounding" order="0-">
+ <icon src="sounding.xpm" />
+ </item>
+ <item type="poi_sport" order="0-">
+ <icon src="sport.xpm" />
+ </item>
+ <item type="poi_stadium" order="0-">
+ <icon src="stadium.xpm" />
+ </item>
+ <item type="poi_subdivision" order="0-">
+ <icon src="subdivision.xpm" />
+ </item>
+ <item type="poi_swimming" order="12-">
+ <icon src="swimming.xpm" />
+ </item>
+ <item type="poi_telephone" order="13-">
+ <icon src="telephone.xpm" />
+ </item>
+ <item type="poi_theater" order="12-">
+ <icon src="theater.xpm" />
+ </item>
+ <item type="poi_tide" order="0-">
+ <icon src="tide.xpm" />
+ </item>
+ <item type="poi_tower" order="13-">
+ <icon src="tower.xpm" />
+ </item>
+ <item type="poi_townhall" order="12-">
+ <icon src="townhall.xpm" />
+ </item>
+ <item type="poi_trail" order="0-">
+ <icon src="trail.xpm" />
+ </item>
+ <item type="poi_truck_stop" order="0-">
+ <icon src="truck_stop.xpm" />
+ </item>
+ <item type="poi_tunnel" order="0-">
+ <icon src="tunnel.xpm" />
+ </item>
+ <item type="poi_wine" order="0-">
+ <icon src="wine.xpm" />
+ </item>
+ <item type="poi_worship" order="0-">
+ <icon src="worship.xpm" />
+ </item>
+ <item type="poi_wrecker" order="0-">
+ <icon src="wrecker.xpm" />
+ </item>
+ <item type="poi_zoo" order="0-">
+ <icon src="zoo.xpm" />
+ </item>
+ <item type="poi_picnic" order="11-">
+ <icon src="picnic.xpm" />
+ </item>
+ <item type="poi_gc_multi" order="0-">
+ <icon src="gc_multi.xpm" />
+ </item>
+ <item type="poi_gc_tradi" order="0-">
+ <icon src="gc_tradi.xpm" />
+ </item>
+ <item type="poi_gc_event" order="0-">
+ <icon src="gc_event.xpm" />
+ </item>
+ <item type="poi_gc_mystery" order="0-">
+ <icon src="gc_mystery.xpm" />
+ </item>
+ <item type="poi_gc_question" order="0-">
+ <icon src="gc_question.xpm" />
+ </item>
+ <item type="poi_gc_stages" order="0-">
+ <icon src="gc_stages.xpm" />
+ </item>
+ <item type="poi_gc_reference" order="0-">
+ <icon src="gc_reference.xpm" />
+ </item>
+ <item type="poi_gc_webcam" order="0-">
+ <icon src="gc_webcam.xpm" />
+ </item>
+ <item type="traffic_signals" order="13-">
+ <icon src="traffic_signals.xpm" />
+ </item>
+ <item type="poly_flats,poly_scrub,poly_military_zone,poly_marine,plantation,tundra" order="0-">
+ <polygon color="#a0a0a0" />
+ <label label_size="5" />
+ </item>
+ <item type="poi_image" order="0-">
+ <image />
+ </item>
+ <item type="rg_segment" order="0-">
+ <polyline color="#FF089C" width="1" />
+ </item>
+ <item type="rg_point" order="0-">
+ <circle color="#FF089C" radius="10" label_size="7" />
+ </item>
+ </layer>
+ </layout>
+ <layout name="Bike" color= "#ffefb7">
+ <layer name="polygons">
+ <item type="image" order="0-">
+ <image />
+ </item>
+ <item type="poly_wood" order="0-">
+ <polygon color="#8ec78d" />
+ </item>
+ <item type="poly_town" order="0-">
+ <polygon color="#ffc895" />
+ <polyline color="#ebb481" />
+ </item>
+ <item type="poly_park" order="0-">
+ <polygon color="#7cc334" />
+ <label label_size="5" />
+ </item>
+ <item type="poly_water" order="0-">
+ <polygon color="#82c8ea" />
+ <polyline color="#5096b8" />
+ <label label_size="5" />
+ </item>
+ <item type="poly_land" order="0-">
+ <polygon color="#ffefb7" />
+ <polyline color="#ffefb7" />
+ <label label_size="5" />
+ </item>
+ <item type="poly_airport" order="0-">
+ <polygon color="#a0a0a0" />
+ </item>
+ <item type="sport_poly,poly_sport" order="0-">
+ <polygon color="#ff8c00" />
+ </item>
+ <item type="poly_industry,poly_place,poly_railway" order="0-">
+ <polygon color="#e6e6e6" />
+ </item>
+ <item type="poly_commercial" order="0-">
+ <polygon color="#fff8dc" />
+ </item>
+
+ <!-- landuse=industrial -->
+ <item type="industry_poly,building_poly,place_poly,poly_brownfield,poly_greenfield,poly_construction,poly_railway" order="0-">
+ <polygon color="#ecd8ff" />
+ </item>
+ <!-- landuse=farm -->
+ <item type="poly_farm" order="0-">
+ <polygon color="#c7f1a3" />
+ <polyline color="#79c691" />
+ <label label_size="5" />
+ </item>
+ <item type="poly_scree,poly_scrub,poly_fell,poly_heath" order="0-">
+ <polygon color="#c7f1a3" />
+ <polyline color="#79c691" />
+ <label label_size="5" />
+ </item>
+ <item type="poly_marsh,poly_mud,poly_quarry" order="0-">
+ <polygon color="#DEB887" />
+ <polyline color="#DEB887" />
+ <label label_size="5" />
+ </item>
+
+ <item type="poly_allotments,poly_playground,poly_village_green,poly_recreation_ground,poly_common,poly_garden" order="0-">
+ <polygon color="#c7f1a3" />
+ <polyline color="#79c691" />
+ <label label_size="5" />
+ </item>
+
+ <item type="poly_building" order="0-">
+ <polygon color="#ff6347" />
+ </item>
+ <item type="water_line" order="0-">
+ <polyline color="#82c8ea" width="2" />
+ <label label_size="5" />
+ </item>
+ <item type="water_river" order="0-">
+ <polyline color="#82c8ea" width="4" />
+ <label label_size="5" />
+ </item>
+ <item type="water_canal" order="0-">
+ <polyline color="#82c8ea" width="3" />
+ <label label_size="5" />
+ </item>
+ <item type="water_stream" order="0-">
+ <polyline color="#82c8ea" width="2" />
+ <label label_size="5" />
+ </item>
+ <item type="water_drain" order="0-">
+ <polyline color="#82c8ea" width="1" />
+ <label label_size="5" />
+ </item>
+ <item type="poly_apron" order="0-">
+ <polygon color="#d0d0d0" />
+ </item>
+ <item type="poly_terminal" order="7-">
+ <polygon color="#e3c6a6" />
+ </item>
+ <item type="poly_cemetery" order="1-">
+ <polygon color="#bde3cb" />
+ </item>
+ <item type="poly_car_parking" order="1-">
+ <polygon color="#d2d2d2" />
+ </item>
+
+ <!-- borders -->
+ <item type="border_state" order="0-5">
+ <polyline color="#778899" dash="3,2,1,3" width="3" />
+ </item>
+ <item type="border_country" order="0-5">
+ <polyline color="#778899" dash="3,2,1,3" width="2" />
+ </item>
+
+ <item type="border_state" order="6-11">
+ <polyline color="#778899" dash="6,6,1,6" width="3" />
+ </item>
+ <item type="border_country" order="6-11">
+ <polyline color="#778899" dash="6,6,1,6" width="2" />
+ </item>
+
+ <item type="border_state" order="12-20">
+ <polyline color="#778899" dash="10,10,2,10" width="3" />
+ </item>
+ <item type="border_country" order="12-20">
+ <polyline color="#778899" dash="10,10,2,10" width="2" />
+ </item>
+
+ <item type="height_line_1" order="0-">
+ <polyline color="#000000" width="1" />
+ </item>
+ <item type="height_line_2" order="0-">
+ <polyline color="#000000" width="2" />
+ </item>
+ <item type="street_route" order="2">
+ <polyline color="#0000a0" width="4" />
+ </item>
+ <item type="street_route" order="3-5">
+ <polyline color="#0000a0" width="8" />
+ </item>
+ <item type="street_route" order="6">
+ <polyline color="#0000a0" width="10" />
+ </item>
+ <item type="street_route" order="7-8">
+ <polyline color="#0000a0" width="16" />
+ </item>
+ <item type="street_route" order="9-10">
+ <polyline color="#0000a0" width="20" />
+ </item>
+ <item type="street_route" order="11">
+ <polyline color="#0000a0" width="28" />
+ </item>
+ <item type="street_route" order="12">
+ <polyline color="#0000a0" width="32" />
+ </item>
+ <item type="street_route" order="13">
+ <polyline color="#0000a0" width="52" />
+ </item>
+ <item type="street_route" order="14">
+ <polyline color="#0000a0" width="64" />
+ </item>
+ <item type="street_route" order="15">
+ <polyline color="#0000a0" width="68" />
+ </item>
+ <item type="street_route" order="16">
+ <polyline color="#0000a0" width="132" />
+ </item>
+ <item type="street_route" order="17">
+ <polyline color="#0000a0" width="268" />
+ </item>
+ <item type="street_route" order="18">
+ <polyline color="#0000a0" width="530" />
+ </item>
+ <item type="street_nopass" order="10-">
+ <polyline color="#000000" width="1" />
+ </item>
+ <item type="track_paved" order="9-">
+ <polyline color="#d2d2d2" width="4" />
+ <polyline color="#fefefe" width="2" />
+ </item>
+ <item type="track_gravelled" order="10-">
+ <polyline color="#d2d2d2" width="3" />
+ <polyline color="#fefefe" width="1" />
+ </item>
+ <item type="track_unpaved" order="11-">
+ <polyline color="#fff0f5" width="2" />
+ <polyline color="#fff0f5" width="1" />
+ </item>
+ <item type="track_ground" order="12-">
+ <polyline color="#fff0f5" width="2" />
+ <polyline color="#fff0f5" width="1" />
+ </item>
+ <item type="track_grass" order="13-">
+ <polyline color="#ffffe0" width="2" />
+ <polyline color="#ffffe0" width="1" />
+ </item>
+ <item type="bridleway" order="10-">
+ <polyline color="#8b4513" width="3" />
+ <polyline color="#f4a460" width="1" />
+ </item>
+ <item type="cycleway" order="10-">
+ <polyline color="#006400" width="4" />
+ <polyline color="#3cb371" width="2" />
+ </item>
+ <item type="footway" order="12-">
+ <polyline color="#8b4513" width="3" />
+ <polyline color="#CD853F" width="1" />
+ </item>
+ <item type="steps" order="12-">
+ <polyline color="#8b4513" width="3" />
+ <polyline color="#F4A460" width="1" dash="6,4" />
+ </item>
+ <item type="poly_pedestrian,poly_plaza" order="0-">
+ <polygon color="#d2d2d2" />
+ </item>
+ <item type="street_pedestrian,living_street" order="10">
+ <polyline color="#d2d2d2" width="3" />
+ <polyline color="#dddddd" width="1" />
+ </item>
+ <item type="street_pedestrian,living_street" order="11">
+ <polyline color="#d2d2d2" width="5" />
+ <polyline color="#dddddd" width="3" />
+ </item>
+ <item type="street_pedestrian,living_street" order="12">
+ <polyline color="#d2d2d2" width="8" />
+ <polyline color="#dddddd" width="6" />
+ </item>
+ <item type="street_pedestrian,living_street" order="13">
+ <polyline color="#d2d2d2" width="9" />
+ <polyline color="#dddddd" width="7" />
+ </item>
+ <item type="street_pedestrian,living_street" order="14">
+ <polyline color="#d2d2d2" width="13" />
+ <polyline color="#dddddd" width="9" />
+ </item>
+ <item type="street_pedestrian,living_street" order="15">
+ <polyline color="#d2d2d2" width="18" />
+ <polyline color="#dddddd" width="14" />
+ </item>
+ <item type="street_pedestrian,living_street" order="16">
+ <polyline color="#d2d2d2" width="21" />
+ <polyline color="#dddddd" width="17" />
+ </item>
+ <item type="street_pedestrian,living_street" order="17">
+ <polyline color="#d2d2d2" width="25" />
+ <polyline color="#dddddd" width="21" />
+ </item>
+ <item type="street_pedestrian,living_street" order="18">
+ <polyline color="#d2d2d2" width="40" />
+ <polyline color="#dddddd" width="34" />
+ </item>
+ <item type="street_service" order="9">
+ <polyline color="#d2d2d2" width="2" />
+ <polyline color="#fefefe" width="1" />
+ </item>
+ <item type="street_service" order="10">
+ <polyline color="#d2d2d2" width="3" />
+ <polyline color="#fefefe" width="2" />
+ </item>
+ <item type="street_service" order="11">
+ <polyline color="#d2d2d2" width="4" />
+ <polyline color="#fefefe" width="2" />
+ </item>
+ <item type="street_service" order="12">
+ <polyline color="#d2d2d2" width="5" />
+ <polyline color="#fefefe" width="3" />
+ </item>
+ <item type="street_service" order="13">
+ <polyline color="#d2d2d2" width="6" />
+ <polyline color="#fefefe" width="4" />
+ </item>
+ <item type="street_service" order="14">
+ <polyline color="#d2d2d2" width="7" />
+ <polyline color="#fefefe" width="5" />
+ </item>
+ <item type="street_service" order="15">
+ <polyline color="#d2d2d2" width="8" />
+ <polyline color="#fefefe" width="6" />
+ </item>
+ <item type="street_service" order="16">
+ <polyline color="#d2d2d2" width="9" />
+ <polyline color="#fefefe" width="7" />
+ </item>
+ <item type="street_service" order="17">
+ <polyline color="#d2d2d2" width="10" />
+ <polyline color="#fefefe" width="8" />
+ </item>
+ <item type="street_service" order="18">
+ <polyline color="#d2d2d2" width="11" />
+ <polyline color="#fefefe" width="9" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="8-10">
+ <polyline color="#d2d2d2" width="4" />
+ <polyline color="#ffffff" width="2" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="11">
+ <polyline color="#d2d2d2" width="6" />
+ <polyline color="#ffffff" width="4" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="12">
+ <polyline color="#d2d2d2" width="10" />
+ <polyline color="#ffffff" width="8" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="13">
+ <polyline color="#d2d2d2" width="12" />
+ <polyline color="#ffffff" width="9" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="14">
+ <polyline color="#d2d2d2" width="15" />
+ <polyline color="#ffffff" width="13" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="15">
+ <polyline color="#d2d2d2" width="17" />
+ <polyline color="#ffffff" width="14" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="16">
+ <polyline color="#d2d2d2" width="33" />
+ <polyline color="#ffffff" width="26" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="17">
+ <polyline color="#d2d2d2" width="69" />
+ <polyline color="#ffffff" width="61" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="18">
+ <polyline color="#d2d2d2" width="132" />
+ <polyline color="#ffffff" width="126" />
+ </item>
+ <item type="street_2_city,street_2_land" order="7-8">
+ <polyline color="#c0c0c0" width="3" />
+ <polyline color="#ffff00" width="1" />
+ </item>
+ <item type="street_2_city,street_2_land" order="9">
+ <polyline color="#c0c0c0" width="4" />
+ <polyline color="#ffff00" width="2" />
+ </item>
+ <item type="street_2_city,street_2_land" order="10">
+ <polyline color="#c0c0c0" width="6" />
+ <polyline color="#ffff00" width="4" />
+ </item>
+ <item type="street_2_city,street_2_land" order="11">
+ <polyline color="#c0c0c0" width="8" />
+ <polyline color="#ffff00" width="6" />
+ </item>
+ <item type="street_2_city,street_2_land" order="12">
+ <polyline color="#c0c0c0" width="12" />
+ <polyline color="#ffff00" width="9" />
+ </item>
+ <item type="street_2_city,street_2_land" order="13">
+ <polyline color="#c0c0c0" width="15" />
+ <polyline color="#ffff00" width="11" />
+ </item>
+ <item type="street_2_city,street_2_land" order="14">
+ <polyline color="#c0c0c0" width="18" />
+ <polyline color="#ffff00" width="14" />
+ </item>
+ <item type="street_2_city,street_2_land" order="15">
+ <polyline color="#c0c0c0" width="21" />
+ <polyline color="#ffff00" width="17" />
+ </item>
+ <item type="street_2_city,street_2_land" order="16">
+ <polyline color="#c0c0c0" width="35" />
+ <polyline color="#ffff00" width="30" />
+ </item>
+ <item type="street_2_city,street_2_land" order="17">
+ <polyline color="#c0c0c0" width="73" />
+ <polyline color="#ffff00" width="67" />
+ </item>
+ <item type="street_2_city,street_2_land" order="18">
+ <polyline color="#c0c0c0" width="144" />
+ <polyline color="#ffff00" width="138" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="7-8">
+ <polyline color="#a0a0a0" width="3" />
+ <polyline color="#ffff00" width="1" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="9">
+ <polyline color="#a0a0a0" width="5" />
+ <polyline color="#ffff00" width="3" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="10">
+ <polyline color="#a0a0a0" width="8" />
+ <polyline color="#ffff00" width="6" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="11">
+ <polyline color="#a0a0a0" width="9" />
+ <polyline color="#ffff00" width="7" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="12">
+ <polyline color="#a0a0a0" width="13" />
+ <polyline color="#ffff00" width="9" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="13">
+ <polyline color="#a0a0a0" width="18" />
+ <polyline color="#ffff00" width="14" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="14">
+ <polyline color="#a0a0a0" width="21" />
+ <polyline color="#ffff00" width="17" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="15">
+ <polyline color="#a0a0a0" width="25" />
+ <polyline color="#ffff00" width="21" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="16">
+ <polyline color="#a0a0a0" width="40" />
+ <polyline color="#ffff00" width="34" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="17">
+ <polyline color="#a0a0a0" width="79" />
+ <polyline color="#ffff00" width="73" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp,roundabout" order="18">
+ <polyline color="#a0a0a0" width="156" />
+ <polyline color="#ffff00" width="150" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="2-6">
+ <polyline color="#404040" width="1" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="7-8">
+ <polyline color="#404040" width="3" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="9">
+ <polyline color="#000000" width="5" />
+ <polyline color="#ff0000" width="3" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="10">
+ <polyline color="#000000" width="6" />
+ <polyline color="#ff0000" width="4" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="11">
+ <polyline color="#000000" width="9" />
+ <polyline color="#ff0000" width="7" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="12">
+ <polyline color="#000000" width="13" />
+ <polyline color="#ff0000" width="9" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="13">
+ <polyline color="#000000" width="18" />
+ <polyline color="#ff0000" width="14" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="14">
+ <polyline color="#000000" width="21" />
+ <polyline color="#ff0000" width="17" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="15">
+ <polyline color="#000000" width="24" />
+ <polyline color="#ff0000" width="20" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="16">
+ <polyline color="#000000" width="39" />
+ <polyline color="#ff0000" width="33" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="17">
+ <polyline color="#000000" width="78" />
+ <polyline color="#ff0000" width="72" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="18">
+ <polyline color="#000000" width="156" />
+ <polyline color="#ff0000" width="150" />
+ </item>
+ <item type="highway_city,highway_land" order="2">
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="3-5">
+ <polyline color="#ff0000" width="3" />
+ <polyline color="#ffff00" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="6">
+ <polyline color="#ff0000" width="4" />
+ <polyline color="#ffff00" width="2" />
+ </item>
+ <item type="highway_city,highway_land" order="7-8">
+ <polyline color="#ff0000" width="7" />
+ <polyline color="#ffff00" width="5" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="9-10">
+ <polyline color="#ff0000" width="9" />
+ <polyline color="#ffff00" width="5" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="11">
+ <polyline color="#ff0000" width="13" />
+ <polyline color="#ffff00" width="9" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="12">
+ <polyline color="#ff0000" width="15" />
+ <polyline color="#ffff00" width="10" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="13">
+ <polyline color="#ff0000" width="25" />
+ <polyline color="#ffff00" width="17" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="14">
+ <polyline color="#ff0000" width="31" />
+ <polyline color="#ffff00" width="24" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="15">
+ <polyline color="#ff0000" width="33" />
+ <polyline color="#ffff00" width="27" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="16">
+ <polyline color="#ff0000" width="65" />
+ <polyline color="#ffff00" width="59" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="17">
+ <polyline color="#ff0000" width="133" />
+ <polyline color="#ffff00" width="127" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="18">
+ <polyline color="#ff0000" width="264" />
+ <polyline color="#ffff00" width="258" />
+ <polyline color="#ff0000" width="1" />
+ </item>
+ <item type="street_unkn" order="0-">
+ <polyline color="#8080ff" width="3" />
+ </item>
+ <item type="highway_exit_label" order="10-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="highway_city,highway_land,street_4_city,street_4_land,street_n_lanes" order="10-18">
+ <label label_size="8" />
+ </item>
+ <item type="street_2_city,street_2_land,street_3_city,street_3_land,ramp" order="11-18">
+ <label label_size="9" />
+ </item>
+ <item type="street_nopass,street_0,street_1_city,street_1_land" order="12-18">
+ <label label_size="9" />
+ </item>
+ <item type="aeroway_taxiway" order="10">
+ <polyline color="#989994" width="4" />
+ <polyline color="#d3dbbc" width="2" />
+ </item>
+ <item type="aeroway_taxiway" order="11">
+ <polyline color="#989994" width="6" />
+ <polyline color="#d3dbbc" width="4" />
+ </item>
+ <item type="aeroway_taxiway" order="12">
+ <polyline color="#989994" width="10" />
+ <polyline color="#d3dbbc" width="8" />
+ </item>
+ <item type="aeroway_taxiway" order="13">
+ <polyline color="#989994" width="12" />
+ <polyline color="#d3dbbc" width="9" />
+ </item>
+ <item type="aeroway_taxiway" order="14">
+ <polyline color="#989994" width="15" />
+ <polyline color="#d3dbbc" width="13" />
+ </item>
+ <item type="aeroway_taxiway" order="15">
+ <polyline color="#989994" width="17" />
+ <polyline color="#d3dbbc" width="14" />
+ </item>
+ <item type="aeroway_taxiway" order="16">
+ <polyline color="#989994" width="33" />
+ <polyline color="#d3dbbc" width="26" />
+ </item>
+ <item type="aeroway_taxiway" order="17">
+ <polyline color="#989994" width="69" />
+ <polyline color="#d3dbbc" width="61" />
+ </item>
+ <item type="aeroway_taxiway" order="18">
+ <polyline color="#989994" width="132" />
+ <polyline color="#d3dbbc" width="126" />
+ </item>
+ <item type="aeroway_runway" order="2-6">
+ <polyline color="#404040" width="1" />
+ </item>
+ <item type="aeroway_runway" order="7-8">
+ <polyline color="#404040" width="3" />
+ <polyline color="#d3dbbc" width="1" />
+ </item>
+ <item type="aeroway_runway" order="9">
+ <polyline color="#6b6f5f" width="5" />
+ <polyline color="#d3dbbc" width="3" />
+ </item>
+ <item type="aeroway_runway" order="10">
+ <polyline color="#6b6f5f" width="6" />
+ <polyline color="#d3dbbc" width="4" />
+ </item>
+ <item type="aeroway_runway" order="11">
+ <polyline color="#6b6f5f" width="9" />
+ <polyline color="#d3dbbc" width="7" />
+ </item>
+ <item type="aeroway_runway" order="12">
+ <polyline color="#6b6f5f" width="13" />
+ <polyline color="#d3dbbc" width="9" />
+ </item>
+ <item type="aeroway_runway" order="13">
+ <polyline color="#6b6f5f" width="18" />
+ <polyline color="#d3dbbc" width="14" />
+ </item>
+ <item type="aeroway_runway" order="14">
+ <polyline color="#6b6f5f" width="21" />
+ <polyline color="#d3dbbc" width="17" />
+ </item>
+ <item type="aeroway_runway" order="15">
+ <polyline color="#6b6f5f" width="24" />
+ <polyline color="#d3dbbc" width="20" />
+ </item>
+ <item type="aeroway_runway" order="16">
+ <polyline color="#6b6f5f" width="39" />
+ <polyline color="#d3dbbc" width="33" />
+ </item>
+ <item type="aeroway_runway" order="17">
+ <polyline color="#6b6f5f" width="78" />
+ <polyline color="#d3dbbc" width="72" />
+ </item>
+ <item type="aeroway_runway" order="18">
+ <polyline color="#6b6f5f" width="156" />
+ <polyline color="#d3dbbc" width="150" />
+ </item>
+
+
+ <item type="rail" order="6-9">
+ <polyline color="#696969" width="4" />
+ <polyline color="#FFFFFF" dash="2,5" width="2" />
+ </item>
+ <item type="rail_narrow_gauge" order="6-9">
+ <polyline color="#696969" width="4" />
+ <polyline color="#FFFFFF" dash="2,5" width="2" />
+ </item>
+
+ <item type="rail" order="10-13">
+ <polyline color="#696969" width="6" />
+ <polyline color="#FFFFFF" dash="3,8" width="3" />
+ </item>
+ <item type="rail_narrow_gauge" order="10-13">
+ <polyline color="#696969" width="6" />
+ <polyline color="#FFFFFF" dash="3,8" width="3" />
+ </item>
+
+ <item type="rail" order="14-18">
+ <polyline color="#696969" width="8" />
+ <polyline color="#FFFFFF" dash="4,12" width="5" />
+ </item>
+ <item type="rail_narrow_gauge" order="14-18">
+ <polyline color="#696969" width="8" />
+ <polyline color="#FFFFFF" dash="4,12" width="5" />
+ </item>
+
+ <item type="rail_light" order="10-13">
+ <polyline color="#696969" width="4" />
+ <polyline color="#FFFFFF" dash="2,5" width="2" />
+ </item>
+
+ <item type="rail_light" order="14-18">
+ <polyline color="#696969" width="6" />
+ <polyline color="#FFFFFF" dash="4,8" width="4" />
+ </item>
+
+ <item type="rail_subway" order="8-">
+ <polyline color="#696969" width="2" />
+ <polyline color="#FFFFFF" dash="5,5" width="2" />
+ </item>
+ <item type="rail_mono" order="10-">
+ <polyline color="#696969" width="2" />
+ </item>
+ <item type="rail_tram,bus_guideway" order="10-">
+ <polyline color="#696969" width="2" />
+ </item>
+ <item type="rail_preserved" order="10-">
+ <polyline color="#696969" width="1" dash="7" />
+ </item>
+ <item type="rail_disused" order="12-">
+ <polyline color="#d3d3d3" width="1" dash="10" />
+ </item>
+ <item type="rail_abandoned" order="12-">
+ <polyline color="#f5f5f5" width="1" dash="10" />
+ </item>
+ <item type="lift_cable_car" order="6-">
+ <polyline color="#696969" width="1" dash="5" />
+ </item>
+ <item type="lift_chair" order="6-">
+ <polyline color="#696969" width="1" dash="5" />
+ </item>
+ <item type="lift_drag" order="6-">
+ <polyline color="#696969" width="1" dash="5" />
+ </item>
+ <item type="ferry" order="5-">
+ <polyline color="#000000" width="3" dash="5" />
+ </item>
+ <item type="track" order="3-">
+ <polyline color="#3f3f3f" width="1" />
+ </item>
+
+
+
+ <item type="town_label,district_label,town_label_0e0,town_label_1e0,town_label_2e0,town_label_5e0,town_label_1e1,town_label_2e1,town_label_5e1,town_label_1e2,town_label_2e2,town_label_5e2,district_label_0e0,district_label_1e0,district_label_2e0,district_label_5e0,district_label_1e1,district_label_2e1,district_label_5e1,district_label_1e2,district_label_2e2,district_label_5e2" order="12-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="district_label_1e3,district_label_2e3,district_label_5e3" order="9-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="town_label_1e3,town_label_2e3,town_label_5e3" order="9-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="district_label_1e4,district_label_2e4,district_label_5e4" order="7-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="town_label_1e4,town_label_2e4,town_label_5e4" order="7-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="district_label_1e5,district_label_2e5,district_label_5e5" order="5-">
+ <circle color="#000000" radius="3" label_size="10" />
+ </item>
+ <item type="town_label_1e5,town_label_2e5,town_label_5e5" order="5-">
+ <circle color="#000000" radius="3" label_size="10" />
+ </item>
+ <item type="district_label_1e6,district_label_2e6,district_label_5e6" order="3-">
+ <circle color="#000000" radius="3" label_size="15" />
+ </item>
+ <item type="town_label_1e6,town_label_2e6,town_label_5e6" order="3-">
+ <circle color="#000000" radius="3" label_size="15" />
+ </item>
+ <item type="town_label_1e7,district_label_1e7" order="1-">
+ <circle color="#000000" radius="3" label_size="15" />
+ </item>
+ </layer>
+ <xi:include xpointer="xpointer(/config/navit/layout[@name='Car']/layer[@name='points'])" />
+ </layout>
+
+
+
+ <layout name="T@H">
+ <layer name="sea" details="0">
+
+<!-- landuse=forest -->
+ <item type="wood" order="0-">
+ <polygon color="#72bf81" />
+ </item>
+<!-- landuse=residential -->
+ <item type="town_poly" order="0-">
+ <polygon color="#f2f2f2" />
+ </item>
+<!-- natural=water -->
+ <item type="water_poly" order="0-">
+ <polygon color="#b5d6f1" />
+ <polyline color="#b5d6f1" />
+ <label label_size="8" />
+ </item>
+<!-- leisure=park -->
+ <item type="park_poly" order="0-">
+ <polygon color="#c7f1a3" />
+ <polyline color="#79c691" />
+ <label label_size="5" />
+ </item>
+ <item type="airport_poly" order="0-">
+ <polygon color="#a0a0a0" />
+ </item>
+ <item type="sport_poly" order="0-">
+ <polygon color="#4af04f" />
+ </item>
+
+<!-- landuse=industrial -->
+ <item type="industry_poly,building_poly,place_poly" order="0-">
+ <polygon color="#ecd8ff" />
+ </item>
+<!-- waterway=stream -->
+ <item type="water_line" order="0-4">
+ <polyline color="#b5d6f1" width="1" />
+ <label label_size="8" />
+ </item>
+<!-- railway=subway -->
+ <item type="rail" order="6">
+ <polyline color="#aaaaaa" width="1" />
+ </item>
+ <item type="rail" order="7-8">
+ <polyline color="#aaaaaa" width="2" />
+ </item>
+ <item type="rail" order="9-">
+ <polyline color="#aaaaaa" width="6" />
+ </item>
+ <item type="ferry" order="5-">
+ <polyline color="#000000" width="1" />
+ </item>
+ <item type="border_country" order="0-">
+ <polyline color="#b8434e" width="1" />
+ </item>
+ <item type="border_state" order="0-">
+ <polyline color="#808080" width="1" />
+ </item>
+ <item type="height_line_1" order="0-">
+ <polyline color="#000000" width="1" />
+ </item>
+ <item type="height_line_2" order="0-">
+ <polyline color="#000000" width="2" />
+ </item>
+<!-- routing -->
+ <item type="street_route" order="2">
+ <polyline color="#0000a0" width="4" />
+ </item>
+ <item type="street_route" order="3-5">
+ <polyline color="#0000a0" width="8" />
+ </item>
+ <item type="street_route" order="6">
+ <polyline color="#0000a0" width="10" />
+ </item>
+ <item type="street_route" order="7-8">
+ <polyline color="#0000a0" width="16" />
+ </item>
+ <item type="street_route" order="9-10">
+ <polyline color="#0000a0" width="20" />
+ </item>
+ <item type="street_route" order="11">
+ <polyline color="#0000a0" width="28" />
+ </item>
+ <item type="street_route" order="12">
+ <polyline color="#0000a0" width="32" />
+ </item>
+ <item type="street_route" order="13">
+ <polyline color="#0000a0" width="52" />
+ </item>
+ <item type="street_route" order="14">
+ <polyline color="#0000a0" width="64" />
+ </item>
+ <item type="street_route" order="15">
+ <polyline color="#0000a0" width="68" />
+ </item>
+ <item type="street_route" order="16">
+ <polyline color="#0000a0" width="132" />
+ </item>
+ <item type="street_route" order="17">
+ <polyline color="#0000a0" width="268" />
+ </item>
+ <item type="street_route" order="18">
+ <polyline color="#0000a0" width="530" />
+ </item>
+<!-- highway=service,footway, ,... -->
+ <item type="street_nopass" order="10">
+ <polyline color="#efeaa0" width="1" />
+ </item>
+ <item type="street_nopass" order="11-12">
+ <polyline color="#efeaa0" width="2" />
+ </item>
+ <item type="street_nopass" order="13-">
+ <polyline color="#efeaa0" width="4" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="10">
+ <polyline color="#d2d2d2" width="4" />
+ <polyline color="#ffffff" width="2" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="11">
+ <polyline color="#d2d2d2" width="6" />
+ <polyline color="#ffffff" width="4" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="12">
+ <polyline color="#d2d2d2" width="10" />
+ <polyline color="#ffffff" width="8" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="13">
+ <polyline color="#d2d2d2" width="12" />
+ <polyline color="#ffffff" width="9" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="14">
+ <polyline color="#d2d2d2" width="15" />
+ <polyline color="#ffffff" width="13" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="15">
+ <polyline color="#d2d2d2" width="17" />
+ <polyline color="#ffffff" width="14" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="16">
+ <polyline color="#d2d2d2" width="33" />
+ <polyline color="#ffffff" width="26" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="17">
+ <polyline color="#d2d2d2" width="69" />
+ <polyline color="#ffffff" width="61" />
+ </item>
+ <item type="street_0,street_1_city,street_1_land" order="18">
+ <polyline color="#d2d2d2" width="132" />
+ <polyline color="#ffffff" width="126" />
+ </item>
+<!-- highway=tertiary -->
+ <item type="street_2_city,street_2_land" order="7-8">
+ <polyline color="#c4c4c4" width="2" />
+ </item>
+ <item type="street_2_city,street_2_land" order="9">
+ <polyline color="#c4c4c4" width="4" />
+ <polyline color="#f7f496" width="2" />
+ </item>
+ <item type="street_2_city,street_2_land" order="10">
+ <polyline color="#c4c4c4" width="6" />
+ <polyline color="#f7f496" width="4" />
+ </item>
+ <item type="street_2_city,street_2_land" order="11">
+ <polyline color="#c4c4c4" width="8" />
+ <polyline color="#f7f496" width="6" />
+ </item>
+ <item type="street_2_city,street_2_land" order="12">
+ <polyline color="#c4c4c4" width="12" />
+ <polyline color="#f7f496" width="9" />
+ </item>
+ <item type="street_2_city,street_2_land" order="13">
+ <polyline color="#c4c4c4" width="15" />
+ <polyline color="#f7f496" width="11" />
+ </item>
+ <item type="street_2_city,street_2_land" order="14">
+ <polyline color="#c4c4c4" width="18" />
+ <polyline color="#f7f496" width="14" />
+ </item>
+ <item type="street_2_city,street_2_land" order="15">
+ <polyline color="#c4c4c4" width="21" />
+ <polyline color="#f7f496" width="17" />
+ </item>
+ <item type="street_2_city,street_2_land" order="16">
+ <polyline color="#c4c4c4" width="35" />
+ <polyline color="#f7f496" width="30" />
+ </item>
+ <item type="street_2_city,street_2_land" order="17">
+ <polyline color="#c4c4c4" width="73" />
+ <polyline color="#f7f496" width="67" />
+ </item>
+ <item type="street_2_city,street_2_land" order="18">
+ <polyline color="#c4c4c4" width="144" />
+ <polyline color="#f7f496" width="138" />
+ </item>
+<!-- highway=secondary -->
+ <item type="street_3_city,street_3_land,ramp" order="7">
+ <polyline color="#fdbf6f" width="1" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp" order="8">
+ <polyline color="#000000" width="2" />
+ <polyline color="#fdbf6f" width="1" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp" order="9">
+ <polyline color="#000000" width="5" />
+ <polyline color="#fdbf6f" width="3" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp" order="10">
+ <polyline color="#000000" width="8" />
+ <polyline color="#fdbf6f" width="6" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp" order="11">
+ <polyline color="#000000" width="9" />
+ <polyline color="#fdbf6f" width="7" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp" order="12">
+ <polyline color="#000000" width="11" />
+ <polyline color="#fdbf6f" width="9" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp" order="13">
+ <polyline color="#000000" width="16" />
+ <polyline color="#fdbf6f" width="14" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp" order="14">
+ <polyline color="#000000" width="19" />
+ <polyline color="#fdbf6f" width="17" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp" order="15">
+ <polyline color="#000000" width="23" />
+ <polyline color="#fdbf6f" width="21" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp" order="16">
+ <polyline color="#000000" width="36" />
+ <polyline color="#fdbf6f" width="34" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp" order="17">
+ <polyline color="#000000" width="75" />
+ <polyline color="#fdbf6f" width="73" />
+ </item>
+ <item type="street_3_city,street_3_land,ramp" order="18">
+ <polyline color="#000000" width="152" />
+ <polyline color="#fdbf6f" width="150" />
+ </item>
+<!-- highway=primary -->
+ <item type="street_4_city,street_4_land,street_n_lanes" order="2-6">
+ <polyline color="#e46d71" width="1" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="7-8">
+ <polyline color="#e46d71" width="3" />
+ <polyline color="#e46d71" width="1" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="9">
+ <polyline color="#e46d71" width="5" />
+ <polyline color="#e46d71" width="3" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="10">
+ <polyline color="#e46d71" width="6" />
+ <polyline color="#e46d71" width="4" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="11">
+ <polyline color="#e46d71" width="9" />
+ <polyline color="#e46d71" width="7" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="12">
+ <polyline color="#e46d71" width="13" />
+ <polyline color="#e46d71" width="9" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="13">
+ <polyline color="#e46d71" width="18" />
+ <polyline color="#e46d71" width="14" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="14">
+ <polyline color="#e46d71" width="21" />
+ <polyline color="#e46d71" width="17" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="15">
+ <polyline color="#e46d71" width="24" />
+ <polyline color="#e46d71" width="20" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="16">
+ <polyline color="#e46d71" width="39" />
+ <polyline color="#e46d71" width="33" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="17">
+ <polyline color="#e46d71" width="78" />
+ <polyline color="#e46d71" width="72" />
+ </item>
+ <item type="street_4_city,street_4_land,street_n_lanes" order="18">
+ <polyline color="#e46d71" width="156" />
+ <polyline color="#e46d71" width="150" />
+ </item>
+<!-- highway=motorway -->
+ <item type="highway_city,highway_land" order="2">
+ <polyline color="#809bc0" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="3-5">
+ <polyline color="#87908a" width="3" />
+ <polyline color="#809bc0" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="6">
+ <polyline color="#87908a" width="4" />
+ <polyline color="#809bc0" width="2" />
+ </item>
+ <item type="highway_city,highway_land" order="7-8">
+ <polyline color="#87908a" width="7" />
+ <polyline color="#809bc0" width="5" />
+ <polyline color="#809bc0" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="9-10">
+ <polyline color="#87908a" width="9" />
+ <polyline color="#809bc0" width="5" />
+ <polyline color="#809bc0" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="11">
+ <polyline color="#87908a" width="13" />
+ <polyline color="#809bc0" width="9" />
+ <polyline color="#809bc0" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="12">
+ <polyline color="#87908a" width="15" />
+ <polyline color="#809bc0" width="10" />
+ <polyline color="#809bc0" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="13">
+ <polyline color="#87908a" width="25" />
+ <polyline color="#809bc0" width="17" />
+ <polyline color="#809bc0" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="14">
+ <polyline color="#87908a" width="31" />
+ <polyline color="#809bc0" width="24" />
+ <polyline color="#809bc0" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="15">
+ <polyline color="#87908a" width="33" />
+ <polyline color="#809bc0" width="27" />
+ <polyline color="#809bc0" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="16">
+ <polyline color="#87908a" width="65" />
+ <polyline color="#809bc0" width="59" />
+ <polyline color="#809bc0" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="17">
+ <polyline color="#87908a" width="133" />
+ <polyline color="#809bc0" width="127" />
+ <polyline color="#809bc0" width="1" />
+ </item>
+ <item type="highway_city,highway_land" order="18">
+ <polyline color="#87908a" width="264" />
+ <polyline color="#809bc0" width="258" />
+ <polyline color="#809bc0" width="1" />
+ </item>
+<!-- unbekannte elemente -->
+ <item type="street_unkn" order="11-">
+ <polyline color="#f3d6b6" width="3" />
+ </item>
+ <item type="highway_exit_label" order="10-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+<!-- highway=primary (font)-->
+ <item type="highway_city,highway_land,street_4_city,street_4_land,street_n_lanes" order="10-18">
+ <label label_size="9" />
+ </item>
+ <item type="street_2_city,street_2_land,street_3_city,street_3_land,ramp" order="11-18">
+ <label label_size="9" />
+ </item>
+ <item type="street_nopass,street_0,street_1_city,street_1_land" order="12-18">
+ <label label_size="9" />
+ </item>
+<!-- place=suburb -->
+ <item type="town_label,district_label,town_label_0e0,town_label_1e0,town_label_2e0,town_label_5e0,town_label_1e1,town_label_2e1,town_label_5e1,town_label_1e2,town_label_2e2,town_label_5e2,district_label_0e0,district_label_1e0,district_label_2e0,district_label_5e0,district_label_1e1,district_label_2e1,district_label_5e1,district_label_1e2,district_label_2e2,district_label_5e2" order="9-">
+ <circle color="#000000" radius="3" label_size="9" />
+ </item>
+ <item type="district_label_1e3,district_label_2e3,district_label_5e3" order="11-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="town_label_1e3,town_label_2e3,town_label_5e3" order="10-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="district_label_1e4,district_label_2e4,district_label_5e4" order="9-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="town_label_1e4,town_label_2e4,town_label_5e4" order="8-">
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ <item type="district_label_1e5,district_label_2e5,district_label_5e5" order="6-">
+ <circle color="#000000" radius="3" label_size="10" />
+ </item>
+<!-- place=city -->
+ <item type="town_label_1e5,town_label_2e5,town_label_5e5" order="4-">
+ <circle color="#000000" radius="3" label_size="15" />
+ </item>
+ <item type="district_label_1e6,district_label_2e6,district_label_5e6" order="3-">
+ <circle color="#000000" radius="3" label_size="15" />
+ </item>
+ <item type="town_label_1e6,town_label_2e6,town_label_5e6" order="2-">
+ <circle color="#000000" radius="3" label_size="15" />
+ </item>
+ <item type="town_label_1e7,district_label_1e7" order="1-">
+ <circle color="#000000" radius="3" label_size="15" />
+ </item>
+ <item type="flats,scrub,military_zone,marine_poly,plantation,tundra" order="0-">
+ <polygon color="#a0a0a0" />
+ <label label_size="5" />
+ </item>
+ <item type="rg_point" order="0-">
+ <circle color="#FF089C" radius="10" />
+ </item>
+
+<!-- !!!!...POIs...!!!! -->
+
+<!-- amenity=bank -->
+ <item type="poi_bank" order="14-">
+ <icon src="bank.xpm" />
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+<!-- amenity=fuel -->
+ <item type="poi_fuel" order="14-">
+ <icon src="fuel.xpm" />
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+<!-- amenity=hospitalg -->
+ <item type="poi_hospital" order="14-">
+ <icon src="hospital.xpm" />
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+<!-- amenity=parking -->
+ <item type="poi_car_parking" order="14-">
+ <icon src="parking.xpm" />
+ </item>
+<!-- amenity=police -->
+ <item type="poi_police" order="14-">
+ <icon src="police.xpm" />
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+<!-- amenity=restaurant -->
+ <item type="poi_restaurant" order="14-">
+ <icon src="restaurant.xpm" />
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+<!-- leisure=golf_curse -->
+ <item type="poi_golf" order="14-">
+ <icon src="golf.xpm" />
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+<!-- tourism=hotel -->
+ <item type="poi_hotel" order="14-">
+ <icon src="hotel.xpm" />
+ <circle color="#000000" radius="3" label_size="7" />
+ </item>
+ </layer>
+ </layout>
+</navit>
+</config>
+
+
diff --git a/navit/osd.c b/navit/osd.c
new file mode 100644
index 000000000..d078ff273
--- /dev/null
+++ b/navit/osd.c
@@ -0,0 +1,100 @@
+#if 0
+//#include <math.h>
+#include <stdio.h>
+#include <glib.h>
+#include "point.h"
+//#include "coord.h"
+#include "graphics.h"
+//#include "transform.h"
+//#include "route.h"
+#include "vehicle.h"
+#include "container.h"
+#include "osd.h"
+
+void
+osd_set_next_command(char *new_command,char *new_road){
+ extern struct container *co;
+ // struct osd *this=co->osd;
+ strcpy(co->osd->command,new_command);
+ strcpy(co->osd->road_name,new_road);
+ osd_draw(co->osd, co);
+}
+
+void
+osd_draw(struct osd *osd, struct container *co)
+{
+ double *speed;
+ struct point p;
+
+ if (! co->vehicle)
+ return;
+
+ speed=vehicle_speed_get(co->vehicle);
+ osd->gr->draw_mode(osd->gr, draw_mode_begin);
+ p.x=0;
+ p.y=0;
+ osd->gr->draw_rectangle(osd->gr, osd->bg, &p, 360, 80);
+ p.x=10;
+ p.y=20;
+// osd->gr->draw_text(osd->gr, osd->green, NULL, osd->font, osd->command, &p, 0x13000, 0);
+ char osd_data[256];
+ sprintf(osd_data,"%.1f km/h",(*speed));
+ osd->gr->draw_text(osd->gr, osd->green, NULL, osd->font, osd_data, &p, 0x13000, 0);
+ p.x=10;
+ p.y=40;
+ osd->gr->draw_text(osd->gr, osd->green, NULL, osd->font, osd->command, &p, 0x13000, 0);
+// osd->gr->draw_text(osd->gr, osd->green, NULL, osd->font, "Overlay", &p, 0x10000, 0);
+// printf("Text %s should appear\n",osd->command);
+ osd->gr->draw_mode(osd->gr, draw_mode_end);
+}
+
+
+struct osd *
+osd_new(struct container *co)
+{
+ printf("Spawning an OSD\n");
+ struct osd *this=g_new0(struct osd, 1);
+ struct point p;
+ p.x=100;
+ p.y=10;
+ this->gr=co->gra->overlay_new(co->gra, &p, 360, 80);
+ this->bg=this->gr->gc_new(this->gr);
+ this->gr->gc_set_foreground(this->bg, 0, 0, 0);
+ this->white=this->gr->gc_new(this->gr);
+ this->gr->gc_set_foreground(this->white, 0xffff, 0xffff, 0xffff);
+ this->gr->gc_set_linewidth(this->white, 10);
+ this->green=this->gr->gc_new(this->gr);
+ this->gr->gc_set_foreground(this->green, 0x0, 0xffff, 0x0);
+ this->gr->gc_set_linewidth(this->green, 10);
+
+ this->font=this->gr->font_new(this->gr, 200);
+ osd_draw(this, co);
+ return this;
+}
+#endif
+
+#include <glib.h>
+#include "debug.h"
+#include "plugin.h"
+#include "osd.h"
+
+
+struct osd {
+ struct osd_methods meth;
+ struct osd_priv *priv;
+};
+
+struct osd *
+osd_new(struct navit *nav, const char *type, struct attr **attrs)
+{
+ struct osd *o;
+ struct osd_priv *(*new)(struct navit *nav, struct osd_methods *meth, struct attr **attrs);
+
+ new=plugin_get_osd_type(type);
+ if (! new)
+ return NULL;
+ o=g_new0(struct osd, 1);
+ o->priv=new(nav, &o->meth, attrs);
+ return o;
+}
+
diff --git a/navit/osd.h b/navit/osd.h
new file mode 100644
index 000000000..9a50e99b6
--- /dev/null
+++ b/navit/osd.h
@@ -0,0 +1,16 @@
+#ifndef NAVIT_OSD_H
+#define NAVIT_OSD_H
+
+struct osd_methods {
+ void (*osd_destroy)(struct osd_priv *osd);
+};
+
+/* prototypes */
+struct attr;
+struct navit;
+struct osd;
+struct osd *osd_new(struct navit *nav, const char *type, struct attr **attrs);
+/* end of prototypes */
+
+#endif
+
diff --git a/navit/osd/Makefile.am b/navit/osd/Makefile.am
new file mode 100644
index 000000000..eabd69101
--- /dev/null
+++ b/navit/osd/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS=core
diff --git a/navit/osd/core/Makefile.am b/navit/osd/core/Makefile.am
new file mode 100644
index 000000000..cacb41747
--- /dev/null
+++ b/navit/osd/core/Makefile.am
@@ -0,0 +1,4 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=osd_core
+moduleosd_LTLIBRARIES = libosd_core.la
+libosd_core_la_SOURCES = osd_core.c
diff --git a/navit/osd/core/osd_core.c b/navit/osd/core/osd_core.c
new file mode 100644
index 000000000..588bedaec
--- /dev/null
+++ b/navit/osd/core/osd_core.c
@@ -0,0 +1,578 @@
+#include <math.h>
+#include <stdio.h>
+#include <glib.h>
+#include <time.h>
+#include <stdlib.h>
+#include <string.h>
+#include "config.h"
+#include "item.h"
+#include "point.h"
+#include "coord.h"
+#include "graphics.h"
+#include "transform.h"
+#include "route.h"
+#include "navit.h"
+#include "plugin.h"
+#include "debug.h"
+#include "callback.h"
+#include "color.h"
+#include "vehicle.h"
+#include "navigation.h"
+#include "track.h"
+#include "map.h"
+
+struct compass {
+ struct point p;
+ int w,h;
+ struct graphics *gr;
+ struct graphics_gc *bg;
+ struct graphics_gc *white;
+ struct graphics_gc *green;
+ struct graphics_font *font;
+};
+
+
+static void
+transform_rotate(struct point *center, int angle, struct point *p, int count)
+{
+ int i,x,y;
+ double dx,dy;
+ for (i = 0 ; i < count ; i++)
+ {
+ dx=sin(M_PI*angle/180.0);
+ dy=cos(M_PI*angle/180.0);
+ x=dy*p->x-dx*p->y;
+ y=dx*p->x+dy*p->y;
+
+ p->x=center->x+x;
+ p->y=center->y+y;
+ p++;
+ }
+}
+
+static void
+handle(struct graphics *gr, struct graphics_gc *gc, struct point *p, int r, int dir)
+{
+ struct point ph[3];
+ int l=r*0.4;
+
+ ph[0].x=0;
+ ph[0].y=r;
+ ph[1].x=0;
+ ph[1].y=-r;
+ transform_rotate(p, dir, ph, 2);
+ graphics_draw_lines(gr, gc, ph, 2);
+ ph[0].x=-l;
+ ph[0].y=-r+l;
+ ph[1].x=0;
+ ph[1].y=-r;
+ ph[2].x=l;
+ ph[2].y=-r+l;
+ transform_rotate(p, dir, ph, 3);
+ graphics_draw_lines(gr, gc, ph, 3);
+}
+
+static void
+format_distance(char *buffer, double distance)
+{
+ if (distance >= 100000)
+ sprintf(buffer,"%.0f km", distance/1000);
+ else if (distance >= 10000)
+ sprintf(buffer,"%.1f km", distance/1000);
+ else if (distance >= 300)
+ sprintf(buffer,"%.0f m", round(distance/25)*25);
+ else if (distance >= 50)
+ sprintf(buffer,"%.0f m", round(distance/10)*10);
+ else if (distance >= 10)
+ sprintf(buffer,"%.0f m", distance);
+ else
+ sprintf(buffer,"%.1f m", distance);
+}
+
+static void
+osd_compass_draw(struct compass *this, struct navit *nav, struct vehicle *v)
+{
+ struct point p;
+ struct attr attr_dir, destination_attr, position_attr;
+ double dir,vdir=0;
+ char buffer[16];
+ struct coord c1, c2;
+ enum projection pro;
+
+ graphics_draw_mode(this->gr, draw_mode_begin);
+ p.x=0;
+ p.y=0;
+ graphics_draw_rectangle(this->gr, this->bg, &p, this->w, this->h);
+ p.x=30;
+ p.y=30;
+ graphics_draw_circle(this->gr, this->white, &p, 50);
+ if (v && vehicle_get_attr(v, attr_position_direction, &attr_dir)) {
+ vdir=*attr_dir.u.numd;
+ handle(this->gr, this->white, &p, 20, -vdir);
+ }
+ if (navit_get_attr(nav, attr_destination, &destination_attr, NULL) && v && vehicle_get_attr(v, attr_position_coord_geo, &position_attr)) {
+ pro=destination_attr.u.pcoord->pro;
+ transform_from_geo(pro, position_attr.u.coord_geo, &c1);
+ c2.x=destination_attr.u.pcoord->x;
+ c2.y=destination_attr.u.pcoord->y;
+ dir=atan2(c2.x-c1.x,c2.y-c1.y)*180.0/M_PI;
+ dir-=vdir;
+ handle(this->gr, this->green, &p, 20, dir);
+ format_distance(buffer, transform_distance(pro, &c1, &c2));
+ p.x=8;
+ p.y=72;
+ graphics_draw_text(this->gr, this->green, NULL, this->font, buffer, &p, 0x10000, 0);
+ }
+ graphics_draw_mode(this->gr, draw_mode_end);
+}
+
+static void
+osd_compass_init(struct compass *this, struct navit *nav)
+{
+ struct graphics *navit_gr;
+ struct color c;
+ navit_gr=navit_get_graphics(nav);
+ this->gr=graphics_overlay_new(navit_gr, &this->p, this->w, this->h);
+
+ this->bg=graphics_gc_new(this->gr);
+ c.r=0; c.g=0; c.b=0;
+ graphics_gc_set_foreground(this->bg, &c);
+
+ this->white=graphics_gc_new(this->gr);
+ c.r=65535; c.g=65535; c.b=65535;
+ graphics_gc_set_foreground(this->white, &c);
+ graphics_gc_set_linewidth(this->white, 2);
+
+ this->green=graphics_gc_new(this->gr);
+ c.r=0; c.g=65535; c.b=0;
+ graphics_gc_set_foreground(this->green, &c);
+ graphics_gc_set_linewidth(this->green, 2);
+
+ this->font=graphics_font_new(this->gr, 200, 1);
+ navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_compass_draw), attr_position_coord_geo, this));
+
+ osd_compass_draw(this, nav, NULL);
+}
+
+static struct osd_priv *
+osd_compass_new(struct navit *nav, struct osd_methods *meth, struct attr **attrs)
+{
+ struct compass *this=g_new0(struct compass, 1);
+ struct attr *attr;
+ this->p.x=20;
+ this->p.y=20;
+ this->w=60;
+ this->h=80;
+ attr=attr_search(attrs, NULL, attr_x);
+ if (attr)
+ this->p.x=attr->u.num;
+ attr=attr_search(attrs, NULL, attr_y);
+ if (attr)
+ this->p.y=attr->u.num;
+ navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_compass_init), attr_navit, this));
+ return (struct osd_priv *) this;
+}
+
+struct eta {
+ struct point p;
+ int w,h;
+ struct graphics *gr;
+ struct graphics_gc *bg;
+ struct graphics_gc *white;
+ struct graphics_font *font;
+ struct graphics_image *flag;
+ int active;
+ char last_eta[16];
+ char last_distance[16];
+};
+
+static void
+osd_eta_draw(struct eta *this, struct navit *navit, struct vehicle *v)
+{
+ struct point p;
+ char eta[16];
+ char distance[16];
+ int days=0,do_draw=0;
+ time_t etat;
+ struct tm tm,eta_tm,eta_tm0;
+ struct attr attr;
+ struct navigation *nav=NULL;
+ struct map *map=NULL;
+ struct map_rect *mr=NULL;
+ struct item *item=NULL;
+
+
+ eta[0]='\0';
+ distance[0]='\0';
+
+ if (navit)
+ nav=navit_get_navigation(navit);
+ if (nav)
+ map=navigation_get_map(nav);
+ if (map)
+ mr=map_rect_new(map, NULL);
+ if (mr)
+ item=map_rect_get_item(mr);
+ if (item) {
+ if (item_attr_get(item, attr_destination_length, &attr)) {
+ format_distance(distance, attr.u.num);
+ }
+ if (item_attr_get(item, attr_destination_time, &attr)) {
+ etat=time(NULL);
+ tm=*localtime(&etat);
+ etat+=attr.u.num/10;
+ eta_tm=*localtime(&etat);
+ if (tm.tm_year != eta_tm.tm_year || tm.tm_mon != eta_tm.tm_mon || tm.tm_mday != eta_tm.tm_mday) {
+ eta_tm0=eta_tm;
+ eta_tm0.tm_sec=0;
+ eta_tm0.tm_min=0;
+ eta_tm0.tm_hour=0;
+ tm.tm_sec=0;
+ tm.tm_min=0;
+ tm.tm_hour=0;
+ days=(mktime(&eta_tm0)-mktime(&tm)+43200)/86400;
+ }
+ if (days)
+ sprintf(eta, "%d+%02d:%02d", days, eta_tm.tm_hour, eta_tm.tm_min);
+ else
+ sprintf(eta, " %02d:%02d", eta_tm.tm_hour, eta_tm.tm_min);
+ }
+ if (this->active != 1 || strcmp(this->last_distance, distance) || strcmp(this->last_eta, eta)) {
+ this->active=1;
+ strcpy(this->last_distance, distance);
+ strcpy(this->last_eta, eta);
+ do_draw=1;
+ }
+ } else {
+ if (this->active != 0) {
+ this->active=0;
+ do_draw=1;
+ }
+ }
+ if (mr)
+ map_rect_destroy(mr);
+
+ if (do_draw) {
+ graphics_draw_mode(this->gr, draw_mode_begin);
+ p.x=0;
+ p.y=0;
+ graphics_draw_rectangle(this->gr, this->bg, &p, this->w, this->h);
+ p.x=6;
+ p.y=6;
+ if (this->flag)
+ graphics_draw_image(this->gr, this->white, &p, this->flag);
+ if (eta[0]) {
+ p.x=28;
+ p.y=28;
+ graphics_draw_text(this->gr, this->white, NULL, this->font, "ETA", &p, 0x10000, 0);
+ p.x=6;
+ p.y=42;
+ graphics_draw_text(this->gr, this->white, NULL, this->font, eta, &p, 0x10000, 0);
+ }
+ if (distance[0]) {
+ p.x=6;
+ p.y=56;
+ graphics_draw_text(this->gr, this->white, NULL, this->font, distance, &p, 0x10000, 0);
+ }
+ graphics_draw_mode(this->gr, draw_mode_end);
+ }
+}
+
+static void
+osd_eta_init(struct eta *this, struct navit *nav)
+{
+ struct graphics *navit_gr;
+ struct color c;
+ char *flag=g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/xpm/flag_wh_bk.xpm", NULL);
+ navit_gr=navit_get_graphics(nav);
+ this->gr=graphics_overlay_new(navit_gr, &this->p, this->w, this->h);
+
+ this->bg=graphics_gc_new(this->gr);
+ c.r=0; c.g=0; c.b=0;
+ graphics_gc_set_foreground(this->bg, &c);
+
+ this->white=graphics_gc_new(this->gr);
+ c.r=65535; c.g=65535; c.b=65535;
+ graphics_gc_set_foreground(this->white, &c);
+ graphics_gc_set_linewidth(this->white, 2);
+
+ this->font=graphics_font_new(this->gr, 200, 1);
+ this->flag=graphics_image_new(this->gr, flag);
+ navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_eta_draw), attr_position_coord_geo, this));
+
+ osd_eta_draw(this, nav, NULL);
+ g_free(flag);
+}
+
+static struct osd_priv *
+osd_eta_new(struct navit *nav, struct osd_methods *meth, struct attr **attrs)
+{
+ struct eta *this=g_new0(struct eta, 1);
+ struct attr *attr;
+ this->p.x=-80;
+ this->p.y=20;
+ this->w=60;
+ this->h=60;
+ this->active=-1;
+ attr=attr_search(attrs, NULL, attr_x);
+ if (attr)
+ this->p.x=attr->u.num;
+ attr=attr_search(attrs, NULL, attr_y);
+ if (attr)
+ this->p.y=attr->u.num;
+ navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_eta_init), attr_navit, this));
+ return (struct osd_priv *) this;
+}
+
+struct osd_navigation {
+ struct point p;
+ int w,h;
+ struct graphics *gr;
+ struct graphics_gc *bg;
+ struct graphics_gc *white;
+ struct graphics_font *font;
+ int active;
+ char last_distance[16];
+ char *last_name;
+};
+
+static void
+osd_navigation_draw(struct osd_navigation *this, struct navit *navit, struct vehicle *v)
+{
+ struct point p;
+ char distance[16];
+ int do_draw=0;
+ struct attr attr;
+ struct navigation *nav=NULL;
+ struct map *map=NULL;
+ struct map_rect *mr=NULL;
+ struct item *item=NULL;
+ struct graphics_image *gr_image;
+ char *image;
+ char *name="unknown";
+
+ distance[0]='\0';
+
+ if (navit)
+ nav=navit_get_navigation(navit);
+ if (nav)
+ map=navigation_get_map(nav);
+ if (map)
+ mr=map_rect_new(map, NULL);
+ if (mr)
+ item=map_rect_get_item(mr);
+ if (item) {
+ name=item_to_name(item->type);
+ dbg(1,"name=%s\n", name);
+ if (item_attr_get(item, attr_length, &attr)) {
+ format_distance(distance, attr.u.num);
+ }
+ if (this->active != 1 || strcmp(this->last_distance, distance) || this->last_name != name) {
+ this->active=1;
+ strcpy(this->last_distance, distance);
+ this->last_name=name;
+ do_draw=1;
+ }
+ } else {
+ if (this->active != 0) {
+ this->active=0;
+ do_draw=1;
+ }
+ }
+ if (mr)
+ map_rect_destroy(mr);
+
+ if (do_draw) {
+ graphics_draw_mode(this->gr, draw_mode_begin);
+ p.x=0;
+ p.y=0;
+ graphics_draw_rectangle(this->gr, this->bg, &p, this->w, this->h);
+ if (this->active) {
+ image=g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/xpm/", name, "_32.xpm", NULL);
+ gr_image=graphics_image_new(this->gr, image);
+ if (! gr_image) {
+ g_free(image);
+ image=g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/xpm/unknown.xpm", NULL);
+ gr_image=graphics_image_new(this->gr, image);
+ }
+ dbg(1,"gr_image=%p\n", gr_image);
+ if (gr_image) {
+ p.x=(this->w-gr_image->width)/2;
+ p.y=(46-gr_image->height)/2;
+ graphics_draw_image(this->gr, this->white, &p, gr_image);
+ graphics_image_free(this->gr, gr_image);
+ }
+ p.x=12;
+ p.y=56;
+ graphics_draw_text(this->gr, this->white, NULL, this->font, distance, &p, 0x10000, 0);
+ }
+ graphics_draw_mode(this->gr, draw_mode_end);
+ }
+}
+
+static void
+osd_navigation_init(struct osd_navigation *this, struct navit *nav)
+{
+ struct graphics *navit_gr;
+ struct color c;
+ navit_gr=navit_get_graphics(nav);
+ this->gr=graphics_overlay_new(navit_gr, &this->p, this->w, this->h);
+
+ this->bg=graphics_gc_new(this->gr);
+ c.r=0; c.g=0; c.b=0;
+ graphics_gc_set_foreground(this->bg, &c);
+
+ this->white=graphics_gc_new(this->gr);
+ c.r=65535; c.g=65535; c.b=65535;
+ graphics_gc_set_foreground(this->white, &c);
+ graphics_gc_set_linewidth(this->white, 2);
+
+ this->font=graphics_font_new(this->gr, 200, 1);
+ navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_navigation_draw), attr_position_coord_geo, this));
+
+ osd_navigation_draw(this, nav, NULL);
+}
+
+static struct osd_priv *
+osd_navigation_new(struct navit *nav, struct osd_methods *meth, struct attr **attrs)
+{
+ struct osd_navigation *this=g_new0(struct osd_navigation, 1);
+ struct attr *attr;
+ this->p.x=20;
+ this->p.y=-80;
+ this->w=60;
+ this->h=60;
+ this->active=-1;
+ attr=attr_search(attrs, NULL, attr_x);
+ if (attr)
+ this->p.x=attr->u.num;
+ attr=attr_search(attrs, NULL, attr_y);
+ if (attr)
+ this->p.y=attr->u.num;
+ navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_navigation_init), attr_navit, this));
+ return (struct osd_priv *) this;
+}
+
+struct osd_street_name {
+ struct point p;
+ int w,h;
+ struct graphics *gr;
+ struct graphics_gc *bg;
+ struct graphics_gc *white;
+ struct graphics_font *font;
+ int active;
+ struct item item;
+};
+
+static void
+osd_street_name_draw(struct osd_street_name *this, struct navit *navit, struct vehicle *v)
+{
+ struct point p;
+ char distance[16];
+ int do_draw=0;
+ struct attr attr_name1, attr_name2;
+ char *name1=NULL,*name2=NULL;
+ struct tracking *tr=NULL;
+ struct map_rect *mr=NULL;
+ struct item *item=NULL;
+ char *name=NULL;
+
+ distance[0]='\0';
+ if (navit)
+ tr=navit_get_tracking(navit);
+ if (tr)
+ item=tracking_get_current_item(tr);
+ dbg(1,"navit=%p tr=%p item=%p\n", navit, tr, item);
+ if (item) {
+ if (!item_is_equal(*item, this->item)) {
+ do_draw=1;
+ this->item=*item;
+ mr=map_rect_new(item->map,NULL);
+ item=map_rect_get_item_byid(mr, item->id_hi, item->id_lo);
+ if (item_attr_get(item, attr_street_name, &attr_name1))
+ name1=map_convert_string(item->map, attr_name1.u.str);
+ if (item_attr_get(item, attr_street_name_systematic, &attr_name2))
+ name2=map_convert_string(item->map, attr_name2.u.str);
+ printf("name1=%s name2=%s\n", name1, name2);
+ map_rect_destroy(mr);
+ if (name1 && name2)
+ name=g_strdup_printf("%s/%s", name2,name1);
+ else
+ name=g_strdup(name1?name1:name2);
+ map_convert_free(name1);
+ map_convert_free(name2);
+ this->active=1;
+ }
+ } else {
+ if (this->item.map || this->active)
+ do_draw=1;
+ this->active=0;
+ memset(&this->item, 0, sizeof(this->item));
+ name=NULL;
+ }
+ if (do_draw) {
+ dbg(1,"name=%s\n", name);
+ graphics_draw_mode(this->gr, draw_mode_begin);
+ p.x=0;
+ p.y=0;
+ graphics_draw_rectangle(this->gr, this->bg, &p, 32767, 32767);
+ if (name) {
+ p.x=2;
+ p.y=12;
+ graphics_draw_text(this->gr, this->white, NULL, this->font, name, &p, 0x10000, 0);
+ }
+ graphics_draw_mode(this->gr, draw_mode_end);
+ }
+}
+
+static void
+osd_street_name_init(struct osd_street_name *this, struct navit *nav)
+{
+ struct graphics *navit_gr;
+ struct color c;
+ navit_gr=navit_get_graphics(nav);
+ this->active=-1;
+ this->gr=graphics_overlay_new(navit_gr, &this->p, this->w, this->h);
+
+ this->bg=graphics_gc_new(this->gr);
+ c.r=0; c.g=0; c.b=0;
+ graphics_gc_set_foreground(this->bg, &c);
+
+ this->white=graphics_gc_new(this->gr);
+ c.r=65535; c.g=65535; c.b=65535;
+ graphics_gc_set_foreground(this->white, &c);
+
+ this->font=graphics_font_new(this->gr, 200, 1);
+ navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_street_name_draw), attr_position_coord_geo, this));
+
+ osd_street_name_draw(this, nav, NULL);
+}
+
+static struct osd_priv *
+osd_street_name_new(struct navit *nav, struct osd_methods *meth, struct attr **attrs)
+{
+ struct osd_street_name *this=g_new0(struct osd_street_name, 1);
+ struct attr *attr;
+ this->p.x=90;
+ this->p.y=-36;
+ this->w=150;
+ this->h=16;
+ attr=attr_search(attrs, NULL, attr_x);
+ if (attr)
+ this->p.x=attr->u.num;
+ attr=attr_search(attrs, NULL, attr_y);
+ if (attr)
+ this->p.y=attr->u.num;
+ navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_street_name_init), attr_navit, this));
+ return (struct osd_priv *) this;
+}
+
+void
+plugin_init(void)
+{
+ plugin_register_osd_type("compass", osd_compass_new);
+ plugin_register_osd_type("eta", osd_eta_new);
+ plugin_register_osd_type("navigation", osd_navigation_new);
+ plugin_register_osd_type("street_name", osd_street_name_new);
+}
+
diff --git a/navit/osm2navit.c b/navit/osm2navit.c
new file mode 100644
index 000000000..ace673556
--- /dev/null
+++ b/navit/osm2navit.c
@@ -0,0 +1,2442 @@
+
+#define _FILE_OFFSET_BITS 64
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+#include <glib.h>
+#include <assert.h>
+#include <string.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <zlib.h>
+#include "item.h"
+#include "zipfile.h"
+#include "config.h"
+
+#define BUFFER_SIZE 1280
+
+#define GENERATE_INDEX
+
+#if 1
+#define debug_tile(x) 0
+#else
+#define debug_tile(x) (!strcmp(x,"bcdbd") || !strcmp(x,"bcdbd") || !strcmp(x,"bcdbda") || !strcmp(x,"bcdbdb") || !strcmp(x,"bcdbdba") || !strcmp(x,"bcdbdbb") || !strcmp(x,"bcdbdbba") || !strcmp(x,"bcdbdbaa") || !strcmp(x,"bcdbdbacaa") || !strcmp(x,"bcdbdbacab") || !strcmp(x,"bcdbdbacaba") || !strcmp(x,"bcdbdbacabaa") || !strcmp(x,"bcdbdbacabab") || !strcmp(x,"bcdbdbacababb") || !strcmp(x,"bcdbdbacababba") || !strcmp(x,"bcdbdbacababbb") || !strcmp(x,"bcdbdbacababbd") || !strcmp(x,"bcdbdbacababaa") || !strcmp(x,"bcdbdbacababab") || !strcmp(x,"bcdbdbacababac") || !strcmp(x,"bcdbdbacababad") || !strcmp(x,"bcdbdbacabaaa") || !strcmp(x,"bcdbdbacabaaba") || !strcmp(x,"bcdbdbacabaabb") || !strcmp(x,"bcdbdbacabaabc") || !strcmp(x,"bcdbdbacabaabd") || !strcmp(x,"bcdbdbacabaaaa") || !strcmp(x,"bcdbdbacabaaab") || !strcmp(x,"bcdbdbacabaaac") || !strcmp(x,"bcdbdbacabaaad") || 0)
+#endif
+
+#define IS_TOWN(item) ((item).type >= type_town_label && (item).type <= type_town_label_1e7)
+#define IS_STREET(item) ((item).type >= type_street_nopass && (item).type <= type_ferry)
+
+static GHashTable *dedupe_ways_hash;
+
+static int attr_debug_level=1;
+static int nodeid,wayid;
+static int report,phase;
+static int ignore_unkown = 0, coverage=0;
+
+static char *attrmap={
+ "n *=* point_unkn\n"
+ "n amenity=hospital poi_hospital\n"
+ "n amenity=atm poi_bank\n"
+ "n amenity=bank poi_bank\n"
+ "n amenity=pub poi_bar\n"
+ "n amenity=cafe poi_cafe\n"
+ "n amenity=bus_station poi_bus_station\n"
+ "n amenity=parking poi_car_parking\n"
+ "n amenity=cinema poi_cinema\n"
+ "n amenity=fire_station poi_firebrigade\n"
+ "n amenity=fuel poi_fuel\n"
+ "n amenity=courthouse poi_justice\n"
+ "n amenity=library poi_library\n"
+ "n amenity=pharmacy poi_pharmacy\n"
+ "n amenity=place_of_worship,religion=christian poi_church\n"
+ "n amenity=police poi_police\n"
+ "n amenity=post_office poi_post\n"
+ "n amenity=post_box poi_post\n"
+ "n amenity=public_building poi_public_office\n"
+ "n amenity=restaurant poi_restaurant\n"
+ "n amenity=fast_food poi_fastfood\n"
+ "n amenity=toilets poi_restroom\n"
+ "n amenity=school poi_school\n"
+ "n amenity=university poi_school\n"
+ "n amenity=college poi_school\n"
+ "n amenity=telephone poi_telephone\n"
+ "n amenity=theatre poi_theater\n"
+ "n amenity=townhall poi_townhall\n"
+ "n highway=bus_stop poi_bus_stop\n"
+ "n highway=mini_roundabout mini_roundabout\n"
+ "n highway=motorway_junction highway_exit\n"
+ "n highway=traffic_signals traffic_signals\n"
+ "n highway=turning_circle turning_circle\n"
+ "n leisure=slipway poi_boat_ramp\n"
+ "n leisure=fishing poi_fish\n"
+ "n sport=golf poi_golf\n"
+ "n leisure=golf_course poi_golf\n"
+ "n leisure=marina poi_marine\n"
+ "n leisure=sports_centre poi_sport\n"
+ "n leisure=stadium poi_stadium\n"
+ "n shop=supermarket poi_shopping\n"
+ "n shop=convenience poi_shop_grocery\n"
+ "n tourism=attraction poi_attraction\n"
+ "n tourism=camp_site poi_camp_rv\n"
+ "n tourism=caravan_site poi_camp_rv\n"
+ "n tourism=hotel poi_hotel\n"
+ "n tourism=motel poi_hotel\n"
+ "n tourism=guest_house poi_hotel\n"
+ "n tourism=hostel poi_hotel\n"
+ "n tourism=information poi_information\n"
+ "n tourism=museum poi_museum_history\n"
+ "n tourism=picnic_site poi_picnic\n"
+ "n tourism=theme_park poi_resort\n"
+ "n tourism=zoo poi_zoo\n"
+ "n amenity=grave_yard poi_cemetery\n"
+ "n landuse=cemetery poi_cemetery\n"
+ "n military=airfield poi_military\n"
+ "n military=bunker poi_military\n"
+ "n military=barracks poi_military\n"
+ "n military=range poi_military\n"
+ "n military=danger_area poi_danger_area\n"
+ "n sport=swimming poi_swimming\n"
+ "n sport=skiing poi_skiing\n"
+ "n aeroway=aerodrome poi_airport\n"
+ "n aeroway=airport poi_airport\n"
+ "n aeroway=terminal poi_airport\n"
+ "n aeroway=helipad poi_heliport\n"
+ "n man_made=tower poi_tower\n"
+ "n natural=bay poi_bay\n"
+ "n natural=peak poi_peak\n"
+ "n place=suburb district_label\n"
+ "n place=city town_label_2e5\n"
+ "n place=town town_label_2e4\n"
+ "n place=village town_label_2e3\n"
+ "n place=hamlet town_label_2e2\n"
+ "n place=locality town_label_2e0\n"
+ "n railway=halt poi_rail_halt\n"
+ "n railway=level_crossing poi_level_crossing\n"
+ "n railway=station poi_rail_station\n"
+ "n railway=tram_stop poi_rail_tram_stop\n"
+ "w *=* street_unkn\n"
+ "w amenity=place_of_worship poly_building\n"
+ "w building=* poly_building\n"
+ "w aeroway=aerodrome poly_airport\n"
+ "w aeroway=apron poly_apron\n"
+ "w aeroway=runway aeroway_runway\n"
+ "w aeroway=taxiway aeroway_taxiway\n"
+ "w aeroway=terminal poly_terminal\n"
+ "w highway=bridleway bridleway\n"
+ "w highway=cycleway cycleway\n"
+ "w highway=cyclepath cycleway\n"
+ "w cycleway=track cycleway\n"
+ "w highway=footway footway\n"
+ "w highway=steps steps\n"
+ "w highway=unsurfaced track_gravelled\n"
+ "w highway=track track_gravelled\n"
+ "w highway=track,tracktype=grade1 track_paved\n"
+ "w highway=track,surface=paved track_paved\n"
+ "w highway=track,tracktype=grade2 track_gravelled\n"
+ "w highway=track,surface=gravel track_gravelled\n"
+ "w highway=track,tracktype=grade3 track_unpaved\n"
+ "w highway=track,surface=unpaved track_unpaved\n"
+ "w highway=track,tracktype=grade4 track_ground\n"
+ "w highway=track,surface=ground track_ground\n"
+ "w highway=track,tracktype=grade5 track_grass\n"
+ "w highway=track,surface=grass track_grass\n"
+ "w highway=service street_service\n"
+ "w highway=construction street_construction\n"
+ "w highway=pedestrian street_pedestrian\n"
+ "w highway=pedestrian,area=1 poly_pedestrian\n"
+ "w highway=plaza poly_plaza\n"
+ "w landuse=plaza poly_plaza\n"
+ "w highway=residential street_1_city\n"
+ "w highway=living_street living_street\n"
+ "w highway=unclassified street_1_city\n"
+ "w highway=minor street_1_land\n"
+ "w highway=tertiary street_2_city\n"
+ "w highway=secondary street_3_city\n"
+ "w highway=primary street_4_city\n"
+ "w highway=primary_link ramp\n"
+ "w highway=trunk street_4_city\n"
+ "w highway=trunk_link ramp\n"
+ "w highway=motorway highway_city\n"
+ "w highway=motorway_link ramp\n"
+ "w historic=town gate poly_building\n"
+ "w amenity=parking poly_car_parking\n"
+ "w landuse=allotments poly_allotments\n"
+ "w landuse=cemetery poly_cemetery\n"
+ "w amenity=grave_yard poly_cemetery\n"
+ "w landuse=forest poly_wood\n"
+ "w landuse=industrial poly_industry\n"
+ "w landuse=residential poly_town\n"
+ "w landuse=residential,area=1 poly_town\n"
+ "w amenity=college poly_college\n"
+ "w amenity=university poly_university\n"
+ "w tourism=camp_site poly_camp_site\n"
+ "w tourism=caravan_site poly_caravan_site\n"
+ "w tourism=picnic_site poly_picnic_site\n"
+ "w tourism=theme_park poly_theme_park\n"
+ "w tourism=attraction poly_attraction\n"
+ "w tourism=zoo poly_zoo\n"
+ "w tourism=artwork poly_artwork\n"
+ "w historic=archaeological_site poly_archaeological_site\n"
+ "w historic=ruins poly_ruins\n"
+ "w historic=battlefield poly_battlefield\n"
+ "w landuse=quarry poly_quarry\n"
+ "w landuse=landfill poly_landfill\n"
+ "w landuse=retail poly_retail\n"
+ "w landuse=commercial poly_commercial\n"
+ "w landuse=brownfield poly_brownfield\n"
+ "w landuse=greenfield poly_greenfield\n"
+ "w landuse=construction poly_construction\n"
+ "w landuse=railway poly_railway\n"
+ "w natural=glacier poly_glacier\n"
+ "w natural=scree poly_scree\n"
+ "w natural=scrub poly_scrub\n"
+ "w natural=fell poly_fell\n"
+ "w natural=heath poly_heath\n"
+ "w natural=marsh poly_marsh\n"
+ "w natural=mud poly_mud\n"
+ "w natural=beach poly_beach\n"
+ "w natural=land poly_land\n"
+ "w landuse=basin poly_basin\n"
+ "w landuse=reservoir poly_reservoir\n"
+ "w landuse=farm poly_farm\n"
+ "w leisure=park poly_park\n"
+ "w landuse=village_green poly_village_green\n"
+ "w landuse=recreation_ground poly_recreation_ground\n"
+ "w natural=wood poly_wood\n"
+ "w natural=water poly_water\n"
+ "w natural=coastline water_line\n"
+ "w place=suburb poly_town\n"
+ "w place=town poly_town\n"
+ "w landuse=military poly_military\n"
+ "w military=airfield poly_airfield\n"
+ "w military=barracks poly_barracks\n"
+ "w military=danger_area poly_danger_area\n"
+ "w military=range poly_range\n"
+ "w military=naval_base poly_naval_base\n"
+ "w power=line powerline\n"
+ "w railway=rail rail\n"
+ "w railway=narrow_gauge rail_narrow_gauge\n"
+ "w railway=light_rail rail_light\n"
+ "w railway=subway rail_subway\n"
+ "w railway=tram rail_tram\n"
+ "w railway=monorail rail_mono\n"
+ "w railway=preserved rail_preserved\n"
+ "w railway=disused rail_disused\n"
+ "w railway=abandoned rail_abandoned\n"
+ "w aerialway=cable_car lift_cable_car\n"
+ "w aerialway=chair_lift lift_chair\n"
+ "w aerialway=drag_lift lift_drag\n"
+ "w leisure=golf_course poly_golf_course\n"
+ "w sport=* poly_sport\n"
+ "w leisure=sports_centre poly_sport\n"
+ "w leisure=stadium poly_sports_stadium\n"
+ "w leisure=track poly_sports_track\n"
+ "w leisure=pitch poly_sports_pitch\n"
+ "w leisure=water_park poly_water_park\n"
+ "w leisure=marina poly_marina\n"
+ "w leisure=fishing poly_fishing\n"
+ "w leisure=garden poly_garden\n"
+ "w leisure=common poly_common\n"
+ "w leisure=playground poly_playground\n"
+ "w leisure=nature_reserve poly_nature_reserve\n"
+ "w waterway=canal water_canal\n"
+ "w waterway=river water_river\n"
+ "w waterway=stream water_stream\n"
+ "w waterway=drain water_drain\n"
+ "w waterway=riverbank poly_water\n"
+ "w boundary=administrative border_country\n"
+ "w boundary=civil border_civil\n"
+ "w boundary=political border_political\n"
+ "w boundary=national_park border_national_park\n"
+ "w route=ferry ferry\n"
+ "w highway=bus_guideway bus_guideway\n"
+};
+
+struct coord {
+ int x;
+ int y;
+} coord_buffer[65536];
+
+#define IS_REF(c) ((c).x >= (1 << 30))
+#define REF(c) ((c).y)
+#define SET_REF(c,ref) do { (c).x = 1 << 30; (c).y = ref ; } while(0)
+
+struct rect {
+ struct coord l,h;
+};
+
+static void bbox_extend(struct coord *c, struct rect *r);
+
+#ifdef GENERATE_INDEX
+
+static GHashTable *aux_tile_hash;
+GList *aux_tile_list;
+
+struct country_table {
+ int countryid;
+ char *names;
+ FILE *file;
+ int size;
+ int count;
+ struct rect r;
+} country_table[] = {
+ { 40,"Austria,Österreich,AUT"},
+ {124,"Canada"},
+ {276,"Germany,Deutschland,Bundesrepublik Deutschland"},
+ {528,"Nederland,The Netherlands,Niederlande,NL"},
+ {756,"Schweiz"},
+};
+
+static GHashTable *country_table_hash;
+#endif
+
+struct attr_mapping {
+ enum item_type type;
+ int attr_present_idx_count;
+ int attr_present_idx[0];
+};
+
+static struct attr_mapping **attr_mapping_node;
+static int attr_mapping_node_count;
+static struct attr_mapping **attr_mapping_way;
+static int attr_mapping_way_count;
+
+static char *attr_present;
+static int attr_present_count;
+static GHashTable *attr_hash;
+
+
+static GHashTable *strings_hash = NULL;
+
+
+static char* string_hash_lookup( const char* key )
+{
+ char* key_ptr = NULL;
+
+ if ( strings_hash == NULL ) {
+ strings_hash = g_hash_table_new(g_str_hash, g_str_equal);
+ }
+
+ if ( ( key_ptr = g_hash_table_lookup(strings_hash, key )) == NULL ) {
+ key_ptr = g_strdup( key );
+ g_hash_table_insert(strings_hash, key_ptr, (gpointer)key_ptr );
+
+ }
+ return key_ptr;
+}
+
+static void
+build_attrmap_line(char *line)
+{
+ char *t=NULL,*kvl=NULL,*i=NULL,*p,*kv;
+ struct attr_mapping ***attr_mapping_curr,*attr_mapping=g_malloc0(sizeof(struct attr_mapping));
+ int idx,attr_mapping_count=0,*attr_mapping_curr_count;
+ t=line;
+ p=strchr(t,'\t');
+ if (p) {
+ while (*p == '\t')
+ *p++='\0';
+ kvl=p;
+ p=strchr(kvl,'\t');
+ }
+ if (p) {
+ while (*p == '\t')
+ *p++='\0';
+ i=p;
+ }
+ if (t[0] == 'w') {
+ if (! i)
+ i="street_unkn";
+ attr_mapping_curr=&attr_mapping_way;
+ attr_mapping_curr_count=&attr_mapping_way_count;
+ } else {
+ if (! i)
+ i="point_unkn";
+ attr_mapping_curr=&attr_mapping_node;
+ attr_mapping_curr_count=&attr_mapping_node_count;
+ }
+ attr_mapping->type=item_from_name(i);
+ while ((kv=strtok(kvl, ","))) {
+ kvl=NULL;
+ if (!(idx=(int)g_hash_table_lookup(attr_hash, kv))) {
+ idx=attr_present_count++;
+ g_hash_table_insert(attr_hash, kv, (gpointer) idx);
+ }
+ attr_mapping=g_realloc(attr_mapping, sizeof(struct attr_mapping)+(attr_mapping_count+1)*sizeof(int));
+ attr_mapping->attr_present_idx[attr_mapping_count++]=idx;
+ attr_mapping->attr_present_idx_count=attr_mapping_count;
+ }
+ *attr_mapping_curr=g_realloc(*attr_mapping_curr, sizeof(**attr_mapping_curr)*(*attr_mapping_curr_count+1));
+ (*attr_mapping_curr)[(*attr_mapping_curr_count)++]=attr_mapping;
+}
+
+static void
+build_attrmap(char *map)
+{
+ char *p;
+ attr_hash=g_hash_table_new(g_str_hash, g_str_equal);
+ attr_present_count=1;
+ while (map) {
+ p=strchr(map,'\n');
+ if (p)
+ *p++='\0';
+ if (strlen(map))
+ build_attrmap_line(map);
+ map=p;
+ }
+ attr_present=g_malloc0(sizeof(*attr_present)*attr_present_count);
+}
+
+#ifdef GENERATE_INDEX
+static void
+build_countrytable(void)
+{
+ int i;
+ char *names,*str,*tok;
+ country_table_hash=g_hash_table_new(g_str_hash, g_str_equal);
+ for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++) {
+ names=g_strdup(country_table[i].names);
+ str=names;
+ while ((tok=strtok(str, ","))) {
+ str=NULL;
+ g_hash_table_insert(country_table_hash, tok, (gpointer)&country_table[i]);
+ }
+ }
+}
+#endif
+
+
+
+static int processed_nodes, processed_nodes_out, processed_ways, processed_relations, processed_tiles;
+static int in_way, in_node, in_relation;
+
+static void
+sig_alrm(int sig)
+{
+#ifndef _WIN32
+ signal(SIGALRM, sig_alrm);
+#endif
+ alarm(30);
+ fprintf(stderr,"PROGRESS%d: Processed %d nodes (%d out) %d ways %d relations %d tiles\n", phase, processed_nodes, processed_nodes_out, processed_ways, processed_relations, processed_tiles);
+}
+
+struct item_bin {
+ int len;
+ enum item_type type;
+ int clen;
+} item;
+
+struct attr_bin {
+ int len;
+ enum attr_type type;
+};
+
+struct attr_bin label_attr = {
+ 0, attr_label
+};
+char label_attr_buffer[BUFFER_SIZE];
+
+struct attr_bin town_name_attr = {
+ 0, attr_town_name
+};
+
+struct attr_bin street_name_attr = {
+ 0, attr_street_name
+};
+
+struct attr_bin street_name_systematic_attr = {
+ 0, attr_street_name_systematic
+};
+char street_name_systematic_attr_buffer[BUFFER_SIZE];
+
+struct attr_bin debug_attr = {
+ 0, attr_debug
+};
+char debug_attr_buffer[BUFFER_SIZE];
+
+struct attr_bin flags_attr = {
+ 0, attr_flags
+};
+int flags_attr_value;
+
+char is_in_buffer[BUFFER_SIZE];
+
+
+static void write_zipmember(FILE *out, FILE *dir_out, char *name, int filelen, char *data, int data_size, int compression_level);
+
+static void
+pad_text_attr(struct attr_bin *a, char *buffer)
+{
+ int l;
+ if (buffer && buffer[0]) {
+ l=strlen(buffer)+1;
+ while (l % 4)
+ buffer[l++]='\0';
+ a->len=l/4+1;
+ } else
+ a->len=0;
+}
+
+static int
+xml_get_attribute(char *xml, char *attribute, char *buffer, int buffer_size)
+{
+ int len=strlen(attribute);
+ char *pos,*i,s,attr[len+2];
+ strcpy(attr, attribute);
+ strcpy(attr+len, "=");
+ pos=strstr(xml, attr);
+ if (! pos)
+ return 0;
+ pos+=len+1;
+ s=*pos++;
+ if (! s)
+ return 0;
+ i=strchr(pos, s);
+ if (! i)
+ return 0;
+ if (i - pos > buffer_size) {
+ fprintf(stderr,"Buffer overflow %d vs %d\n", i-pos, buffer_size);
+ return 0;
+ }
+ strncpy(buffer, pos, i-pos);
+ buffer[i-pos]='\0';
+ return 1;
+}
+
+static int node_is_tagged;
+
+static void
+add_tag(char *k, char *v)
+{
+ GHashTable *value_hash;
+ enum item_type type;
+ int idx,level=2;
+ char buffer[BUFFER_SIZE*2+2];
+ if (! strcmp(k,"ele"))
+ level=9;
+ if (! strcmp(k,"time"))
+ level=9;
+ if (! strcmp(k,"created_by"))
+ level=9;
+ if (! strncmp(k,"tiger:",6) || !strcmp(k,"AND_nodes"))
+ level=9;
+ if (! strcmp(k,"converted_by") || ! strcmp(k,"source"))
+ level=8;
+ if (! strncmp(k,"osmarender:",11) || !strncmp(k,"svg:",4))
+ level=8;
+ if (! strcmp(k,"layer"))
+ level=7;
+ if (! strcasecmp(v,"true") || ! strcasecmp(v,"yes"))
+ v="1";
+ if (! strcmp(k,"oneway")) {
+ if (!strcmp(v,"1")) {
+ flags_attr_value=AF_ONEWAY;
+ flags_attr.len=2;
+ }
+ if (! strcmp(v,"-1")) {
+ flags_attr_value=AF_ONEWAYREV;
+ flags_attr.len=2;
+ }
+ if (!in_way)
+ level=6;
+ else
+ level=5;
+ }
+ if (! strcmp(k,"junction")) {
+ if (! strcmp(v,"roundabout")) {
+ flags_attr_value=AF_ONEWAY;
+ flags_attr.len=2;
+ }
+ }
+ if (! strcmp(k,"maxspeed")) {
+ level=5;
+ }
+ if (! strcmp(k,"bicycle")) {
+ level=5;
+ }
+ if (! strcmp(k,"foot")) {
+ level=5;
+ }
+ if (! strcmp(k,"note"))
+ level=5;
+ if (! strcmp(k,"name")) {
+ strcpy(label_attr_buffer, v);
+ pad_text_attr(&label_attr, label_attr_buffer);
+ level=5;
+ }
+ if (! strcmp(k,"ref")) {
+ if (in_way) {
+ strcpy(street_name_systematic_attr_buffer, v);
+ pad_text_attr(&street_name_systematic_attr, street_name_systematic_attr_buffer);
+ }
+ level=5;
+ }
+ if (! strcmp(k,"is_in")) {
+ strcpy(is_in_buffer, v);
+ level=5;
+ }
+ if (! strcmp(k,"lanes")) {
+ level=5;
+ }
+ if (attr_debug_level >= level) {
+ int bytes_left = sizeof( debug_attr_buffer ) - strlen(debug_attr_buffer) - 1;
+ if ( bytes_left > 0 )
+ {
+ snprintf(debug_attr_buffer+strlen(debug_attr_buffer), bytes_left, " %s=%s", k, v);
+ debug_attr_buffer[ sizeof( debug_attr_buffer ) - 1 ] = '\0';
+ node_is_tagged=1;
+ }
+ }
+ if (level < 6)
+ node_is_tagged=1;
+ if (level >= 5)
+ return;
+
+ strcpy(buffer,"*=*");
+ if ((idx=(int)g_hash_table_lookup(attr_hash, buffer)))
+ attr_present[idx]=1;
+
+ sprintf(buffer,"%s=*", k);
+ if ((idx=(int)g_hash_table_lookup(attr_hash, buffer)))
+ attr_present[idx]=2;
+
+ sprintf(buffer,"*=%s", v);
+ if ((idx=(int)g_hash_table_lookup(attr_hash, buffer)))
+ attr_present[idx]=2;
+
+ sprintf(buffer,"%s=%s", k, v);
+ if ((idx=(int)g_hash_table_lookup(attr_hash, buffer)))
+ attr_present[idx]=4;
+}
+
+struct entity {
+ char *entity;
+ char c;
+} entities[]= {
+ {"&qout;",'"'},
+ {"&apos;",'\''},
+ {"&amp;",'&'},
+ {"&lt;",'<'},
+ {"&gt;",'>'},
+};
+
+static void
+decode_entities(char *buffer)
+{
+ char *pos=buffer;
+ int i,len,found;
+
+ while ((pos=strchr(pos, '&'))) {
+ found=0;
+ for (i = 0 ; i < sizeof(entities)/sizeof(struct entity); i++) {
+ len=strlen(entities[i].entity);
+ if (!strncmp(pos, entities[i].entity, len)) {
+ *pos=entities[i].c;
+ memmove(pos+1, pos+len, strlen(pos+len)+1);
+ found=1;
+ break;
+ }
+ }
+ pos++;
+ }
+}
+
+static int
+parse_tag(char *p)
+{
+ char k_buffer[BUFFER_SIZE];
+ char v_buffer[BUFFER_SIZE];
+ if (!xml_get_attribute(p, "k", k_buffer, BUFFER_SIZE))
+ return 0;
+ if (!xml_get_attribute(p, "v", v_buffer, BUFFER_SIZE))
+ return 0;
+ decode_entities(v_buffer);
+ add_tag(k_buffer, v_buffer);
+ return 1;
+}
+
+
+struct buffer {
+ int malloced_step;
+ size_t malloced;
+ unsigned char *base;
+ size_t size;
+};
+
+static struct tile_head {
+ int num_subtiles;
+ int total_size;
+ char *name;
+ char *zip_data;
+ int total_size_used;
+ int zipnum;
+ int process;
+ struct tile_head *next;
+ // char subtiles[0];
+} *tile_head_root;
+
+
+int coord_count;
+
+struct node_item {
+ int id;
+ char ref_node;
+ char ref_way;
+ char ref_ref;
+ char dummy;
+ struct coord c;
+};
+
+static struct buffer node_buffer = {
+ 64*1024*1024,
+};
+
+
+static char** th_get_subtile( const struct tile_head* th, int idx )
+{
+ char* subtile_ptr = NULL;
+ subtile_ptr = (char*)th + sizeof( struct tile_head ) + idx * sizeof( char *);
+ return (char**)subtile_ptr;
+}
+
+static void
+extend_buffer(struct buffer *b)
+{
+ b->malloced+=b->malloced_step;
+ b->base=realloc(b->base, b->malloced);
+ if (b->base == NULL) {
+ fprintf(stderr,"realloc of %d bytes failed\n",b->malloced);
+ exit(1);
+ }
+
+}
+
+int nodeid_last;
+GHashTable *node_hash;
+
+static void
+node_buffer_to_hash(void)
+{
+ int i,count=node_buffer.size/sizeof(struct node_item);
+ struct node_item *ni=(struct node_item *)node_buffer.base;
+ for (i = 0 ; i < count ; i++)
+ g_hash_table_insert(node_hash, (gpointer)(ni[i].id), (gpointer)i);
+}
+
+static struct node_item *ni;
+
+static void
+add_node(int id, double lat, double lon)
+{
+ if (node_buffer.size + sizeof(struct node_item) > node_buffer.malloced)
+ extend_buffer(&node_buffer);
+ node_is_tagged=0;
+ nodeid=id;
+ item.type=type_point_unkn;
+ label_attr.len=0;
+ town_name_attr.len=0;
+ debug_attr.len=0;
+ is_in_buffer[0]='\0';
+ sprintf(debug_attr_buffer,"nodeid=%d", nodeid);
+ ni=(struct node_item *)(node_buffer.base+node_buffer.size);
+ ni->id=id;
+ ni->ref_node=0;
+ ni->ref_way=0;
+ ni->ref_ref=0;
+ ni->dummy=0;
+ ni->c.x=lon*6371000.0*M_PI/180;
+ ni->c.y=log(tan(M_PI_4+lat*M_PI/360))*6371000.0;
+ node_buffer.size+=sizeof(struct node_item);
+ if (! node_hash) {
+ if (ni->id > nodeid_last) {
+ nodeid_last=ni->id;
+ } else {
+ fprintf(stderr,"INFO: Nodes out of sequence (new %d vs old %d), adding hash\n", ni->id, nodeid_last);
+ node_hash=g_hash_table_new(NULL, NULL);
+ node_buffer_to_hash();
+ }
+ } else
+ if (!g_hash_table_lookup(node_hash, (gpointer)(ni->id)))
+ g_hash_table_insert(node_hash, (gpointer)(ni->id), (gpointer)(ni-(struct node_item *)node_buffer.base));
+ else {
+ node_buffer.size-=sizeof(struct node_item);
+ nodeid=0;
+ }
+
+}
+
+static int
+parse_node(char *p)
+{
+ char id_buffer[BUFFER_SIZE];
+ char lat_buffer[BUFFER_SIZE];
+ char lon_buffer[BUFFER_SIZE];
+ if (!xml_get_attribute(p, "id", id_buffer, BUFFER_SIZE))
+ return 0;
+ if (!xml_get_attribute(p, "lat", lat_buffer, BUFFER_SIZE))
+ return 0;
+ if (!xml_get_attribute(p, "lon", lon_buffer, BUFFER_SIZE))
+ return 0;
+ add_node(atoi(id_buffer), atof(lat_buffer), atof(lon_buffer));
+ return 1;
+}
+
+
+static struct node_item *
+node_item_get(int id)
+{
+ struct node_item *ni=(struct node_item *)(node_buffer.base);
+ int count=node_buffer.size/sizeof(struct node_item);
+ int interval=count/4;
+ int p=count/2;
+ if (node_hash) {
+ int i;
+ i=(int)(g_hash_table_lookup(node_hash, (gpointer)id));
+ return ni+i;
+ }
+ while (ni[p].id != id) {
+#if 0
+ fprintf(stderr,"p=%d count=%d interval=%d id=%d ni[p].id=%d\n", p, count, interval, id, ni[p].id);
+#endif
+ if (ni[p].id < id) {
+ p+=interval;
+ if (interval == 1) {
+ if (p >= count)
+ return NULL;
+ if (ni[p].id > id)
+ return NULL;
+ } else {
+ if (p >= count)
+ p=count-1;
+ }
+ } else {
+ p-=interval;
+ if (interval == 1) {
+ if (p < 0)
+ return NULL;
+ if (ni[p].id < id)
+ return NULL;
+ } else {
+ if (p < 0)
+ p=0;
+ }
+ }
+ if (interval > 1)
+ interval/=2;
+ }
+
+ return &ni[p];
+}
+
+static void
+node_ref_way(int id)
+{
+ struct node_item *ni=node_item_get(id);
+ if (! ni) {
+ fprintf(stderr,"WARNING: node id %d not found\n", id);
+ return;
+ }
+ ni->ref_way++;
+}
+
+
+static void
+add_way(int id)
+{
+ wayid=id;
+ coord_count=0;
+ item.type=type_street_unkn;
+ label_attr.len=0;
+ street_name_attr.len=0;
+ street_name_systematic_attr.len=0;
+ debug_attr.len=0;
+ flags_attr.len=0;
+ sprintf(debug_attr_buffer,"wayid=%d", wayid);
+}
+
+static int
+parse_way(char *p)
+{
+ char id_buffer[BUFFER_SIZE];
+ if (!xml_get_attribute(p, "id", id_buffer, BUFFER_SIZE))
+ return 0;
+ add_way(atoi(id_buffer));
+ return 1;
+}
+
+static int
+parse_relation(char *p)
+{
+ debug_attr_buffer[0]='\0';
+ return 1;
+}
+
+static void
+write_attr(FILE *out, struct attr_bin *attr, void *buffer)
+{
+ if (attr->len) {
+ fwrite(attr, sizeof(*attr), 1, out);
+ fwrite(buffer, (attr->len-1)*4, 1, out);
+ }
+}
+
+static int
+attr_longest_match(struct attr_mapping **mapping, int mapping_count, enum item_type *types, int types_count)
+{
+ int i,j,longest=0,ret=0,sum,val;
+ struct attr_mapping *curr;
+ for (i = 0 ; i < mapping_count ; i++) {
+ sum=0;
+ curr=mapping[i];
+ for (j = 0 ; j < curr->attr_present_idx_count ; j++) {
+ val=attr_present[curr->attr_present_idx[j]];
+ if (val)
+ sum+=val;
+ else {
+ sum=-1;
+ break;
+ }
+ }
+ if (sum > longest) {
+ longest=sum;
+ ret=0;
+ }
+ if (sum > 0 && sum == longest && ret < types_count)
+ types[ret++]=curr->type;
+ }
+ memset(attr_present, 0, sizeof(*attr_present)*attr_present_count);
+ return ret;
+}
+
+static void
+end_way(FILE *out)
+{
+ int alen=0,count;
+ enum item_type types[5];
+
+ if (! out)
+ return;
+ if (dedupe_ways_hash) {
+ if (g_hash_table_lookup(dedupe_ways_hash, (gpointer)wayid))
+ return;
+ g_hash_table_insert(dedupe_ways_hash, (gpointer)wayid, (gpointer)1);
+ }
+ count=attr_longest_match(attr_mapping_way, attr_mapping_way_count, types, sizeof(types)/sizeof(enum item_type));
+ pad_text_attr(&debug_attr, debug_attr_buffer);
+ if (label_attr.len)
+ alen+=label_attr.len+1;
+ if (street_name_systematic_attr.len)
+ alen+=street_name_systematic_attr.len+1;
+ if (debug_attr.len)
+ alen+=debug_attr.len+1;
+ if (flags_attr.len)
+ alen+=flags_attr.len+1;
+ if (count)
+ item.type=types[0];
+ else
+ item.type=type_street_unkn;
+ if (coverage && IS_STREET(item))
+ item.type=type_coverage;
+ item.clen=coord_count*2;
+ item.len=item.clen+2+alen;
+ fwrite(&item, sizeof(item), 1, out);
+ fwrite(coord_buffer, coord_count*sizeof(struct coord), 1, out);
+ if (IS_STREET(item)) {
+ street_name_attr.len=label_attr.len;
+ write_attr(out, &street_name_attr, label_attr_buffer);
+ } else
+ write_attr(out, &label_attr, label_attr_buffer);
+ write_attr(out, &street_name_systematic_attr, street_name_systematic_attr_buffer);
+ write_attr(out, &debug_attr, debug_attr_buffer);
+ write_attr(out, &flags_attr, &flags_attr_value);
+}
+
+static void
+end_node(FILE *out)
+{
+ int alen=0,conflict=0,count;
+ enum item_type types[5];
+ struct country_table *result=NULL, *lookup;
+ if (!out || ! node_is_tagged || ! nodeid)
+ return;
+ count=attr_longest_match(attr_mapping_node, attr_mapping_node_count, types, sizeof(types)/sizeof(enum item_type));
+ pad_text_attr(&debug_attr, debug_attr_buffer);
+ if (label_attr.len)
+ alen+=label_attr.len+1;
+ if (debug_attr.len)
+ alen+=debug_attr.len+1;
+ if (count)
+ item.type=types[0];
+ else
+ item.type=type_point_unkn;
+ item.clen=2;
+ item.len=item.clen+2+alen;
+ fwrite(&item, sizeof(item), 1, out);
+ fwrite(&ni->c, 1*sizeof(struct coord), 1, out);
+ if (IS_TOWN(item)) {
+ town_name_attr.len=label_attr.len;
+ write_attr(out, &town_name_attr, label_attr_buffer);
+ } else
+ write_attr(out, &label_attr, label_attr_buffer);
+ write_attr(out, &debug_attr, debug_attr_buffer);
+#ifdef GENERATE_INDEX
+ if (IS_TOWN(item) && town_name_attr.len) {
+ char *tok,*buf=is_in_buffer;
+ while ((tok=strtok(buf, ","))) {
+ while (*tok==' ')
+ tok++;
+ lookup=g_hash_table_lookup(country_table_hash,tok);
+ if (lookup) {
+ if (result && result->countryid != lookup->countryid) {
+ fprintf(stderr,"conflict for %s %s country %d vs %d\n", label_attr_buffer, debug_attr_buffer, lookup->countryid, result->countryid);
+ conflict=1;
+ } else
+ result=lookup;
+ }
+ buf=NULL;
+ }
+ if (result && !conflict) {
+ if (!result->file) {
+ char *name=g_strdup_printf("country_%d.bin.unsorted", result->countryid);
+ result->file=fopen(name,"w");
+ g_free(name);
+ }
+ if (result->file) {
+ item.clen=2;
+ item.len=item.clen+2+label_attr.len+1;
+ fwrite(&item, sizeof(item), 1, result->file);
+ fwrite(&ni->c, 1*sizeof(struct coord), 1, result->file);
+ write_attr(result->file, &town_name_attr, label_attr_buffer);
+ result->count++;
+ result->size+=(item.clen+3+label_attr.len+1)*4;
+ }
+
+ }
+ }
+#endif
+ processed_nodes_out++;
+}
+
+static int
+sort_countries_compare(const void *p1, const void *p2)
+{
+ struct item_bin *ib1=*((struct item_bin **)p1),*ib2=*((struct item_bin **)p2);
+ struct attr_bin *attr1,*attr2;
+ char *s1,*s2;
+ assert(ib1->clen==2);
+ assert(ib2->clen==2);
+ attr1=(struct attr_bin *)((int *)(ib1+1)+ib1->clen);
+ attr2=(struct attr_bin *)((int *)(ib2+1)+ib1->clen);
+ assert(attr1->type == attr_town_name);
+ assert(attr2->type == attr_town_name);
+ s1=(char *)(attr1+1);
+ s2=(char *)(attr2+1);
+ return strcmp(s1, s2);
+#if 0
+ fprintf(stderr,"sort_countries_compare p1=%p p2=%p %s %s\n",p1,p2,s1,s2);
+#endif
+ return 0;
+}
+
+#ifdef GENERATE_INDEX
+static void
+sort_countries(void)
+{
+ int i,j;
+ struct country_table *co;
+ struct coord *c;
+ struct item_bin *ib;
+ FILE *f;
+ char *p,*buffer,**idx,*name;
+ for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++) {
+ co=&country_table[i];
+ if (co->file) {
+ fclose(co->file);
+ co->file=NULL;
+ }
+ if (co->size) {
+ buffer=malloc(co->size);
+ assert(buffer != NULL);
+ idx=malloc(co->count*sizeof(void *));
+ assert(idx != NULL);
+ name=g_strdup_printf("country_%d.bin.unsorted", co->countryid);
+ f=fopen(name,"r");
+ assert(f != NULL);
+ fread(buffer, co->size, 1, f);
+ fclose(f);
+ unlink(name);
+ g_free(name);
+ p=buffer;
+ for (j = 0 ; j < co->count ; j++) {
+ idx[j]=p;
+ p+=(*((int *)p)+1)*4;
+ }
+ qsort(idx, co->count, sizeof(void *), sort_countries_compare);
+ name=g_strdup_printf("country_%d.bin", co->countryid);
+ f=fopen(name,"w");
+ for (j = 0 ; j < co->count ; j++) {
+ ib=(struct item_bin *)(idx[j]);
+ c=(struct coord *)(ib+1);
+ fwrite(ib, (ib->len+1)*4, 1, f);
+ if (j)
+ bbox_extend(c, &co->r);
+ else
+ co->r.l=*c;
+ co->r.h=*c;
+ }
+ fclose(f);
+ }
+ }
+}
+#endif
+
+static void
+add_nd(char *p, int ref)
+{
+ int len;
+ struct node_item *ni;
+ ni=node_item_get(ref);
+ if (ni) {
+#if 0
+ coord_buffer[coord_count++]=ni->c;
+#else
+ SET_REF(coord_buffer[coord_count], ref);
+ coord_count++;
+#endif
+ ni->ref_way++;
+ } else {
+ len=strlen(p);
+ if (len > 0 && p[len-1]=='\n')
+ p[len-1]='\0';
+ fprintf(stderr,"WARNING: way %d: node %d not found (%s)\n",wayid,ref,p);
+ }
+ if (coord_count > 65536) {
+ fprintf(stderr,"ERROR: Overflow\n");
+ exit(1);
+ }
+}
+
+static int
+parse_nd(char *p)
+{
+ char ref_buffer[BUFFER_SIZE];
+ if (!xml_get_attribute(p, "ref", ref_buffer, BUFFER_SIZE))
+ return 0;
+ add_nd(p, atoi(ref_buffer));
+ return 1;
+}
+
+
+static void
+save_buffer(char *filename, struct buffer *b)
+{
+ FILE *f;
+ f=fopen(filename,"wb+");
+ fwrite(b->base, b->size, 1, f);
+ fclose(f);
+}
+
+static void
+load_buffer(char *filename, struct buffer *b)
+{
+ FILE *f;
+ if (b->base)
+ free(b->base);
+ b->malloced=0;
+ f=fopen(filename,"rb");
+ fseek(f, 0, SEEK_END);
+ b->size=b->malloced=ftell(f);
+ fprintf(stderr,"reading %d bytes from %s\n", b->size, filename);
+ fseek(f, 0, SEEK_SET);
+ b->base=malloc(b->size);
+ assert(b->base != NULL);
+ fread(b->base, b->size, 1, f);
+ fclose(f);
+}
+
+static int
+phase1(FILE *in, FILE *out_ways, FILE *out_nodes)
+{
+ int size=4096;
+ char buffer[size];
+ char *p;
+ sig_alrm(0);
+ while (fgets(buffer, size, in)) {
+ p=strchr(buffer,'<');
+ if (! p) {
+ fprintf(stderr,"WARNING: wrong line %s\n", buffer);
+ continue;
+ }
+ if (!strncmp(p, "<?xml ",6)) {
+ } else if (!strncmp(p, "<osm ",5)) {
+ } else if (!strncmp(p, "<bound ",7)) {
+ } else if (!strncmp(p, "<node ",6)) {
+ if (!parse_node(p))
+ fprintf(stderr,"WARNING: failed to parse %s\n", buffer);
+ in_node=1;
+ processed_nodes++;
+ } else if (!strncmp(p, "<tag ",5)) {
+ if (!parse_tag(p))
+ fprintf(stderr,"WARNING: failed to parse %s\n", buffer);
+ } else if (!strncmp(p, "<way ",5)) {
+ in_way=1;
+ if (!parse_way(p))
+ fprintf(stderr,"WARNING: failed to parse %s\n", buffer);
+ processed_ways++;
+ } else if (!strncmp(p, "<nd ",4)) {
+ if (!parse_nd(p))
+ fprintf(stderr,"WARNING: failed to parse %s\n", buffer);
+ } else if (!strncmp(p, "<relation ",10)) {
+ in_relation=1;
+ if (!parse_relation(p))
+ fprintf(stderr,"WARNING: failed to parse %s\n", buffer);
+ processed_relations++;
+ } else if (!strncmp(p, "<member ",8)) {
+ } else if (!strncmp(p, "</node>",7)) {
+ in_node=0;
+ end_node(out_nodes);
+ } else if (!strncmp(p, "</way>",6)) {
+ in_way=0;
+ end_way(out_ways);
+ } else if (!strncmp(p, "</relation>",11)) {
+ in_relation=0;
+ } else if (!strncmp(p, "</osm>",6)) {
+ } else {
+ fprintf(stderr,"WARNING: unknown tag in %s\n", buffer);
+ }
+ }
+ sig_alrm(0);
+ alarm(0);
+ return 1;
+}
+
+static char buffer[150000];
+
+int bytes_read=0;
+
+static struct item_bin *
+read_item(FILE *in)
+{
+ struct item_bin *ib=(struct item_bin *) buffer;
+ int r,s;
+ r=fread(ib, sizeof(*ib), 1, in);
+ if (r != 1)
+ return NULL;
+ bytes_read+=r;
+ assert((ib->len+1) < sizeof(buffer));
+ s=(ib->len+1)*4-sizeof(*ib);
+ r=fread(ib+1, s, 1, in);
+ if (r != 1)
+ return NULL;
+ bytes_read+=r;
+ return ib;
+}
+
+static void
+bbox_extend(struct coord *c, struct rect *r)
+{
+ if (c->x < r->l.x)
+ r->l.x=c->x;
+ if (c->y < r->l.y)
+ r->l.y=c->y;
+ if (c->x > r->h.x)
+ r->h.x=c->x;
+ if (c->y > r->h.y)
+ r->h.y=c->y;
+}
+
+static void
+bbox(struct coord *c, int count, struct rect *r)
+{
+ if (! count)
+ return;
+ r->l=*c;
+ r->h=*c;
+ while (--count) {
+ c++;
+ bbox_extend(c, r);
+ }
+}
+
+static int
+contains_bbox(int xl, int yl, int xh, int yh, struct rect *r)
+{
+ if (r->h.x < xl || r->h.x > xh) {
+ return 0;
+ }
+ if (r->l.x > xh || r->l.x < xl) {
+ return 0;
+ }
+ if (r->h.y < yl || r->h.y > yh) {
+ return 0;
+ }
+ if (r->l.y > yh || r->l.y < yl) {
+ return 0;
+ }
+ return 1;
+
+}
+struct rect world_bbox = {
+ { -20000000, -20000000},
+ { 20000000, 20000000},
+};
+
+static void
+tile(struct rect *r, char *ret, int max)
+{
+ int x0,x1,x2,x3,x4;
+ int y0,y1,y2,y3,y4;
+ int i;
+ x0=world_bbox.l.x;
+ y0=world_bbox.l.y;
+ x4=world_bbox.h.x;
+ y4=world_bbox.h.y;
+ for (i = 0 ; i < max ; i++) {
+ x2=(x0+x4)/2;
+ y2=(y0+y4)/2;
+ x1=(x0+x2)/2;
+ y1=(y0+y2)/2;
+ x3=(x2+x4)/2;
+ y3=(y2+y4)/2;
+ if ( contains_bbox(x0,y0,x2,y2,r)) {
+ strcat(ret,"d");
+ x4=x2;
+ y4=y2;
+ } else if (contains_bbox(x2,y0,x4,y2,r)) {
+ strcat(ret,"c");
+ x0=x2;
+ y4=y2;
+ } else if (contains_bbox(x0,y2,x2,y4,r)) {
+ strcat(ret,"b");
+ x4=x2;
+ y0=y2;
+ } else if (contains_bbox(x2,y2,x4,y4,r)) {
+ strcat(ret,"a");
+ x0=x2;
+ y0=y2;
+ } else
+ return;
+ }
+}
+
+static void
+tile_bbox(char *tile, struct rect *r)
+{
+ struct coord c;
+ *r=world_bbox;
+ while (*tile) {
+ c.x=(r->l.x+r->h.x)/2;
+ c.y=(r->l.y+r->h.y)/2;
+ switch (*tile) {
+ case 'a':
+ r->l.x=c.x;
+ r->l.y=c.y;
+ break;
+ case 'b':
+ r->h.x=c.x;
+ r->l.y=c.y;
+ break;
+ case 'c':
+ r->l.x=c.x;
+ r->h.y=c.y;
+ break;
+ case 'd':
+ r->h.x=c.x;
+ r->h.y=c.y;
+ break;
+ }
+ tile++;
+ }
+}
+
+GHashTable *tile_hash;
+GHashTable *tile_hash2;
+
+static void
+tile_extend(char *tile, struct item_bin *ib, GList **tiles_list)
+{
+ struct tile_head *th=NULL;
+ if (debug_tile(tile))
+ fprintf(stderr,"Tile:Writing %d bytes to '%s' (%p,%p)\n", (ib->len+1)*4, tile, g_hash_table_lookup(tile_hash, tile), tile_hash2 ? g_hash_table_lookup(tile_hash2, tile) : NULL);
+ if (tile_hash2)
+ th=g_hash_table_lookup(tile_hash2, tile);
+ if (!th)
+ th=g_hash_table_lookup(tile_hash, tile);
+ if (! th) {
+ th=malloc(sizeof(struct tile_head)+ sizeof( char* ) );
+ assert(th != NULL);
+ // strcpy(th->subtiles, tile);
+ th->num_subtiles=1;
+ th->total_size=0;
+ th->total_size_used=0;
+ th->zipnum=0;
+ th->zip_data=NULL;
+ th->name=string_hash_lookup(tile);
+ *th_get_subtile( th, 0 ) = th->name;
+
+ if (tile_hash2)
+ g_hash_table_insert(tile_hash2, string_hash_lookup( th->name ), th);
+ if (tiles_list)
+ *tiles_list=g_list_append(*tiles_list, string_hash_lookup( th->name ) );
+ processed_tiles++;
+ if (debug_tile(tile))
+ fprintf(stderr,"new '%s'\n", tile);
+ }
+ th->total_size+=ib->len*4+4;
+ if (debug_tile(tile))
+ fprintf(stderr,"New total size of %s(%p):%d\n", th->name, th, th->total_size);
+ g_hash_table_insert(tile_hash, string_hash_lookup( th->name ), th);
+}
+
+static int
+tile_data_size(char *tile)
+{
+ struct tile_head *th;
+ th=g_hash_table_lookup(tile_hash, tile);
+ if (! th)
+ return 0;
+ return th->total_size;
+}
+
+static int
+merge_tile(char *base, char *sub)
+{
+ struct tile_head *thb, *ths;
+ thb=g_hash_table_lookup(tile_hash, base);
+ ths=g_hash_table_lookup(tile_hash, sub);
+ if (! ths)
+ return 0;
+ if (debug_tile(base) || debug_tile(sub))
+ fprintf(stderr,"merging '%s'(%p) (%d) with '%s'(%p) (%d)\n", base, thb, thb ? thb->total_size : 0, sub, ths, ths->total_size);
+ if (! thb) {
+ thb=ths;
+ g_hash_table_remove(tile_hash, sub);
+ thb->name=string_hash_lookup(base);
+ g_hash_table_insert(tile_hash, string_hash_lookup( thb->name ), thb);
+
+ } else {
+ thb=realloc(thb, sizeof(struct tile_head)+( ths->num_subtiles+thb->num_subtiles ) * sizeof( char*) );
+ assert(thb != NULL);
+ memcpy( th_get_subtile( thb, thb->num_subtiles ), th_get_subtile( ths, 0 ), ths->num_subtiles * sizeof( char*) );
+ thb->num_subtiles+=ths->num_subtiles;
+ thb->total_size+=ths->total_size;
+ g_hash_table_insert(tile_hash, string_hash_lookup( thb->name ), thb);
+ g_hash_table_remove(tile_hash, sub);
+ g_free(ths);
+ }
+ return 1;
+}
+
+
+static void
+get_tiles_list_func(char *key, struct tile_head *th, GList **list)
+{
+ *list=g_list_prepend(*list, key);
+}
+
+static GList *
+get_tiles_list(void)
+{
+ GList *ret=NULL;
+ g_hash_table_foreach(tile_hash, (GHFunc)get_tiles_list_func, &ret);
+ return ret;
+}
+
+#if 0
+static void
+write_tile(char *key, struct tile_head *th, gpointer dummy)
+{
+ FILE *f;
+ char buffer[1024];
+ fprintf(stderr,"DEBUG: Writing %s\n", key);
+ strcpy(buffer,"tiles/");
+ strcat(buffer,key);
+#if 0
+ strcat(buffer,".bin");
+#endif
+ f=fopen(buffer, "wb+");
+ while (th) {
+ fwrite(th->data, th->size, 1, f);
+ th=th->next;
+ }
+ fclose(f);
+}
+#endif
+
+static void
+write_item(char *tile, struct item_bin *ib)
+{
+ struct tile_head *th;
+ int size;
+
+ th=g_hash_table_lookup(tile_hash2, tile);
+ if (! th)
+ th=g_hash_table_lookup(tile_hash, tile);
+ if (th) {
+ if (th->process != 0 && th->process != 1) {
+ fprintf(stderr,"error with tile '%s' of length %d\n", tile, strlen(tile));
+ abort();
+ }
+ if (! th->process)
+ return;
+ if (debug_tile(tile))
+ fprintf(stderr,"Data:Writing %d bytes to '%s' (%p,%p)\n", (ib->len+1)*4, tile, g_hash_table_lookup(tile_hash, tile), tile_hash2 ? g_hash_table_lookup(tile_hash2, tile) : NULL);
+ size=(ib->len+1)*4;
+ if (th->total_size_used+size > th->total_size) {
+ fprintf(stderr,"Overflow in tile %s (used %d max %d item %d)\n", tile, th->total_size_used, th->total_size, size);
+ exit(1);
+ return;
+ }
+ memcpy(th->zip_data+th->total_size_used, ib, size);
+ th->total_size_used+=size;
+ } else {
+ fprintf(stderr,"no tile hash found for %s\n", tile);
+ exit(1);
+ }
+}
+
+
+static void
+write_item_part(FILE *out, struct item_bin *orig, int first, int last)
+{
+ struct item_bin new;
+ struct coord *c=(struct coord *)(orig+1);
+ char *attr=(char *)(c+orig->clen/2);
+ int attr_len=orig->len-orig->clen-2;
+ processed_ways++;
+ new.type=orig->type;
+ new.clen=(last-first+1)*2;
+ new.len=new.clen+attr_len+2;
+#if 0
+ fprintf(stderr,"first %d last %d type 0x%x len %d clen %d attr_len %d\n", first, last, new.type, new.len, new.clen, attr_len);
+#endif
+ fwrite(&new, sizeof(new), 1, out);
+ fwrite(c+first, new.clen*4, 1, out);
+ fwrite(attr, attr_len*4, 1, out);
+}
+
+static int
+phase2(FILE *in, FILE *out)
+{
+ struct coord *c;
+ int i,ccount,last,ndref;
+ struct item_bin *ib;
+ struct node_item *ni;
+
+ processed_nodes=processed_nodes_out=processed_ways=processed_relations=processed_tiles=0;
+ sig_alrm(0);
+ while ((ib=read_item(in))) {
+#if 0
+ fprintf(stderr,"type 0x%x len %d clen %d\n", ib->type, ib->len, ib->clen);
+#endif
+ ccount=ib->clen/2;
+ c=(struct coord *)(ib+1);
+ last=0;
+ for (i = 0 ; i < ccount ; i++) {
+ if (IS_REF(c[i])) {
+ ndref=REF(c[i]);
+ ni=node_item_get(ndref);
+#if 0
+ fprintf(stderr,"ni=%p\n", ni);
+#endif
+ c[i]=ni->c;
+ if (ni->ref_way > 1 && i != 0 && i != ccount-1 && IS_STREET(*ib)) {
+ write_item_part(out, ib, last, i);
+ last=i;
+ }
+ }
+ }
+ write_item_part(out, ib, last, ccount-1);
+ }
+ sig_alrm(0);
+ alarm(0);
+ return 0;
+}
+
+static void
+phase34_process_file(int phase, FILE *in)
+{
+ struct item_bin *ib;
+ struct rect r;
+ char buffer[1024];
+ int max;
+
+ while ((ib=read_item(in))) {
+ if (ib->type < 0x80000000)
+ processed_nodes++;
+ else
+ processed_ways++;
+ bbox((struct coord *)(ib+1), ib->clen/2, &r);
+ buffer[0]='\0';
+ max=14;
+ if (ib->type == type_street_n_lanes || ib->type == type_highway_city || ib->type == type_highway_land || ib->type == type_ramp)
+ max=8;
+ if (ib->type == type_street_3_city || ib->type == type_street_4_city || ib->type == type_street_3_land || ib->type == type_street_4_land)
+ max=12;
+
+ tile(&r, buffer, max);
+#if 0
+ fprintf(stderr,"%s\n", buffer);
+#endif
+ if (phase == 3)
+ tile_extend(buffer, ib, NULL);
+ else
+ write_item(buffer, ib);
+ }
+}
+
+struct index_item {
+ struct item_bin item;
+ struct rect r;
+ struct attr_bin attr_order_limit;
+ short min;
+ short max;
+ struct attr_bin attr_zipfile_ref;
+ int zipfile_ref;
+};
+
+static void
+index_submap_add(int phase, struct tile_head *th, GList **tiles_list)
+{
+ struct index_item ii;
+ int len=strlen(th->name);
+ char index_tile[len+1];
+
+ ii.min=(len > 4) ? len-4 : 0;
+ ii.max=255;
+ strcpy(index_tile, th->name);
+ if (len > 6)
+ len=6;
+ else
+ len=0;
+ index_tile[len]=0;
+ tile_bbox(th->name, &ii.r);
+
+ ii.item.len=sizeof(ii)/4-1;
+ ii.item.type=type_submap;
+ ii.item.clen=4;
+
+ ii.attr_order_limit.len=2;
+ ii.attr_order_limit.type=attr_order_limit;
+
+ ii.attr_zipfile_ref.len=2;
+ ii.attr_zipfile_ref.type=attr_zipfile_ref;
+ ii.zipfile_ref=th->zipnum;
+
+ if (phase == 3)
+ tile_extend(index_tile, (struct item_bin *)&ii, tiles_list);
+ else
+ write_item(index_tile, (struct item_bin *)&ii);
+#if 0
+ unsigned int *c=(unsigned int *)&ii;
+ int i;
+ for (i = 0 ; i < sizeof(ii)/4 ; i++) {
+ fprintf(stderr,"%08x ", c[i]);
+ }
+ fprintf(stderr,"\n");
+#endif
+}
+
+static int
+add_tile_hash(struct tile_head *th)
+{
+ int idx,len,maxnamelen=0;
+ char **data;
+
+#if 0
+ g_hash_table_insert(tile_hash2, string_hash_lookup( th->name ), th);
+#endif
+ for( idx = 0; idx < th->num_subtiles; idx++ ) {
+
+ data = th_get_subtile( th, idx );
+
+ if (debug_tile(data) || debug_tile(th->name)) {
+ fprintf(stderr,"Parent for '%s' is '%s'\n", *data, th->name);
+ }
+
+ g_hash_table_insert(tile_hash2, *data, th);
+
+ len = strlen( *data );
+
+ if (len > maxnamelen) {
+ maxnamelen=len;
+ }
+ }
+ return maxnamelen;
+}
+
+
+static int
+create_tile_hash(void)
+{
+ struct tile_head *th;
+ int len,maxnamelen=0;
+
+ tile_hash2=g_hash_table_new(g_str_hash, g_str_equal);
+ th=tile_head_root;
+ while (th) {
+ len=add_tile_hash(th);
+ if (len > maxnamelen)
+ maxnamelen=len;
+ th=th->next;
+ }
+ return maxnamelen;
+}
+
+static void
+create_tile_hash_list(GList *list)
+{
+ GList *next;
+ struct tile_head *th;
+
+ tile_hash2=g_hash_table_new(g_str_hash, g_str_equal);
+
+ fprintf(stderr,"list=%p\n", list);
+ next=g_list_first(list);
+ while (next) {
+ th=g_hash_table_lookup(tile_hash, next->data);
+ if (!th) {
+ fprintf(stderr,"No tile found for '%s'\n", (char *)(next->data));
+ }
+ add_tile_hash(th);
+ next=g_list_next(next);
+ }
+}
+
+static void
+destroy_tile_hash(void)
+{
+ g_hash_table_destroy(tile_hash2);
+ tile_hash2=NULL;
+}
+
+static int zipnum;
+
+static void write_countrydir(int phase, int maxnamelen);
+
+static void
+write_tilesdir(int phase, int maxlen, FILE *out)
+{
+ int idx,len;
+ GList *tiles_list,*next;
+ char **data;
+ struct tile_head *th,**last=NULL;
+ zipnum=0;
+
+ tiles_list=get_tiles_list();
+ if (phase == 3)
+ create_tile_hash_list(tiles_list);
+ next=g_list_first(tiles_list);
+ last=&tile_head_root;
+ if (! maxlen) {
+ while (next) {
+ if (strlen(next->data) > maxlen)
+ maxlen=strlen(next->data);
+ next=g_list_next(next);
+ }
+ }
+ len=maxlen;
+ while (len >= 0) {
+#if 0
+ fprintf(stderr,"PROGRESS: collecting tiles with len=%d\n", len);
+#endif
+#ifdef GENERATE_INDEX
+ if (! len)
+ write_countrydir(phase, maxlen);
+#endif
+ next=g_list_first(tiles_list);
+ while (next) {
+ if (strlen(next->data) == len) {
+ th=g_hash_table_lookup(tile_hash, next->data);
+ if (phase == 3) {
+ *last=th;
+ last=&th->next;
+ th->next=NULL;
+ th->zipnum=zipnum;
+ fprintf(out,"%s:%d",(char *)next->data,th->total_size);
+
+ for ( idx = 0; idx< th->num_subtiles; idx++ ){
+ data= th_get_subtile( th, idx );
+ fprintf(out,":%s", *data);
+ }
+
+ fprintf(out,"\n");
+ }
+ if (th->name[0])
+ index_submap_add(phase, th, &tiles_list);
+ zipnum++;
+ processed_tiles++;
+ }
+ next=g_list_next(next);
+ }
+ len--;
+ }
+}
+
+static void
+merge_tiles(void)
+{
+ struct tile_head *th;
+ char basetile[1024];
+ char subtile[1024];
+ GList *tiles_list_sorted,*last;
+ int i,i_min,len,size_all,size[5],size_min,work_done;
+ long long zip_size;
+
+ do {
+ tiles_list_sorted=get_tiles_list();
+ fprintf(stderr,"PROGRESS: sorting %d tiles\n", g_list_length(tiles_list_sorted));
+ tiles_list_sorted=g_list_sort(tiles_list_sorted, (GCompareFunc)strcmp);
+ fprintf(stderr,"PROGRESS: sorting %d tiles done\n", g_list_length(tiles_list_sorted));
+ last=g_list_last(tiles_list_sorted);
+ zip_size=0;
+ while (last) {
+ th=g_hash_table_lookup(tile_hash, last->data);
+ zip_size+=th->total_size;
+ last=g_list_previous(last);
+ }
+ fprintf(stderr,"DEBUG: size=%Ld\n", zip_size);
+ last=g_list_last(tiles_list_sorted);
+ work_done=0;
+ while (last) {
+ processed_tiles++;
+ len=strlen(last->data);
+ if (len >= 1) {
+ strcpy(basetile,last->data);
+ basetile[len-1]='\0';
+ strcpy(subtile,last->data);
+ for (i = 0 ; i < 4 ; i++) {
+ subtile[len-1]='a'+i;
+ size[i]=tile_data_size(subtile);
+ }
+ size[4]=tile_data_size(basetile);
+ size_all=size[0]+size[1]+size[2]+size[3]+size[4];
+ if (size_all < 65536 && size_all > 0 && size_all != size[4]) {
+ for (i = 0 ; i < 4 ; i++) {
+ subtile[len-1]='a'+i;
+ work_done+=merge_tile(basetile, subtile);
+ }
+ } else {
+ for (;;) {
+ size_min=size_all;
+ i_min=-1;
+ for (i = 0 ; i < 4 ; i++) {
+ if (size[i] && size[i] < size_min) {
+ size_min=size[i];
+ i_min=i;
+ }
+ }
+ if (i_min == -1)
+ break;
+ if (size[4]+size_min >= 65536)
+ break;
+ subtile[len-1]='a'+i_min;
+ work_done+=merge_tile(basetile, subtile);
+ size[4]+=size[i_min];
+ size[i_min]=0;
+ }
+ }
+ }
+ last=g_list_previous(last);
+ }
+ g_list_free(tiles_list_sorted);
+ fprintf(stderr,"PROGRESS: merged %d tiles\n", work_done);
+ } while (work_done);
+}
+
+struct country_index_item {
+ struct item_bin item;
+ struct attr_bin attr_country_id;
+ int country_id;
+ struct attr_bin attr_zipfile_ref;
+ int zipfile_ref;
+};
+
+static void
+index_country_add(int phase, int country_id, int zipnum)
+{
+ struct country_index_item ii;
+ char *index_tile="";
+
+ ii.item.len=sizeof(ii)/4-1;
+ ii.item.type=type_countryindex;
+ ii.item.clen=0;
+
+ ii.attr_country_id.len=2;
+ ii.attr_country_id.type=attr_country_id;
+ ii.country_id=country_id;
+
+ ii.attr_zipfile_ref.len=2;
+ ii.attr_zipfile_ref.type=attr_zipfile_ref;
+ ii.zipfile_ref=zipnum;
+
+ if (phase == 3)
+ tile_extend(index_tile, (struct item_bin *)&ii, NULL);
+ else
+ write_item(index_tile, (struct item_bin *)&ii);
+}
+
+#ifdef GENERATE_INDEX
+struct aux_tile {
+ char *name;
+ char *filename;
+ int size;
+};
+
+static int
+add_aux_tile(int phase, char *name, char *filename, int size)
+{
+ struct aux_tile *at;
+ if (phase == 3) {
+ at=g_new0(struct aux_tile, 1);
+ at->name=g_strdup(name);
+ at->filename=g_strdup(filename);
+ at->size=size;
+ aux_tile_list=g_list_append(aux_tile_list, at);
+ }
+ return zipnum++;
+}
+
+static int
+write_aux_tiles(FILE *out, FILE *dir_out, int compression_level, int namelen)
+{
+ GList *l=aux_tile_list;
+ struct aux_tile *at;
+ char *buffer;
+ FILE *f;
+ int count=0;
+
+ while (l) {
+ at=l->data;
+ buffer=malloc(at->size);
+ assert(buffer != NULL);
+ f=fopen(at->filename,"r");
+ assert(f != NULL);
+ fread(buffer, at->size, 1, f);
+ fclose(f);
+ write_zipmember(out, dir_out, at->name, namelen, buffer, at->size, compression_level);
+ count++;
+ l=g_list_next(l);
+ }
+ return count;
+}
+
+static void
+write_countrydir(int phase, int maxnamelen)
+{
+ int i,zipnum;
+ int max=11;
+ char tilename[32];
+ char searchtile[32];
+ char filename[32];
+ struct country_table *co;
+ for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++) {
+ co=&country_table[i];
+ if (co->size) {
+ tilename[0]='\0';
+ tile(&co->r, tilename, max);
+ sprintf(searchtile,"%ss%d", tilename, 0);
+ sprintf(filename,"country_%d.bin", co->countryid);
+ zipnum=add_aux_tile(phase, searchtile, filename, co->size);
+ index_country_add(phase,co->countryid,zipnum);
+ }
+ }
+}
+
+static void
+remove_countryfiles(void)
+{
+ int i;
+ char filename[32];
+ struct country_table *co;
+
+ for (i = 0 ; i < sizeof(country_table)/sizeof(struct country_table) ; i++) {
+ co=&country_table[i];
+ if (co->size) {
+ sprintf(filename,"country_%d.bin", co->countryid);
+ unlink(filename);
+ }
+ }
+}
+#endif
+
+static int
+phase34(int phase, int maxnamelen, FILE *ways_in, FILE *nodes_in, FILE *tilesdir_out)
+{
+
+ processed_nodes=processed_nodes_out=processed_ways=processed_relations=processed_tiles=0;
+ bytes_read=0;
+ sig_alrm(0);
+ if (phase == 3)
+ tile_hash=g_hash_table_new(g_str_hash, g_str_equal);
+ if (ways_in)
+ phase34_process_file(phase, ways_in);
+ if (nodes_in)
+ phase34_process_file(phase, nodes_in);
+ fprintf(stderr,"read %d bytes\n", bytes_read);
+ if (phase == 3)
+ merge_tiles();
+ sig_alrm(0);
+ alarm(0);
+ write_tilesdir(phase, maxnamelen, tilesdir_out);
+
+ return 0;
+
+}
+
+static int
+phase3(FILE *ways_in, FILE *nodes_in, FILE *tilesdir_out)
+{
+ return phase34(3, 0, ways_in, nodes_in, tilesdir_out);
+}
+
+static long long zipoffset;
+static int zipdir_size;
+
+static int
+compress2_int(Byte *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level)
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+
+ err = deflateInit2(&stream, level, Z_DEFLATED, -15, 9, Z_DEFAULT_STRATEGY);
+ if (err != Z_OK) return err;
+
+ err = deflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ deflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *destLen = stream.total_out;
+
+ err = deflateEnd(&stream);
+ return err;
+}
+
+static void
+write_zipmember(FILE *out, FILE *dir_out, char *name, int filelen, char *data, int data_size, int compression_level)
+{
+ struct zip_lfh lfh = {
+ 0x04034b50,
+ 0x0a,
+ 0x0,
+ 0x0,
+ 0xbe2a,
+ 0x5d37,
+ 0x0,
+ 0x0,
+ 0x0,
+ filelen,
+ 0x0,
+ };
+ struct zip_cd cd = {
+ 0x02014b50,
+ 0x17,
+ 0x00,
+ 0x0a,
+ 0x00,
+ 0x0000,
+ 0x0,
+ 0xbe2a,
+ 0x5d37,
+ 0x0,
+ 0x0,
+ 0x0,
+ filelen,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0,
+ zipoffset,
+ };
+ char filename[filelen+1];
+ int error,crc,len,comp_size=data_size;
+ uLongf destlen=data_size+data_size/500+12;
+ char compbuffer[destlen];
+
+ crc=crc32(0, NULL, 0);
+ crc=crc32(crc, (unsigned char *)data, data_size);
+ if (compression_level) {
+ error=compress2_int((Byte *)compbuffer, &destlen, (Bytef *)data, data_size, compression_level);
+ if (error == Z_OK) {
+ if (destlen < data_size) {
+ data=compbuffer;
+ comp_size=destlen;
+ }
+ } else {
+ fprintf(stderr,"compress2 returned %d\n", error);
+ }
+ }
+ lfh.zipcrc=crc;
+ lfh.zipsize=comp_size;
+ lfh.zipuncmp=data_size;
+ lfh.zipmthd=compression_level ? 8:0;
+ cd.zipccrc=crc;
+ cd.zipcsiz=comp_size;
+ cd.zipcunc=data_size;
+ cd.zipcmthd=compression_level ? 8:0;
+ strcpy(filename, name);
+ len=strlen(filename);
+ while (len < filelen) {
+ filename[len++]='_';
+ }
+ filename[filelen]='\0';
+ fwrite(&lfh, sizeof(lfh), 1, out);
+ fwrite(filename, filelen, 1, out);
+ fwrite(data, comp_size, 1, out);
+ zipoffset+=sizeof(lfh)+filelen+comp_size;
+ fwrite(&cd, sizeof(cd), 1, dir_out);
+ fwrite(filename, filelen, 1, dir_out);
+ zipdir_size+=sizeof(cd)+filelen;
+}
+
+static int
+process_slice(FILE *ways_in, FILE *nodes_in, int size, int maxnamelen, FILE *out, FILE *dir_out, int compression_level)
+{
+ struct tile_head *th;
+ char *slice_data,*zip_data;
+ int zipfiles=0;
+
+ slice_data=malloc(size);
+ assert(slice_data != NULL);
+ zip_data=slice_data;
+ th=tile_head_root;
+ while (th) {
+ if (th->process) {
+ th->zip_data=zip_data;
+ zip_data+=th->total_size;
+ }
+ th=th->next;
+ }
+ if (ways_in)
+ fseek(ways_in, 0, SEEK_SET);
+ if (nodes_in)
+ fseek(nodes_in, 0, SEEK_SET);
+ phase34(4, maxnamelen, ways_in, nodes_in, NULL);
+
+ th=tile_head_root;
+ while (th) {
+ if (th->process) {
+#ifdef GENERATE_INDEX
+ if (! strlen(th->name))
+ zipfiles+=write_aux_tiles(out, dir_out, compression_level, maxnamelen);
+#endif
+ if (th->total_size != th->total_size_used) {
+ fprintf(stderr,"Size error '%s': %d vs %d\n", th->name, th->total_size, th->total_size_used);
+ exit(1);
+ } else {
+ if (strlen(th->name))
+ write_zipmember(out, dir_out, th->name, maxnamelen, th->zip_data, th->total_size, compression_level);
+ else {
+ write_zipmember(out, dir_out, "index", sizeof("index")-1, th->zip_data, th->total_size, compression_level);
+ }
+ zipfiles++;
+ }
+ }
+ th=th->next;
+ }
+ free(slice_data);
+
+ return zipfiles;
+}
+
+static void
+cat(FILE *in, FILE *out)
+{
+ size_t size;
+ char buffer[4096];
+ while ((size=fread(buffer, 1, 4096, in)))
+ fwrite(buffer, 1, size, out);
+}
+
+static int
+phase4(FILE *ways_in, FILE *nodes_in, FILE *out, FILE *dir_out, int compression_level)
+{
+ int slice_size=1024*1024*1024;
+ int maxnamelen,size,slices;
+ int zipfiles=0;
+ struct tile_head *th,*th2;
+ struct zip_eoc eoc = {
+ 0x06054b50,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0,
+ 0x0,
+ 0x0,
+ };
+
+ maxnamelen=create_tile_hash();
+
+ th=tile_head_root;
+ size=0;
+ slices=0;
+ fprintf(stderr, "Maximum slice size %d\n", slice_size);
+ while (th) {
+ if (size + th->total_size > slice_size) {
+ fprintf(stderr,"Slice %d is of size %d\n", slices, size);
+ size=0;
+ slices++;
+ }
+ size+=th->total_size;
+ th=th->next;
+ }
+ if (size)
+ fprintf(stderr,"Slice %d is of size %d\n", slices, size);
+ th=tile_head_root;
+ size=0;
+ slices=0;
+ while (th) {
+ th2=tile_head_root;
+ while (th2) {
+ th2->process=0;
+ th2=th2->next;
+ }
+ size=0;
+ while (th && size+th->total_size < slice_size) {
+ size+=th->total_size;
+ th->process=1;
+ th=th->next;
+ }
+ zipfiles+=process_slice(ways_in, nodes_in, size, maxnamelen, out, dir_out, compression_level);
+ slices++;
+ }
+ fseek(dir_out, 0, SEEK_SET);
+ cat(dir_out, out);
+ eoc.zipenum=zipfiles;
+ eoc.zipecenn=zipfiles;
+ eoc.zipecsz=zipdir_size;
+ eoc.zipeofst=zipoffset;
+ fwrite(&eoc, sizeof(eoc), 1, out);
+ sig_alrm(0);
+ alarm(0);
+ return 0;
+}
+
+static void
+usage(FILE *f)
+{
+ fprintf(f,"\n");
+ fprintf(f,"osm2navit - parse osm textfile and converts to NavIt binfile format\n\n");
+ fprintf(f,"Usage :\n");
+ fprintf(f,"bzcat planet.osm.bz2 | osm2navit mymap.bin\n");
+ fprintf(f,"Available switches:\n");
+ fprintf(f,"-h (--help) : this screen\n");
+ fprintf(f,"-N (--nodes-only) : process only nodes\n");
+ fprintf(f,"-W (--ways-only) : process only ways\n");
+ fprintf(f,"-a (--attr-debug-level) : control which data is included in the debug attribute\n");
+ fprintf(f,"-c (--dump-coordinates) : dump coordinates after phase 1\n");
+ fprintf(f,"-e (--end) : end at specified phase\n");
+ fprintf(f,"-k (--keep-tmpfiles) : do not delete tmp files after processing. useful to reuse them\n\n");
+ fprintf(f,"-o (--coverage) : map every street to item overage\n");
+ fprintf(f,"-s (--start) : start at specified phase\n");
+ fprintf(f,"-i (--input-file) : specify the input file name (OSM), overrules default stdin\n");
+ fprintf(f,"-w (--dedupe-ways) : ensure no duplicate ways or nodes. useful when using several input files\n");
+ fprintf(f,"-z (--compression-level) : set the compression level\n");
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ FILE *ways=NULL,*ways_split=NULL,*nodes=NULL,*tilesdir,*zipdir,*res;
+ char *map=g_strdup(attrmap);
+ int c,start=1,end=4,dump_coordinates=0;
+ int keep_tmpfiles=0;
+ int process_nodes=1, process_ways=1;
+ int compression_level=9;
+ char *result;
+ FILE* input_file = stdin;
+
+
+ while (1) {
+#if 0
+ int this_option_optind = optind ? optind : 1;
+#endif
+ int option_index = 0;
+ static struct option long_options[] = {
+ {"attr-debug-level", 1, 0, 'a'},
+ {"compression-level", 1, 0, 'z'},
+ {"coverage", 0, 0, 'o'},
+ {"dedupe-ways", 0, 0, 'w'},
+ {"end", 1, 0, 'e'},
+ {"help", 0, 0, 'h'},
+ {"keep-tmpfiles", 0, 0, 'k'},
+ {"nodes-only", 0, 0, 'N'},
+ {"start", 1, 0, 's'},
+ {"input-file", 1, 0, 'i'},
+ {"ignore-unknown", 0, 0, 'n'},
+ {"ways-only", 0, 0, 'W'},
+ {0, 0, 0, 0}
+ };
+ c = getopt_long (argc, argv, "Nni:Wa:ce:hks:w", long_options, &option_index);
+ if (c == -1)
+ break;
+ switch (c) {
+ case 'N':
+ process_ways=0;
+ break;
+ case 'W':
+ process_nodes=0;
+ break;
+ case 'a':
+ attr_debug_level=atoi(optarg);
+ break;
+ case 'c':
+ dump_coordinates=1;
+ break;
+ case 'e':
+ end=atoi(optarg);
+ break;
+ case 'h':
+ usage(stdout);
+ break;
+ case 'n':
+ fprintf(stderr,"I will IGNORE unknown types\n");
+ ignore_unkown=1;
+ break;
+ case 'k':
+ fprintf(stderr,"I will KEEP tmp files\n");
+ keep_tmpfiles=1;
+ break;
+ case 'o':
+ coverage=1;
+ break;
+ case 's':
+ start=atoi(optarg);
+ break;
+ case 'w':
+ dedupe_ways_hash=g_hash_table_new(NULL, NULL);
+ break;
+ case 'i':
+ input_file = fopen( optarg, "r" );
+ if ( input_file == NULL )
+ {
+ fprintf( stderr, "\nInput file (%s) not found\n", optarg );
+ exit( -1 );
+ }
+ break;
+ case 'z':
+ compression_level=atoi(optarg);
+ break;
+ case '?':
+ usage(stderr);
+ break;
+ default:
+ fprintf(stderr,"c=%d\n", c);
+ }
+
+ }
+ if (optind != argc-1)
+ usage(stderr);
+ result=argv[optind];
+ build_attrmap(map);
+#ifdef GENERATE_INDEX
+ build_countrytable();
+#endif
+
+
+ if (start == 1) {
+ if (process_ways)
+ ways=fopen("ways.tmp","wb+");
+ if (process_nodes)
+ nodes=fopen("nodes.tmp","wb+");
+ phase=1;
+ fprintf(stderr,"PROGRESS: Phase 1: collecting data\n");
+ phase1(input_file,ways,nodes);
+ if (ways)
+ fclose(ways);
+ if (nodes)
+ fclose(nodes);
+#ifdef GENERATE_INDEX
+ fprintf(stderr,"PROGRESS: Phase 1: sorting countries\n");
+ sort_countries();
+#endif
+ }
+ if (end == 1 || dump_coordinates)
+ save_buffer("coords.tmp",&node_buffer);
+ if (end == 1)
+ exit(0);
+ if (start == 2)
+ load_buffer("coords.tmp",&node_buffer);
+ if (start <= 2) {
+ if (process_ways) {
+ ways=fopen("ways.tmp","rb");
+ ways_split=fopen("ways_split.tmp","wb+");
+ phase=2;
+ fprintf(stderr,"PROGRESS: Phase 2: finding intersections\n");
+ phase2(ways,ways_split);
+ fclose(ways_split);
+ fclose(ways);
+ if(!keep_tmpfiles)
+ remove("ways.tmp");
+ } else
+ fprintf(stderr,"PROGRESS: Skipping Phase 2\n");
+ }
+ free(node_buffer.base);
+ node_buffer.base=NULL;
+ node_buffer.malloced=0;
+ node_buffer.size=0;
+ if (end == 2)
+ exit(0);
+ if (start <= 3) {
+ phase=3;
+ fprintf(stderr,"PROGRESS: Phase 3: generating tiles\n");
+ if (process_ways)
+ ways_split=fopen("ways_split.tmp","rb");
+ if (process_nodes)
+ nodes=fopen("nodes.tmp","rb");
+ tilesdir=fopen("tilesdir.tmp","wb+");
+ phase3(ways_split,nodes,tilesdir);
+ fclose(tilesdir);
+ if (nodes)
+ fclose(nodes);
+ if (ways_split)
+ fclose(ways_split);
+ }
+ if (end == 3)
+ exit(0);
+ if (start <= 4) {
+ phase=4;
+ fprintf(stderr,"PROGRESS: Phase 4: assembling map\n");
+ if (process_ways)
+ ways_split=fopen("ways_split.tmp","rb");
+ if (process_nodes)
+ nodes=fopen("nodes.tmp","rb");
+ res=fopen(result,"wb+");
+ zipdir=fopen("zipdir.tmp","wb+");
+ phase4(ways_split,nodes,res,zipdir,compression_level);
+ fclose(zipdir);
+ fclose(res);
+ if (nodes)
+ fclose(nodes);
+ if (ways_split)
+ fclose(ways_split);
+ if(!keep_tmpfiles) {
+ remove("nodes.tmp");
+ remove("ways_split.tmp");
+ remove("tilesdir.tmp");
+ remove("zipdir.tmp");
+#ifdef GENERATE_INDEX
+ remove_countryfiles();
+#endif
+ }
+ }
+ return 0;
+}
diff --git a/navit/param.c b/navit/param.c
new file mode 100644
index 000000000..94157a587
--- /dev/null
+++ b/navit/param.c
@@ -0,0 +1,46 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "param.h"
+
+void
+param_add_string(char *name, char *value, struct param_list **param, int *count)
+{
+ if (*count > 0) {
+ (*param)->name=malloc(strlen(value)+strlen(name)+2);
+ (*param)->value=(*param)->name+strlen(name)+1;
+ strcpy((*param)->name, name);
+ strcpy((*param)->value, value);
+ (*count)--;
+ (*param)++;
+ }
+
+}
+
+void
+param_add_dec(char *name, unsigned long value, struct param_list **param, int *count)
+{
+ char buffer[1024];
+ sprintf(buffer, "%ld", value);
+ param_add_string(name, buffer, param, count);
+}
+
+
+void
+param_add_hex(char *name, unsigned long value, struct param_list **param, int *count)
+{
+ char buffer[1024];
+ sprintf(buffer, "0x%lx", value);
+ param_add_string(name, buffer, param, count);
+}
+
+void
+param_add_hex_sig(char *name, long value, struct param_list **param, int *count)
+{
+ char buffer[1024];
+ if (value < 0)
+ sprintf(buffer, "-0x%lx", -value);
+ else
+ sprintf(buffer, "0x%lx", value);
+ param_add_string(name, buffer, param, count);
+}
diff --git a/navit/param.h b/navit/param.h
new file mode 100644
index 000000000..e450cc725
--- /dev/null
+++ b/navit/param.h
@@ -0,0 +1,15 @@
+#ifndef NAVIT_PARAM_H
+#define NAVIT_PARAM_H
+
+struct param_list {
+ char *name;
+ char *value;
+};
+
+void param_add_string(char *name, char *value, struct param_list **param, int *count);
+void param_add_dec(char *name, unsigned long value, struct param_list **param, int *count);
+void param_add_hex(char *name, unsigned long value, struct param_list **param, int *count);
+void param_add_hex_sig(char *name, long value, struct param_list **param, int *count);
+
+#endif
+
diff --git a/navit/phrase.c b/navit/phrase.c
new file mode 100644
index 000000000..dcdbad2e4
--- /dev/null
+++ b/navit/phrase.c
@@ -0,0 +1,34 @@
+#include <time.h>
+#include <glib.h>
+#include "coord.h"
+#include "item.h"
+#include "route.h"
+#include "speech.h"
+#include "phrase.h"
+
+void
+phrase_route_calc(void *speech)
+{
+#if 0
+ if (! speech)
+ return;
+ speech_say(speech,"Die Route wird berechnet\n");
+#endif
+}
+
+void
+phrase_route_calculated(void *speech, void *route)
+{
+#if 0
+ struct tm *eta;
+#endif
+ if (! speech)
+ return;
+
+#if 0 /* FIXME */
+ eta=route_get_eta(route);
+
+ speech_sayf(speech,"Die Route wurde berechnet, geschätzte Ankunftszeit %d Uhr %d Entfernung %4.0f Kilometer", eta->tm_hour,eta->tm_min,route_get_len(route)/1000);
+#endif
+
+}
diff --git a/navit/phrase.h b/navit/phrase.h
new file mode 100644
index 000000000..5fd1af261
--- /dev/null
+++ b/navit/phrase.h
@@ -0,0 +1,8 @@
+#ifndef NAVIT_PHRASE_H
+#define NAVIT_PHRASE_H
+
+void phrase_route_calc(void *speech);
+void phrase_route_calculated(void *speech, void *route);
+
+#endif
+
diff --git a/navit/plugin.c b/navit/plugin.c
new file mode 100644
index 000000000..7f5230164
--- /dev/null
+++ b/navit/plugin.c
@@ -0,0 +1,200 @@
+#include <glib.h>
+#include <gmodule.h>
+#include "config.h"
+#include "plugin.h"
+#include "file.h"
+#define PLUGIN_C
+#include "plugin.h"
+
+struct plugin {
+ int active;
+ int lazy;
+ char *name;
+ GModule *mod;
+ void (*init)(void);
+};
+
+struct plugins {
+ GHashTable *hash;
+ GList *list;
+};
+
+struct plugin *
+plugin_new(char *plugin)
+{
+ struct plugin *ret;
+ if (! g_module_supported()) {
+ return NULL;
+ }
+ ret=g_new0(struct plugin, 1);
+ ret->name=g_strdup(plugin);
+ return ret;
+
+}
+
+int
+plugin_load(struct plugin *pl)
+{
+ gpointer init;
+
+ GModule *mod;
+
+ if (pl->mod) {
+ g_warning("can't load '%s', already loaded\n", pl->name);
+ return 0;
+ }
+ mod=g_module_open(pl->name, G_MODULE_BIND_LOCAL | (pl->lazy ? G_MODULE_BIND_LAZY : 0));
+ if (! mod) {
+ g_warning("can't load '%s', Error '%s'\n", pl->name, g_module_error());
+ return 0;
+ }
+ if (!g_module_symbol(mod, "plugin_init", &init)) {
+ g_warning("can't load '%s', plugin_init not found\n", pl->name);
+ g_module_close(mod);
+ return 0;
+ } else {
+ pl->mod=mod;
+ pl->init=init;
+ }
+ return 1;
+}
+
+char *
+plugin_get_name(struct plugin *pl)
+{
+ return pl->name;
+}
+
+int
+plugin_get_active(struct plugin *pl)
+{
+ return pl->active;
+}
+
+void
+plugin_set_active(struct plugin *pl, int active)
+{
+ pl->active=active;
+}
+
+void
+plugin_set_lazy(struct plugin *pl, int lazy)
+{
+ pl->lazy=lazy;
+}
+
+void
+plugin_call_init(struct plugin *pl)
+{
+ pl->init();
+}
+
+void
+plugin_unload(struct plugin *pl)
+{
+ g_module_close(pl->mod);
+ pl->mod=NULL;
+}
+
+void
+plugin_destroy(struct plugin *pl)
+{
+ g_free(pl);
+}
+
+struct plugins *
+plugins_new(void)
+{
+ struct plugins *ret=g_new0(struct plugins, 1);
+ ret->hash=g_hash_table_new(g_str_hash, g_str_equal);
+ return ret;
+}
+
+void
+plugins_add_path(struct plugins *pls, const char *path, int active, int lazy)
+{
+ struct file_wordexp *we;
+ int i, count;
+ char **array;
+ char *name;
+ struct plugin *pl;
+
+ we=file_wordexp_new(path);
+ count=file_wordexp_get_count(we);
+ array=file_wordexp_get_array(we);
+ for (i = 0 ; i < count ; i++) {
+ name=array[i];
+ if (! (pl=g_hash_table_lookup(pls->hash, name))) {
+ pl=plugin_new(name);
+ if (! pl) {
+ g_warning("failed to create plugin '%s'\n", name);
+ continue;
+ }
+ g_hash_table_insert(pls->hash, plugin_get_name(pl), pl);
+ pls->list=g_list_append(pls->list, pl);
+ } else {
+ pls->list=g_list_remove(pls->list, pl);
+ pls->list=g_list_append(pls->list, pl);
+ }
+ plugin_set_active(pl, active);
+ plugin_set_lazy(pl, lazy);
+ }
+ file_wordexp_destroy(we);
+}
+
+void
+plugins_init(struct plugins *pls)
+{
+#ifdef USE_PLUGINS
+ struct plugin *pl;
+ GList *l;
+
+ l=pls->list;
+ while (l) {
+ pl=l->data;
+ if (plugin_get_active(pl))
+ if (!plugin_load(pl))
+ plugin_set_active(pl, 0);
+ l=g_list_next(l);
+ }
+ l=pls->list;
+ while (l) {
+ pl=l->data;
+ if (plugin_get_active(pl))
+ plugin_call_init(pl);
+ l=g_list_next(l);
+ }
+#endif
+}
+
+void
+plugins_destroy(struct plugins *pls)
+{
+ GList *l;
+ struct plugin *pl;
+
+ l=pls->list;
+ while (l) {
+ pl=l->data;
+ plugin_unload(pl);
+ plugin_destroy(pl);
+ }
+ g_list_free(pls->list);
+ g_hash_table_destroy(pls->hash);
+ g_free(pls);
+}
+
+void *
+plugin_get_type(enum plugin_type type, const char *name)
+{
+ GList *l;
+ struct name_val *nv;
+ l=plugin_types[type];
+ while (l) {
+ nv=l->data;
+ if (!g_ascii_strcasecmp(nv->name, name))
+ return nv->val;
+ l=g_list_next(l);
+ }
+ return NULL;
+}
diff --git a/navit/plugin.h b/navit/plugin.h
new file mode 100644
index 000000000..bdd0e5d4f
--- /dev/null
+++ b/navit/plugin.h
@@ -0,0 +1,137 @@
+#ifndef PLUGIN_C
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct plugin;
+
+enum plugin_type {
+ plugin_type_graphics,
+ plugin_type_gui,
+ plugin_type_map,
+ plugin_type_osd,
+ plugin_type_speech,
+ plugin_type_vehicle,
+ plugin_type_last,
+};
+#endif
+
+struct container;
+struct popup;
+struct popup_item;
+#undef PLUGIN_FUNC1
+#undef PLUGIN_FUNC3
+#undef PLUGIN_FUNC4
+#undef PLUGIN_TYPE
+#define PLUGIN_PROTO(name,args...) void name(args)
+
+#ifdef PLUGIN_C
+#define PLUGIN_REGISTER(name,args...) \
+void \
+plugin_register_##name(PLUGIN_PROTO((*func),args)) \
+{ \
+ plugin_##name##_func=func; \
+}
+
+#define PLUGIN_CALL(name,args...) \
+{ \
+ if (plugin_##name##_func) \
+ (*plugin_##name##_func)(args); \
+}
+
+#define PLUGIN_FUNC1(name,t1,p1) \
+PLUGIN_PROTO((*plugin_##name##_func),t1 p1); \
+void plugin_call_##name(t1 p1) PLUGIN_CALL(name,p1) \
+PLUGIN_REGISTER(name,t1 p1)
+
+#define PLUGIN_FUNC3(name,t1,p1,t2,p2,t3,p3) \
+PLUGIN_PROTO((*plugin_##name##_func),t1 p1,t2 p2,t3 p3); \
+void plugin_call_##name(t1 p1,t2 p2, t3 p3) PLUGIN_CALL(name,p1,p2,p3) \
+PLUGIN_REGISTER(name,t1 p1,t2 p2,t3 p3)
+
+#define PLUGIN_FUNC4(name,t1,p1,t2,p2,t3,p3,t4,p4) \
+PLUGIN_PROTO((*plugin_##name##_func),t1 p1,t2 p2,t3 p3,t4 p4); \
+void plugin_call_##name(t1 p1,t2 p2, t3 p3, t4 p4) PLUGIN_CALL(name,p1,p2,p3,p4) \
+PLUGIN_REGISTER(name,t1 p1,t2 p2,t3 p3,t4 p4)
+
+struct name_val {
+ char *name;
+ void *val;
+};
+
+GList *plugin_types[plugin_type_last];
+
+#define PLUGIN_TYPE(type,newargs) \
+struct type##_priv; \
+struct type##_methods; \
+void \
+plugin_register_##type##_type(const char *name, struct type##_priv *(*new_) newargs) \
+{ \
+ struct name_val *nv; \
+ nv=g_new(struct name_val, 1); \
+ nv->name=g_strdup(name); \
+ nv->val=new_; \
+ plugin_types[plugin_type_##type]=g_list_append(plugin_types[plugin_type_##type], nv); \
+} \
+ \
+void * \
+plugin_get_##type##_type(const char *name) \
+{ \
+ return plugin_get_type(plugin_type_##type, name); \
+}
+
+#else
+#define PLUGIN_FUNC1(name,t1,p1) \
+void plugin_register_##name(void(*func)(t1 p1)); \
+void plugin_call_##name(t1 p1);
+
+#define PLUGIN_FUNC3(name,t1,p1,t2,p2,t3,p3) \
+void plugin_register_##name(void(*func)(t1 p1,t2 p2,t3 p3)); \
+void plugin_call_##name(t1 p1,t2 p2,t3 p3);
+
+#define PLUGIN_FUNC4(name,t1,p1,t2,p2,t3,p3,t4,p4) \
+void plugin_register_##name(void(*func)(t1 p1,t2 p2,t3 p3,t4 p4)); \
+void plugin_call_##name(t1 p1,t2 p2,t3 p3,t4 p4);
+
+#define PLUGIN_TYPE(type,newargs) \
+struct type##_priv; \
+struct type##_methods; \
+void plugin_register_##type##_type(const char *name, struct type##_priv *(*new_) newargs); \
+void *plugin_get_##type##_type(const char *name);
+
+#endif
+
+#include "plugin_def.h"
+
+#ifndef USE_PLUGINS
+#define plugin_module_cat3(pre,mod,post) pre##mod##post
+#define plugin_module_cat2(pre,mod,post) plugin_module_cat3(pre,mod,post)
+#define plugin_module_cat(pre,post) plugin_module_cat2(pre,MODULE,post)
+#define plugin_init plugin_module_cat(module_,_init)
+#endif
+
+void plugin_init(void);
+
+/* prototypes */
+struct plugin *plugin_new(char *plugin);
+int plugin_load(struct plugin *pl);
+char *plugin_get_name(struct plugin *pl);
+int plugin_get_active(struct plugin *pl);
+void plugin_set_active(struct plugin *pl, int active);
+void plugin_set_lazy(struct plugin *pl, int lazy);
+void plugin_call_init(struct plugin *pl);
+void plugin_unload(struct plugin *pl);
+void plugin_destroy(struct plugin *pl);
+struct plugins *plugins_new(void);
+void plugins_add_path(struct plugins *pls, const char *path, int active, int lazy);
+void plugins_init(struct plugins *pls);
+void plugins_destroy(struct plugins *pls);
+void *plugin_get_type(enum plugin_type type, const char *name);
+/* end of prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+
+
diff --git a/navit/plugin_def.h b/navit/plugin_def.h
new file mode 100644
index 000000000..3d82b5b25
--- /dev/null
+++ b/navit/plugin_def.h
@@ -0,0 +1,11 @@
+struct attr;
+struct navit;
+struct callback_list;
+PLUGIN_FUNC1(draw, struct container *, co)
+PLUGIN_FUNC3(popup, struct container *, map, struct popup *, p, struct popup_item **, list)
+PLUGIN_TYPE(graphics, (struct graphics_methods *meth, struct attr **attrs))
+PLUGIN_TYPE(gui, (struct navit *nav, struct gui_methods *meth, struct attr **attrs))
+PLUGIN_TYPE(map, (struct map_methods *meth, struct attr **attrs))
+PLUGIN_TYPE(osd, (struct navit *nav, struct osd_methods *meth, struct attr **attrs))
+PLUGIN_TYPE(speech, (char *data, struct speech_methods *meth))
+PLUGIN_TYPE(vehicle, (struct vehicle_methods *meth, struct callback_list *cbl, struct attr **attrs))
diff --git a/navit/point.h b/navit/point.h
new file mode 100644
index 000000000..7f75dd134
--- /dev/null
+++ b/navit/point.h
@@ -0,0 +1,13 @@
+#ifndef NAVIT_POINT_H
+#define NAVIT_POINT_H
+
+struct point {
+ int x;
+ int y;
+};
+
+struct point_rect {
+ struct point lu;
+ struct point rl;
+};
+#endif
diff --git a/navit/popup.c b/navit/popup.c
new file mode 100644
index 000000000..a9fe71294
--- /dev/null
+++ b/navit/popup.c
@@ -0,0 +1,259 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <libintl.h>
+#include <glib.h>
+#include "popup.h"
+#include "debug.h"
+#include "navit.h"
+#include "coord.h"
+#include "gui.h"
+#include "menu.h"
+#include "point.h"
+#include "transform.h"
+#include "projection.h"
+#include "map.h"
+#include "graphics.h"
+#include "item.h"
+#include "callback.h"
+#include "route.h"
+
+#define _(STRING) gettext(STRING)
+#if 0
+static void
+popup_set_no_passing(struct popup_item *item, void *param)
+{
+#if 0
+ struct display_list *l=param;
+ struct segment *seg=(struct segment *)(l->data);
+ struct street_str *str=(struct street_str *)(seg->data[0]);
+ char log[256];
+ int segid=str->segid;
+ if (segid < 0)
+ segid=-segid;
+
+ sprintf(log,"Attributes Street 0x%x updated: limit=0x%x(0x%x)", segid, 0x33, str->limit);
+ str->limit=0x33;
+ log_write(log, seg->blk_inf.file, str, sizeof(*str));
+#endif
+}
+
+#endif
+
+static void
+popup_set_destination(struct navit *nav, struct pcoord *pc)
+{
+ struct coord c;
+ struct coord_geo g;
+ char buffer[1024];
+ char buffer_geo[1024];
+ c.x = pc->x;
+ c.y = pc->y;
+ transform_to_geo(transform_get_projection(navit_get_trans(nav)), &c, &g);
+ transform_geo_text(&g, buffer_geo);
+ sprintf(buffer,"Map Point %s", buffer_geo);
+ navit_set_destination(nav, pc, buffer);
+}
+
+static void
+popup_set_bookmark(struct navit *nav, struct pcoord *pc)
+{
+ struct coord c;
+ struct coord_geo g;
+ char buffer[1024];
+ char buffer_geo[1024];
+ c.x = pc->x;
+ c.y = pc->y;
+ transform_to_geo(pc->pro, &c, &g);
+ transform_geo_text(&g, buffer_geo);
+ sprintf(buffer,"Map Point %s", buffer_geo);
+ if (!gui_add_bookmark(navit_get_gui(nav), pc, buffer))
+ navit_add_bookmark(nav, pc, buffer);
+}
+
+
+extern void *vehicle;
+
+static void
+popup_set_position(struct navit *nav, struct pcoord *pc)
+{
+ dbg(0,"%p %p\n", nav, pc);
+ navit_set_position(nav, pc);
+}
+
+#if 0
+static void
+popup_break_crossing(struct display_list *l)
+{
+ struct segment *seg=(struct segment *)(l->data);
+ struct street_str *str=(struct street_str *)(seg->data[0]);
+ char log[256];
+ int segid=str->segid;
+ if (segid < 0)
+ segid=-segid;
+
+ sprintf(log,"Coordinates Street 0x%x updated: limit=0x%x(0x%x)", segid, 0x33, str->limit);
+ str->limit=0x33;
+ log_write(log, seg->blk_inf.file, str, sizeof(*str));
+}
+#endif
+
+
+#define popup_printf(menu, type, fmt...) popup_printf_cb(menu, type, NULL, fmt)
+
+static void *
+popup_printf_cb(void *menu, enum menu_type type, struct callback *cb, const char *fmt, ...)
+{
+ gchar *str;
+ va_list ap;
+ void *ret;
+
+ va_start(ap, fmt);
+ str=g_strdup_vprintf(fmt, ap);
+ dbg(0,"%s\n", str);
+ ret=menu_add(menu, str, type, cb);
+ va_end(ap);
+ g_free(str);
+ return ret;
+}
+
+static void
+popup_show_attr_val(struct map *map, void *menu, struct attr *attr)
+{
+ char *attr_name=attr_to_name(attr->type);
+ char *str;
+
+ str=attr_to_text(attr, map, 1);
+ popup_printf(menu, menu_type_menu, "%s: %s", attr_name, str);
+ g_free(str);
+}
+
+#if 0
+static void
+popup_show_attr(void *menu, struct item *item, enum attr_type attr_type)
+{
+ struct attr attr;
+ memset(&attr, 0, sizeof(attr));
+ attr.type=attr_type;
+ if (item_attr_get(item, attr_type, &attr))
+ popup_show_attr_val(menu, &attr);
+}
+#endif
+
+static void
+popup_show_attrs(struct map *map, void *menu, struct item *item)
+{
+#if 0
+ popup_show_attr(menu, item, attr_debug);
+ popup_show_attr(menu, item, attr_address);
+ popup_show_attr(menu, item, attr_phone);
+ popup_show_attr(menu, item, attr_phone);
+ popup_show_attr(menu, item, attr_entry_fee);
+ popup_show_attr(menu, item, attr_open_hours);
+#else
+ struct attr attr;
+ for (;;) {
+ memset(&attr, 0, sizeof(attr));
+ if (item_attr_get(item, attr_any, &attr))
+ popup_show_attr_val(map, menu, &attr);
+ else
+ break;
+ }
+
+#endif
+}
+
+static void
+popup_show_item(struct navit *nav, void *popup, struct displayitem *di)
+{
+ struct map_rect *mr;
+ void *menu, *menu_map, *menu_item;
+ char *label;
+ struct item *item;
+
+ label=graphics_displayitem_get_label(di);
+ item=graphics_displayitem_get_item(di);
+
+ if (label)
+ menu=popup_printf(popup, menu_type_submenu, "%s '%s'", item_to_name(item->type), label);
+ else
+ menu=popup_printf(popup, menu_type_submenu, "%s", item_to_name(item->type));
+ menu_item=popup_printf(menu, menu_type_submenu, "Item");
+ popup_printf(menu_item, menu_type_menu, "type: 0x%x", item->type);
+ popup_printf(menu_item, menu_type_menu, "id: 0x%x 0x%x", item->id_hi, item->id_lo);
+ if (item->map) {
+ mr=map_rect_new(item->map,NULL);
+ item=map_rect_get_item_byid(mr, item->id_hi, item->id_lo);
+ dbg(1,"item=%p\n", item);
+ if (item) {
+ popup_show_attrs(item->map, menu_item, item);
+ if (item->type < type_line) {
+ struct coord co;
+ struct pcoord *c;
+ if (item_coord_get(item, &co, 1)) {
+ c=g_new(struct pcoord, 1);
+ c->pro = transform_get_projection(navit_get_trans(nav));
+ c->x = co.x;
+ c->y = co.y;
+ popup_printf_cb(menu_item, menu_type_menu, callback_new_2(callback_cast(popup_set_position), nav, c), _("Set as position"));
+ popup_printf_cb(menu_item, menu_type_menu, callback_new_2(callback_cast(popup_set_destination), nav, c), _("Set as destination"));
+ popup_printf_cb(menu_item, menu_type_menu, callback_new_2(callback_cast(popup_set_bookmark), nav, c), _("Add as bookmark"));
+ }
+ }
+ }
+ map_rect_destroy(mr);
+ menu_map=popup_printf(menu, menu_type_submenu, "Map");
+ } else {
+ popup_printf(menu, menu_type_menu, "(No map)");
+ }
+}
+
+static void
+popup_display(struct navit *nav, void *popup, struct point *p)
+{
+ struct displaylist_handle *dlh;
+ struct displaylist *display;
+ struct displayitem *di;
+
+ display=navit_get_displaylist(nav);
+ dlh=graphics_displaylist_open(display);
+ while ((di=graphics_displaylist_next(dlh))) {
+ if (graphics_displayitem_within_dist(di, p, 5)) {
+ popup_show_item(nav, popup, di);
+ }
+ }
+ graphics_displaylist_close(dlh);
+}
+
+static struct pcoord c;
+
+void
+popup(struct navit *nav, int button, struct point *p)
+{
+ void *popup,*men;
+ char buffer[1024];
+ struct coord_geo g;
+ struct coord co;
+
+ popup=gui_popup_new(navit_get_gui(nav));
+ if (! popup)
+ return;
+ transform_reverse(navit_get_trans(nav), p, &co);
+ men=popup_printf(popup, menu_type_submenu, _("Point 0x%x 0x%x"), co.x, co.y);
+ popup_printf(men, menu_type_menu, _("Screen coord : %d %d"), p->x, p->y);
+ transform_to_geo(transform_get_projection(navit_get_trans(nav)), &co, &g);
+ transform_geo_text(&g, buffer);
+ popup_printf(men, menu_type_menu, "%s", buffer);
+ popup_printf(men, menu_type_menu, "%f %f", g.lat, g.lng);
+ dbg(0,"%p %p\n", nav, &c);
+ c.pro = transform_get_projection(navit_get_trans(nav));
+ c.x = co.x;
+ c.y = co.y;
+ popup_printf_cb(men, menu_type_menu, callback_new_2(callback_cast(popup_set_position), nav, &c), _("Set as position"));
+ popup_printf_cb(men, menu_type_menu, callback_new_2(callback_cast(popup_set_destination), nav, &c), _("Set as destination"));
+ popup_printf_cb(men, menu_type_menu, callback_new_2(callback_cast(popup_set_bookmark), nav, &c), _("Add as bookmark"));
+ popup_display(nav, popup, p);
+ menu_popup(popup);
+}
diff --git a/navit/popup.h b/navit/popup.h
new file mode 100644
index 000000000..3738c35db
--- /dev/null
+++ b/navit/popup.h
@@ -0,0 +1,8 @@
+#ifndef NAVIT_POPUP_H
+#define NAVIT_POPUP_H
+
+struct navit;
+struct point;
+void popup(struct navit *nav, int button, struct point *p);
+
+#endif
diff --git a/navit/profile.c b/navit/profile.c
new file mode 100644
index 000000000..677af4bab
--- /dev/null
+++ b/navit/profile.c
@@ -0,0 +1,43 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include "profile.h"
+#include "debug.h"
+
+void
+profile_timer(int level, const char *module, const char *function, const char *fmt, ...)
+{
+ va_list ap;
+ static struct timeval last[3];
+ struct timeval curr;
+ int msec,usec;
+ char buffer[strlen(module)+20];
+
+ va_start(ap, fmt);
+ if (level < 0)
+ level=0;
+ if (level > 2)
+ level=2;
+ if (fmt) {
+ gettimeofday(&curr, NULL);
+ msec=(curr.tv_usec-last[level].tv_usec)/1000+
+ (curr.tv_sec-last[level].tv_sec)*1000;
+
+ sprintf(buffer, "profile:%s", module);
+ debug_vprintf(1, buffer, strlen(buffer), function, strlen(function), 1, fmt, ap);
+ if (msec >= 100)
+ debug_printf(1, buffer, strlen(buffer), function, strlen(function), 0, " %d msec\n", msec);
+ else {
+ usec=(curr.tv_usec-last[level].tv_usec)+(curr.tv_sec-last[level].tv_sec)*1000*1000;
+ debug_printf(1, buffer, strlen(buffer), function, strlen(function), 0, " %d.%d msec\n", usec/1000, usec%1000);
+ }
+ gettimeofday(&last[level], NULL);
+ } else {
+ gettimeofday(&curr, NULL);
+ for (level = 0 ; level < 3 ; level++)
+ last[level]=curr;
+ }
+ va_end(ap);
+}
diff --git a/navit/profile.h b/navit/profile.h
new file mode 100644
index 000000000..4afa16aee
--- /dev/null
+++ b/navit/profile.h
@@ -0,0 +1,17 @@
+#ifndef NAVIT_PROFILE_H
+#define NAVIT_PROFILE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define profile_str2(x) #x
+#define profile_str1(x) profile_str2(x)
+#define profile_module profile_str1(MODULE)
+#define profile(level,fmt...) profile_timer(level,profile_module,__PRETTY_FUNCTION__,fmt)
+void profile_timer(int level, const char *module, const char *function, const char *fmt, ...);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/navit/projection.c b/navit/projection.c
new file mode 100644
index 000000000..614a9c0f3
--- /dev/null
+++ b/navit/projection.c
@@ -0,0 +1,43 @@
+#include <string.h>
+#include <glib.h>
+#include "coord.h"
+#include "debug.h"
+#include "projection.h"
+
+struct projection_name {
+ enum projection projection;
+ char *name;
+};
+
+
+struct projection_name projection_names[]={
+ {projection_none, ""},
+ {projection_mg, "mg"},
+ {projection_garmin, "garmin"},
+};
+
+
+enum projection
+projection_from_name(const char *name)
+{
+ int i;
+
+ for (i=0 ; i < sizeof(projection_names)/sizeof(struct projection_name) ; i++) {
+ if (! strcmp(projection_names[i].name, name))
+ return projection_names[i].projection;
+ }
+ return projection_none;
+}
+
+char *
+projection_to_name(enum projection proj)
+{
+ int i;
+
+ for (i=0 ; i < sizeof(projection_names)/sizeof(struct projection_name) ; i++) {
+ if (projection_names[i].projection == proj)
+ return projection_names[i].name;
+ }
+ return NULL;
+}
+
diff --git a/navit/projection.h b/navit/projection.h
new file mode 100644
index 000000000..bad3a4837
--- /dev/null
+++ b/navit/projection.h
@@ -0,0 +1,16 @@
+#ifndef NAVIT_PROJECTION_H
+#define NAVIT_PROJECTION_H
+
+enum projection {
+ projection_none, projection_mg, projection_garmin
+};
+
+enum map_datum {
+ map_datum_none, map_datum_wgs84, map_datum_dhdn
+};
+
+enum projection projection_from_name(const char *name);
+char * projection_to_name(enum projection proj);
+
+#endif
+
diff --git a/navit/route.c b/navit/route.c
new file mode 100644
index 000000000..f8082b98d
--- /dev/null
+++ b/navit/route.c
@@ -0,0 +1,1780 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if 0
+#include <math.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/time.h>
+#endif
+#include <glib.h>
+#include "config.h"
+#include "debug.h"
+#include "profile.h"
+#include "coord.h"
+#include "projection.h"
+#include "map.h"
+#include "mapset.h"
+#include "item.h"
+#include "route.h"
+#include "track.h"
+#include "point.h"
+#include "graphics.h"
+#include "transform.h"
+#include "plugin.h"
+#include "fib.h"
+
+
+struct map_priv {
+ struct route *route;
+};
+
+int debug_route=0;
+
+struct route_graph_point {
+ struct route_graph_point *next;
+ struct route_graph_point *hash_next;
+ struct route_graph_segment *start;
+ struct route_graph_segment *end;
+ struct route_graph_segment *seg;
+ struct fibheap_el *el;
+ int value;
+ struct coord c;
+};
+
+struct route_graph_segment {
+ struct route_graph_segment *next;
+ struct route_graph_segment *start_next;
+ struct route_graph_segment *end_next;
+ struct route_graph_point *start;
+ struct route_graph_point *end;
+ struct item item;
+ int flags;
+ int len;
+ int offset;
+};
+
+struct route_path_segment {
+ struct route_path_segment *next;
+ struct item item;
+ unsigned int offset;
+#if 0
+ int time;
+#endif
+ int length;
+ int dir;
+ unsigned ncoords;
+ struct coord c[0];
+};
+
+struct route_info {
+ struct coord c;
+ struct coord lp;
+ int pos;
+
+ int dist;
+ int dir;
+
+ struct street_data *street;
+};
+
+struct route_path {
+ struct route_path_segment *path;
+ struct route_path_segment *path_last;
+ /* XXX: path_hash is not necessery now */
+ struct item_hash *path_hash;
+};
+
+#define RF_FASTEST (1<<0)
+#define RF_SHORTEST (1<<1)
+#define RF_AVOIDHW (1<<2)
+#define RF_AVOIDPAID (1<<3)
+#define RF_LOCKONROAD (1<<4)
+#define RF_SHOWGRAPH (1<<5)
+
+struct route {
+ int version;
+ struct mapset *ms;
+ unsigned flags;
+ struct route_info *pos;
+ struct route_info *dst;
+
+ struct route_graph *graph;
+ struct route_path *path2;
+ struct map *map;
+ struct map *graph_map;
+ int speedlist[route_item_last-route_item_first+1];
+};
+
+struct route_graph {
+ struct route_graph_point *route_points;
+ struct route_graph_segment *route_segments;
+#define HASH_SIZE 8192
+ struct route_graph_point *hash[HASH_SIZE];
+};
+
+#define HASHCOORD(c) ((((c)->x +(c)->y) * 2654435761UL) & (HASH_SIZE-1))
+
+static struct route_info * route_find_nearest_street(struct mapset *ms, struct pcoord *c);
+static struct route_graph_point *route_graph_get_point(struct route_graph *this, struct coord *c);
+static void route_graph_update(struct route *this);
+static struct route_path *route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, int *speedlist);
+static void route_process_street_graph(struct route_graph *this, struct item *item);
+static void route_graph_destroy(struct route_graph *this);
+static void route_path_update(struct route *this);
+
+static enum projection route_projection(struct route *route)
+{
+ struct street_data *street;
+ street = route->pos ? route->pos->street : route->dst->street;
+ return map_projection(street->item.map);
+}
+
+static void
+route_path_destroy(struct route_path *this)
+{
+ struct route_path_segment *c,*n;
+ if (! this)
+ return;
+ if (this->path_hash) {
+ item_hash_destroy(this->path_hash);
+ this->path_hash=NULL;
+ }
+ c=this->path;
+ while (c) {
+ n=c->next;
+ g_free(c);
+ c=n;
+ }
+ g_free(this);
+}
+
+struct route *
+route_new(struct attr **attrs)
+{
+ struct route *this=g_new0(struct route, 1);
+ if (!this) {
+ printf("%s:Out of memory\n", __FUNCTION__);
+ return NULL;
+ }
+ return this;
+}
+
+void
+route_set_mapset(struct route *this, struct mapset *ms)
+{
+ this->ms=ms;
+}
+
+struct mapset *
+route_get_mapset(struct route *this)
+{
+ return this->ms;
+}
+
+struct route_info *
+route_get_pos(struct route *this)
+{
+ return this->pos;
+}
+
+struct route_info *
+route_get_dst(struct route *this)
+{
+ return this->dst;
+}
+
+int *
+route_get_speedlist(struct route *this)
+{
+ return this->speedlist;
+}
+
+int
+route_get_path_set(struct route *this)
+{
+ return this->path2 != NULL;
+}
+
+int
+route_set_speed(struct route *this, enum item_type type, int value)
+{
+ if (type < route_item_first || type > route_item_last) {
+ dbg(0,"street type %d out of range [%d,%d]", type, route_item_first, route_item_last);
+ return 0;
+ }
+ this->speedlist[type-route_item_first]=value;
+ return 1;
+}
+
+int
+route_contains(struct route *this, struct item *item)
+{
+ if (! this->path2 || !this->path2->path_hash)
+ return 0;
+ return (int)item_hash_lookup(this->path2->path_hash, item);
+}
+
+static void
+route_path_update(struct route *this)
+{
+ struct route_path *oldpath = NULL;
+ if (! this->pos || ! this->dst) {
+ route_path_destroy(this->path2);
+ this->path2 = NULL;
+ return;
+ }
+ /* the graph is destroyed when setting the destination */
+ if (this->graph && this->pos && this->dst && this->path2) {
+ // we can try to update
+ oldpath = this->path2;
+ this->path2 = NULL;
+ }
+ if (! this->graph || !(this->path2=route_path_new(this->graph, oldpath, this->pos, this->dst, this->speedlist))) {
+ profile(0,NULL);
+ route_graph_update(this);
+ this->path2=route_path_new(this->graph, oldpath, this->pos, this->dst, this->speedlist);
+ profile(1,"route_path_new");
+ profile(0,"end");
+ }
+ if (oldpath) {
+ /* Destroy what's left */
+ route_path_destroy(oldpath);
+ }
+}
+
+void
+route_set_position(struct route *this, struct pcoord *pos)
+{
+ if (this->pos)
+ route_info_free(this->pos);
+ this->pos=NULL;
+ this->pos=route_find_nearest_street(this->ms, pos);
+ dbg(1,"this->pos=%p\n", this->pos);
+ if (! this->pos)
+ return;
+ if (this->dst)
+ route_path_update(this);
+}
+
+void
+route_set_position_from_tracking(struct route *this, struct tracking *tracking)
+{
+ struct coord *c;
+ struct route_info *ret;
+
+ dbg(2,"enter\n");
+ c=tracking_get_pos(tracking);
+ ret=g_new0(struct route_info, 1);
+ if (!ret) {
+ printf("%s:Out of memory\n", __FUNCTION__);
+ return;
+ }
+ if (this->pos)
+ route_info_free(this->pos);
+ this->pos=NULL;
+ ret->c=*c;
+ ret->lp=*c;
+ ret->pos=tracking_get_segment_pos(tracking);
+ ret->dist=0;
+ ret->dir=0;
+ ret->street=street_data_dup(tracking_get_street_data(tracking));
+ dbg(3,"c->x=0x%x, c->y=0x%x pos=%d item=(0x%x,0x%x)\n", c->x, c->y, ret->pos, ret->street->item.id_hi, ret->street->item.id_lo);
+ dbg(3,"street 0=(0x%x,0x%x) %d=(0x%x,0x%x)\n", ret->street->c[0].x, ret->street->c[0].y, ret->street->count-1, ret->street->c[ret->street->count-1].x, ret->street->c[ret->street->count-1].y);
+ this->pos=ret;
+ if (this->dst)
+ route_path_update(this);
+ dbg(2,"ret\n");
+}
+
+/* Used for debuging of route_rect, what routing sees */
+struct map_selection *route_selection;
+
+struct map_selection *
+route_rect(int order, struct coord *c1, struct coord *c2, int rel, int abs)
+{
+ int dx,dy,sx=1,sy=1,d,m;
+ struct map_selection *sel=g_new(struct map_selection, 1);
+ if (!sel) {
+ printf("%s:Out of memory\n", __FUNCTION__);
+ return sel;
+ }
+ sel->order[layer_town]=0;
+ sel->order[layer_poly]=0;
+ sel->order[layer_street]=order;
+ dbg(1,"%p %p\n", c1, c2);
+ dx=c1->x-c2->x;
+ dy=c1->y-c2->y;
+ if (dx < 0) {
+ sx=-1;
+ sel->u.c_rect.lu.x=c1->x;
+ sel->u.c_rect.rl.x=c2->x;
+ } else {
+ sel->u.c_rect.lu.x=c2->x;
+ sel->u.c_rect.rl.x=c1->x;
+ }
+ if (dy < 0) {
+ sy=-1;
+ sel->u.c_rect.lu.y=c2->y;
+ sel->u.c_rect.rl.y=c1->y;
+ } else {
+ sel->u.c_rect.lu.y=c1->y;
+ sel->u.c_rect.rl.y=c2->y;
+ }
+ if (dx*sx > dy*sy)
+ d=dx*sx;
+ else
+ d=dy*sy;
+ m=d*rel/100+abs;
+ sel->u.c_rect.lu.x-=m;
+ sel->u.c_rect.rl.x+=m;
+ sel->u.c_rect.lu.y+=m;
+ sel->u.c_rect.rl.y-=m;
+ sel->next=NULL;
+ return sel;
+}
+
+static struct map_selection *
+route_calc_selection(struct coord *c1, struct coord *c2)
+{
+ struct map_selection *ret,*sel;
+ sel=route_rect(4, c1, c2, 25, 0);
+ ret=sel;
+ sel->next=route_rect(8, c1, c1, 0, 40000);
+ sel=sel->next;
+ sel->next=route_rect(18, c1, c1, 0, 10000);
+ sel=sel->next;
+ sel->next=route_rect(8, c2, c2, 0, 40000);
+ sel=sel->next;
+ sel->next=route_rect(18, c2, c2, 0, 10000);
+ /* route_selection=ret; */
+ return ret;
+}
+
+static void
+route_free_selection(struct map_selection *sel)
+{
+ struct map_selection *next;
+ while (sel) {
+ next=sel->next;
+ g_free(sel);
+ sel=next;
+ }
+}
+
+
+
+void
+route_set_destination(struct route *this, struct pcoord *dst)
+{
+ profile(0,NULL);
+ if (this->dst)
+ route_info_free(this->dst);
+ this->dst=NULL;
+ if (dst)
+ this->dst=route_find_nearest_street(this->ms, dst);
+ profile(1,"find_nearest_street");
+ route_graph_destroy(this->graph);
+ this->graph=NULL;
+ route_path_update(this);
+ profile(0,"end");
+}
+
+static struct route_graph_point *
+route_graph_get_point(struct route_graph *this, struct coord *c)
+{
+ struct route_graph_point *p;
+ int hashval=HASHCOORD(c);
+ p=this->hash[hashval];
+ while (p) {
+ if (p->c.x == c->x && p->c.y == c->y)
+ return p;
+ p=p->hash_next;
+ }
+ return NULL;
+}
+
+
+static struct route_graph_point *
+route_graph_add_point(struct route_graph *this, struct coord *f)
+{
+ int hashval;
+ struct route_graph_point *p;
+
+ p=route_graph_get_point(this,f);
+ if (!p) {
+ hashval=HASHCOORD(f);
+ if (debug_route)
+ printf("p (0x%x,0x%x)\n", f->x, f->y);
+ p=g_new(struct route_graph_point,1);
+ if (!p) {
+ printf("%s:Out of memory\n", __FUNCTION__);
+ return p;
+ }
+ p->hash_next=this->hash[hashval];
+ this->hash[hashval]=p;
+ p->next=this->route_points;
+ p->el=NULL;
+ p->start=NULL;
+ p->end=NULL;
+ p->seg=NULL;
+ p->value=INT_MAX;
+ p->c=*f;
+ this->route_points=p;
+ }
+ return p;
+}
+
+
+static void
+route_graph_free_points(struct route_graph *this)
+{
+ struct route_graph_point *curr,*next;
+ curr=this->route_points;
+ while (curr) {
+ next=curr->next;
+ g_free(curr);
+ curr=next;
+ }
+ this->route_points=NULL;
+ memset(this->hash, 0, sizeof(this->hash));
+}
+
+static void
+route_graph_add_segment(struct route_graph *this, struct route_graph_point *start,
+ struct route_graph_point *end, int len, struct item *item,
+ int flags, int offset)
+{
+ struct route_graph_segment *s;
+ s = g_new0(struct route_graph_segment, 1);
+ if (!s) {
+ printf("%s:Out of memory\n", __FUNCTION__);
+ return;
+ }
+ s->start=start;
+ s->start_next=start->start;
+ start->start=s;
+ s->end=end;
+ s->end_next=end->end;
+ end->end=s;
+ g_assert(len >= 0);
+ s->len=len;
+ s->item=*item;
+ s->flags=flags;
+ s->offset = offset;
+ s->next=this->route_segments;
+ this->route_segments=s;
+ if (debug_route)
+ printf("l (0x%x,0x%x)-(0x%x,0x%x)\n", start->c.x, start->c.y, end->c.x, end->c.y);
+}
+
+static int get_item_seg_coords(struct item *i, struct coord *c, int max,
+ struct route_graph_segment *rgs)
+{
+ struct map_rect *mr;
+ struct item *item;
+ int rc = 0, fs = 0, p = 0;
+ struct coord c1;
+ mr=map_rect_new(i->map, NULL);
+ if (!mr)
+ return 0;
+ item = map_rect_get_item_byid(mr, i->id_hi, i->id_lo);
+ if (item) {
+ do {
+ rc = item_coord_get(item, &c1, 1);
+ if (rc) {
+ if (!fs) {
+ if (c1.x == rgs->start->c.x &&
+ c1.y == rgs->start->c.y)
+ fs = 1;
+ }
+ if (fs) {
+ c[p++] = c1;
+ if (c1.x == rgs->end->c.x &&
+ c1.y == rgs->end->c.y)
+ break;
+ }
+ }
+ } while (rc);
+ }
+ map_rect_destroy(mr);
+ return p;
+}
+
+static struct route_path_segment *
+route_extract_segment_from_path(struct route_path *path, struct item *item,
+ int offset)
+{
+ struct route_path_segment *sp = NULL, *s;
+ s = path->path;
+ while (s) {
+ if (s->offset == offset && item_is_equal(s->item,*item)) {
+ if (sp) {
+ sp->next = s->next;
+ break;
+ } else {
+ path->path = s->next;
+ break;
+ }
+ }
+ sp = s;
+ s = s->next;
+ }
+ if (s)
+ item_hash_remove(path->path_hash, item);
+ return s;
+}
+
+static void
+route_path_add_item(struct route_path *this, struct route_path *oldpath,
+ struct route_graph_segment *rgs, int len, int offset, int dir)
+{
+ struct route_path_segment *segment;
+ int ccnt = 0;
+ struct coord ca[2048];
+
+ if (oldpath) {
+ ccnt = (int)item_hash_lookup(oldpath->path_hash, &rgs->item);
+ if (ccnt) {
+ segment = route_extract_segment_from_path(oldpath,
+ &rgs->item, offset);
+ if (segment)
+ goto linkold;
+ }
+ }
+
+ ccnt = get_item_seg_coords(&rgs->item, ca, 2047, rgs);
+ segment= g_malloc0(sizeof(*segment) + sizeof(struct coord) * ccnt);
+ if (!segment) {
+ printf("%s:Out of memory\n", __FUNCTION__);
+ return;
+ }
+ memcpy(segment->c, ca, ccnt * sizeof(struct coord));
+ segment->ncoords = ccnt;
+ segment->item=rgs->item;
+ segment->offset = offset;
+linkold:
+ segment->length=len;
+ segment->dir=dir;
+ segment->next=NULL;
+ item_hash_insert(this->path_hash, &rgs->item, (void *)offset);
+ if (!this->path)
+ this->path=segment;
+ if (this->path_last)
+ this->path_last->next=segment;
+ this->path_last=segment;
+}
+
+struct route_path_handle {
+ struct route_path_segment *s;
+};
+
+struct route_path_handle *
+route_path_open(struct route *this)
+{
+ struct route_path_handle *ret;
+
+ if (! this->path2 || ! this->path2->path)
+ return NULL;
+
+ ret=g_new(struct route_path_handle, 1);
+ if (!ret) {
+ printf("%s:Out of memory\n", __FUNCTION__);
+ return ret;
+ }
+ ret->s=this->path2->path;
+ return ret;
+}
+
+struct route_path_segment *
+route_path_get_segment(struct route_path_handle *h)
+{
+ struct route_path_segment *ret=h->s;
+
+ if (ret)
+ h->s=ret->next;
+
+ return ret;
+}
+
+static struct coord *
+route_path_segment_get_helper(struct route_path_segment *s, int dir)
+{
+ if (s->dir == dir)
+ return &s->c[0];
+ else
+ return &s->c[s->ncoords-1];
+}
+
+struct coord *
+route_path_segment_get_start(struct route_path_segment *s)
+{
+ return route_path_segment_get_helper(s, 1);
+}
+
+struct coord *
+route_path_segment_get_end(struct route_path_segment *s)
+{
+ return route_path_segment_get_helper(s, -1);
+}
+
+struct item *
+route_path_segment_get_item(struct route_path_segment *s)
+{
+ return &s->item;
+}
+
+void
+route_path_close(struct route_path_handle *h)
+{
+ g_free(h);
+}
+
+static void
+route_graph_free_segments(struct route_graph *this)
+{
+ struct route_graph_segment *curr,*next;
+ curr=this->route_segments;
+ while (curr) {
+ next=curr->next;
+ g_free(curr);
+ curr=next;
+ }
+ this->route_segments=NULL;
+}
+
+static void
+route_graph_destroy(struct route_graph *this)
+{
+ if (this) {
+ route_graph_free_points(this);
+ route_graph_free_segments(this);
+ g_free(this);
+ }
+}
+
+int
+route_time(int *speedlist, struct item *item, int len)
+{
+ if (item->type < route_item_first || item->type > route_item_last) {
+ dbg(0,"street type %d out of range [%d,%d]", item->type, route_item_first, route_item_last);
+ return len*36;
+ }
+ return len*36/speedlist[item->type-route_item_first];
+}
+
+
+static int
+route_value(int *speedlist, struct item *item, int len)
+{
+ int ret;
+ if (len < 0) {
+ printf("len=%d\n", len);
+ }
+ g_assert(len >= 0);
+ ret=route_time(speedlist, item, len);
+ dbg(1, "route_value(0x%x, %d)=%d\n", item->type, len, ret);
+ return ret;
+}
+
+static void
+route_process_street_graph(struct route_graph *this, struct item *item)
+{
+#ifdef AVOID_FLOAT
+ int len=0;
+#else
+ double len=0;
+#endif
+ struct route_graph_point *s_pnt,*e_pnt;
+ struct coord c,l;
+ struct attr attr;
+ int flags = 0;
+ int segmented = 0;
+ int offset = 1;
+
+ if (item_coord_get(item, &l, 1)) {
+ if (item_attr_get(item, attr_flags, &attr)) {
+ flags = attr.u.num;
+ if (flags & AF_SEGMENTED)
+ segmented = 1;
+ }
+ s_pnt=route_graph_add_point(this,&l);
+ if (!segmented) {
+ while (item_coord_get(item, &c, 1)) {
+ len+=transform_distance(map_projection(item->map), &l, &c);
+ l=c;
+ }
+ e_pnt=route_graph_add_point(this,&l);
+ g_assert(len >= 0);
+ route_graph_add_segment(this, s_pnt, e_pnt, len, item, flags, offset);
+ } else {
+ int isseg,rc;
+ int sc = 0;
+ do {
+ isseg = item_coord_is_segment(item);
+ rc = item_coord_get(item, &c, 1);
+ if (rc) {
+ len+=transform_distance(map_projection(item->map), &l, &c);
+ l=c;
+ if (isseg) {
+ e_pnt=route_graph_add_point(this,&l);
+ route_graph_add_segment(this, s_pnt, e_pnt, len, item, flags, offset);
+ offset++;
+ s_pnt=route_graph_add_point(this,&l);
+ len = 0;
+ }
+ }
+ } while(rc);
+ e_pnt=route_graph_add_point(this,&l);
+ g_assert(len >= 0);
+ sc++;
+ route_graph_add_segment(this, s_pnt, e_pnt, len, item, flags, offset);
+ }
+ }
+}
+
+static int
+compare(void *v1, void *v2)
+{
+ struct route_graph_point *p1=v1;
+ struct route_graph_point *p2=v2;
+#if 0
+ if (debug_route)
+ printf("compare %d (%p) vs %d (%p)\n", p1->value,p1,p2->value,p2);
+#endif
+ return p1->value-p2->value;
+}
+
+int
+route_info_length(struct route_info *pos, struct route_info *dst, int dir)
+{
+ struct route_info_handle *h;
+ struct coord *c,*l;
+ int ret=0;
+ struct street_data *street;
+
+ dbg(2,"enter pos=%p dst=%p dir=%d\n", pos, dst, dir);
+ h=route_info_open(pos, dst, dir);
+ if (! h) {
+ dbg(2,"ret=-1\n");
+ return -1;
+ }
+ street = pos ? pos->street : dst->street;
+ l=route_info_get(h);
+ while ((c=route_info_get(h))) {
+ dbg(3,"c=%p\n", c);
+ ret+=transform_distance(map_projection(street->item.map), c, l);
+ l=c;
+ }
+ dbg(2,"ret=%d\n", ret);
+ return ret;
+}
+
+static void
+route_graph_flood(struct route_graph *this, struct route_info *dst, int *speedlist)
+{
+ struct route_graph_point *p_min,*end=NULL;
+ struct route_graph_segment *s;
+ int min,new,old,val;
+ struct fibheap *heap;
+ struct street_data *sd=dst->street;
+
+ heap = fh_makeheap();
+ fh_setcmp(heap, compare);
+
+ if (! (sd->flags & AF_ONEWAYREV)) {
+ end=route_graph_get_point(this, &sd->c[0]);
+ g_assert(end != 0);
+ end->value=route_value(speedlist, &sd->item, route_info_length(NULL, dst, -1));
+ end->el=fh_insert(heap, end);
+ }
+
+ if (! (sd->flags & AF_ONEWAY)) {
+ end=route_graph_get_point(this, &sd->c[sd->count-1]);
+ g_assert(end != 0);
+ end->value=route_value(speedlist, &sd->item, route_info_length(NULL, dst, 1));
+ end->el=fh_insert(heap, end);
+ }
+
+ dbg(1,"0x%x,0x%x\n", end->c.x, end->c.y);
+ for (;;) {
+ p_min=fh_extractmin(heap);
+ if (! p_min)
+ break;
+ min=p_min->value;
+ if (debug_route)
+ printf("extract p=%p free el=%p min=%d, 0x%x, 0x%x\n", p_min, p_min->el, min, p_min->c.x, p_min->c.y);
+ p_min->el=NULL;
+ s=p_min->start;
+ while (s) {
+ val=route_value(speedlist, &s->item, s->len);
+#if 0
+ val+=val*2*street_route_contained(s->str->segid);
+#endif
+ new=min+val;
+ if (debug_route)
+ printf("begin %d len %d vs %d (0x%x,0x%x)\n",new,val,s->end->value, s->end->c.x, s->end->c.y);
+ if (new < s->end->value && !(s->flags & AF_ONEWAY)) {
+ s->end->value=new;
+ s->end->seg=s;
+ if (! s->end->el) {
+ if (debug_route)
+ printf("insert_end p=%p el=%p val=%d ", s->end, s->end->el, s->end->value);
+ s->end->el=fh_insert(heap, s->end);
+ if (debug_route)
+ printf("el new=%p\n", s->end->el);
+ }
+ else {
+ if (debug_route)
+ printf("replace_end p=%p el=%p val=%d\n", s->end, s->end->el, s->end->value);
+ fh_replacedata(heap, s->end->el, s->end);
+ }
+ }
+ if (debug_route)
+ printf("\n");
+ s=s->start_next;
+ }
+ s=p_min->end;
+ while (s) {
+ val=route_value(speedlist, &s->item, s->len);
+ new=min+val;
+ if (debug_route)
+ printf("end %d len %d vs %d (0x%x,0x%x)\n",new,val,s->start->value,s->start->c.x, s->start->c.y);
+ if (new < s->start->value && !(s->flags & AF_ONEWAYREV)) {
+ old=s->start->value;
+ s->start->value=new;
+ s->start->seg=s;
+ if (! s->start->el) {
+ if (debug_route)
+ printf("insert_start p=%p el=%p val=%d ", s->start, s->start->el, s->start->value);
+ s->start->el=fh_insert(heap, s->start);
+ if (debug_route)
+ printf("el new=%p\n", s->start->el);
+ }
+ else {
+ if (debug_route)
+ printf("replace_start p=%p el=%p val=%d\n", s->start, s->start->el, s->start->value);
+ fh_replacedata(heap, s->start->el, s->start);
+ }
+ }
+ if (debug_route)
+ printf("\n");
+ s=s->end_next;
+ }
+ }
+ fh_deleteheap(heap);
+}
+
+static struct route_path *
+route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, int *speedlist)
+{
+ struct route_graph_point *start1=NULL,*start2=NULL,*start;
+ struct route_graph_segment *s=NULL;
+ int len=0,segs=0;
+ int ilen,seg_len;
+#if 0
+ int time=0,hr,min,sec
+#endif
+ unsigned int val1=0xffffffff,val2=0xffffffff;
+ struct street_data *sd=pos->street;
+ struct route_path *ret;
+
+ if (! (sd->flags & AF_ONEWAY)) {
+ start1=route_graph_get_point(this, &sd->c[0]);
+ if (! start1)
+ return NULL;
+ val1=start1->value+route_value(speedlist, &sd->item, route_info_length(pos, NULL, -1));
+ dbg(1,"start1: %d(route)+%d=%d\n", start1->value, val1-start1->value, val1);
+ }
+ if (! (sd->flags & AF_ONEWAYREV)) {
+ start2=route_graph_get_point(this, &sd->c[sd->count-1]);
+ if (! start2)
+ return NULL;
+ val2=start2->value+route_value(speedlist, &sd->item, route_info_length(pos, NULL, 1));
+ dbg(1,"start2: %d(route)+%d=%d\n", start2->value, val2-start2->value, val2);
+ }
+ dbg(1,"val1=%d val2=%d\n", val1, val2);
+ if (val1 == val2) {
+ val1=start1->start->start->value;
+ val2=start2->end->end->value;
+ }
+ if (start1 && (val1 < val2)) {
+ start=start1;
+ pos->dir=-1;
+ } else {
+ if (start2) {
+ start=start2;
+ pos->dir=1;
+ } else {
+ printf("no route found, pos blocked\n");
+ return NULL;
+ }
+ }
+ ret=g_new0(struct route_path, 1);
+ if (!ret) {
+ printf("%s:Out of memory\n", __FUNCTION__);
+ return ret;
+ }
+ ret->path_hash=item_hash_new();
+ dbg(1,"dir=%d\n", pos->dir);
+ while ((s=start->seg)) {
+ segs++;
+#if 0
+ printf("start->value=%d 0x%x,0x%x\n", start->value, start->c.x, start->c.y);
+#endif
+ seg_len=s->len;
+ len+=seg_len;
+ if (s->start == start) {
+ route_path_add_item(ret, oldpath, s, seg_len, s->offset, 1);
+ start=s->end;
+ } else {
+ route_path_add_item(ret, oldpath, s, seg_len, s->offset, -1);
+ start=s->start;
+ }
+ }
+ sd=dst->street;
+ dbg(1,"start->value=%d 0x%x,0x%x\n", start->value, start->c.x, start->c.y);
+ dbg(1,"dst sd->flags=%d sd->c[0]=0x%x,0x%x sd->c[sd->count-1]=0x%x,0x%x\n", sd->flags, sd->c[0].x,sd->c[0].y, sd->c[sd->count-1].x, sd->c[sd->count-1].y);
+ if (start->c.x == sd->c[0].x && start->c.y == sd->c[0].y)
+ dst->dir=-1;
+ else if (start->c.x == sd->c[sd->count-1].x && start->c.y == sd->c[sd->count-1].y)
+ dst->dir=1;
+ else {
+ printf("no route found\n");
+ route_path_destroy(ret);
+ return NULL;
+ }
+ ilen=route_info_length(pos, NULL, 0);
+ len+=ilen;
+
+ ilen=route_info_length(NULL, dst, 0);
+ len+=ilen;
+
+ dbg(1, "%d segments\n", segs);
+ return ret;
+}
+
+static struct route_graph *
+route_graph_build(struct mapset *ms, struct coord *c1, struct coord *c2)
+{
+ struct route_graph *ret=g_new0(struct route_graph, 1);
+ struct map_selection *sel;
+ struct mapset_handle *h;
+ struct map_rect *mr;
+ struct map *m;
+ struct item *item;
+
+ if (!ret) {
+ printf("%s:Out of memory\n", __FUNCTION__);
+ return ret;
+ }
+ sel=route_calc_selection(c1, c2);
+ h=mapset_open(ms);
+ while ((m=mapset_next(h,1))) {
+ mr=map_rect_new(m, sel);
+ if (! mr)
+ continue;
+ while ((item=map_rect_get_item(mr))) {
+ if (item->type >= type_street_0 && item->type <= type_ferry) {
+ route_process_street_graph(ret, item);
+ }
+ }
+ map_rect_destroy(mr);
+ }
+ mapset_close(h);
+ route_free_selection(sel);
+
+ return ret;
+}
+
+static void
+route_graph_update(struct route *this)
+{
+ route_graph_destroy(this->graph);
+ profile(1,"graph_free");
+ this->graph=route_graph_build(this->ms, &this->pos->c, &this->dst->c);
+ profile(1,"route_graph_build");
+ route_graph_flood(this->graph, this->dst, this->speedlist);
+ profile(1,"route_graph_flood");
+ this->version++;
+}
+
+struct street_data *
+street_get_data (struct item *item)
+{
+ int maxcount=2000;
+ struct coord c[maxcount];
+ int count=0;
+ struct street_data *ret;
+ struct attr attr;
+
+ while (count < maxcount) {
+ if (!item_coord_get(item, &c[count], 1))
+ break;
+ count++;
+ }
+ if (count >= maxcount) {
+ dbg(0, "count=%d maxcount=%d id_hi=0x%x id_lo=0x%x\n", count, maxcount, item->id_hi, item->id_lo);
+ if (item_attr_get(item, attr_debug, &attr))
+ dbg(0,"debug='%s'\n", attr.u.str);
+ }
+ g_assert(count < maxcount);
+ ret=g_malloc(sizeof(struct street_data)+count*sizeof(struct coord));
+ ret->item=*item;
+ ret->count=count;
+ if (item_attr_get(item, attr_flags, &attr))
+ ret->flags=attr.u.num;
+ else
+ ret->flags=0;
+ memcpy(ret->c, c, count*sizeof(struct coord));
+
+ return ret;
+}
+
+struct street_data *
+street_data_dup(struct street_data *orig)
+{
+ struct street_data *ret;
+ int size=sizeof(struct street_data)+orig->count*sizeof(struct coord);
+
+ ret=g_malloc(size);
+ memcpy(ret, orig, size);
+
+ return ret;
+}
+
+void
+street_data_free(struct street_data *sd)
+{
+ g_free(sd);
+}
+
+static struct route_info *
+route_find_nearest_street(struct mapset *ms, struct pcoord *pc)
+{
+ struct route_info *ret=NULL;
+ int max_dist=1000;
+ struct map_selection *sel;
+ int dist,pos;
+ struct mapset_handle *h;
+ struct map *m;
+ struct map_rect *mr;
+ struct item *item;
+ struct coord lp;
+ struct street_data *sd;
+ struct coord c;
+ struct coord_geo g;
+
+ c.x = pc->x;
+ c.y = pc->y;
+ /*
+ * This is not correct for two reasons:
+ * - You may need to go back first
+ * - Currently we allow mixing of mapsets
+ */
+ sel = route_rect(18, &c, &c, 0, max_dist);
+ h=mapset_open(ms);
+ while ((m=mapset_next(h,1))) {
+ c.x = pc->x;
+ c.y = pc->y;
+ if (map_projection(m) != pc->pro) {
+ transform_to_geo(pc->pro, &c, &g);
+ transform_from_geo(map_projection(m), &g, &c);
+ }
+ mr=map_rect_new(m, sel);
+ if (! mr)
+ continue;
+ while ((item=map_rect_get_item(mr))) {
+ if (item->type >= type_street_0 && item->type <= type_ferry) {
+ sd=street_get_data(item);
+ dist=transform_distance_polyline_sq(sd->c, sd->count, &c, &lp, &pos);
+ if (!ret || dist < ret->dist) {
+ if (ret) {
+ street_data_free(ret->street);
+ g_free(ret);
+ }
+ ret=g_new(struct route_info, 1);
+ if (!ret) {
+ printf("%s:Out of memory\n", __FUNCTION__);
+ return ret;
+ }
+ ret->c=c;
+ ret->lp=lp;
+ ret->pos=pos;
+ ret->dist=dist;
+ ret->dir=0;
+ ret->street=sd;
+ dbg(1,"dist=%d id 0x%x 0x%x pos=%d\n", dist, item->id_hi, item->id_lo, pos);
+ } else
+ street_data_free(sd);
+ }
+ }
+ map_rect_destroy(mr);
+ }
+ mapset_close(h);
+ map_selection_destroy(sel);
+
+ return ret;
+}
+
+void
+route_info_free(struct route_info *inf)
+{
+ if (inf->street)
+ street_data_free(inf->street);
+ g_free(inf);
+}
+
+
+#include "point.h"
+
+struct street_data *
+route_info_street(struct route_info *rinf)
+{
+ return rinf->street;
+}
+
+struct coord *
+route_info_point(struct route_info *rinf, int point)
+{
+ struct street_data *sd=rinf->street;
+ int dir;
+
+ switch(point) {
+ case -1:
+ case 2:
+ dir=(point == 2) ? rinf->dir : -rinf->dir;
+ if (dir > 0)
+ return &sd->c[sd->count-1];
+ else
+ return &sd->c[0];
+ case 0:
+ return &rinf->c;
+ case 1:
+ return &rinf->lp;
+ }
+ return NULL;
+
+}
+
+struct route_info_handle {
+ struct route_info *start;
+ struct route_info *curr;
+ struct route_info *end;
+ struct coord *last;
+ int count;
+ int iter;
+ int pos;
+ int endpos;
+ int dir;
+};
+
+struct route_info_handle *
+route_info_open(struct route_info *start, struct route_info *end, int dir)
+{
+ struct route_info_handle *ret=g_new0(struct route_info_handle, 1);
+ struct route_info *curr;
+ dbg(2,"enter start=%p end=%p dir=%d\n", start, end, dir);
+ if (!ret) {
+ printf("%s:Out of memory\n", __FUNCTION__);
+ return ret;
+ }
+ ret->start=start;
+ ret->end=end;
+ if (start)
+ curr=start;
+ else
+ curr=end;
+ ret->endpos=-2;
+ if (start && end) {
+ if (start->street->item.map != end->street->item.map || start->street->item.id_hi != end->street->item.id_hi || start->street->item.id_lo != end->street->item.id_lo) {
+ dbg(1,"return NULL\n");
+ return NULL;
+ }
+ printf("trivial start=%d end=%d start dir %d end dir %d\n", start->pos, end->pos, start->dir, end->dir);
+ if (start->pos == end->pos) {
+ printf("fixme\n");
+ start->dir=0;
+ end->dir=0;
+ }
+ if (start->pos > end->pos) {
+ printf("fixme\n");
+ start->dir=-1;
+ end->dir=1;
+ }
+ if (start->pos < end->pos) {
+ printf("fixme\n");
+ start->dir=1;
+ end->dir=-1;
+ }
+ printf("trivial now start=%d end=%d start dir %d end dir %d\n", start->pos, end->pos, start->dir, end->dir);
+ ret->endpos=end->pos;
+ }
+
+ if (!dir)
+ dir=curr->dir;
+ dbg(2,"dir=%d\n", dir);
+ ret->dir=dir;
+ ret->curr=curr;
+ ret->pos=curr->pos;
+ if (dir > 0) {
+ ret->pos++;
+ ret->endpos++;
+ }
+ dbg(2,"ret=%p\n",ret);
+ return ret;
+}
+
+struct coord *
+route_info_get(struct route_info_handle *h)
+{
+ struct coord *new;
+ for (;;) {
+ new=NULL;
+ dbg(1,"iter=%d\n", h->iter);
+ switch(h->iter) {
+ case 0:
+ if (h->start) {
+ new=&h->start->c;
+ h->iter++;
+ break;
+ } else {
+ h->iter=2;
+ continue;
+ }
+ case 1:
+ new=&h->start->lp;
+ h->iter++;
+ break;
+ case 2:
+ dbg(1,"h->pos=%d\n", h->pos);
+ if (h->dir && h->pos >= 0 && h->pos < h->curr->street->count && (h->end == NULL || h->endpos!=h->pos)) {
+ new=&h->curr->street->c[h->pos];
+ h->pos+=h->dir;
+ } else {
+ h->iter++;
+ continue;
+ }
+ break;
+ case 3:
+ if (h->end) {
+ new=&h->end->lp;
+ h->iter++;
+ break;
+ }
+ break;
+ case 4:
+ new=&h->end->c;
+ h->iter++;
+ break;
+
+ }
+ if (new) {
+ dbg(1,"new=%p (0x%x,0x%x) last=%p\n", new, new->x, new->y, h->last);
+ if (h->last && new->x == h->last->x && new->y == h->last->y)
+ continue;
+ h->last=new;
+ return new;
+ }
+ return NULL;
+ }
+}
+
+void
+route_info_close(struct route_info_handle *h)
+{
+ g_free(h);
+}
+
+
+#if 0
+struct route_crossings *
+route_crossings_get(struct route *this, struct coord *c)
+{
+ struct route_point *pnt;
+ struct route_segment *seg;
+ int crossings=0;
+ struct route_crossings *ret;
+
+ pnt=route_graph_get_point(this, c);
+ seg=pnt->start;
+ while (seg) {
+ printf("start: 0x%x 0x%x\n", seg->item.id_hi, seg->item.id_lo);
+ crossings++;
+ seg=seg->start_next;
+ }
+ seg=pnt->end;
+ while (seg) {
+ printf("end: 0x%x 0x%x\n", seg->item.id_hi, seg->item.id_lo);
+ crossings++;
+ seg=seg->end_next;
+ }
+ ret=g_malloc(sizeof(struct route_crossings)+crossings*sizeof(struct route_crossing));
+ ret->count=crossings;
+ return ret;
+}
+#endif
+
+
+struct map_rect_priv {
+ struct route_info_handle *ri;
+ enum attr_type attr_next;
+ int pos_next;
+ int pos;
+ struct map_priv *mpriv;
+ struct item item;
+ struct item *sitem;
+ int length;
+ unsigned int last_coord;
+ struct route_path_segment *seg;
+ struct route_graph_point *point;
+ struct route_graph_segment *rseg;
+ char *str;
+};
+
+static void
+rm_coord_rewind(void *priv_data)
+{
+ struct map_rect_priv *mr = priv_data;
+ mr->last_coord = 0;
+}
+
+static void
+rm_attr_rewind(void *priv_data)
+{
+ struct map_rect_priv *mr = priv_data;
+ mr->attr_next = attr_street_item;
+}
+
+static int
+rm_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+ struct map_rect_priv *mr = priv_data;
+ struct route_path_segment *seg=mr->seg;
+ struct route *route=mr->mpriv->route;
+ attr->type=attr_type;
+ switch (attr_type) {
+ case attr_any:
+ while (mr->attr_next != attr_none) {
+ if (rm_attr_get(priv_data, mr->attr_next, attr))
+ return 1;
+ }
+ return 0;
+ case attr_street_item:
+ if (seg)
+ attr->u.item=&seg->item;
+ else
+ attr->u.item=mr->sitem;
+ mr->attr_next=attr_length;
+ return 1;
+ case attr_length:
+ if (seg)
+ attr->u.num=seg->length;
+ else
+ attr->u.num=mr->length;
+ mr->attr_next=attr_time;
+ return 1;
+ case attr_time:
+ if (seg)
+ attr->u.num=route_time(route->speedlist, &seg->item, seg->length);
+ else
+ attr->u.num=route_time(route->speedlist, mr->sitem, mr->length);
+ mr->attr_next=attr_none;
+ return 1;
+ default:
+ attr->type=attr_none;
+ return 0;
+ }
+ return 0;
+}
+
+static int
+rm_coord_get(void *priv_data, struct coord *c, int count)
+{
+ struct map_rect_priv *mr = priv_data;
+ struct route_path_segment *seg = mr->seg;
+ struct coord *c1;
+ int rc = 0,i;
+ dbg(1,"pos=%d seg=%p\n", mr->pos, seg);
+ switch (mr->pos) {
+ case -1:
+ for (i=0; i < count; i++) {
+ if ((c1=route_info_get(mr->ri))) {
+ c[i]=*c1;
+ rc++;
+ }
+ }
+ break;
+ case 0:
+ for (i=0; i < count; i++) {
+ if (mr->last_coord >= seg->ncoords)
+ break;
+ if (i >= seg->ncoords)
+ break;
+ if (seg->dir < 0)
+ c[i] = seg->c[seg->ncoords-++mr->last_coord];
+ else
+ c[i] = seg->c[mr->last_coord++];
+ rc++;
+ }
+ break;
+ case 1:
+ for (i=0; i < count; i++) {
+ if ((c1=route_info_get(mr->ri))) {
+ c[i]=*c1;
+ rc++;
+ }
+ }
+ break;
+ default:
+ rc=0;
+ }
+ dbg(1,"return %d\n",rc);
+ return rc;
+}
+
+static struct item_methods methods_route_item = {
+ rm_coord_rewind,
+ rm_coord_get,
+ rm_attr_rewind,
+ rm_attr_get,
+};
+
+static void
+rp_attr_rewind(void *priv_data)
+{
+ struct map_rect_priv *mr = priv_data;
+ mr->attr_next = attr_label;
+}
+
+static int
+rp_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+ struct map_rect_priv *mr = priv_data;
+ struct route_graph_point *p = mr->point;
+ if (mr->item.type != type_rg_point)
+ return 0;
+ switch (attr_type) {
+ case attr_any:
+ while (mr->attr_next != attr_none) {
+ if (rm_attr_get(priv_data, mr->attr_next, attr))
+ return 1;
+ }
+ case attr_label:
+ attr->type = attr_label;
+ if (mr->str)
+ g_free(mr->str);
+ if (p->value != INT_MAX)
+ mr->str=g_strdup_printf("%d", p->value);
+ else
+ mr->str=g_strdup("-");
+ attr->u.str = mr->str;
+ mr->attr_next=attr_none;
+ return 1;
+ case attr_debug:
+ attr->type = attr_debug;
+ if (mr->str)
+ g_free(mr->str);
+ mr->str=g_strdup_printf("x=%d y=%d", p->c.x, p->c.y);
+ attr->u.str = mr->str;
+ mr->attr_next=attr_none;
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int
+rp_coord_get(void *priv_data, struct coord *c, int count)
+{
+ struct map_rect_priv *mr = priv_data;
+ struct route_graph_point *p = mr->point;
+ struct route_graph_segment *seg = mr->rseg;
+ int rc = 0,i;
+ for (i=0; i < count; i++) {
+ if (mr->item.type == type_rg_point) {
+ if (mr->last_coord >= 1)
+ break;
+ c[i] = p->c;
+ } else {
+ if (mr->last_coord >= 2)
+ break;
+ if (mr->last_coord)
+ c[i] = seg->end->c;
+ else
+ c[i] = seg->start->c;
+ }
+ mr->last_coord++;
+ rc++;
+ }
+ return rc;
+}
+
+static struct item_methods methods_point_item = {
+ rm_coord_rewind,
+ rp_coord_get,
+ rp_attr_rewind,
+ rp_attr_get,
+};
+
+static void
+rm_destroy(struct map_priv *priv)
+{
+ g_free(priv);
+}
+
+static struct map_rect_priv *
+rm_rect_new(struct map_priv *priv, struct map_selection *sel)
+{
+ struct map_rect_priv * mr;
+ dbg(1,"enter\n");
+ if (! route_get_pos(priv->route))
+ return NULL;
+ if (! route_get_dst(priv->route))
+ return NULL;
+ if (! priv->route->path2)
+ return NULL;
+ mr=g_new0(struct map_rect_priv, 1);
+ mr->mpriv = priv;
+ mr->ri=route_info_open(route_get_pos(priv->route), route_get_dst(priv->route), 0);
+ mr->pos_next=1;
+ mr->sitem=&(route_get_pos(priv->route)->street->item);
+ mr->item.priv_data = mr;
+ mr->item.type = type_street_route;
+ mr->item.meth = &methods_route_item;
+ if (mr->ri) {
+ mr->length=route_info_length(route_get_pos(priv->route), route_get_dst(priv->route), 0);
+ } else {
+ mr->ri=route_info_open(route_get_pos(priv->route), NULL, 0);
+ mr->length=route_info_length(route_get_pos(priv->route), NULL, 0);
+ mr->pos_next=-1;
+ }
+ return mr;
+}
+
+static struct map_rect_priv *
+rp_rect_new(struct map_priv *priv, struct map_selection *sel)
+{
+ struct map_rect_priv * mr;
+ dbg(1,"enter\n");
+ if (! priv->route->graph || ! priv->route->graph->route_points)
+ return NULL;
+ mr=g_new0(struct map_rect_priv, 1);
+ mr->mpriv = priv;
+ mr->item.priv_data = mr;
+ mr->item.type = type_rg_point;
+ mr->item.meth = &methods_point_item;
+ return mr;
+}
+
+static void
+rm_rect_destroy(struct map_rect_priv *mr)
+{
+ if (mr->ri)
+ route_info_close(mr->ri);
+ if (mr->str)
+ g_free(mr->str);
+ g_free(mr);
+}
+
+static struct item *
+rp_get_item(struct map_rect_priv *mr)
+{
+ struct route *r = mr->mpriv->route;
+ struct route_graph_point *p = mr->point;
+ struct route_graph_segment *seg = mr->rseg;
+
+ if (mr->item.type == type_rg_point) {
+ if (!p)
+ p = r->graph->route_points;
+ else
+ p = p->next;
+ if (p) {
+ mr->point = p;
+ mr->item.id_lo++;
+ rm_coord_rewind(mr);
+ rp_attr_rewind(mr);
+ return &mr->item;
+ } else
+ mr->item.type = type_rg_segment;
+ }
+ if (!seg)
+ seg=r->graph->route_segments;
+ else
+ seg=seg->next;
+ if (seg) {
+ mr->rseg = seg;
+ mr->item.id_lo++;
+ rm_coord_rewind(mr);
+ rp_attr_rewind(mr);
+ return &mr->item;
+ }
+ return NULL;
+
+}
+
+static struct item *
+rp_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo)
+{
+ struct item *ret=NULL;
+ while (id_lo-- > 0)
+ ret=rp_get_item(mr);
+ return ret;
+}
+
+
+static struct item *
+rm_get_item(struct map_rect_priv *mr)
+{
+ struct route *r = mr->mpriv->route;
+ struct route_path_segment *seg = mr->seg;
+ dbg(1,"enter\n", mr->pos);
+
+ mr->pos=mr->pos_next;
+ switch(mr->pos) {
+ case -1:
+ mr->pos_next=0;
+ break;
+ case 0:
+ if (!seg)
+ seg = r->path2->path;
+ else
+ seg = seg->next;
+ if (seg) {
+ mr->sitem = &seg->item;
+ break;
+ }
+ mr->pos=1;
+ route_info_close(mr->ri);
+ mr->ri=route_info_open(NULL, route_get_dst(r), 0);
+ mr->sitem=&(route_get_dst(r)->street->item);
+ mr->length=route_info_length(NULL, route_get_dst(r), 0);
+ case 1:
+ mr->pos_next=2;
+ break;
+ case 2:
+ return NULL;
+ }
+ mr->seg = seg;
+ mr->last_coord = 0;
+ mr->item.id_lo++;
+ rm_attr_rewind(mr);
+ return &mr->item;
+}
+
+static struct item *
+rm_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo)
+{
+ struct item *ret=NULL;
+ while (id_lo-- > 0)
+ ret=rm_get_item(mr);
+ return ret;
+}
+
+static struct map_methods route_meth = {
+ projection_mg,
+ NULL,
+ rm_destroy,
+ rm_rect_new,
+ rm_rect_destroy,
+ rm_get_item,
+ rm_get_item_byid,
+ NULL,
+ NULL,
+ NULL,
+};
+
+static struct map_methods route_graph_meth = {
+ projection_mg,
+ NULL,
+ rm_destroy,
+ rp_rect_new,
+ rm_rect_destroy,
+ rp_get_item,
+ rp_get_item_byid,
+ NULL,
+ NULL,
+ NULL,
+};
+
+void
+route_toggle_routegraph_display(struct route *route)
+{
+ if (route->flags & RF_SHOWGRAPH) {
+ route->flags &= ~RF_SHOWGRAPH;
+ } else {
+ route->flags |= RF_SHOWGRAPH;
+ }
+}
+
+static struct map_priv *
+route_map_new_helper(struct map_methods *meth, struct attr **attrs, int graph)
+{
+ struct map_priv *ret;
+ struct attr *route_attr;
+
+ route_attr=attr_search(attrs, NULL, attr_route);
+ if (! route_attr)
+ return NULL;
+ ret=g_new0(struct map_priv, 1);
+ if (graph)
+ *meth=route_graph_meth;
+ else
+ *meth=route_meth;
+ ret->route=route_attr->u.route;
+
+ return ret;
+}
+
+static struct map_priv *
+route_map_new(struct map_methods *meth, struct attr **attrs)
+{
+ return route_map_new_helper(meth, attrs, 0);
+}
+
+static struct map_priv *
+route_graph_map_new(struct map_methods *meth, struct attr **attrs)
+{
+ return route_map_new_helper(meth, attrs, 1);
+}
+
+static struct map *
+route_get_map_helper(struct route *this_, struct map **map, char *type)
+{
+ struct attr route_attr;
+ struct attr data_attr;
+ struct attr *attrs_route[]={&route_attr, &data_attr, NULL};
+ route_attr.type=attr_route;
+ route_attr.u.route=this_;
+ data_attr.type=attr_data;
+ data_attr.u.str="";
+
+ if (! *map)
+ *map=map_new(type,attrs_route);
+ return *map;
+}
+
+struct map *
+route_get_map(struct route *this_)
+{
+ return route_get_map_helper(this_, &this_->map, "route");
+}
+
+
+struct map *
+route_get_graph_map(struct route *this_)
+{
+ return route_get_map_helper(this_, &this_->graph_map, "route_graph");
+}
+
+void
+route_set_projection(struct route *this_, enum projection pro)
+{
+}
+
+void
+route_init(void)
+{
+ plugin_register_map_type("route", route_map_new);
+ plugin_register_map_type("route_graph", route_graph_map_new);
+}
diff --git a/navit/route.h b/navit/route.h
new file mode 100644
index 000000000..9fb4268e2
--- /dev/null
+++ b/navit/route.h
@@ -0,0 +1,84 @@
+#ifndef NAVIT_ROUTE_H
+#define NAVIT_ROUTE_H
+
+struct route_crossing {
+ long segid;
+ int dir;
+};
+
+struct route_crossings {
+ int count;
+ struct route_crossing crossing[0];
+};
+
+struct street_data {
+ struct item item;
+ int count;
+ int flags;
+ struct coord c[0];
+};
+
+#define route_item_first type_street_0
+#define route_item_last type_ferry
+
+/* prototypes */
+enum item_type;
+struct coord;
+struct displaylist;
+struct item;
+struct map_selection;
+struct mapset;
+struct route;
+struct route_info;
+struct route_info_handle;
+struct route_path_coord_handle;
+struct route_path_handle;
+struct route_path_segment;
+struct street_data;
+struct tracking;
+struct transformation;
+struct route *route_new(struct attr **attrs);
+void route_set_mapset(struct route *this, struct mapset *ms);
+struct mapset *route_get_mapset(struct route *this);
+struct route_info *route_get_pos(struct route *this);
+struct route_info *route_get_dst(struct route *this);
+int *route_get_speedlist(struct route *this);
+int route_get_path_set(struct route *this);
+int route_set_speed(struct route *this, enum item_type type, int value);
+int route_contains(struct route *this, struct item *item);
+void route_set_position(struct route *this, struct pcoord *pos);
+void route_set_position_from_tracking(struct route *this, struct tracking *tracking);
+struct map_selection *route_rect(int order, struct coord *c1, struct coord *c2, int rel, int abs);
+void route_set_destination(struct route *this, struct pcoord *dst);
+struct route_path_handle *route_path_open(struct route *this);
+struct route_path_segment *route_path_get_segment(struct route_path_handle *h);
+struct coord *route_path_segment_get_start(struct route_path_segment *s);
+struct coord *route_path_segment_get_end(struct route_path_segment *s);
+struct item *route_path_segment_get_item(struct route_path_segment *s);
+int route_path_segment_get_length(struct route_path_segment *s);
+int route_path_segment_get_time(struct route_path_segment *s);
+void route_path_close(struct route_path_handle *h);
+struct route_path_coord_handle *route_path_coord_open(struct route *this);
+struct coord *route_path_coord_get(struct route_path_coord_handle *h);
+void route_path_coord_close(struct route_path_coord_handle *h);
+int route_time(int *speedlist, struct item *item, int len);
+int route_info_length(struct route_info *pos, struct route_info *dst, int dir);
+struct street_data *street_get_data(struct item *item);
+struct street_data *street_data_dup(struct street_data *orig);
+void street_data_free(struct street_data *sd);
+void route_info_free(struct route_info *inf);
+struct street_data *route_info_street(struct route_info *rinf);
+struct coord *route_info_point(struct route_info *rinf, int point);
+struct route_info_handle *route_info_open(struct route_info *start, struct route_info *end, int dir);
+struct coord *route_info_get(struct route_info_handle *h);
+void route_info_close(struct route_info_handle *h);
+void route_draw(struct route *this, struct transformation *t, struct displaylist *dsp);
+struct map *route_get_map(struct route *route);
+struct map *route_get_graph_map(struct route *route);
+void route_toggle_routegraph_display(struct route *route);
+void route_set_projection(struct route *this_, enum projection pro);
+void route_init(void);
+/* end of prototypes */
+
+#endif
+
diff --git a/navit/script/check_itemdef b/navit/script/check_itemdef
new file mode 100755
index 000000000..361f87be3
--- /dev/null
+++ b/navit/script/check_itemdef
@@ -0,0 +1,26 @@
+#! /bin/sh
+function check_item
+{
+ grep -q "[(,]$1)" ../item_def.h || echo "$1 missing"
+}
+
+echo osm2navit.c
+egrep '^ "[nw] +[^ ]+ +[^ ]+ +' ../osm2navit.c | sed "s/.* //" |
+while read -r x
+do
+ check_item "${x%%\\n\"}"
+done
+
+echo "navit.xml"
+grep '<item type="' <../navit.xml | cut -d \" -f 2 | tr "," "\012" |
+while read -r x
+do
+ check_item "$x"
+done
+
+echo "garmintypes.txt"
+grep ^0x ../data/garmin/garmintypes.txt | sed -e 's/[A-Z][A-Z]*, //' -e 's/.*= \([^,]*\),.*/\1/' |
+while read -r x
+do
+ check_item "$x"
+done
diff --git a/navit/script/download_index.html b/navit/script/download_index.html
new file mode 100644
index 000000000..51ca2cf66
--- /dev/null
+++ b/navit/script/download_index.html
@@ -0,0 +1,145 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Planet Extraction</title>
+ <style type="text/css">
+ html, body {
+ margin: 0;
+ padding: 1em;
+ font: 0.9em Verdana, Arial, sans serif;
+ }
+ input, select, textarea {
+ font: 1em Verdana, Arial, sans serif;
+ }
+ .input {
+ border: none;
+ width: 100px;
+ }
+ .bbox {
+ font-size: 12px;
+ color: #000;
+ background-color: #fff;
+ width: 300px;
+ border: 1px solid gray;
+ }
+ .button {
+ width: 200px;
+ height: 50px;
+ font-weight: bold;
+ }
+ #map {
+ float: left;
+ width: 500px;
+ height: 500px;
+ border: 1px solid gray;
+ }
+ #controls {
+ float: left;
+
+ }
+ </style>
+ <script src="http://openlayers.org/dev/lib/OpenLayers.js"></script>
+ <script type="text/javascript">
+ var map, polygonControl, polygonLayer, bbox_set;
+
+ OpenLayers.Util.onImageLoadErrorColor = "transparent";
+ function init(){
+ map = new OpenLayers.Map('map');
+
+ var wmsLayer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0?", {layers: 'basic'});
+
+ polygonLayer = new OpenLayers.Layer.Vector("Polygon Layer");
+
+ map.addLayers([wmsLayer, polygonLayer]);
+ map.addControl(new OpenLayers.Control.LayerSwitcher());
+ map.addControl(new OpenLayers.Control.MousePosition());
+
+ polyOptions = {sides: 4, irregular: true};
+ polygonControl = new OpenLayers.Control.DrawFeature(polygonLayer,
+ OpenLayers.Handler.RegularPolygon,
+ {handlerOptions: polyOptions});
+ //alert(polygonControl);
+
+ map.addControl(polygonControl);
+
+ polygonControl.featureAdded=featureInsert;
+
+ map.setCenter(new OpenLayers.LonLat(0, 0), 3);
+
+ document.getElementById('noneToggle').checked = true;
+ //document.getElementById('irregularToggle').checked = false;
+
+ //var polyOptions = {sides: 4, irregular: true};
+ //polygonControl.handler.setOptions(polyOptions);
+ }
+
+ function featureInsert(feature){
+ var old=[];
+ for (var i = 0; i < polygonLayer.features.length; i++) {
+ if (polygonLayer.features[i] != feature) {
+ old.push(polygonLayer.features[i]);
+ }
+ }
+ polygonLayer.destroyFeatures(old);
+
+ var bounds = feature.geometry.getBounds();
+
+ document.form.bounds_top.value = bounds.top;
+ document.form.bounds_right.value = bounds.right;
+ document.form.bounds_btm.value = bounds.bottom;
+ document.form.bounds_left.value = bounds.left;
+ bbox_set=true;
+ }
+ function download() {
+ var bbox = document.form.bounds_left.value + "," +
+ document.form.bounds_btm.value + "," +
+ document.form.bounds_right.value + "," +
+ document.form.bounds_top.value;
+ if (bbox_set) {
+ location.href="http://maps.navit-project.org/api/map?bbox=" + bbox;
+ } else {
+ alert("Please select a bounding box first\n");
+ }
+ }
+ function setOptions(options) {
+ polygonControl.handler.setOptions(options);
+ }
+ function setSize(fraction) {
+ var radius = fraction * map.getExtent().getHeight();
+ polygonControl.handler.setOptions({radius: radius,
+ angle: 0});
+ }
+ </script>
+ </head>
+ <body onload="init()">
+ <h2>Planet extract</h2>
+ <div id="map"></div>
+ <div id="controls">
+ <ul style="list-style:none;"><b>Map Controls</b>
+ <li>
+ <input type="radio" name="type"
+ value="none" id="noneToggle"
+ onclick="polygonControl.deactivate()"
+ checked="checked" />
+ <label for="noneToggle">navigate</label>
+ </li>
+ <li>
+ <input type="radio" name="type"
+ value="polygon" id="polygonToggle"
+ onclick="polygonControl.activate()" />
+ <label for="polygonToggle">select</label>
+ </li>
+ </ul>
+ <ul style="list-style:none"><b>Fetch box</b>
+ <form name="form">
+ <li>Top Right: <input type="text" name="bounds_top" class="input">,
+ <input type="text" name="bounds_right" class="input"></li>
+ <li>Bottom left: <input type="text" name="bounds_btm" class="input">,
+ <input type="text" name="bounds_left" class="input"></li>
+ </form>
+ <li>&nbsp;</li>
+ <li><input type="button" value="Get map!" onclick="javascript:download()"></li>
+ </ul>
+ </div>
+ </body>
+</html>
diff --git a/navit/script/geotag b/navit/script/geotag
new file mode 100755
index 000000000..e025cbc61
--- /dev/null
+++ b/navit/script/geotag
@@ -0,0 +1,36 @@
+#! /bin/sh
+#TZ=UTC+00:00:00
+TZ=UTC+00:59:57
+export TZ
+order=${5%%,*}
+case $order in
+10|11)
+ size=1000
+ ;;
+12|13)
+ size=4000
+ ;;
+14|15)
+ size=16000
+ ;;
+16|17|18|19)
+ size=64000
+ ;;
+*)
+ exit
+esac
+ls -l --full-time images/*.jpg | sed -e 's/^\([^ ]* \)\{5\}//' -e 's/20\([0-9]*\)-\([0-9]*\)-\([0-9]*\) \([0-9]*\):\([0-9]*\):\([0-9]*\)\.[0-9]* [^ ]*/\\$GPRMC,\4\5\6\\.000,\\([^,]*,\\)\\{7\\}\3\2\1,\\([^,]*,\\)\\{2\\}[^,]*\\*..$/' | tail +2 |
+while read -r sentence image
+do
+ if [ ! -f $image.$size ]
+ then
+ djpeg -scale 1/8 $image | pamscale -pixels $size | cjpeg >$image.$size
+
+ fi
+ if [ ! -f $image.txt ]
+ then
+ grep -e "$sentence" tracks/* | sed -e 's/^\([^,]*,\)\{3\}\(\([^,]*,\)\{4\}\).*/\2/' -e 's/,/ /g' > $image.txt
+ [ -s $image.txt ] || echo "$sentence not found" >&2
+ fi
+ sed "s&\$&type=poi_image label=$image.$size&" <$image.txt
+done
diff --git a/navit/script/get_map b/navit/script/get_map
new file mode 100755
index 000000000..7c8ef970f
--- /dev/null
+++ b/navit/script/get_map
@@ -0,0 +1,5 @@
+#! /bin/bash
+echo "/* XPM */" >map.xpm
+req="<MapRequest reqVer='100' format='jpeg' visibleRoutes='111111111' colorDepth='4'><Rect l='0' t='0' r='$1' b='$2'></Rect><Rect l='$3' t='$4' r='$5' b='$6'></Rect></MapRequest>"
+perl -e 'print (pack("a20",length($ARGV[0]))) ; print $ARGV[0]' "$req" | netcat localhost 10371 | dd bs=20 skip=1 2>/dev/null | tail +2 >>map.xpm
+xv map.xpm &
diff --git a/navit/script/gps_emu b/navit/script/gps_emu
new file mode 100755
index 000000000..f2eef3e50
--- /dev/null
+++ b/navit/script/gps_emu
@@ -0,0 +1,19 @@
+#! /bin/bash
+function send_data
+{
+ trap send_data SIGPIPE
+ while read line
+ do
+ case $line in
+ \$GPVTG*)
+ echo "$line"
+ sleep 1
+ ;;
+ *)
+ echo "$line"
+ ;;
+ esac
+ done <track/all.txt >/tmp/gpsdata
+}
+
+send_data
diff --git a/navit/script/gps_emu2 b/navit/script/gps_emu2
new file mode 100755
index 000000000..e9e79b42a
--- /dev/null
+++ b/navit/script/gps_emu2
@@ -0,0 +1,46 @@
+#! /usr/bin/perl
+
+open(FILE,"<$ARGV[0]");
+read(FILE,$header,64);
+
+($magic,$version)=unpack("a8l",$header);
+
+#print "magic=$magic version=$version\n";
+
+select STDOUT; $| = 1;
+
+$count=$ARGV[1];
+while ($count) {
+ read(FILE,$record,64);
+ $count--;
+}
+
+while (read(FILE,$record,64))
+{
+ ($flags,$status,$mode,$hdop,$vdop,$pdop,$sats,$timestampl,$timestamph,$latitude,$longitude,$altitude,$speed,$direction)=unpack("SCCCCCCLLddddd",$record);
+
+
+ if ($mode == 3) {
+ ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($timestampl);
+ $datestring=sprintf("%02d.%02d.%d %02d:%02d:%02d",$mday,$mon+1,$year+1900,$hour,$min,$sec);
+ $long_dir="E";
+ $lat_dir="N";
+ if ($longitude < 0) {
+ $long_dir="W";
+ $logitude=-$longitude;
+ }
+ if ($latitude < 0) {
+ $lat_dir="S";
+ $latitude=-$latitude;
+ }
+ $long_deg=int($longitude);
+ $lat_deg=int($latitude);
+ $long_gps=$long_deg*100+($longitude-$long_deg)*60;
+ $lat_gps=$lat_deg*100+($latitude-$lat_deg)*60;
+ $lastpos="$lat_gps $lat_dir $long_gps $long_dir";
+ printf("\$GPGGA,%02d%02d%02d,%s,%s,%s,%s,1,%d,%s,%s,M,,,,0000*0C\n",$hour,$min,$sec,$lat_gps,$lat_dir,$long_gps,$long_dir,$sats,$hdop,$altitude);
+ printf("\$GPVTG,%s,T,,M,,N,%s,K,*6A\n",$direction,$speed*1.852);
+ printf(STDERR "\$GPGGA,%02d%02d%02d,%s,%s,%s,%s,1,%d,%s,%s,M,,,,0000*0C\n",$hour,$min,$sec,$lat_gps,$lat_dir,$long_gps,$long_dir,$sats,$hdop,$altitude);
+ sleep(1);
+ }
+}
diff --git a/navit/script/gps_emu3 b/navit/script/gps_emu3
new file mode 100755
index 000000000..5c0ecf256
--- /dev/null
+++ b/navit/script/gps_emu3
@@ -0,0 +1,12 @@
+#! /bin/bash
+while read line
+do
+ if [ -n "$line" ]
+ then
+ echo $line
+ fi
+ if [ "${line#\$GPVTG}" != "$line" ]
+ then
+ sleep 1
+ fi
+done <$1
diff --git a/navit/script/mapExtract.class.php b/navit/script/mapExtract.class.php
new file mode 100644
index 000000000..f5c4bbbc3
--- /dev/null
+++ b/navit/script/mapExtract.class.php
@@ -0,0 +1,283 @@
+<?php
+
+class mapExtract {
+
+ var $input_fd;
+ var $output_fd;
+ var $fetchBbox;
+
+ var $formats;
+ var $worldBbox;
+
+ function mapExtract() {
+ $formats = array();
+
+ $formats['ziphpack'] = "lssssslLLSS";
+ $formats['zipheader'] = "l" . "ziplocsig"; # Signature (is always the same)
+ $formats['zipheader'] .= "/s" . "zipver"; # zip version needed
+ $formats['zipheader'] .= "/s" . "zipgenfld";# type of os that generated the file
+ $formats['zipheader'] .= "/s" . "zipmthd"; #
+ $formats['zipheader'] .= "/s" . "ziptime"; # time
+ $formats['zipheader'] .= "/s" . "zipdate"; # date
+ $formats['zipheader'] .= "/l" . "zipcrc"; # crc checksum
+ $formats['zipheader'] .= "/L" . "zipsize"; # data size
+ $formats['zipheader'] .= "/L" . "zipuncmp"; # uncompressed size
+ $formats['zipheader'] .= "/S" . "zipfnln"; # length of filename
+ $formats['zipheader'] .= "/S" . "zipxtraln";# length of extra data (always 0)
+
+ $formats['zipcdpack'] = "iccccssssiIISSSSSII";
+ $formats['zipcd'] = "".
+ "i" . "zipcensig/".
+ "c" . "zipcver/".
+ "c" . "zipcos/".
+ "c" . "zipcvxt/".
+ "c" . "zipcexos/".
+ "s" . "zipcflg/".
+ "s" . "zipcmthd/".
+ "s" . "ziptim/".
+ "s" . "zipdat/".
+ "i" . "zipccrc/".
+ "I" . "zipcsiz/".
+ "I" . "zipcunc/".
+ "S" . "zipcfnl/".
+ "S" . "zipcxtl/".
+ "S" . "zipccml/".
+ "S" . "zipdsk/".
+ "S" . "zipint/".
+ "I" . "zipext/".
+ "I" . "zipofst";
+
+ $formats['zipeocpack'] = "iSSSSIIs";
+ $formats['zipeoc'] = "".
+ "i" . "zipesig/".
+ "S" . "zipedsk/".
+ "S" . "zipecen/".
+ "S" . "zipenum/".
+ "S" . "zipecenn/".
+ "I" . "zipecsz/".
+ "I" . "zipeofst/".
+ "s" . "zipecoml/".
+
+ $world_bbox = array();
+ $world_bbox['l']['x'] = -20000000;
+ $world_bbox['l']['y'] = -20000000;
+ $world_bbox['h']['x'] = 20000000;
+ $world_bbox['h']['y'] = 20000000;
+
+ $this->formats = $formats;
+ $this->worldBbox = $world_bbox;
+ }
+
+
+ function process() {
+
+ if (!is_array($this->fetchBbox)) {
+ return "Fetch box not set";
+ }
+ #
+ if (!$this->input_fd) {
+ return "No useable input set";
+ }
+ if (!$this->output_fd) {
+ return "No useable output set";
+ }
+ $filecount = 0;
+ $offset = 0;
+ $zipcd_data = '';
+ $report = array();
+
+ /**
+ * Read through zipheaders
+ *
+ */
+ for(;;) {
+ $buffer = fread($this->input_fd, 30);
+ if (! strlen($buffer))
+ break;
+ $tileinfo = unpack($this->formats['zipheader'], $buffer);
+
+ if ($tileinfo['ziplocsig'] != 0x4034b50)
+ break;
+
+ if ($tileinfo['zipfnln'] <= 0)
+ break;
+
+ $filename = fread($this->input_fd, $tileinfo['zipfnln']);
+ $done=false;
+
+ $r = $this->worldBbox;
+
+ $len=strlen($filename);
+ for ($i=0 ; $i < $len ; $i++) {
+ $c['x'] = floor( ($r['l']['x'] + $r['h']['x'])/2 );
+ $c['y'] = floor( ($r['l']['y'] + $r['h']['y'])/2 );
+
+ switch($filename[$i]) {
+ case 'a':
+ $r['l']['x'] = $c['x'];
+ $r['l']['y'] = $c['y'];
+ break;
+ case 'b':
+ $r['h']['x'] = $c['x'];
+ $r['l']['y'] = $c['y'];
+ break;
+ case 'c':
+ $r['l']['x'] = $c['x'];
+ $r['h']['y'] = $c['y'];
+ break;
+ case 'd':
+ $r['h']['x'] = $c['x'];
+ $r['h']['y'] = $c['y'];
+ break;
+ default:
+ $done=true;
+ }
+ if ($done)
+ break;
+ }
+ # print "zipsize=" . $tileinfo['zipsize'];
+ $tilecontent = fread($this->input_fd, $tileinfo['zipsize']);
+
+ # print "tile $filename";
+ /* Area inside box, save it! */
+ if ($this->contains_bbox($r)) {
+ $report['added_areas']++;
+
+ $zipheader = $buffer;
+ # print " in\n";
+
+ /* Area outside of box, set zipcontent=0 */
+ } else {
+ # print " out\n";
+ $report['excluded_areas']++;
+
+ $tileinfo['zipmthd'] = $tileinfo['zipcrc'] = $tileinfo
+['zipsize'] = $tileinfo['zipuncmp'] = 0;
+ $zipheader = $tileinfo;
+ $tilecontent = '';
+ $zipheader = pack($this->formats['ziphpack'],
+ $tileinfo['ziplocsig'],
+ $tileinfo['zipver'],
+ $tileinfo['zipgenfld'],
+ $tileinfo['zipmthd'],
+ $tileinfo['ziptime'],
+ $tileinfo['zipdate'],
+ $tileinfo['zipcrc'],
+ $tileinfo['zipsize'],
+ $tileinfo['zipuncmp'],
+ $tileinfo['zipfnln'],
+ $tileinfo['zipxtraln']
+ );
+ }
+
+ $put = $zipheader.$filename.$tilecontent;
+
+ /* Zip directory */
+ $zipcd_data .= pack($this->formats['zipcdpack'],
+ 0x02014b50,
+ $tileinfo['zipver'],
+ 0x00,
+ 0x0a,
+ 0x00,
+ 0x00,
+ $tileinfo['zipmthd'],
+ $tileinfo['ziptime'],
+ $tileinfo['zipdate'],
+ $tileinfo['zipcrc'],
+ $tileinfo['zipsize'],
+ $tileinfo['zipuncmp'],
+ $tileinfo['zipfnln'],
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ $offset
+ ) . $filename;
+
+ fwrite($this->output_fd, $put);
+ $offset += strlen($put);
+ $filecount += 1;
+ }
+
+ fwrite($this->output_fd, $zipcd_data);
+ $ecsz = strlen($zipcd_data);
+
+ /* Zip central directory */
+ $zip_eoc = pack($this->formats['zipeocpack'],
+ 0x06054b50, #zipesig;
+ 0, #zipedsk;
+ 0, #zipecen;
+ $filecount, #zipenum;
+ $filecount, #zipecenn;
+ $ecsz, #zipecsz;
+ $offset, #zipeofst;
+ 0 #zipecoml;
+ );
+ fwrite($this->output_fd, $zip_eoc);
+
+
+ return null;
+ }
+
+ function setBbox($sx,$sy,$ex,$ey) {
+ if ($ex<$sx)
+ return false;
+ if ($ey<$sy)
+ return false;
+ $this->fetchBbox = $this->getmercator($sx,$sy,$ex,$ey);
+ return true;
+ }
+
+ function setInput($file) {
+ $this->input_fd=fopen($file,'r');
+ }
+ function setInputFD($fd) {
+ $this->input_fd=$fd;
+ }
+
+ function setOutput($file) {
+ $this->output_fd=fopen($file,'w');
+ }
+
+ function setOutputFD($fd) {
+ $this->output_fd=$fd;
+ }
+
+
+ function contains_bbox(&$r) {
+ $c =& $this->fetchBbox;
+ if ($c['l']['x'] > $r['h']['x'])
+ return false;
+ elseif ($c['h']['x'] < $r['l']['x'])
+ return false;
+ elseif ($c['l']['y'] > $r['h']['y'])
+ return false;
+ elseif ($c['h']['y'] < $r['l']['y'])
+ return false;
+ else
+ return true;
+ }
+
+ function getmercator($sx,$sy,$ex,$ey) {
+ $sx = $sx*6371000.0*M_PI/180;
+ $sy = log(tan(M_PI_4+$sy*M_PI/360))*6371000.0;
+
+ $ex = $ex*6371000.0*M_PI/180;
+ $ey = log(tan(M_PI_4+$ey*M_PI/360))*6371000.0;
+ return array(
+ 'l' => array(
+ 'x' => $sx,
+ 'y' => $sy
+ ),
+ 'h' => array(
+ 'x' => $ex,
+ 'y' => $ey
+ )
+ );
+ }
+
+}
+
+
+?>
diff --git a/navit/script/map_index.php b/navit/script/map_index.php
new file mode 100644
index 000000000..b71dbac6a
--- /dev/null
+++ b/navit/script/map_index.php
@@ -0,0 +1,42 @@
+<?php
+ set_time_limit(600);
+ require_once("mapExtract.class.php");
+ $bbox=split(',',urldecode($HTTP_GET_VARS['bbox']));
+ if (count($bbox) == 4) {
+ $mapextract = new mapExtract();
+ $mapextract->setBbox($bbox[0], $bbox[1], $bbox[2], $bbox[3]);
+ $fp=fopen('php://output','w');
+ $mapextract->setInput('../../planet.bin');
+ $mapextract->setOutputFD($fp);
+ if(isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'],'MSIE'))
+ header('Content-Type: application/force-download');
+ else
+ header('Content-Type: application/octet-stream');
+ $name='osm_bbox_';
+ $name.=round($bbox[0],1) . ',' . round($bbox[1],1) . ',';
+ $name.=round($bbox[2],1) . ',' . round($bbox[3],1);
+ $name.='.bin';
+ header("Content-disposition: attachment; filename=\"$name\"");
+ $error=$mapextract->process();
+ if ($error) {
+ header('Content-Type: text/plain');
+ echo $error;
+ }
+ fclose($fp);
+ } else {
+ #echo "<pre>";
+ #print_r($HTTP_HOST);
+ #echo "</pre>";
+ $areas=array(
+ 'Germany' => '5,47,16,55.1',
+ );
+ $url='http://' . $HTTP_HOST . $PHP_SELF;
+ echo "Use: $url?bbox=bllon,bllat,trlon,trlat <br />\n";
+ echo "<br />\n";
+ while (list($area,$bbox)=each($areas)) {
+ $urlf=$url . "?bbox=$bbox";
+ echo "$area <a href='$urlf'>$urlf</a><br />\n";
+ }
+
+ }
+?>
diff --git a/navit/script/mapextract.php b/navit/script/mapextract.php
new file mode 100644
index 000000000..004b63caf
--- /dev/null
+++ b/navit/script/mapextract.php
@@ -0,0 +1,225 @@
+#!/usr/local/bin/php &#8211;q
+<?php
+function getmercator($sx,$sy,$ex,$ey) {
+
+ $sx = $sx*6371000.0*M_PI/180;
+ $sy = log(tan(M_PI_4+$sy*M_PI/360))*6371000.0;
+
+ $ex = $ex*6371000.0*M_PI/180;
+ $ey = log(tan(M_PI_4+$ey*M_PI/360))*6371000.0;
+
+ return array(
+ 'l' => array(
+ 'x' => $sx,
+ 'y' => $sy
+ ),
+ 'h' => array(
+ 'x' => $ex,
+ 'y' => $ey
+ )
+ );
+
+}
+function contains_bbox($c, &$r) {
+ if ($c['l']['x'] > $r['h']['x'])
+ return false;
+ elseif ($c['h']['x'] < $r['l']['x'])
+ return false;
+ elseif ($c['l']['y'] > $r['h']['y'])
+ return false;
+ elseif ($c['h']['y'] < $r['l']['y'])
+ return false;
+ else
+ return true;
+}
+
+$fetch_bbox = getmercator(11.3, 47.9, 11.4, 48.0);
+
+$files = array();
+$files['input'] = '/home/burner/carputer/navit/src/maps/osm_bbox_11.3,47.9,11.7,48.2.bin';
+$files['output'] = 'myarea.bin';
+
+$formats = array();
+$formats['ziphpack'] = "lssssslLLSS";
+$formats['zipheader'] = "l" . "ziplocsig"; # Signature (is always the same)
+$formats['zipheader'] .= "/s" . "zipver"; # zip version needed
+$formats['zipheader'] .= "/s" . "zipgenfld";# type of os that generated the file
+$formats['zipheader'] .= "/s" . "zipmthd"; #
+$formats['zipheader'] .= "/s" . "ziptime"; # time
+$formats['zipheader'] .= "/s" . "zipdate"; # date
+$formats['zipheader'] .= "/l" . "zipcrc"; # crc checksum
+$formats['zipheader'] .= "/L" . "zipsize"; # data size
+$formats['zipheader'] .= "/L" . "zipuncmp"; # uncompressed size
+$formats['zipheader'] .= "/S" . "zipfnln"; # length of filename
+$formats['zipheader'] .= "/S" . "zipxtraln";# length of extra data (always 0)
+
+$formats['zipcd'] = "".
+ "i" . "zipcensig/".
+ "c" . "zipcver/".
+ "c" . "zipcos/".
+ "c" . "zipcvxt/".
+ "c" . "zipcexos/".
+ "s" . "zipcflg/".
+ "s" . "zipcmthd/".
+ "s" . "ziptim/".
+ "s" . "zipdat/".
+ "i" . "zipccrc/".
+ "I" . "zipcsiz/".
+ "I" . "zipcunc/".
+ "S" . "zipcfnl/".
+ "S" . "zipcxtl/".
+ "S" . "zipccml/".
+ "S" . "zipdsk/".
+ "S" . "zipint/".
+ "I" . "zipext/".
+ "I" . "zipofst/".
+$formats['zipcdpack'] = "iccccssssiIISSSSSII";
+
+$formats['zipcontent'] = "i5x/i5y/ii";
+
+$world_bbox = array();
+$world_bbox['l']['x'] = -20000000;
+$world_bbox['l']['y'] = -20000000;
+$world_bbox['h']['x'] = 20000000;
+$world_bbox['h']['y'] = 20000000;
+
+$fp = fopen($files['input'], 'r');
+$sp = fopen($files['output'], 'w');
+
+$files = array();
+$offset = 0;
+
+/**
+ * Read through zipheaders
+ *
+ */
+while (!feof($fp)) {
+
+ $buffer = fread($fp, 30);
+ $tileinfo = unpack($formats['zipheader'], $buffer);
+
+ if ($tileinfo['zipfnln'] <= 0)
+ break;
+
+ $filename = fread($fp, $tileinfo['zipfnln']);
+ $x=0;
+ $done=false;
+
+ $r = $world_bbox;
+
+ while (!$done) {
+ $c['x'] = floor( ($r['l']['x'] + $r['h']['x'])/2 );
+ $c['y'] = floor( ($r['l']['y'] + $r['h']['y'])/2 );
+
+ switch($filename[$x]) {
+ case 'a':
+ $r['l']['x'] = $c['x'];
+ $r['l']['y'] = $c['y'];
+ break;
+ case 'b':
+ $r['h']['x'] = $c['x'];
+ $r['l']['y'] = $c['y'];
+ break;
+ case 'c':
+ $r['l']['x'] = $c['x'];
+ $r['h']['y'] = $c['y'];
+ break;
+ case 'd':
+ $r['h']['x'] = $c['x'];
+ $r['h']['y'] = $c['y'];
+ break;
+ default:
+ $done=true;
+ }
+ $x++;
+ }
+
+ $tilecontent = fread($fp, $tileinfo['zipsize']);
+
+ /* Area inside box, save it! */
+ if (contains_bbox($fetch_bbox, $r)) {
+ #echo "In box. ";
+ #echo $filename . " ";
+ $zipheader = $buffer;
+ #echo "\n";
+
+ /* Area outside of box, set zipcontent=0 */
+ } else {
+ $tileinfo['zipmthd'] = $tileinfo['zipcrc'] = $tileinfo['zipsize'] = $tileinfo['zipuncmp'] = 0;
+ #echo "Out of box";
+ $zipheader = $tileinfo;
+ $tilecontent = '';
+ $zipheader = pack($formats['ziphpack'],
+ $tileinfo['ziplocsig'],
+ $tileinfo['zipver'],
+ $tileinfo['zipgenfld'],
+ $tileinfo['zipmthd'],
+ $tileinfo['ziptime'],
+ $tileinfo['zipdate'],
+ $tileinfo['zipcrc'],
+ $tileinfo['zipsize'],
+ $tileinfo['zipuncmp'],
+ $tileinfo['zipfnln'],
+ $tileinfo['zipxtraln']
+ );
+ }
+
+ $put = $zipheader.$filename.$tilecontent;
+ $files[$filename]['header'] = $tileinfo;
+ $files[$filename]['size'] = strlen($put);
+
+ $zipcd = array();
+ $zipcd['zipcensig'] = 0x02014b50;
+ $zipcd['zipcver'] = $tileinfo['zipver'];
+ $zipcd['zipcos'] = 0x00;
+ $zipcd['zipcvxt'] = 0x0a;
+ $zipcd['zipcexos'] = 0x00;
+ $zipcd['zipcflg'] = 0x00;
+ $zipcd['zipcmthd'] = $tileinfo['zipmthd'];
+ $zipcd['ziptim'] = $tileinfo['ziptime'];
+ $zipcd['zipdat'] = $tileinfo['zipdate'];
+ $zipcd['zipccrc'] = $tileinfo['zipcrc'];
+ $zipcd['zipcsiz'] = $tileinfo['zipsize'];
+ $zipcd['zipcunc'] = $tileinfo['zipuncmp'];
+ $zipcd['zipcfnl'] = $tileinfo['zipfnln'];
+ $zipcd['zipcxtl'] = 0x00;
+ $zipcd['zipccml'] = 0x00;
+ $zipcd['zipdsk'] = 0x00;
+ $zipcd['zipint'] = 0x00;
+ $zipcd['zipext'] = 0x00;
+ $zipcd['zipofst'] = $offset;
+
+ $zipcd_data .= pack($formats['zipcdpack'],
+ $zipcd['zipcensig'],
+ $zipcd['zipcver'],
+ $zipcd['zipcos'],
+ $zipcd['zipcvxt'],
+ $zipcd['zipcexos'],
+ $zipcd['zipcflg'],
+ $zipcd['zipcmthd'],
+ $zipcd['ziptim'],
+ $zipcd['zipdat'],
+ $zipcd['zipccrc'],
+ $zipcd['zipcsiz'],
+ $zipcd['zipcunc'],
+ $zipcd['zipcfnl'],
+ $zipcd['zipcxtl'],
+ $zipcd['zipccml'],
+ $zipcd['zipdsk'],
+ $zipcd['zipint'],
+ $zipcd['zipext'],
+ $zipcd['zipofst']
+ ) . $filename;
+
+
+ fwrite($sp, $put);
+ $offset += strlen($put);
+
+}
+
+fwrite($sp, $zipcd_data);
+
+fclose($fp);
+fclose($sp);
+
+?>
diff --git a/navit/script/wiki2def b/navit/script/wiki2def
new file mode 100755
index 000000000..ab8349358
--- /dev/null
+++ b/navit/script/wiki2def
@@ -0,0 +1,37 @@
+#! /bin/bash
+rm -f item_def.h.wiki
+rm -f osmmap_def.h.wiki
+IFS="|"
+echo "/* This file is generated from http://wiki.navit-project.org/index.php/Item_def.h, do not edit it, edit the wiki page instead */" >item_def.h.wiki
+echo "/* This file is generated from http://wiki.navit-project.org/index.php/Item_def.h, do not edit it, edit the wiki page instead */" >osmmap_def.h.wiki
+type="n"
+wget -O - "http://wiki.navit-project.org/index.php/Item_def.h?action=edit" |
+awk '/<textarea/,/<\/textarea/ { print $0 }' |
+grep "^| " |
+sed -e 's/^| *//' -e 's/ *$//' -e 's/ *|/|/g' -e 's/| */|/g' -e 's/||/|/g' |
+while read id item description osmtags dummy
+do
+ if [[ "$id" == colspan=* ]]
+ then
+ echo "/* $item */" >>item_def.h.wiki
+ continue
+ fi
+ if [[ -z "$id" ]]
+ then
+ echo "ITEM($item)" >>item_def.h.wiki
+ else
+ echo "ITEM2($id,$item)" >>item_def.h.wiki
+ if [ "$id" == "0x80000000" ]
+ then
+ type="w"
+ fi
+ fi
+ if [[ -n "$osmtags" ]]
+ then
+ for osmtag in $(echo "$osmtags" | sed 's/&lt;br\/&gt;/|/g')
+ do
+ printf '"%s\t%s\t%s\t%s\\n"\n' $type $osmtag $item >> osmmap_def.h.wiki
+ done
+ fi
+done
+exit 0
diff --git a/navit/search.c b/navit/search.c
new file mode 100644
index 000000000..f4db7736b
--- /dev/null
+++ b/navit/search.c
@@ -0,0 +1,332 @@
+#include <glib.h>
+#include <string.h>
+#include "debug.h"
+#include "projection.h"
+#include "map.h"
+#include "mapset.h"
+#include "coord.h"
+#include "item.h"
+#include "search.h"
+
+struct search_list_level {
+ struct mapset *ms;
+ struct item *parent;
+ struct attr attr;
+ int partial;
+ struct mapset_search *search;
+ GHashTable *hash;
+ GList *list,*curr,*last;
+};
+
+struct search_list {
+ struct mapset *ms;
+ int level;
+ struct search_list_level levels[4];
+ struct search_list_result result;
+};
+
+static guint
+search_item_hash_hash(gconstpointer key)
+{
+ const struct item *itm=key;
+ gconstpointer hashkey=(gconstpointer)(itm->id_hi^itm->id_lo);
+ return g_direct_hash(hashkey);
+}
+
+static gboolean
+search_item_hash_equal(gconstpointer a, gconstpointer b)
+{
+ const struct item *itm_a=a;
+ const struct item *itm_b=b;
+ if (item_is_equal_id(*itm_a, *itm_b))
+ return TRUE;
+ return FALSE;
+}
+
+struct search_list *
+search_list_new(struct mapset *ms)
+{
+ struct search_list *ret;
+
+ ret=g_new0(struct search_list, 1);
+ ret->ms=ms;
+
+ return ret;
+}
+
+static void search_list_search_free(struct search_list *sl, int level);
+void
+search_list_search(struct search_list *this_, struct attr *search_attr, int partial)
+{
+ int level=-1;
+ struct search_list_level *le;
+ switch(search_attr->type) {
+ case attr_country_all:
+ case attr_country_id:
+ case attr_country_iso2:
+ case attr_country_iso3:
+ case attr_country_car:
+ case attr_country_name:
+ level=0;
+ break;
+ case attr_town_postal:
+ level=1;
+ break;
+ case attr_town_name:
+ level=1;
+ break;
+ case attr_street_name:
+ level=2;
+ break;
+ default:
+ break;
+ }
+ dbg(0,"level=%d\n", level);
+ if (level != -1) {
+ this_->level=level;
+ le=&this_->levels[level];
+ le->attr=*search_attr;
+ if (search_attr->type != attr_country_id)
+ le->attr.u.str=g_strdup(search_attr->u.str);
+ search_list_search_free(this_, level);
+ le->partial=partial;
+ if (level > 0) {
+ le=&this_->levels[level-1];
+ le->curr=le->list;
+ }
+ dbg(1,"le=%p partial=%d\n", le, partial);
+ }
+}
+
+static struct search_list_country *
+search_list_country_new(struct item *item)
+{
+ struct search_list_country *ret=g_new0(struct search_list_country, 1);
+ struct attr attr;
+
+ ret->item=*item;
+ if (item_attr_get(item, attr_country_car, &attr))
+ ret->car=g_strdup(attr.u.str);
+ if (item_attr_get(item, attr_country_iso2, &attr))
+ ret->iso2=g_strdup(attr.u.str);
+ if (item_attr_get(item, attr_country_iso3, &attr))
+ ret->iso3=g_strdup(attr.u.str);
+ if (item_attr_get(item, attr_country_name, &attr))
+ ret->name=g_strdup(attr.u.str);
+ return ret;
+}
+
+static void
+search_list_country_destroy(struct search_list_country *this_)
+{
+ g_free(this_->car);
+ g_free(this_->iso2);
+ g_free(this_->iso3);
+ g_free(this_->name);
+ g_free(this_);
+}
+
+static struct search_list_town *
+search_list_town_new(struct item *item)
+{
+ struct search_list_town *ret=g_new0(struct search_list_town, 1);
+ struct attr attr;
+ struct coord c;
+
+ ret->itemt=*item;
+ if (item_attr_get(item, attr_town_streets_item, &attr)) {
+ dbg(1,"town_assoc 0x%x 0x%x\n", attr.u.item->id_hi, attr.u.item->id_lo);
+ ret->item=*attr.u.item;
+ }
+ else
+ ret->item=*item;
+ if (item_attr_get(item, attr_town_name, &attr))
+ ret->name=map_convert_string(item->map,attr.u.str);
+ if (item_attr_get(item, attr_town_postal, &attr))
+ ret->postal=map_convert_string(item->map,attr.u.str);
+ if (item_attr_get(item, attr_district_name, &attr))
+ ret->district=map_convert_string(item->map,attr.u.str);
+ if (item_coord_get(item, &c, 1)) {
+ ret->c=g_new(struct pcoord, 1);
+ ret->c->x=c.x;
+ ret->c->y=c.y;
+ ret->c->pro = map_projection(item->map);
+ }
+ return ret;
+}
+
+static void
+search_list_town_destroy(struct search_list_town *this_)
+{
+ map_convert_free(this_->name);
+ map_convert_free(this_->postal);
+ if (this_->c)
+ g_free(this_->c);
+ g_free(this_);
+}
+
+static struct search_list_street *
+search_list_street_new(struct item *item)
+{
+ struct search_list_street *ret=g_new0(struct search_list_street, 1);
+ struct attr attr;
+ struct coord c;
+
+ ret->item=*item;
+ if (item_attr_get(item, attr_street_name, &attr))
+ ret->name=map_convert_string(item->map, attr.u.str);
+ if (item_coord_get(item, &c, 1)) {
+ ret->c=g_new(struct pcoord, 1);
+ ret->c->x=c.x;
+ ret->c->y=c.y;
+ ret->c->pro = map_projection(item->map);
+ }
+ return ret;
+}
+
+static void
+search_list_street_destroy(struct search_list_street *this_)
+{
+ map_convert_free(this_->name);
+ if (this_->c)
+ g_free(this_->c);
+ g_free(this_);
+}
+
+
+static void
+search_list_result_destroy(int level, void *p)
+{
+ switch (level) {
+ case 0:
+ search_list_country_destroy(p);
+ break;
+ case 1:
+ search_list_town_destroy(p);
+ break;
+ case 2:
+ search_list_street_destroy(p);
+ break;
+ }
+}
+
+static void
+search_list_search_free(struct search_list *sl, int level)
+{
+ struct search_list_level *le=&sl->levels[level];
+ GList *next,*curr;
+ if (le->search) {
+ mapset_search_destroy(le->search);
+ le->search=NULL;
+ }
+#if 0 /* FIXME */
+ if (le->hash) {
+ g_hash_table_destroy(le->hash);
+ le->hash=NULL;
+ }
+#endif
+ curr=le->list;
+ while (curr) {
+ search_list_result_destroy(level, curr->data);
+ next=g_list_next(curr);
+ curr=next;
+ }
+ g_list_free(le->list);
+ le->list=NULL;
+ le->curr=NULL;
+ le->last=NULL;
+
+}
+
+static int
+search_add_result(struct search_list_level *le, void *p)
+{
+ if (! g_hash_table_lookup(le->hash, p)) {
+ g_hash_table_insert(le->hash, p, (void *)1);
+ le->list=g_list_append(le->list, p);
+ return 1;
+ }
+ return 0;
+}
+
+struct search_list_result *
+search_list_get_result(struct search_list *this_)
+{
+ struct search_list_level *le,*leu;
+ struct item *item;
+ int level=this_->level;
+
+ dbg(1,"enter\n");
+ le=&this_->levels[level];
+ dbg(1,"le=%p\n", le);
+ for (;;) {
+ dbg(1,"le->search=%p\n", le->search);
+ if (! le->search) {
+ dbg(1,"partial=%d\n", le->partial);
+ if (! level)
+ le->parent=NULL;
+ else {
+ leu=&this_->levels[level-1];
+ if (! leu->curr)
+ break;
+ le->parent=leu->curr->data;
+ leu->last=leu->curr;
+ leu->curr=g_list_next(leu->curr);
+ }
+ if (le->parent)
+ dbg(1,"mapset_search_new with item(%d,%d)\n", le->parent->id_hi, le->parent->id_lo);
+ dbg(1,"attr=%s\n", attr_to_name(le->attr.type));
+ le->search=mapset_search_new(this_->ms, le->parent, &le->attr, le->partial);
+ le->hash=g_hash_table_new(search_item_hash_hash, search_item_hash_equal);
+ }
+ dbg(1,"le->search=%p\n", le->search);
+ item=mapset_search_get_item(le->search);
+ dbg(1,"item=%p\n", item);
+ if (item) {
+ void *p=NULL;
+ dbg(1,"id_hi=%d id_lo=%d\n", item->id_hi, item->id_lo);
+ this_->result.country=NULL;
+ this_->result.town=NULL;
+ this_->result.street=NULL;
+ this_->result.c=NULL;
+ switch (level) {
+ case 0:
+ p=search_list_country_new(item);
+ this_->result.country=p;
+ break;
+ case 1:
+ p=search_list_town_new(item);
+ this_->result.country=this_->levels[0].last->data;
+ this_->result.town=p;
+ this_->result.c=this_->result.town->c;
+ break;
+ case 2:
+ p=search_list_street_new(item);
+ this_->result.country=this_->levels[0].last->data;
+ this_->result.town=this_->levels[1].last->data;
+ this_->result.street=p;
+ this_->result.c=this_->result.street->c;
+ break;
+ }
+ if (p) {
+ if (search_add_result(le, p))
+ return &this_->result;
+ else
+ search_list_result_destroy(level, p);
+ }
+ } else {
+ mapset_search_destroy(le->search);
+ le->search=NULL;
+ g_hash_table_destroy(le->hash);
+ if (! level)
+ break;
+ }
+ }
+ return NULL;
+}
+
+void
+search_list_destroy(struct search_list *this_)
+{
+ g_free(this_);
+}
diff --git a/navit/search.h b/navit/search.h
new file mode 100644
index 000000000..494e89c73
--- /dev/null
+++ b/navit/search.h
@@ -0,0 +1,52 @@
+#ifndef NAVIT_SEARCH_H
+#define NAVIT_SEARCH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+struct search_list_country {
+ struct item item;
+ char *car;
+ char *iso2;
+ char *iso3;
+ char *name;
+};
+
+struct search_list_town {
+ struct item item;
+ struct item itemt;
+ struct pcoord *c;
+ char *postal;
+ char *name;
+ char *district;
+};
+
+struct search_list_street {
+ struct item item;
+ struct pcoord *c;
+ char *name;
+};
+
+struct search_list_result {
+ struct pcoord *c;
+ struct search_list_country *country;
+ struct search_list_town *town;
+ struct search_list_street *street;
+};
+
+/* prototypes */
+struct attr;
+struct mapset;
+struct search_list;
+struct search_list_result;
+struct search_list *search_list_new(struct mapset *ms);
+void search_list_search(struct search_list *this_, struct attr *search_attr, int partial);
+struct search_list_result *search_list_get_result(struct search_list *this_);
+void search_list_destroy(struct search_list *this_);
+/* end of prototypes */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/navit/speech.c b/navit/speech.c
new file mode 100644
index 000000000..0e49cd753
--- /dev/null
+++ b/navit/speech.c
@@ -0,0 +1,41 @@
+#include <glib.h>
+#include <string.h>
+#include "debug.h"
+#include "speech.h"
+#include "plugin.h"
+
+struct speech {
+ struct speech_priv *priv;
+ struct speech_methods meth;
+};
+
+struct speech *
+speech_new(const char *type, const char *data)
+{
+ struct speech *this_;
+ struct speech_priv *(*speech_new)(const char *data, struct speech_methods *meth);
+
+ dbg(1,"enter type=%s data=%s\n", type, data);
+ speech_new=plugin_get_speech_type(type);
+ dbg(1,"new=%p\n", speech_new);
+ if (! speech_new) {
+ return NULL;
+ }
+ this_=g_new0(struct speech, 1);
+ this_->priv=speech_new(data, &this_->meth);
+ dbg(1, "say=%p\n", this_->meth.say);
+ dbg(1,"priv=%p\n", this_->priv);
+ if (! this_->priv) {
+ g_free(this_);
+ return NULL;
+ }
+ dbg(1,"return %p\n", this_);
+ return this_;
+}
+
+int
+speech_say(struct speech *this_, const char *text)
+{
+ dbg(1, "this_=%p text='%s' calling %p\n", this_, text, this_->meth.say);
+ return (this_->meth.say)(this_->priv, text);
+}
diff --git a/navit/speech.h b/navit/speech.h
new file mode 100644
index 000000000..46f199ef6
--- /dev/null
+++ b/navit/speech.h
@@ -0,0 +1,19 @@
+#ifndef NAVIT_SPEECH_H
+#define NAVIT_SPEECH_H
+
+struct speech_priv;
+
+struct speech_methods {
+ void (*destroy)(struct speech_priv *this_);
+ int (*say)(struct speech_priv *this_, const char *text);
+};
+
+/* prototypes */
+struct speech * speech_new(const char *type, const char *data);
+int speech_say(struct speech *this_, const char *text);
+int speech_sayf(struct speech *this_, const char *format, ...);
+void speech_destroy(struct speech *this_);
+/* end of prototypes */
+
+#endif
+
diff --git a/navit/speech/Makefile.am b/navit/speech/Makefile.am
new file mode 100644
index 000000000..b0ee9f5d0
--- /dev/null
+++ b/navit/speech/Makefile.am
@@ -0,0 +1,4 @@
+SUBDIRS=cmdline
+if SPEECH_SPEECH_DISPATCHER
+ SUBDIRS += speech_dispatcher
+endif
diff --git a/navit/speech/cmdline/Makefile.am b/navit/speech/cmdline/Makefile.am
new file mode 100644
index 000000000..592990c28
--- /dev/null
+++ b/navit/speech/cmdline/Makefile.am
@@ -0,0 +1,4 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=speech_cmdline
+modulespeech_LTLIBRARIES = libspeech_cmdline.la
+libspeech_cmdline_la_SOURCES = speech_cmdline.c
diff --git a/navit/speech/cmdline/speech_cmdline.c b/navit/speech/cmdline/speech_cmdline.c
new file mode 100644
index 000000000..df3b9f127
--- /dev/null
+++ b/navit/speech/cmdline/speech_cmdline.c
@@ -0,0 +1,47 @@
+#include <stdlib.h>
+#include <glib.h>
+#include "config.h"
+#include "plugin.h"
+#include "speech.h"
+
+struct speech_priv {
+ char *cmdline;
+};
+
+static int
+speechd_say(struct speech_priv *this, const char *text)
+{
+ char *cmdline;
+
+ cmdline=g_strdup_printf(this->cmdline, text);
+ return system(cmdline);
+}
+
+static void
+speechd_destroy(struct speech_priv *this) {
+ g_free(this->cmdline);
+ g_free(this);
+}
+
+static struct speech_methods speechd_meth = {
+ speechd_destroy,
+ speechd_say,
+};
+
+static struct speech_priv *
+speechd_new(char *data, struct speech_methods *meth) {
+ struct speech_priv *this;
+ if (! data)
+ return NULL;
+ this=g_new(struct speech_priv,1);
+ this->cmdline=g_strdup(data);
+ *meth=speechd_meth;
+ return this;
+}
+
+
+void
+plugin_init(void)
+{
+ plugin_register_speech_type("cmdline", speechd_new);
+}
diff --git a/navit/speech/speech_dispatcher/Makefile.am b/navit/speech/speech_dispatcher/Makefile.am
new file mode 100644
index 000000000..3980e90f1
--- /dev/null
+++ b/navit/speech/speech_dispatcher/Makefile.am
@@ -0,0 +1,6 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=speech_speech_dispatcher
+modulespeech_LTLIBRARIES = libspeech_speech_dispatcher.la
+libspeech_speech_dispatcher_la_SOURCES = speech_speech_dispatcher.c
+libspeech_speech_dispatcher_la_LIBADD = @SPEECHD_LIBS@
+
diff --git a/navit/speech/speech_dispatcher/speech_speech_dispatcher.c b/navit/speech/speech_dispatcher/speech_speech_dispatcher.c
new file mode 100644
index 000000000..87f5032f6
--- /dev/null
+++ b/navit/speech/speech_dispatcher/speech_speech_dispatcher.c
@@ -0,0 +1,67 @@
+
+/* speechd simple client program
+ * CVS revision: $Id: speech_speech_dispatcher.c,v 1.3 2007-07-08 20:41:35 martin-s Exp $
+ * Author: Tomas Cerha <cerha@brailcom.cz> */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <stdarg.h>
+#include "config.h"
+#include <libspeechd.h>
+#include "plugin.h"
+#include "speech.h"
+
+struct speech_priv {
+ SPDConnection *conn;
+};
+
+static int
+speechd_say(struct speech_priv *this, const char *text) {
+ int err;
+
+ err = spd_sayf(this->conn, SPD_MESSAGE, text);
+ if (err != 1)
+ return 1;
+ return 0;
+}
+
+static void
+speechd_destroy(struct speech_priv *this) {
+ spd_close(this->conn);
+ g_free(this);
+}
+
+static struct speech_methods speechd_meth = {
+ speechd_destroy,
+ speechd_say,
+};
+
+static struct speech_priv *
+speechd_new(char *data, struct speech_methods *meth) {
+ struct speech_priv *this;
+ SPDConnection *conn;
+
+ conn = spd_open("navit","main",NULL,SPD_MODE_SINGLE);
+ if (! conn)
+ return NULL;
+ this=g_new(struct speech_priv,1);
+ if (this) {
+ this->conn=conn;
+ *meth=speechd_meth;
+ spd_set_punctuation(conn, SPD_PUNCT_NONE);
+ }
+ return this;
+}
+
+
+void
+plugin_init(void)
+{
+ plugin_register_speech_type("speech_dispatcher", speechd_new);
+}
diff --git a/navit/tools/gpx2navit_txt/AUTHORS b/navit/tools/gpx2navit_txt/AUTHORS
new file mode 100644
index 000000000..06a46c26d
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/AUTHORS
@@ -0,0 +1,9 @@
+AUTHORS
+========
+Toshihiro Hiraoka <washitoshi at yahoo.co.jp>
+ maintainer
+Petter Reinholdtsen <pere at hungry.com>
+ bug fix, debian package and advices
+
+bodenseepingu bodenseepingu at user.sourceforge.net
+ for modifications towards gpx2navit_txt
diff --git a/navit/tools/gpx2navit_txt/COPYING b/navit/tools/gpx2navit_txt/COPYING
new file mode 100644
index 000000000..514d6c73f
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place - Suite 330, Boston, MA 02111 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
+
+ Appendix: 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 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/navit/tools/gpx2navit_txt/ChangeLog b/navit/tools/gpx2navit_txt/ChangeLog
new file mode 100644
index 000000000..431aa18be
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/ChangeLog
@@ -0,0 +1,21 @@
+0.1 new version gpx2navit_txt
+
+0.69
+ by Petter Reinholdsen
+ - Add configure option "--enable-coverage".
+ - Add few check targets.
+ - Patch for compile warning in DBFWriteAttribute().
+ - Patch for compile warning in createParseData().
+ by Toshihiro Hiraoka
+ - Bug (Debian Bug #292514: Segfaults when called only with -v) fix
+ - Delete few unused functions from utils.c
+
+0.68-1
+======
+ by Petter Reinholdtsen
+ - New debian package gpx2shp_0.68-1_i386.deb.
+ - Update debian releted files.
+ debian/watch, control, changelog
+ - Delete src/configure.ac.
+ - Delete libz check entry from configure.ac.
+
diff --git a/navit/tools/gpx2navit_txt/INSTALL b/navit/tools/gpx2navit_txt/INSTALL
new file mode 100644
index 000000000..b5dbb9e31
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/INSTALL
@@ -0,0 +1,17 @@
+Requirements
+==============
+- proj >ver4.0
+- expat >ver2.0
+- gpsbabel If you want to convert from GPS to shp directory but the
+ future is not stable yet.
+
+Installation
+==============
+It's not special. Just type below like others.
+
+ ./configure
+ make
+ su
+ make install
+
+gpx2navit_txt image will be at /usr/local/bin.
diff --git a/navit/tools/gpx2navit_txt/Makefile.am b/navit/tools/gpx2navit_txt/Makefile.am
new file mode 100644
index 000000000..05f1ce1a0
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/Makefile.am
@@ -0,0 +1,27 @@
+SUBDIRS = src man
+
+EXTRA_DIST = gps2shp pinatest2.gpx debian develop
+
+debian-dist:
+ dpkg-buildpackage -rfakeroot -d -tc -us -uc
+
+CLEANFILES = \
+ pinatest2_wpt.shx \
+ pinatest2_wpt.shp \
+ pinatest2_wpt.dbf \
+ pinatest2_trk.shx \
+ pinatest2_trk.shp \
+ pinatest2_trk.dbf \
+ pinatest2_rte.shx \
+ pinatest2_rte.shp \
+ pinatest2_rte.dbf \
+ pinatest2_meta.txt
+
+GPX2SHP=src/gpx2shp
+check: $(GPX2SHP)
+ $(GPX2SHP) || true
+ $(GPX2SHP) --version
+ $(GPX2SHP) -s pinatest2.gpx
+ $(GPX2SHP) -e pinatest2.gpx
+ $(GPX2SHP) -p pinatest2.gpx
+ $(GPX2SHP) -v pinatest2.gpx > /dev/null
diff --git a/navit/tools/gpx2navit_txt/NEWS b/navit/tools/gpx2navit_txt/NEWS
new file mode 100644
index 000000000..7bd167323
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/NEWS
@@ -0,0 +1,64 @@
+0.69
+====
+ by Petter Reinholdtsen
+ - Add compile check options
+ - Compile warning fixes
+ by Toshihiro Hiraoka
+ - Bug fix
+
+0.68-1
+======
+ by Petter Reinholdtsen
+ - Add debian files
+ by Susumu Murakami
+ - RPM package for Vine 3.1
+
+0.68
+====
+ by Toshihiro Hiraoka
+ - Change XML parser from libxml2 to expat for big file support
+ - Remake almost all strucutes.
+ - Rewrite almost all sources.
+ - Add three path check options --min-points, --min-length and
+ --min-time to reduce the noise.
+ - Add -b, --basix-columns option
+ - Add -g, --gpxline option
+ - Add -f, --fast option
+ - README
+ - AUTHORS
+ - Change comment style to javadoc style.
+ - Structures flow
+ - Error code
+
+0.65-1
+======
+ by Petter Reinholdtsen
+ - Add some debian missing files.
+ - Added config.sub and config.guess.
+ - debian package available now!
+
+ by Toshihiro Hiraoka
+ - Stop to use strange version number.
+
+0.65a
+=====
+ by Petter Reinholdtsen
+ - Add configure script etc.
+ - Get rid of some warnings about loosing the 'const'-ness of the
+ variable.
+ - Remove unused include <math.h>.
+ - Add include to find prototype for geod_set().
+ - Fix handling of output filename, to make sure it handles
+ './foo.gpx' (used to give random filename).
+ - Correct the prototype of closeFiles().
+ - Add files in debian/ to make debian package. This is just a
+ framework, and need more work. The package description and a lot
+ of the support files are from the dh-make package, and should be
+ edited or removed. To build the package, run debuild from the
+ devscripts package.
+ - Solve some memory leaks and complaints.
+
+ by Toshihiro Hiraoka
+ - Restruct directory
+ - Add many prototypes etc.
+
diff --git a/navit/tools/gpx2navit_txt/README b/navit/tools/gpx2navit_txt/README
new file mode 100644
index 000000000..afa985313
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/README
@@ -0,0 +1,117 @@
+==============
+gpx2navit_txt README
+==============
+bodenseepingu
+4/01/2008
+
+What's This
+===========
+ gpx2navit_txt is a converter from GPX file to Navit Text map format
+
+For gpx2navit_txt was the original code from gpx2shp used and modified.
+This is a output of Metro Manila Transit Map Project by JOCV (Japan
+Overseas Cooperation Volunteers) program of JICA (Japan International
+Cooperation Agency in 2004. It is provided you on GPL2.
+
+
+How to Use
+==========
+- Basic
+ There are three types of data on GPX that are waypoint, trkpoint and
+route. gpx2navit_txt converts the data to navit file(s)
+Please try to convert a sample file "pinatest2.gpx" in this archive.
+
+ prompt> gpx2navit_txt pinatest2.gpx
+ prompt> ls
+ pinatest2.gpx (source gpx)
+ pinatest2_meta.txt (meta data may be there)
+
+ You can convert only a certain type of data like only waypoint or
+track point using option '-w' (waypoint), '-t' (trackpoint) or '-r'
+(route).
+
+ prompt> gpx2navit_txt -r pinatest2.gpx
+
+- Convert path data to points and etc
+ As default, track point and route data is converted as a arc data but
+you can convert it other ways using option '-p'(convert as point) and
+'-e' (as edge). The edge file has '_edg' in the filename and the point
+file has '_pnt' in the filename.
+
+ prompt> gpx2navit_txt -p -e pinatest2.gpx
+
+- Statistics
+ If you add '-s' option you can see a conversion summery.
+
+ prompt> gpx2navit_txt -s pinatest2.gpx
+ Track Points:
+ track count: 4
+ point count: 658
+ total length: 156565.627989
+ unconverted: 0( 0.00%)
+ Routes:
+ route count: 1
+ point count: 323
+ total length: 9258.618971
+ unconverted: 0( 0.00%)
+ Waypoints:
+ point count: 118
+
+- Noise reduction
+ gpx2navit_txt has several thresholds to reduct the noise path data. The
+value can set as '--min-points', '--min-length' and '--min-time'. Please
+try a example below.
+
+ prompt> gpx2navit_txt --min-points 6 -s pinatest2.gpx
+ gpx2navit_txt:../pinatest3.gpx:3962 track was not converted because of
+ less then 6 points. (<- this path is not converted because the path
+ has only 5 points)
+ Track Points:
+ track count: 3
+ point count: 653
+ total length: 156439.490642
+ unconverted: 1(25.00%)
+ Routes:
+ route count: 1
+ point count: 323
+ total length: 9258.618971
+ unconverted: 0( 0.00%)
+ Waypoints:
+ point count: 118
+
+
+- Length and time units
+ You can choose any length related units that are supported by proj4
+for attribute table using
+ '--length-unit' (for length column, default: m),
+ '--time-unit' (for time column, default: sec),
+ '--speed-length-unit' (for speed column, default: km),
+ '--speed-time-unit' (for speed column, default: hour) and
+ '--length-ellipsoid' (for length calculation, default: UGS84).
+ You can see the supported units by 'geod -lu' and 'geod -le' command.
+ Supported time unit are 'sec', 'min', 'hour' and 'day'.
+
+- Other futures
+ There are other futures in gpx2navit_txt. Please check the option list using
+
+ gpx2navit_txt --help
+
+Problem or Suggestion
+=====================
+Please let me know about your opinion in English by e-mail.
+ bodenseepingu at users.sourceforge.net
+ navit on sourceforge.net
+ http://gpx2shp.sourceforge.jp/ for original gpx2shp
+ todo for gpx2navit_txt
+
+Acknowledgments
+===============
+NEDA (National Economic and Development Authority) Region IV-B office
+ My generous counter part
+Yoshio Tanaka
+ My project leader gpx2shp
+Petter Reinholdtsen
+ Many support to develop this
+Frank Warmerdam and the team
+ shapelib and proj4
+bodenseepingu for modifications towards navit
diff --git a/navit/tools/gpx2navit_txt/TODO b/navit/tools/gpx2navit_txt/TODO
new file mode 100644
index 000000000..de50135f8
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/TODO
@@ -0,0 +1 @@
+....to be filled
diff --git a/navit/tools/gpx2navit_txt/config.guess b/navit/tools/gpx2navit_txt/config.guess
new file mode 100644
index 000000000..822947132
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/config.guess
@@ -0,0 +1,1453 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+timestamp='2004-11-12'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted 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.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+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@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
+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 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # 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 -q "$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 ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@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
+
+# 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 ;;
+ *) 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 __ELF__ >/dev/null
+ 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 0 ;;
+ amd64:OpenBSD:*:*)
+ echo x86_64-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ cats:OpenBSD:*:*)
+ echo arm-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ luna88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvmeppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips64-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:MirBSD:*:*)
+ echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit 0 ;;
+ 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 0 ;;
+ 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 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit 0;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit 0 ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit 0 ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit 0 ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit 0 ;;
+ 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 0 ;;
+ esac ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(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 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ # 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 0 ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit 0 ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit 0 ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ 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 \
+ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && exit 0
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit 0 ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit 0 ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $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 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ 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 0 ;;
+ *: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
+ $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:[45])
+ 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 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[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
+ # avoid double evaluation of $set_cc_for_build
+ test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 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 && $dummy && exit 0
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ 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 0 ;;
+ 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 0 ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit 0 ;;
+ x86:Interix*:[34]*)
+ echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+ exit 0 ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit 0 ;;
+ 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 0 ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit 0 ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit 0 ;;
+ arm*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-gnu
+ exit 0 ;;
+ crisv32:Linux:*:*)
+ echo crisv32-axis-linux-gnu
+ exit 0 ;;
+ frv:Linux:*:*)
+ echo frv-unknown-linux-gnu
+ exit 0 ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ mips:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips
+ #undef mipsel
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mipsel
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+ ;;
+ mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips64
+ #undef mips64el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mips64el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips64
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+ ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit 0 ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit 0 ;;
+ 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 ld.so.1 >/dev/null
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit 0 ;;
+ 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-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit 0 ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit 0 ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit 0 ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit 0 ;;
+ i*86:Linux:*:*)
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ # Set LC_ALL=C to ensure ld outputs messages in English.
+ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+ | sed -ne '/supported targets:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported targets: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_targets" in
+ elf32-i386)
+ TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+ ;;
+ a.out-i386-linux)
+ echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+ exit 0 ;;
+ coff-i386)
+ echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+ exit 0 ;;
+ "")
+ # Either a pre-BFD a.out linker (linux-gnuoldld) or
+ # one that does not give us useful --help.
+ echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+ exit 0 ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #ifdef __ELF__
+ # ifdef __GLIBC__
+ # if __GLIBC__ >= 2
+ LIBC=gnu
+ # else
+ LIBC=gnulibc1
+ # endif
+ # else
+ LIBC=gnulibc1
+ # endif
+ #else
+ #ifdef __INTEL_COMPILER
+ LIBC=gnu
+ #else
+ LIBC=gnuaout
+ #endif
+ #endif
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+ test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+ ;;
+ 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 0 ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit 0 ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit 0 ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit 0 ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit 0 ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit 0 ;;
+ 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 0 ;;
+ i*86:*:5:[78]*)
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit 0 ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|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 0 ;;
+ 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 i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit 0 ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit 0 ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 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 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ 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-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
+ *86) UNAME_PROCESSOR=i686 ;;
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit 0 ;;
+ *: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 0 ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit 0 ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit 0 ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit 0 ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit 0 ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit 0 ;;
+ *: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}-unknown-plan9
+ exit 0 ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit 0 ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit 0 ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit 0 ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit 0 ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit 0 ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit 0 ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit 0 ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms && exit 0 ;;
+ I*) echo ia64-dec-vms && exit 0 ;;
+ V*) echo vax-dec-vms && exit 0 ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+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"); 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 && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+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
+
+ ftp://ftp.gnu.org/pub/gnu/config/
+
+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@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/navit/tools/gpx2navit_txt/config.sub b/navit/tools/gpx2navit_txt/config.sub
new file mode 100644
index 000000000..0f84ac2c5
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/config.sub
@@ -0,0 +1,1566 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+timestamp='2004-11-30'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted 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.
+
+# 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@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+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 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # 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 0;;
+
+ * )
+ 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-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-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)
+ os=
+ basic_machine=$1
+ ;;
+ -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
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -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 \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | m32r | m32rle | m68000 | m68k | m88k | mcore \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64vr | mips64vrel \
+ | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | msp430 \
+ | ns16k | ns32k \
+ | openrisc | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+ | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \
+ | strongarm \
+ | tahoe | thumb | tic4x | tic80 | tron \
+ | v850 | v850e \
+ | we32k \
+ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+ | z8k)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+
+ # 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-* \
+ | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | mcore-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | msp430-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* \
+ | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tron-* \
+ | v850-* | v850e-* | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+ | xstormy16-* | xtensa-* \
+ | ymp-* \
+ | z8k-*)
+ ;;
+ # 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
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ 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
+ ;;
+ cr16c)
+ basic_machine=cr16c-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
+ ;;
+ 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
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ 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
+ ;;
+ 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
+ ;;
+ or32 | or32-*)
+ basic_machine=or32-unknown
+ os=-coff
+ ;;
+ 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
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ 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
+ ;;
+ 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
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ 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
+ ;;
+ 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
+ ;;
+ 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
+ ;;
+ sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b)
+ 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.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+ | -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* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -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*)
+ # 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* \
+ | -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
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-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
+ ;;
+ 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
+ ;;
+ *-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
+ ;;
+ -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 0
+
+# 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/navit/tools/gpx2navit_txt/configure.ac b/navit/tools/gpx2navit_txt/configure.ac
new file mode 100644
index 000000000..c34753222
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/configure.ac
@@ -0,0 +1,47 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.57)
+AC_INIT(gpx2shp, 0.69, kogame at gmail.com)
+AM_INIT_AUTOMAKE(gpx2shp, 0.69)
+AC_CONFIG_SRCDIR(src/main.c)
+AM_CONFIG_HEADER(src/config.h)
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_MAKE_SET
+
+# Ask GCC to give us heaps of warnings
+if eval "test x$GCC = xyes"; then
+ CFLAGS="$CFLAGS -W -Wall -Wcast-align -Wcast-qual"
+ CFLAGS="$CFLAGS -Wmissing-declarations -Wmissing-prototypes"
+ CFLAGS="$CFLAGS -Wstrict-prototypes -Wpointer-arith -Wreturn-type"
+ AC_SUBST(CFLAGS)
+fi
+
+AC_ARG_ENABLE(coverage,
+[ --enable-coverage compile with coverage testing enabled],
+ CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage")
+
+# Checks for libraries.
+AC_CHECK_LIB(proj, pj_param)
+AC_CHECK_LIB(proj, pj_init, [], [ echo "Error you need lib proj4" && exit -1])
+AC_CHECK_LIB(expat, XML_SetUserData)
+AC_CHECK_LIB(m, cos)
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS(limits.h stdlib.h string.h unistd.h)
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_STRUCT_TM
+
+# Checks for library functions.
+AC_FUNC_MALLOC
+AC_FUNC_MKTIME
+AC_FUNC_REALLOC
+AC_CHECK_FUNCS(memset sqrt)
+
+AC_CONFIG_FILES(Makefile src/Makefile man/Makefile)
+AC_OUTPUT
diff --git a/navit/tools/gpx2navit_txt/depcomp b/navit/tools/gpx2navit_txt/depcomp
new file mode 100755
index 000000000..807b991f4
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/depcomp
@@ -0,0 +1,423 @@
+#! /bin/sh
+
+# depcomp - compile a program generating dependencies as side-effects
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# 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@dcc.unicamp.br>.
+
+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
+# `libtool' can also be set to `yes' or `no'.
+
+if test -z "$depfile"; then
+ base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
+ dir=`echo "$object" | sed 's,/.*$,/,'`
+ if test "$dir" = "$object"; then
+ dir=
+ fi
+ # FIXME: should be _deps on DOS.
+ depfile="$dir.deps/$base"
+fi
+
+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
+
+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.
+ "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+ 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. 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.
+ stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
+ tmpdepfile="$stripped.u"
+ outname="$stripped.o"
+ if test "$libtool" = yes; then
+ "$@" -Wc,-M
+ else
+ "$@" -M
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+
+ 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,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+ sed -e "s,^$outname: \(.*\)$,\1:," < "$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"
+ ;;
+
+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
+ tmpdepfile1="$dir.libs/$base.lo.d"
+ tmpdepfile2="$dir.libs/$base.d"
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1="$dir$base.o.d"
+ tmpdepfile2="$dir$base.d"
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile1"; then
+ tmpdepfile="$tmpdepfile1"
+ else
+ tmpdepfile="$tmpdepfile2"
+ fi
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a space and a tab 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 proprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'. We will use -o /dev/null later,
+ # however we can't do the remplacement now because
+ # `-o $object' might simply not be used
+ 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
+ "$@" -o /dev/null $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 $?
+ # X makedepend
+ shift
+ cleared=no
+ for arg in "$@"; do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ -*)
+ ;;
+ *)
+ 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 proprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--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 '/^# [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 proprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ "$@" || exit $?
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/navit/tools/gpx2navit_txt/develop/structures.gif b/navit/tools/gpx2navit_txt/develop/structures.gif
new file mode 100644
index 000000000..ba0c18aba
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/develop/structures.gif
Binary files differ
diff --git a/navit/tools/gpx2navit_txt/install-sh b/navit/tools/gpx2navit_txt/install-sh
new file mode 100755
index 000000000..11870f1b0
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/install-sh
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ :
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=$mkdirprog
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f "$src" ] || [ -d "$src" ]
+ then
+ :
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ :
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ :
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+ '
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ :
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ :
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/navit/tools/gpx2navit_txt/man/Makefile.am b/navit/tools/gpx2navit_txt/man/Makefile.am
new file mode 100644
index 000000000..71f0f055d
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/man/Makefile.am
@@ -0,0 +1,2 @@
+man_MANS = gpx2navit_txt.1
+EXTRA_DIST = $(man_MANS)
diff --git a/navit/tools/gpx2navit_txt/man/gpx2navit_txt.1 b/navit/tools/gpx2navit_txt/man/gpx2navit_txt.1
new file mode 100644
index 000000000..26edd281f
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/man/gpx2navit_txt.1
@@ -0,0 +1,103 @@
+.\"
+.TH "gpx2navit_txt" "1" "0.1" "bodenseepingu" ""
+.SH "NAME"
+gpx2navit_txt \- Convert GPX files to navit txt files
+.SH "SYNOPSIS"
+gpx2navit_txt [options] [\-o output file] gpxfile
+.SH "DESCRIPTION"
+gpx2navit_txt is a converter from GPX file to navit txt file
+The original gpx2shp was used for that program.
+This is a output of Metro Manila Transit Map Project by JOCV (Japan Overseas Cooperation Volunteers) program of JICA (Japan International Cooperation Agency) in 2004. It is provided you on GPL2.
+.SH "OPTIONS"
+.TP
+.B \-o, \-\-output
+Sets output basename. The default is (source file name) \- (extention name)
+.TP
+.B \-w, \-\-waypoints
+Converts only waypoints data from a gpx file.
+.TP
+.B \-t, \-\-trackpoints
+Converts only trackpoints data from a gpx file.
+.TP
+.B \-r, \-\-routes
+Converts only routes data from a gpx file.
+.TP
+.B \-a, \-\-all
+Converts all types of data from a gpx file.(default)
+.TP
+.B \-e, \-\-as\-edge
+Makes a separated output by each edges.
+.TP
+.B \-p, \-\-as\-point
+Makes a separated output by each points.
+.TP
+.B \-s, \-\-stats
+Shows simple statistics of the outputs.
+.TP
+.B \-b, \-\-basic\-columns
+Stores only basic data as attribures to reduce memory and storage usage. (ele, name, cmt, type, time, fix, sym and number).
+.TP
+.B \-L, \-\-no\-length
+Removes length column from a waypoint or trackpoint attribute table.
+.TP
+.B \-S, \-\-no\-speed
+Removes speed column from a waypoint or trackpoint attribute table.
+.TP
+.B \-T, \-\-no\-time
+Removes time column from an attribute table.
+.TP
+.B \-g, \-\-gpxline
+Adds line number of GPX file as attribures.
+.TP
+.B \-f, \-\-fast
+Make it faster without any checks.
+.TP
+.B \-3, \-\-3d
+Converts data using 3d format. (It's not compatible for Arcview 3.x.)
+.TP
+.B \-\-min\-points
+Sets path minimum points to convert for noise reduction. Default is 2.
+.TP
+.B \-\-min\-length
+Sets path minimum length to convert for noise reduction. Default is 0.
+.TP
+.B \-\-min\-time
+Sets path minimum time period to convert for noise reduction. Default is 0.
+.TP
+.B \-\-length\-unit
+Sets length unit from m,km,feet,mi and etc. The default is m. You can see the unit list from "geod \-lu" command.
+.TP
+.B \-\-time\-unit
+Sets time unit. The default is sec. You can set from day, hour, min and sec.
+.TP
+.B \-\-speed\-length\-unit
+Sets length unit for speed. The default is km. You can see the unit list from "geod \-lu" command.
+.TP
+.B \-\-speed\-time\-unit
+Sets time unit for speed calulation. Default is hour. You can set from day, hour, min and sec.
+.TP
+.B \-\-length\-ellipsoid
+Sets length ellipsoid like UGS84, clrk66. The default is UGS84. You can see the unit list from "geod \-le" command.
+.TP
+.B \-v, \-\-verbose
+Gives many messages.
+.TP
+.B \-\-version
+Shows version.
+.TP
+.B \-h, \-\-help
+Shows this list.
+.SH "AUTHORS"
+Toshihiro Hiraoka
+.br
+Petter Reinholdtsen
+
+.SH "BUGS or OPINIONS"
+Please e\-mail your bugs or opinions to
+.br
+washitoshi at yahoo.co.jp
+
+.SH "SEE ALSO"
+gpx2shp / gps2shp homepage
+.br
+http://gpx2shp.sourceforge.jp
diff --git a/navit/tools/gpx2navit_txt/missing b/navit/tools/gpx2navit_txt/missing
new file mode 100755
index 000000000..6a37006e8
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/missing
@@ -0,0 +1,336 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# 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=:
+
+# 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
+
+case "$1" in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --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'
+ 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]"
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing 0.4 - GNU automake"
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+ aclocal*)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. 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)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. 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)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. 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*)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. 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)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+ system. You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1Help2man' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+ test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+ 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' is missing on your system. 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 [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f y.tab.h ]; then
+ echo >y.tab.h
+ fi
+ if [ ! -f y.tab.c ]; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex|flex)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. 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 [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f lex.yy.c ]; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. 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 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+ fi
+ if [ -f "$file" ]; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit 1
+ fi
+ ;;
+
+ makeinfo)
+ if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
+ # We have makeinfo, but it failed.
+ exit 1
+ fi
+
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. 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."
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+ fi
+ touch $file
+ ;;
+
+ tar)
+ shift
+ if test -n "$run"; then
+ echo 1>&2 "ERROR: \`tar' requires --run"
+ exit 1
+ fi
+
+ # 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 you do not seem to have it handy on your
+ system. You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequirements for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/navit/tools/gpx2navit_txt/mkinstalldirs b/navit/tools/gpx2navit_txt/mkinstalldirs
new file mode 100755
index 000000000..8ab885ec9
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/mkinstalldirs
@@ -0,0 +1,99 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
+
+# process command line arguments
+while test $# -gt 0 ; do
+ case "${1}" in
+ -h | --help | --h* ) # -h for help
+ echo "${usage}" 1>&2; exit 0 ;;
+ -m ) # -m PERM arg
+ shift
+ test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
+ dirmode="${1}"
+ shift ;;
+ -- ) shift; break ;; # stop option processing
+ -* ) echo "${usage}" 1>&2; exit 1 ;; # unknown option
+ * ) break ;; # first non-opt arg
+ esac
+done
+
+for file
+do
+ if test -d "$file"; then
+ shift
+ else
+ break
+ fi
+done
+
+case $# in
+0) exit 0 ;;
+esac
+
+case $dirmode in
+'')
+ if mkdir -p -- . 2>/dev/null; then
+ echo "mkdir -p -- $*"
+ exec mkdir -p -- "$@"
+ fi ;;
+*)
+ if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
+ echo "mkdir -m $dirmode -p -- $*"
+ exec mkdir -m "$dirmode" -p -- "$@"
+ fi ;;
+esac
+
+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
+ 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: 3
+# End:
+# mkinstalldirs ends here
diff --git a/navit/tools/gpx2navit_txt/pinatest2.gpx b/navit/tools/gpx2navit_txt/pinatest2.gpx
new file mode 100644
index 000000000..3d99f4064
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/pinatest2.gpx
@@ -0,0 +1,4790 @@
+<?xml version="1.0"?>
+<gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="Toshihiro Hiraoka" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
+ <metadata>
+<name>Manila to Mt. Pinatubo</name>
+<copyright>Toshihiro Hiraoka</copyright>
+<author>Toshihiro Hiraoka</author>
+<keyword>Manila Mt. Pinatubo gpx2shp</keyword>
+<link>http://gpx2shp.sourceforge.jp</link>
+<description>This is test data for gpx2shp.</description>
+ <time>2004-12-29T08:23:55Z</time>
+ </metadata>
+<trk>
+<name>07-SEP-04</name>
+<number>1</number>
+<trkseg>
+<trkpt lat="14.585381" lon="121.056118">
+<ele>42.916016</ele>
+<time>2004-09-06T15:35:56Z</time>
+</trkpt>
+<trkpt lat="14.595809" lon="121.059465">
+<ele>48.203369</ele>
+<time>2004-09-06T15:37:14Z</time>
+</trkpt>
+<trkpt lat="14.598942" lon="121.059852">
+<ele>49.645264</ele>
+<time>2004-09-06T15:37:39Z</time>
+</trkpt>
+<trkpt lat="14.602568" lon="121.058972">
+<ele>51.567871</ele>
+<time>2004-09-06T15:38:06Z</time>
+</trkpt>
+<trkpt lat="14.604285" lon="121.058199">
+<ele>48.683960</ele>
+<time>2004-09-06T15:38:21Z</time>
+</trkpt>
+<trkpt lat="14.606109" lon="121.057341">
+<ele>51.087158</ele>
+<time>2004-09-06T15:38:38Z</time>
+</trkpt>
+<trkpt lat="14.608727" lon="121.056161">
+<ele>46.280640</ele>
+<time>2004-09-06T15:39:01Z</time>
+</trkpt>
+<trkpt lat="14.610808" lon="121.055152">
+<ele>52.529175</ele>
+<time>2004-09-06T15:39:18Z</time>
+</trkpt>
+<trkpt lat="14.630678" lon="121.046162">
+<ele>39.551270</ele>
+<time>2004-09-06T15:42:59Z</time>
+</trkpt>
+<trkpt lat="14.632244" lon="121.045668">
+<ele>47.241821</ele>
+<time>2004-09-06T15:43:45Z</time>
+</trkpt>
+<trkpt lat="14.632373" lon="121.046140">
+<ele>46.280640</ele>
+<time>2004-09-06T15:43:53Z</time>
+</trkpt>
+<trkpt lat="14.633574" lon="121.046312">
+<ele>48.683960</ele>
+<time>2004-09-06T15:44:40Z</time>
+</trkpt>
+<trkpt lat="14.637222" lon="121.042707">
+<ele>69.352295</ele>
+<time>2004-09-07T06:03:25Z</time>
+</trkpt>
+<trkpt lat="14.637179" lon="121.042664">
+<ele>54.451782</ele>
+<time>2004-09-07T06:05:36Z</time>
+</trkpt>
+<trkpt lat="14.637437" lon="121.042578">
+<ele>53.009766</ele>
+<time>2004-09-07T06:05:57Z</time>
+</trkpt>
+<trkpt lat="14.637587" lon="121.042728">
+<ele>52.529175</ele>
+<time>2004-09-07T06:06:14Z</time>
+</trkpt>
+<trkpt lat="14.638424" lon="121.044037">
+<ele>52.048584</ele>
+<time>2004-09-07T06:08:18Z</time>
+</trkpt>
+<trkpt lat="14.638982" lon="121.044188">
+<ele>50.125977</ele>
+<time>2004-09-07T06:09:31Z</time>
+</trkpt>
+<trkpt lat="14.640076" lon="121.043093">
+<ele>48.203369</ele>
+<time>2004-09-07T06:10:47Z</time>
+</trkpt>
+<trkpt lat="14.640591" lon="121.043158">
+<ele>49.645264</ele>
+<time>2004-09-07T06:12:27Z</time>
+</trkpt>
+<trkpt lat="14.639797" lon="121.043286">
+<ele>48.683960</ele>
+<time>2004-09-07T06:16:48Z</time>
+</trkpt>
+<trkpt lat="14.639003" lon="121.043801">
+<ele>50.606567</ele>
+<time>2004-09-07T06:18:13Z</time>
+</trkpt>
+<trkpt lat="14.638467" lon="121.043994">
+<ele>48.683960</ele>
+<time>2004-09-07T06:19:05Z</time>
+</trkpt>
+<trkpt lat="14.637415" lon="121.042600">
+<ele>52.529175</ele>
+<time>2004-09-07T06:21:33Z</time>
+</trkpt>
+<trkpt lat="14.636300" lon="121.043329">
+<ele>53.490479</ele>
+<time>2004-09-07T06:23:19Z</time>
+</trkpt>
+<trkpt lat="14.633617" lon="121.046076">
+<ele>48.203369</ele>
+<time>2004-09-07T09:36:53Z</time>
+</trkpt>
+<trkpt lat="14.633617" lon="121.046526">
+<ele>49.645264</ele>
+<time>2004-09-07T09:37:26Z</time>
+</trkpt>
+<trkpt lat="14.634218" lon="121.046612">
+<ele>50.125977</ele>
+<time>2004-09-07T09:38:15Z</time>
+</trkpt>
+<trkpt lat="14.634390" lon="121.045625">
+<ele>47.241821</ele>
+<time>2004-09-07T09:39:43Z</time>
+</trkpt>
+<trkpt lat="14.633360" lon="121.045196">
+<ele>44.838623</ele>
+<time>2004-09-07T09:41:07Z</time>
+</trkpt>
+<trkpt lat="14.632695" lon="121.044123">
+<ele>47.241821</ele>
+<time>2004-09-07T09:43:22Z</time>
+</trkpt>
+<trkpt lat="14.624047" lon="121.049724">
+<ele>34.264160</ele>
+<time>2004-09-07T12:47:09Z</time>
+</trkpt>
+<trkpt lat="14.623339" lon="121.049616">
+<ele>25.131714</ele>
+<time>2004-09-07T12:51:01Z</time>
+</trkpt>
+<trkpt lat="14.629004" lon="121.047277">
+<ele>25.131714</ele>
+<time>2004-09-07T12:51:05Z</time>
+</trkpt>
+<trkpt lat="14.629219" lon="121.046762">
+<ele>25.612305</ele>
+<time>2004-09-07T12:51:13Z</time>
+</trkpt>
+<trkpt lat="14.632995" lon="121.045239">
+<ele>39.551270</ele>
+<time>2004-09-07T12:51:52Z</time>
+</trkpt>
+<trkpt lat="14.636257" lon="121.043308">
+<ele>34.264160</ele>
+<time>2004-09-07T12:52:26Z</time>
+</trkpt>
+<trkpt lat="14.645784" lon="121.036763">
+<ele>34.264160</ele>
+<time>2004-09-07T12:54:07Z</time>
+</trkpt>
+<trkpt lat="14.651492" lon="121.033201">
+<ele>28.015503</ele>
+<time>2004-09-07T12:55:29Z</time>
+</trkpt>
+<trkpt lat="14.651191" lon="121.033094">
+<ele>28.496216</ele>
+<time>2004-09-07T12:56:22Z</time>
+</trkpt>
+<trkpt lat="14.655526" lon="121.030240">
+<ele>26.092896</ele>
+<time>2004-09-07T12:59:59Z</time>
+</trkpt>
+<trkpt lat="14.656255" lon="121.028244">
+<ele>25.612305</ele>
+<time>2004-09-07T13:01:05Z</time>
+</trkpt>
+<trkpt lat="14.656920" lon="121.028695">
+<ele>26.573608</ele>
+<time>2004-09-07T13:01:27Z</time>
+</trkpt>
+<trkpt lat="14.656448" lon="121.027966">
+<ele>26.573608</ele>
+<time>2004-09-07T13:06:14Z</time>
+</trkpt>
+<trkpt lat="14.656942" lon="121.025476">
+<ele>24.170288</ele>
+<time>2004-09-07T13:06:59Z</time>
+</trkpt>
+<trkpt lat="14.657843" lon="121.020477">
+<ele>15.037720</ele>
+<time>2004-09-07T13:09:56Z</time>
+</trkpt>
+<trkpt lat="14.658144" lon="121.020391">
+<ele>15.518433</ele>
+<time>2004-09-07T13:10:00Z</time>
+</trkpt>
+<trkpt lat="14.657779" lon="121.020477">
+<ele>15.999023</ele>
+<time>2004-09-07T13:10:22Z</time>
+</trkpt>
+<trkpt lat="14.657822" lon="121.019275">
+<ele>9.269897</ele>
+<time>2004-09-07T13:12:39Z</time>
+</trkpt>
+<trkpt lat="14.657586" lon="121.009920">
+<ele>17.441162</ele>
+<time>2004-09-07T13:14:54Z</time>
+</trkpt>
+<trkpt lat="14.657156" lon="120.984557">
+<ele>13.595825</ele>
+<time>2004-09-07T13:18:26Z</time>
+</trkpt>
+<trkpt lat="14.657350" lon="120.983698">
+<ele>13.115112</ele>
+<time>2004-09-07T13:18:44Z</time>
+</trkpt>
+<trkpt lat="14.655440" lon="120.984449">
+<ele>13.595825</ele>
+<time>2004-09-07T13:19:43Z</time>
+</trkpt>
+<trkpt lat="14.655933" lon="120.983613">
+<ele>15.518433</ele>
+<time>2004-09-07T13:31:26Z</time>
+</trkpt>
+<trkpt lat="14.655633" lon="120.983505">
+<ele>13.115112</ele>
+<time>2004-09-07T13:31:56Z</time>
+</trkpt>
+<trkpt lat="14.655633" lon="120.983484">
+<ele>5.905273</ele>
+<time>2004-09-07T13:32:07Z</time>
+</trkpt>
+<trkpt lat="14.655912" lon="120.983698">
+<ele>6.385864</ele>
+<time>2004-09-07T13:35:30Z</time>
+</trkpt>
+<trkpt lat="14.655762" lon="120.983140">
+<ele>8.308594</ele>
+<time>2004-09-07T13:38:04Z</time>
+</trkpt>
+<trkpt lat="14.655590" lon="120.981896">
+<ele>5.424561</ele>
+<time>2004-09-07T13:39:07Z</time>
+</trkpt>
+<trkpt lat="14.656706" lon="120.981231">
+<ele>4.943848</ele>
+<time>2004-09-07T13:39:08Z</time>
+</trkpt>
+<trkpt lat="14.657135" lon="120.982304">
+<ele>11.192505</ele>
+<time>2004-09-07T13:39:24Z</time>
+</trkpt>
+<trkpt lat="14.657028" lon="120.983655">
+<ele>12.634399</ele>
+<time>2004-09-07T13:39:50Z</time>
+</trkpt>
+<trkpt lat="14.656749" lon="120.984600">
+<ele>11.673218</ele>
+<time>2004-09-07T13:40:21Z</time>
+</trkpt>
+<trkpt lat="14.657006" lon="120.989149">
+<ele>15.999023</ele>
+<time>2004-09-07T13:41:24Z</time>
+</trkpt>
+<trkpt lat="14.657071" lon="120.990865">
+<ele>12.153809</ele>
+<time>2004-09-07T13:41:47Z</time>
+</trkpt>
+<trkpt lat="14.657114" lon="120.993268">
+<ele>21.286377</ele>
+<time>2004-09-07T13:42:04Z</time>
+</trkpt>
+<trkpt lat="14.657199" lon="120.999985">
+<ele>17.441162</ele>
+<time>2004-09-07T13:43:09Z</time>
+</trkpt>
+<trkpt lat="14.657092" lon="121.000950">
+<ele>15.518433</ele>
+<time>2004-09-07T13:43:24Z</time>
+</trkpt>
+<trkpt lat="14.656620" lon="121.000907">
+<ele>14.557007</ele>
+<time>2004-09-07T13:43:32Z</time>
+</trkpt>
+<trkpt lat="14.656234" lon="121.000628">
+<ele>12.634399</ele>
+<time>2004-09-07T13:43:43Z</time>
+</trkpt>
+<trkpt lat="14.656298" lon="121.000242">
+<ele>13.115112</ele>
+<time>2004-09-07T13:44:05Z</time>
+</trkpt>
+<trkpt lat="14.657629" lon="121.000350">
+<ele>11.192505</ele>
+<time>2004-09-07T13:44:42Z</time>
+</trkpt>
+<trkpt lat="14.666641" lon="121.000328">
+<ele>22.247559</ele>
+<time>2004-09-07T13:48:40Z</time>
+</trkpt>
+<trkpt lat="14.667950" lon="121.000371">
+<ele>20.324951</ele>
+<time>2004-09-07T13:48:56Z</time>
+</trkpt>
+<trkpt lat="14.671898" lon="121.000693">
+<ele>27.534912</ele>
+<time>2004-09-07T13:52:48Z</time>
+</trkpt>
+<trkpt lat="14.678614" lon="121.000371">
+<ele>11.673218</ele>
+<time>2004-09-07T13:54:13Z</time>
+</trkpt>
+<trkpt lat="14.687476" lon="121.000907">
+<ele>10.711792</ele>
+<time>2004-09-07T13:55:15Z</time>
+</trkpt>
+<trkpt lat="14.689107" lon="121.000950">
+<ele>17.921753</ele>
+<time>2004-09-07T13:55:34Z</time>
+</trkpt>
+<trkpt lat="14.694450" lon="121.000178">
+<ele>15.037720</ele>
+<time>2004-09-07T13:56:30Z</time>
+</trkpt>
+<trkpt lat="14.702561" lon="120.996058">
+<ele>18.883057</ele>
+<time>2004-09-07T13:57:48Z</time>
+</trkpt>
+<trkpt lat="14.708569" lon="120.992861">
+<ele>10.231201</ele>
+<time>2004-09-07T13:58:45Z</time>
+</trkpt>
+<trkpt lat="14.716787" lon="120.988290">
+<ele>24.170288</ele>
+<time>2004-09-07T13:59:54Z</time>
+</trkpt>
+<trkpt lat="14.719920" lon="120.986595">
+<ele>12.153809</ele>
+<time>2004-09-07T14:00:19Z</time>
+</trkpt>
+<trkpt lat="14.722559" lon="120.985200">
+<ele>14.557007</ele>
+<time>2004-09-07T14:00:40Z</time>
+</trkpt>
+<trkpt lat="14.726958" lon="120.982926">
+<ele>14.076416</ele>
+<time>2004-09-07T14:01:07Z</time>
+</trkpt>
+<trkpt lat="14.730091" lon="120.981209">
+<ele>11.192505</ele>
+<time>2004-09-07T14:01:27Z</time>
+</trkpt>
+<trkpt lat="14.749510" lon="120.970716">
+<ele>22.728271</ele>
+<time>2004-09-07T14:03:10Z</time>
+</trkpt>
+<trkpt lat="14.754295" lon="120.968163">
+<ele>10.711792</ele>
+<time>2004-09-07T14:03:36Z</time>
+</trkpt>
+<trkpt lat="14.762986" lon="120.963421">
+<ele>22.247559</ele>
+<time>2004-09-07T14:04:31Z</time>
+</trkpt>
+<trkpt lat="14.771633" lon="120.958786">
+<ele>10.711792</ele>
+<time>2004-09-07T14:05:15Z</time>
+</trkpt>
+<trkpt lat="14.787319" lon="120.950353">
+<ele>22.247559</ele>
+<time>2004-09-07T14:06:46Z</time>
+</trkpt>
+<trkpt lat="14.797447" lon="120.944839">
+<ele>10.231201</ele>
+<time>2004-09-07T14:07:39Z</time>
+</trkpt>
+<trkpt lat="14.799614" lon="120.943723">
+<ele>8.308594</ele>
+<time>2004-09-07T14:07:52Z</time>
+</trkpt>
+<trkpt lat="14.802597" lon="120.943186">
+<ele>8.308594</ele>
+<time>2004-09-07T14:08:12Z</time>
+</trkpt>
+<trkpt lat="14.803669" lon="120.942543">
+<ele>9.750610</ele>
+<time>2004-09-07T14:08:20Z</time>
+</trkpt>
+<trkpt lat="14.805365" lon="120.940611">
+<ele>9.269897</ele>
+<time>2004-09-07T14:08:36Z</time>
+</trkpt>
+<trkpt lat="14.808626" lon="120.938745">
+<ele>13.595825</ele>
+<time>2004-09-07T14:08:56Z</time>
+</trkpt>
+<trkpt lat="14.815836" lon="120.934582">
+<ele>7.827881</ele>
+<time>2004-09-07T14:09:39Z</time>
+</trkpt>
+<trkpt lat="14.817102" lon="120.933187">
+<ele>7.827881</ele>
+<time>2004-09-07T14:09:51Z</time>
+</trkpt>
+<trkpt lat="14.818990" lon="120.929883">
+<ele>7.347168</ele>
+<time>2004-09-07T14:10:14Z</time>
+</trkpt>
+<trkpt lat="14.826264" lon="120.916150">
+<ele>14.076416</ele>
+<time>2004-09-07T14:11:29Z</time>
+</trkpt>
+<trkpt lat="14.831479" lon="120.906429">
+<ele>7.827881</ele>
+<time>2004-09-07T14:12:22Z</time>
+</trkpt>
+<trkpt lat="14.833839" lon="120.902760">
+<ele>10.711792</ele>
+<time>2004-09-07T14:12:51Z</time>
+</trkpt>
+<trkpt lat="14.833324" lon="120.899284">
+<ele>15.037720</ele>
+<time>2004-09-07T14:13:15Z</time>
+</trkpt>
+<trkpt lat="14.833410" lon="120.889478">
+<ele>16.479736</ele>
+<time>2004-09-07T14:14:01Z</time>
+</trkpt>
+<trkpt lat="14.836650" lon="120.872955">
+<ele>17.441162</ele>
+<time>2004-09-07T14:15:13Z</time>
+</trkpt>
+<trkpt lat="14.837337" lon="120.867591">
+<ele>9.269897</ele>
+<time>2004-09-07T14:18:15Z</time>
+</trkpt>
+<trkpt lat="14.837852" lon="120.866561">
+<ele>8.308594</ele>
+<time>2004-09-07T14:18:38Z</time>
+</trkpt>
+<trkpt lat="14.839118" lon="120.860767">
+<ele>9.269897</ele>
+<time>2004-09-07T14:20:34Z</time>
+</trkpt>
+<trkpt lat="14.839053" lon="120.860360">
+<ele>9.269897</ele>
+<time>2004-09-07T14:21:15Z</time>
+</trkpt>
+<trkpt lat="14.838860" lon="120.860660">
+<ele>10.231201</ele>
+<time>2004-09-07T14:21:30Z</time>
+</trkpt>
+<trkpt lat="14.838710" lon="120.861325">
+<ele>9.269897</ele>
+<time>2004-09-07T14:21:42Z</time>
+</trkpt>
+<trkpt lat="14.837701" lon="120.861926">
+<ele>12.153809</ele>
+<time>2004-09-07T14:22:02Z</time>
+</trkpt>
+<trkpt lat="14.837379" lon="120.862892">
+<ele>13.115112</ele>
+<time>2004-09-07T14:22:36Z</time>
+</trkpt>
+<trkpt lat="14.838173" lon="120.862656">
+<ele>16.479736</ele>
+<time>2004-09-07T14:23:19Z</time>
+</trkpt>
+<trkpt lat="14.845898" lon="120.859780">
+<ele>8.308594</ele>
+<time>2004-09-07T14:25:33Z</time>
+</trkpt>
+<trkpt lat="14.847894" lon="120.859609">
+<ele>13.115112</ele>
+<time>2004-09-07T14:26:00Z</time>
+</trkpt>
+<trkpt lat="14.853001" lon="120.860939">
+<ele>15.037720</ele>
+<time>2004-09-07T14:26:40Z</time>
+</trkpt>
+<trkpt lat="14.853837" lon="120.861003">
+<ele>9.750610</ele>
+<time>2004-09-07T14:26:52Z</time>
+</trkpt>
+<trkpt lat="14.856155" lon="120.859973">
+<ele>14.557007</ele>
+<time>2004-09-07T14:27:36Z</time>
+</trkpt>
+<trkpt lat="14.860318" lon="120.858858">
+<ele>10.231201</ele>
+<time>2004-09-07T14:28:17Z</time>
+</trkpt>
+<trkpt lat="14.861755" lon="120.858729">
+<ele>17.921753</ele>
+<time>2004-09-07T14:28:38Z</time>
+</trkpt>
+<trkpt lat="14.863901" lon="120.859437">
+<ele>8.789185</ele>
+<time>2004-09-07T14:29:22Z</time>
+</trkpt>
+<trkpt lat="14.862356" lon="120.859716">
+<ele>12.153809</ele>
+<time>2004-09-07T14:30:04Z</time>
+</trkpt>
+<trkpt lat="14.864266" lon="120.856261">
+<ele>18.402344</ele>
+<time>2004-09-07T14:30:35Z</time>
+</trkpt>
+<trkpt lat="14.867806" lon="120.851369">
+<ele>21.286377</ele>
+<time>2004-09-07T14:31:06Z</time>
+</trkpt>
+<trkpt lat="14.872677" lon="120.845790">
+<ele>20.324951</ele>
+<time>2004-09-07T14:31:39Z</time>
+</trkpt>
+<trkpt lat="14.878299" lon="120.840554">
+<ele>19.844360</ele>
+<time>2004-09-07T14:32:16Z</time>
+</trkpt>
+<trkpt lat="14.880359" lon="120.838838">
+<ele>25.131714</ele>
+<time>2004-09-07T14:32:28Z</time>
+</trkpt>
+<trkpt lat="14.888406" lon="120.832958">
+<ele>19.844360</ele>
+<time>2004-09-07T14:33:14Z</time>
+</trkpt>
+<trkpt lat="14.894006" lon="120.829332">
+<ele>22.728271</ele>
+<time>2004-09-07T14:33:46Z</time>
+</trkpt>
+<trkpt lat="14.902847" lon="120.822079">
+<ele>23.689575</ele>
+<time>2004-09-07T14:34:36Z</time>
+</trkpt>
+<trkpt lat="14.906366" lon="120.818989">
+<ele>15.999023</ele>
+<time>2004-09-07T14:35:03Z</time>
+</trkpt>
+<trkpt lat="14.908404" lon="120.818152">
+<ele>9.269897</ele>
+<time>2004-09-07T14:36:31Z</time>
+</trkpt>
+<trkpt lat="14.904649" lon="120.776439">
+<ele>13.115112</ele>
+<time>2004-09-07T14:45:12Z</time>
+</trkpt>
+<trkpt lat="14.905465" lon="120.773413">
+<ele>9.269897</ele>
+<time>2004-09-07T14:46:20Z</time>
+</trkpt>
+<trkpt lat="14.907653" lon="120.767405">
+<ele>13.115112</ele>
+<time>2004-09-07T14:47:30Z</time>
+</trkpt>
+<trkpt lat="14.908297" lon="120.766890">
+<ele>10.711792</ele>
+<time>2004-09-07T14:47:48Z</time>
+</trkpt>
+<trkpt lat="14.909606" lon="120.766697">
+<ele>14.076416</ele>
+<time>2004-09-07T14:48:16Z</time>
+</trkpt>
+<trkpt lat="14.911773" lon="120.766611">
+<ele>8.789185</ele>
+<time>2004-09-07T14:49:01Z</time>
+</trkpt>
+<trkpt lat="14.920807" lon="120.765774">
+<ele>12.153809</ele>
+<time>2004-09-07T14:51:39Z</time>
+</trkpt>
+<trkpt lat="14.928145" lon="120.764079">
+<ele>18.883057</ele>
+<time>2004-09-07T14:52:47Z</time>
+</trkpt>
+<trkpt lat="14.932373" lon="120.762062">
+<ele>16.960449</ele>
+<time>2004-09-07T14:53:18Z</time>
+</trkpt>
+<trkpt lat="14.934025" lon="120.760860">
+<ele>16.960449</ele>
+<time>2004-09-07T14:53:35Z</time>
+</trkpt>
+<trkpt lat="14.934497" lon="120.759938">
+<ele>15.037720</ele>
+<time>2004-09-07T14:53:48Z</time>
+</trkpt>
+<trkpt lat="14.935355" lon="120.758286">
+<ele>16.479736</ele>
+<time>2004-09-07T14:54:24Z</time>
+</trkpt>
+<trkpt lat="14.935892" lon="120.757234">
+<ele>13.595825</ele>
+<time>2004-09-07T14:55:05Z</time>
+</trkpt>
+<trkpt lat="14.936578" lon="120.756419">
+<ele>16.960449</ele>
+<time>2004-09-07T14:55:34Z</time>
+</trkpt>
+<trkpt lat="14.938166" lon="120.755861">
+<ele>17.441162</ele>
+<time>2004-09-07T14:55:49Z</time>
+</trkpt>
+<trkpt lat="14.948165" lon="120.758972">
+<ele>13.595825</ele>
+<time>2004-09-07T14:57:10Z</time>
+</trkpt>
+<trkpt lat="14.949260" lon="120.758865">
+<ele>10.711792</ele>
+<time>2004-09-07T14:57:25Z</time>
+</trkpt>
+<trkpt lat="14.965503" lon="120.757878">
+<ele>19.363770</ele>
+<time>2004-09-07T15:00:36Z</time>
+</trkpt>
+<trkpt lat="14.969988" lon="120.757577">
+<ele>15.037720</ele>
+<time>2004-09-07T15:01:05Z</time>
+</trkpt>
+<trkpt lat="14.972456" lon="120.756633">
+<ele>15.518433</ele>
+<time>2004-09-07T15:01:24Z</time>
+</trkpt>
+<trkpt lat="14.972885" lon="120.756462">
+<ele>13.595825</ele>
+<time>2004-09-07T15:01:28Z</time>
+</trkpt>
+<trkpt lat="14.977026" lon="120.754616">
+<ele>17.921753</ele>
+<time>2004-09-07T15:02:06Z</time>
+</trkpt>
+<trkpt lat="14.978828" lon="120.753822">
+<ele>10.231201</ele>
+<time>2004-09-07T15:02:30Z</time>
+</trkpt>
+<trkpt lat="14.984064" lon="120.751483">
+<ele>13.595825</ele>
+<time>2004-09-07T15:03:45Z</time>
+</trkpt>
+<trkpt lat="14.985566" lon="120.750132">
+<ele>15.999023</ele>
+<time>2004-09-07T15:04:00Z</time>
+</trkpt>
+<trkpt lat="14.987884" lon="120.747600">
+<ele>12.634399</ele>
+<time>2004-09-07T15:04:54Z</time>
+</trkpt>
+<trkpt lat="14.988506" lon="120.748243">
+<ele>13.115112</ele>
+<time>2004-09-07T15:05:16Z</time>
+</trkpt>
+<trkpt lat="14.989879" lon="120.749488">
+<ele>20.805664</ele>
+<time>2004-09-07T15:05:43Z</time>
+</trkpt>
+<trkpt lat="14.990823" lon="120.750260">
+<ele>17.921753</ele>
+<time>2004-09-07T15:06:02Z</time>
+</trkpt>
+<trkpt lat="14.991982" lon="120.749295">
+<ele>14.076416</ele>
+<time>2004-09-07T15:06:36Z</time>
+</trkpt>
+<trkpt lat="15.002947" lon="120.742192">
+<ele>31.380127</ele>
+<time>2004-09-07T15:07:54Z</time>
+</trkpt>
+<trkpt lat="15.010028" lon="120.736871">
+<ele>29.457520</ele>
+<time>2004-09-07T15:08:36Z</time>
+</trkpt>
+<trkpt lat="15.016336" lon="120.731528">
+<ele>30.899536</ele>
+<time>2004-09-07T15:09:11Z</time>
+</trkpt>
+<trkpt lat="15.020499" lon="120.727558">
+<ele>31.380127</ele>
+<time>2004-09-07T15:09:34Z</time>
+</trkpt>
+<trkpt lat="15.027838" lon="120.719898">
+<ele>25.131714</ele>
+<time>2004-09-07T15:10:29Z</time>
+</trkpt>
+<trkpt lat="15.039017" lon="120.705822">
+<ele>34.264160</ele>
+<time>2004-09-07T15:11:42Z</time>
+</trkpt>
+<trkpt lat="15.046914" lon="120.697410">
+<ele>27.054321</ele>
+<time>2004-09-07T15:12:27Z</time>
+</trkpt>
+<trkpt lat="15.049381" lon="120.695136">
+<ele>20.324951</ele>
+<time>2004-09-07T15:12:44Z</time>
+</trkpt>
+<trkpt lat="15.051098" lon="120.693870">
+<ele>16.960449</ele>
+<time>2004-09-07T15:13:03Z</time>
+</trkpt>
+<trkpt lat="15.051613" lon="120.693891">
+<ele>18.402344</ele>
+<time>2004-09-07T15:13:09Z</time>
+</trkpt>
+<trkpt lat="15.051506" lon="120.695093">
+<ele>15.518433</ele>
+<time>2004-09-07T15:13:28Z</time>
+</trkpt>
+<trkpt lat="15.050840" lon="120.695887">
+<ele>14.557007</ele>
+<time>2004-09-07T15:14:27Z</time>
+</trkpt>
+<trkpt lat="15.050454" lon="120.695908">
+<ele>15.999023</ele>
+<time>2004-09-07T15:14:55Z</time>
+</trkpt>
+<trkpt lat="15.049403" lon="120.694900">
+<ele>22.728271</ele>
+<time>2004-09-07T15:15:33Z</time>
+</trkpt>
+<trkpt lat="15.046442" lon="120.691445">
+<ele>22.247559</ele>
+<time>2004-09-07T15:16:50Z</time>
+</trkpt>
+<trkpt lat="15.042257" lon="120.684750">
+<ele>25.131714</ele>
+<time>2004-09-07T15:17:38Z</time>
+</trkpt>
+<trkpt lat="15.040562" lon="120.682325">
+<ele>15.999023</ele>
+<time>2004-09-07T15:18:05Z</time>
+</trkpt>
+<trkpt lat="15.039082" lon="120.680845">
+<ele>23.689575</ele>
+<time>2004-09-07T15:19:25Z</time>
+</trkpt>
+<trkpt lat="15.038245" lon="120.680051">
+<ele>17.921753</ele>
+<time>2004-09-07T15:19:40Z</time>
+</trkpt>
+<trkpt lat="15.038095" lon="120.679793">
+<ele>17.921753</ele>
+<time>2004-09-07T15:21:17Z</time>
+</trkpt>
+<trkpt lat="15.036163" lon="120.678570">
+<ele>26.092896</ele>
+<time>2004-09-07T15:21:44Z</time>
+</trkpt>
+<trkpt lat="15.027580" lon="120.673742">
+<ele>21.286377</ele>
+<time>2004-09-07T15:23:02Z</time>
+</trkpt>
+<trkpt lat="15.024319" lon="120.671489">
+<ele>19.363770</ele>
+<time>2004-09-07T15:23:41Z</time>
+</trkpt>
+<trkpt lat="15.020478" lon="120.668035">
+<ele>28.015503</ele>
+<time>2004-09-07T15:24:55Z</time>
+</trkpt>
+<trkpt lat="15.018547" lon="120.665781">
+<ele>31.380127</ele>
+<time>2004-09-07T15:25:11Z</time>
+</trkpt>
+<trkpt lat="15.014706" lon="120.660696">
+<ele>24.170288</ele>
+<time>2004-09-07T15:25:53Z</time>
+</trkpt>
+<trkpt lat="15.011380" lon="120.656211">
+<ele>35.706055</ele>
+<time>2004-09-07T15:26:34Z</time>
+</trkpt>
+<trkpt lat="14.997926" lon="120.639024">
+<ele>30.899536</ele>
+<time>2004-09-07T15:28:46Z</time>
+</trkpt>
+<trkpt lat="14.993334" lon="120.633316">
+<ele>18.402344</ele>
+<time>2004-09-07T15:29:47Z</time>
+</trkpt>
+<trkpt lat="14.988334" lon="120.627201">
+<ele>25.612305</ele>
+<time>2004-09-07T15:30:58Z</time>
+</trkpt>
+<trkpt lat="14.986897" lon="120.625398">
+<ele>13.595825</ele>
+<time>2004-09-07T15:31:23Z</time>
+</trkpt>
+<trkpt lat="14.984944" lon="120.623016">
+<ele>16.960449</ele>
+<time>2004-09-07T15:31:58Z</time>
+</trkpt>
+<trkpt lat="14.984772" lon="120.622716">
+<ele>15.999023</ele>
+<time>2004-09-07T15:33:17Z</time>
+</trkpt>
+<trkpt lat="14.983528" lon="120.623167">
+<ele>15.037720</ele>
+<time>2004-09-07T15:33:57Z</time>
+</trkpt>
+<trkpt lat="14.976103" lon="120.627544">
+<ele>20.324951</ele>
+<time>2004-09-07T15:35:09Z</time>
+</trkpt>
+<trkpt lat="14.968400" lon="120.632050">
+<ele>16.960449</ele>
+<time>2004-09-07T15:36:48Z</time>
+</trkpt>
+<trkpt lat="14.968143" lon="120.632329">
+<ele>14.557007</ele>
+<time>2004-09-07T15:37:01Z</time>
+</trkpt>
+<trkpt lat="14.970181" lon="120.634131">
+<ele>14.076416</ele>
+<time>2004-09-07T15:37:42Z</time>
+</trkpt>
+<trkpt lat="14.969666" lon="120.634646">
+<ele>15.037720</ele>
+<time>2004-09-07T15:37:59Z</time>
+</trkpt>
+<trkpt lat="14.966791" lon="120.632479">
+<ele>15.037720</ele>
+<time>2004-09-07T15:39:05Z</time>
+</trkpt>
+<trkpt lat="14.966061" lon="120.633101">
+<ele>14.076416</ele>
+<time>2004-09-07T15:39:20Z</time>
+</trkpt>
+<trkpt lat="14.965847" lon="120.632651">
+<ele>13.595825</ele>
+<time>2004-09-07T15:40:09Z</time>
+</trkpt>
+<trkpt lat="14.964538" lon="120.630612">
+<ele>16.479736</ele>
+<time>2004-09-07T15:40:37Z</time>
+</trkpt>
+<trkpt lat="14.964087" lon="120.629411">
+<ele>15.999023</ele>
+<time>2004-09-07T15:40:50Z</time>
+</trkpt>
+<trkpt lat="14.964130" lon="120.628166">
+<ele>16.479736</ele>
+<time>2004-09-07T15:41:05Z</time>
+</trkpt>
+<trkpt lat="14.965310" lon="120.624433">
+<ele>18.883057</ele>
+<time>2004-09-07T15:41:37Z</time>
+</trkpt>
+<trkpt lat="14.966726" lon="120.622780">
+<ele>19.844360</ele>
+<time>2004-09-07T15:41:53Z</time>
+</trkpt>
+<trkpt lat="14.968765" lon="120.620978">
+<ele>21.766968</ele>
+<time>2004-09-07T15:42:11Z</time>
+</trkpt>
+<trkpt lat="14.969687" lon="120.620055">
+<ele>20.324951</ele>
+<time>2004-09-07T15:42:20Z</time>
+</trkpt>
+<trkpt lat="14.970138" lon="120.618939">
+<ele>17.921753</ele>
+<time>2004-09-07T15:42:29Z</time>
+</trkpt>
+<trkpt lat="14.970138" lon="120.618703">
+<ele>15.999023</ele>
+<time>2004-09-07T15:42:32Z</time>
+</trkpt>
+<trkpt lat="14.969366" lon="120.617223">
+<ele>18.402344</ele>
+<time>2004-09-07T15:42:51Z</time>
+</trkpt>
+<trkpt lat="14.967628" lon="120.614820">
+<ele>19.844360</ele>
+<time>2004-09-07T15:43:15Z</time>
+</trkpt>
+<trkpt lat="14.967284" lon="120.614026">
+<ele>14.076416</ele>
+<time>2004-09-07T15:43:31Z</time>
+</trkpt>
+<trkpt lat="14.965761" lon="120.611258">
+<ele>17.921753</ele>
+<time>2004-09-07T15:45:03Z</time>
+</trkpt>
+<trkpt lat="14.964902" lon="120.610592">
+<ele>19.363770</ele>
+<time>2004-09-07T15:45:12Z</time>
+</trkpt>
+<trkpt lat="14.963551" lon="120.610206">
+<ele>20.805664</ele>
+<time>2004-09-07T15:45:22Z</time>
+</trkpt>
+<trkpt lat="14.961598" lon="120.609798">
+<ele>14.076416</ele>
+<time>2004-09-07T15:45:52Z</time>
+</trkpt>
+<trkpt lat="14.959388" lon="120.609198">
+<ele>20.324951</ele>
+<time>2004-09-07T15:46:39Z</time>
+</trkpt>
+<trkpt lat="14.957714" lon="120.608404">
+<ele>13.595825</ele>
+<time>2004-09-07T15:47:39Z</time>
+</trkpt>
+<trkpt lat="14.956083" lon="120.607502">
+<ele>17.921753</ele>
+<time>2004-09-07T15:48:04Z</time>
+</trkpt>
+<trkpt lat="14.953079" lon="120.604520">
+<ele>21.286377</ele>
+<time>2004-09-07T15:48:38Z</time>
+</trkpt>
+<trkpt lat="14.950418" lon="120.601280">
+<ele>14.076416</ele>
+<time>2004-09-07T15:49:24Z</time>
+</trkpt>
+<trkpt lat="14.947844" lon="120.597610">
+<ele>21.286377</ele>
+<time>2004-09-07T15:50:05Z</time>
+</trkpt>
+<trkpt lat="14.946878" lon="120.596902">
+<ele>17.921753</ele>
+<time>2004-09-07T15:50:15Z</time>
+</trkpt>
+<trkpt lat="14.945741" lon="120.596859">
+<ele>19.363770</ele>
+<time>2004-09-07T15:50:24Z</time>
+</trkpt>
+<trkpt lat="14.944882" lon="120.597246">
+<ele>14.557007</ele>
+<time>2004-09-07T15:50:42Z</time>
+</trkpt>
+<trkpt lat="14.943552" lon="120.597653">
+<ele>17.921753</ele>
+<time>2004-09-07T15:51:34Z</time>
+</trkpt>
+<trkpt lat="14.942050" lon="120.597546">
+<ele>20.324951</ele>
+<time>2004-09-07T15:51:46Z</time>
+</trkpt>
+<trkpt lat="14.939368" lon="120.596216">
+<ele>14.557007</ele>
+<time>2004-09-07T15:52:19Z</time>
+</trkpt>
+<trkpt lat="14.929519" lon="120.591066">
+<ele>20.805664</ele>
+<time>2004-09-07T15:54:35Z</time>
+</trkpt>
+<trkpt lat="14.928167" lon="120.589843">
+<ele>22.728271</ele>
+<time>2004-09-07T15:54:47Z</time>
+</trkpt>
+<trkpt lat="14.923275" lon="120.582397">
+<ele>15.037720</ele>
+<time>2004-09-07T15:56:01Z</time>
+</trkpt>
+<trkpt lat="14.915378" lon="120.570059">
+<ele>24.651001</ele>
+<time>2004-09-07T15:59:05Z</time>
+</trkpt>
+<trkpt lat="14.912031" lon="120.564802">
+<ele>15.518433</ele>
+<time>2004-09-07T16:00:07Z</time>
+</trkpt>
+<trkpt lat="14.876862" lon="120.509870">
+<ele>32.822266</ele>
+<time>2004-09-07T16:07:31Z</time>
+</trkpt>
+<trkpt lat="14.853859" lon="120.474057">
+<ele>17.921753</ele>
+<time>2004-09-07T16:11:57Z</time>
+</trkpt>
+<trkpt lat="14.854009" lon="120.473478">
+<ele>17.441162</ele>
+<time>2004-09-07T16:12:07Z</time>
+</trkpt>
+<trkpt lat="14.859738" lon="120.471246">
+<ele>24.651001</ele>
+<time>2004-09-07T16:12:51Z</time>
+</trkpt>
+<trkpt lat="14.869137" lon="120.467620">
+<ele>16.479736</ele>
+<time>2004-09-07T16:14:12Z</time>
+</trkpt>
+<trkpt lat="14.870489" lon="120.466933">
+<ele>17.441162</ele>
+<time>2004-09-07T16:14:44Z</time>
+</trkpt>
+<trkpt lat="14.869673" lon="120.463951">
+<ele>23.208984</ele>
+<time>2004-09-07T16:15:12Z</time>
+</trkpt>
+<trkpt lat="14.868343" lon="120.459852">
+<ele>24.170288</ele>
+<time>2004-09-07T16:15:41Z</time>
+</trkpt>
+<trkpt lat="14.867785" lon="120.458200">
+<ele>17.921753</ele>
+<time>2004-09-07T16:16:05Z</time>
+</trkpt>
+<trkpt lat="14.866691" lon="120.454788">
+<ele>26.092896</ele>
+<time>2004-09-07T16:16:39Z</time>
+</trkpt>
+<trkpt lat="14.864802" lon="120.448909">
+<ele>19.363770</ele>
+<time>2004-09-07T16:17:22Z</time>
+</trkpt>
+<trkpt lat="14.863622" lon="120.445240">
+<ele>27.534912</ele>
+<time>2004-09-07T16:17:56Z</time>
+</trkpt>
+<trkpt lat="14.862678" lon="120.442729">
+<ele>28.976929</ele>
+<time>2004-09-07T16:18:12Z</time>
+</trkpt>
+<trkpt lat="14.861240" lon="120.440433">
+<ele>31.860718</ele>
+<time>2004-09-07T16:18:27Z</time>
+</trkpt>
+<trkpt lat="14.858644" lon="120.436506">
+<ele>29.457520</ele>
+<time>2004-09-07T16:18:52Z</time>
+</trkpt>
+<trkpt lat="14.857228" lon="120.434361">
+<ele>33.783447</ele>
+<time>2004-09-07T16:19:07Z</time>
+</trkpt>
+<trkpt lat="14.846971" lon="120.420542">
+<ele>29.457520</ele>
+<time>2004-09-07T16:20:43Z</time>
+</trkpt>
+<trkpt lat="14.846563" lon="120.419362">
+<ele>29.457520</ele>
+<time>2004-09-07T16:20:52Z</time>
+</trkpt>
+<trkpt lat="14.847507" lon="120.413740">
+<ele>31.860718</ele>
+<time>2004-09-07T16:21:25Z</time>
+</trkpt>
+<trkpt lat="14.846048" lon="120.406015">
+<ele>37.148071</ele>
+<time>2004-09-07T16:22:10Z</time>
+</trkpt>
+<trkpt lat="14.845533" lon="120.402646">
+<ele>41.473999</ele>
+<time>2004-09-07T16:22:35Z</time>
+</trkpt>
+<trkpt lat="14.845469" lon="120.401359">
+<ele>35.225464</ele>
+<time>2004-09-07T16:22:45Z</time>
+</trkpt>
+<trkpt lat="14.848516" lon="120.401444">
+<ele>31.380127</ele>
+<time>2004-09-07T16:22:52Z</time>
+</trkpt>
+<trkpt lat="14.848065" lon="120.398333">
+<ele>27.054321</ele>
+<time>2004-09-07T16:23:39Z</time>
+</trkpt>
+<trkpt lat="14.847851" lon="120.394514">
+<ele>34.744873</ele>
+<time>2004-09-07T16:24:23Z</time>
+</trkpt>
+<trkpt lat="14.850490" lon="120.390844">
+<ele>36.186768</ele>
+<time>2004-09-07T16:24:53Z</time>
+</trkpt>
+<trkpt lat="14.849482" lon="120.388377">
+<ele>46.761230</ele>
+<time>2004-09-07T16:25:15Z</time>
+</trkpt>
+<trkpt lat="14.849696" lon="120.387089">
+<ele>49.645264</ele>
+<time>2004-09-07T16:25:27Z</time>
+</trkpt>
+<trkpt lat="14.850962" lon="120.386596">
+<ele>46.761230</ele>
+<time>2004-09-07T16:25:37Z</time>
+</trkpt>
+<trkpt lat="14.851627" lon="120.385909">
+<ele>42.435425</ele>
+<time>2004-09-07T16:25:44Z</time>
+</trkpt>
+<trkpt lat="14.851649" lon="120.385158">
+<ele>41.473999</ele>
+<time>2004-09-07T16:25:50Z</time>
+</trkpt>
+<trkpt lat="14.850833" lon="120.383635">
+<ele>40.032104</ele>
+<time>2004-09-07T16:26:02Z</time>
+</trkpt>
+<trkpt lat="14.851005" lon="120.383141">
+<ele>36.186768</ele>
+<time>2004-09-07T16:26:59Z</time>
+</trkpt>
+<trkpt lat="14.853323" lon="120.379772">
+<ele>51.087158</ele>
+<time>2004-09-07T16:27:44Z</time>
+</trkpt>
+<trkpt lat="14.851863" lon="120.376725">
+<ele>44.358032</ele>
+<time>2004-09-07T16:28:25Z</time>
+</trkpt>
+<trkpt lat="14.851499" lon="120.374644">
+<ele>54.932373</ele>
+<time>2004-09-07T16:29:01Z</time>
+</trkpt>
+<trkpt lat="14.854825" lon="120.365160">
+<ele>76.081421</ele>
+<time>2004-09-07T16:30:31Z</time>
+</trkpt>
+<trkpt lat="14.849653" lon="120.365310">
+<ele>75.600830</ele>
+<time>2004-09-07T16:30:39Z</time>
+</trkpt>
+<trkpt lat="14.847744" lon="120.364966">
+<ele>75.120239</ele>
+<time>2004-09-07T16:30:47Z</time>
+</trkpt>
+<trkpt lat="14.847314" lon="120.364301">
+<ele>71.755493</ele>
+<time>2004-09-07T16:30:54Z</time>
+</trkpt>
+<trkpt lat="14.846799" lon="120.363443">
+<ele>75.600830</ele>
+<time>2004-09-07T16:31:03Z</time>
+</trkpt>
+<trkpt lat="14.846177" lon="120.359645">
+<ele>87.136597</ele>
+<time>2004-09-07T16:31:33Z</time>
+</trkpt>
+<trkpt lat="14.845490" lon="120.358572">
+<ele>90.981934</ele>
+<time>2004-09-07T16:31:42Z</time>
+</trkpt>
+<trkpt lat="14.845276" lon="120.357971">
+<ele>95.307739</ele>
+<time>2004-09-07T16:31:47Z</time>
+</trkpt>
+<trkpt lat="14.845641" lon="120.356576">
+<ele>102.517700</ele>
+<time>2004-09-07T16:31:59Z</time>
+</trkpt>
+<trkpt lat="14.846349" lon="120.355546">
+<ele>107.324341</ele>
+<time>2004-09-07T16:32:09Z</time>
+</trkpt>
+<trkpt lat="14.847121" lon="120.354195">
+<ele>111.169556</ele>
+<time>2004-09-07T16:32:20Z</time>
+</trkpt>
+<trkpt lat="14.847422" lon="120.349817">
+<ele>137.605835</ele>
+<time>2004-09-07T16:32:57Z</time>
+</trkpt>
+<trkpt lat="14.847078" lon="120.348916">
+<ele>143.373657</ele>
+<time>2004-09-07T16:33:07Z</time>
+</trkpt>
+<trkpt lat="14.845684" lon="120.347843">
+<ele>152.025757</ele>
+<time>2004-09-07T16:33:49Z</time>
+</trkpt>
+<trkpt lat="14.845233" lon="120.346255">
+<ele>153.467651</ele>
+<time>2004-09-07T16:34:06Z</time>
+</trkpt>
+<trkpt lat="14.845126" lon="120.345354">
+<ele>150.103027</ele>
+<time>2004-09-07T16:34:15Z</time>
+</trkpt>
+<trkpt lat="14.845576" lon="120.344346">
+<ele>142.893066</ele>
+<time>2004-09-07T16:34:28Z</time>
+</trkpt>
+<trkpt lat="14.847250" lon="120.344667">
+<ele>136.163940</ele>
+<time>2004-09-07T16:34:49Z</time>
+</trkpt>
+<trkpt lat="14.847572" lon="120.344367">
+<ele>132.799316</ele>
+<time>2004-09-07T16:34:56Z</time>
+</trkpt>
+<trkpt lat="14.847400" lon="120.343659">
+<ele>129.915283</ele>
+<time>2004-09-07T16:35:06Z</time>
+</trkpt>
+<trkpt lat="14.847314" lon="120.343444">
+<ele>127.031372</ele>
+<time>2004-09-07T16:35:09Z</time>
+</trkpt>
+<trkpt lat="14.847314" lon="120.342844">
+<ele>126.069946</ele>
+<time>2004-09-07T16:35:16Z</time>
+</trkpt>
+<trkpt lat="14.847507" lon="120.341578">
+<ele>115.495605</ele>
+<time>2004-09-07T16:35:35Z</time>
+</trkpt>
+<trkpt lat="14.848623" lon="120.340140">
+<ele>103.479004</ele>
+<time>2004-09-07T16:36:10Z</time>
+</trkpt>
+<trkpt lat="14.847229" lon="120.340869">
+<ele>90.501343</ele>
+<time>2004-09-07T16:36:36Z</time>
+</trkpt>
+<trkpt lat="14.845684" lon="120.340719">
+<ele>78.484741</ele>
+<time>2004-09-07T16:36:59Z</time>
+</trkpt>
+<trkpt lat="14.845448" lon="120.339904">
+<ele>75.600830</ele>
+<time>2004-09-07T16:37:08Z</time>
+</trkpt>
+<trkpt lat="14.845555" lon="120.339410">
+<ele>69.832886</ele>
+<time>2004-09-07T16:37:13Z</time>
+</trkpt>
+<trkpt lat="14.848194" lon="120.338616">
+<ele>74.639526</ele>
+<time>2004-09-07T16:37:41Z</time>
+</trkpt>
+<trkpt lat="14.848945" lon="120.337994">
+<ele>81.849365</ele>
+<time>2004-09-07T16:37:52Z</time>
+</trkpt>
+<trkpt lat="14.847980" lon="120.335376">
+<ele>84.733398</ele>
+<time>2004-09-07T16:38:15Z</time>
+</trkpt>
+<trkpt lat="14.848237" lon="120.335033">
+<ele>84.733398</ele>
+<time>2004-09-07T16:38:20Z</time>
+</trkpt>
+<trkpt lat="14.849718" lon="120.335119">
+<ele>91.462524</ele>
+<time>2004-09-07T16:38:36Z</time>
+</trkpt>
+<trkpt lat="14.851413" lon="120.333982">
+<ele>100.114502</ele>
+<time>2004-09-07T16:38:55Z</time>
+</trkpt>
+<trkpt lat="14.852507" lon="120.334175">
+<ele>103.959717</ele>
+<time>2004-09-07T16:39:20Z</time>
+</trkpt>
+<trkpt lat="14.851542" lon="120.333402">
+<ele>113.572998</ele>
+<time>2004-09-07T16:39:46Z</time>
+</trkpt>
+<trkpt lat="14.850254" lon="120.332909">
+<ele>121.263550</ele>
+<time>2004-09-07T16:40:01Z</time>
+</trkpt>
+<trkpt lat="14.849782" lon="120.332179">
+<ele>122.224731</ele>
+<time>2004-09-07T16:40:10Z</time>
+</trkpt>
+<trkpt lat="14.850469" lon="120.329626">
+<ele>131.837891</ele>
+<time>2004-09-07T16:40:34Z</time>
+</trkpt>
+<trkpt lat="14.850318" lon="120.327802">
+<ele>139.528442</ele>
+<time>2004-09-07T16:40:58Z</time>
+</trkpt>
+<trkpt lat="14.849954" lon="120.326729">
+<ele>141.451050</ele>
+<time>2004-09-07T16:41:15Z</time>
+</trkpt>
+<trkpt lat="14.849675" lon="120.325935">
+<ele>141.451050</ele>
+<time>2004-09-07T16:41:29Z</time>
+</trkpt>
+<trkpt lat="14.848645" lon="120.325484">
+<ele>134.721924</ele>
+<time>2004-09-07T16:41:51Z</time>
+</trkpt>
+<trkpt lat="14.849095" lon="120.323918">
+<ele>123.186157</ele>
+<time>2004-09-07T16:42:15Z</time>
+</trkpt>
+<trkpt lat="14.848623" lon="120.323725">
+<ele>119.340820</ele>
+<time>2004-09-07T16:42:23Z</time>
+</trkpt>
+<trkpt lat="14.847229" lon="120.324862">
+<ele>110.688843</ele>
+<time>2004-09-07T16:42:46Z</time>
+</trkpt>
+<trkpt lat="14.846435" lon="120.324969">
+<ele>105.882446</ele>
+<time>2004-09-07T16:42:58Z</time>
+</trkpt>
+<trkpt lat="14.845984" lon="120.324025">
+<ele>98.191895</ele>
+<time>2004-09-07T16:43:10Z</time>
+</trkpt>
+<trkpt lat="14.845963" lon="120.323038">
+<ele>90.981934</ele>
+<time>2004-09-07T16:43:22Z</time>
+</trkpt>
+<trkpt lat="14.846306" lon="120.322587">
+<ele>87.136597</ele>
+<time>2004-09-07T16:43:29Z</time>
+</trkpt>
+<trkpt lat="14.846585" lon="120.322394">
+<ele>85.694580</ele>
+<time>2004-09-07T16:43:34Z</time>
+</trkpt>
+<trkpt lat="14.847400" lon="120.322394">
+<ele>79.446045</ele>
+<time>2004-09-07T16:43:46Z</time>
+</trkpt>
+<trkpt lat="14.848194" lon="120.322373">
+<ele>76.081421</ele>
+<time>2004-09-07T16:43:57Z</time>
+</trkpt>
+<trkpt lat="14.847958" lon="120.321000">
+<ele>67.910278</ele>
+<time>2004-09-07T16:44:14Z</time>
+</trkpt>
+<trkpt lat="14.848216" lon="120.319304">
+<ele>61.181030</ele>
+<time>2004-09-07T16:44:39Z</time>
+</trkpt>
+<trkpt lat="14.848859" lon="120.318768">
+<ele>56.855103</ele>
+<time>2004-09-07T16:44:53Z</time>
+</trkpt>
+<trkpt lat="14.848816" lon="120.318296">
+<ele>54.932373</ele>
+<time>2004-09-07T16:45:01Z</time>
+</trkpt>
+<trkpt lat="14.848688" lon="120.317116">
+<ele>46.280640</ele>
+<time>2004-09-07T16:45:35Z</time>
+</trkpt>
+<trkpt lat="14.849052" lon="120.316386">
+<ele>45.799927</ele>
+<time>2004-09-07T16:45:47Z</time>
+</trkpt>
+<trkpt lat="14.849117" lon="120.314691">
+<ele>38.109375</ele>
+<time>2004-09-07T16:46:07Z</time>
+</trkpt>
+<trkpt lat="14.848709" lon="120.313275">
+<ele>31.860718</ele>
+<time>2004-09-07T16:46:25Z</time>
+</trkpt>
+<trkpt lat="14.848258" lon="120.307438">
+<ele>26.092896</ele>
+<time>2004-09-07T16:47:29Z</time>
+</trkpt>
+<trkpt lat="14.850082" lon="120.303125">
+<ele>28.976929</ele>
+<time>2004-09-07T16:48:11Z</time>
+</trkpt>
+<trkpt lat="14.849954" lon="120.300765">
+<ele>27.054321</ele>
+<time>2004-09-07T16:48:31Z</time>
+</trkpt>
+<trkpt lat="14.846971" lon="120.295444">
+<ele>30.418823</ele>
+<time>2004-09-07T16:49:20Z</time>
+</trkpt>
+<trkpt lat="14.846756" lon="120.292568">
+<ele>27.054321</ele>
+<time>2004-09-07T16:49:42Z</time>
+</trkpt>
+<trkpt lat="14.843323" lon="120.288556">
+<ele>23.689575</ele>
+<time>2004-09-07T16:50:26Z</time>
+</trkpt>
+<trkpt lat="14.842551" lon="120.288255">
+<ele>23.689575</ele>
+<time>2004-09-07T16:50:29Z</time>
+</trkpt>
+<trkpt lat="14.841328" lon="120.286925">
+<ele>23.689575</ele>
+<time>2004-09-07T16:50:43Z</time>
+</trkpt>
+<trkpt lat="14.839911" lon="120.285337">
+<ele>18.883057</ele>
+<time>2004-09-07T16:51:00Z</time>
+</trkpt>
+<trkpt lat="14.840298" lon="120.285788">
+<ele>19.844360</ele>
+<time>2004-09-07T16:51:28Z</time>
+</trkpt>
+<trkpt lat="14.840491" lon="120.285079">
+<ele>18.883057</ele>
+<time>2004-09-07T16:51:50Z</time>
+</trkpt>
+<trkpt lat="14.839718" lon="120.284178">
+<ele>17.441162</ele>
+<time>2004-09-07T16:55:42Z</time>
+</trkpt>
+<trkpt lat="14.975588" lon="120.155540">
+<ele>29.938110</ele>
+<time>2004-09-08T02:02:19Z</time>
+</trkpt>
+<trkpt lat="14.975159" lon="120.157127">
+<ele>36.186768</ele>
+<time>2004-09-08T02:47:04Z</time>
+</trkpt>
+<trkpt lat="14.975181" lon="120.157149">
+<ele>42.916016</ele>
+<time>2004-09-08T02:47:26Z</time>
+</trkpt>
+<trkpt lat="14.975867" lon="120.169616">
+<ele>50.606567</ele>
+<time>2004-09-08T02:55:08Z</time>
+</trkpt>
+<trkpt lat="14.975502" lon="120.174830">
+<ele>54.451782</ele>
+<time>2004-09-08T02:56:01Z</time>
+</trkpt>
+<trkpt lat="14.979751" lon="120.190022">
+<ele>60.700317</ele>
+<time>2004-09-08T02:58:47Z</time>
+</trkpt>
+<trkpt lat="14.980502" lon="120.193992">
+<ele>63.103638</ele>
+<time>2004-09-08T03:02:22Z</time>
+</trkpt>
+<trkpt lat="14.980674" lon="120.196137">
+<ele>77.042847</ele>
+<time>2004-09-08T03:16:27Z</time>
+</trkpt>
+<trkpt lat="14.982047" lon="120.196846">
+<ele>65.026367</ele>
+<time>2004-09-08T03:18:11Z</time>
+</trkpt>
+<trkpt lat="14.984407" lon="120.199678">
+<ele>68.871582</ele>
+<time>2004-09-08T03:22:57Z</time>
+</trkpt>
+<trkpt lat="14.985566" lon="120.200622">
+<ele>68.871582</ele>
+<time>2004-09-08T03:25:05Z</time>
+</trkpt>
+<trkpt lat="14.988184" lon="120.202982">
+<ele>75.600830</ele>
+<time>2004-09-08T03:34:23Z</time>
+</trkpt>
+<trkpt lat="14.992883" lon="120.206931">
+<ele>79.926636</ele>
+<time>2004-09-08T03:43:48Z</time>
+</trkpt>
+<trkpt lat="14.996316" lon="120.209484">
+<ele>82.810791</ele>
+<time>2004-09-08T03:51:12Z</time>
+</trkpt>
+<trkpt lat="14.997883" lon="120.209827">
+<ele>84.252686</ele>
+<time>2004-09-08T03:55:15Z</time>
+</trkpt>
+<trkpt lat="14.998097" lon="120.210900">
+<ele>85.213989</ele>
+<time>2004-09-08T03:58:17Z</time>
+</trkpt>
+<trkpt lat="14.999664" lon="120.212381">
+<ele>85.213989</ele>
+<time>2004-09-08T04:01:25Z</time>
+</trkpt>
+<trkpt lat="15.003011" lon="120.213647">
+<ele>87.136597</ele>
+<time>2004-09-08T04:07:25Z</time>
+</trkpt>
+<trkpt lat="15.006766" lon="120.216758">
+<ele>91.943237</ele>
+<time>2004-09-08T04:16:18Z</time>
+</trkpt>
+<trkpt lat="15.009899" lon="120.217338">
+<ele>95.788452</ele>
+<time>2004-09-08T04:20:50Z</time>
+</trkpt>
+<trkpt lat="15.012367" lon="120.219333">
+<ele>94.827148</ele>
+<time>2004-09-08T04:24:59Z</time>
+</trkpt>
+<trkpt lat="15.013268" lon="120.221393">
+<ele>95.307739</ele>
+<time>2004-09-08T04:27:52Z</time>
+</trkpt>
+<trkpt lat="15.013804" lon="120.221758">
+<ele>94.827148</ele>
+<time>2004-09-08T04:28:46Z</time>
+</trkpt>
+<trkpt lat="15.014405" lon="120.222144">
+<ele>92.904541</ele>
+<time>2004-09-08T04:29:57Z</time>
+</trkpt>
+<trkpt lat="15.014727" lon="120.222208">
+<ele>90.981934</ele>
+<time>2004-09-08T04:30:42Z</time>
+</trkpt>
+<trkpt lat="15.014770" lon="120.222445">
+<ele>86.656006</ele>
+<time>2004-09-08T04:31:03Z</time>
+</trkpt>
+<trkpt lat="15.014749" lon="120.222487">
+<ele>93.385132</ele>
+<time>2004-09-08T04:31:09Z</time>
+</trkpt>
+<trkpt lat="15.014877" lon="120.223088">
+<ele>90.501343</ele>
+<time>2004-09-08T04:32:14Z</time>
+</trkpt>
+<trkpt lat="15.015070" lon="120.223367">
+<ele>90.501343</ele>
+<time>2004-09-08T04:32:47Z</time>
+</trkpt>
+<trkpt lat="15.016572" lon="120.224397">
+<ele>93.865845</ele>
+<time>2004-09-08T04:46:16Z</time>
+</trkpt>
+<trkpt lat="15.019448" lon="120.225148">
+<ele>92.423950</ele>
+<time>2004-09-08T04:51:28Z</time>
+</trkpt>
+<trkpt lat="15.021250" lon="120.226822">
+<ele>94.827148</ele>
+<time>2004-09-08T04:55:35Z</time>
+</trkpt>
+<trkpt lat="15.022924" lon="120.227702">
+<ele>98.191895</ele>
+<time>2004-09-08T04:58:14Z</time>
+</trkpt>
+<trkpt lat="15.024319" lon="120.227852">
+<ele>100.114502</ele>
+<time>2004-09-08T05:01:58Z</time>
+</trkpt>
+<trkpt lat="15.025413" lon="120.228431">
+<ele>98.672485</ele>
+<time>2004-09-08T05:05:57Z</time>
+</trkpt>
+<trkpt lat="15.028589" lon="120.228946">
+<ele>105.882446</ele>
+<time>2004-09-08T05:12:08Z</time>
+</trkpt>
+<trkpt lat="15.029683" lon="120.229611">
+<ele>108.766235</ele>
+<time>2004-09-08T05:15:30Z</time>
+</trkpt>
+<trkpt lat="15.031443" lon="120.230169">
+<ele>110.208252</ele>
+<time>2004-09-08T05:18:16Z</time>
+</trkpt>
+<trkpt lat="15.032752" lon="120.231757">
+<ele>117.418213</ele>
+<time>2004-09-08T05:22:13Z</time>
+</trkpt>
+<trkpt lat="15.033288" lon="120.233452">
+<ele>119.821411</ele>
+<time>2004-09-08T05:25:00Z</time>
+</trkpt>
+<trkpt lat="15.034060" lon="120.234547">
+<ele>124.628052</ele>
+<time>2004-09-08T05:26:57Z</time>
+</trkpt>
+<trkpt lat="15.034661" lon="120.235448">
+<ele>122.224731</ele>
+<time>2004-09-08T05:28:32Z</time>
+</trkpt>
+<trkpt lat="15.034940" lon="120.236714">
+<ele>129.434692</ele>
+<time>2004-09-08T05:31:45Z</time>
+</trkpt>
+<trkpt lat="15.035219" lon="120.236328">
+<ele>129.915283</ele>
+<time>2004-09-08T05:32:35Z</time>
+</trkpt>
+<trkpt lat="15.037129" lon="120.236349">
+<ele>154.909546</ele>
+<time>2004-09-08T06:40:26Z</time>
+</trkpt>
+<trkpt lat="15.037301" lon="120.236542">
+<ele>144.815796</ele>
+<time>2004-09-08T06:43:49Z</time>
+</trkpt>
+<trkpt lat="15.037901" lon="120.236928">
+<ele>152.506348</ele>
+<time>2004-09-08T06:46:06Z</time>
+</trkpt>
+<trkpt lat="15.038202" lon="120.237036">
+<ele>156.351563</ele>
+<time>2004-09-08T06:48:26Z</time>
+</trkpt>
+<trkpt lat="15.038309" lon="120.237186">
+<ele>157.793579</ele>
+<time>2004-09-08T06:48:47Z</time>
+</trkpt>
+<trkpt lat="15.042386" lon="120.246134">
+<ele>185.191162</ele>
+<time>2004-09-08T07:16:13Z</time>
+</trkpt>
+<trkpt lat="15.043287" lon="120.254095">
+<ele>204.417480</ele>
+<time>2004-09-08T07:37:30Z</time>
+</trkpt>
+<trkpt lat="15.043287" lon="120.254095">
+<ele>209.224121</ele>
+<time>2004-09-08T07:37:31Z</time>
+</trkpt>
+</trkseg>
+</trk>
+<trk>
+ <name>08-SEP-04</name>
+<number>2</number>
+<trkseg>
+<trkpt lat="15.043309" lon="120.254095">
+<ele>206.340088</ele>
+<time>2004-09-08T07:39:34Z</time>
+</trkpt>
+<trkpt lat="15.043309" lon="120.254095">
+<ele>209.704834</ele>
+<time>2004-09-08T07:39:38Z</time>
+</trkpt>
+<trkpt lat="15.043330" lon="120.254717">
+<ele>210.666016</ele>
+<time>2004-09-08T07:41:08Z</time>
+</trkpt>
+<trkpt lat="15.043309" lon="120.254695">
+<ele>210.185425</ele>
+<time>2004-09-08T07:41:21Z</time>
+</trkpt>
+<trkpt lat="15.043201" lon="120.253429">
+<ele>207.301392</ele>
+<time>2004-09-08T07:43:06Z</time>
+</trkpt>
+<trkpt lat="15.043116" lon="120.253193">
+<ele>207.301392</ele>
+<time>2004-09-08T07:43:27Z</time>
+</trkpt>
+<trkpt lat="15.043073" lon="120.252485">
+<ele>205.378784</ele>
+<time>2004-09-08T07:45:17Z</time>
+</trkpt>
+<trkpt lat="15.043008" lon="120.251842">
+<ele>202.014282</ele>
+<time>2004-09-08T07:46:09Z</time>
+</trkpt>
+<trkpt lat="15.042858" lon="120.249889">
+<ele>195.765625</ele>
+<time>2004-09-08T07:48:50Z</time>
+</trkpt>
+<trkpt lat="15.042708" lon="120.249052">
+<ele>191.439575</ele>
+<time>2004-09-08T07:49:59Z</time>
+</trkpt>
+<trkpt lat="15.042601" lon="120.248537">
+<ele>190.478394</ele>
+<time>2004-09-08T07:50:41Z</time>
+</trkpt>
+<trkpt lat="15.042558" lon="120.247958">
+<ele>188.075073</ele>
+<time>2004-09-08T07:51:27Z</time>
+</trkpt>
+<trkpt lat="15.042579" lon="120.247872">
+<ele>188.555786</ele>
+<time>2004-09-08T07:51:46Z</time>
+</trkpt>
+<trkpt lat="15.042558" lon="120.247378">
+<ele>187.113770</ele>
+<time>2004-09-08T07:52:44Z</time>
+</trkpt>
+<trkpt lat="15.042408" lon="120.246606">
+<ele>185.191162</ele>
+<time>2004-09-08T07:54:58Z</time>
+</trkpt>
+<trkpt lat="15.042365" lon="120.246305">
+<ele>185.671753</ele>
+<time>2004-09-08T07:55:23Z</time>
+</trkpt>
+<trkpt lat="15.042236" lon="120.245962">
+<ele>184.710571</ele>
+<time>2004-09-08T07:56:05Z</time>
+</trkpt>
+<trkpt lat="15.042171" lon="120.245984">
+<ele>184.710571</ele>
+<time>2004-09-08T07:56:23Z</time>
+</trkpt>
+<trkpt lat="15.042236" lon="120.245941">
+<ele>184.710571</ele>
+<time>2004-09-08T07:57:01Z</time>
+</trkpt>
+<trkpt lat="15.042150" lon="120.245748">
+<ele>183.749023</ele>
+<time>2004-09-08T07:57:20Z</time>
+</trkpt>
+<trkpt lat="15.041893" lon="120.245233">
+<ele>182.307129</ele>
+<time>2004-09-08T07:58:05Z</time>
+</trkpt>
+<trkpt lat="15.041807" lon="120.245147">
+<ele>182.307129</ele>
+<time>2004-09-08T07:58:23Z</time>
+</trkpt>
+<trkpt lat="15.041785" lon="120.245018">
+<ele>180.865234</ele>
+<time>2004-09-08T07:58:42Z</time>
+</trkpt>
+<trkpt lat="15.041528" lon="120.244396">
+<ele>179.903809</ele>
+<time>2004-09-08T08:00:10Z</time>
+</trkpt>
+<trkpt lat="15.041463" lon="120.244160">
+<ele>179.423218</ele>
+<time>2004-09-08T08:00:31Z</time>
+</trkpt>
+<trkpt lat="15.041399" lon="120.243988">
+<ele>178.461914</ele>
+<time>2004-09-08T08:00:46Z</time>
+</trkpt>
+<trkpt lat="15.041378" lon="120.243838">
+<ele>178.942627</ele>
+<time>2004-09-08T08:02:01Z</time>
+</trkpt>
+<trkpt lat="15.041356" lon="120.243838">
+<ele>178.942627</ele>
+<time>2004-09-08T08:02:20Z</time>
+</trkpt>
+<trkpt lat="15.041313" lon="120.243623">
+<ele>177.981201</ele>
+<time>2004-09-08T08:03:02Z</time>
+</trkpt>
+<trkpt lat="15.041227" lon="120.243387">
+<ele>177.981201</ele>
+<time>2004-09-08T08:03:27Z</time>
+</trkpt>
+<trkpt lat="15.041227" lon="120.243387">
+<ele>176.539307</ele>
+<time>2004-09-08T08:03:37Z</time>
+</trkpt>
+<trkpt lat="15.040991" lon="120.243044">
+<ele>177.981201</ele>
+<time>2004-09-08T08:04:37Z</time>
+</trkpt>
+<trkpt lat="15.040519" lon="120.241756">
+<ele>177.020020</ele>
+<time>2004-09-08T08:06:26Z</time>
+</trkpt>
+<trkpt lat="15.040219" lon="120.241263">
+<ele>176.058594</ele>
+<time>2004-09-08T08:08:06Z</time>
+</trkpt>
+<trkpt lat="15.040004" lon="120.240855">
+<ele>174.135864</ele>
+<time>2004-09-08T08:09:00Z</time>
+</trkpt>
+<trkpt lat="15.039854" lon="120.240426">
+<ele>174.616577</ele>
+<time>2004-09-08T08:10:08Z</time>
+</trkpt>
+<trkpt lat="15.039704" lon="120.240104">
+<ele>174.135864</ele>
+<time>2004-09-08T08:10:37Z</time>
+</trkpt>
+<trkpt lat="15.039532" lon="120.239868">
+<ele>173.655273</ele>
+<time>2004-09-08T08:11:01Z</time>
+</trkpt>
+<trkpt lat="15.039361" lon="120.239718">
+<ele>173.174683</ele>
+<time>2004-09-08T08:11:20Z</time>
+</trkpt>
+<trkpt lat="15.039318" lon="120.239675">
+<ele>173.174683</ele>
+<time>2004-09-08T08:11:41Z</time>
+</trkpt>
+<trkpt lat="15.039318" lon="120.239697">
+<ele>173.174683</ele>
+<time>2004-09-08T08:12:08Z</time>
+</trkpt>
+<trkpt lat="15.039210" lon="120.239546">
+<ele>171.732666</ele>
+<time>2004-09-08T08:12:25Z</time>
+</trkpt>
+<trkpt lat="15.038974" lon="120.238903">
+<ele>169.810059</ele>
+<time>2004-09-08T08:15:01Z</time>
+</trkpt>
+<trkpt lat="15.038953" lon="120.238860">
+<ele>169.810059</ele>
+<time>2004-09-08T08:15:17Z</time>
+</trkpt>
+<trkpt lat="15.038974" lon="120.238903">
+<ele>169.810059</ele>
+<time>2004-09-08T08:15:54Z</time>
+</trkpt>
+<trkpt lat="15.038996" lon="120.238903">
+<ele>170.771362</ele>
+<time>2004-09-08T08:17:00Z</time>
+</trkpt>
+<trkpt lat="15.038996" lon="120.238860">
+<ele>170.290649</ele>
+<time>2004-09-08T08:17:28Z</time>
+</trkpt>
+<trkpt lat="15.038910" lon="120.238709">
+<ele>169.329468</ele>
+<time>2004-09-08T08:17:44Z</time>
+</trkpt>
+<trkpt lat="15.038910" lon="120.238731">
+<ele>168.848755</ele>
+<time>2004-09-08T08:18:11Z</time>
+</trkpt>
+<trkpt lat="15.038803" lon="120.238473">
+<ele>168.368042</ele>
+<time>2004-09-08T08:18:48Z</time>
+</trkpt>
+<trkpt lat="15.038781" lon="120.238452">
+<ele>167.406738</ele>
+<time>2004-09-08T08:19:07Z</time>
+</trkpt>
+<trkpt lat="15.038717" lon="120.238216">
+<ele>167.406738</ele>
+<time>2004-09-08T08:20:20Z</time>
+</trkpt>
+<trkpt lat="15.038610" lon="120.237958">
+<ele>165.964722</ele>
+<time>2004-09-08T08:21:16Z</time>
+</trkpt>
+<trkpt lat="15.038588" lon="120.237873">
+<ele>165.003418</ele>
+<time>2004-09-08T08:21:34Z</time>
+</trkpt>
+<trkpt lat="15.038524" lon="120.237808">
+<ele>164.042114</ele>
+<time>2004-09-08T08:21:59Z</time>
+</trkpt>
+<trkpt lat="15.038524" lon="120.237765">
+<ele>164.522705</ele>
+<time>2004-09-08T08:22:02Z</time>
+</trkpt>
+<trkpt lat="15.038395" lon="120.237443">
+<ele>159.716187</ele>
+<time>2004-09-08T08:23:54Z</time>
+</trkpt>
+<trkpt lat="15.038395" lon="120.237422">
+<ele>161.158203</ele>
+<time>2004-09-08T08:24:39Z</time>
+</trkpt>
+<trkpt lat="15.038245" lon="120.237143">
+<ele>157.793579</ele>
+<time>2004-09-08T08:25:25Z</time>
+</trkpt>
+<trkpt lat="15.038266" lon="120.237100">
+<ele>157.793579</ele>
+<time>2004-09-08T08:26:41Z</time>
+</trkpt>
+<trkpt lat="15.038116" lon="120.237014">
+<ele>155.870972</ele>
+<time>2004-09-08T08:27:30Z</time>
+</trkpt>
+<trkpt lat="15.038073" lon="120.236971">
+<ele>155.870972</ele>
+<time>2004-09-08T08:27:48Z</time>
+</trkpt>
+<trkpt lat="15.037880" lon="120.236821">
+<ele>152.025757</ele>
+<time>2004-09-08T08:30:37Z</time>
+</trkpt>
+<trkpt lat="15.037816" lon="120.236778">
+<ele>152.506348</ele>
+<time>2004-09-08T08:32:19Z</time>
+</trkpt>
+<trkpt lat="15.037816" lon="120.236735">
+<ele>152.025757</ele>
+<time>2004-09-08T08:32:55Z</time>
+</trkpt>
+<trkpt lat="15.037730" lon="120.236671">
+<ele>151.064209</ele>
+<time>2004-09-08T08:33:07Z</time>
+</trkpt>
+<trkpt lat="15.037601" lon="120.236564">
+<ele>147.699707</ele>
+<time>2004-09-08T08:33:57Z</time>
+</trkpt>
+<trkpt lat="15.037301" lon="120.236349">
+<ele>146.257813</ele>
+<time>2004-09-08T08:35:52Z</time>
+</trkpt>
+<trkpt lat="15.036914" lon="120.236156">
+<ele>138.086548</ele>
+<time>2004-09-08T08:36:31Z</time>
+</trkpt>
+<trkpt lat="15.036635" lon="120.235705">
+<ele>135.202515</ele>
+<time>2004-09-08T08:38:06Z</time>
+</trkpt>
+<trkpt lat="15.036550" lon="120.235684">
+<ele>134.721924</ele>
+<time>2004-09-08T08:38:14Z</time>
+</trkpt>
+<trkpt lat="15.036356" lon="120.235813">
+<ele>133.760498</ele>
+<time>2004-09-08T08:38:34Z</time>
+</trkpt>
+<trkpt lat="15.036142" lon="120.235791">
+<ele>133.279907</ele>
+<time>2004-09-08T08:38:52Z</time>
+</trkpt>
+<trkpt lat="15.035906" lon="120.235727">
+<ele>131.357300</ele>
+<time>2004-09-08T08:40:00Z</time>
+</trkpt>
+<trkpt lat="15.035605" lon="120.235856">
+<ele>130.395996</ele>
+<time>2004-09-08T08:40:28Z</time>
+</trkpt>
+<trkpt lat="15.035155" lon="120.235834">
+<ele>131.357300</ele>
+<time>2004-09-08T08:41:23Z</time>
+</trkpt>
+<trkpt lat="15.035005" lon="120.235856">
+<ele>130.876709</ele>
+<time>2004-09-08T08:42:18Z</time>
+</trkpt>
+<trkpt lat="15.034962" lon="120.235898">
+<ele>131.357300</ele>
+<time>2004-09-08T08:42:36Z</time>
+</trkpt>
+<trkpt lat="15.034962" lon="120.235963">
+<ele>131.837891</ele>
+<time>2004-09-08T08:43:03Z</time>
+</trkpt>
+<trkpt lat="15.034962" lon="120.236156">
+<ele>131.837891</ele>
+<time>2004-09-08T08:43:19Z</time>
+</trkpt>
+<trkpt lat="15.034833" lon="120.236285">
+<ele>131.357300</ele>
+<time>2004-09-08T08:43:34Z</time>
+</trkpt>
+<trkpt lat="15.034919" lon="120.236650">
+<ele>133.760498</ele>
+<time>2004-09-08T08:45:14Z</time>
+</trkpt>
+<trkpt lat="15.034833" lon="120.236778">
+<ele>134.241211</ele>
+<time>2004-09-08T08:46:43Z</time>
+</trkpt>
+<trkpt lat="15.035090" lon="120.236928">
+<ele>135.683105</ele>
+<time>2004-09-08T08:47:40Z</time>
+</trkpt>
+<trkpt lat="15.035133" lon="120.237014">
+<ele>136.644653</ele>
+<time>2004-09-08T08:47:59Z</time>
+</trkpt>
+<trkpt lat="15.035133" lon="120.237014">
+<ele>135.202515</ele>
+<time>2004-09-08T08:48:15Z</time>
+</trkpt>
+<trkpt lat="15.035176" lon="120.237207">
+<ele>137.125244</ele>
+<time>2004-09-08T08:48:35Z</time>
+</trkpt>
+<trkpt lat="15.035155" lon="120.237207">
+<ele>136.644653</ele>
+<time>2004-09-08T08:49:29Z</time>
+</trkpt>
+<trkpt lat="15.035155" lon="120.237186">
+<ele>135.683105</ele>
+<time>2004-09-08T08:49:31Z</time>
+</trkpt>
+<trkpt lat="15.035112" lon="120.237143">
+<ele>134.241211</ele>
+<time>2004-09-08T08:49:36Z</time>
+</trkpt>
+<trkpt lat="15.034854" lon="120.236864">
+<ele>127.031372</ele>
+<time>2004-09-08T09:46:50Z</time>
+</trkpt>
+<trkpt lat="15.034811" lon="120.236864">
+<ele>124.147339</ele>
+<time>2004-09-08T09:47:29Z</time>
+</trkpt>
+<trkpt lat="15.034811" lon="120.236864">
+<ele>116.937500</ele>
+<time>2004-09-08T09:47:39Z</time>
+</trkpt>
+<trkpt lat="15.034790" lon="120.236864">
+<ele>114.053589</ele>
+<time>2004-09-08T09:47:54Z</time>
+</trkpt>
+</trkseg>
+</trk>
+<trk>
+ <name>08-SEP-04 02</name>
+<number>3</number>
+<trkseg>
+<trkpt lat="15.043309" lon="120.254095">
+<ele>206.340088</ele>
+<time>2004-09-08T07:39:34Z</time>
+</trkpt>
+<trkpt lat="15.043309" lon="120.254095">
+<ele>209.704834</ele>
+<time>2004-09-08T07:39:38Z</time>
+</trkpt>
+<trkpt lat="15.043330" lon="120.254717">
+<ele>210.666016</ele>
+<time>2004-09-08T07:41:08Z</time>
+</trkpt>
+<trkpt lat="15.043309" lon="120.254695">
+<ele>210.185425</ele>
+<time>2004-09-08T07:41:21Z</time>
+</trkpt>
+<trkpt lat="15.043201" lon="120.253429">
+<ele>207.301392</ele>
+<time>2004-09-08T07:43:06Z</time>
+</trkpt>
+<trkpt lat="15.043116" lon="120.253193">
+<ele>207.301392</ele>
+<time>2004-09-08T07:43:27Z</time>
+</trkpt>
+<trkpt lat="15.043073" lon="120.252485">
+<ele>205.378784</ele>
+<time>2004-09-08T07:45:17Z</time>
+</trkpt>
+<trkpt lat="15.043008" lon="120.251842">
+<ele>202.014282</ele>
+<time>2004-09-08T07:46:09Z</time>
+</trkpt>
+<trkpt lat="15.042858" lon="120.249889">
+<ele>195.765625</ele>
+<time>2004-09-08T07:48:50Z</time>
+</trkpt>
+<trkpt lat="15.042708" lon="120.249052">
+<ele>191.439575</ele>
+<time>2004-09-08T07:49:59Z</time>
+</trkpt>
+<trkpt lat="15.042601" lon="120.248537">
+<ele>190.478394</ele>
+<time>2004-09-08T07:50:41Z</time>
+</trkpt>
+<trkpt lat="15.042558" lon="120.247958">
+<ele>188.075073</ele>
+<time>2004-09-08T07:51:27Z</time>
+</trkpt>
+<trkpt lat="15.042579" lon="120.247872">
+<ele>188.555786</ele>
+<time>2004-09-08T07:51:46Z</time>
+</trkpt>
+<trkpt lat="15.042558" lon="120.247378">
+<ele>187.113770</ele>
+<time>2004-09-08T07:52:44Z</time>
+</trkpt>
+<trkpt lat="15.042408" lon="120.246606">
+<ele>185.191162</ele>
+<time>2004-09-08T07:54:58Z</time>
+</trkpt>
+<trkpt lat="15.042365" lon="120.246305">
+<ele>185.671753</ele>
+<time>2004-09-08T07:55:23Z</time>
+</trkpt>
+<trkpt lat="15.042236" lon="120.245962">
+<ele>184.710571</ele>
+<time>2004-09-08T07:56:05Z</time>
+</trkpt>
+<trkpt lat="15.042171" lon="120.245984">
+<ele>184.710571</ele>
+<time>2004-09-08T07:56:23Z</time>
+</trkpt>
+<trkpt lat="15.042236" lon="120.245941">
+<ele>184.710571</ele>
+<time>2004-09-08T07:57:01Z</time>
+</trkpt>
+<trkpt lat="15.042150" lon="120.245748">
+<ele>183.749023</ele>
+<time>2004-09-08T07:57:20Z</time>
+</trkpt>
+<trkpt lat="15.041893" lon="120.245233">
+<ele>182.307129</ele>
+<time>2004-09-08T07:58:05Z</time>
+</trkpt>
+<trkpt lat="15.041807" lon="120.245147">
+<ele>182.307129</ele>
+<time>2004-09-08T07:58:23Z</time>
+</trkpt>
+<trkpt lat="15.041785" lon="120.245018">
+<ele>180.865234</ele>
+<time>2004-09-08T07:58:42Z</time>
+</trkpt>
+<trkpt lat="15.041528" lon="120.244396">
+<ele>179.903809</ele>
+<time>2004-09-08T08:00:10Z</time>
+</trkpt>
+<trkpt lat="15.041463" lon="120.244160">
+<ele>179.423218</ele>
+<time>2004-09-08T08:00:31Z</time>
+</trkpt>
+<trkpt lat="15.041399" lon="120.243988">
+<ele>178.461914</ele>
+<time>2004-09-08T08:00:46Z</time>
+</trkpt>
+<trkpt lat="15.041378" lon="120.243838">
+<ele>178.942627</ele>
+<time>2004-09-08T08:02:01Z</time>
+</trkpt>
+<trkpt lat="15.041356" lon="120.243838">
+<ele>178.942627</ele>
+<time>2004-09-08T08:02:20Z</time>
+</trkpt>
+<trkpt lat="15.041313" lon="120.243623">
+<ele>177.981201</ele>
+<time>2004-09-08T08:03:02Z</time>
+</trkpt>
+<trkpt lat="15.041227" lon="120.243387">
+<ele>177.981201</ele>
+<time>2004-09-08T08:03:27Z</time>
+</trkpt>
+<trkpt lat="15.041227" lon="120.243387">
+<ele>176.539307</ele>
+<time>2004-09-08T08:03:37Z</time>
+</trkpt>
+<trkpt lat="15.040991" lon="120.243044">
+<ele>177.981201</ele>
+<time>2004-09-08T08:04:37Z</time>
+</trkpt>
+<trkpt lat="15.040519" lon="120.241756">
+<ele>177.020020</ele>
+<time>2004-09-08T08:06:26Z</time>
+</trkpt>
+<trkpt lat="15.040219" lon="120.241263">
+<ele>176.058594</ele>
+<time>2004-09-08T08:08:06Z</time>
+</trkpt>
+<trkpt lat="15.040004" lon="120.240855">
+<ele>174.135864</ele>
+<time>2004-09-08T08:09:00Z</time>
+</trkpt>
+<trkpt lat="15.039854" lon="120.240426">
+<ele>174.616577</ele>
+<time>2004-09-08T08:10:08Z</time>
+</trkpt>
+<trkpt lat="15.039704" lon="120.240104">
+<ele>174.135864</ele>
+<time>2004-09-08T08:10:37Z</time>
+</trkpt>
+<trkpt lat="15.039532" lon="120.239868">
+<ele>173.655273</ele>
+<time>2004-09-08T08:11:01Z</time>
+</trkpt>
+<trkpt lat="15.039361" lon="120.239718">
+<ele>173.174683</ele>
+<time>2004-09-08T08:11:20Z</time>
+</trkpt>
+<trkpt lat="15.039318" lon="120.239675">
+<ele>173.174683</ele>
+<time>2004-09-08T08:11:41Z</time>
+</trkpt>
+<trkpt lat="15.039318" lon="120.239697">
+<ele>173.174683</ele>
+<time>2004-09-08T08:12:08Z</time>
+</trkpt>
+<trkpt lat="15.039210" lon="120.239546">
+<ele>171.732666</ele>
+<time>2004-09-08T08:12:25Z</time>
+</trkpt>
+<trkpt lat="15.038974" lon="120.238903">
+<ele>169.810059</ele>
+<time>2004-09-08T08:15:01Z</time>
+</trkpt>
+<trkpt lat="15.038953" lon="120.238860">
+<ele>169.810059</ele>
+<time>2004-09-08T08:15:17Z</time>
+</trkpt>
+<trkpt lat="15.038974" lon="120.238903">
+<ele>169.810059</ele>
+<time>2004-09-08T08:15:54Z</time>
+</trkpt>
+<trkpt lat="15.038996" lon="120.238903">
+<ele>170.771362</ele>
+<time>2004-09-08T08:17:00Z</time>
+</trkpt>
+<trkpt lat="15.038996" lon="120.238860">
+<ele>170.290649</ele>
+<time>2004-09-08T08:17:28Z</time>
+</trkpt>
+<trkpt lat="15.038910" lon="120.238709">
+<ele>169.329468</ele>
+<time>2004-09-08T08:17:44Z</time>
+</trkpt>
+<trkpt lat="15.038910" lon="120.238731">
+<ele>168.848755</ele>
+<time>2004-09-08T08:18:11Z</time>
+</trkpt>
+<trkpt lat="15.038803" lon="120.238473">
+<ele>168.368042</ele>
+<time>2004-09-08T08:18:48Z</time>
+</trkpt>
+<trkpt lat="15.038781" lon="120.238452">
+<ele>167.406738</ele>
+<time>2004-09-08T08:19:07Z</time>
+</trkpt>
+<trkpt lat="15.038717" lon="120.238216">
+<ele>167.406738</ele>
+<time>2004-09-08T08:20:20Z</time>
+</trkpt>
+<trkpt lat="15.038610" lon="120.237958">
+<ele>165.964722</ele>
+<time>2004-09-08T08:21:16Z</time>
+</trkpt>
+<trkpt lat="15.038588" lon="120.237873">
+<ele>165.003418</ele>
+<time>2004-09-08T08:21:34Z</time>
+</trkpt>
+<trkpt lat="15.038524" lon="120.237808">
+<ele>164.042114</ele>
+<time>2004-09-08T08:21:59Z</time>
+</trkpt>
+<trkpt lat="15.038524" lon="120.237765">
+<ele>164.522705</ele>
+<time>2004-09-08T08:22:02Z</time>
+</trkpt>
+<trkpt lat="15.038395" lon="120.237443">
+<ele>159.716187</ele>
+<time>2004-09-08T08:23:54Z</time>
+</trkpt>
+<trkpt lat="15.038395" lon="120.237422">
+<ele>161.158203</ele>
+<time>2004-09-08T08:24:39Z</time>
+</trkpt>
+<trkpt lat="15.038245" lon="120.237143">
+<ele>157.793579</ele>
+<time>2004-09-08T08:25:25Z</time>
+</trkpt>
+<trkpt lat="15.038266" lon="120.237100">
+<ele>157.793579</ele>
+<time>2004-09-08T08:26:41Z</time>
+</trkpt>
+<trkpt lat="15.038116" lon="120.237014">
+<ele>155.870972</ele>
+<time>2004-09-08T08:27:30Z</time>
+</trkpt>
+<trkpt lat="15.038073" lon="120.236971">
+<ele>155.870972</ele>
+<time>2004-09-08T08:27:48Z</time>
+</trkpt>
+<trkpt lat="15.037880" lon="120.236821">
+<ele>152.025757</ele>
+<time>2004-09-08T08:30:37Z</time>
+</trkpt>
+<trkpt lat="15.037816" lon="120.236778">
+<ele>152.506348</ele>
+<time>2004-09-08T08:32:19Z</time>
+</trkpt>
+<trkpt lat="15.037816" lon="120.236735">
+<ele>152.025757</ele>
+<time>2004-09-08T08:32:55Z</time>
+</trkpt>
+<trkpt lat="15.037730" lon="120.236671">
+<ele>151.064209</ele>
+<time>2004-09-08T08:33:07Z</time>
+</trkpt>
+<trkpt lat="15.037601" lon="120.236564">
+<ele>147.699707</ele>
+<time>2004-09-08T08:33:57Z</time>
+</trkpt>
+<trkpt lat="15.037301" lon="120.236349">
+<ele>146.257813</ele>
+<time>2004-09-08T08:35:52Z</time>
+</trkpt>
+<trkpt lat="15.036914" lon="120.236156">
+<ele>138.086548</ele>
+<time>2004-09-08T08:36:31Z</time>
+</trkpt>
+<trkpt lat="15.036635" lon="120.235705">
+<ele>135.202515</ele>
+<time>2004-09-08T08:38:06Z</time>
+</trkpt>
+<trkpt lat="15.036550" lon="120.235684">
+<ele>134.721924</ele>
+<time>2004-09-08T08:38:14Z</time>
+</trkpt>
+<trkpt lat="15.036356" lon="120.235813">
+<ele>133.760498</ele>
+<time>2004-09-08T08:38:34Z</time>
+</trkpt>
+<trkpt lat="15.036142" lon="120.235791">
+<ele>133.279907</ele>
+<time>2004-09-08T08:38:52Z</time>
+</trkpt>
+<trkpt lat="15.035906" lon="120.235727">
+<ele>131.357300</ele>
+<time>2004-09-08T08:40:00Z</time>
+</trkpt>
+<trkpt lat="15.035605" lon="120.235856">
+<ele>130.395996</ele>
+<time>2004-09-08T08:40:28Z</time>
+</trkpt>
+<trkpt lat="15.035155" lon="120.235834">
+<ele>131.357300</ele>
+<time>2004-09-08T08:41:23Z</time>
+</trkpt>
+<trkpt lat="15.035005" lon="120.235856">
+<ele>130.876709</ele>
+<time>2004-09-08T08:42:18Z</time>
+</trkpt>
+<trkpt lat="15.034962" lon="120.235898">
+<ele>131.357300</ele>
+<time>2004-09-08T08:42:36Z</time>
+</trkpt>
+<trkpt lat="15.034962" lon="120.235963">
+<ele>131.837891</ele>
+<time>2004-09-08T08:43:03Z</time>
+</trkpt>
+<trkpt lat="15.034962" lon="120.236156">
+<ele>131.837891</ele>
+<time>2004-09-08T08:43:19Z</time>
+</trkpt>
+<trkpt lat="15.034833" lon="120.236285">
+<ele>131.357300</ele>
+<time>2004-09-08T08:43:34Z</time>
+</trkpt>
+<trkpt lat="15.034919" lon="120.236650">
+<ele>133.760498</ele>
+<time>2004-09-08T08:45:14Z</time>
+</trkpt>
+<trkpt lat="15.034833" lon="120.236778">
+<ele>134.241211</ele>
+<time>2004-09-08T08:46:43Z</time>
+</trkpt>
+<trkpt lat="15.035090" lon="120.236928">
+<ele>135.683105</ele>
+<time>2004-09-08T08:47:40Z</time>
+</trkpt>
+<trkpt lat="15.035133" lon="120.237014">
+<ele>136.644653</ele>
+<time>2004-09-08T08:47:59Z</time>
+</trkpt>
+<trkpt lat="15.035133" lon="120.237014">
+<ele>135.202515</ele>
+<time>2004-09-08T08:48:15Z</time>
+</trkpt>
+<trkpt lat="15.035176" lon="120.237207">
+<ele>137.125244</ele>
+<time>2004-09-08T08:48:35Z</time>
+</trkpt>
+<trkpt lat="15.035155" lon="120.237207">
+<ele>136.644653</ele>
+<time>2004-09-08T08:49:29Z</time>
+</trkpt>
+<trkpt lat="15.035155" lon="120.237186">
+<ele>135.683105</ele>
+<time>2004-09-08T08:49:31Z</time>
+</trkpt>
+<trkpt lat="15.035112" lon="120.237143">
+<ele>134.241211</ele>
+<time>2004-09-08T08:49:36Z</time>
+</trkpt>
+<trkpt lat="15.034854" lon="120.236864">
+<ele>127.031372</ele>
+<time>2004-09-08T09:46:50Z</time>
+</trkpt>
+<trkpt lat="15.034811" lon="120.236864">
+<ele>124.147339</ele>
+<time>2004-09-08T09:47:29Z</time>
+</trkpt>
+<trkpt lat="15.034811" lon="120.236864">
+<ele>120.302124</ele>
+<time>2004-09-08T09:47:33Z</time>
+</trkpt>
+<trkpt lat="15.034811" lon="120.236864">
+<ele>116.937500</ele>
+<time>2004-09-08T09:47:39Z</time>
+</trkpt>
+<trkpt lat="15.034790" lon="120.236864">
+<ele>114.053589</ele>
+<time>2004-09-08T09:47:54Z</time>
+</trkpt>
+<trkpt lat="15.034726" lon="120.236886">
+<ele>116.937500</ele>
+<time>2004-09-08T09:50:48Z</time>
+</trkpt>
+<trkpt lat="15.034769" lon="120.237293">
+<ele>108.766235</ele>
+<time>2004-09-08T11:47:25Z</time>
+</trkpt>
+<trkpt lat="15.034769" lon="120.237143">
+<ele>106.843628</ele>
+<time>2004-09-08T11:48:25Z</time>
+</trkpt>
+<trkpt lat="15.037408" lon="120.236907">
+<ele>119.821411</ele>
+<time>2004-09-09T01:02:30Z</time>
+</trkpt>
+<trkpt lat="15.037322" lon="120.236564">
+<ele>116.937500</ele>
+<time>2004-09-09T01:03:19Z</time>
+</trkpt>
+<trkpt lat="15.037301" lon="120.236542">
+<ele>119.821411</ele>
+<time>2004-09-09T01:05:55Z</time>
+</trkpt>
+<trkpt lat="15.037386" lon="120.236542">
+<ele>121.263550</ele>
+<time>2004-09-09T01:07:13Z</time>
+</trkpt>
+<trkpt lat="15.037987" lon="120.236993">
+<ele>128.473389</ele>
+<time>2004-09-09T01:08:39Z</time>
+</trkpt>
+<trkpt lat="15.038223" lon="120.237036">
+<ele>132.318604</ele>
+<time>2004-09-09T01:09:29Z</time>
+</trkpt>
+<trkpt lat="15.038331" lon="120.237207">
+<ele>133.279907</ele>
+<time>2004-09-09T01:09:49Z</time>
+</trkpt>
+<trkpt lat="15.038416" lon="120.237422">
+<ele>135.683105</ele>
+<time>2004-09-09T01:10:20Z</time>
+</trkpt>
+<trkpt lat="15.038331" lon="120.237443">
+<ele>137.125244</ele>
+<time>2004-09-09T01:11:08Z</time>
+</trkpt>
+<trkpt lat="15.038438" lon="120.237551">
+<ele>138.567261</ele>
+<time>2004-09-09T01:11:26Z</time>
+</trkpt>
+<trkpt lat="15.038481" lon="120.237658">
+<ele>140.970459</ele>
+<time>2004-09-09T01:11:46Z</time>
+</trkpt>
+<trkpt lat="15.038674" lon="120.238087">
+<ele>143.854370</ele>
+<time>2004-09-09T01:12:53Z</time>
+</trkpt>
+<trkpt lat="15.038910" lon="120.238709">
+<ele>147.699707</ele>
+<time>2004-09-09T01:14:41Z</time>
+</trkpt>
+<trkpt lat="15.039103" lon="120.239267">
+<ele>149.622314</ele>
+<time>2004-09-09T01:17:19Z</time>
+</trkpt>
+<trkpt lat="15.039232" lon="120.239482">
+<ele>151.064209</ele>
+<time>2004-09-09T01:17:59Z</time>
+</trkpt>
+<trkpt lat="15.039275" lon="120.239503">
+<ele>151.544922</ele>
+<time>2004-09-09T01:18:04Z</time>
+</trkpt>
+<trkpt lat="15.039382" lon="120.239654">
+<ele>152.986938</ele>
+<time>2004-09-09T01:18:27Z</time>
+</trkpt>
+<trkpt lat="15.039768" lon="120.240061">
+<ele>152.986938</ele>
+<time>2004-09-09T01:19:29Z</time>
+</trkpt>
+<trkpt lat="15.039897" lon="120.240319">
+<ele>153.467651</ele>
+<time>2004-09-09T01:19:55Z</time>
+</trkpt>
+<trkpt lat="15.039918" lon="120.240490">
+<ele>153.948364</ele>
+<time>2004-09-09T01:20:16Z</time>
+</trkpt>
+<trkpt lat="15.039961" lon="120.240662">
+<ele>155.390259</ele>
+<time>2004-09-09T01:20:37Z</time>
+</trkpt>
+<trkpt lat="15.040133" lon="120.241091">
+<ele>155.390259</ele>
+<time>2004-09-09T01:21:21Z</time>
+</trkpt>
+<trkpt lat="15.040326" lon="120.241477">
+<ele>158.274170</ele>
+<time>2004-09-09T01:22:26Z</time>
+</trkpt>
+<trkpt lat="15.040412" lon="120.241606">
+<ele>159.235474</ele>
+<time>2004-09-09T01:22:44Z</time>
+</trkpt>
+<trkpt lat="15.040519" lon="120.241714">
+<ele>159.716187</ele>
+<time>2004-09-09T01:23:03Z</time>
+</trkpt>
+<trkpt lat="15.040519" lon="120.241756">
+<ele>159.716187</ele>
+<time>2004-09-09T01:23:08Z</time>
+</trkpt>
+<trkpt lat="15.040584" lon="120.241842">
+<ele>160.196899</ele>
+<time>2004-09-09T01:23:18Z</time>
+</trkpt>
+<trkpt lat="15.040755" lon="120.242379">
+<ele>161.638916</ele>
+<time>2004-09-09T01:24:16Z</time>
+</trkpt>
+<trkpt lat="15.041056" lon="120.243108">
+<ele>162.600098</ele>
+<time>2004-09-09T01:25:28Z</time>
+</trkpt>
+<trkpt lat="15.041249" lon="120.243409">
+<ele>161.638916</ele>
+<time>2004-09-09T01:26:03Z</time>
+</trkpt>
+<trkpt lat="15.041292" lon="120.243537">
+<ele>161.638916</ele>
+<time>2004-09-09T01:26:42Z</time>
+</trkpt>
+<trkpt lat="15.041420" lon="120.244009">
+<ele>162.600098</ele>
+<time>2004-09-09T01:27:35Z</time>
+</trkpt>
+<trkpt lat="15.041807" lon="120.245061">
+<ele>167.887329</ele>
+<time>2004-09-09T01:29:46Z</time>
+</trkpt>
+<trkpt lat="15.042279" lon="120.245941">
+<ele>171.252075</ele>
+<time>2004-09-09T01:31:31Z</time>
+</trkpt>
+<trkpt lat="15.042279" lon="120.245962">
+<ele>170.290649</ele>
+<time>2004-09-09T01:31:46Z</time>
+</trkpt>
+<trkpt lat="15.042408" lon="120.246327">
+<ele>173.174683</ele>
+<time>2004-09-09T01:33:59Z</time>
+</trkpt>
+<trkpt lat="15.042472" lon="120.246863">
+<ele>174.616577</ele>
+<time>2004-09-09T01:34:56Z</time>
+</trkpt>
+<trkpt lat="15.042515" lon="120.246992">
+<ele>174.616577</ele>
+<time>2004-09-09T01:35:12Z</time>
+</trkpt>
+<trkpt lat="15.042579" lon="120.247314">
+<ele>176.539307</ele>
+<time>2004-09-09T01:36:56Z</time>
+</trkpt>
+<trkpt lat="15.042622" lon="120.248365">
+<ele>180.384521</ele>
+<time>2004-09-09T01:38:29Z</time>
+</trkpt>
+<trkpt lat="15.042622" lon="120.248516">
+<ele>179.903809</ele>
+<time>2004-09-09T01:38:47Z</time>
+</trkpt>
+<trkpt lat="15.042751" lon="120.249267">
+<ele>182.307129</ele>
+<time>2004-09-09T01:40:00Z</time>
+</trkpt>
+<trkpt lat="15.042794" lon="120.249438">
+<ele>184.229858</ele>
+<time>2004-09-09T01:40:17Z</time>
+</trkpt>
+<trkpt lat="15.042837" lon="120.249653">
+<ele>183.749023</ele>
+<time>2004-09-09T01:40:37Z</time>
+</trkpt>
+<trkpt lat="15.043008" lon="120.251262">
+<ele>189.997681</ele>
+<time>2004-09-09T01:43:08Z</time>
+</trkpt>
+<trkpt lat="15.043094" lon="120.252550">
+<ele>197.207520</ele>
+<time>2004-09-09T01:45:04Z</time>
+</trkpt>
+<trkpt lat="15.043287" lon="120.254116">
+<ele>202.975464</ele>
+<time>2004-09-09T01:48:23Z</time>
+</trkpt>
+<trkpt lat="15.044446" lon="120.254309">
+<ele>203.936890</ele>
+<time>2004-09-09T01:52:20Z</time>
+</trkpt>
+<trkpt lat="15.043266" lon="120.254395">
+<ele>203.936890</ele>
+<time>2004-09-09T01:52:27Z</time>
+</trkpt>
+<trkpt lat="15.043287" lon="120.254674">
+<ele>203.936890</ele>
+<time>2004-09-09T01:52:49Z</time>
+</trkpt>
+<trkpt lat="15.043309" lon="120.254931">
+<ele>204.898071</ele>
+<time>2004-09-09T01:53:10Z</time>
+</trkpt>
+<trkpt lat="15.043352" lon="120.255082">
+<ele>206.340088</ele>
+<time>2004-09-09T01:53:27Z</time>
+</trkpt>
+<trkpt lat="15.043416" lon="120.255103">
+<ele>206.340088</ele>
+<time>2004-09-09T01:53:39Z</time>
+</trkpt>
+<trkpt lat="15.043416" lon="120.255103">
+<ele>202.014282</ele>
+<time>2004-09-09T01:53:52Z</time>
+</trkpt>
+<trkpt lat="15.043437" lon="120.255103">
+<ele>205.859497</ele>
+<time>2004-09-09T01:53:54Z</time>
+</trkpt>
+<trkpt lat="15.043437" lon="120.255082">
+<ele>206.340088</ele>
+<time>2004-09-09T01:53:55Z</time>
+</trkpt>
+<trkpt lat="15.043652" lon="120.255039">
+<ele>205.859497</ele>
+<time>2004-09-09T01:54:15Z</time>
+</trkpt>
+<trkpt lat="15.044425" lon="120.254910">
+<ele>206.820679</ele>
+<time>2004-09-09T01:55:24Z</time>
+</trkpt>
+<trkpt lat="15.044682" lon="120.254889">
+<ele>210.185425</ele>
+<time>2004-09-09T01:55:52Z</time>
+</trkpt>
+<trkpt lat="15.044682" lon="120.254910">
+<ele>210.185425</ele>
+<time>2004-09-09T01:56:23Z</time>
+</trkpt>
+<trkpt lat="15.044639" lon="120.254910">
+<ele>209.704834</ele>
+<time>2004-09-09T01:56:51Z</time>
+</trkpt>
+</trkseg>
+</trk>
+<rte>
+ <name>10-SEP-04</name>
+<number>4</number>
+<rtept lat="15.044639" lon="120.254910">
+<ele>209.704834</ele>
+<time>2004-09-09T01:57:08Z</time>
+</rtept>
+<rtept lat="15.044446" lon="120.254910">
+<ele>206.340088</ele>
+<time>2004-09-09T01:57:48Z</time>
+</rtept>
+<rtept lat="15.044231" lon="120.254931">
+<ele>206.340088</ele>
+<time>2004-09-09T01:58:07Z</time>
+</rtept>
+<rtept lat="15.043373" lon="120.255103">
+<ele>207.782104</ele>
+<time>2004-09-09T01:59:24Z</time>
+</rtept>
+<rtept lat="15.043330" lon="120.255060">
+<ele>206.820679</ele>
+<time>2004-09-09T01:59:31Z</time>
+</rtept>
+<rtept lat="15.043309" lon="120.254738">
+<ele>205.859497</ele>
+<time>2004-09-09T01:59:57Z</time>
+</rtept>
+<rtept lat="15.043244" lon="120.254374">
+<ele>206.340088</ele>
+<time>2004-09-09T02:00:51Z</time>
+</rtept>
+<rtept lat="15.043180" lon="120.253386">
+<ele>203.456177</ele>
+<time>2004-09-09T02:02:25Z</time>
+</rtept>
+<rtept lat="15.043094" lon="120.253150">
+<ele>202.975464</ele>
+<time>2004-09-09T02:02:45Z</time>
+</rtept>
+<rtept lat="15.043094" lon="120.252850">
+<ele>201.533569</ele>
+<time>2004-09-09T02:03:07Z</time>
+</rtept>
+<rtept lat="15.043051" lon="120.252550">
+<ele>201.533569</ele>
+<time>2004-09-09T02:03:29Z</time>
+</rtept>
+<rtept lat="15.043051" lon="120.252228">
+<ele>199.610840</ele>
+<time>2004-09-09T02:03:53Z</time>
+</rtept>
+<rtept lat="15.042944" lon="120.251219">
+<ele>195.765625</ele>
+<time>2004-09-09T02:05:15Z</time>
+</rtept>
+<rtept lat="15.042880" lon="120.250597">
+<ele>194.323730</ele>
+<time>2004-09-09T02:06:13Z</time>
+</rtept>
+<rtept lat="15.042880" lon="120.250340">
+<ele>193.843018</ele>
+<time>2004-09-09T02:06:34Z</time>
+</rtept>
+<rtept lat="15.042815" lon="120.249782">
+<ele>190.478394</ele>
+<time>2004-09-09T02:07:16Z</time>
+</rtept>
+<rtept lat="15.042622" lon="120.248687">
+<ele>186.152466</ele>
+<time>2004-09-09T02:08:40Z</time>
+</rtept>
+<rtept lat="15.042579" lon="120.248451">
+<ele>185.671753</ele>
+<time>2004-09-09T02:08:59Z</time>
+</rtept>
+<rtept lat="15.042558" lon="120.247850">
+<ele>183.749023</ele>
+<time>2004-09-09T02:09:44Z</time>
+</rtept>
+<rtept lat="15.042515" lon="120.247207">
+<ele>182.787842</ele>
+<time>2004-09-09T02:10:33Z</time>
+</rtept>
+<rtept lat="15.042365" lon="120.246348">
+<ele>181.345825</ele>
+<time>2004-09-09T02:11:44Z</time>
+</rtept>
+<rtept lat="15.042107" lon="120.245705">
+<ele>179.423218</ele>
+<time>2004-09-09T02:12:40Z</time>
+</rtept>
+<rtept lat="15.042000" lon="120.245490">
+<ele>178.461914</ele>
+<time>2004-09-09T02:12:59Z</time>
+</rtept>
+<rtept lat="15.041893" lon="120.245275">
+<ele>177.981201</ele>
+<time>2004-09-09T02:13:18Z</time>
+</rtept>
+<rtept lat="15.041764" lon="120.245061">
+<ele>176.539307</ele>
+<time>2004-09-09T02:13:38Z</time>
+</rtept>
+<rtept lat="15.041635" lon="120.244761">
+<ele>175.577881</ele>
+<time>2004-09-09T02:14:01Z</time>
+</rtept>
+<rtept lat="15.041399" lon="120.244117">
+<ele>175.577881</ele>
+<time>2004-09-09T02:15:03Z</time>
+</rtept>
+<rtept lat="15.041206" lon="120.243430">
+<ele>175.577881</ele>
+<time>2004-09-09T02:16:02Z</time>
+</rtept>
+<rtept lat="15.041034" lon="120.243173">
+<ele>175.577881</ele>
+<time>2004-09-09T02:16:24Z</time>
+</rtept>
+<rtept lat="15.040863" lon="120.242808">
+<ele>174.616577</ele>
+<time>2004-09-09T02:17:06Z</time>
+</rtept>
+<rtept lat="15.040798" lon="120.242572">
+<ele>174.135864</ele>
+<time>2004-09-09T02:17:26Z</time>
+</rtept>
+<rtept lat="15.040691" lon="120.242336">
+<ele>174.135864</ele>
+<time>2004-09-09T02:17:50Z</time>
+</rtept>
+<rtept lat="15.040627" lon="120.242164">
+<ele>173.655273</ele>
+<time>2004-09-09T02:18:23Z</time>
+</rtept>
+<rtept lat="15.040562" lon="120.241885">
+<ele>173.174683</ele>
+<time>2004-09-09T02:18:45Z</time>
+</rtept>
+<rtept lat="15.040412" lon="120.241649">
+<ele>173.655273</ele>
+<time>2004-09-09T02:19:07Z</time>
+</rtept>
+<rtept lat="15.040219" lon="120.241306">
+<ele>172.213257</ele>
+<time>2004-09-09T02:19:40Z</time>
+</rtept>
+<rtept lat="15.040240" lon="120.241263">
+<ele>171.732666</ele>
+<time>2004-09-09T02:25:56Z</time>
+</rtept>
+<rtept lat="15.040219" lon="120.241263">
+<ele>171.252075</ele>
+<time>2004-09-09T02:26:48Z</time>
+</rtept>
+<rtept lat="15.040219" lon="120.241241">
+<ele>172.693970</ele>
+<time>2004-09-09T02:27:16Z</time>
+</rtept>
+<rtept lat="15.040305" lon="120.241241">
+<ele>172.213257</ele>
+<time>2004-09-09T02:27:32Z</time>
+</rtept>
+<rtept lat="15.040176" lon="120.241263">
+<ele>171.252075</ele>
+<time>2004-09-09T02:30:30Z</time>
+</rtept>
+<rtept lat="15.040176" lon="120.241220">
+<ele>170.771362</ele>
+<time>2004-09-09T02:31:16Z</time>
+</rtept>
+<rtept lat="15.040047" lon="120.240963">
+<ele>169.810059</ele>
+<time>2004-09-09T02:31:39Z</time>
+</rtept>
+<rtept lat="15.039940" lon="120.240748">
+<ele>170.290649</ele>
+<time>2004-09-09T02:31:59Z</time>
+</rtept>
+<rtept lat="15.039768" lon="120.240233">
+<ele>169.810059</ele>
+<time>2004-09-09T02:32:44Z</time>
+</rtept>
+<rtept lat="15.039575" lon="120.239954">
+<ele>169.329468</ele>
+<time>2004-09-09T02:33:10Z</time>
+</rtept>
+<rtept lat="15.039339" lon="120.239739">
+<ele>168.368042</ele>
+<time>2004-09-09T02:33:34Z</time>
+</rtept>
+<rtept lat="15.039189" lon="120.239654">
+<ele>168.368042</ele>
+<time>2004-09-09T02:34:06Z</time>
+</rtept>
+<rtept lat="15.038867" lon="120.239525">
+<ele>164.522705</ele>
+<time>2004-09-09T02:34:40Z</time>
+</rtept>
+<rtept lat="15.038416" lon="120.239267">
+<ele>162.119507</ele>
+<time>2004-09-09T02:35:26Z</time>
+</rtept>
+<rtept lat="15.038202" lon="120.239096">
+<ele>160.677490</ele>
+<time>2004-09-09T02:35:49Z</time>
+</rtept>
+<rtept lat="15.038009" lon="120.238881">
+<ele>160.677490</ele>
+<time>2004-09-09T02:36:11Z</time>
+</rtept>
+<rtept lat="15.037751" lon="120.238602">
+<ele>158.274170</ele>
+<time>2004-09-09T02:36:38Z</time>
+</rtept>
+<rtept lat="15.037537" lon="120.238409">
+<ele>157.793579</ele>
+<time>2004-09-09T02:36:59Z</time>
+</rtept>
+<rtept lat="15.036936" lon="120.238109">
+<ele>152.506348</ele>
+<time>2004-09-09T02:37:52Z</time>
+</rtept>
+<rtept lat="15.036571" lon="120.237894">
+<ele>152.025757</ele>
+<time>2004-09-09T02:38:44Z</time>
+</rtept>
+<rtept lat="15.036399" lon="120.237722">
+<ele>148.661011</ele>
+<time>2004-09-09T02:39:08Z</time>
+</rtept>
+<rtept lat="15.036056" lon="120.237486">
+<ele>147.218994</ele>
+<time>2004-09-09T02:39:40Z</time>
+</rtept>
+<rtept lat="15.035348" lon="120.237379">
+<ele>138.567261</ele>
+<time>2004-09-09T02:40:39Z</time>
+</rtept>
+<rtept lat="15.035241" lon="120.237207">
+<ele>136.644653</ele>
+<time>2004-09-09T02:41:17Z</time>
+</rtept>
+<rtept lat="15.035241" lon="120.237207">
+<ele>133.279907</ele>
+<time>2004-09-09T02:41:20Z</time>
+</rtept>
+<rtept lat="15.035241" lon="120.237207">
+<ele>137.605835</ele>
+<time>2004-09-09T02:41:21Z</time>
+</rtept>
+<rtept lat="15.035241" lon="120.237207">
+<ele>134.241211</ele>
+<time>2004-09-09T02:41:22Z</time>
+</rtept>
+<rtept lat="15.035241" lon="120.237186">
+<ele>136.644653</ele>
+<time>2004-09-09T02:41:36Z</time>
+</rtept>
+<rtept lat="15.035563" lon="120.236864">
+<ele>135.683105</ele>
+<time>2004-09-09T02:42:31Z</time>
+</rtept>
+<rtept lat="15.035756" lon="120.236499">
+<ele>132.799316</ele>
+<time>2004-09-09T02:43:04Z</time>
+</rtept>
+<rtept lat="15.036013" lon="120.235684">
+<ele>129.915283</ele>
+<time>2004-09-09T02:44:37Z</time>
+</rtept>
+<rtept lat="15.036056" lon="120.235620">
+<ele>130.395996</ele>
+<time>2004-09-09T02:44:52Z</time>
+</rtept>
+<rtept lat="15.036035" lon="120.235662">
+<ele>131.357300</ele>
+<time>2004-09-09T02:44:58Z</time>
+</rtept>
+<rtept lat="15.035992" lon="120.235791">
+<ele>129.434692</ele>
+<time>2004-09-09T02:45:12Z</time>
+</rtept>
+<rtept lat="15.036013" lon="120.235813">
+<ele>129.434692</ele>
+<time>2004-09-09T02:45:17Z</time>
+</rtept>
+<rtept lat="15.038309" lon="120.235984">
+<ele>147.699707</ele>
+<time>2004-09-09T03:40:20Z</time>
+</rtept>
+<rtept lat="15.037258" lon="120.236478">
+<ele>144.335205</ele>
+<time>2004-09-09T03:41:06Z</time>
+</rtept>
+<rtept lat="15.037000" lon="120.236435">
+<ele>139.047852</ele>
+<time>2004-09-09T03:41:50Z</time>
+</rtept>
+<rtept lat="15.037000" lon="120.236413">
+<ele>139.528442</ele>
+<time>2004-09-09T03:42:03Z</time>
+</rtept>
+<rtept lat="15.036936" lon="120.236413">
+<ele>140.009155</ele>
+<time>2004-09-09T03:42:24Z</time>
+</rtept>
+<rtept lat="15.036786" lon="120.236371">
+<ele>139.528442</ele>
+<time>2004-09-09T03:42:39Z</time>
+</rtept>
+<rtept lat="15.036635" lon="120.236349">
+<ele>140.970459</ele>
+<time>2004-09-09T03:42:55Z</time>
+</rtept>
+<rtept lat="15.036592" lon="120.236349">
+<ele>139.528442</ele>
+<time>2004-09-09T03:43:14Z</time>
+</rtept>
+<rtept lat="15.036592" lon="120.236371">
+<ele>141.451050</ele>
+<time>2004-09-09T03:43:28Z</time>
+</rtept>
+<rtept lat="15.036378" lon="120.236242">
+<ele>135.202515</ele>
+<time>2004-09-09T03:44:01Z</time>
+</rtept>
+<rtept lat="15.036378" lon="120.236242">
+<ele>133.279907</ele>
+<time>2004-09-09T03:44:06Z</time>
+</rtept>
+<rtept lat="15.036356" lon="120.236177">
+<ele>132.318604</ele>
+<time>2004-09-09T03:44:16Z</time>
+</rtept>
+<rtept lat="15.036249" lon="120.236135">
+<ele>135.202515</ele>
+<time>2004-09-09T03:44:41Z</time>
+</rtept>
+<rtept lat="15.036249" lon="120.236199">
+<ele>136.644653</ele>
+<time>2004-09-09T03:45:01Z</time>
+</rtept>
+<rtept lat="15.036206" lon="120.236263">
+<ele>139.528442</ele>
+<time>2004-09-09T03:45:40Z</time>
+</rtept>
+<rtept lat="15.036206" lon="120.236328">
+<ele>142.893066</ele>
+<time>2004-09-09T03:46:08Z</time>
+</rtept>
+<rtept lat="15.036228" lon="120.236392">
+<ele>141.931763</ele>
+<time>2004-09-09T03:46:26Z</time>
+</rtept>
+<rtept lat="15.036271" lon="120.236392">
+<ele>140.970459</ele>
+<time>2004-09-09T03:46:38Z</time>
+</rtept>
+<rtept lat="15.036271" lon="120.236413">
+<ele>140.489868</ele>
+<time>2004-09-09T03:46:43Z</time>
+</rtept>
+<rtept lat="15.036249" lon="120.236456">
+<ele>141.451050</ele>
+<time>2004-09-09T03:47:02Z</time>
+</rtept>
+<rtept lat="15.036206" lon="120.236456">
+<ele>141.451050</ele>
+<time>2004-09-09T03:47:21Z</time>
+</rtept>
+<rtept lat="15.036206" lon="120.236478">
+<ele>141.931763</ele>
+<time>2004-09-09T03:47:22Z</time>
+</rtept>
+<rtept lat="15.036077" lon="120.236499">
+<ele>141.931763</ele>
+<time>2004-09-09T03:47:43Z</time>
+</rtept>
+<rtept lat="15.035927" lon="120.236542">
+<ele>136.163940</ele>
+<time>2004-09-09T03:48:13Z</time>
+</rtept>
+<rtept lat="15.035691" lon="120.236542">
+<ele>133.279907</ele>
+<time>2004-09-09T03:48:35Z</time>
+</rtept>
+<rtept lat="15.035434" lon="120.236456">
+<ele>130.876709</ele>
+<time>2004-09-09T03:49:25Z</time>
+</rtept>
+<rtept lat="15.035348" lon="120.236499">
+<ele>131.357300</ele>
+<time>2004-09-09T03:49:42Z</time>
+</rtept>
+<rtept lat="15.035219" lon="120.236499">
+<ele>130.876709</ele>
+<time>2004-09-09T03:50:05Z</time>
+</rtept>
+<rtept lat="15.035219" lon="120.236478">
+<ele>130.395996</ele>
+<time>2004-09-09T03:50:59Z</time>
+</rtept>
+<rtept lat="15.034747" lon="120.235770">
+<ele>130.876709</ele>
+<time>2004-09-09T03:51:15Z</time>
+</rtept>
+<rtept lat="15.034897" lon="120.236521">
+<ele>130.876709</ele>
+<time>2004-09-09T03:51:18Z</time>
+</rtept>
+<rtept lat="15.034919" lon="120.237143">
+<ele>134.241211</ele>
+<time>2004-09-09T03:52:59Z</time>
+</rtept>
+<rtept lat="15.034897" lon="120.237036">
+<ele>134.241211</ele>
+<time>2004-09-09T03:53:21Z</time>
+</rtept>
+<rtept lat="15.034811" lon="120.235405">
+<ele>123.666748</ele>
+<time>2004-09-09T23:03:55Z</time>
+</rtept>
+<rtept lat="15.034854" lon="120.235384">
+<ele>120.782837</ele>
+<time>2004-09-09T23:04:11Z</time>
+</rtept>
+<rtept lat="15.034811" lon="120.235426">
+<ele>117.418213</ele>
+<time>2004-09-09T23:04:18Z</time>
+</rtept>
+<rtept lat="15.034726" lon="120.235405">
+<ele>115.014893</ele>
+<time>2004-09-09T23:04:24Z</time>
+</rtept>
+<rtept lat="15.034575" lon="120.235362">
+<ele>112.611572</ele>
+<time>2004-09-09T23:04:40Z</time>
+</rtept>
+<rtept lat="15.034533" lon="120.235298">
+<ele>113.092285</ele>
+<time>2004-09-09T23:04:48Z</time>
+</rtept>
+<rtept lat="15.034468" lon="120.235019">
+<ele>112.611572</ele>
+<time>2004-09-09T23:05:12Z</time>
+</rtept>
+<rtept lat="15.034339" lon="120.234783">
+<ele>113.572998</ele>
+<time>2004-09-09T23:05:30Z</time>
+</rtept>
+<rtept lat="15.034168" lon="120.234590">
+<ele>115.014893</ele>
+<time>2004-09-09T23:05:51Z</time>
+</rtept>
+<rtept lat="15.034039" lon="120.234461">
+<ele>115.014893</ele>
+<time>2004-09-09T23:06:05Z</time>
+</rtept>
+<rtept lat="15.033846" lon="120.233989">
+<ele>113.572998</ele>
+<time>2004-09-09T23:06:45Z</time>
+</rtept>
+<rtept lat="15.033395" lon="120.233603">
+<ele>112.611572</ele>
+<time>2004-09-09T23:07:30Z</time>
+</rtept>
+<rtept lat="15.033288" lon="120.233409">
+<ele>111.650269</ele>
+<time>2004-09-09T23:07:47Z</time>
+</rtept>
+<rtept lat="15.033159" lon="120.233173">
+<ele>111.650269</ele>
+<time>2004-09-09T23:08:07Z</time>
+</rtept>
+<rtept lat="15.033138" lon="120.232766">
+<ele>112.130981</ele>
+<time>2004-09-09T23:08:40Z</time>
+</rtept>
+<rtept lat="15.032988" lon="120.232229">
+<ele>110.688843</ele>
+<time>2004-09-09T23:09:20Z</time>
+</rtept>
+<rtept lat="15.032730" lon="120.231693">
+<ele>109.246948</ele>
+<time>2004-09-09T23:10:03Z</time>
+</rtept>
+<rtept lat="15.032258" lon="120.231113">
+<ele>107.324341</ele>
+<time>2004-09-09T23:11:04Z</time>
+</rtept>
+<rtept lat="15.032001" lon="120.230727">
+<ele>104.921021</ele>
+<time>2004-09-09T23:11:43Z</time>
+</rtept>
+<rtept lat="15.031657" lon="120.230405">
+<ele>102.517700</ele>
+<time>2004-09-09T23:12:21Z</time>
+</rtept>
+<rtept lat="15.031507" lon="120.230212">
+<ele>102.037109</ele>
+<time>2004-09-09T23:12:40Z</time>
+</rtept>
+<rtept lat="15.031357" lon="120.230105">
+<ele>102.517700</ele>
+<time>2004-09-09T23:12:56Z</time>
+</rtept>
+<rtept lat="15.030606" lon="120.229740">
+<ele>100.595093</ele>
+<time>2004-09-09T23:14:06Z</time>
+</rtept>
+<rtept lat="15.029833" lon="120.229611">
+<ele>101.556396</ele>
+<time>2004-09-09T23:15:16Z</time>
+</rtept>
+<rtept lat="15.029318" lon="120.229418">
+<ele>100.114502</ele>
+<time>2004-09-09T23:15:56Z</time>
+</rtept>
+<rtept lat="15.029104" lon="120.229397">
+<ele>99.153076</ele>
+<time>2004-09-09T23:16:15Z</time>
+</rtept>
+<rtept lat="15.028782" lon="120.229247">
+<ele>99.633789</ele>
+<time>2004-09-09T23:16:44Z</time>
+</rtept>
+<rtept lat="15.028546" lon="120.229204">
+<ele>98.672485</ele>
+<time>2004-09-09T23:17:01Z</time>
+</rtept>
+<rtept lat="15.028288" lon="120.229268">
+<ele>98.191895</ele>
+<time>2004-09-09T23:17:21Z</time>
+</rtept>
+<rtept lat="15.028245" lon="120.229268">
+<ele>97.711182</ele>
+<time>2004-09-09T23:17:26Z</time>
+</rtept>
+<rtept lat="15.028181" lon="120.229225">
+<ele>97.230469</ele>
+<time>2004-09-09T23:17:41Z</time>
+</rtept>
+<rtept lat="15.028074" lon="120.229096">
+<ele>97.711182</ele>
+<time>2004-09-09T23:18:08Z</time>
+</rtept>
+<rtept lat="15.027966" lon="120.229053">
+<ele>97.230469</ele>
+<time>2004-09-09T23:18:22Z</time>
+</rtept>
+<rtept lat="15.027838" lon="120.229011">
+<ele>96.749878</ele>
+<time>2004-09-09T23:18:33Z</time>
+</rtept>
+<rtept lat="15.027494" lon="120.228989">
+<ele>96.749878</ele>
+<time>2004-09-09T23:19:09Z</time>
+</rtept>
+<rtept lat="15.027344" lon="120.228946">
+<ele>96.269287</ele>
+<time>2004-09-09T23:19:20Z</time>
+</rtept>
+<rtept lat="15.027194" lon="120.228732">
+<ele>96.269287</ele>
+<time>2004-09-09T23:19:40Z</time>
+</rtept>
+<rtept lat="15.026979" lon="120.228624">
+<ele>96.749878</ele>
+<time>2004-09-09T23:20:00Z</time>
+</rtept>
+<rtept lat="15.026743" lon="120.228646">
+<ele>95.307739</ele>
+<time>2004-09-09T23:20:29Z</time>
+</rtept>
+<rtept lat="15.026507" lon="120.228624">
+<ele>93.865845</ele>
+<time>2004-09-09T23:21:03Z</time>
+</rtept>
+<rtept lat="15.026164" lon="120.228517">
+<ele>94.827148</ele>
+<time>2004-09-09T23:21:49Z</time>
+</rtept>
+<rtept lat="15.025692" lon="120.228496">
+<ele>94.346558</ele>
+<time>2004-09-09T23:22:23Z</time>
+</rtept>
+<rtept lat="15.025198" lon="120.228345">
+<ele>93.865845</ele>
+<time>2004-09-09T23:23:01Z</time>
+</rtept>
+<rtept lat="15.024984" lon="120.228324">
+<ele>94.346558</ele>
+<time>2004-09-09T23:23:17Z</time>
+</rtept>
+<rtept lat="15.024705" lon="120.228260">
+<ele>93.385132</ele>
+<time>2004-09-09T23:23:38Z</time>
+</rtept>
+<rtept lat="15.024126" lon="120.228002">
+<ele>93.865845</ele>
+<time>2004-09-09T23:24:22Z</time>
+</rtept>
+<rtept lat="15.024061" lon="120.227959">
+<ele>94.346558</ele>
+<time>2004-09-09T23:24:28Z</time>
+</rtept>
+<rtept lat="15.023997" lon="120.227852">
+<ele>93.865845</ele>
+<time>2004-09-09T23:24:37Z</time>
+</rtept>
+<rtept lat="15.023718" lon="120.227787">
+<ele>93.385132</ele>
+<time>2004-09-09T23:24:59Z</time>
+</rtept>
+<rtept lat="15.023460" lon="120.227787">
+<ele>92.904541</ele>
+<time>2004-09-09T23:25:18Z</time>
+</rtept>
+<rtept lat="15.023332" lon="120.227787">
+<ele>92.904541</ele>
+<time>2004-09-09T23:25:28Z</time>
+</rtept>
+<rtept lat="15.023053" lon="120.227723">
+<ele>92.904541</ele>
+<time>2004-09-09T23:25:49Z</time>
+</rtept>
+<rtept lat="15.022838" lon="120.227616">
+<ele>91.943237</ele>
+<time>2004-09-09T23:26:07Z</time>
+</rtept>
+<rtept lat="15.022345" lon="120.227230">
+<ele>90.501343</ele>
+<time>2004-09-09T23:26:51Z</time>
+</rtept>
+<rtept lat="15.021808" lon="120.226994">
+<ele>90.020630</ele>
+<time>2004-09-09T23:27:34Z</time>
+</rtept>
+<rtept lat="15.021508" lon="120.226843">
+<ele>89.059326</ele>
+<time>2004-09-09T23:27:57Z</time>
+</rtept>
+<rtept lat="15.021207" lon="120.226758">
+<ele>90.020630</ele>
+<time>2004-09-09T23:28:19Z</time>
+</rtept>
+<rtept lat="15.020885" lon="120.226307">
+<ele>88.578735</ele>
+<time>2004-09-09T23:29:02Z</time>
+</rtept>
+<rtept lat="15.020757" lon="120.226200">
+<ele>90.020630</ele>
+<time>2004-09-09T23:29:16Z</time>
+</rtept>
+<rtept lat="15.020392" lon="120.225964">
+<ele>88.578735</ele>
+<time>2004-09-09T23:29:51Z</time>
+</rtept>
+<rtept lat="15.020263" lon="120.225770">
+<ele>88.578735</ele>
+<time>2004-09-09T23:30:21Z</time>
+</rtept>
+<rtept lat="15.019898" lon="120.225384">
+<ele>86.656006</ele>
+<time>2004-09-09T23:31:00Z</time>
+</rtept>
+<rtept lat="15.019598" lon="120.225148">
+<ele>87.136597</ele>
+<time>2004-09-09T23:31:38Z</time>
+</rtept>
+<rtept lat="15.019362" lon="120.224891">
+<ele>87.617188</ele>
+<time>2004-09-09T23:32:28Z</time>
+</rtept>
+<rtept lat="15.019104" lon="120.224805">
+<ele>88.098022</ele>
+<time>2004-09-09T23:33:04Z</time>
+</rtept>
+<rtept lat="15.018568" lon="120.224719">
+<ele>87.136597</ele>
+<time>2004-09-09T23:33:44Z</time>
+</rtept>
+<rtept lat="15.018375" lon="120.224633">
+<ele>87.136597</ele>
+<time>2004-09-09T23:34:00Z</time>
+</rtept>
+<rtept lat="15.018311" lon="120.224633">
+<ele>86.175293</ele>
+<time>2004-09-09T23:34:05Z</time>
+</rtept>
+<rtept lat="15.017774" lon="120.224655">
+<ele>89.059326</ele>
+<time>2004-09-09T23:34:46Z</time>
+</rtept>
+<rtept lat="15.017409" lon="120.224504">
+<ele>86.175293</ele>
+<time>2004-09-09T23:35:19Z</time>
+</rtept>
+<rtept lat="15.016787" lon="120.224462">
+<ele>86.175293</ele>
+<time>2004-09-09T23:36:10Z</time>
+</rtept>
+<rtept lat="15.016615" lon="120.224419">
+<ele>85.213989</ele>
+<time>2004-09-09T23:36:59Z</time>
+</rtept>
+<rtept lat="15.016315" lon="120.224097">
+<ele>84.733398</ele>
+<time>2004-09-09T23:37:39Z</time>
+</rtept>
+<rtept lat="15.015972" lon="120.223818">
+<ele>83.771973</ele>
+<time>2004-09-09T23:38:14Z</time>
+</rtept>
+<rtept lat="15.015736" lon="120.223689">
+<ele>83.771973</ele>
+<time>2004-09-09T23:38:46Z</time>
+</rtept>
+<rtept lat="15.015564" lon="120.223625">
+<ele>84.733398</ele>
+<time>2004-09-09T23:39:31Z</time>
+</rtept>
+<rtept lat="15.015500" lon="120.223625">
+<ele>84.252686</ele>
+<time>2004-09-09T23:39:46Z</time>
+</rtept>
+<rtept lat="15.015435" lon="120.223582">
+<ele>84.733398</ele>
+<time>2004-09-09T23:39:58Z</time>
+</rtept>
+<rtept lat="15.015113" lon="120.223346">
+<ele>84.733398</ele>
+<time>2004-09-09T23:40:35Z</time>
+</rtept>
+<rtept lat="15.015006" lon="120.223174">
+<ele>85.694580</ele>
+<time>2004-09-09T23:40:51Z</time>
+</rtept>
+<rtept lat="15.014813" lon="120.222766">
+<ele>83.771973</ele>
+<time>2004-09-09T23:41:31Z</time>
+</rtept>
+<rtept lat="15.014770" lon="120.222487">
+<ele>84.252686</ele>
+<time>2004-09-09T23:41:53Z</time>
+</rtept>
+<rtept lat="15.014749" lon="120.222337">
+<ele>82.810791</ele>
+<time>2004-09-09T23:42:14Z</time>
+</rtept>
+<rtept lat="15.014641" lon="120.221930">
+<ele>84.733398</ele>
+<time>2004-09-09T23:42:49Z</time>
+</rtept>
+<rtept lat="15.014448" lon="120.222015">
+<ele>85.694580</ele>
+<time>2004-09-09T23:43:06Z</time>
+</rtept>
+<rtept lat="15.014427" lon="120.222230">
+<ele>86.175293</ele>
+<time>2004-09-09T23:43:22Z</time>
+</rtept>
+<rtept lat="15.014319" lon="120.222273">
+<ele>86.175293</ele>
+<time>2004-09-09T23:43:35Z</time>
+</rtept>
+<rtept lat="15.014277" lon="120.222251">
+<ele>86.656006</ele>
+<time>2004-09-09T23:43:39Z</time>
+</rtept>
+<rtept lat="15.014148" lon="120.222101">
+<ele>86.175293</ele>
+<time>2004-09-09T23:43:58Z</time>
+</rtept>
+<rtept lat="15.013912" lon="120.221908">
+<ele>87.617188</ele>
+<time>2004-09-09T23:44:39Z</time>
+</rtept>
+<rtept lat="15.013826" lon="120.221736">
+<ele>89.539917</ele>
+<time>2004-09-09T23:44:57Z</time>
+</rtept>
+<rtept lat="15.013268" lon="120.221350">
+<ele>90.020630</ele>
+<time>2004-09-09T23:45:51Z</time>
+</rtept>
+<rtept lat="15.013075" lon="120.220857">
+<ele>90.501343</ele>
+<time>2004-09-09T23:46:40Z</time>
+</rtept>
+<rtept lat="15.013011" lon="120.220599">
+<ele>90.981934</ele>
+<time>2004-09-09T23:47:01Z</time>
+</rtept>
+<rtept lat="15.012753" lon="120.220063">
+<ele>90.501343</ele>
+<time>2004-09-09T23:47:45Z</time>
+</rtept>
+<rtept lat="15.012732" lon="120.219998">
+<ele>90.981934</ele>
+<time>2004-09-09T23:47:59Z</time>
+</rtept>
+<rtept lat="15.012753" lon="120.219870">
+<ele>91.462524</ele>
+<time>2004-09-09T23:48:36Z</time>
+</rtept>
+<rtept lat="15.012560" lon="120.219569">
+<ele>90.501343</ele>
+<time>2004-09-09T23:49:00Z</time>
+</rtept>
+<rtept lat="15.012496" lon="120.219419">
+<ele>90.501343</ele>
+<time>2004-09-09T23:49:20Z</time>
+</rtept>
+<rtept lat="15.012045" lon="120.219097">
+<ele>90.501343</ele>
+<time>2004-09-09T23:50:19Z</time>
+</rtept>
+<rtept lat="15.011959" lon="120.218990">
+<ele>90.501343</ele>
+<time>2004-09-09T23:50:32Z</time>
+</rtept>
+<rtept lat="15.011873" lon="120.218925">
+<ele>90.501343</ele>
+<time>2004-09-09T23:50:45Z</time>
+</rtept>
+<rtept lat="15.011809" lon="120.218818">
+<ele>90.020630</ele>
+<time>2004-09-09T23:51:07Z</time>
+</rtept>
+<rtept lat="15.011337" lon="120.218518">
+<ele>90.501343</ele>
+<time>2004-09-09T23:51:50Z</time>
+</rtept>
+<rtept lat="15.010564" lon="120.218046">
+<ele>89.059326</ele>
+<time>2004-09-09T23:52:56Z</time>
+</rtept>
+<rtept lat="15.010328" lon="120.217874">
+<ele>90.020630</ele>
+<time>2004-09-09T23:53:17Z</time>
+</rtept>
+<rtept lat="15.010200" lon="120.217595">
+<ele>89.059326</ele>
+<time>2004-09-09T23:53:39Z</time>
+</rtept>
+<rtept lat="15.009985" lon="120.217359">
+<ele>89.059326</ele>
+<time>2004-09-09T23:54:03Z</time>
+</rtept>
+<rtept lat="15.009727" lon="120.217230">
+<ele>90.501343</ele>
+<time>2004-09-09T23:54:26Z</time>
+</rtept>
+<rtept lat="15.009470" lon="120.217187">
+<ele>90.501343</ele>
+<time>2004-09-09T23:54:44Z</time>
+</rtept>
+<rtept lat="15.008826" lon="120.217102">
+<ele>89.539917</ele>
+<time>2004-09-09T23:55:30Z</time>
+</rtept>
+<rtept lat="15.008633" lon="120.216951">
+<ele>89.059326</ele>
+<time>2004-09-09T23:55:49Z</time>
+</rtept>
+<rtept lat="15.008333" lon="120.216887">
+<ele>89.059326</ele>
+<time>2004-09-09T23:56:11Z</time>
+</rtept>
+<rtept lat="15.007989" lon="120.216844">
+<ele>88.578735</ele>
+<time>2004-09-09T23:56:37Z</time>
+</rtept>
+<rtept lat="15.007753" lon="120.216908">
+<ele>88.578735</ele>
+<time>2004-09-09T23:56:55Z</time>
+</rtept>
+<rtept lat="15.007582" lon="120.217016">
+<ele>87.136597</ele>
+<time>2004-09-09T23:57:16Z</time>
+</rtept>
+<rtept lat="15.007303" lon="120.216908">
+<ele>86.175293</ele>
+<time>2004-09-09T23:57:43Z</time>
+</rtept>
+<rtept lat="15.007174" lon="120.216930">
+<ele>86.175293</ele>
+<time>2004-09-09T23:57:53Z</time>
+</rtept>
+<rtept lat="15.007110" lon="120.216908">
+<ele>82.330078</ele>
+<time>2004-09-09T23:58:03Z</time>
+</rtept>
+<rtept lat="15.007110" lon="120.216908">
+<ele>86.656006</ele>
+<time>2004-09-09T23:58:04Z</time>
+</rtept>
+<rtept lat="15.006959" lon="120.216823">
+<ele>87.136597</ele>
+<time>2004-09-09T23:58:20Z</time>
+</rtept>
+<rtept lat="15.006723" lon="120.216715">
+<ele>86.656006</ele>
+<time>2004-09-09T23:58:38Z</time>
+</rtept>
+<rtept lat="15.005844" lon="120.216072">
+<ele>86.656006</ele>
+<time>2004-09-09T23:59:58Z</time>
+</rtept>
+<rtept lat="15.005565" lon="120.215921">
+<ele>86.175293</ele>
+<time>2004-09-10T00:00:20Z</time>
+</rtept>
+<rtept lat="15.005350" lon="120.215750">
+<ele>86.175293</ele>
+<time>2004-09-10T00:00:40Z</time>
+</rtept>
+<rtept lat="15.004535" lon="120.214999">
+<ele>84.733398</ele>
+<time>2004-09-10T00:02:00Z</time>
+</rtept>
+<rtept lat="15.004320" lon="120.214849">
+<ele>84.733398</ele>
+<time>2004-09-10T00:02:19Z</time>
+</rtept>
+<rtept lat="15.004084" lon="120.214591">
+<ele>84.252686</ele>
+<time>2004-09-10T00:02:43Z</time>
+</rtept>
+<rtept lat="15.003977" lon="120.214527">
+<ele>84.733398</ele>
+<time>2004-09-10T00:02:58Z</time>
+</rtept>
+<rtept lat="15.003741" lon="120.214269">
+<ele>84.252686</ele>
+<time>2004-09-10T00:03:38Z</time>
+</rtept>
+<rtept lat="15.003526" lon="120.214097">
+<ele>84.252686</ele>
+<time>2004-09-10T00:04:15Z</time>
+</rtept>
+<rtept lat="15.003312" lon="120.213926">
+<ele>83.291382</ele>
+<time>2004-09-10T00:04:34Z</time>
+</rtept>
+<rtept lat="15.003161" lon="120.213754">
+<ele>83.291382</ele>
+<time>2004-09-10T00:04:57Z</time>
+</rtept>
+<rtept lat="15.003119" lon="120.213711">
+<ele>81.849365</ele>
+<time>2004-09-10T00:05:13Z</time>
+</rtept>
+<rtept lat="15.003011" lon="120.213647">
+<ele>82.330078</ele>
+<time>2004-09-10T00:05:41Z</time>
+</rtept>
+<rtept lat="15.002711" lon="120.213583">
+<ele>81.849365</ele>
+<time>2004-09-10T00:06:15Z</time>
+</rtept>
+<rtept lat="15.002153" lon="120.213432">
+<ele>84.252686</ele>
+<time>2004-09-10T00:07:12Z</time>
+</rtept>
+<rtept lat="15.001574" lon="120.213132">
+<ele>83.291382</ele>
+<time>2004-09-10T00:08:06Z</time>
+</rtept>
+<rtept lat="15.001295" lon="120.213025">
+<ele>82.810791</ele>
+<time>2004-09-10T00:08:28Z</time>
+</rtept>
+<rtept lat="15.001037" lon="120.212917">
+<ele>83.291382</ele>
+<time>2004-09-10T00:08:49Z</time>
+</rtept>
+<rtept lat="15.000801" lon="120.212767">
+<ele>84.733398</ele>
+<time>2004-09-10T00:09:08Z</time>
+</rtept>
+<rtept lat="15.000222" lon="120.212553">
+<ele>84.252686</ele>
+<time>2004-09-10T00:09:55Z</time>
+</rtept>
+<rtept lat="14.999964" lon="120.212510">
+<ele>83.771973</ele>
+<time>2004-09-10T00:10:14Z</time>
+</rtept>
+<rtept lat="14.999514" lon="120.212274">
+<ele>83.291382</ele>
+<time>2004-09-10T00:10:50Z</time>
+</rtept>
+<rtept lat="14.999342" lon="120.212102">
+<ele>83.291382</ele>
+<time>2004-09-10T00:11:08Z</time>
+</rtept>
+<rtept lat="14.999213" lon="120.211952">
+<ele>84.252686</ele>
+<time>2004-09-10T00:11:23Z</time>
+</rtept>
+<rtept lat="14.998977" lon="120.211802">
+<ele>83.771973</ele>
+<time>2004-09-10T00:11:42Z</time>
+</rtept>
+<rtept lat="14.998548" lon="120.211329">
+<ele>81.368774</ele>
+<time>2004-09-10T00:12:27Z</time>
+</rtept>
+<rtept lat="14.998097" lon="120.210857">
+<ele>80.888184</ele>
+<time>2004-09-10T00:13:16Z</time>
+</rtept>
+<rtept lat="14.998033" lon="120.210342">
+<ele>80.407471</ele>
+<time>2004-09-10T00:13:59Z</time>
+</rtept>
+<rtept lat="14.998012" lon="120.210364">
+<ele>80.888184</ele>
+<time>2004-09-10T00:14:06Z</time>
+</rtept>
+<rtept lat="14.998033" lon="120.210321">
+<ele>81.849365</ele>
+<time>2004-09-10T00:14:09Z</time>
+</rtept>
+<rtept lat="14.997904" lon="120.210106">
+<ele>79.926636</ele>
+<time>2004-09-10T00:14:28Z</time>
+</rtept>
+<rtept lat="14.997904" lon="120.209849">
+<ele>80.407471</ele>
+<time>2004-09-10T00:14:47Z</time>
+</rtept>
+<rtept lat="14.997411" lon="120.209699">
+<ele>78.484741</ele>
+<time>2004-09-10T00:16:12Z</time>
+</rtept>
+<rtept lat="14.997218" lon="120.209720">
+<ele>78.484741</ele>
+<time>2004-09-10T00:16:45Z</time>
+</rtept>
+<rtept lat="14.997110" lon="120.209699">
+<ele>78.004028</ele>
+<time>2004-09-10T00:17:02Z</time>
+</rtept>
+<rtept lat="14.996939" lon="120.209613">
+<ele>78.484741</ele>
+<time>2004-09-10T00:17:23Z</time>
+</rtept>
+<rtept lat="14.996789" lon="120.209484">
+<ele>78.484741</ele>
+<time>2004-09-10T00:17:41Z</time>
+</rtept>
+<rtept lat="14.996338" lon="120.209270">
+<ele>78.004028</ele>
+<time>2004-09-10T00:18:37Z</time>
+</rtept>
+<rtept lat="14.996037" lon="120.209205">
+<ele>78.004028</ele>
+<time>2004-09-10T00:19:23Z</time>
+</rtept>
+<rtept lat="14.995866" lon="120.209119">
+<ele>78.484741</ele>
+<time>2004-09-10T00:19:39Z</time>
+</rtept>
+<rtept lat="14.995244" lon="120.208712">
+<ele>77.523438</ele>
+<time>2004-09-10T00:20:55Z</time>
+</rtept>
+<rtept lat="14.995179" lon="120.208626">
+<ele>77.523438</ele>
+<time>2004-09-10T00:21:05Z</time>
+</rtept>
+<rtept lat="14.994943" lon="120.208454">
+<ele>78.004028</ele>
+<time>2004-09-10T00:21:25Z</time>
+</rtept>
+<rtept lat="14.994450" lon="120.208089">
+<ele>77.523438</ele>
+<time>2004-09-10T00:22:14Z</time>
+</rtept>
+<rtept lat="14.994278" lon="120.207918">
+<ele>77.523438</ele>
+<time>2004-09-10T00:22:34Z</time>
+</rtept>
+<rtept lat="14.994106" lon="120.207832">
+<ele>77.042847</ele>
+<time>2004-09-10T00:23:11Z</time>
+</rtept>
+<rtept lat="14.993935" lon="120.207703">
+<ele>76.562134</ele>
+<time>2004-09-10T00:23:29Z</time>
+</rtept>
+<rtept lat="14.993763" lon="120.207574">
+<ele>77.042847</ele>
+<time>2004-09-10T00:23:48Z</time>
+</rtept>
+<rtept lat="14.993613" lon="120.207381">
+<ele>77.042847</ele>
+<time>2004-09-10T00:24:08Z</time>
+</rtept>
+<rtept lat="14.992926" lon="120.206866">
+<ele>77.042847</ele>
+<time>2004-09-10T00:25:19Z</time>
+</rtept>
+<rtept lat="14.991510" lon="120.205643">
+<ele>76.562134</ele>
+<time>2004-09-10T00:27:46Z</time>
+</rtept>
+<rtept lat="14.991081" lon="120.205407">
+<ele>77.042847</ele>
+<time>2004-09-10T00:28:27Z</time>
+</rtept>
+<rtept lat="14.990845" lon="120.205214">
+<ele>77.523438</ele>
+<time>2004-09-10T00:28:50Z</time>
+</rtept>
+<rtept lat="14.990609" lon="120.204999">
+<ele>78.484741</ele>
+<time>2004-09-10T00:29:14Z</time>
+</rtept>
+<rtept lat="14.990137" lon="120.204592">
+<ele>78.004028</ele>
+<time>2004-09-10T00:30:01Z</time>
+</rtept>
+<rtept lat="14.989836" lon="120.204377">
+<ele>77.042847</ele>
+<time>2004-09-10T00:30:28Z</time>
+</rtept>
+<rtept lat="14.989343" lon="120.203991">
+<ele>76.562134</ele>
+<time>2004-09-10T00:31:16Z</time>
+</rtept>
+<rtept lat="14.989171" lon="120.203819">
+<ele>76.562134</ele>
+<time>2004-09-10T00:31:37Z</time>
+</rtept>
+<rtept lat="14.988956" lon="120.203669">
+<ele>76.562134</ele>
+<time>2004-09-10T00:32:11Z</time>
+</rtept>
+<rtept lat="14.988849" lon="120.203540">
+<ele>76.562134</ele>
+<time>2004-09-10T00:32:34Z</time>
+</rtept>
+<rtept lat="14.988613" lon="120.203326">
+<ele>76.562134</ele>
+<time>2004-09-10T00:33:07Z</time>
+</rtept>
+<rtept lat="14.988506" lon="120.203218">
+<ele>77.042847</ele>
+<time>2004-09-10T00:33:25Z</time>
+</rtept>
+<rtept lat="14.987991" lon="120.202768">
+<ele>76.081421</ele>
+<time>2004-09-10T00:34:25Z</time>
+</rtept>
+<rtept lat="14.987819" lon="120.202553">
+<ele>76.081421</ele>
+<time>2004-09-10T00:34:48Z</time>
+</rtept>
+<rtept lat="14.987476" lon="120.202274">
+<ele>76.562134</ele>
+<time>2004-09-10T00:35:33Z</time>
+</rtept>
+<rtept lat="14.987390" lon="120.202167">
+<ele>75.600830</ele>
+<time>2004-09-10T00:36:03Z</time>
+</rtept>
+<rtept lat="14.987111" lon="120.201952">
+<ele>76.562134</ele>
+<time>2004-09-10T00:36:41Z</time>
+</rtept>
+<rtept lat="14.986811" lon="120.201631">
+<ele>76.562134</ele>
+<time>2004-09-10T00:37:31Z</time>
+</rtept>
+<rtept lat="14.986575" lon="120.201459">
+<ele>75.600830</ele>
+<time>2004-09-10T00:37:54Z</time>
+</rtept>
+<rtept lat="14.986339" lon="120.201244">
+<ele>76.081421</ele>
+<time>2004-09-10T00:38:19Z</time>
+</rtept>
+<rtept lat="14.986081" lon="120.201073">
+<ele>76.562134</ele>
+<time>2004-09-10T00:38:42Z</time>
+</rtept>
+<rtept lat="14.985824" lon="120.200880">
+<ele>76.081421</ele>
+<time>2004-09-10T00:39:08Z</time>
+</rtept>
+<rtept lat="14.985631" lon="120.200665">
+<ele>75.600830</ele>
+<time>2004-09-10T00:39:30Z</time>
+</rtept>
+<rtept lat="14.985437" lon="120.200472">
+<ele>75.600830</ele>
+<time>2004-09-10T00:39:51Z</time>
+</rtept>
+<rtept lat="14.985223" lon="120.200322">
+<ele>74.639526</ele>
+<time>2004-09-10T00:40:14Z</time>
+</rtept>
+<rtept lat="14.984837" lon="120.200064">
+<ele>75.120239</ele>
+<time>2004-09-10T00:40:50Z</time>
+</rtept>
+<rtept lat="14.984622" lon="120.199828">
+<ele>74.639526</ele>
+<time>2004-09-10T00:41:16Z</time>
+</rtept>
+<rtept lat="14.984386" lon="120.199656">
+<ele>74.639526</ele>
+<time>2004-09-10T00:41:39Z</time>
+</rtept>
+<rtept lat="14.984043" lon="120.199227">
+<ele>74.639526</ele>
+<time>2004-09-10T00:42:37Z</time>
+</rtept>
+<rtept lat="14.983699" lon="120.198841">
+<ele>75.120239</ele>
+<time>2004-09-10T00:43:15Z</time>
+</rtept>
+<rtept lat="14.983227" lon="120.198219">
+<ele>75.120239</ele>
+<time>2004-09-10T00:44:20Z</time>
+</rtept>
+<rtept lat="14.982927" lon="120.197918">
+<ele>75.120239</ele>
+<time>2004-09-10T00:44:51Z</time>
+</rtept>
+<rtept lat="14.982777" lon="120.197725">
+<ele>75.120239</ele>
+<time>2004-09-10T00:45:12Z</time>
+</rtept>
+<rtept lat="14.982412" lon="120.197339">
+<ele>75.120239</ele>
+<time>2004-09-10T00:45:53Z</time>
+</rtept>
+<rtept lat="14.982133" lon="120.196931">
+<ele>75.120239</ele>
+<time>2004-09-10T00:46:32Z</time>
+</rtept>
+<rtept lat="14.981983" lon="120.196760">
+<ele>74.639526</ele>
+<time>2004-09-10T00:46:48Z</time>
+</rtept>
+<rtept lat="14.981897" lon="120.196695">
+<ele>75.120239</ele>
+<time>2004-09-10T00:46:58Z</time>
+</rtept>
+<rtept lat="14.981790" lon="120.196545">
+<ele>75.120239</ele>
+<time>2004-09-10T00:47:12Z</time>
+</rtept>
+<rtept lat="14.981382" lon="120.196288">
+<ele>80.888184</ele>
+<time>2004-09-10T00:48:04Z</time>
+</rtept>
+<rtept lat="14.981360" lon="120.196052">
+<ele>78.965454</ele>
+<time>2004-09-10T00:48:22Z</time>
+</rtept>
+<rtept lat="14.981382" lon="120.195816">
+<ele>77.042847</ele>
+<time>2004-09-10T00:48:41Z</time>
+</rtept>
+<rtept lat="14.981403" lon="120.195601">
+<ele>74.158813</ele>
+<time>2004-09-10T00:48:57Z</time>
+</rtept>
+<rtept lat="14.981253" lon="120.195408">
+<ele>71.755493</ele>
+<time>2004-09-10T00:49:16Z</time>
+</rtept>
+<rtept lat="14.980974" lon="120.195022">
+<ele>71.274902</ele>
+<time>2004-09-10T00:49:53Z</time>
+</rtept>
+<rtept lat="14.980781" lon="120.194528">
+<ele>69.832886</ele>
+<time>2004-09-10T00:50:34Z</time>
+</rtept>
+<rtept lat="14.980609" lon="120.193799">
+<ele>69.832886</ele>
+<time>2004-09-10T00:51:33Z</time>
+</rtept>
+<rtept lat="14.980567" lon="120.193627">
+<ele>68.871582</ele>
+<time>2004-09-10T00:51:48Z</time>
+</rtept>
+</rte>
+<trk>
+ <name>Only 5 points</name>
+<number>7</number>
+<trkseg>
+<trkpt lat="14.907889" lon="120.558472">
+<ele>28.976929</ele>
+<time>2004-09-10T08:35:38Z</time>
+</trkpt>
+<trkpt lat="14.907975" lon="120.558579">
+<ele>28.976929</ele>
+<time>2004-09-10T08:35:55Z</time>
+</trkpt>
+<trkpt lat="14.908168" lon="120.558879">
+<ele>28.496216</ele>
+<time>2004-09-10T08:36:11Z</time>
+</trkpt>
+<trkpt lat="14.908383" lon="120.559223">
+<ele>28.496216</ele>
+<time>2004-09-10T08:36:32Z</time>
+</trkpt>
+<trkpt lat="14.908597" lon="120.559545">
+<ele>28.015503</ele>
+<time>2004-09-10T08:36:43Z</time>
+</trkpt>
+</trkseg>
+</trk>
+<wpt lat="14.636015547" lon="121.043382715">
+ <ele>45.307495</ele>
+ <name>001</name>
+ <cmt>001</cmt>
+ <desc>001</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="14.637198653" lon="121.042653322">
+ <ele>50.594727</ele>
+ <name>002</name>
+ <cmt>002</cmt>
+ <desc>002</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="14.640581002" lon="121.043165457">
+ <ele>46.989868</ele>
+ <name>003</name>
+ <cmt>003</cmt>
+ <desc>003</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="14.975596117" lon="120.155537082">
+ <ele>38.097656</ele>
+ <name>004</name>
+ <cmt>004</cmt>
+ <desc>004</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.037303017" lon="120.236538453">
+ <ele>147.687134</ele>
+ <name>005</name>
+ <cmt>005</cmt>
+ <desc>005</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.037305867" lon="120.236548427">
+ <ele>145.043579</ele>
+ <name>006</name>
+ <cmt>006</cmt>
+ <desc>006</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.038105585" lon="120.237012533">
+ <ele>160.905151</ele>
+ <name>007</name>
+ <cmt>007</cmt>
+ <desc>007</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.038478328" lon="120.237643858">
+ <ele>165.231079</ele>
+ <name>008</name>
+ <cmt>008</cmt>
+ <desc>008</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.038991300" lon="120.238984879">
+ <ele>173.882935</ele>
+ <name>009</name>
+ <cmt>009</cmt>
+ <desc>009</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.039099846" lon="120.239190236">
+ <ele>166.192383</ele>
+ <name>010</name>
+ <cmt>010</cmt>
+ <desc>010</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.040223943" lon="120.241263332">
+ <ele>175.324829</ele>
+ <name>011</name>
+ <cmt>011</cmt>
+ <desc>011</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.042621084" lon="120.247956365">
+ <ele>186.860474</ele>
+ <name>012</name>
+ <cmt>012</cmt>
+ <desc>012</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.043179905" lon="120.253084749">
+ <ele>208.730347</ele>
+ <name>013</name>
+ <cmt>013</cmt>
+ <desc>013</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.043297336" lon="120.254095523">
+ <ele>211.374023</ele>
+ <name>014</name>
+ <cmt>014</cmt>
+ <desc>014</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.043296246" lon="120.254105665">
+ <ele>213.296631</ele>
+ <name>015</name>
+ <cmt>015</cmt>
+ <desc>015</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.042568864" lon="120.247880174">
+ <ele>189.984863</ele>
+ <name>016</name>
+ <cmt>016</cmt>
+ <desc>016</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.042486135" lon="120.246971911">
+ <ele>187.100830</ele>
+ <name>017</name>
+ <cmt>017</cmt>
+ <desc>017</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.042233923" lon="120.245966502">
+ <ele>185.418579</ele>
+ <name>018</name>
+ <cmt>018</cmt>
+ <desc>018</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.041693626" lon="120.244808039">
+ <ele>181.092651</ele>
+ <name>019</name>
+ <cmt>019</cmt>
+ <desc>019</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.041558258" lon="120.244476954">
+ <ele>179.410400</ele>
+ <name>020</name>
+ <cmt>020</cmt>
+ <desc>020</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.041360026" lon="120.243841019">
+ <ele>178.689453</ele>
+ <name>021</name>
+ <cmt>021</cmt>
+ <desc>021</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.040351683" lon="120.241488637">
+ <ele>176.526489</ele>
+ <name>022</name>
+ <cmt>022</cmt>
+ <desc>022</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.040215813" lon="120.241269115">
+ <ele>177.247437</ele>
+ <name>023</name>
+ <cmt>023</cmt>
+ <desc>023</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.039894953" lon="120.240607113">
+ <ele>173.161987</ele>
+ <name>024</name>
+ <cmt>024</cmt>
+ <desc>024</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.039318446" lon="120.239687199">
+ <ele>170.277832</ele>
+ <name>025</name>
+ <cmt>025</cmt>
+ <desc>025</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.039147874" lon="120.239404980">
+ <ele>170.037598</ele>
+ <name>026</name>
+ <cmt>026</cmt>
+ <desc>026</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.039016195" lon="120.239027124">
+ <ele>169.797241</ele>
+ <name>027</name>
+ <cmt>027</cmt>
+ <desc>027</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.038951570" lon="120.238857307">
+ <ele>169.316650</ele>
+ <name>028</name>
+ <cmt>028</cmt>
+ <desc>028</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.038922066" lon="120.238720765">
+ <ele>169.076294</ele>
+ <name>029</name>
+ <cmt>029</cmt>
+ <desc>029</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.038786530" lon="120.238445755">
+ <ele>164.510010</ele>
+ <name>030</name>
+ <cmt>030</cmt>
+ <desc>030</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.038752332" lon="120.238321787">
+ <ele>164.750366</ele>
+ <name>031</name>
+ <cmt>031</cmt>
+ <desc>031</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.038600871" lon="120.237971172">
+ <ele>166.432617</ele>
+ <name>032</name>
+ <cmt>032</cmt>
+ <desc>032</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.038484363" lon="120.237681828">
+ <ele>165.711670</ele>
+ <name>033</name>
+ <cmt>033</cmt>
+ <desc>033</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.038389480" lon="120.237437915">
+ <ele>162.106812</ele>
+ <name>034</name>
+ <cmt>034</cmt>
+ <desc>034</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.038236845" lon="120.237119906">
+ <ele>157.300293</ele>
+ <name>035</name>
+ <cmt>035</cmt>
+ <desc>035</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.038081110" lon="120.236975150">
+ <ele>154.175903</ele>
+ <name>036</name>
+ <cmt>036</cmt>
+ <desc>036</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.037884219" lon="120.236842548">
+ <ele>152.253296</ele>
+ <name>037</name>
+ <cmt>037</cmt>
+ <desc>037</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.037822025" lon="120.236781947">
+ <ele>152.734009</ele>
+ <name>038</name>
+ <cmt>038</cmt>
+ <desc>038</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.037694452" lon="120.236648759">
+ <ele>148.167847</ele>
+ <name>039</name>
+ <cmt>039</cmt>
+ <desc>039</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.037404103" lon="120.236415155">
+ <ele>142.880615</ele>
+ <name>040</name>
+ <cmt>040</cmt>
+ <desc>040</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.036643613" lon="120.235724067">
+ <ele>131.344849</ele>
+ <name>041</name>
+ <cmt>041</cmt>
+ <desc>041</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.035957471" lon="120.235749800">
+ <ele>131.585205</ele>
+ <name>042</name>
+ <cmt>042</cmt>
+ <desc>042</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.035150293" lon="120.235839151">
+ <ele>126.057617</ele>
+ <name>043</name>
+ <cmt>043</cmt>
+ <desc>043</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.034987517" lon="120.235854574">
+ <ele>126.297974</ele>
+ <name>044</name>
+ <cmt>044</cmt>
+ <desc>044</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.034929262" lon="120.235940237">
+ <ele>127.499634</ele>
+ <name>045</name>
+ <cmt>045</cmt>
+ <desc>045</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.034842342" lon="120.236292612">
+ <ele>128.701294</ele>
+ <name>046</name>
+ <cmt>046</cmt>
+ <desc>046</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.034868326" lon="120.236495705">
+ <ele>131.585205</ele>
+ <name>047</name>
+ <cmt>047</cmt>
+ <desc>047</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.034914091" lon="120.236638952">
+ <ele>130.623901</ele>
+ <name>048</name>
+ <cmt>048</cmt>
+ <desc>048</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.034842929" lon="120.236782283">
+ <ele>130.623901</ele>
+ <name>049</name>
+ <cmt>049</cmt>
+ <desc>049</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.035138307" lon="120.237012701">
+ <ele>130.143188</ele>
+ <name>050</name>
+ <cmt>050</cmt>
+ <desc>050</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.035181055" lon="120.237215459">
+ <ele>133.507812</ele>
+ <name>051</name>
+ <cmt>051</cmt>
+ <desc>051</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.037302515" lon="120.236531328">
+ <ele>142.640259</ele>
+ <name>052</name>
+ <cmt>052</cmt>
+ <desc>052</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.038081612" lon="120.237016557">
+ <ele>153.214600</ele>
+ <name>053</name>
+ <cmt>053</cmt>
+ <desc>053</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.038484028" lon="120.237650061">
+ <ele>160.184204</ele>
+ <name>054</name>
+ <cmt>054</cmt>
+ <desc>054</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.039010160" lon="120.239003822">
+ <ele>167.874634</ele>
+ <name>055</name>
+ <cmt>055</cmt>
+ <desc>055</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.040213466" lon="120.241269115">
+ <ele>174.363525</ele>
+ <name>056</name>
+ <cmt>056</cmt>
+ <desc>056</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.043153167" lon="120.253080474">
+ <ele>210.893311</ele>
+ <name>057</name>
+ <cmt>057</cmt>
+ <desc>057</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.043287948" lon="120.254115807">
+ <ele>214.017578</ele>
+ <name>058</name>
+ <cmt>058</cmt>
+ <desc>058</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.043408228" lon="120.255108811">
+ <ele>210.652954</ele>
+ <name>059</name>
+ <cmt>059</cmt>
+ <desc>059</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.044677416" lon="120.254899012">
+ <ele>216.180542</ele>
+ <name>060</name>
+ <cmt>060</cmt>
+ <desc>060</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.043236231" lon="120.254365504">
+ <ele>210.893311</ele>
+ <name>061</name>
+ <cmt>061</cmt>
+ <desc>061</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.039282907" lon="120.239687199">
+ <ele>169.797241</ele>
+ <name>062</name>
+ <cmt>062</cmt>
+ <desc>062</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.036760792" lon="120.238004448">
+ <ele>154.175903</ele>
+ <name>063</name>
+ <cmt>063</cmt>
+ <desc>063</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.035345173" lon="120.237376308">
+ <ele>137.593262</ele>
+ <name>064</name>
+ <cmt>064</cmt>
+ <desc>064</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.035234699" lon="120.237213951">
+ <ele>134.709473</ele>
+ <name>065</name>
+ <cmt>065</cmt>
+ <desc>065</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.035907766" lon="120.235997736">
+ <ele>126.297974</ele>
+ <name>066</name>
+ <cmt>066</cmt>
+ <desc>066</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.035970211" lon="120.235796738">
+ <ele>126.538330</ele>
+ <name>067</name>
+ <cmt>067</cmt>
+ <desc>067</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.037343334" lon="120.236459579">
+ <ele>144.803223</ele>
+ <name>068</name>
+ <cmt>068</cmt>
+ <desc>068</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.037007639" lon="120.236442396">
+ <ele>141.919312</ele>
+ <name>069</name>
+ <cmt>069</cmt>
+ <desc>069</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.036581503" lon="120.236358577">
+ <ele>139.515869</ele>
+ <name>070</name>
+ <cmt>070</cmt>
+ <desc>070</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.036247736" lon="120.236462262">
+ <ele>143.361206</ele>
+ <name>071</name>
+ <cmt>071</cmt>
+ <desc>071</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.035688411" lon="120.236551194">
+ <ele>134.469116</ele>
+ <name>072</name>
+ <cmt>072</cmt>
+ <desc>072</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.035237549" lon="120.236503417">
+ <ele>134.228760</ele>
+ <name>073</name>
+ <cmt>073</cmt>
+ <desc>073</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.034895400" lon="120.236642389">
+ <ele>135.430420</ele>
+ <name>074</name>
+ <cmt>074</cmt>
+ <desc>074</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.034930268" lon="120.237154271">
+ <ele>135.430420</ele>
+ <name>075</name>
+ <cmt>075</cmt>
+ <desc>075</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.034847539" lon="120.235381918">
+ <ele>96.978027</ele>
+ <name>076</name>
+ <cmt>076</cmt>
+ <desc>076</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.034693647" lon="120.235394575">
+ <ele>112.359009</ele>
+ <name>077</name>
+ <cmt>077</cmt>
+ <desc>077</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.032701520" lon="120.231625903">
+ <ele>114.281616</ele>
+ <name>078</name>
+ <cmt>078</cmt>
+ <desc>078</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.031369971" lon="120.230112802">
+ <ele>111.157349</ele>
+ <name>079</name>
+ <cmt>079</cmt>
+ <desc>079</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.031269640" lon="120.230063936">
+ <ele>110.436401</ele>
+ <name>080</name>
+ <cmt>080</cmt>
+ <desc>080</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.029314896" lon="120.229415931">
+ <ele>105.629761</ele>
+ <name>081</name>
+ <cmt>081</cmt>
+ <desc>081</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.028247628" lon="120.229260782">
+ <ele>103.226440</ele>
+ <name>082</name>
+ <cmt>082</cmt>
+ <desc>082</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.027997931" lon="120.229063304">
+ <ele>101.784546</ele>
+ <name>083</name>
+ <cmt>083</cmt>
+ <desc>083</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.026977602" lon="120.228622919">
+ <ele>102.986084</ele>
+ <name>084</name>
+ <cmt>084</cmt>
+ <desc>084</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.026555741" lon="120.228640521">
+ <ele>101.784546</ele>
+ <name>085</name>
+ <cmt>085</cmt>
+ <desc>085</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.021198532" lon="120.226751072">
+ <ele>93.853760</ele>
+ <name>086</name>
+ <cmt>086</cmt>
+ <desc>086</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.020887312" lon="120.226317560">
+ <ele>95.295654</ele>
+ <name>087</name>
+ <cmt>087</cmt>
+ <desc>087</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.020824028" lon="120.226252014">
+ <ele>95.055420</ele>
+ <name>088</name>
+ <cmt>088</cmt>
+ <desc>088</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.020084241" lon="120.225583892">
+ <ele>87.845459</ele>
+ <name>089</name>
+ <cmt>089</cmt>
+ <desc>089</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.019395584" lon="120.224903030">
+ <ele>92.892456</ele>
+ <name>090</name>
+ <cmt>090</cmt>
+ <desc>090</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.017774021" lon="120.224660626">
+ <ele>92.892456</ele>
+ <name>091</name>
+ <cmt>091</cmt>
+ <desc>091</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.017061057" lon="120.224452335">
+ <ele>90.489136</ele>
+ <name>092</name>
+ <cmt>092</cmt>
+ <desc>092</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.016638860" lon="120.224422915">
+ <ele>85.682495</ele>
+ <name>093</name>
+ <cmt>093</cmt>
+ <desc>093</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.016528722" lon="120.224321326">
+ <ele>86.884155</ele>
+ <name>094</name>
+ <cmt>094</cmt>
+ <desc>094</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.016059754" lon="120.223885886">
+ <ele>88.566528</ele>
+ <name>095</name>
+ <cmt>095</cmt>
+ <desc>095</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.015040850" lon="120.223270738">
+ <ele>87.605103</ele>
+ <name>096</name>
+ <cmt>096</cmt>
+ <desc>096</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.014152871" lon="120.222094171">
+ <ele>89.287476</ele>
+ <name>097</name>
+ <cmt>097</cmt>
+ <desc>097</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.013247039" lon="120.221332423">
+ <ele>92.652100</ele>
+ <name>098</name>
+ <cmt>098</cmt>
+ <desc>098</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.012727026" lon="120.220021661">
+ <ele>91.450317</ele>
+ <name>099</name>
+ <cmt>099</cmt>
+ <desc>099</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.012746723" lon="120.219879504">
+ <ele>91.450317</ele>
+ <name>100</name>
+ <cmt>100</cmt>
+ <desc>100</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.012489315" lon="120.219430067">
+ <ele>91.690674</ele>
+ <name>101</name>
+ <cmt>101</cmt>
+ <desc>101</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.012095952" lon="120.219129324">
+ <ele>91.450317</ele>
+ <name>102</name>
+ <cmt>102</cmt>
+ <desc>102</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.011870563" lon="120.218922459">
+ <ele>91.690674</ele>
+ <name>103</name>
+ <cmt>103</cmt>
+ <desc>103</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.007610880" lon="120.216987077">
+ <ele>88.566528</ele>
+ <name>104</name>
+ <cmt>104</cmt>
+ <desc>104</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.007109391" lon="120.216904096">
+ <ele>87.364868</ele>
+ <name>105</name>
+ <cmt>105</cmt>
+ <desc>105</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.003595361" lon="120.214147121">
+ <ele>85.682495</ele>
+ <name>106</name>
+ <cmt>106</cmt>
+ <desc>106</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="15.002421224" lon="120.213506240">
+ <ele>83.279297</ele>
+ <name>107</name>
+ <cmt>107</cmt>
+ <desc>107</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="14.998089289" lon="120.210867617">
+ <ele>79.674438</ele>
+ <name>108</name>
+ <cmt>108</cmt>
+ <desc>108</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="14.997864654" lon="120.209834045">
+ <ele>84.480957</ele>
+ <name>109</name>
+ <cmt>109</cmt>
+ <desc>109</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="14.981388599" lon="120.196274891">
+ <ele>84.721313</ele>
+ <name>110</name>
+ <cmt>110</cmt>
+ <desc>110</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="14.474465596" lon="120.917379661">
+ <ele>5.172729</ele>
+ <name>111</name>
+ <cmt>111</cmt>
+ <desc>111</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="14.942621375" lon="120.938029736">
+ <ele>28.965332</ele>
+ <name>112</name>
+ <cmt>112</cmt>
+ <desc>112</desc>
+ <sym>Residence</sym>
+</wpt>
+<wpt lat="12.255321192" lon="124.379444299">
+ <ele>21.995728</ele>
+ <name>113</name>
+ <cmt>113</cmt>
+ <desc>113</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="38.855549991" lon="-94.799016668">
+ <ele>325.049072</ele>
+ <name>GARMIN</name>
+ <cmt>GARMIN</cmt>
+ <desc>GARMIN</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="50.982883293" lon="-1.463899976">
+ <ele>35.934692</ele>
+ <name>GRMEUR</name>
+ <cmt>GRMEUR</cmt>
+ <desc>GRMEUR</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="33.330189949" lon="-111.946110008">
+ <ele>361.098145</ele>
+ <name>GRMPHX</name>
+ <cmt>GRMPHX</cmt>
+ <desc>GRMPHX</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="25.061783362" lon="121.640266674">
+ <ele>38.097656</ele>
+ <name>GRMTWN</name>
+ <cmt>GRMTWN</cmt>
+ <desc>GRMTWN</desc>
+ <sym>Flag</sym>
+</wpt>
+<wpt lat="14.636060139" lon="121.043607602">
+ <ele>8.296997</ele>
+ <name>NEDA4</name>
+ <cmt>NEDA4</cmt>
+ <desc>NEDA4</desc>
+ <sym>Residence</sym>
+</wpt>
+</gpx>
diff --git a/navit/tools/gpx2navit_txt/src/Makefile.am b/navit/tools/gpx2navit_txt/src/Makefile.am
new file mode 100644
index 000000000..5cce6fa3c
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/Makefile.am
@@ -0,0 +1,26 @@
+bin_PROGRAMS = gpx2navit_txt
+
+gpx2navit_txt_SOURCES = \
+ emess.h \
+ geod_for.c \
+ geod_inv.c \
+ geod_set.c \
+ geodesic.h \
+ gpx2navit_txt.h \
+ main.c \
+ misc.c \
+ utils.c \
+ parser.c \
+ elementControl.c\
+ setwpt.c \
+ setpath.c \
+ setmeta.c \
+ errorcode.h
+
+INCLUDES= -I$(srcdir)
+
+AM_CFLAGS = -g
+
+debian-dist:
+ dpkg-buildpackage -rfakeroot -d -tc -us -uc
+
diff --git a/navit/tools/gpx2navit_txt/src/config.h.in b/navit/tools/gpx2navit_txt/src/config.h.in
new file mode 100644
index 000000000..724d6f656
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/config.h.in
@@ -0,0 +1,99 @@
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the `alarm' function. */
+#undef HAVE_ALARM
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `expat' library (-lexpat). */
+#undef HAVE_LIBEXPAT
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the `proj' library (-lproj). */
+#undef HAVE_LIBPROJ
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* 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 <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define to 1 if your system has a GNU libc compatible `realloc' function,
+ and to 0 otherwise. */
+#undef HAVE_REALLOC
+
+/* Define to 1 if you have the `sqrt' function. */
+#undef HAVE_SQRT
+
+/* 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 <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 <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 the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* 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 version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* 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
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#undef malloc
+
+/* Define to rpl_realloc if the replacement function should be used. */
+#undef realloc
diff --git a/navit/tools/gpx2navit_txt/src/elementControl.c b/navit/tools/gpx2navit_txt/src/elementControl.c
new file mode 100644
index 000000000..40bbe44c2
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/elementControl.c
@@ -0,0 +1,226 @@
+#include "gpx2navit_txt.h"
+
+void startElementControl(parsedata * pdata, const char *element,
+ const char **attr);
+void endElementControl(parsedata * pdata, const char *element);
+
+/*
+ * This method controls tag start event.
+ * It corrects attributes.
+ */
+void
+startElementControl(parsedata * pdata, const char *element,
+ const char **attr)
+{
+ int i;
+ static int isFirstTrk = 1;
+ static int isFirstRte = 1;
+ static int isFirstPathpt = 1;
+ for (i = 0; attr[i]; i += 2) {
+ if (!strcmp(attr[i], "lon")) {
+ pdata->attr->lon = atof(attr[i + 1]);
+ }
+ if (!strcmp(attr[i], "lat")) {
+ pdata->attr->lat = atof(attr[i + 1]);
+ }
+ if (!strcmp(attr[i], "minlon")) {
+ pdata->attr->minlon = atof(attr[i + 1]);
+ }
+ if (!strcmp(attr[i], "minlat")) {
+ pdata->attr->minlat = atof(attr[i + 1]);
+ }
+ if (!strcmp(attr[i], "maxlon")) {
+ pdata->attr->maxlon = atof(attr[i + 1]);
+ }
+ if (!strcmp(attr[i], "maxlat")) {
+ pdata->attr->maxlat = atof(attr[i + 1]);
+ }
+ if (!strcmp(attr[i], "author")) {
+ strcpy(pdata->attr->author, attr[i + 1]);
+ }
+ }
+ if (pdata->prop->parseTrk) {
+ if (!strcmp(element, "trk")) {
+ if (isFirstTrk) {
+ isFirstTrk = 0;
+ }
+ }
+ if (!strcmp(element, "trkseg")) {
+ isFirstPathpt = 1;
+ }
+ if (!strcmp(element, "trkpt")) {
+ if (isFirstPathpt) {
+ initPathAttr(pdata->pattr, pdata->attr);
+ isFirstPathpt = 0;
+ }
+ }
+ }
+ if (pdata->prop->parseRte) {
+ if (!strcmp(element, "rte")) {
+ if (isFirstRte) {
+ isFirstRte = 0;
+ isFirstPathpt = 1;
+ }
+ }
+ if (!strcmp(element, "rtept")) {
+ if (isFirstPathpt) {
+ initPathAttr(pdata->pattr, pdata->attr);
+ isFirstPathpt = 0;
+ }
+ }
+ }
+}
+
+/**
+ * This method is kicked by tag end event.
+ * It corrects char elements when the element tag has some data,
+ * then start to convert when tag is top level tag like <wpt>.
+ */
+void endElementControl(parsedata * pdata, const char *element)
+{
+ static int isFirstWpt = 1;
+ static int isFirstTrkAsPoint = 1;
+ static int isFirstRteAsPoint = 1;
+ /* common elements */
+ if (!strcmp(element, "name")) {
+ strcpy(pdata->attr->name, pdata->databuf);
+ }
+ if (!strcmp(element, "cmt")) {
+ strcpy(pdata->attr->cmt, pdata->databuf);
+ }
+ if (!strcmp(element, "desc")) {
+ strcpy(pdata->attr->desc, pdata->databuf);
+ }
+ if (!strcmp(element, "src")) {
+ strcpy(pdata->attr->src, pdata->databuf);
+ }
+ if (!strcmp(element, "link")) {
+ strcpy(pdata->attr->link, pdata->databuf);
+ }
+ if (!strcmp(element, "type")) {
+ strcpy(pdata->attr->type, pdata->databuf);
+ }
+ /* waypoint and metadata elements */
+ if (!strcmp(element, "time")) {
+ strcpy(pdata->attr->time, pdata->databuf);
+ }
+ /* route and track point elements */
+ if (!strcmp(element, "number")) {
+ pdata->attr->number = atoi(pdata->databuf);
+ }
+ /* waypoint elements */
+ if (!strcmp(element, "ele")) {
+ pdata->attr->ele = atof(pdata->databuf);
+ }
+ if (!strcmp(element, "magvar")) {
+ pdata->attr->magvar = atof(pdata->databuf);
+ }
+ if (!strcmp(element, "geoidheight")) {
+ pdata->attr->geoidheight = atof(pdata->databuf);
+ }
+ if (!strcmp(element, "sym")) {
+ strcpy(pdata->attr->sym, pdata->databuf);
+ }
+ if (!strcmp(element, "fix")) {
+ strcpy(pdata->attr->fix, pdata->databuf);
+ }
+ if (!strcmp(element, "sat")) {
+ pdata->attr->sat = atoi(pdata->databuf);
+ }
+ if (!strcmp(element, "hdop")) {
+ pdata->attr->hdop = atof(pdata->databuf);
+ }
+ if (!strcmp(element, "vdop")) {
+ pdata->attr->vdop = atof(pdata->databuf);
+ }
+ if (!strcmp(element, "pdop")) {
+ pdata->attr->pdop = atof(pdata->databuf);
+ }
+ if (!strcmp(element, "ageofdgpsdata")) {
+ pdata->attr->ageofdgpsdata = atof(pdata->databuf);
+ }
+ /* metadata elements */
+ if (!strcmp(element, "author")) {
+ strcpy(pdata->attr->author, pdata->databuf);
+ }
+ if (!strcmp(element, "keywords")) {
+ strcpy(pdata->attr->keywords, pdata->databuf);
+ }
+ if (!strcmp(element, "copyright")) {
+ strcpy(pdata->attr->copyright, pdata->databuf);
+ }
+ if (!strcmp(element, "year")) {
+ pdata->attr->year = atoi(pdata->databuf);
+ }
+ if (!strcmp(element, "license")) {
+ strcpy(pdata->attr->license, pdata->databuf);
+ }
+ if (!strcmp(element, "bounds")) {
+ /* none */
+ }
+ /* top elements */
+ /* set waypoint data */
+ if (!strcmp(element, "wpt")) {
+ if (pdata->prop->parseWpt) {
+ if (isFirstWpt) {
+ isFirstWpt = 0;
+ }
+ //todo
+ if (DEBUG) {
+ fprintf(stderr,"\neectrl wpt %s %s",
+ pdata->attr->desc,pdata->attr->name);
+ }
+ setWpt(pdata);
+ wipeAttr(pdata->attr);
+ }
+ }
+ /* set trackpoint data */
+ if (!strcmp(element, "trkpt")) {
+ if (pdata->prop->parseTrk) {
+ setPathData(pdata->pattr, pdata->attr);
+ if (!pdata->prop->isFast)
+ setPathInterval(pdata);
+ }
+ /* set trackpoint data as point */
+ if (pdata->prop->isPoint) {
+ if (isFirstTrkAsPoint) {
+ isFirstTrkAsPoint = 0;
+ }
+ setWpt(pdata);
+ }
+ wipeAttr(pdata->attr);
+ }
+ /* write trackpoint */
+ if (!strcmp(element, "trkseg")) {
+ if (pdata->prop->parseTrk) {
+ setPath( pdata);
+ }
+ }
+ /* set route data */
+ if (!strcmp(element, "rtept")) {
+ if (pdata->prop->parseRte) {
+ setPathData(pdata->pattr, pdata->attr);
+ if (!pdata->prop->isFast)
+ setPathInterval(pdata);
+ }
+ /* set route data as point */
+ if (pdata->prop->isPoint) {
+ if (isFirstRteAsPoint) {
+ isFirstRteAsPoint = 0;
+ }
+ setWpt( pdata);
+ }
+ wipeAttr(pdata->attr);
+ }
+ /* write route */
+ if (!strcmp(element, "rte")) {
+ if (pdata->prop->parseRte) {
+ setPath( pdata);
+ }
+ }
+ if (!strcmp(element, "metadata")) {
+ setMetadata(pdata);
+ wipeAttr(pdata->attr);
+ }
+ pdata->bufptr = NULL; //reset bufptr now
+}
diff --git a/navit/tools/gpx2navit_txt/src/emess.h b/navit/tools/gpx2navit_txt/src/emess.h
new file mode 100644
index 000000000..b35bc2502
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/emess.h
@@ -0,0 +1,32 @@
+/* Error message processing header file */
+#ifndef EMESS_H
+#define EMESS_H
+
+#ifndef lint
+/*static char EMESS_H_ID[] = "@(#)emess.h 4.1 93/03/08 GIE REL";*/
+#endif
+
+struct EMESS {
+ char *File_name, /* input file name */
+ *Prog_name; /* name of program */
+ int File_line; /* approximate line read
+ where error occured */
+};
+
+#ifdef EMESS_ROUTINE /* use type */
+/* for emess procedure */
+struct EMESS emess_dat = { (char *)0, (char *)0, 0 };
+
+#ifdef sun /* Archaic SunOs 4.1.1, etc. */
+extern char *sys_errlist[];
+#define strerror(n) (sys_errlist[n])
+#endif
+
+#else /* for for calling procedures */
+
+extern struct EMESS emess_dat;
+void emess(int, char *, ...);
+
+#endif /* use type */
+
+#endif /* end EMESS_H */
diff --git a/navit/tools/gpx2navit_txt/src/errorcode.h b/navit/tools/gpx2navit_txt/src/errorcode.h
new file mode 100644
index 000000000..efaf88d89
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/errorcode.h
@@ -0,0 +1,22 @@
+#ifndef ERRORCODE_H
+#define ERRORCODE_H
+
+/* os level */
+#define ERR_OUTOFMEMORY 11
+#define ERR_CANNOTOPEN 12
+#define ERR_CREATEFILE 13
+#define ERR_READERROR 14
+#define ERR_FREEFAILED 15
+/* option */
+#define ERR_NOARGS 21
+#define ERR_WRONGOPTION 22
+#define ERR_OPTIONCONFRICT 23
+/* parser */
+#define ERR_ISNOTGPX 31
+#define ERR_PARSEERROR 32
+/* unit */
+#define ERR_ELLPSUNIT 41
+#define ERR_LENGTHUNIT 42
+#define ERR_TIMEUNIT 43
+
+#endif /* ERRORCODE_H */
diff --git a/navit/tools/gpx2navit_txt/src/geod_for.c b/navit/tools/gpx2navit_txt/src/geod_for.c
new file mode 100644
index 000000000..4466a1d24
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/geod_for.c
@@ -0,0 +1,108 @@
+#ifndef lint
+static const char SCCSID[] =
+ "@(#)geod_for.c 4.6 95/09/23 GIE REL";
+#endif
+# include "projects.h"
+# include "geodesic.h"
+# define MERI_TOL 1e-9
+static double th1, costh1, sinth1, sina12, cosa12, M, N, c1, c2, D, P, s1;
+static int merid, signS;
+void geod_pre(void)
+{
+ al12 = adjlon(al12); /* reduce to +- 0-PI */
+ signS = fabs(al12) > HALFPI ? 1 : 0;
+ th1 = ellipse ? atan(onef * tan(phi1)) : phi1;
+ costh1 = cos(th1);
+ sinth1 = sin(th1);
+ if ((merid = fabs(sina12 = sin(al12)) < MERI_TOL)) {
+ sina12 = 0.;
+ cosa12 = fabs(al12) < HALFPI ? 1. : -1.;
+ M = 0.;
+ } else {
+ cosa12 = cos(al12);
+ M = costh1 * sina12;
+ }
+ N = costh1 * cosa12;
+ if (ellipse) {
+ if (merid) {
+ c1 = 0.;
+ c2 = f4;
+ D = 1. - c2;
+ D *= D;
+ P = c2 / D;
+ } else {
+ c1 = geod_f * M;
+ c2 = f4 * (1. - M * M);
+ D = (1. - c2) * (1. - c2 - c1 * M);
+ P = (1. + .5 * c1 * M) * c2 / D;
+ }
+ }
+ if (merid)
+ s1 = HALFPI - th1;
+ else {
+ s1 = (fabs(M) >= 1.) ? 0. : acos(M);
+ s1 = sinth1 / sin(s1);
+ s1 = (fabs(s1) >= 1.) ? 0. : acos(s1);
+ }
+}
+void geod_for(void)
+{
+ double d, sind, u, V, X, ds, cosds, sinds, ss = 0, de;
+
+ if (ellipse) {
+ d = geod_S / (D * geod_a);
+ if (signS)
+ d = -d;
+ u = 2. * (s1 - d);
+ V = cos(u + d);
+ X = c2 * c2 * (sind = sin(d)) * cos(d) * (2. * V * V - 1.);
+ ds = d + X - 2. * P * V * (1. - 2. * P * cos(u)) * sind;
+ ss = s1 + s1 - ds;
+ } else {
+ ds = geod_S / geod_a;
+ if (signS)
+ ds = -ds;
+ }
+ cosds = cos(ds);
+ sinds = sin(ds);
+ if (signS)
+ sinds = -sinds;
+ al21 = N * cosds - sinth1 * sinds;
+ if (merid) {
+ phi2 = atan(tan(HALFPI + s1 - ds) / onef);
+ if (al21 > 0.) {
+ al21 = PI;
+ if (signS)
+ de = PI;
+ else {
+ phi2 = -phi2;
+ de = 0.;
+ }
+ } else {
+ al21 = 0.;
+ if (signS) {
+ phi2 = -phi2;
+ de = 0;
+ } else
+ de = PI;
+ }
+ } else {
+ al21 = atan(M / al21);
+ if (al21 > 0)
+ al21 += PI;
+ if (al12 < 0.)
+ al21 -= PI;
+ al21 = adjlon(al21);
+ phi2 = atan(-(sinth1 * cosds + N * sinds) * sin(al21) /
+ (ellipse ? onef * M : M));
+ de = atan2(sinds * sina12,
+ (costh1 * cosds - sinth1 * sinds * cosa12));
+ if (ellipse) {
+ if (signS)
+ de += c1 * ((1. - c2) * ds + c2 * sinds * cos(ss));
+ else
+ de -= c1 * ((1. - c2) * ds - c2 * sinds * cos(ss));
+ }
+ }
+ lam2 = adjlon(lam1 + de);
+}
diff --git a/navit/tools/gpx2navit_txt/src/geod_inv.c b/navit/tools/gpx2navit_txt/src/geod_inv.c
new file mode 100644
index 000000000..d938da8a3
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/geod_inv.c
@@ -0,0 +1,73 @@
+#ifndef lint
+static const char SCCSID[] =
+ "@(#)geod_inv.c 4.5 95/09/23 GIE REL";
+#endif
+# include "projects.h"
+# include "geodesic.h"
+# define DTOL 1e-12
+void geod_inv(void)
+{
+ double th1,
+ th2,
+ thm,
+ dthm,
+ dlamm,
+ dlam,
+ sindlamm,
+ costhm,
+ sinthm,
+ cosdthm,
+ sindthm, L, E, cosd, d, X, Y, T, sind, tandlammp, u, v, D, A, B;
+
+ if (ellipse) {
+ th1 = atan(onef * tan(phi1));
+ th2 = atan(onef * tan(phi2));
+ } else {
+ th1 = phi1;
+ th2 = phi2;
+ }
+ thm = .5 * (th1 + th2);
+ dthm = .5 * (th2 - th1);
+ dlamm = .5 * (dlam = adjlon(lam2 - lam1));
+ if (fabs(dlam) < DTOL && fabs(dthm) < DTOL) {
+ al12 = al21 = geod_S = 0.;
+ return;
+ }
+ sindlamm = sin(dlamm);
+ costhm = cos(thm);
+ sinthm = sin(thm);
+ cosdthm = cos(dthm);
+ sindthm = sin(dthm);
+ L = sindthm * sindthm + (cosdthm * cosdthm - sinthm * sinthm)
+ * sindlamm * sindlamm;
+ d = acos(cosd = 1 - L - L);
+ if (ellipse) {
+ E = cosd + cosd;
+ sind = sin(d);
+ Y = sinthm * cosdthm;
+ Y *= (Y + Y) / (1. - L);
+ T = sindthm * costhm;
+ T *= (T + T) / L;
+ X = Y + T;
+ Y -= T;
+ T = d / sind;
+ D = 4. * T * T;
+ A = D * E;
+ B = D + D;
+ geod_S = geod_a * sind * (T - f4 * (T * X - Y) +
+ f64 * (X * (A + (T - .5 * (A - E)) * X) -
+ Y * (B + E * Y) + D * X * Y));
+ tandlammp = tan(.5 * (dlam - .25 * (Y + Y - E * (4. - X)) *
+ (f2 * T + f64 * (32. * T - (20. * T - A)
+ * X - (B +
+ 4.) * Y)) *
+ tan(dlam)));
+ } else {
+ geod_S = geod_a * d;
+ tandlammp = tan(dlamm);
+ }
+ u = atan2(sindthm, (tandlammp * costhm));
+ v = atan2(cosdthm, (tandlammp * sinthm));
+ al12 = adjlon(TWOPI + v - u);
+ al21 = adjlon(TWOPI - v - u);
+}
diff --git a/navit/tools/gpx2navit_txt/src/geod_set.c b/navit/tools/gpx2navit_txt/src/geod_set.c
new file mode 100644
index 000000000..1ba2ef42f
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/geod_set.c
@@ -0,0 +1,95 @@
+#ifndef lint
+/*
+ * static const char SCCSID[]="@(#)geod_set.c 4.8 95/09/23 GIE REL";
+ */
+#endif
+
+#define _IN_GEOD_SET
+
+#include <string.h>
+#include "projects.h"
+#include "geodesic.h"
+#include "emess.h"
+void geod_set(int argc, char **argv)
+{
+ paralist *start = 0, *curr = NULL; /* added NULL */
+ double es;
+ char *name;
+ int i;
+
+/*
+ * put arguments into internal linked list
+ */
+ if (argc <= 0)
+ emess(1, "no arguments in initialization list");
+ for (i = 0; i < argc; ++i)
+ if (i)
+ curr = curr->next = pj_mkparam(argv[i]);
+ else
+ start = curr = pj_mkparam(argv[i]);
+/*
+ * set elliptical parameters
+ */
+ if (pj_ell_set(start, &geod_a, &es))
+ emess(1, "ellipse setup failure");
+/*
+ * set units
+ */
+ if ((name = pj_param(start, "sunits").s)) { /* added parentheses */
+ char *s;
+
+ for (i = 0; (s = pj_units[i].id) && strcmp(name, s); ++i);
+ if (!s)
+ emess(1, "%s unknown unit conversion id", name);
+ fr_meter = 1. / (to_meter = atof(pj_units[i].to_meter));
+ } else
+ to_meter = fr_meter = 1.;
+ if ((ellipse = es != 0.)) { /* added parentheses */
+ onef = sqrt(1. - es);
+ geod_f = 1 - onef;
+ f2 = geod_f / 2;
+ f4 = geod_f / 4;
+ f64 = geod_f * geod_f / 64;
+ } else {
+ onef = 1.;
+ geod_f = f2 = f4 = f64 = 0.;
+ }
+/*
+ * check if line or arc mode
+ */
+ if (pj_param(start, "tlat_1").i) {
+ double del_S;
+#undef f
+ phi1 = pj_param(start, "rlat_1").f;
+ lam1 = pj_param(start, "rlon_1").f;
+ if (pj_param(start, "tlat_2").i) {
+ phi2 = pj_param(start, "rlat_2").f;
+ lam2 = pj_param(start, "rlon_2").f;
+ geod_inv();
+ geod_pre();
+ } else if ((geod_S = pj_param(start, "dS").f)) { /* added
+ * parentheses
+ */
+ al12 = pj_param(start, "rA").f;
+ geod_pre();
+ geod_for();
+ } else
+ emess(1, "incomplete geodesic/arc info");
+ if ((n_alpha = pj_param(start, "in_A").i) > 0) {
+ if (!(del_alpha = pj_param(start, "rdel_A").f))
+ emess(1, "del azimuth == 0");
+ } else if ((del_S = fabs(pj_param(start, "ddel_S").f))) { /* added
+ * parentheses
+ */
+ n_S = geod_S / del_S + .5;
+ } else if ((n_S = pj_param(start, "in_S").i) <= 0)
+ emess(1, "no interval divisor selected");
+ }
+/*
+ * free up linked list
+ */
+ for (; start; start = curr) {
+ curr = start->next;
+ pj_dalloc(start);
+ }
+}
diff --git a/navit/tools/gpx2navit_txt/src/geodesic.h b/navit/tools/gpx2navit_txt/src/geodesic.h
new file mode 100644
index 000000000..b9aa853d4
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/geodesic.h
@@ -0,0 +1,51 @@
+#ifndef lint
+/*static char GEODESIC_H_ID[] = "@(#)geodesic.h 4.3 95/08/19 GIE REL"; */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _IN_GEOD_SET
+# define GEOD_EXTERN extern
+#else
+# define GEOD_EXTERN
+#endif
+
+GEOD_EXTERN struct geodesic {
+ double A;
+ double LAM1, PHI1, ALPHA12;
+ double LAM2, PHI2, ALPHA21;
+ double DIST;
+ double ONEF, FLAT, FLAT2, FLAT4, FLAT64;
+ int ELLIPSE;
+} GEODESIC;
+
+# define geod_a GEODESIC.A
+# define lam1 GEODESIC.LAM1
+# define phi1 GEODESIC.PHI1
+# define al12 GEODESIC.ALPHA12
+# define lam2 GEODESIC.LAM2
+# define phi2 GEODESIC.PHI2
+# define al21 GEODESIC.ALPHA21
+# define geod_S GEODESIC.DIST
+# define geod_f GEODESIC.FLAT
+# define onef GEODESIC.ONEF
+# define f2 GEODESIC.FLAT2
+# define f4 GEODESIC.FLAT4
+# define ff2 GEODESIC.FLAT4
+# define f64 GEODESIC.FLAT64
+# define ellipse GEODESIC.ELLIPSE
+
+
+GEOD_EXTERN int n_alpha, n_S;
+GEOD_EXTERN double to_meter, fr_meter, del_alpha;
+
+void geod_set(int, char **);
+void geod_for(void);
+void geod_pre(void);
+void geod_inv(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/navit/tools/gpx2navit_txt/src/gpx2navit_txt.h b/navit/tools/gpx2navit_txt/src/gpx2navit_txt.h
new file mode 100644
index 000000000..cd4b5e495
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/gpx2navit_txt.h
@@ -0,0 +1,273 @@
+#ifndef GPX2SHP_H_INCLUDED
+#define GPX2SHP_H_INCLUDED
+
+#define PROG gpx2navit_txt
+#define FILENAMELENGTH 255 /* 255 is max length for dbf string column */
+#define COMMENTLENGTH 255 /* 255 is max length for dbf string column */
+#define NAMELENGTH 32
+#define TIMELENGTH 32
+#define TYPELENGTH 16
+#define BUFFSIZE 8192
+#define DATABUFSIZE 16
+#define failToWriteAttr(S, T) failToWriteAttrRep((S), (T),__FILE__, __LINE__ )
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <libgen.h>
+#include <getopt.h>
+#include <time.h>
+#include <assert.h>
+#include <expat.h>
+#include "errorcode.h"
+//#include "shapefil.h"
+
+
+#define DEBUG 0
+/**
+ * make xml parent and child list
+ */
+typedef struct parent {
+ char *name; /** element name */
+ struct parent *parentptr;
+ /** parent pointer */
+} parent;
+
+/**
+ * set attribute columns on/off
+ */
+typedef struct g2scolumns {
+/**
+ * each member corresponds to attribute column of attribute table
+ */
+ int name;
+ int cmt;
+ int desc;
+ int src;
+ int link;
+ int type;
+ int time;
+ int number;
+ int ele;
+ int magvar;
+ int geoidheight;
+ int sym;
+ int fix;
+ int sat;
+ int hdop;
+ int vdop;
+ int pdop;
+ int ageofdgpsdata;
+ int dgpsid;
+ int length;
+ int interval;
+ int speed;
+ int points;
+ int gpxline;
+} g2scolumns;
+
+/**
+ * store each path attribute values for trackpoint and route.
+ */
+typedef struct pathattr {
+ char name[NAMELENGTH];
+ char cmt[COMMENTLENGTH];
+ char desc[COMMENTLENGTH];
+ char src[COMMENTLENGTH];
+ char link[FILENAMELENGTH];
+ int number;
+ char type[TYPELENGTH];
+ double length;
+ double interval;
+ double speed;
+ /*
+ double *x;
+ double *y;
+ double *z;
+ */
+ double *point;
+ int count;
+} pathattr;
+
+/**
+ * store each point attribute values.
+ */
+typedef struct g2sattr {
+/**
+ * the structure cames from GPX1.1 format
+ */
+ double lon;
+ double lat;
+ double minlon;
+ double minlat;
+ double maxlon;
+ double maxlat;
+ char name[NAMELENGTH];
+ char cmt[COMMENTLENGTH];
+ char desc[COMMENTLENGTH];
+ char src[COMMENTLENGTH];
+ char link[FILENAMELENGTH];
+ char type[TYPELENGTH];
+ char time[TIMELENGTH];
+ int number;
+ double ele;
+ double magvar;
+ double geoidheight;
+ char sym[NAMELENGTH];
+ char fix[NAMELENGTH];
+ int sat;
+ double hdop;
+ double vdop;
+ double pdop;
+ double ageofdgpsdata;
+ int dgpsid;
+ char author[NAMELENGTH];
+ char keywords[NAMELENGTH];
+ char copyright[NAMELENGTH];
+ int year;
+ char license[NAMELENGTH];
+} g2sattr;
+
+/**
+ * statistics structure
+ */
+typedef struct g2sstats {
+ int trkpoints; /** track point total count */
+ int trkcount; /** track path total count */
+ double trklength; /** track total length */
+ int rtepoints; /** route point total count */
+ int rtecount; /** route path totol count */
+ double rtelength; /** route total length */
+ int wptpoints; /** way point total count */
+ int trkunconverted; /** unconverted track path count */
+ int rteunconverted; /** unconverted route path count */
+} g2sstats;
+
+/**
+ * cluster of all dbfhandles
+ */
+//typedef struct dbfhandles {
+// DBFHandle trk; /** for track */
+// DBFHandle wpt; /** for waypoint */
+// DBFHandle rte; /** for route */
+// DBFHandle trk_edg; /** for track each edge */
+// DBFHandle trk_pnt; /** for track each point */
+// DBFHandle rte_edg; /** for route each edge */
+// DBFHandle rte_pnt; /** for route each point */
+//} dbfhandles;
+
+/**
+ * cluster of all shphandles
+ */
+//typedef struct shphandles {
+// SHPHandle trk; /** for track */
+// SHPHandle wpt; /** for waypoint */
+// SHPHandle rte; /** for route */
+// SHPHandle trk_edg; /** for track each edge */
+// SHPHandle trk_pnt; /** for track each point */
+// SHPHandle rte_edg; /** for route each edge */
+// SHPHandle rte_pnt; /** for route each point */
+//} shphandles;
+
+/**
+ * propaties structure for gpx2navit_txt
+ */
+typedef struct g2sprop {
+ int parseWpt; /** convert waypoint data or not */
+ int parseTrk; /** convert track data or not */
+ int parseRte; /** convert route data or not */
+ int is3d; /** using 3D mode */
+ int isEdge; /** convert path data as each separated path */
+ int isPoint; /** convert path data as point */
+ int isFast; /** fast mode that skips path check */
+ int needsStats; /** shows statistics at last */
+ int minpoints; /** minimum points to convert as a path */
+ int minlength; /** minimum length to convert as a path */
+ int mintime; /** minimum time to convert as a path */
+ int verbose; /** verbose mode on/off */
+ char *sourcefile; /** source .gpx file */
+ char *output; /** output file base name */
+ char *ellipsoid; /** ellipsoid type to calculate length */
+ char *lengthUnit; /** length unit for attributes*/
+ double length2meter;/** meter value of lenght unit */
+ char *timeUnit; /** time unit for attributes */
+ double time2sec; /** value to convert time unit to second */
+ char *speedLengthUnit;
+ /** lenght unit to calculate speed*/
+ double speed2meter; /** meter value of speedLengthUnit */
+ char *speedTimeUnit;/** time unit to calculate speed */
+ int speed2sec; /** value to convert speedTimeUnit to seconde */
+ g2sstats *stats; /** convert statistics */
+ g2scolumns *cols; /** attribute table column switch */
+} g2sprop;
+
+/**
+ * userdata structure between expat methods
+ */
+typedef struct parsedata {
+ int depth; /** xml path depth */
+ char *databuf; /** character buffer in tags */
+ char *bufptr; /** pointer to databuf to add '\0' to databuf */
+ int failed; /** xml parse failed flag */
+ int failedid; /** xml parse failed id */
+ XML_Parser parser; /** xml parser itself*/
+ parent *parent; /** pointer to parent node */
+ parent *current; /** pointer to current node */
+ FILE *fp; /** File handle to write out data points*/
+// shphandles *shps; /** .shp file cluster that is used in this program */
+// dbfhandles *dbfs; /** .dbf file cluster that is used in this program */
+ g2sattr *attr; /** each point attributes */
+ pathattr *pattr; /** each path attributes */
+ g2sprop *prop; /** propaties for this program */
+} parsedata;
+
+/* utils.c */
+void checkEllpsUnit(char *unit);
+double checkLengthUnit(char *unit);
+int checkTimeUnit(char *unit);
+double getTimeInterval(char *_t, char *t);
+double getSpeed(double length, double ti, double to_meter, int to_sec);
+double getDistance(double _x, double _y, double x, double y);
+//void closeShpFiles(shphandles * shps);
+//void closeDbfFiles(dbfhandles * dbfs);
+void *myMallocRep(size_t size, const char *fileName, int line);
+
+/* misc.c */
+void failToWriteAttrRep(int iShape, int col, char *file, int line);
+void showStats(g2sprop * prop);
+void wipePathAttr(pathattr * pattr);
+pathattr *createPathAttr(void);
+void wipeAttr(g2sattr * attr);
+void setColsDefault(g2scolumns * cols);
+g2scolumns *createCols(void);
+g2sattr *createAttr(void);
+g2sprop *createProp(void);
+void closeProp(g2sprop * prop);
+//shphandles *createShps(void);
+//dbfhandles *createDbfs(void);
+parsedata *createParsedata(XML_Parser parser, g2sprop * prop);
+void closeParsedata(parsedata * pdata);
+
+/* parser.c */
+void parseMain(g2sprop * pr);
+
+/* elementControl.c */
+void startElementControl(parsedata * pdata, const char *element,
+ const char **attr);
+void endElementControl(parsedata * pdata, const char *element);
+
+/* setwpt.c */
+void setWpt( parsedata * pdata);
+
+/* setpath.c */
+void initPathAttr(pathattr * pattr, g2sattr * attr);
+void setPathInterval(parsedata *pdata);
+void setPathData(pathattr * parrt, g2sattr * attr);
+void setPath( parsedata * pdata);
+
+/* setmetadata.c */
+void setMetadata(parsedata * pdata);
+
+#endif
diff --git a/navit/tools/gpx2navit_txt/src/main.c b/navit/tools/gpx2navit_txt/src/main.c
new file mode 100644
index 000000000..af8df875c
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/main.c
@@ -0,0 +1,389 @@
+#include "gpx2navit_txt.h"
+#include "geodesic.h"
+
+void version(void);
+void usage(char **argv);
+void setDefault(g2sprop * prop);
+void setOptions(int argc, char **argv, g2sprop * prop);
+
+/**
+ * Shows a version
+ */
+void version(void)
+{
+ fprintf(stdout, "gpx2navit_txt 0.1\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "by Toshihiro Hiraoka\n");
+ fprintf(stdout, " Petter Reinholdtsen\n");
+}
+
+/**
+ * Shows a usage message
+ */
+void usage(char **argv)
+{
+ fprintf(stdout, "Usage: %s gpxfile [options] [-o output basename]\n",
+ argv[0]);
+ fprintf(stdout,
+ "-o, --output Sets output basename. The default is (source file\n");
+ fprintf(stdout, " name) - (extention name)\n");
+ fprintf
+ (stdout,
+ "-w, --waypoints Converts only waypoints data from a gpx file.\n");
+ fprintf(stdout,
+ "-t, --trackpoints Converts only trackpoints data from a gpx file.\n");
+ fprintf(stdout,
+ "-r, --routes Converts only routes data from a gpx file.\n");
+ fprintf(stdout,
+ "-a, --all Converts all types of data from a gpx file.(default)\n");
+ fprintf(stdout,
+ "-e, --as-edge Makes a separated output by each edges.\n");
+ fprintf(stdout,
+ "-p, --as-point Makes a separated output by each points.\n");
+ fprintf(stdout,
+ "-s, --stats Shows simple statistics of the outputs.\n");
+ fprintf(stdout,
+ "-b, --basic-columns Stores only basic data as attribures to \n");
+ fprintf(stdout,
+ " reduce memory and storage usage.\n");
+ fprintf(stdout,
+ " (ele, name, cmt, type, time, fix, sym and number).\n");
+ fprintf(stdout,
+ "-L, --no-length Removes length column from a waypoint or trackpoint\n");
+ fprintf(stdout, " attribute table.\n");
+ fprintf
+ (stdout,
+ "-S, --no-speed Removes speed column from a waypoint or trackpoint\n");
+ fprintf(stdout, " attribute table.\n");
+ fprintf
+ (stdout,
+ "-T, --no-time Removes time column from an attribute table.\n");
+ fprintf(stdout,
+ "-g, --gpxline Adds line number of GPX file as attribures.\n");
+ fprintf
+ (stdout,
+ "-f, --fast Make it faster without any checks.\n");
+ fprintf(stdout,
+ "-3, --3d Converts data using 3d format. (It's not compatible\n");
+ fprintf(stdout, " for Arcview 3.x.)\n");
+ fprintf(stdout,
+ " --min-points Sets path minimum points to convert for noise reduction.\n");
+ fprintf(stdout, " Default is 2.\n");
+ fprintf(stdout,
+ " --min-length Sets path minimum length to convert for noise reduction.\n");
+ fprintf(stdout, " Default is 0.\n");
+ fprintf(stdout,
+ " --min-time Sets path minimum time period to convert for noise\n");
+ fprintf(stdout, " reduction.\n");
+ fprintf(stdout, " Default is 0.\n");
+ fprintf(stdout,
+ " --length-unit Sets length unit from m,km,feet,mi and etc.\n");
+ fprintf(stdout, " The default is m.\n");
+ fprintf(stdout,
+ " You can see the unit list from \"geod -lu\" command.\n");
+ fprintf
+ (stdout,
+ " --time-unit Sets time unit. The default is sec.\n");
+ fprintf(stdout,
+ " You can set from day, hour, min and sec.\n");
+ fprintf(stdout,
+ " --speed-length-unit Sets length unit for speed.\n");
+ fprintf(stdout, " The default is km.\n");
+ fprintf(stdout,
+ " You can see the unit list from \"geod -lu\" command.\n");
+ fprintf(stdout,
+ " --speed-time-unit Sets time unit for speed calulation. Default is hour.\n");
+ fprintf(stdout,
+ " You can set from day, hour, min and sec.\n");
+ fprintf(stdout,
+ " --length-ellipsoid Sets length ellipsoid like UGS84, clrk66. The default is\n");
+ fprintf(stdout, " UGS84.\n");
+ fprintf
+ (stdout,
+ " You can see the unit list from \"geod -le\" command.\n");
+ fprintf(stdout, "-v, --verbose Gives many messages.\n");
+ fprintf(stdout, " --version Shows version.\n");
+ fprintf(stdout, "-h, --help Shows this list.\n");
+}
+
+/**
+ * Sets default values to the properties when there is no user setting.
+ */
+void setDefault(g2sprop * prop)
+{
+ char *pargv[2];
+ int pargc = 2;
+ char *ellps;
+ /* if there are no options like -p,-w,-e, sets as -a */
+ if (!(prop->parseWpt | prop->parseTrk | prop->parseRte)) {
+ prop->parseWpt = 1;
+ prop->parseTrk = 1;
+ prop->parseRte = 1;
+ }
+ /* if there is no output setting, sets it as [sourcefile name] - ".gpx" */
+ if (prop->output == NULL) {
+ char *dot = strrchr(prop->sourcefile, '.');
+ prop->output =
+ (char *) malloc(sizeof(char) * strlen(prop->sourcefile) + 1);
+ if (0 == strcmp(dot, ".gpx")) {
+ int len = dot - prop->sourcefile;
+ strncpy(prop->output, prop->sourcefile, len);
+ prop->output[len] = 0;
+ } else {
+ fprintf(stderr,
+ "The source file doesn't have .gpx extension.\n");
+ exit(ERR_ISNOTGPX);
+ }
+ }
+ /* sets ellipsoid "WGS84" */
+ if (prop->ellipsoid == NULL) {
+ prop->ellipsoid = (char *) malloc(sizeof(char) * 7);
+ strcpy(prop->ellipsoid, "WGS84");
+ }
+ /* sets lengthUnit "m" */
+ if (prop->lengthUnit == NULL) {
+ prop->lengthUnit = (char *) malloc(sizeof(char) * 2);
+ strcpy(prop->lengthUnit, "m");
+ }
+ /* sets timeUnit "sec" */
+ if (prop->timeUnit == NULL) {
+ prop->timeUnit = (char *) malloc(sizeof(char) * 4);
+ strcpy(prop->timeUnit, "sec");
+ }
+ /* sets speedLengthUnit "km" */
+ if (prop->speedLengthUnit == NULL) {
+ prop->speedLengthUnit = (char *) malloc(sizeof(char) * 3);
+ strcpy(prop->speedLengthUnit, "km");
+ }
+ /* sets speedTimeUnit "hour" */
+ if (prop->speedTimeUnit == NULL) {
+ prop->speedTimeUnit = (char *) malloc(sizeof(char) * 5);
+ strcpy(prop->speedTimeUnit, "hour");
+ }
+ /* sets ellipsoid setting to geod* programs */
+ ellps = malloc(sizeof(char) * (strlen(prop->ellipsoid) + 8));
+ strcpy(ellps, "+ellps=");
+ strcat(ellps, prop->ellipsoid);
+ pargv[0] = ellps;
+ pargv[1] = prop->lengthUnit;
+ checkEllpsUnit(prop->ellipsoid);
+ prop->length2meter = checkLengthUnit(prop->lengthUnit);
+ prop->time2sec = checkTimeUnit(prop->timeUnit);
+ prop->speed2meter = checkLengthUnit(prop->speedLengthUnit);
+ prop->speed2sec = checkTimeUnit(prop->speedTimeUnit);
+ geod_set(pargc, pargv);
+ if (prop->verbose) {
+ printf("source filename:\t%s\n", prop->sourcefile);
+ printf("output file base name:\t%s\n", prop->output);
+ }
+ free(ellps);
+}
+
+/**
+ * Set options from command arguments
+ */
+void setOptions(int argc, char **argv, g2sprop * prop)
+{
+ int result;
+ /* option struct for getopt_long */
+ struct option const long_options[] = {
+ {"waypoints", no_argument, 0, 'w'},
+ {"trackpoints", no_argument, 0, 't'},
+ {"routes", no_argument, 0, 'r'},
+ {"output", required_argument, 0, 'o'},
+ {"as-edge", no_argument, 0, 'e'},
+ {"as-point", no_argument, 0, 'p'},
+ {"min-points", required_argument, 0, 'P'},
+ {"min-length", required_argument, 0, 'l'},
+ {"min-time", required_argument, 0, 'm'},
+ {"stats", no_argument, 0, 's'},
+ {"basic-columns", no_argument, 0, 'b'},
+ {"fast", no_argument, 0, 'f'},
+ {"length-unit", required_argument, 0, '4'},
+ {"time-unit", required_argument, 0, '8'},
+ {"length-ellipsoid", required_argument, 0, '7'},
+ {"speed-length-unit", required_argument, 0, '5'},
+ {"speed-time-unit", required_argument, 0, '6'},
+ {"no-speed", no_argument, 0, 'S'},
+ {"no-length", no_argument, 0, 'L'},
+ {"no-time", no_argument, 0, 'T'},
+ {"verbose", no_argument, 0, 'v'},
+ {"gpxline", no_argument, 0, 'g'},
+ {"all", no_argument, 0, 'a'},
+ {"version", no_argument, 0, 'V'},
+ {"help", no_argument, 0, '?'},
+ {0, no_argument, 0, '0'},
+ };
+ if (argc <= 1) {
+ fprintf(stderr, "There is no argument.\n");
+ usage(argv);
+ exit(ERR_NOARGS);
+ }
+ /* set option attributes */
+ while ((result =
+ getopt_long(argc, argv, "3wtrao:epfP:l:m:bS4:5:6:7:8:LTSsvg0",
+ long_options, NULL)) != -1) {
+ switch (result) {
+ case '3': /* 3d output */
+ prop->is3d = 1;
+ break;
+ case 'w': /* converts only waypoint */
+ prop->parseWpt = 1;
+ break;
+ case 't': /* converts only trackpoint */
+ prop->parseTrk = 1;
+ break;
+ case 'r': /* converts only route */
+ prop->parseRte = 1;
+ break;
+ case 'a': /* converts all */
+ prop->parseWpt = 1;
+ prop->parseTrk = 1;
+ prop->parseRte = 1;
+ break;
+ case 'o': /* sets basename of output file */
+ prop->output =
+ (char *) malloc(sizeof(char) * strlen(optarg) + 1);
+ strcpy(prop->output, optarg);
+ break;
+ case 'e': /* make output by each edges */
+ if (prop->isEdge) {
+ fprintf(stderr, "option -e cannot use with -f\n");
+ exit(ERR_OPTIONCONFRICT);
+ }
+ prop->isEdge = 1;
+ break;
+ case 'p': /* make output by each edges */
+ prop->isPoint = 1;
+ break;
+ case 'f': /* make it faster */
+ if (prop->isEdge) {
+ fprintf(stderr, "option -f cannot use with -e\n");
+ exit(ERR_OPTIONCONFRICT);
+ }
+ prop->isFast = 1;
+ prop->cols->desc = 0;
+ prop->cols->src = 0;
+ prop->cols->link = 0;
+ prop->cols->magvar = 0;
+ prop->cols->geoidheight = 0;
+ prop->cols->sat = 0;
+ prop->cols->hdop = 0;
+ prop->cols->vdop = 0;
+ prop->cols->pdop = 0;
+ prop->cols->ageofdgpsdata = 0;
+ prop->cols->dgpsid = 0;
+ prop->cols->length = 0;
+ prop->cols->interval = 0;
+ prop->cols->speed = 0;
+ break;
+ case 'P': /* sets minimun points as a path */
+ prop->minpoints = atoi(optarg);
+ break;
+ case 'l': /* sets minimun length as a path */
+ prop->minlength = atoi(optarg);
+ break;
+ case 'm': /* sets minimun time as a path */
+ prop->mintime = atoi(optarg);
+ break;
+ case 'b': /* use only some columns */
+ prop->cols->desc = 0;
+ prop->cols->src = 0;
+ prop->cols->link = 0;
+ prop->cols->magvar = 0;
+ prop->cols->geoidheight = 0;
+ prop->cols->sat = 0;
+ prop->cols->hdop = 0;
+ prop->cols->vdop = 0;
+ prop->cols->pdop = 0;
+ prop->cols->ageofdgpsdata = 0;
+ prop->cols->dgpsid = 0;
+ prop->cols->length = 0;
+ prop->cols->interval = 0;
+ prop->cols->speed = 0;
+ break;
+ case 'S': /* doesn't make speed column */
+ prop->cols->speed = 0;
+ break;
+ case '4': /* sets length unit */
+ prop->lengthUnit = malloc(sizeof(char) * (strlen(optarg) + 1));
+ strcpy(prop->lengthUnit, optarg);
+ break;
+ case '5': /* sets length unit for calculating speed */
+ prop->speedLengthUnit =
+ malloc(sizeof(char) * (strlen(optarg) + 1));
+ strcpy(prop->speedLengthUnit, optarg);
+ break;
+ case '6': /* sets time unit for calculating speed */
+ prop->speedTimeUnit =
+ malloc(sizeof(char) * (strlen(optarg) + 1));
+ strcpy(prop->speedTimeUnit, optarg);
+ break;
+ case '7': /* sets ellipsoid for calculating length */
+ prop->ellipsoid = malloc(sizeof(char) * (strlen(optarg) + 1));
+ strcpy(prop->ellipsoid, optarg);
+ break;
+ case '8': /* sets time unit */
+ prop->timeUnit = malloc(sizeof(char) * (strlen(optarg) + 1));
+ strcpy(prop->timeUnit, optarg);
+ break;
+ case 'L': /* doesn't make length column */
+ prop->cols->length = 0;
+ break;
+ case 'T': /* doesn't make time column */
+ prop->cols->interval = 0;
+ break;
+ case 's': /* shows source file stats */
+ prop->needsStats = 1;
+ break;
+ case 'v': /* verbose mode */
+ prop->verbose = 1;
+ break;
+ case 'V': /* shows version */
+ version();
+ exit(EXIT_SUCCESS);
+ break;
+ case 'g': /* adds gpx line number column */
+ prop->cols->gpxline = 1;
+ break;
+ case ':':
+ usage(argv);
+ exit(ERR_WRONGOPTION);
+ break;
+ case '0':
+ usage(argv);
+ exit(ERR_WRONGOPTION);
+ break;
+ default:
+ usage(argv);
+ exit(ERR_WRONGOPTION);
+ break;
+ }
+ }
+ /* gets a source file name */
+ if(argv[optind] == NULL) {
+ fprintf(stderr, "There is no gpxfile description.\n");
+ usage(argv);
+ exit(ERR_WRONGOPTION);
+ }
+ prop->sourcefile = malloc(sizeof(char) * (strlen(argv[optind]) + 1));
+ /** @note needs to change here to support
+ * a several files convertion */
+ strcpy(prop->sourcefile, argv[optind]);
+ setDefault(prop);
+}
+
+/**
+ * Main
+ */
+int main(int argc, char **argv)
+{
+ g2sprop *prop;
+ prop = createProp();
+ setOptions(argc, argv, prop);
+ parseMain(prop);
+ if (prop->needsStats)
+ showStats(prop);
+ closeProp(prop);
+ return (0);
+}
diff --git a/navit/tools/gpx2navit_txt/src/misc.c b/navit/tools/gpx2navit_txt/src/misc.c
new file mode 100644
index 000000000..b5fddd347
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/misc.c
@@ -0,0 +1,344 @@
+#include "gpx2navit_txt.h"
+
+void failToWriteAttrRep(int iShape, int col, char *file, int line);
+void showStats(g2sprop * prop);
+void wipePathAttr(pathattr * pattr);
+pathattr *createPathAttr(void);
+void wipeAttr(g2sattr * attr);
+void setColsDefault(g2scolumns * cols);
+g2scolumns *createCols(void);
+g2sattr *createAttr(void);
+g2sprop *createProp(void);
+void closeProp(g2sprop * prop);
+//shphandles *createShps(void);
+//dbfhandles *createDbfs(void);
+parsedata *createParsedata(XML_Parser parser, g2sprop * prop);
+void closeParsedata(parsedata * pdata);
+
+/**
+ * message when fail to write attribute
+ */
+void failToWriteAttrRep(int iShape, int col, char *file, int line)
+{
+ printf("Fail to write a attribute at %s:%i. shapeid:%i col:%i\n", file,
+ line, iShape, col);
+}
+
+/**
+ * shows short statistics
+ */
+void showStats(g2sprop * prop)
+{
+ g2sstats *stats = prop->stats;
+ double ratio;
+ if (prop->needsStats) {
+ if (prop->parseTrk) {
+ if (stats->trkunconverted != 0) {
+ ratio =
+ (double) stats->trkunconverted / (stats->trkcount +
+ stats->
+ trkunconverted) *
+ 100;
+ } else {
+ ratio = 0;
+ }
+ printf("Track Points:\n");
+ printf("\ttrack count:\t%i\n", stats->trkcount);
+ printf("\tpoint count:\t%i\n", stats->trkpoints);
+ if (!prop->isFast) {
+ printf("\ttotal length:\t%f\n", stats->trklength);
+ printf("\tunconverted:\t%i(%5.2f%%)\n",
+ stats->trkunconverted, ratio);
+ }
+ }
+ if (prop->parseRte) {
+ if (stats->rteunconverted != 0) {
+ ratio =
+ (double) stats->rteunconverted / (stats->rtecount +
+ stats->
+ rteunconverted) *
+ 100;
+ } else {
+ ratio = 0;
+ }
+ printf("Routes:\n");
+ printf("\troute count:\t%i\n", stats->rtecount);
+ printf("\tpoint count:\t%i\n", stats->rtepoints);
+ if (!prop->isFast) {
+ printf("\ttotal length:\t%f\n", stats->rtelength);
+ printf("\tunconverted:\t%i(%5.2f%%)\n",
+ stats->rteunconverted, ratio);
+ }
+ }
+ if (prop->parseWpt) {
+ printf("Waypoints:\n");
+ printf("\tpoint count:\t%i\n", stats->wptpoints);
+ }
+ }
+}
+
+/**
+ * clears a path attribute structure
+ */
+void wipePathAttr(pathattr * pattr)
+{
+ pattr->name[0] = '\0';
+ pattr->cmt[0] = '\0';
+ pattr->desc[0] = '\0';
+ pattr->src[0] = '\0';
+ pattr->link[0] = '\0';
+ pattr->number = 0;
+ pattr->type[0] = '\0';
+ pattr->length = 0;
+ pattr->interval = 0;
+ pattr->speed = 0;
+ //pattr->point = NULL;
+ pattr->count = 0;
+}
+
+/**
+ * creates a new path attribute
+ */
+pathattr *createPathAttr(void)
+{
+ pathattr *pattr;
+ pattr = (pathattr *) malloc(sizeof(pathattr));
+ wipePathAttr(pattr);
+ return pattr;
+}
+
+/**
+ * clears a element attribute structure
+ */
+void wipeAttr(g2sattr * attr)
+{
+ attr->lon = 0;
+ attr->lat = 0;
+ attr->minlon = 0;
+ attr->minlat = 0;
+ attr->maxlon = 0;
+ attr->maxlat = 0;
+ attr->name[0] = '\0';
+ attr->cmt[0] = '\0';
+ attr->desc[0] = '\0';
+ attr->src[0] = '\0';
+ attr->link[0] = '\0';
+ attr->type[0] = '\0';
+ attr->time[0] = '\0';
+ attr->number = 0;
+ attr->ele = 0;
+ attr->magvar = 0;
+ attr->geoidheight = 0;
+ attr->sym[0] = '\0';
+ attr->fix[0] = '\0';
+ attr->sat = 0;
+ attr->hdop = 0;
+ attr->vdop = 0;
+ attr->pdop = 0;
+ attr->ageofdgpsdata = 0;
+ attr->dgpsid = 0;
+ attr->author[0] = '\0';
+ attr->keywords[0] = '\0';
+ attr->copyright[0] = '\0';
+ attr->year = 0;
+ attr->license[0] = '\0';
+ attr->minlat = 0;
+ attr->minlon = 0;
+ attr->maxlat = 0;
+ attr->maxlon = 0;
+}
+
+/**
+ * sets default values to a column properties.
+ */
+void setColsDefault(g2scolumns * cols)
+{
+ cols->name = 1;
+ cols->cmt = 1;
+ cols->desc = 1;
+ cols->src = 1;
+ cols->link = 1;
+ cols->type = 1;
+ cols->time = 1;
+ cols->number = 1;
+ cols->ele = 1;
+ cols->magvar = 1;
+ cols->geoidheight = 1;
+ cols->sym = 1;
+ cols->fix = 1;
+ cols->sat = 1;
+ cols->hdop = 1;
+ cols->vdop = 1;
+ cols->pdop = 1;
+ cols->ageofdgpsdata = 1;
+ cols->dgpsid = 1;
+ cols->length = 1;
+ cols->interval = 1;
+ cols->speed = 1;
+ cols->points = 1;
+ cols->gpxline = 0;
+}
+
+/**
+ * creates a column structure
+ */
+g2scolumns *createCols(void)
+{
+ g2scolumns *cols;
+ cols = (g2scolumns *) malloc(sizeof(g2scolumns));
+ setColsDefault(cols);
+ return cols;
+}
+
+/**
+ * creates a element attribute structure.
+ */
+g2sattr *createAttr(void)
+{
+ g2sattr *attr;
+ attr = (g2sattr *) malloc(sizeof(g2sattr));
+ wipeAttr(attr);
+ return attr;
+}
+
+/**
+ * creates a properties structure for gpx2shp
+ */
+g2sprop *createProp(void)
+{
+ g2sprop *prop;
+ g2sstats *stats;
+ g2scolumns *cols;
+ prop = malloc(sizeof(g2sprop));
+ stats = malloc(sizeof(g2sstats));
+ cols = createCols();
+ prop->stats = stats;
+ prop->parseWpt = 0;
+ prop->parseTrk = 0;
+ prop->parseRte = 0;
+ prop->minpoints = 2;
+ prop->minlength = 0;
+ prop->mintime = 0;
+ prop->is3d = 0;
+ prop->isEdge = 0;
+ prop->isPoint = 0;
+ prop->isFast = 0;
+ prop->needsStats = 0;
+ prop->verbose = 0;
+ prop->output = NULL;
+ prop->ellipsoid = NULL;
+ prop->lengthUnit = NULL;
+ prop->speedLengthUnit = NULL;
+ prop->speedTimeUnit = NULL;
+ prop->timeUnit = NULL;
+ prop->stats->trkcount = 0;
+ prop->stats->trkpoints = 0;
+ prop->stats->trklength = 0;
+ prop->stats->trkunconverted = 0;
+ prop->stats->rtecount = 0;
+ prop->stats->rtepoints = 0;
+ prop->stats->rtelength = 0;
+ prop->stats->rteunconverted = 0;
+ prop->stats->wptpoints = 0;
+ prop->cols = cols;
+ return prop;
+}
+
+/**
+ * close and free a propertires structure
+ */
+void closeProp(g2sprop * prop)
+{
+ free(prop->stats);
+ free(prop->sourcefile);
+ free(prop->ellipsoid);
+ free(prop->timeUnit);
+ free(prop->speedLengthUnit);
+ free(prop->speedTimeUnit);
+ free(prop->lengthUnit);
+ free(prop->output);
+ free(prop->cols);
+ free(prop);
+}
+
+/**
+ * creates a shapehandles structure
+ */
+//shphandles *createShps(void)
+//{
+// shphandles *shps;
+// shps = malloc(sizeof(shphandles));
+// shps->trk = NULL;
+// shps->wpt = NULL;
+// shps->rte = NULL;
+// shps->trk_edg = NULL;
+// shps->rte_edg = NULL;
+// shps->trk_pnt = NULL;
+// shps->rte_pnt = NULL;
+// return shps;
+//}
+
+/**
+ * creates a dbfhandles structure
+ */
+/* dbfhandles *createDbfs(void)
+{
+ dbfhandles *dbfs;
+ dbfs = malloc(sizeof(dbfhandles));
+ dbfs->trk = NULL;
+ dbfs->wpt = NULL;
+ dbfs->rte = NULL;
+ dbfs->trk_edg = NULL;
+ dbfs->rte_edg = NULL;
+ dbfs->trk_pnt = NULL;
+ dbfs->rte_pnt = NULL;
+ return dbfs;
+} */
+
+/**
+ * creates a parse structure
+ */
+parsedata *createParsedata(XML_Parser parser, g2sprop * prop)
+{
+ parsedata *pdata = (parsedata *) malloc(sizeof(parsedata));
+ pdata->fp = NULL;
+ //shphandles *shps = createShps();
+ //dbfhandles *dbfs = createDbfs();
+ pathattr *pattr = createPathAttr();
+ g2sattr *attr = createAttr();
+ parent *p = (parent *) malloc(sizeof(parent));
+ parent *c = (parent *) malloc(sizeof(parent));
+ p->name = NULL;
+ p->parentptr = NULL;
+ c->name = "root";
+ c->parentptr = p;
+ pdata->depth = 0;
+ pdata->databuf = malloc(sizeof(char) * DATABUFSIZE);
+ pdata->bufptr = NULL;
+ pdata->failed = 0;
+ pdata->failedid = 0;
+ pdata->parser = parser;
+ pdata->parent = p;
+ pdata->current = c;
+ //pdata->shps = shps;
+ //pdata->dbfs = dbfs;
+ pdata->prop = prop;
+ pdata->pattr = pattr;
+ pdata->attr = attr;
+ return pdata;
+}
+
+/*
+ * close and free resoures
+ */
+void closeParsedata(parsedata * pdata)
+{
+ //free(pdata->shps);
+ //free(pdata->dbfs);
+ free(pdata->parent);
+ free(pdata->current);
+ free(pdata->databuf);
+ free(pdata->attr);
+ free(pdata->pattr);
+ free(pdata);
+}
diff --git a/navit/tools/gpx2navit_txt/src/parser.c b/navit/tools/gpx2navit_txt/src/parser.c
new file mode 100644
index 000000000..70104dafe
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/parser.c
@@ -0,0 +1,148 @@
+#include "gpx2navit_txt.h"
+
+void charHandle(void *userdata, const XML_Char * data, int length);
+void startElement(void *userdata, const char *element, const char **attr);
+void endElement(void *userdata, const char *element);
+void parseMain(g2sprop * prop);
+
+/**
+ * a handler to parse charctor data on expat
+ */
+void charHandle(void *userdata, const XML_Char * data, int length)
+{
+ static int bufsize = DATABUFSIZE;
+ static int string_length = 0;
+ int new_length;
+ static int begin_copy = 0;
+ int i;
+ parsedata *pdata = (parsedata *) userdata;
+ if (pdata->bufptr == NULL) {
+ //start of buffer -->pdata->bufptr set to 0 at endelement
+ string_length = 0;
+ begin_copy = 0; //begin to copy after first space
+ pdata->bufptr= pdata->databuf;
+ }
+ new_length = string_length + length + 1; //additonal 0
+ if (bufsize < new_length) {
+ pdata->databuf =
+ realloc(pdata->databuf, new_length);
+ bufsize = new_length;
+ //because of realloc the pointer may have changed
+ pdata->bufptr = pdata->databuf + string_length;
+ }
+ // because expat calls this routine several times on special chars
+ // we need to do following
+ // --concat strings until reset (bufptr set to NULL)
+ // --filter out blank chars at begin of string
+ for (i=0; i<length;i++) {
+ if (begin_copy || !isspace(data[i])) {
+ *pdata->bufptr = data[i];
+ pdata->bufptr++;
+ string_length ++;
+ begin_copy = 1;
+ if (DEBUG) fprintf(stderr,"%c",data[i]);
+ }
+ }
+ *pdata->bufptr = '\0';
+}
+
+/**
+ * a handler when a element starts
+ */
+void startElement(void *userdata, const char *element, const char **attr)
+{
+ parsedata *pdata = (parsedata *) userdata;
+ pdata->parent = pdata->current;
+ pdata->current = malloc(sizeof(parent));
+ pdata->current->name = malloc(sizeof(char) * (strlen(element) + 1));
+ strcpy(pdata->current->name, element);
+ pdata->current->parentptr = pdata->parent;
+ startElementControl(pdata, element, attr);
+ if (pdata->prop->verbose) {
+ int i;
+ for (i = 0; i < pdata->depth; i++)
+ printf(" ");
+ printf("<%s>: ", element);
+ for (i = 0; attr[i]; i += 2) {
+ printf(" %s='%s'", attr[i], attr[i + 1]);
+ }
+ printf("\n");
+ }
+ pdata->depth++;
+}
+
+/**
+ * a handler when a element ends
+ */
+void endElement(void *userdata, const char *element)
+{
+ parsedata *pdata = (parsedata *) userdata;
+ endElementControl(pdata, element);
+ pdata->depth--;
+ if (pdata->prop->verbose) {
+ int i;
+ for (i = 0; i < pdata->depth; i++)
+ printf(" ");
+ printf("</%s>:%s\n ", element,pdata->parent->name);
+ }
+ free(pdata->current->name);
+ free(pdata->current);
+ pdata->current = pdata->parent;
+ pdata->parent = pdata->parent->parentptr;
+}
+
+void parseMain(g2sprop * prop)
+{
+ FILE *fp;
+ char buff[BUFFSIZE];
+ XML_Parser parser;
+ parsedata *pdata;
+ fp = fopen(prop->sourcefile, "r");
+ if (fp == NULL) {
+ fprintf(stderr, "Cannot open gpx file: %s\n", prop->sourcefile);
+ exit(ERR_CANNOTOPEN);
+ }
+ parser = XML_ParserCreate(NULL);
+ if (!parser) {
+ fprintf(stderr, "Couldn't allocate memory for parser\n");
+ exit(ERR_OUTOFMEMORY);
+ }
+ pdata = createParsedata(parser, prop);
+
+ char *output_wpt =
+ (char *) malloc(sizeof(char) * (strlen(pdata->prop->output) + 9));
+ strcpy(output_wpt, pdata->prop->output);
+ strcat(output_wpt, "_nav.txt");
+ pdata->fp = fopen(output_wpt,"w");
+ if (pdata->fp == NULL)
+ {
+ //todo
+ fprintf(stderr,"Failure opening File %s for writing",output_wpt);
+ exit(1);
+ }
+ free(output_wpt);
+ XML_SetUserData(parser, pdata);
+ XML_SetElementHandler(parser, startElement, endElement);
+ XML_SetCharacterDataHandler(parser, charHandle);
+ for (;;) {
+ int done;
+ int len;
+ fgets(buff, BUFFSIZE, fp);
+ len = (int) strlen(buff);
+ if (ferror(fp)) {
+ fprintf(stderr, "Read error file: %s\n", prop->sourcefile);
+ exit(ERR_READERROR);
+ }
+ done = feof(fp);
+ if (done)
+ break;
+ if (!XML_Parse(parser, buff, len, done)) {
+ fprintf(stderr, "Parse error at line %d:\n%s\n",
+ XML_GetCurrentLineNumber(parser),
+ XML_ErrorString(XML_GetErrorCode(parser)));
+ exit(ERR_PARSEERROR);
+ }
+ }
+ fclose(pdata->fp); //close out file
+ closeParsedata(pdata);
+}
diff --git a/navit/tools/gpx2navit_txt/src/setmeta.c b/navit/tools/gpx2navit_txt/src/setmeta.c
new file mode 100644
index 000000000..9d23ffd1c
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/setmeta.c
@@ -0,0 +1,54 @@
+#include "gpx2navit_txt.h"
+
+/**
+ * store gpx metadata into text file
+ */
+void setMetadata(parsedata * pdata)
+{
+ g2sprop *prop = pdata->prop;
+ g2sattr *attr = pdata->attr;
+ FILE *metafile;
+ char *output = malloc(sizeof(char) * (strlen(prop->output) + 10));
+ strcpy(output, prop->output);
+ strcat(output, "_meta.txt");
+ metafile = fopen(output, "w");
+ if (metafile == NULL) {
+ fprintf(stderr, "Cannot create file: %s\n", output);
+ exit(ERR_CREATEFILE);
+ }
+ if (attr->name) {
+ fprintf(metafile, "name\t%s\n", attr->name);
+ }
+ if (attr->desc) {
+ fprintf(metafile, "description\t%s\n", attr->desc);
+ }
+ if (attr->author) {
+ fprintf(metafile, "author\t%s\n", attr->author);
+ }
+ if (attr->copyright) {
+ fprintf(metafile, "copyright\t%s\n", attr->copyright);
+ }
+ if (attr->link) {
+ fprintf(metafile, "link\t%s\n", attr->link);
+ }
+ if (attr->time) {
+ fprintf(metafile, "time\t%s\n", attr->time);
+ }
+ if (attr->keywords) {
+ fprintf(metafile, "keywords\t%s\n", attr->keywords);
+ }
+ if (attr->minlat) {
+ fprintf(metafile, "min latitude\t%f\n", attr->minlat);
+ }
+ if (attr->minlon) {
+ fprintf(metafile, "min longitude\t%f\n", attr->minlon);
+ }
+ if (attr->maxlat) {
+ fprintf(metafile, "max latitude\t%f\n", attr->maxlat);
+ }
+ if (attr->maxlon) {
+ fprintf(metafile, "max longitude\t%f\n", attr->maxlon);
+ }
+ fclose(metafile);
+ free(output);
+}
diff --git a/navit/tools/gpx2navit_txt/src/setpath.c b/navit/tools/gpx2navit_txt/src/setpath.c
new file mode 100644
index 000000000..5402e4ea6
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/setpath.c
@@ -0,0 +1,241 @@
+#include "gpx2navit_txt.h"
+
+void initPathAttr(pathattr * pattr, g2sattr * attr);
+void setEdge(parsedata * pdata, double _x, double _y, double _z,
+ double length, double interval, double speed);
+void setPathInterval(parsedata * pdata);
+void setPathData(pathattr * pattr, g2sattr * attr);
+void countUnconverted(parsedata * pdata);
+void countPath(parsedata * pdata);
+int checkPath(parsedata * pdata);
+void setPath( parsedata * pdata);
+
+
+
+/**
+ * initialize a path attribute
+ */
+void initPathAttr(pathattr * pattr, g2sattr * attr)
+{
+ strcpy(pattr->name, attr->name);
+ strcpy(pattr->cmt, attr->cmt);
+ strcpy(pattr->desc, attr->desc);
+ strcpy(pattr->src, attr->src);
+ strcpy(pattr->link, attr->link);
+ pattr->number = attr->number;
+ strcpy(pattr->type, attr->type);
+ pattr->length = 0;
+ pattr->interval = 0;
+ pattr->speed = 0;
+ pattr->count = 0;
+ pattr->point = NULL;
+}
+
+
+/**
+ * set edge data and store it
+ */
+void setEdge(parsedata * pdata, double _x, double _y, double _z,
+ double length, double interval, double speed)
+{
+ pathattr *pattr = pdata->pattr;
+ static int isFirstTrkAsEdge = 1;
+ static int isFirstRteAsEdge = 1;
+ double x[2], y[2], z[2];
+ double _length, _interval, _speed;
+ if (!strcmp(pdata->current->name, "trkpt")) {
+ if (isFirstTrkAsEdge) {
+ isFirstTrkAsEdge = 0;
+ }
+ } else {
+ if (isFirstRteAsEdge) {
+ isFirstRteAsEdge = 0;
+ }
+ }
+ _length = pattr->length;
+ _interval = pattr->interval;
+ _speed = pattr->speed;
+ pattr->length = length;
+ pattr->interval = interval;
+ pattr->speed = speed;
+ x[0] = _x;
+ y[0] = _y;
+ z[0] = _z;
+ x[1] = pdata->attr->lon;
+ y[1] = pdata->attr->lat;
+ z[1] = pdata->attr->ele;
+ if (pdata->prop->is3d) {
+ } else {
+ }
+ pattr->length = _length;
+ pattr->interval = _interval;
+ pattr->speed = _speed;
+}
+
+/**
+ * sets interval data between two track points
+ */
+void setPathInterval(parsedata * pdata)
+{
+ pathattr *pattr = pdata->pattr;
+ g2sattr *attr = pdata->attr;
+ g2sprop *prop = pdata->prop;
+ static char _t[TIMELENGTH];
+ double intvl = 0;
+ static double _x, _y, _z;
+ double leng = 0;
+ double spd;
+ if (pattr->count == 1) {
+ strcpy(_t, attr->time);
+ } else {
+ /* time interval */
+ intvl = getTimeInterval(_t, attr->time);
+ pattr->interval = pattr->interval + intvl;
+ strcpy(_t, attr->time);
+ /* length interval */
+ leng = getDistance(_x, _y, attr->lon, attr->lat);
+ pattr->length = pattr->length + leng;
+ /* interval speed */
+ spd = getSpeed(leng, intvl, prop->speed2meter, prop->speed2sec);
+ /* sets edge data */
+ if (prop->isEdge) {
+ setEdge(pdata, _x, _y, _z, leng, intvl, spd);
+ }
+ }
+ _x = attr->lon;
+ _y = attr->lat;
+ _z = attr->ele;
+}
+
+/**
+ * sets each track point data in array.
+ */
+void setPathData(pathattr * pattr, g2sattr * attr)
+{
+ const int reallocsize = 100;
+ if (pattr->count == 0) {
+ pattr->point = malloc(sizeof(double) * 3 * reallocsize);
+ }
+ if ((pattr->count % reallocsize) == 0) {
+ pattr->point = realloc(pattr->point,
+ sizeof(double) * 3 * (pattr->count +
+ reallocsize));
+ }
+ pattr->point[pattr->count * 3] = attr->lon;
+ pattr->point[pattr->count * 3 + 1] = attr->lat;
+ pattr->point[pattr->count * 3 + 2] = attr->ele;
+ pattr->count++;
+}
+
+/**
+ * counts paths that wasn't converted
+ */
+void countUnconverted(parsedata * pdata)
+{
+ g2sstats *stats = pdata->prop->stats;
+ if (!strcmp(pdata->current->name, "trkseg"))
+ stats->trkunconverted++;
+ else
+ stats->rteunconverted++;
+}
+
+/**
+ * counts paths
+ */
+void countPath(parsedata * pdata)
+{
+ g2sstats *stats = pdata->prop->stats;
+ pathattr *pattr = pdata->pattr;
+ if (!strcmp(pdata->current->name, "trkseg")) {
+ stats->trkcount++;
+ stats->trklength += pattr->length;
+ stats->trkpoints += pattr->count;
+ } else {
+ stats->rtecount++;
+ stats->rtelength += pattr->length;
+ stats->rtepoints += pattr->count;
+ }
+}
+
+int checkPath(parsedata * pdata)
+{
+ pathattr *pattr = pdata->pattr;
+ g2sprop *prop = pdata->prop;
+ /* check point count. */
+ if (pattr->count < prop->minpoints) {
+ fprintf
+ (stderr,
+ "gpx2navit_txt:%s:%i track was not converted because of less then %d points. \n",
+ prop->sourcefile, XML_GetCurrentLineNumber(pdata->parser),
+ prop->minpoints);
+ countUnconverted(pdata);
+ return 0;
+ /* check path length */
+ } else if (pattr->length < prop->minlength * prop->length2meter) {
+ fprintf
+ (stderr,
+ "gpx2navit_txt:%s:%i track was not converted because it is shorter than %dm.\n",
+ prop->sourcefile, XML_GetCurrentLineNumber(pdata->parser),
+ prop->minlength);
+ countUnconverted(pdata);
+ return 0;
+ /* check path time */
+ } else if (pattr->interval < prop->mintime * prop->time2sec) {
+ fprintf
+ (stderr,
+ "gpx2navit_txt:%s:%i track was not converted because it is shorter than %d sed.\n",
+ prop->sourcefile, XML_GetCurrentLineNumber(pdata->parser),
+ prop->mintime);
+ countUnconverted(pdata);
+ return 0;
+ /* check path speed */
+ } else if (pattr->speed == .0) {
+ fprintf
+ (stderr,
+ "gpx2navit_txt:%s:%i track was not converted because no move recorded.\n",
+ prop->sourcefile, XML_GetCurrentLineNumber(pdata->parser));
+ countUnconverted(pdata);
+ return 0;
+ }
+ return 1;
+}
+
+/**
+ * saves path data into files.
+ */
+void setPath( parsedata * pdata)
+{
+ pathattr *pattr = pdata->pattr;
+ g2sprop *prop = pdata->prop;
+ int isOk = 0;
+ pattr->speed =
+ getSpeed(pattr->length, pattr->interval, prop->speed2meter,
+ prop->speed2sec);
+ if (prop->isFast) {
+ isOk = 1;
+ } else {
+ isOk = checkPath(pdata);
+ }
+ if (isOk) {
+ double x[pattr->count];
+ double y[pattr->count];
+ double z[pattr->count];
+ int i;
+ fprintf(pdata->fp,"type=track label=\"%s\" desc=\"%s\" type=\"%s\"\ length=\"%5.3f\" count=\"%5d\"\n"
+ ,pdata->pattr->name,pdata->pattr->desc,
+ pdata->pattr->type,pdata->pattr->length,
+ pdata->pattr->count);
+
+ for (i = 0; i < pattr->count; i++) {
+ x[i] = pattr->point[i * 3];
+ y[i] = pattr->point[i * 3 + 1];
+ z[i] = pattr->point[i * 3 + 2];
+ fprintf(pdata->fp,"%3.6f %4.6f\n",x[i],y[i]);
+ }
+ if (pdata->prop->is3d) {
+ } else {
+ }
+ countPath(pdata);
+ }
+ free(pattr->point);
+}
diff --git a/navit/tools/gpx2navit_txt/src/setwpt.c b/navit/tools/gpx2navit_txt/src/setwpt.c
new file mode 100644
index 000000000..9af217f0a
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/setwpt.c
@@ -0,0 +1,52 @@
+#include "gpx2navit_txt.h"
+
+void setWpt(parsedata * pdata);
+
+/**
+ * save point objects in *_wpt or *_pnt file
+ */
+void setWpt( parsedata * pdata)
+{
+ double x[1], y[1], z[1];
+ x[0] = pdata->attr->lon;
+ y[0] = pdata->attr->lat;
+ z[0] = pdata->attr->ele;
+ if (pdata->prop->is3d) {
+ //nothing at the moment
+ } else {
+ //do not know if i will change something here
+ }
+ // Write attributes to file first line waypoint-info, second line coords
+ char poi_type[20]="poi_attraction";
+ if (!strcmp(pdata->attr->type,"Geocache|Traditional Cache"))
+ strcpy(poi_type,"poi_gc_tradi");
+ if (!strcmp(pdata->attr->type,"Geocache|Multi-cache"))
+ strcpy(poi_type,"poi_gc_multi");
+ if (!strcmp(pdata->attr->type,"Geocache|Unknown Cache"))
+ strcpy(poi_type,"poi_gc_mystery");
+ if (!strcmp(pdata->attr->type,"Geocache|Event Cache"))
+ strcpy(poi_type,"poi_gc_event");
+ if (!strcmp(pdata->attr->type,"Geocache")) //for OC
+ strcpy(poi_type,"poi_gc_tradi");
+ if (!strcmp(pdata->attr->type,"Waypoint|Parking Area"))
+ strcpy(poi_type,"poi_car_parking");
+ if (!strcmp(pdata->attr->type,"Waypoint|Question to Answer"))
+ strcpy(poi_type,"poi_gc_question");
+ if (!strcmp(pdata->attr->type,"Waypoint|Reference Point"))
+ strcpy(poi_type,"poi_gc_reference");
+ if (!strcmp(pdata->attr->type,"Waypoint|Stages of a Multicache"))
+ strcpy(poi_type,"poi_gc_stages");
+
+ //generate the file
+ fprintf(pdata->fp,"type=%s label=\"%s\" description=\"%s\" gc_type=\"%s\"\n",
+ poi_type,pdata->attr->name,pdata->attr->desc,pdata->attr->type);
+ fprintf(pdata->fp,"%3.6f %4.6f\n",x[0],y[0]);
+
+ //writeWptAttribute(hDBF, pdata, iShape);
+ if (!strcmp(pdata->current->name, "wpt")) {
+ pdata->prop->stats->wptpoints++;
+ }
+ return;
+}
+
+
diff --git a/navit/tools/gpx2navit_txt/src/utils.c b/navit/tools/gpx2navit_txt/src/utils.c
new file mode 100644
index 000000000..b9b724791
--- /dev/null
+++ b/navit/tools/gpx2navit_txt/src/utils.c
@@ -0,0 +1,199 @@
+#include "gpx2navit_txt.h"
+#include "projects.h"
+#include "geodesic.h"
+
+double getDistanceCore(char *p1, char *l1, char *p2, char *l2);
+void checkEllpsUnit(char *unit);
+double checkLengthUnit(char *unit);
+int checkTimeUnit(char *unit);
+double getTimeInterval(char *_t, char *t);
+double getSpeed(double length, double ti, double to_meter, int to_sec);
+double getDistance(double _x, double _y, double x, double y);
+// todo void closeShpFiles(shphandles * shps);
+// todo void closeDbfFiles(dbfhandles * dbfs);
+void *myMallocRep(size_t size, const char *fileName, int line);
+
+void checkEllpsUnit(char *unit)
+{
+/*
+ * checks ellipse unit can be used by proj4
+ */
+ int isOK = 0;
+ struct PJ_ELLPS *el; /* project.h of proj4 */
+ for (el = pj_ellps; el->id; ++el) {
+ if (!strcmp(el->id, unit)) {
+ isOK = 1;
+ }
+ }
+ if (!isOK) {
+ fputs
+ ("The ellipse argument is not correct or supported by libproj\n",
+ stderr);
+ fputs("You can choose the argument from a list below.\n\n",
+ stderr);
+ for (el = pj_ellps; el->id; el++) {
+ printf("%10s\t%s\n", el->id, el->name);
+ }
+ exit(ERR_ELLPSUNIT);
+ }
+}
+
+double checkLengthUnit(char *unit)
+{
+/*
+ * checks length unit can be used by proj4
+ * then returns unit value to meter
+ */
+ int isOK = 0;
+ double to_meter = 0;
+ struct PJ_UNITS *ut; /* project.h of proj4 */
+ for (ut = pj_units; ut->id; ut++) {
+ if (!strcmp(ut->id, unit)) {
+ isOK = 1;
+ to_meter = atof(ut->to_meter);
+ }
+ }
+ if (!isOK) {
+ fputs
+ ("The length unit argument is not correct or supported by libproj.\n",
+ stderr);
+ fputs("You can choose the argument from a list below.\n\n",
+ stderr);
+ for (ut = pj_units; ut->id; ut++) {
+ printf("%s\t%s\n", ut->id, ut->name);
+ }
+ exit(ERR_LENGTHUNIT);
+ }
+ return to_meter;
+}
+
+int checkTimeUnit(char *unit)
+{
+ char *u[8] = { "sec", "s", "min", "m", "hour", "h", "day", "d" };
+ int p[8] = { 1, 1, 60, 60, 3600, 3600, 86400, 86400 };
+ int i, to_sec = 0;
+ for (i = 0; i < 8; i++) {
+ if (!strcmp(u[i], unit)) {
+ to_sec = p[i];
+ }
+ }
+ if (!to_sec) {
+ fputs("The time unit argument is not correct.\n", stderr);
+ fputs("You can choose the argument from sec, min, hour or day.\n",
+ stderr);
+ exit(ERR_TIMEUNIT);
+ }
+ return to_sec;
+}
+
+double getTimeInterval(char *_t, char *t)
+{
+/*
+ * Returns a time interval between _t and t.
+ * The arguments should be "YYYY-MM-DDThh:mm:ssZ" (xml schema
+ * datetime format without time zone) format.
+ */
+ double ti;
+ struct tm _tt;
+ struct tm tt;
+ time_t _tmt, tmt;
+ memset(&_tt, 0, sizeof(_tt));
+ memset(&tt, 0, sizeof(tt));
+ sscanf(_t, "%d-%d-%dT%d:%d:%dZ", &_tt.tm_year, &_tt.tm_mon,
+ &_tt.tm_mday, &_tt.tm_hour, &_tt.tm_min, &_tt.tm_sec);
+ _tt.tm_year -= 1900;
+ _tt.tm_mon -= 1;
+ sscanf(t, "%d-%d-%dT%d:%d:%d", &tt.tm_year, &tt.tm_mon, &tt.tm_mday,
+ &tt.tm_hour, &tt.tm_min, &tt.tm_sec);
+ tt.tm_year -= 1900;
+ tt.tm_mon -= 1;
+ _tmt = mktime(&_tt);
+ tmt = mktime(&tt);
+ ti = difftime(tmt, _tmt);
+ return ti;
+}
+
+double getSpeed(double length, double ti, double to_meter, int to_sec)
+{
+/*
+ * Culculates speed from length and time.
+ */
+ double speed;
+ if (!length || !ti)
+ speed = 0;
+ else
+ speed = (length / to_meter) / (ti / to_sec);
+ return speed;
+}
+
+double getDistanceCore(char *p1, char *l1, char *p2, char *l2)
+{
+ /*
+ * Culculates a geodesic length between two points
+ * using geod_*.c
+ */
+ phi1 = dmstor(p1, &p1);
+ lam1 = dmstor(l1, &l1);
+ phi2 = dmstor(p2, &p2);
+ lam2 = dmstor(l2, &l2);
+ geod_inv();
+ return geod_S;
+}
+
+double getDistance(double _x, double _y, double x, double y)
+{
+ /*
+ * Culculates a geodesic length between two points
+ */
+ double length;
+ char p1[17], l1[17], p2[17], l2[17];
+ sprintf(p1, "%f", _x);
+ sprintf(l1, "%f", _y);
+ sprintf(p2, "%f", x);
+ sprintf(l2, "%f", y);
+ length = getDistanceCore(p1, l1, p2, l2);
+ return length;
+}
+
+//todo void closeShpFiles(shphandles * shps)
+//{
+ /*
+ * Closes all SHP files if they opened
+ */
+// if (shps->wpt)
+// SHPClose(shps->wpt);
+// if (shps->trk)
+// SHPClose(shps->trk);
+// if (shps->trk_edg)
+// SHPClose(shps->trk_edg);
+// if (shps->trk_pnt)
+// SHPClose(shps->trk_pnt);
+// if (shps->rte)
+// SHPClose(shps->rte);
+// if (shps->rte_edg)
+// SHPClose(shps->rte_edg);
+// if (shps->rte_pnt)
+// SHPClose(shps->rte_pnt);
+//}
+
+//todo void closeDbfFiles(dbfhandles * dbfs)
+//{
+ /*
+ * Closes all DBF files if they opened
+ */
+// if (dbfs->wpt)
+// DBFClose(dbfs->wpt);
+// if (dbfs->trk)
+// DBFClose(dbfs->trk);
+// if (dbfs->trk_edg)
+// DBFClose(dbfs->trk_edg);
+// if (dbfs->trk_pnt)
+// DBFClose(dbfs->trk_pnt);
+// if (dbfs->rte)
+// DBFClose(dbfs->rte);
+// if (dbfs->rte_edg)
+// DBFClose(dbfs->rte_edg);
+// if (dbfs->rte_pnt)
+// DBFClose(dbfs->rte_pnt);
+//}
+
diff --git a/navit/track.c b/navit/track.c
new file mode 100644
index 000000000..3f08b9a08
--- /dev/null
+++ b/navit/track.c
@@ -0,0 +1,318 @@
+#include <glib.h>
+#include <string.h>
+#include "item.h"
+#include "attr.h"
+#include "track.h"
+#include "debug.h"
+#include "transform.h"
+#include "coord.h"
+#include "route.h"
+#include "projection.h"
+#include "map.h"
+#include "mapset.h"
+
+struct tracking_line
+{
+ struct street_data *street;
+#if 0
+ long segid;
+ int linenum;
+ struct coord c[2];
+ struct coord lpnt;
+ int value;
+ int dir;
+#endif
+ struct tracking_line *next;
+ int angle[0];
+};
+
+
+struct tracking {
+ struct mapset *ms;
+#if 0
+ struct transformation t;
+#endif
+ struct coord last_updated;
+ struct tracking_line *lines;
+#if 0
+ struct tracking_line **last_ptr;
+#endif
+ struct tracking_line *curr_line;
+ int pos;
+ struct coord curr[2];
+ struct coord last_in;
+ struct coord last_out;
+};
+
+
+int angle_factor=30;
+int connected_pref=-10;
+int nostop_pref=10;
+int offroad_limit_pref=5000;
+
+
+struct coord *
+tracking_get_pos(struct tracking *tr)
+{
+ return &tr->last_out;
+}
+
+int
+tracking_get_segment_pos(struct tracking *tr)
+{
+ return tr->pos;
+}
+
+struct street_data *
+tracking_get_street_data(struct tracking *tr)
+{
+ return tr->curr_line->street;
+}
+
+int
+tracking_get_current_attr(struct tracking *_this, enum attr_type type, struct attr *attr)
+{
+ struct item *item;
+ struct map_rect *mr;
+ int result=0;
+ if (! _this->curr_line || ! _this->curr_line->street)
+ return 0;
+ item=&_this->curr_line->street->item;
+ mr=map_rect_new(item->map,NULL);
+ item=map_rect_get_item_byid(mr, item->id_hi, item->id_lo);
+ if (item_attr_get(item, type, attr))
+ result=1;
+ map_rect_destroy(mr);
+ return result;
+}
+
+struct item *
+tracking_get_current_item(struct tracking *_this)
+{
+ if (! _this->curr_line || ! _this->curr_line->street)
+ return NULL;
+ return &_this->curr_line->street->item;
+}
+
+static void
+tracking_get_angles(struct tracking_line *tl)
+{
+ int i;
+ struct street_data *sd=tl->street;
+ for (i = 0 ; i < sd->count-1 ; i++)
+ tl->angle[i]=transform_get_angle_delta(&sd->c[i], &sd->c[i+1], 0);
+}
+
+static void
+tracking_doupdate_lines(struct tracking *tr, struct coord *cc)
+{
+ int max_dist=1000;
+ struct map_selection *sel=route_rect(18, cc, cc, 0, max_dist);
+ struct mapset_handle *h;
+ struct map *m;
+ struct map_rect *mr;
+ struct item *item;
+ struct street_data *street;
+ struct tracking_line *tl;
+#if 0
+ struct coord c;
+#endif
+
+ dbg(1,"enter\n");
+ h=mapset_open(tr->ms);
+ while ((m=mapset_next(h,1))) {
+ mr=map_rect_new(m, sel);
+ if (! mr)
+ continue;
+ while ((item=map_rect_get_item(mr))) {
+ if (item->type >= type_street_0 && item->type <= type_ferry) {
+ street=street_get_data(item);
+ tl=g_malloc(sizeof(struct tracking_line)+(street->count-1)*sizeof(int));
+ tl->street=street;
+ tracking_get_angles(tl);
+ tl->next=tr->lines;
+ tr->lines=tl;
+ }
+ }
+ map_rect_destroy(mr);
+ }
+ mapset_close(h);
+ map_selection_destroy(sel);
+ dbg(1, "exit\n");
+#if 0
+
+ struct transformation t;
+
+ tr->last_ptr=&tr->lines;
+ transform_setup_source_rect_limit(&t,c,1000);
+ transform_setup_source_rect_limit(&tr->t,c,1000);
+
+
+ profile_timer(NULL);
+ street_get_block(tr->ma,&t,tst_callback,tr);
+ profile_timer("end");
+#endif
+}
+
+
+static void
+tracking_free_lines(struct tracking *tr)
+{
+ struct tracking_line *tl=tr->lines,*next;
+ dbg(1,"enter(tr=%p)\n", tr);
+
+ while (tl) {
+ next=tl->next;
+ street_data_free(tl->street);
+ g_free(tl);
+ tl=next;
+ }
+ tr->lines=NULL;
+}
+
+static int
+tracking_angle_abs_diff(int a1, int a2, int full)
+{
+ int ret;
+
+ if (a2 > a1)
+ ret=(a2-a1)%full;
+ else
+ ret=(a1-a2)%full;
+ if (ret > full/2)
+ ret=full-ret;
+ return ret;
+}
+
+static int
+tracking_angle_delta(int vehicle_angle, int street_angle, int dir)
+{
+ int full=180;
+ int ret;
+ if (dir) {
+ full=360;
+ if (dir < 0)
+ street_angle=(street_angle+180)%360;
+ }
+ ret=tracking_angle_abs_diff(vehicle_angle, street_angle, full);
+
+ return ret*ret;
+}
+
+static int
+tracking_is_connected(struct coord *c1, struct coord *c2)
+{
+ if (c1[0].x == c2[0].x && c1[0].y == c2[0].y)
+ return 1;
+ if (c1[0].x == c2[1].x && c1[0].y == c2[1].y)
+ return 1;
+ if (c1[1].x == c2[0].x && c1[1].y == c2[0].y)
+ return 1;
+ if (c1[1].x == c2[1].x && c1[1].y == c2[1].y)
+ return 1;
+ return 0;
+}
+
+int
+tracking_update(struct tracking *tr, struct coord *c, int angle)
+{
+ struct tracking_line *t;
+ int i,value,min=0;
+ struct coord lpnt;
+#if 0
+ int min,dist;
+ int debug=0;
+#endif
+ dbg(1,"enter(%p,%p,%d)\n", tr, c, angle);
+ dbg(1,"c=0x%x,0x%x\n", c->x, c->y);
+
+ if (c->x == tr->last_in.x && c->y == tr->last_in.y) {
+ *c=tr->last_out;
+ return 0;
+ }
+ tr->last_in=*c;
+ if (!tr->lines || transform_distance_sq(&tr->last_updated, c) > 250000) {
+ dbg(1, "update\n");
+ tracking_free_lines(tr);
+ tracking_doupdate_lines(tr, c);
+ tr->last_updated=*c;
+ dbg(1,"update end\n");
+ }
+
+ t=tr->lines;
+ if (! t)
+ return 0;
+ tr->curr_line=NULL;
+ while (t) {
+ struct street_data *sd=t->street;
+ int dir = 0;
+ switch(sd->flags & AF_ONEWAYMASK) {
+ case 0:
+ dir=0;
+ break;
+ case 1:
+ dir=1;
+ break;
+ case 2:
+ dir=-1;
+ break;
+ case 3:
+ t=t->next;
+ continue;
+ }
+ for (i = 0; i < sd->count-1 ; i++) {
+ dbg(2, "%d: (0x%x,0x%x)-(0x%x,0x%x)\n", i, sd->c[i].x, sd->c[i].y, sd->c[i+1].x, sd->c[i+1].y);
+ value=transform_distance_line_sq(&sd->c[i], &sd->c[i+1], c, &lpnt);
+ if (value < INT_MAX/2)
+ value += tracking_angle_delta(angle, t->angle[i], dir)*angle_factor>>4;
+ if (tracking_is_connected(tr->curr, &sd->c[i]))
+ value += connected_pref;
+ if (lpnt.x == tr->last_out.x && lpnt.y == tr->last_out.y)
+ value += nostop_pref;
+ if (! tr->curr_line || value < min) {
+ tr->curr_line=t;
+ tr->pos=i;
+ tr->curr[0]=sd->c[i];
+ tr->curr[1]=sd->c[i+1];
+ dbg(1,"lpnt.x=0x%x,lpnt.y=0x%x pos=%d %d+%d+%d+%d=%d\n", lpnt.x, lpnt.y, i,
+ transform_distance_line_sq(&sd->c[i], &sd->c[i+1], c, &lpnt),
+ tracking_angle_delta(angle, t->angle[i], 0)*angle_factor,
+ tracking_is_connected(tr->curr, &sd->c[i]) ? connected_pref : 0,
+ lpnt.x == tr->last_out.x && lpnt.y == tr->last_out.y ? nostop_pref : 0,
+ value
+ );
+ tr->last_out=lpnt;
+ min=value;
+ }
+ }
+ t=t->next;
+ }
+ dbg(1,"tr->curr_line=%p min=%d\n", tr->curr_line, min);
+ if (!tr->curr_line || min > offroad_limit_pref)
+ return 0;
+ dbg(1,"found 0x%x,0x%x\n", tr->last_out.x, tr->last_out.y);
+ *c=tr->last_out;
+ return 1;
+}
+
+struct tracking *
+tracking_new(struct mapset *ms)
+{
+ struct tracking *this=g_new0(struct tracking, 1);
+ this->ms=ms;
+
+ return this;
+}
+
+void
+tracking_set_mapset(struct tracking *this, struct mapset *ms)
+{
+ this->ms=ms;
+}
+
+void
+tracking_destroy(struct tracking *tr)
+{
+ tracking_free_lines(tr);
+ g_free(tr);
+}
diff --git a/navit/track.h b/navit/track.h
new file mode 100644
index 000000000..69024ef1c
--- /dev/null
+++ b/navit/track.h
@@ -0,0 +1,26 @@
+#ifndef NAVIT_TRACK_H
+#define NAVIT_TRACK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* prototypes */
+struct coord;
+struct mapset;
+struct street_data;
+struct tracking;
+struct coord *tracking_get_pos(struct tracking *tr);
+int tracking_get_segment_pos(struct tracking *tr);
+struct street_data *tracking_get_street_data(struct tracking *tr);
+int tracking_update(struct tracking *tr, struct coord *c, int angle);
+struct tracking *tracking_new(struct mapset *ms);
+void tracking_set_mapset(struct tracking *this_, struct mapset *ms);
+int tracking_get_current_attr(struct tracking *_this, enum attr_type type, struct attr *attr);
+struct item *tracking_get_current_item(struct tracking *_this);
+void tracking_destroy(struct tracking *tr);
+/* end of prototypes */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/navit/transform.c b/navit/transform.c
new file mode 100644
index 000000000..0abe6fbd3
--- /dev/null
+++ b/navit/transform.c
@@ -0,0 +1,747 @@
+#include <assert.h>
+#include <stdio.h>
+#include <math.h>
+#include <limits.h>
+#include <glib.h>
+#include <string.h>
+#include "config.h"
+#include "coord.h"
+#include "debug.h"
+#include "map.h"
+#include "transform.h"
+#include "projection.h"
+#include "point.h"
+
+struct transformation {
+ long scale; /* Scale factor */
+ int angle; /* Rotation angle */
+ double cos_val,sin_val; /* cos and sin of rotation angle */
+ enum projection pro;
+ struct map_selection *map_sel;
+ struct map_selection *screen_sel;
+ struct point screen_center;
+ struct coord map_center; /* Center of source rectangle */
+};
+
+struct transformation *
+transform_new(void)
+{
+ struct transformation *this_;
+
+ this_=g_new0(struct transformation, 1);
+
+ return this_;
+}
+
+static const double gar2geo_units = 360.0/(1<<24);
+static const double geo2gar_units = 1/(360.0/(1<<24));
+
+void
+transform_to_geo(enum projection pro, struct coord *c, struct coord_geo *g)
+{
+ switch (pro) {
+ case projection_mg:
+ g->lng=c->x/6371000.0/M_PI*180;
+ g->lat=atan(exp(c->y/6371000.0))/M_PI*360-90;
+ break;
+ case projection_garmin:
+ g->lng=c->x*gar2geo_units;
+ g->lat=c->y*gar2geo_units;
+ break;
+ default:
+ break;
+ }
+}
+
+void
+transform_from_geo(enum projection pro, struct coord_geo *g, struct coord *c)
+{
+ switch (pro) {
+ case projection_mg:
+ c->x=g->lng*6371000.0*M_PI/180;
+ c->y=log(tan(M_PI_4+g->lat*M_PI/360))*6371000.0;
+ break;
+ case projection_garmin:
+ c->x=g->lng*geo2gar_units;
+ c->y=g->lat*geo2gar_units;
+ break;
+ default:
+ break;
+ }
+}
+
+void
+transform_from_to(struct coord *cfrom, enum projection from, struct coord *cto, enum projection to)
+{
+ struct coord_geo g;
+ transform_to_geo(from, cfrom, &g);
+ transform_from_geo(to, &g, cto);
+}
+
+void
+transform_geo_to_cart(struct coord_geo *geo, double a, double b, struct coord_geo_cart *cart)
+{
+ double n,ee=1-b*b/(a*a);
+ n = a/sqrt(1-ee*sin(geo->lat)*sin(geo->lat));
+ cart->x=n*cos(geo->lat)*cos(geo->lng);
+ cart->y=n*cos(geo->lat)*sin(geo->lng);
+ cart->z=n*(1-ee)*sin(geo->lat);
+}
+
+void
+transform_cart_to_geo(struct coord_geo_cart *cart, double a, double b, struct coord_geo *geo)
+{
+ double lat,lati,n,ee=1-b*b/(a*a), lng = atan(cart->y/cart->x);
+
+ lat = atan(cart->z / sqrt((cart->x * cart->x) + (cart->y * cart->y)));
+ do
+ {
+ lati = lat;
+
+ n = a / sqrt(1-ee*sin(lat)*sin(lat));
+ lat = atan((cart->z + ee * n * sin(lat)) / sqrt(cart->x * cart->x + cart->y * cart->y));
+ }
+ while (fabs(lat - lati) >= 0.000000000000001);
+
+ geo->lng=lng/M_PI*180;
+ geo->lat=lat/M_PI*180;
+}
+
+
+void
+transform_datum(struct coord_geo *from, enum map_datum from_datum, struct coord_geo *to, enum map_datum to_datum)
+{
+}
+
+int
+transform(struct transformation *t, enum projection pro, struct coord *c, struct point *p, int count, int unique)
+{
+ struct coord c1;
+ int xcn, ycn;
+ struct coord_geo g;
+#ifdef AVOID_FLOAT
+ int xc,yc;
+#else
+ double xc,yc;
+#endif
+ int i,j = 0;
+ for (i=0; i < count; i++) {
+ if (pro == t->pro) {
+ xc=c[i].x;
+ yc=c[i].y;
+ } else {
+ transform_to_geo(pro, &c[i], &g);
+ transform_from_geo(t->pro, &g, &c1);
+ xc=c1.x;
+ yc=c1.y;
+ }
+// dbg(2,"0x%x, 0x%x - 0x%x,0x%x contains 0x%x,0x%x\n", t->r.lu.x, t->r.lu.y, t->r.rl.x, t->r.rl.y, c->x, c->y);
+// ret=coord_rect_contains(&t->r, c);
+ xc-=t->map_center.x;
+ yc-=t->map_center.y;
+ yc=-yc;
+ if (t->angle) {
+ xcn=xc*t->cos_val+yc*t->sin_val;
+ ycn=-xc*t->sin_val+yc*t->cos_val;
+ xc=xcn;
+ yc=ycn;
+ }
+ xc=xc*16;
+ yc=yc*16;
+#ifndef AVOID_FLOAT
+ if (t->scale!=1) {
+ xc=xc/(double)(t->scale);
+ yc=yc/(double)(t->scale);
+ }
+#else
+ if (t->scale!=1) {
+ xc=xc/t->scale;
+ yc=yc/t->scale;
+ }
+#endif
+ xc+=t->screen_center.x;
+ yc+=t->screen_center.y;
+ if (xc < -0x8000)
+ xc=-0x8000;
+ if (xc > 0x7fff) {
+ xc=0x7fff;
+ }
+ if (yc < -0x8000)
+ yc=-0x8000;
+ if (yc > 0x7fff)
+ yc=0x7fff;
+ if (j == 0 || !unique || p[j-1].x != xc || p[j-1].y != yc) {
+ p[j].x=xc;
+ p[j].y=yc;
+ j++;
+ }
+ }
+ return j;
+}
+
+void
+transform_reverse(struct transformation *t, struct point *p, struct coord *c)
+{
+ int xc,yc;
+ xc=p->x;
+ yc=p->y;
+ xc-=t->screen_center.x;
+ yc-=t->screen_center.y;
+ xc=xc*t->scale/16;
+ yc=-yc*t->scale/16;
+ if (t->angle) {
+ int xcn, ycn;
+ xcn=xc*t->cos_val+yc*t->sin_val;
+ ycn=-xc*t->sin_val+yc*t->cos_val;
+ xc=xcn;
+ yc=ycn;
+ }
+ c->x=t->map_center.x+xc;
+ c->y=t->map_center.y+yc;
+}
+
+enum projection
+transform_get_projection(struct transformation *this_)
+{
+ return this_->pro;
+}
+
+void
+transform_set_projection(struct transformation *this_, enum projection pro)
+{
+ this_->pro=pro;
+}
+
+static int
+min4(int v1,int v2, int v3, int v4)
+{
+ int res=v1;
+ if (v2 < res)
+ res=v2;
+ if (v3 < res)
+ res=v3;
+ if (v4 < res)
+ res=v4;
+ return res;
+}
+
+static int
+max4(int v1,int v2, int v3, int v4)
+{
+ int res=v1;
+ if (v2 > res)
+ res=v2;
+ if (v3 > res)
+ res=v3;
+ if (v4 > res)
+ res=v4;
+ return res;
+}
+
+struct map_selection *
+transform_get_selection(struct transformation *this_, enum projection pro, int order)
+{
+
+ struct map_selection *ret,*curri,*curro;
+ struct coord_geo g;
+ int i;
+
+ ret=map_selection_dup(this_->map_sel);
+ curri=this_->map_sel;
+ curro=ret;
+ while (curri) {
+ if (this_->pro != pro) {
+ transform_to_geo(this_->pro, &curri->u.c_rect.lu, &g);
+ transform_from_geo(pro, &g, &curro->u.c_rect.lu);
+ dbg(1,"%f,%f", g.lat, g.lng);
+ transform_to_geo(this_->pro, &curri->u.c_rect.rl, &g);
+ transform_from_geo(pro, &g, &curro->u.c_rect.rl);
+ dbg(1,": - %f,%f\n", g.lat, g.lng);
+ }
+ dbg(1,"transform rect for %d is %d,%d - %d,%d\n", pro, curro->u.c_rect.lu.x, curro->u.c_rect.lu.y, curro->u.c_rect.rl.x, curro->u.c_rect.rl.y);
+ for (i = 0 ; i < layer_end ; i++)
+ curro->order[i]+=order;
+ curri=curri->next;
+ curro=curro->next;
+ }
+ return ret;
+}
+
+struct coord *
+transform_center(struct transformation *this_)
+{
+ return &this_->map_center;
+}
+
+void
+transform_set_angle(struct transformation *t,int angle)
+{
+ t->angle=angle;
+ t->cos_val=cos(M_PI*t->angle/180);
+ t->sin_val=sin(M_PI*t->angle/180);
+}
+
+int
+transform_get_angle(struct transformation *this_,int angle)
+{
+ return this_->angle;
+}
+
+void
+transform_set_screen_selection(struct transformation *t, struct map_selection *sel)
+{
+ map_selection_destroy(t->screen_sel);
+ t->screen_sel=map_selection_dup(sel);
+ if (sel) {
+ t->screen_center.x=(sel->u.p_rect.rl.x-sel->u.p_rect.lu.x)/2;
+ t->screen_center.y=(sel->u.p_rect.rl.y-sel->u.p_rect.lu.y)/2;
+ }
+}
+
+#if 0
+void
+transform_set_size(struct transformation *t, int width, int height)
+{
+ t->width=width;
+ t->height=height;
+}
+#endif
+
+void
+transform_get_size(struct transformation *t, int *width, int *height)
+{
+ struct point_rect *r;
+ if (t->screen_sel) {
+ r=&t->screen_sel->u.p_rect;
+ *width=r->rl.x-r->lu.x;
+ *height=r->rl.y-r->lu.y;
+ }
+}
+
+void
+transform_setup(struct transformation *t, struct pcoord *c, int scale, int angle)
+{
+ t->pro=c->pro;
+ t->map_center.x=c->x;
+ t->map_center.y=c->y;
+ t->scale=scale;
+ transform_set_angle(t, angle);
+}
+
+#if 0
+
+void
+transform_setup_source_rect_limit(struct transformation *t, struct coord *center, int limit)
+{
+ t->center=*center;
+ t->scale=1;
+ t->angle=0;
+ t->r.lu.x=center->x-limit;
+ t->r.rl.x=center->x+limit;
+ t->r.rl.y=center->y-limit;
+ t->r.lu.y=center->y+limit;
+}
+#endif
+
+void
+transform_setup_source_rect(struct transformation *t)
+{
+ int i;
+ struct coord screen[4];
+ struct point screen_pnt[4];
+ struct point_rect *pr;
+ struct map_selection *ms,*msm,*next,**msm_last;
+ ms=t->map_sel;
+ while (ms) {
+ next=ms->next;
+ g_free(ms);
+ ms=next;
+ }
+ t->map_sel=NULL;
+ msm_last=&t->map_sel;
+ ms=t->screen_sel;
+ while (ms) {
+ msm=g_new0(struct map_selection, 1);
+ *msm=*ms;
+ pr=&ms->u.p_rect;
+ screen_pnt[0].x=pr->lu.x;
+ screen_pnt[0].y=pr->lu.y;
+ screen_pnt[1].x=pr->rl.x;
+ screen_pnt[1].y=pr->lu.y;
+ screen_pnt[2].x=pr->lu.x;
+ screen_pnt[2].y=pr->rl.y;
+ screen_pnt[3].x=pr->rl.x;
+ screen_pnt[3].y=pr->rl.y;
+ for (i = 0 ; i < 4 ; i++) {
+ transform_reverse(t, &screen_pnt[i], &screen[i]);
+ }
+ msm->u.c_rect.lu.x=min4(screen[0].x,screen[1].x,screen[2].x,screen[3].x);
+ msm->u.c_rect.rl.x=max4(screen[0].x,screen[1].x,screen[2].x,screen[3].x);
+ msm->u.c_rect.rl.y=min4(screen[0].y,screen[1].y,screen[2].y,screen[3].y);
+ msm->u.c_rect.lu.y=max4(screen[0].y,screen[1].y,screen[2].y,screen[3].y);
+ *msm_last=msm;
+ msm_last=&msm->next;
+ ms=ms->next;
+ }
+}
+
+long
+transform_get_scale(struct transformation *t)
+{
+ return t->scale;
+}
+
+void
+transform_set_scale(struct transformation *t, long scale)
+{
+ t->scale=scale;
+}
+
+
+int
+transform_get_order(struct transformation *t)
+{
+ int scale=t->scale;
+ int order=0;
+ while (scale > 1) {
+ order++;
+ scale>>=1;
+ }
+ order=18-order;
+ if (order < 0)
+ order=0;
+ return order;
+}
+
+
+void
+transform_geo_text(struct coord_geo *g, char *buffer)
+{
+ double lng=g->lng;
+ double lat=g->lat;
+ char lng_c='E';
+ char lat_c='N';
+
+ if (lng < 0) {
+ lng=-lng;
+ lng_c='W';
+ }
+ if (lat < 0) {
+ lat=-lat;
+ lat_c='S';
+ }
+
+ sprintf(buffer,"%02.0f%07.4f%c %03.0f%07.4f%c", floor(lat), fmod(lat*60,60), lat_c, floor(lng), fmod(lng*60,60), lng_c);
+
+}
+
+#define TWOPI (M_PI*2)
+#define GC2RAD(c) ((c) * TWOPI/(1<<24))
+#define minf(a,b) ((a) < (b) ? (a) : (b))
+
+static double
+transform_distance_garmin(struct coord *c1, struct coord *c2)
+{
+#ifdef USE_HALVESINE
+ static const int earth_radius = 6371*1000; //m change accordingly
+// static const int earth_radius = 3960; //miles
+
+//Point 1 cords
+ float lat1 = GC2RAD(c1->y);
+ float long1 = GC2RAD(c1->x);
+
+//Point 2 cords
+ float lat2 = GC2RAD(c2->y);
+ float long2 = GC2RAD(c2->x);
+
+//Haversine Formula
+ float dlong = long2-long1;
+ float dlat = lat2-lat1;
+
+ float sinlat = sinf(dlat/2);
+ float sinlong = sinf(dlong/2);
+
+ float a=(sinlat*sinlat)+cosf(lat1)*cosf(lat2)*(sinlong*sinlong);
+ float c=2*asinf(minf(1,sqrt(a)));
+#ifdef AVOID_FLOAT
+ return round(earth_radius*c);
+#else
+ return earth_radius*c;
+#endif
+#else
+#define GMETER 2.3887499999999999
+ double dx,dy;
+ dx=c1->x-c2->x;
+ dy=c1->y-c2->y;
+ return sqrt(dx*dx+dy*dy)*GMETER;
+#undef GMETER
+#endif
+}
+
+double
+transform_scale(int y)
+{
+ struct coord c;
+ struct coord_geo g;
+ c.x=0;
+ c.y=y;
+ transform_to_geo(projection_mg, &c, &g);
+ return 1/cos(g.lat/180*M_PI);
+}
+
+#ifdef AVOID_FLOAT
+static int
+tab_sqrt[]={14142,13379,12806,12364,12018,11741,11517,11333,11180,11051,10943,10850,10770,10701,10640,10587,10540,10499,10462,10429,10400,10373,10349,10327,10307,10289,10273,10257,10243,10231,10219,10208};
+#endif
+
+double
+transform_distance(enum projection pro, struct coord *c1, struct coord *c2)
+{
+ if (pro == projection_mg) {
+#ifndef AVOID_FLOAT
+ double dx,dy,scale=transform_scale((c1->y+c2->y)/2);
+ dx=c1->x-c2->x;
+ dy=c1->y-c2->y;
+ return sqrt(dx*dx+dy*dy)/scale;
+#else
+ int dx,dy,f,scale=15539;
+ dx=c1->x-c2->x;
+ dy=c1->y-c2->y;
+ if (dx < 0)
+ dx=-dx;
+ if (dy < 0)
+ dy=-dy;
+ while (dx > 20000 || dy > 20000) {
+ dx/=10;
+ dy/=10;
+ scale/=10;
+ }
+ if (! dy)
+ return dx*10000/scale;
+ if (! dx)
+ return dy*10000/scale;
+ if (dx > dy) {
+ f=dx*8/dy-8;
+ if (f >= 32)
+ return dx*10000/scale;
+ return dx*tab_sqrt[f]/scale;
+ } else {
+ f=dy*8/dx-8;
+ if (f >= 32)
+ return dy*10000/scale;
+ return dy*tab_sqrt[f]/scale;
+ }
+#endif
+ } else if (pro == projection_garmin) {
+ return transform_distance_garmin(c1, c2);
+ } else {
+ printf("Unknown projection: %d\n", pro);
+ return 0;
+ }
+}
+
+int
+transform_distance_sq(struct coord *c1, struct coord *c2)
+{
+ int dx=c1->x-c2->x;
+ int dy=c1->y-c2->y;
+
+ if (dx > 32767 || dy > 32767 || dx < -32767 || dy < -32767)
+ return INT_MAX;
+ else
+ return dx*dx+dy*dy;
+}
+
+int
+transform_distance_line_sq(struct coord *l0, struct coord *l1, struct coord *ref, struct coord *lpnt)
+{
+ int vx,vy,wx,wy;
+ int c1,c2;
+ int climit=1000000;
+ struct coord l;
+
+ vx=l1->x-l0->x;
+ vy=l1->y-l0->y;
+ wx=ref->x-l0->x;
+ wy=ref->y-l0->y;
+
+ c1=vx*wx+vy*wy;
+ if ( c1 <= 0 ) {
+ if (lpnt)
+ *lpnt=*l0;
+ return transform_distance_sq(l0, ref);
+ }
+ c2=vx*vx+vy*vy;
+ if ( c2 <= c1 ) {
+ if (lpnt)
+ *lpnt=*l1;
+ return transform_distance_sq(l1, ref);
+ }
+ while (c1 > climit || c2 > climit) {
+ c1/=256;
+ c2/=256;
+ }
+ l.x=l0->x+vx*c1/c2;
+ l.y=l0->y+vy*c1/c2;
+ if (lpnt)
+ *lpnt=l;
+ return transform_distance_sq(&l, ref);
+}
+
+int
+transform_distance_polyline_sq(struct coord *c, int count, struct coord *ref, struct coord *lpnt, int *pos)
+{
+ int i,dist,distn;
+ struct coord lp;
+ if (count < 2)
+ return INT_MAX;
+ if (pos)
+ *pos=0;
+ dist=transform_distance_line_sq(&c[0], &c[1], ref, lpnt);
+ for (i=2 ; i < count ; i++) {
+ distn=transform_distance_line_sq(&c[i-1], &c[i], ref, &lp);
+ if (distn < dist) {
+ dist=distn;
+ if (lpnt)
+ *lpnt=lp;
+ if (pos)
+ *pos=i-1;
+ }
+ }
+ return dist;
+}
+
+
+void
+transform_print_deg(double deg)
+{
+ printf("%2.0f:%2.0f:%2.4f", floor(deg), fmod(deg*60,60), fmod(deg*3600,60));
+}
+
+#ifdef AVOID_FLOAT
+static int tab_atan[]={0,262,524,787,1051,1317,1584,1853,2126,2401,2679,2962,3249,3541,3839,4142,4452,4770,5095,5430,5774,6128,6494,6873,7265,7673,8098,8541,9004,9490,10000,10538};
+
+static int
+atan2_int_lookup(int val)
+{
+ int len=sizeof(tab_atan)/sizeof(int);
+ int i=len/2;
+ int p=i-1;
+ for (;;) {
+ i>>=1;
+ if (val < tab_atan[p])
+ p-=i;
+ else
+ if (val < tab_atan[p+1])
+ return p+(p>>1);
+ else
+ p+=i;
+ }
+}
+
+static int
+atan2_int(int dx, int dy)
+{
+ int f,mul=1,add=0,ret;
+ if (! dx) {
+ return dy < 0 ? 180 : 0;
+ }
+ if (! dy) {
+ return dx < 0 ? -90 : 90;
+ }
+ if (dx < 0) {
+ dx=-dx;
+ mul=-1;
+ }
+ if (dy < 0) {
+ dy=-dy;
+ add=180*mul;
+ mul*=-1;
+ }
+ while (dx > 20000 || dy > 20000) {
+ dx/=10;
+ dy/=10;
+ }
+ if (dx > dy) {
+ ret=90-atan2_int_lookup(dy*10000/dx);
+ } else {
+ ret=atan2_int_lookup(dx*10000/dy);
+ }
+ return ret*mul+add;
+}
+#endif
+
+int
+transform_get_angle_delta(struct coord *c1, struct coord *c2, int dir)
+{
+ int dx=c2->x-c1->x;
+ int dy=c2->y-c1->y;
+#ifndef AVOID_FLOAT
+ double angle;
+ angle=atan2(dx,dy);
+ angle*=180/M_PI;
+#else
+ int angle;
+ angle=atan2_int(dx,dy);
+#endif
+ if (dir == -1)
+ angle=angle-180;
+ if (angle < 0)
+ angle+=360;
+ return angle;
+}
+
+int
+transform_within_border(struct transformation *this_, struct point *p, int border)
+{
+ struct map_selection *ms=this_->screen_sel;
+ while (ms) {
+ struct point_rect *r=&ms->u.p_rect;
+ if (p->x >= r->lu.x+border && p->x <= r->rl.x-border &&
+ p->y >= r->lu.y+border && p->y <= r->rl.y-border)
+ return 1;
+ ms=ms->next;
+ }
+ return 0;
+}
+
+/*
+Note: there are many mathematically equivalent ways to express these formulas. As usual, not all of them are computationally equivalent.
+
+L = latitude in radians (positive north)
+Lo = longitude in radians (positive east)
+E = easting (meters)
+N = northing (meters)
+
+For the sphere
+
+E = r Lo
+N = r ln [ tan (pi/4 + L/2) ]
+
+where
+
+r = radius of the sphere (meters)
+ln() is the natural logarithm
+
+For the ellipsoid
+
+E = a Lo
+N = a * ln ( tan (pi/4 + L/2) * ( (1 - e * sin (L)) / (1 + e * sin (L))) ** (e/2) )
+
+
+ e
+ -
+ pi L 1 - e sin(L) 2
+ = a ln( tan( ---- + ---) (--------------) )
+ 4 2 1 + e sin(L)
+
+
+where
+
+a = the length of the semi-major axis of the ellipsoid (meters)
+e = the first eccentricity of the ellipsoid
+
+
+*/
+
+
diff --git a/navit/transform.h b/navit/transform.h
new file mode 100644
index 000000000..b47a268c1
--- /dev/null
+++ b/navit/transform.h
@@ -0,0 +1,48 @@
+#ifndef NAVIT_TRANSFORM_H
+#define NAVIT_TRANSFORM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/* prototypes */
+enum projection;
+struct coord;
+struct coord_geo;
+struct map_selection;
+struct pcoord;
+struct point;
+struct transformation;
+struct transformation *transform_new(void);
+void transform_to_geo(enum projection pro, struct coord *c, struct coord_geo *g);
+void transform_from_geo(enum projection pro, struct coord_geo *g, struct coord *c);
+void transform_from_to(struct coord *cfrom, enum projection from, struct coord *cto, enum projection to);
+int transform(struct transformation *t, enum projection pro, struct coord *c, struct point *p, int count, int flags);
+void transform_reverse(struct transformation *t, struct point *p, struct coord *c);
+enum projection transform_get_projection(struct transformation *this_);
+void transform_set_projection(struct transformation *this_, enum projection pro);
+struct map_selection *transform_get_selection(struct transformation *this_, enum projection pro, int order);
+struct coord *transform_center(struct transformation *this_);
+void transform_set_angle(struct transformation *t, int angle);
+int transform_get_angle(struct transformation *this_, int angle);
+void transform_set_screen_selection(struct transformation *t, struct map_selection *sel);
+void transform_get_size(struct transformation *t, int *width, int *height);
+void transform_setup(struct transformation *t, struct pcoord *c, int scale, int angle);
+void transform_setup_source_rect(struct transformation *t);
+long transform_get_scale(struct transformation *t);
+void transform_set_scale(struct transformation *t, long scale);
+int transform_get_order(struct transformation *t);
+void transform_geo_text(struct coord_geo *g, char *buffer);
+double transform_scale(int y);
+double transform_distance(enum projection pro, struct coord *c1, struct coord *c2);
+int transform_distance_sq(struct coord *c1, struct coord *c2);
+int transform_distance_line_sq(struct coord *l0, struct coord *l1, struct coord *ref, struct coord *lpnt);
+int transform_distance_polyline_sq(struct coord *c, int count, struct coord *ref, struct coord *lpnt, int *pos);
+void transform_print_deg(double deg);
+int transform_get_angle_delta(struct coord *c1, struct coord *c2, int dir);
+int transform_within_border(struct transformation *this_, struct point *p, int border);
+/* end of prototypes */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/navit/types.h b/navit/types.h
new file mode 100644
index 000000000..0fa5b5a92
--- /dev/null
+++ b/navit/types.h
@@ -0,0 +1,12 @@
+#ifndef NAVIT_TYPES_H
+#define NAVIT_TYPES_H
+#include <stdint.h>
+
+typedef int8_t s8;
+typedef uint8_t u8;
+typedef int16_t s16;
+typedef uint16_t u16;
+typedef int32_t s32;
+typedef uint32_t u32;
+
+#endif
diff --git a/navit/util.c b/navit/util.c
new file mode 100644
index 000000000..44643d4f2
--- /dev/null
+++ b/navit/util.c
@@ -0,0 +1,36 @@
+#include <glib.h>
+#include <ctype.h>
+#include "util.h"
+
+void
+strtoupper(char *dest, const char *src)
+{
+ while (*src)
+ *dest++=toupper(*src++);
+ *dest='\0';
+}
+
+void
+strtolower(char *dest, const char *src)
+{
+ while (*src)
+ *dest++=tolower(*src++);
+ *dest='\0';
+}
+
+
+static void
+hash_callback(gpointer key, gpointer value, gpointer user_data)
+{
+ GList **l=user_data;
+ *l=g_list_prepend(*l, value);
+}
+
+GList *
+g_hash_to_list(GHashTable *h)
+{
+ GList *ret=NULL;
+ g_hash_table_foreach(h, hash_callback, &ret);
+
+ return ret;
+}
diff --git a/navit/util.h b/navit/util.h
new file mode 100644
index 000000000..8e9690a14
--- /dev/null
+++ b/navit/util.h
@@ -0,0 +1,11 @@
+#ifndef NAVIT_types_H
+#define NAVIT_types_H
+
+#include <ctype.h>
+
+void strtoupper(char *dest, const char *src);
+void strtolower(char *dest, const char *src);
+GList * g_hash_to_list(GHashTable *h);
+
+#endif
+
diff --git a/navit/vehicle.c b/navit/vehicle.c
new file mode 100644
index 000000000..5d93142d4
--- /dev/null
+++ b/navit/vehicle.c
@@ -0,0 +1,197 @@
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+#include "config.h"
+#include "debug.h"
+#include "coord.h"
+#include "item.h"
+#include "log.h"
+#include "callback.h"
+#include "plugin.h"
+#include "vehicle.h"
+
+struct vehicle {
+ char *name;
+ struct vehicle_priv *priv;
+ struct vehicle_methods meth;
+ struct callback_list *cbl;
+ struct log *nmea_log, *gpx_log;
+};
+
+static void
+vehicle_log_nmea(struct vehicle *this_, struct log *log)
+{
+ struct attr pos_attr;
+ if (!this_->meth.position_attr_get)
+ return;
+ if (!this_->meth.position_attr_get(this_->priv, attr_position_nmea, &pos_attr))
+ return;
+ log_write(log, pos_attr.u.str, strlen(pos_attr.u.str));
+}
+
+static void
+vehicle_log_gpx(struct vehicle *this_, struct log *log)
+{
+ struct attr pos_attr;
+ char buffer[256];
+ if (!this_->meth.position_attr_get)
+ return;
+ if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &pos_attr))
+ return;
+ sprintf(buffer,"<trkpt lat=\"%f\" lon=\"%f\" />\n", pos_attr.u.coord_geo->lat, pos_attr.u.coord_geo->lng);
+ log_write(log, buffer, strlen(buffer));
+}
+
+
+static void
+vehicle_log_textfile(struct vehicle *this_, struct log *log)
+{
+ struct attr pos_attr;
+ char buffer[256];
+ if (!this_->meth.position_attr_get)
+ return;
+ if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &pos_attr))
+ return;
+ sprintf(buffer,"%f %f type=trackpoint\n", pos_attr.u.coord_geo->lng, pos_attr.u.coord_geo->lat);
+ log_write(log, buffer, strlen(buffer));
+}
+
+static int
+vehicle_add_log(struct vehicle *this_, struct log *log)
+{
+ struct callback *cb;
+ struct attr type_attr;
+ if (!log_get_attr(log, attr_type, &type_attr, NULL))
+ return 1;
+
+ if (!strcmp(type_attr.u.str, "nmea")) {
+ cb=callback_new_2(callback_cast(vehicle_log_nmea), this_, log);
+ } else if (!strcmp(type_attr.u.str, "gpx")) {
+ char *header =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<gpx version=\"1.0\" creator=\"Navit http://navit.sourceforge.net\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.topografix.com/GPX/1/0\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">\n<trk>\n<trkseg>\n";
+ char *trailer = "</trkseg>\n</trk>\n</gpx>\n";
+ log_set_header(log, header, strlen(header));
+ log_set_trailer(log, trailer, strlen(trailer));
+ cb=callback_new_2(callback_cast(vehicle_log_gpx), this_, log);
+ } else if (!strcmp(type_attr.u.str, "textfile")) {
+ char *header = "type=track\n";
+ log_set_header(log, header, strlen(header));
+ cb=callback_new_2(callback_cast(vehicle_log_textfile), this_, log);
+ } else
+ return 1;
+ callback_list_add(this_->cbl, cb);
+ return 0;
+}
+
+struct vehicle *
+vehicle_new(struct attr **attrs)
+{
+ struct vehicle *this_;
+ struct attr *source;
+ struct vehicle_priv *(*vehicletype_new) (struct vehicle_methods *
+ meth,
+ struct callback_list *
+ cbl,
+ struct attr ** attrs);
+ char *type, *colon;
+ struct attr *name;
+
+ dbg(1, "enter\n");
+ source = attr_search(attrs, NULL, attr_source);
+ if (!source) {
+ dbg(0, "no source\n");
+ return NULL;
+ }
+
+ type = g_strdup(source->u.str);
+ colon = index(type, ':');
+ if (colon)
+ *colon = '\0';
+ dbg(1, "source='%s' type='%s'\n", source->u.str, type);
+
+ vehicletype_new = plugin_get_vehicle_type(type);
+ if (!vehicletype_new) {
+ dbg(0, "invalid type\n");
+ return NULL;
+ }
+ this_ = g_new0(struct vehicle, 1);
+ this_->cbl = callback_list_new();
+ this_->priv = vehicletype_new(&this_->meth, this_->cbl, attrs);
+ if (!this_->priv) {
+ dbg(0, "vehicletype_new failed\n");
+ callback_list_destroy(this_->cbl);
+ g_free(this_);
+ return NULL;
+ }
+ dbg(1, "leave\n");
+
+ if ((name=attr_search(attrs, NULL, attr_name))) {
+ this_->name=g_strdup(name->u.str);
+ } else {
+ this_->name=g_strdup("Noname");
+ }
+ return this_;
+}
+
+int
+vehicle_get_attr(struct vehicle *this_, enum attr_type type, struct attr *attr)
+{
+ switch (type) {
+ case attr_name:
+ attr->u.str=this_->name;
+ break;
+ default:
+ if (this_->meth.position_attr_get) {
+ return this_->meth.position_attr_get(this_->priv, type, attr);
+ } else {
+ return 0;
+ }
+ }
+ attr->type=type;
+ return 1;
+}
+
+int
+vehicle_set_attr(struct vehicle *this_, struct attr *attr,
+ struct attr **attrs)
+{
+ if (this_->meth.set_attr)
+ return this_->meth.set_attr(this_->priv, attr, attrs);
+ return 0;
+}
+
+int
+vehicle_add_attr(struct vehicle *this_, struct attr *attr)
+{
+ switch (attr->type) {
+ case attr_callback:
+ callback_list_add(this_->cbl, attr->u.callback);
+ break;
+ case attr_log:
+ return vehicle_add_log(this_, attr->u.log);
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+int
+vehicle_remove_attr(struct vehicle *this_, struct attr *attr)
+{
+ switch (attr->type) {
+ case attr_callback:
+ callback_list_remove(this_->cbl, attr->u.callback);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void
+vehicle_destroy(struct vehicle *this_)
+{
+ callback_list_destroy(this_->cbl);
+ if(this_->name) g_free(this_->name);
+ g_free(this_);
+}
diff --git a/navit/vehicle.h b/navit/vehicle.h
new file mode 100644
index 000000000..971bd3f20
--- /dev/null
+++ b/navit/vehicle.h
@@ -0,0 +1,32 @@
+#ifndef NAVIT_VEHICLE_H
+#define NAVIT_VEHICLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+struct vehicle;
+struct vehicle_priv;
+enum attr_type;
+struct attr;
+
+struct vehicle_methods {
+ void (*destroy)(struct vehicle_priv *priv);
+ int (*position_attr_get)(struct vehicle_priv *priv, enum attr_type type, struct attr *attr);
+ int (*set_attr)(struct vehicle_priv *priv, struct attr *attr, struct attr **attrs);
+
+};
+
+/* prototypes */
+struct vehicle *vehicle_new(struct attr **attrs);
+int vehicle_get_attr(struct vehicle *this_, enum attr_type type, struct attr *attr);
+int vehicle_set_attr(struct vehicle *this_, struct attr *attr, struct attr **attrs);
+int vehicle_add_attr(struct vehicle *this_, struct attr *attr);
+int vehicle_remove_attr(struct vehicle *this_, struct attr *attr);
+void vehicle_destroy(struct vehicle *this_);
+/* end of prototypes */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/navit/vehicle/Makefile.am b/navit/vehicle/Makefile.am
new file mode 100644
index 000000000..8901833f8
--- /dev/null
+++ b/navit/vehicle/Makefile.am
@@ -0,0 +1,4 @@
+SUBDIRS=demo file
+if VEHICLE_GPSD
+ SUBDIRS += gpsd
+endif
diff --git a/navit/vehicle/demo/Makefile.am b/navit/vehicle/demo/Makefile.am
new file mode 100644
index 000000000..3f2f4f369
--- /dev/null
+++ b/navit/vehicle/demo/Makefile.am
@@ -0,0 +1,4 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=vehicle_demo
+modulevehicle_LTLIBRARIES = libvehicle_demo.la
+libvehicle_demo_la_SOURCES = vehicle_demo.c
diff --git a/navit/vehicle/demo/vehicle_demo.c b/navit/vehicle/demo/vehicle_demo.c
new file mode 100644
index 000000000..46b9c68de
--- /dev/null
+++ b/navit/vehicle/demo/vehicle_demo.c
@@ -0,0 +1,176 @@
+#include <glib.h>
+#include <string.h>
+#include "config.h"
+#include "debug.h"
+#include "coord.h"
+#include "item.h"
+#include "navit.h"
+#include "map.h"
+#include "route.h"
+#include "callback.h"
+#include "transform.h"
+#include "plugin.h"
+#include "vehicle.h"
+
+struct vehicle_priv {
+ int interval;
+ int position_set;
+ struct callback_list *cbl;
+ struct navit *navit;
+ struct coord_geo geo;
+ struct coord last;
+ double config_speed;
+ double speed;
+ double direction;
+};
+
+static void
+vehicle_demo_destroy(struct vehicle_priv *priv)
+{
+ g_free(priv);
+}
+
+static int
+vehicle_demo_position_attr_get(struct vehicle_priv *priv,
+ enum attr_type type, struct attr *attr)
+{
+ switch (type) {
+ case attr_position_speed:
+ attr->u.numd = &priv->speed;
+ break;
+ case attr_position_direction:
+ attr->u.numd = &priv->direction;
+ break;
+ case attr_position_coord_geo:
+ attr->u.coord_geo = &priv->geo;
+ break;
+ default:
+ return 0;
+ }
+ attr->type = type;
+ return 1;
+}
+
+static int
+vehicle_demo_set_attr(struct vehicle_priv *priv, struct attr *attr,
+ struct attr **attrs)
+{
+ if (attr->type == attr_navit) {
+ priv->navit = attr->u.navit;
+ return 1;
+ }
+ return 0;
+}
+
+struct vehicle_methods vehicle_demo_methods = {
+ vehicle_demo_destroy,
+ vehicle_demo_position_attr_get,
+ vehicle_demo_set_attr,
+};
+
+static int
+vehicle_demo_timer(struct vehicle_priv *priv)
+{
+ struct coord c, c2, pos, ci;
+ int slen, len, dx, dy;
+ struct route *route=NULL;
+ struct map *route_map=NULL;
+ struct map_rect *mr=NULL;
+ struct item *item=NULL;
+
+ len = (priv->config_speed * priv->interval / 1000)/ 3.6;
+ dbg(1, "###### Entering simulation loop\n");
+ if (priv->navit)
+ route=navit_get_route(priv->navit);
+ if (route)
+ route_map=route_get_map(route);
+ if (route_map)
+ mr=map_rect_new(route_map, NULL);
+ if (mr)
+ item=map_rect_get_item(mr);
+ if (mr && item_coord_get(item, &pos, 1)) {
+ priv->position_set=0;
+ dbg(1, "current pos=0x%x,0x%x\n", pos.x, pos.y);
+ dbg(1, "last pos=0x%x,0x%x\n", priv->last.x, priv->last.y);
+ if (priv->last.x == pos.x && priv->last.y == pos.y) {
+ dbg(1, "endless loop\n");
+ }
+ priv->last = pos;
+ while (item && priv->config_speed) {
+ if (!item_coord_get(item, &c, 1)) {
+ item=map_rect_get_item(mr);
+ continue;
+ }
+ dbg(1, "next pos=0x%x,0x%x\n", c.x, c.y);
+ slen = transform_distance(projection_mg, &pos, &c);
+ dbg(1, "len=%d slen=%d\n", len, slen);
+ if (slen < len) {
+ len -= slen;
+ pos = c;
+ } else {
+ if (item_coord_get(item, &c2, 1) || map_rect_get_item(mr)) {
+ dx = c.x - pos.x;
+ dy = c.y - pos.y;
+ ci.x = pos.x + dx * len / slen;
+ ci.y = pos.y + dy * len / slen;
+ priv->direction =
+ transform_get_angle_delta(&pos, &c, 0);
+ priv->speed=priv->config_speed;
+ } else {
+ ci.x = pos.x;
+ ci.y = pos.y;
+ priv->speed=0;
+ dbg(0,"destination reached\n");
+ }
+ dbg(1, "ci=0x%x,0x%x\n", ci.x, ci.y);
+ transform_to_geo(projection_mg, &ci,
+ &priv->geo);
+ callback_list_call_0(priv->cbl);
+ break;
+ }
+ }
+ } else {
+ if (priv->position_set)
+ callback_list_call_0(priv->cbl);
+ }
+ if (mr)
+ map_rect_destroy(mr);
+ return 1;
+}
+
+
+
+static struct vehicle_priv *
+vehicle_demo_new(struct vehicle_methods
+ *meth, struct callback_list
+ *cbl, struct attr **attrs)
+{
+ struct vehicle_priv *ret;
+ struct attr *interval,*speed,*position_coord_geo;
+
+ dbg(1, "enter\n");
+ ret = g_new0(struct vehicle_priv, 1);
+ ret->cbl = cbl;
+ ret->interval=1000;
+ ret->config_speed=40;
+ if ((speed=attr_search(attrs, NULL, attr_speed))) {
+ ret->config_speed=speed->u.num;
+ }
+ if ((interval=attr_search(attrs, NULL, attr_interval)))
+ ret->interval=interval->u.num;
+ if ((position_coord_geo=attr_search(attrs, NULL, attr_position_coord_geo))) {
+ ret->geo=*(position_coord_geo->u.coord_geo);
+ ret->position_set=1;
+ dbg(0,"position_set %f %f\n", ret->geo.lat, ret->geo.lng);
+ }
+ *meth = vehicle_demo_methods;
+ g_timeout_add(ret->interval, (GSourceFunc) vehicle_demo_timer, ret);
+ return ret;
+}
+
+void
+plugin_init(void)
+{
+ dbg(1, "enter\n");
+ plugin_register_vehicle_type("demo", vehicle_demo_new);
+}
diff --git a/navit/vehicle/file/Makefile.am b/navit/vehicle/file/Makefile.am
new file mode 100644
index 000000000..f46da8480
--- /dev/null
+++ b/navit/vehicle/file/Makefile.am
@@ -0,0 +1,4 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=vehicle_file
+modulevehicle_LTLIBRARIES = libvehicle_file.la
+libvehicle_file_la_SOURCES = vehicle_file.c
diff --git a/navit/vehicle/file/vehicle_file.c b/navit/vehicle/file/vehicle_file.c
new file mode 100644
index 000000000..6b20cf6c2
--- /dev/null
+++ b/navit/vehicle/file/vehicle_file.c
@@ -0,0 +1,500 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <glib.h>
+#include <sys/stat.h>
+#ifdef _WIN32
+ #include <serial_io.h>
+#else
+#include <termios.h>
+#endif
+#include <math.h>
+#include "config.h"
+#include "debug.h"
+#include "callback.h"
+#include "plugin.h"
+#include "coord.h"
+#include "item.h"
+#include "vehicle.h"
+
+static void vehicle_file_disable_watch(struct vehicle_priv *priv);
+static void vehicle_file_enable_watch(struct vehicle_priv *priv);
+static void vehicle_file_parse(struct vehicle_priv *priv, char *buffer);
+static int vehicle_file_open(struct vehicle_priv *priv);
+static void vehicle_file_close(struct vehicle_priv *priv);
+
+
+enum file_type {
+ file_type_pipe = 1, file_type_device, file_type_file
+};
+
+static int buffer_size = 256;
+
+struct vehicle_priv {
+ char *source;
+ enum file_type file_type;
+ struct callback_list *cbl;
+ int fd;
+ FILE *file;
+ guint watch;
+ GIOChannel *iochan;
+ char *buffer;
+ int buffer_pos;
+ char *nmea_data;
+ char *nmea_data_buf;
+
+ struct coord_geo geo;
+ double speed;
+ double direction;
+ double height;
+ int status;
+ int sats_used;
+ int time;
+ int on_eof;
+#ifdef _WIN32
+ int no_data_count;
+#endif
+};
+
+#ifdef _WIN32
+static int vehicle_win32_serial_track(struct vehicle_priv *priv)
+{
+
+ static char buffer[2048] = {0,};
+ static int current_index = 0;
+ const int chunk_size = 1024;
+
+ if ( priv->no_data_count > 5 )
+ {
+ vehicle_file_close( priv );
+ priv->no_data_count = 0;
+ }
+
+ if ( priv->fd <= 0 )
+ {
+ vehicle_file_open( priv );
+ }
+
+ if ( current_index >= ( sizeof( buffer ) - chunk_size ) )
+ {
+ // discard
+ current_index = 0;
+ memset( buffer, 0 , sizeof( buffer ) );
+ }
+
+ int dwBytes = serial_io_read( priv->fd, &buffer[ current_index ], chunk_size );
+ if ( dwBytes > 0 )
+ {
+ current_index += dwBytes;
+
+ char* return_pos = NULL;
+ while ( ( return_pos = strchr( buffer, '\n' ) ) != NULL )
+ {
+ char return_buffer[1024];
+ int bytes_to_copy = return_pos - buffer + 1;
+ memcpy( return_buffer, buffer, bytes_to_copy );
+ return_buffer[ bytes_to_copy + 1 ] = '\0';
+
+ // printf( "received %d : '%s' bytes to copy\n", bytes_to_copy, return_buffer );
+ vehicle_file_parse( priv, return_buffer );
+
+ current_index -= bytes_to_copy;
+ memmove( buffer, &buffer[ bytes_to_copy ] , sizeof( buffer ) - bytes_to_copy );
+ }
+
+ }
+ else
+ {
+ priv->no_data_count++;
+ }
+ return 1;
+}
+#endif
+
+static int
+vehicle_file_open(struct vehicle_priv *priv)
+{
+#ifdef _WIN32
+ dbg(1, "enter vehicle_file_open, priv->source='%s'\n", priv->source);
+
+ if ( priv->source )
+ {
+ char* raw_setting_str = g_strdup( priv->source );
+
+ char* strport = strchr(raw_setting_str, ':' );
+ char* strsettings = strchr(raw_setting_str, ' ' );
+
+ if ( strport && strsettings )
+ {
+ strport++;
+ *strsettings = '\0';
+ strsettings++;
+
+ dbg(1, "calling serial_io_init('%s', '%s')\n", strport, strsettings );
+ priv->fd=serial_io_init( strport, strsettings );
+ }
+ g_free( raw_setting_str );
+ }
+#else
+ char *name;
+ struct stat st;
+ struct termios tio;
+
+ name = priv->source + 5;
+ if (!strncmp(priv->source, "file:", 5)) {
+ priv->fd = open(name, O_RDONLY | O_NDELAY);
+ if (priv->fd < 0)
+ return 0;
+ stat(name, &st);
+ if (S_ISREG(st.st_mode)) {
+ priv->file_type = file_type_file;
+ } else {
+ tcgetattr(priv->fd, &tio);
+ cfmakeraw(&tio);
+ cfsetispeed(&tio, B4800);
+ cfsetospeed(&tio, B4800);
+ tio.c_cc[VMIN] = 16;
+ tio.c_cc[VTIME] = 1;
+ tcsetattr(priv->fd, TCSANOW, &tio);
+ priv->file_type = file_type_device;
+ }
+ } else {
+ priv->file = popen(name, "r");
+ if (!priv->file)
+ return 0;
+ priv->fd = fileno(priv->file);
+ priv->file_type = file_type_pipe;
+ }
+ priv->iochan = g_io_channel_unix_new(priv->fd);
+#endif
+ return 1;
+}
+
+static void
+vehicle_file_close(struct vehicle_priv *priv)
+{
+#ifdef _WIN32
+ serial_io_shutdown( priv->fd );
+#else
+ GError *error = NULL;
+ if (priv->iochan) {
+ g_io_channel_shutdown(priv->iochan, 0, &error);
+ priv->iochan = NULL;
+ }
+ if (priv->file)
+ pclose(priv->file);
+ else if (priv->fd >= 0)
+ close(priv->fd);
+#endif
+ priv->file = NULL;
+ priv->fd = -1;
+}
+
+static int
+vehicle_file_enable_watch_timer(gpointer t)
+{
+ struct vehicle_priv *priv = t;
+ vehicle_file_enable_watch(priv);
+ dbg(1, "enter\n");
+
+ return FALSE;
+}
+
+
+static void
+vehicle_file_parse(struct vehicle_priv *priv, char *buffer)
+{
+ char *nmea_data_buf, *p, *item[16];
+ double lat, lng;
+ int i, bcsum;
+ int len = strlen(buffer);
+ unsigned char csum = 0;
+
+ dbg(1, "buffer='%s'\n", buffer);
+ for (;;) {
+ if (len < 4) {
+ dbg(0, "'%s' too short\n", buffer);
+ return;
+ }
+ if (buffer[len - 1] == '\r' || buffer[len - 1] == '\n')
+ buffer[--len] = '\0';
+ else
+ break;
+ }
+ if (buffer[0] != '$') {
+ dbg(0, "no leading $ in '%s'\n", buffer);
+ return;
+ }
+ if (buffer[len - 3] != '*') {
+ dbg(0, "no *XX in '%s'\n", buffer);
+ return;
+ }
+ for (i = 1; i < len - 3; i++) {
+ csum ^= (unsigned char) (buffer[i]);
+ }
+ if (!sscanf(buffer + len - 2, "%x", &bcsum)) {
+ dbg(0, "no checksum in '%s'\n", buffer);
+ return;
+ }
+ if (bcsum != csum) {
+ dbg(0, "wrong checksum in '%s'\n", buffer);
+ return;
+ }
+
+ if (!priv->nmea_data_buf || strlen(priv->nmea_data_buf) < 65536) {
+ nmea_data_buf=g_strconcat(priv->nmea_data_buf ? priv->nmea_data_buf : "", buffer, "\n", NULL);
+ g_free(priv->nmea_data_buf);
+ priv->nmea_data_buf=nmea_data_buf;
+ } else {
+ dbg(0, "nmea buffer overflow, discarding '%s'\n", buffer);
+ }
+ i = 0;
+ p = buffer;
+ while (i < 16) {
+ item[i++] = p;
+ while (*p && *p != ',')
+ p++;
+ if (!*p)
+ break;
+ *p++ = '\0';
+ }
+
+ if (!strncmp(buffer, "$GPGGA", 6)) {
+ /* 1 1111
+ 0 1 2 3 4 5 6 7 8 9 0 1234
+ $GPGGA,184424.505,4924.2811,N,01107.8846,E,1,05,2.5,408.6,M,,,,0000*0C
+ UTC of Fix[1],Latitude[2],N/S[3],Longitude[4],E/W[5],Quality(0=inv,1=gps,2=dgps)[6],Satelites used[7],
+ HDOP[8],Altitude[9],"M"[10],height of geoid[11], "M"[12], time since dgps update[13], dgps ref station [14]
+ */
+ lat = g_ascii_strtod(item[2], NULL);
+ priv->geo.lat = floor(lat / 100);
+ lat -= priv->geo.lat * 100;
+ priv->geo.lat += lat / 60;
+
+ if (!strcasecmp(item[3],"S"))
+ priv->geo.lat=-priv->geo.lat;
+
+ lng = g_ascii_strtod(item[4], NULL);
+ priv->geo.lng = floor(lng / 100);
+ lng -= priv->geo.lng * 100;
+ priv->geo.lng += lng / 60;
+
+ if (!strcasecmp(item[5],"W"))
+ priv->geo.lng=-priv->geo.lng;
+
+ sscanf(item[6], "%d", &priv->status);
+ sscanf(item[7], "%d", &priv->sats_used);
+ priv->height = g_ascii_strtod(item[9], NULL);
+ g_free(priv->nmea_data);
+ priv->nmea_data=priv->nmea_data_buf;
+ priv->nmea_data_buf=NULL;
+
+ callback_list_call_0(priv->cbl);
+
+#ifndef _WIN32
+ if (priv->file_type == file_type_file) {
+ vehicle_file_disable_watch(priv);
+ g_timeout_add(priv->time,
+ vehicle_file_enable_watch_timer,
+ priv);
+ }
+#endif
+ }
+ if (!strncmp(buffer, "$GPVTG", 6)) {
+ /* 0 1 2 34 5 6 7 8
+ $GPVTG,143.58,T,,M,0.26,N,0.5,K*6A
+ Course Over Ground Degrees True[1],"T"[2],Course Over Ground Degrees Magnetic[3],"M"[4],
+ Speed in Knots[5],"N"[6],"Speed in KM/H"[7],"K"[8]
+ */
+ priv->direction = g_ascii_strtod( item[1], NULL );
+ priv->speed = g_ascii_strtod( item[7], NULL );
+ }
+ if (!strncmp(buffer, "$GPRMC", 6)) {
+ /* 1 1
+ 0 1 2 3 4 5 6 7 8 9 0 1
+ $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A
+ Time[1],Active/Void[2],lat[3],N/S[4],long[5],W/E[6],speed in knots[7],track angle[8],date[9],
+ magnetic variation[10],magnetic variation direction[11]
+ */
+ priv->direction = g_ascii_strtod( item[8], NULL );
+ priv->speed = g_ascii_strtod( item[7], NULL );
+ priv->speed *= 1.852;
+ }
+}
+
+#ifndef _WIN32
+static gboolean
+vehicle_file_io(GIOChannel * iochan, GIOCondition condition, gpointer t)
+{
+ struct vehicle_priv *priv = t;
+ int size;
+ char *str, *tok;
+
+ dbg(1, "enter condition=%d\n", condition);
+ if (condition == G_IO_IN) {
+ size =
+ read(g_io_channel_unix_get_fd(iochan),
+ priv->buffer + priv->buffer_pos,
+ buffer_size - priv->buffer_pos - 1);
+ if (size <= 0) {
+ switch (priv->on_eof) {
+ case 0:
+ vehicle_file_close(priv);
+ vehicle_file_open(priv);
+ break;
+ case 1:
+ break;
+ case 2:
+ exit(0);
+ break;
+ }
+ return TRUE;
+ }
+ priv->buffer_pos += size;
+ priv->buffer[priv->buffer_pos] = '\0';
+ dbg(1, "size=%d pos=%d buffer='%s'\n", size,
+ priv->buffer_pos, priv->buffer);
+ str = priv->buffer;
+ while ((tok = index(str, '\n'))) {
+ *tok++ = '\0';
+ dbg(1, "line='%s'\n", str);
+ vehicle_file_parse(priv, str);
+ str = tok;
+ }
+ if (str != priv->buffer) {
+ size = priv->buffer + priv->buffer_pos - str;
+ memmove(priv->buffer, str, size + 1);
+ priv->buffer_pos = size;
+ dbg(1, "now pos=%d buffer='%s'\n",
+ priv->buffer_pos, priv->buffer);
+ } else if (priv->buffer_pos == buffer_size - 1) {
+ dbg(0,
+ "Overflow. Most likely wrong baud rate or no nmea protocol\n");
+ priv->buffer_pos = 0;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+#endif
+
+static void
+vehicle_file_enable_watch(struct vehicle_priv *priv)
+{
+#ifdef _WIN32
+ g_timeout_add(500, vehicle_win32_serial_track, priv);
+#else
+ priv->watch =
+ g_io_add_watch(priv->iochan, G_IO_IN | G_IO_ERR | G_IO_HUP,
+ vehicle_file_io, priv);
+#endif
+}
+
+static void
+vehicle_file_disable_watch(struct vehicle_priv *priv)
+{
+#ifndef _WIN32
+ if (priv->watch)
+ g_source_remove(priv->watch);
+ priv->watch = 0;
+#endif
+}
+
+
+static void
+vehicle_file_destroy(struct vehicle_priv *priv)
+{
+ vehicle_file_close(priv);
+ if (priv->source)
+ g_free(priv->source);
+ if (priv->buffer)
+ g_free(priv->buffer);
+ g_free(priv);
+}
+
+static int
+vehicle_file_position_attr_get(struct vehicle_priv *priv,
+ enum attr_type type, struct attr *attr)
+{
+ switch (type) {
+ case attr_position_height:
+ attr->u.numd = &priv->height;
+ break;
+ case attr_position_speed:
+ attr->u.numd = &priv->speed;
+ break;
+ case attr_position_direction:
+ attr->u.numd = &priv->direction;
+ break;
+ case attr_position_sats_used:
+ attr->u.num = priv->sats_used;
+ break;
+ case attr_position_coord_geo:
+ attr->u.coord_geo = &priv->geo;
+ break;
+ case attr_position_nmea:
+ attr->u.str=priv->nmea_data;
+ if (! attr->u.str)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ attr->type = type;
+ return 1;
+}
+
+struct vehicle_methods vehicle_file_methods = {
+ vehicle_file_destroy,
+ vehicle_file_position_attr_get,
+};
+
+static struct vehicle_priv *
+vehicle_file_new_file(struct vehicle_methods
+ *meth, struct callback_list
+ *cbl, struct attr **attrs)
+{
+ struct vehicle_priv *ret;
+ struct attr *source;
+ struct attr *time;
+ struct attr *on_eof;
+
+ dbg(1, "enter\n");
+ source = attr_search(attrs, NULL, attr_source);
+ ret = g_new0(struct vehicle_priv, 1);
+ ret->fd = -1;
+ ret->cbl = cbl;
+ ret->source = g_strdup(source->u.str);
+ ret->buffer = g_malloc(buffer_size);
+ ret->time=1000;
+ time = attr_search(attrs, NULL, attr_time);
+ if (time)
+ ret->time=time->u.num;
+ on_eof = attr_search(attrs, NULL, attr_on_eof);
+ if (on_eof && !strcasecmp(on_eof->u.str, "stop"))
+ ret->on_eof=1;
+ if (on_eof && !strcasecmp(on_eof->u.str, "exit"))
+ ret->on_eof=2;
+ dbg(0,"on_eof=%d\n", ret->on_eof);
+ *meth = vehicle_file_methods;
+ if (vehicle_file_open(ret)) {
+ vehicle_file_enable_watch(ret);
+ return ret;
+ }
+
+#ifdef _WIN32
+ ret->no_data_count = 0;
+#endif
+ dbg(0, "Failed to open '%s'\n", ret->source);
+ vehicle_file_destroy(ret);
+ return NULL;
+}
+
+void
+plugin_init(void)
+{
+ dbg(1, "enter\n");
+ plugin_register_vehicle_type("file", vehicle_file_new_file);
+ plugin_register_vehicle_type("pipe", vehicle_file_new_file);
+}
diff --git a/navit/vehicle/gpsd/Makefile.am b/navit/vehicle/gpsd/Makefile.am
new file mode 100644
index 000000000..db7a686d9
--- /dev/null
+++ b/navit/vehicle/gpsd/Makefile.am
@@ -0,0 +1,5 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/src -DMODULE=vehicle_gpsd
+modulevehicle_LTLIBRARIES = libvehicle_gpsd.la
+libvehicle_gpsd_la_SOURCES = vehicle_gpsd.c
+libvehicle_gpsd_la_LIBADD = @GPSD_LIBS@
diff --git a/navit/vehicle/gpsd/vehicle_gpsd.c b/navit/vehicle/gpsd/vehicle_gpsd.c
new file mode 100644
index 000000000..ac7f0c0d9
--- /dev/null
+++ b/navit/vehicle/gpsd/vehicle_gpsd.c
@@ -0,0 +1,285 @@
+#include <config.h>
+#include <gps.h>
+#include <string.h>
+#include <glib.h>
+#include <math.h>
+#include "debug.h"
+#include "callback.h"
+#include "plugin.h"
+#include "coord.h"
+#include "item.h"
+#include "vehicle.h"
+
+static struct vehicle_priv {
+ char *source;
+ char *gpsd_query;
+ struct callback_list *cbl;
+ GIOChannel *iochan;
+ guint retry_interval;
+ guint watch;
+ struct gps_data_t *gps;
+ struct coord_geo geo;
+ double speed;
+ double direction;
+ double height;
+ int status;
+ int sats;
+ int sats_used;
+ char *nmea_data;
+ char *nmea_data_buf;
+ guint retry_timer;
+} *vehicle_last;
+
+#define DEFAULT_RETRY_INTERVAL 10 // seconds
+#define MIN_RETRY_INTERVAL 1 // seconds
+
+static gboolean vehicle_gpsd_io(GIOChannel * iochan,
+ GIOCondition condition, gpointer t);
+
+
+
+static void
+vehicle_gpsd_callback(struct gps_data_t *data, char *buf, size_t len,
+ int level)
+{
+ char *pos,*nmea_data_buf;
+ struct vehicle_priv *priv = vehicle_last;
+ if (buf[0] == '$' && len > 0) {
+ char buffer[len+2];
+ buffer[len+1]='\0';
+ memcpy(buffer, buf, len);
+ pos=strchr(buffer,'\n');
+ if (pos) {
+ *++pos='\0';
+ if (!priv->nmea_data_buf || strlen(priv->nmea_data_buf) < 65536) {
+ nmea_data_buf=g_strconcat(priv->nmea_data_buf ? priv->nmea_data_buf : "", buffer, NULL);
+ g_free(priv->nmea_data_buf);
+ priv->nmea_data_buf=nmea_data_buf;
+ } else {
+ dbg(0, "nmea buffer overflow, discarding '%s'\n", buffer);
+ }
+ }
+ }
+ dbg(1,"data->set=0x%x\n", data->set);
+ // If data->fix.speed is NAN, then the drawing gets jumpy.
+ if (isnan(data->fix.speed)) {
+ return;
+ }
+ dbg(2,"speed ok\n");
+ if (data->set & SPEED_SET) {
+ priv->speed = data->fix.speed * 3.6;
+ data->set &= ~SPEED_SET;
+ }
+ if (data->set & TRACK_SET) {
+ priv->direction = data->fix.track;
+ data->set &= ~TRACK_SET;
+ }
+ if (data->set & ALTITUDE_SET) {
+ priv->height = data->fix.altitude;
+ data->set &= ~ALTITUDE_SET;
+ }
+ if (data->set & SATELLITE_SET) {
+ priv->sats_used = data->satellites_used;
+ priv->sats = data->satellites;
+ data->set &= ~SATELLITE_SET;
+ }
+ if (data->set & STATUS_SET) {
+ priv->status = data->status;
+ data->set &= ~STATUS_SET;
+ }
+ if (data->set & PDOP_SET) {
+ dbg(0, "pdop : %g\n", data->pdop);
+ data->set &= ~PDOP_SET;
+ }
+ if (data->set & LATLON_SET) {
+ priv->geo.lat = data->fix.latitude;
+ priv->geo.lng = data->fix.longitude;
+ dbg(1,"lat=%f lng=%f\n", priv->geo.lat, priv->geo.lng);
+ g_free(priv->nmea_data);
+ priv->nmea_data=priv->nmea_data_buf;
+ priv->nmea_data_buf=NULL;
+ callback_list_call_0(priv->cbl);
+ data->set &= ~LATLON_SET;
+ }
+}
+
+/**
+ * Attempt to open the gps device.
+ * Return FALSE if retry not required
+ * Return TRUE to try again
+ */
+static gboolean
+vehicle_gpsd_try_open(gpointer *data)
+{
+ struct vehicle_priv *priv = (struct vehicle_priv *)data;
+ char *source = g_strdup(priv->source);
+ char *colon = index(source + 7, ':');
+ if (colon) {
+ *colon = '\0';
+ priv->gps = gps_open(source + 7, colon + 1);
+ } else
+ priv->gps = gps_open(source + 7, NULL);
+ g_free(source);
+
+ if (!priv->gps){
+ g_warning("gps_open failed for '%s'. Retrying in %d seconds. Have you started gpsd?\n", priv->source, priv->retry_interval);
+ return TRUE;
+ }
+ gps_query(priv->gps, priv->gpsd_query);
+ gps_set_raw_hook(priv->gps, vehicle_gpsd_callback);
+ priv->iochan = g_io_channel_unix_new(priv->gps->gps_fd);
+ priv->watch =
+ g_io_add_watch(priv->iochan, G_IO_IN | G_IO_ERR | G_IO_HUP,
+ vehicle_gpsd_io, priv);
+ dbg(0,"Connected to gpsd fd=%d iochan=%p watch=%p\n", priv->gps->gps_fd, priv->iochan, priv->watch);
+ return FALSE;
+}
+
+/**
+ * Open a connection to gpsd. Will re-try the connection if it fails
+ */
+static void
+vehicle_gpsd_open(struct vehicle_priv *priv)
+{
+ priv->retry_timer=0;
+ if (vehicle_gpsd_try_open((gpointer *)priv)) {
+ priv->retry_timer = g_timeout_add(priv->retry_interval*1000, (GSourceFunc)vehicle_gpsd_try_open, (gpointer *)priv);
+ }
+}
+
+static void
+vehicle_gpsd_close(struct vehicle_priv *priv)
+{
+ GError *error = NULL;
+
+ if (priv->watch) {
+ g_source_remove(priv->watch);
+ priv->watch = 0;
+ }
+ if (priv->retry_timer) {
+ g_source_remove(priv->retry_timer);
+ priv->retry_timer=0;
+ }
+ if (priv->iochan) {
+ g_io_channel_shutdown(priv->iochan, 0, &error);
+ priv->iochan = NULL;
+ }
+ if (priv->gps) {
+ gps_close(priv->gps);
+ priv->gps = NULL;
+ }
+}
+
+static gboolean
+vehicle_gpsd_io(GIOChannel * iochan, GIOCondition condition, gpointer t)
+{
+ struct vehicle_priv *priv = t;
+
+ dbg(1, "enter condition=%d\n", condition);
+ if (condition == G_IO_IN) {
+ if (priv->gps) {
+ vehicle_last = priv;
+ if (gps_poll(priv->gps)) {
+ g_warning("gps_poll failed\n");
+ vehicle_gpsd_close(priv);
+ vehicle_gpsd_open(priv);
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+vehicle_gpsd_destroy(struct vehicle_priv *priv)
+{
+ vehicle_gpsd_close(priv);
+ if (priv->source)
+ g_free(priv->source);
+ if (priv->gpsd_query)
+ g_free(priv->gpsd_query);
+ g_free(priv);
+}
+
+static int
+vehicle_gpsd_position_attr_get(struct vehicle_priv *priv,
+ enum attr_type type, struct attr *attr)
+{
+ switch (type) {
+ case attr_position_height:
+ attr->u.numd = &priv->height;
+ break;
+ case attr_position_speed:
+ attr->u.numd = &priv->speed;
+ break;
+ case attr_position_direction:
+ attr->u.numd = &priv->direction;
+ break;
+ case attr_position_sats:
+ attr->u.num = priv->sats;
+ break;
+ case attr_position_sats_used:
+ attr->u.num = priv->sats_used;
+ break;
+ case attr_position_coord_geo:
+ attr->u.coord_geo = &priv->geo;
+ break;
+ case attr_position_nmea:
+ attr->u.str=priv->nmea_data;
+ if (! attr->u.str)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ attr->type = type;
+ return 1;
+}
+
+struct vehicle_methods vehicle_gpsd_methods = {
+ vehicle_gpsd_destroy,
+ vehicle_gpsd_position_attr_get,
+};
+
+static struct vehicle_priv *
+vehicle_gpsd_new_gpsd(struct vehicle_methods
+ *meth, struct callback_list
+ *cbl, struct attr **attrs)
+{
+ struct vehicle_priv *ret;
+ struct attr *source, *query, *retry_int;
+
+ dbg(1, "enter\n");
+ source = attr_search(attrs, NULL, attr_source);
+ ret = g_new0(struct vehicle_priv, 1);
+ ret->source = g_strdup(source->u.str);
+ query = attr_search(attrs, NULL, attr_gpsd_query);
+ if (query) {
+ ret->gpsd_query = g_strconcat(query->u.str, "\n", NULL);
+ } else {
+ ret->gpsd_query = g_strdup("w+x\n");
+ }
+ dbg(1,"Format string for gpsd_query: %s\n",ret->gpsd_query);
+ retry_int = attr_search(attrs, NULL, attr_retry_interval);
+ if (retry_int) {
+ ret->retry_interval = retry_int->u.num;
+ if (ret->retry_interval < MIN_RETRY_INTERVAL) {
+ dbg(0, "Retry interval %d too small, setting to %d\n", ret->retry_interval, MIN_RETRY_INTERVAL);
+ ret->retry_interval = MIN_RETRY_INTERVAL;
+ }
+ } else {
+ dbg(0, "Retry interval not defined, setting to %d\n", DEFAULT_RETRY_INTERVAL);
+ ret->retry_interval = DEFAULT_RETRY_INTERVAL;
+ }
+ ret->cbl = cbl;
+ *meth = vehicle_gpsd_methods;
+ vehicle_gpsd_open(ret);
+ return ret;
+}
+
+void
+plugin_init(void)
+{
+ dbg(1, "enter\n");
+ plugin_register_vehicle_type("gpsd", vehicle_gpsd_new_gpsd);
+}
diff --git a/navit/xmlconfig.c b/navit/xmlconfig.c
new file mode 100644
index 000000000..726b43e07
--- /dev/null
+++ b/navit/xmlconfig.c
@@ -0,0 +1,1097 @@
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <string.h>
+#include "debug.h"
+#include "file.h"
+#include "coord.h"
+#include "layout.h"
+#include "mapset.h"
+#include "projection.h"
+#include "map.h"
+#include "navigation.h"
+#include "navit.h"
+#include "plugin.h"
+#include "route.h"
+#include "speech.h"
+#include "track.h"
+#include "vehicle.h"
+#include "point.h"
+#include "graphics.h"
+#include "gui.h"
+#include "osd.h"
+#include "log.h"
+#include "xmlconfig.h"
+#include "config.h"
+
+struct xistate {
+ struct xistate *parent;
+ struct xistate *child;
+ const gchar *element;
+ gchar **attribute_names;
+ gchar **attribute_values;
+};
+
+struct xmldocument {
+ const gchar *href;
+ const gchar *xpointer;
+ gpointer user_data;
+ struct xistate *first;
+ struct xistate *last;
+ int active;
+ int level;
+};
+
+struct xmlstate {
+ const gchar **attribute_names;
+ const gchar **attribute_values;
+ struct xmlstate *parent;
+ struct attr element_attr;
+ const gchar *element;
+ GError **error;
+ struct element_func *func;
+ struct xmldocument *document;
+};
+
+
+
+static struct attr ** convert_to_attrs(struct xmlstate *state)
+{
+ const gchar **attribute_name=state->attribute_names;
+ const gchar **attribute_value=state->attribute_values;
+ int count=0;
+ struct attr **ret;
+
+ while (*attribute_name) {
+ count++;
+ attribute_name++;
+ }
+ ret=g_new(struct attr *, count+1);
+ attribute_name=state->attribute_names;
+ count=0;
+ while (*attribute_name) {
+ ret[count]=attr_new_from_text(*attribute_name,*attribute_value);
+ if (ret[count])
+ count++;
+ attribute_name++;
+ attribute_value++;
+ }
+ ret[count]=NULL;
+ dbg(1,"ret=%p\n", ret);
+ return ret;
+}
+
+
+static const char * find_attribute(struct xmlstate *state, const char *attribute, int required)
+{
+ const gchar **attribute_name=state->attribute_names;
+ const gchar **attribute_value=state->attribute_values;
+ while(*attribute_name) {
+ if(! g_ascii_strcasecmp(attribute,*attribute_name))
+ return *attribute_value;
+ attribute_name++;
+ attribute_value++;
+ }
+ if (required)
+ g_set_error(state->error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT, "element '%s' is missing attribute '%s'", state->element, attribute);
+ return NULL;
+}
+
+static int
+find_color(struct xmlstate *state, int required, struct color *color)
+{
+ const char *value;
+ int r,g,b,a;
+
+ value=find_attribute(state, "color", required);
+ if (! value)
+ return 0;
+ if(strlen(value)==7){
+ sscanf(value,"#%02x%02x%02x", &r, &g, &b);
+ color->r = (r << 8) | r;
+ color->g = (g << 8) | g;
+ color->b = (b << 8) | b;
+ color->a = (65535);
+ } else if(strlen(value)==9){
+ sscanf(value,"#%02x%02x%02x%02x", &r, &g, &b, &a);
+ color->r = (r << 8) | r;
+ color->g = (g << 8) | g;
+ color->b = (b << 8) | b;
+ color->a = (a << 8) | a;
+ } else {
+ dbg(0,"color %i has unknown format\n",value);
+ }
+ return 1;
+}
+
+static int
+find_order(struct xmlstate *state, int required, int *min, int *max)
+{
+ const char *value, *pos;
+ int ret;
+
+ *min=0;
+ *max=18;
+ value=find_attribute(state, "order", required);
+ if (! value)
+ return 0;
+ pos=strchr(value, '-');
+ if (! pos) {
+ ret=sscanf(value,"%d",min);
+ *max=*min;
+ } else if (pos == value)
+ ret=sscanf(value,"-%d",max);
+ else
+ ret=sscanf(value,"%d-%d", min, max);
+ return ret;
+}
+
+static int
+find_boolean(struct xmlstate *state, const char *attribute, int deflt, int required)
+{
+ const char *value;
+
+ value=find_attribute(state, attribute, required);
+ if (! value)
+ return deflt;
+ if (g_ascii_strcasecmp(value,"no") && g_ascii_strcasecmp(value,"0") && g_ascii_strcasecmp(value,"false"))
+ return 1;
+ return 0;
+}
+
+static int
+convert_number(const char *val)
+{
+ if (val)
+ return g_ascii_strtoull(val,NULL,0);
+ else
+ return 0;
+}
+
+static int
+convert_number_list(const char *val, int *table, int size)
+{
+ char *tok,*str,*val_str,*saveptr=NULL;
+ int i;
+ str=val_str=g_strdup(val);
+ for (i=0; i<size && (tok=strtok_r(str, ",", &saveptr)); i++) {
+ table[i]=convert_number(tok);
+ str=NULL;
+ }
+ g_free(val_str);
+ return i;
+}
+
+static int
+xmlconfig_config(struct xmlstate *state)
+{
+ state->element_attr.u.data = (void *)1;
+ return 1;
+}
+
+static int
+xmlconfig_plugin(struct xmlstate *state)
+{
+ const char *path;
+ int active,lazy;
+
+ state->element_attr.u.data=state->parent->element_attr.u.data;
+ path=find_attribute(state, "path", 1);
+ if (! path)
+ return 0;
+ active=find_boolean(state, "active", 1, 0);
+ lazy=find_boolean(state, "lazy", 1, 0);
+ plugins_add_path(state->parent->element_attr.u.data, path, active, lazy);
+ return 1;
+}
+
+static int
+xmlconfig_speech(struct xmlstate *state)
+{
+ const char *type;
+ const char *data;
+ type=find_attribute(state, "type", 1);
+ if (! type)
+ return 0;
+ data=find_attribute(state, "data", 0);
+ state->element_attr.u.data = speech_new(type, data);
+ if (! state->element_attr.u.data)
+ return 0;
+ navit_set_speech(state->parent->element_attr.u.data, state->element_attr.u.data);
+ return 1;
+}
+
+static int
+xmlconfig_debug(struct xmlstate *state)
+{
+ const char *name,*level;
+ name=find_attribute(state, "name", 1);
+ if (! name)
+ return 0;
+ level=find_attribute(state, "level", 1);
+ if (! level)
+ return 0;
+ debug_level_set(name, convert_number(level));
+ return 1;
+}
+
+static int
+xmlconfig_vehicle(struct xmlstate *state)
+{
+ struct attr **attrs;
+ attrs=convert_to_attrs(state);
+
+ state->element_attr.u.data = vehicle_new(attrs);
+ if (! state->element_attr.u.data)
+ return 0;
+ navit_add_vehicle(state->parent->element_attr.u.data, state->element_attr.u.data, attrs);
+ return 1;
+}
+
+static int
+xmlconfig_log_vehicle(struct xmlstate *state)
+{
+ struct attr attr;
+ struct attr **attrs;
+ attrs=convert_to_attrs(state);
+ state->element_attr.u.data = log_new(attrs);
+ if (! state->element_attr.u.data)
+ return 0;
+ attr.type=attr_log;
+ attr.u.log=state->element_attr.u.data;
+ if (vehicle_add_attr(state->parent->element_attr.u.data, &attr))
+ return 0;
+ return 1;
+}
+
+static int
+xmlconfig_log_navit(struct xmlstate *state)
+{
+ struct attr attr;
+ struct attr **attrs;
+ attrs=convert_to_attrs(state);
+ state->element_attr.u.data = log_new(attrs);
+ if (! state->element_attr.u.data)
+ return 0;
+ attr.type=attr_log;
+ attr.u.log=state->element_attr.u.data;
+ if (navit_add_attr(state->parent->element_attr.u.data, &attr))
+ return 0;
+ return 1;
+}
+
+
+static int
+xmlconfig_window_items(struct xmlstate *state)
+{
+ int distance=-1;
+ enum item_type itype;
+ const char *name=find_attribute(state, "name", 1);
+ const char *value=find_attribute(state, "distance", 0);
+ const char *type=find_attribute(state, "type", 1);
+ char *tok,*str,*type_str,*saveptr=NULL;
+ if (! name || !type)
+ return 0;
+ if (value)
+ distance=convert_number(value);
+ state->element_attr.u.data = navit_window_items_new(name, distance);
+ type_str=g_strdup(type);
+ str=type_str;
+ while ((tok=strtok_r(str, ",", &saveptr))) {
+ itype=item_from_name(tok);
+ navit_window_items_add_item(state->element_attr.u.data, itype);
+ str=NULL;
+ }
+ g_free(type_str);
+
+ navit_add_window_items(state->parent->element_attr.u.data, state->element_attr.u.data);
+
+ return 1;
+}
+
+
+static int
+xmlconfig_tracking(struct xmlstate *state)
+{
+ state->element_attr.u.data = tracking_new(NULL);
+ navit_tracking_add(state->parent->element_attr.u.data, state->element_attr.u.data);
+ return 1;
+}
+
+static int
+xmlconfig_route(struct xmlstate *state)
+{
+ struct attr **attrs;
+ struct attr route_attr;
+
+ attrs=convert_to_attrs(state);
+ state->element_attr.u.data = route_new(attrs);
+ if (! state->element_attr.u.data) {
+ dbg(0,"Failed to create route object\n");
+ return 0;
+ }
+ route_attr.type=attr_route;
+ route_attr.u.route=state->element_attr.u.data;
+ return navit_add_attr(state->parent->element_attr.u.data, &route_attr);
+}
+
+static int
+xmlconfig_speed(struct xmlstate *state)
+{
+ const char *type;
+ const char *value;
+ int v;
+ enum item_type itype;
+ char *saveptr=NULL, *tok, *type_str, *str;
+
+ type=find_attribute(state, "type", 1);
+ if (! type)
+ return 0;
+ value=find_attribute(state, "value", 1);
+ if (! value)
+ return 0;
+ v=convert_number(value);
+ type_str=g_strdup(type);
+ str=type_str;
+ while ((tok=strtok_r(str, ",", &saveptr))) {
+ itype=item_from_name(tok);
+ route_set_speed(state->parent->element_attr.u.data, itype, v);
+ str=NULL;
+ }
+ g_free(type_str);
+
+ return 1;
+}
+
+
+static int
+xmlconfig_navigation(struct xmlstate *state)
+{
+ struct attr **attrs;
+ struct attr navigation_attr;
+
+ attrs=convert_to_attrs(state);
+ state->element_attr.u.data = navigation_new(attrs);
+ if (! state->element_attr.u.data) {
+ dbg(0,"Failed to create navigation object\n");
+ return 0;
+ }
+ navigation_attr.type=attr_navigation;
+ navigation_attr.u.navigation=state->element_attr.u.data;
+ return navit_add_attr(state->parent->element_attr.u.data, &navigation_attr);
+}
+
+static int
+xmlconfig_osd(struct xmlstate *state)
+{
+ struct attr **attrs;
+ const char *type=find_attribute(state, "type", 1);
+ if (! type)
+ return 0;
+ attrs=convert_to_attrs(state);
+ state->element_attr.u.data = osd_new(state->parent->element_attr.u.data, type, attrs);
+ return 1;
+}
+
+static int
+xmlconfig_announce(struct xmlstate *state)
+{
+ const char *type,*value;
+ char key[32];
+ int level[3];
+ int i;
+ enum item_type itype;
+ char *saveptr=NULL, *tok, *type_str, *str;
+
+ type=find_attribute(state, "type", 1);
+ if (! type)
+ return 0;
+ for (i = 0 ; i < 3 ; i++) {
+ sprintf(key,"level%d", i);
+ value=find_attribute(state, key, 0);
+ if (value)
+ level[i]=convert_number(value);
+ else
+ level[i]=-1;
+ }
+ type_str=g_strdup(type);
+ str=type_str;
+ while ((tok=strtok_r(str, ",", &saveptr))) {
+ itype=item_from_name(tok);
+ navigation_set_announce(state->parent->element_attr.u.data, itype, level);
+ str=NULL;
+ }
+ g_free(type_str);
+ return 1;
+}
+
+static int
+xmlconfig_mapset(struct xmlstate *state)
+{
+ state->element_attr.u.data = mapset_new();
+ if (! state->element_attr.u.data)
+ return 0;
+ navit_add_mapset(state->parent->element_attr.u.data, state->element_attr.u.data);
+
+ return 1;
+}
+
+static int
+xmlconfig_map(struct xmlstate *state)
+{
+ struct attr **attrs;
+ const char *type=find_attribute(state, "type", 1);
+ if (! type)
+ return 0;
+ attrs=convert_to_attrs(state);
+ state->element_attr.u.data = map_new(type, attrs);
+ if (! state->element_attr.u.data)
+ return 0;
+ if (!find_boolean(state, "active", 1, 0))
+ map_set_active(state->element_attr.u.data, 0);
+ mapset_add(state->parent->element_attr.u.data, state->element_attr.u.data);
+
+ return 1;
+}
+
+static int
+xmlconfig_layout(struct xmlstate *state)
+{
+ const char *name=find_attribute(state, "name", 1);
+ struct color color = {0xffff, 0xefef, 0xb7b7, 0xffff};
+
+ if (! name)
+ return 0;
+ find_color(state, 0, &color);
+ state->element_attr.u.data = layout_new(name, &color);
+ if (! state->element_attr.u.data)
+ return 0;
+ navit_add_layout(state->parent->element_attr.u.data, state->element_attr.u.data);
+ return 1;
+}
+
+static int
+xmlconfig_layer(struct xmlstate *state)
+{
+ const char *name=find_attribute(state, "name", 1);
+ if (! name)
+ return 0;
+ state->element_attr.u.data = layer_new(name, convert_number(find_attribute(state, "details", 0)));
+ if (! state->element_attr.u.data)
+ return 0;
+ layout_add_layer(state->parent->element_attr.u.data, state->element_attr.u.data);
+ return 1;
+}
+
+static int
+xmlconfig_item(struct xmlstate *state)
+{
+ const char *type=find_attribute(state, "type", 1);
+ int min, max;
+ enum item_type itype;
+ char *saveptr=NULL, *tok, *type_str, *str;
+
+ if (! type)
+ return 0;
+ if (! find_order(state, 1, &min, &max))
+ return 0;
+ state->element_attr.u.data=itemtype_new(min, max);
+ if (! state->element_attr.u.data)
+ return 0;
+ type_str=g_strdup(type);
+ str=type_str;
+ layer_add_itemtype(state->parent->element_attr.u.data, state->element_attr.u.data);
+ while ((tok=strtok_r(str, ",", &saveptr))) {
+ itype=item_from_name(tok);
+ itemtype_add_type(state->element_attr.u.data, itype);
+ str=NULL;
+ }
+ g_free(type_str);
+
+ return 1;
+}
+
+static int
+xmlconfig_polygon(struct xmlstate *state)
+{
+ struct color color;
+
+ if (! find_color(state, 1, &color))
+ return 0;
+ state->element_attr.u.data=polygon_new(&color);
+ if (! state->element_attr.u.data)
+ return 0;
+ itemtype_add_element(state->parent->element_attr.u.data, state->element_attr.u.data);
+
+ return 1;
+}
+
+static int
+xmlconfig_polyline(struct xmlstate *state)
+{
+ struct color color;
+ const char *width, *dash, *directed;
+ int w=0, d=0, dt[4], ds=0;
+
+ if (! find_color(state, 1, &color))
+ return 0;
+ width=find_attribute(state, "width", 0);
+ if (width)
+ w=convert_number(width);
+ dash=find_attribute(state, "dash", 0);
+ if (dash)
+ ds=convert_number_list(dash, dt, sizeof(dt)/sizeof(*dt));
+ directed=find_attribute(state, "directed", 0);
+ if (directed)
+ d=convert_number(directed);
+
+ state->element_attr.u.data=polyline_new(&color, w, d, dt, ds);
+ if (! state->element_attr.u.data)
+ return 0;
+ itemtype_add_element(state->parent->element_attr.u.data, state->element_attr.u.data);
+
+ return 1;
+}
+
+static int
+xmlconfig_circle(struct xmlstate *state)
+{
+ struct color color;
+ const char *width, *radius, *label_size;
+ int w=0,r=0,ls=0;
+
+ if (! find_color(state, 1, &color))
+ return 0;
+ width=find_attribute(state, "width", 0);
+ if (width)
+ w=convert_number(width);
+ radius=find_attribute(state, "radius", 0);
+ if (radius)
+ r=convert_number(radius);
+ label_size=find_attribute(state, "label_size", 0);
+ if (label_size)
+ ls=convert_number(label_size);
+ state->element_attr.u.data=circle_new(&color, r, w, ls);
+ if (! state->element_attr.u.data)
+ return 0;
+ itemtype_add_element(state->parent->element_attr.u.data, state->element_attr.u.data);
+
+ return 1;
+}
+
+static int
+xmlconfig_label(struct xmlstate *state)
+{
+ const char *label_size;
+ int ls=0;
+
+ label_size=find_attribute(state, "label_size", 0);
+ if (label_size)
+ ls=convert_number(label_size);
+ state->element_attr.u.data=label_new(ls);
+ if (! state->element_attr.u.data)
+ return 0;
+ itemtype_add_element(state->parent->element_attr.u.data, state->element_attr.u.data);
+
+ return 1;
+}
+
+static int
+xmlconfig_icon(struct xmlstate *state)
+{
+ const char *src=find_attribute(state, "src", 1);
+
+ if (! src)
+ return 0;
+ state->element_attr.u.data=icon_new(src);
+ if (! state->element_attr.u.data)
+ return 0;
+ itemtype_add_element(state->parent->element_attr.u.data, state->element_attr.u.data);
+
+ return 1;
+}
+
+static int
+xmlconfig_image(struct xmlstate *state)
+{
+ state->element_attr.u.data=image_new();
+ if (! state->element_attr.u.data)
+ return 0;
+ itemtype_add_element(state->parent->element_attr.u.data, state->element_attr.u.data);
+
+ return 1;
+}
+
+#define NEW(x) (void *(*)(struct attr *, struct attr **))(x)
+#define ADD(x) (int (*)(void *, struct attr *attr))(x)
+#define INIT(x) (int (*)(void *))(x)
+#define DESTROY(x) (void (*)(void *))(x)
+struct element_func {
+ char *name;
+ char *parent;
+ int (*func)(struct xmlstate *state);
+ void *(*new)(struct attr *parent, struct attr **attrs);
+ int (*add_attr)(void *, struct attr *attr);
+ int (*init)(void *);
+ void (*destroy)(void *);
+} elements[] = {
+ { "config", NULL, xmlconfig_config},
+ { "debug", "config", xmlconfig_debug},
+ { "navit", "config", NULL, NEW(navit_new), ADD(navit_add_attr), INIT(navit_init), DESTROY(navit_destroy)},
+ { "graphics", "navit", NULL, NEW(graphics_new), NULL, NULL, NULL},
+ { "gui", "navit", NULL, NEW(gui_new), NULL, NULL, NULL},
+ { "layout", "navit", xmlconfig_layout},
+ { "layer", "layout", xmlconfig_layer},
+ { "item", "layer", xmlconfig_item},
+ { "circle", "item", xmlconfig_circle},
+ { "icon", "item", xmlconfig_icon},
+ { "image", "item", xmlconfig_image},
+ { "label", "item", xmlconfig_label},
+ { "polygon", "item", xmlconfig_polygon},
+ { "polyline", "item", xmlconfig_polyline},
+ { "mapset", "navit", xmlconfig_mapset},
+ { "map", "mapset", xmlconfig_map},
+ { "navigation", "navit", xmlconfig_navigation},
+ { "osd", "navit", xmlconfig_osd},
+ { "announce", "navigation", xmlconfig_announce},
+ { "speech", "navit", xmlconfig_speech},
+ { "tracking", "navit", xmlconfig_tracking},
+ { "route", "navit", xmlconfig_route},
+ { "speed", "route", xmlconfig_speed},
+ { "vehicle", "navit", xmlconfig_vehicle},
+ { "log", "vehicle", xmlconfig_log_vehicle},
+ { "log", "navit", xmlconfig_log_navit},
+ { "window_items", "navit", xmlconfig_window_items},
+ { "plugins", "config", NULL, NEW(plugins_new), NULL, INIT(plugins_init), NULL},
+ { "plugin", "plugins", xmlconfig_plugin},
+ {},
+};
+
+static void
+start_element(GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ struct xmlstate *new=NULL, **parent = user_data;
+ struct element_func *e=elements,*func=NULL;
+ int found=0;
+ const char *parent_name=NULL;
+ char *s,*sep="",*possible_parents;
+ dbg(2,"name='%s' parent='%s'\n", element_name, *parent ? (*parent)->element:NULL);
+ possible_parents=g_strdup("");
+ if (*parent)
+ parent_name=(*parent)->element;
+ while (e->name) {
+ if (!g_ascii_strcasecmp(element_name, e->name)) {
+ found=1;
+ s=g_strconcat(possible_parents,sep,e->parent,NULL);
+ g_free(possible_parents);
+ possible_parents=s;
+ sep=",";
+ if ((parent_name && e->parent && !g_ascii_strcasecmp(parent_name, e->parent)) ||
+ (!parent_name && !e->parent))
+ func=e;
+ }
+ e++;
+ }
+ if (! found) {
+ g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+ "Unknown element '%s'", element_name);
+ g_free(possible_parents);
+ return;
+ }
+ if (! func) {
+ g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT,
+ "Element '%s' within unexpected context '%s'. Expected '%s'%s",
+ element_name, parent_name, possible_parents, ! strcmp(possible_parents, "config") ? "\nPlease add <config> </config> tags at the beginning/end of your navit.xml": "");
+ g_free(possible_parents);
+ return;
+ }
+ g_free(possible_parents);
+
+ new=g_new(struct xmlstate, 1);
+ new->attribute_names=attribute_names;
+ new->attribute_values=attribute_values;
+ new->parent=*parent;
+ new->element_attr.u.data=NULL;
+ new->element=element_name;
+ new->error=error;
+ new->func=func;
+ *parent=new;
+ if (!find_boolean(new, "enabled", 1, 0))
+ return;
+ if (new->parent && !new->parent->element_attr.u.data)
+ return;
+ if (func->func) {
+ if (!func->func(new)) {
+ return;
+ }
+ } else {
+ struct attr **attrs;
+
+ attrs=convert_to_attrs(new);
+ new->element_attr.type=attr_none;
+ new->element_attr.u.data = func->new(&new->parent->element_attr, attrs);
+ if (! new->element_attr.u.data)
+ return;
+ new->element_attr.type=attr_from_name(element_name);
+ if (new->parent->func->add_attr)
+ new->parent->func->add_attr(new->parent->element_attr.u.data, &new->element_attr);
+ }
+ return;
+}
+
+
+/* Called for close tags </foo> */
+static void
+end_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ struct xmlstate *curr, **state = user_data;
+
+ dbg(2,"name='%s'\n", element_name);
+ curr=*state;
+ if (curr->func->init)
+ curr->func->init(curr->element_attr.u.data);
+ *state=curr->parent;
+ g_free(curr);
+}
+
+static gboolean parse_file(struct xmldocument *document, GError **error);
+
+static void
+xinclude(GMarkupParseContext *context, const gchar **attribute_names, const gchar **attribute_values, struct xmldocument *doc_old, GError **error)
+{
+ struct xmldocument doc_new;
+ struct file_wordexp *we;
+ int i,count;
+ const char *href=NULL;
+ char **we_files;
+
+ if (doc_old->level >= 16) {
+ g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT, "xi:include recursion too deep");
+ return;
+ }
+ memset(&doc_new, 0, sizeof(doc_new));
+ i=0;
+ while (attribute_names[i]) {
+ if(!g_ascii_strcasecmp("href", attribute_names[i])) {
+ if (!href)
+ href=attribute_values[i];
+ else {
+ g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT, "xi:include has more than one href");
+ return;
+ }
+ } else if(!g_ascii_strcasecmp("xpointer", attribute_names[i])) {
+ if (!doc_new.xpointer)
+ doc_new.xpointer=attribute_values[i];
+ else {
+ g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT, "xi:include has more than one xpointer");
+ return;
+ }
+ } else {
+ g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT, "xi:include has invalid attributes");
+ return;
+ }
+ i++;
+ }
+ if (!doc_new.xpointer && !href) {
+ g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_INVALID_CONTENT, "xi:include has neither href nor xpointer");
+ return;
+ }
+ doc_new.level=doc_old->level+1;
+ doc_new.user_data=doc_old->user_data;
+ if (! href) {
+ dbg(1,"no href, using '%s'\n", doc_old->href);
+ doc_new.href=doc_old->href;
+ parse_file(&doc_new, error);
+ } else {
+ dbg(1,"expanding '%s'\n", href);
+ we=file_wordexp_new(href);
+ we_files=file_wordexp_get_array(we);
+ count=file_wordexp_get_count(we);
+ dbg(1,"%d results\n", count);
+ for (i = 0 ; i < count ; i++) {
+ dbg(1,"result[%d]='%s'\n", i, we_files[i]);
+ doc_new.href=we_files[i];
+ parse_file(&doc_new, error);
+ }
+ file_wordexp_destroy(we);
+
+ }
+
+}
+static int
+strncmp_len(const char *s1, int s1len, const char *s2)
+{
+ int ret;
+#if 0
+ char c[s1len+1];
+ strncpy(c, s1, s1len);
+ c[s1len]='\0';
+ dbg(0,"'%s' vs '%s'\n", c, s2);
+#endif
+
+ ret=strncmp(s1, s2, s1len);
+ if (ret)
+ return ret;
+ return strlen(s2)-s1len;
+}
+
+static int
+xpointer_value(const char *test, int len, struct xistate *elem, const char **out, int out_len)
+{
+ int i,ret=0;
+ if (len <= 0 || out_len <= 0) {
+ return 0;
+ }
+ if (!(strncmp_len(test,len,"name(.)"))) {
+ out[0]=elem->element;
+ return 1;
+ }
+ if (test[0] == '@') {
+ i=0;
+ while (elem->attribute_names[i] && out_len > 0) {
+ if (!strncmp_len(test+1,len-1,elem->attribute_names[i])) {
+ out[ret++]=elem->attribute_values[i];
+ out_len--;
+ }
+ i++;
+ }
+ return ret;
+ }
+ return 0;
+}
+
+static int
+xpointer_test(const char *test, int len, struct xistate *elem)
+{
+ int eq,i,count,vlen,cond_req=1,cond=0;
+ char c;
+ const char *tmp[16];
+
+ if (!len)
+ return 0;
+ c=test[len-1];
+ if (c != '\'' && c != '"')
+ return 0;
+ eq=strcspn(test, "=");
+ if (eq >= len || test[eq+1] != c)
+ return 0;
+ vlen=eq;
+ if (eq > 0 && test[eq-1] == '!') {
+ cond_req=0;
+ vlen--;
+ }
+ count=xpointer_value(test,vlen,elem,tmp,16);
+ for (i = 0 ; i < count ; i++) {
+ if (!strncmp_len(test+eq+2,len-eq-3, tmp[i]))
+ cond=1;
+ }
+ if (cond == cond_req)
+ return 1;
+ return 0;
+}
+
+static int
+xpointer_element_match(const char *xpointer, int len, struct xistate *elem)
+{
+ int len_test;
+ len_test=strcspn(xpointer, "[");
+ if (len_test > len)
+ len_test=len;
+ if (strncmp_len(xpointer, len_test, elem->element) && (len_test != 1 || xpointer[0] != '*'))
+ return 0;
+ if (len_test == len)
+ return 1;
+ if (xpointer[len-1] != ']')
+ return 0;
+ return xpointer_test(xpointer+len_test+1, len-len_test-2, elem);
+}
+
+static int
+xpointer_xpointer_match(const char *xpointer, int len, struct xistate *first)
+{
+ const char *c;
+ int s;
+ dbg(2,"%s\n", xpointer);
+ if (xpointer[0] != '/')
+ return 0;
+ c=xpointer+1;
+ len--;
+ do {
+ s=strcspn(c, "/");
+ if (s > len)
+ s=len;
+ if (! xpointer_element_match(c, s, first))
+ return 0;
+ first=first->child;
+ c+=s+1;
+ len-=s+1;
+ } while (s < len && first);
+ if (s < len)
+ return 0;
+ return 1;
+}
+
+static int
+xpointer_match(const char *xpointer, struct xistate *first)
+{
+ char *prefix="xpointer(";
+ int len=strlen(xpointer);
+ if (! xpointer)
+ return 1;
+ if (strncmp(xpointer,prefix,strlen(prefix)))
+ return 0;
+ if (xpointer[len-1] != ')')
+ return 0;
+ return xpointer_xpointer_match(xpointer+strlen(prefix), len-strlen(prefix)-1, first);
+
+}
+
+static void
+xi_start_element(GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ struct xmldocument *doc=user_data;
+ struct xistate *xistate;
+ int i,count=0;
+ while (attribute_names[count++]);
+ xistate=g_new0(struct xistate, 1);
+ xistate->element=element_name;
+ xistate->attribute_names=g_new(char *, count);
+ xistate->attribute_values=g_new(char *, count);
+ for (i = 0 ; i < count ; i++) {
+ xistate->attribute_names[i]=g_strdup(attribute_names[i]);
+ xistate->attribute_values[i]=g_strdup(attribute_values[i]);
+ }
+ xistate->parent=doc->last;
+
+ if (doc->last) {
+ doc->last->child=xistate;
+ } else
+ doc->first=xistate;
+ doc->last=xistate;
+ if (doc->active > 0 || xpointer_match(doc->xpointer, doc->first)) {
+ if(!g_ascii_strcasecmp("xi:include", element_name)) {
+ xinclude(context, attribute_names, attribute_values, doc, error);
+ return;
+ }
+ start_element(context, element_name, attribute_names, attribute_values, doc->user_data, error);
+ doc->active++;
+ }
+
+}
+
+static void
+xi_end_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ struct xmldocument *doc=user_data;
+ struct xistate *xistate=doc->last;
+ int i=0;
+ doc->last=doc->last->parent;
+ if (! doc->last)
+ doc->first=NULL;
+ else
+ doc->last->child=NULL;
+ if (doc->active > 0) {
+ if(!g_ascii_strcasecmp("xi:include", element_name)) {
+ return;
+ }
+ end_element(context, element_name, doc->user_data, error);
+ doc->active--;
+ }
+ while (xistate->attribute_names[i]) {
+ g_free(xistate->attribute_names[i]);
+ g_free(xistate->attribute_values[i]);
+ i++;
+ }
+ g_free(xistate->attribute_names);
+ g_free(xistate->attribute_values);
+ g_free(xistate);
+}
+
+/* Called for character data */
+/* text is not nul-terminated */
+static void
+xi_text (GMarkupParseContext *context,
+ const gchar *text,
+ gsize text_len,
+ gpointer user_data,
+ GError **error)
+{
+}
+
+
+
+static const GMarkupParser parser = {
+ xi_start_element,
+ xi_end_element,
+ xi_text,
+ NULL,
+ NULL
+};
+
+static gboolean
+parse_file(struct xmldocument *document, GError **error)
+{
+ GMarkupParseContext *context;
+ gchar *contents, *message;
+ gsize len;
+ gint line, chr;
+ gboolean result;
+
+ dbg(1,"enter filename='%s'\n", document->href);
+ context = g_markup_parse_context_new (&parser, 0, document, NULL);
+
+ if (!g_file_get_contents (document->href, &contents, &len, error)) {
+ g_markup_parse_context_free (context);
+ return FALSE;
+ }
+ document->active=document->xpointer ? 0:1;
+ document->first=NULL;
+ document->last=NULL;
+ result = g_markup_parse_context_parse (context, contents, len, error);
+ if (!result && error && *error) {
+ g_markup_parse_context_get_position(context, &line, &chr);
+ message=g_strdup_printf("%s at line %d, char %d\n", (*error)->message, line, chr);
+ g_free((*error)->message);
+ (*error)->message=message;
+ }
+ g_markup_parse_context_free (context);
+ g_free (contents);
+ dbg(1,"return %d\n", result);
+
+ return result;
+}
+
+gboolean config_load(char *filename, GError **error)
+{
+ struct xmldocument document;
+ struct xmlstate *curr=NULL;
+ gboolean result;
+
+ dbg(1,"enter filename='%s'\n", filename);
+ memset(&document, 0, sizeof(document));
+ document.href=filename;
+ document.user_data=&curr;
+ result=parse_file(&document, error);
+ if (result && curr) {
+ g_set_error(error,G_MARKUP_ERROR,G_MARKUP_ERROR_PARSE, "element '%s' not closed", curr->element);
+ result=FALSE;
+ }
+ dbg(1,"return %d\n", result);
+ return result;
+}
+
diff --git a/navit/xmlconfig.h b/navit/xmlconfig.h
new file mode 100644
index 000000000..2e03aa62e
--- /dev/null
+++ b/navit/xmlconfig.h
@@ -0,0 +1,8 @@
+#ifndef NAVIT_XMLCONFIG_H
+#define NAVIT_XMLCONFIG_H
+
+struct container;
+gboolean config_load(char *filename,GError **error);
+
+#endif
+
diff --git a/navit/xpm/Makefile.am b/navit/xpm/Makefile.am
new file mode 100644
index 000000000..82569dd57
--- /dev/null
+++ b/navit/xpm/Makefile.am
@@ -0,0 +1,8 @@
+include $(top_srcdir)/Makefile.inc
+xpm_DATA = airport.xpm attraction.xpm bank.xpm bar.xpm bus.xpm cafe.xpm camping.xpm car_dealer.xpm church.xpm cinema.xpm dumping-station.xpm exit.xpm fastfood.xpm firebrigade.xpm flag_bk_tr.xpm flag_bk_wh.xpm flag_bl_wh.xpm flag_wh_bk.xpm fuel.xpm golf.xpm highway_exit.xpm hospital.xpm hotel.xpm information.xpm library.xpm museum.xpm nav_left_1.xpm nav_left_2.xpm nav_right_1.xpm nav_right_2.xpm nav_straight.xpm parking.xpm pharmacy.xpm picnic.xpm police.xpm post.xpm restaurant.xpm restroom.xpm skiing.xpm sports.xpm swimming.xpm telephone.xpm theater.xpm tower.xpm traffic_signals.xpm trailerpark.xpm unknown.xpm gc_tradi.xpm gc_multi.xpm gc_mystery.xpm gc_event.xpm
+xpm_DATA += gc_reference.xpm gc_webcam.xpm gc_question.xpm gc_stages.xpm
+xpm_DATA += shopping.xpm heliport.xpm cursor.xpm peak.xpm mini_roundabout.xpm
+xpm_DATA += townhall.xpm level_crossing.xpm
+EXTRA_DIST = $(xpm_DATA)
+#burgerking.ico:
+# wget http://www.burgerking.de/favicon.ico -O burgerking.ico
diff --git a/navit/xpm/airport.xpm b/navit/xpm/airport.xpm
new file mode 100644
index 000000000..ea40e00d6
--- /dev/null
+++ b/navit/xpm/airport.xpm
@@ -0,0 +1,75 @@
+/* XPM */
+static char * airport_xpm[] = {
+"16 16 56 1",
+" c None",
+". c #03705F",
+"+ c #0F7767",
+"@ c #0F7766",
+"# c #DBEAE8",
+"$ c #D9EAE7",
+"% c #FEFEFE",
+"& c #FAFCFB",
+"* c #F8FAFA",
+"= c #FBFDFC",
+"- c #FCFDFD",
+"; c #0A7463",
+"> c #73B0A6",
+", c #F8FBFB",
+"' c #F9FBFB",
+") c #82B7AE",
+"! c #58A095",
+"~ c #057160",
+"{ c #5CA398",
+"] c #F8FBFA",
+"^ c #FFFFFF",
+"/ c #FBFCFC",
+"( c #E1EDEB",
+"_ c #077261",
+": c #459689",
+"< c #EFF6F5",
+"[ c #6FADA3",
+"} c #2E897B",
+"| c #F1F7F6",
+"1 c #FAFCFC",
+"2 c #388E81",
+"3 c #ECF4F3",
+"4 c #F3F8F7",
+"5 c #EDF5F3",
+"6 c #519C90",
+"7 c #0A7464",
+"8 c #FDFEFE",
+"9 c #087362",
+"0 c #4A988C",
+"a c #AED1CC",
+"b c #61A59B",
+"c c #529D91",
+"d c #0B7564",
+"e c #F7FAFA",
+"f c #338B7D",
+"g c #66A89E",
+"h c #077362",
+"i c #B4D4CF",
+"j c #E7F1F0",
+"k c #097363",
+"l c #DCEBE9",
+"m c #218172",
+"n c #348C7E",
+"o c #047160",
+"p c #278476",
+"q c #30897B",
+".......+@.......",
+".......#$.......",
+".......%%.......",
+".......&*.......",
+".......=-.......",
+".......&-.......",
+".....;>,')!.....",
+"...~{]^^^^/(_...",
+"..:^^^^^^^^^<[..",
+"}|^^^^/^-1/^^^(2",
+"3^4567.88.90#'^a",
+"bcd....e^....f6g",
+"......./1.......",
+".....hi%%jk.....",
+".....l^--^^.....",
+".....mno.pq....."};
diff --git a/navit/xpm/attraction.xpm b/navit/xpm/attraction.xpm
new file mode 100644
index 000000000..f5771b022
--- /dev/null
+++ b/navit/xpm/attraction.xpm
@@ -0,0 +1,141 @@
+/* XPM */
+static char * attraction_xpm[] = {
+"16 16 122 2",
+" c None",
+". c #CC1400",
+"+ c #AE1100",
+"@ c #FB1800",
+"# c #BA1200",
+"$ c #FF1900",
+"% c #F61800",
+"& c #DA1500",
+"* c #DE1500",
+"= c #E51600",
+"- c #C31300",
+"; c #810C00",
+"> c #F01700",
+", c #FE1800",
+"' c #8B0D00",
+") c #8D0D00",
+"! c #D21400",
+"~ c #BB1200",
+"{ c #9D0F00",
+"] c #B21100",
+"^ c #AF1100",
+"/ c #AC1000",
+"( c #D61500",
+"_ c #8C0D00",
+": c #C11200",
+"< c #D71500",
+"[ c #9F0F00",
+"} c #D31400",
+"| c #C71300",
+"1 c #920E00",
+"2 c #F81800",
+"3 c #CD1400",
+"4 c #EE1700",
+"5 c #DC1500",
+"6 c #F71800",
+"7 c #840D00",
+"8 c #B31100",
+"9 c #E61600",
+"0 c #A41000",
+"a c #970E00",
+"b c #8A0D00",
+"c c #B61100",
+"d c #D11400",
+"e c #990F00",
+"f c #8E0D00",
+"g c #C81300",
+"h c #EB1700",
+"i c #E41600",
+"j c #E71600",
+"k c #B91200",
+"l c #B81200",
+"m c #EC1700",
+"n c #C61300",
+"o c #950E00",
+"p c #E01600",
+"q c #DB1500",
+"r c #9C0F00",
+"s c #AA1000",
+"t c #C01200",
+"u c #FA1800",
+"v c #E31600",
+"w c #DF1500",
+"x c #F91800",
+"y c #940E00",
+"z c #F31700",
+"A c #EF1700",
+"B c #D51400",
+"C c #B11100",
+"D c #890D00",
+"E c #A10F00",
+"F c #840C00",
+"G c #F11700",
+"H c #930E00",
+"I c #BE1200",
+"J c #FC1800",
+"K c #850D00",
+"L c #F51800",
+"M c #860D00",
+"N c #DD1500",
+"O c #A91000",
+"P c #EA1700",
+"Q c #E81600",
+"R c #FD1800",
+"S c #A61000",
+"T c #F41700",
+"U c #E11600",
+"V c #B41100",
+"W c #A00F00",
+"X c #D91500",
+"Y c #F21700",
+"Z c #C91300",
+"` c #960E00",
+" . c #CF1400",
+".. c #980E00",
+"+. c #D41400",
+"@. c #820C00",
+"#. c #A20F00",
+"$. c #D61400",
+"%. c #BF1200",
+"&. c #830C00",
+"*. c #9A0F00",
+"=. c #D01400",
+"-. c #A71000",
+";. c #CA1300",
+">. c #B51100",
+",. c #EA1600",
+"'. c #E21600",
+"). c #E91600",
+"!. c #A81000",
+"~. c #B01100",
+"{. c #F41800",
+"]. c #8E0E00",
+"^. c #CB1300",
+"/. c #ED1700",
+"(. c #D81500",
+"_. c #C51300",
+":. c #AD1100",
+"<. c #BD1200",
+"[. c #CE1400",
+"}. c #C21300",
+"|. c #910E00",
+"1. c #C41300",
+" ",
+" $ { ",
+" $ $ ",
+" $ $ ",
+" $ $ ",
+" $ $ $ $ ",
+"$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ",
+" $ $ $ $ $ $ $ $ $ $ $ $ ",
+" $ $ $ $ $ $ $ $ $ $ ",
+" $ $ $ $ $ $ $ $ ",
+" $ $ $ $ $ $ ",
+" $ $ $ $ $ $ $ $ ",
+" $ $ $ $ $ $ $ ",
+" $ $ $ $ ",
+" $ $ $ ",
+" $ $ "};
diff --git a/navit/xpm/bank.xpm b/navit/xpm/bank.xpm
new file mode 100644
index 000000000..cb21ffdb0
--- /dev/null
+++ b/navit/xpm/bank.xpm
@@ -0,0 +1,76 @@
+/* XPM */
+static char *dummy[]={
+"16 16 57 1",
+". c None",
+"X c #000000",
+"z c #010101",
+"T c #030303",
+"k c #060606",
+"w c #0a0a0a",
+"H c #0b0b0b",
+"o c #0d0d0d",
+"n c #0e0e0e",
+"q c #141414",
+"Y c #151515",
+"l c #1a1a1a",
+"G c #1b1b1b",
+"m c #202020",
+"A c #272727",
+"W c #2b2b2b",
+"F c #414141",
+"L c #434343",
+"j c #454545",
+"u c #474747",
+"y c #4d4d4d",
+"t c #4f4f4f",
+"M c #545454",
+"J c #5f5f5f",
+"E c #606060",
+"e c #626262",
+"N c #696969",
+"f c #6f6f6f",
+"B c #727272",
+"v c #787878",
+"0 c #7a7a7a",
+"p c #7c7c7c",
+"Z c #888888",
+"x c #8a8a8a",
+"Q c #8b8b8b",
+"2 c #8e8e8e",
+"b c #8f8f8f",
+"O c #929292",
+"S c #949494",
+"R c #999999",
+"V c #9e9e9e",
+"U c #9f9f9f",
+"c c #a9a9a9",
+"s c #b4b4b4",
+"g c #c3c3c3",
+"I c #cbcbcb",
+"d c #d5d5d5",
+"C c #dcdcdc",
+"D c #dddddd",
+"P c #dedede",
+"# c #e7e7e7",
+"a c #ececec",
+"i c #f1f1f1",
+"h c #f5f5f5",
+"r c #fbfbfb",
+"1 c #fdfdfd",
+"K c #fefefe",
+"................",
+".......#a.......",
+".......bc.......",
+"......defgh.....",
+"....ijklmno.....",
+"....pq.bcrs.....",
+"....tu.bc.......",
+"....vw.xc.......",
+"....iyzzABC.....",
+"......DEFGHI....",
+".......bc.mJ....",
+"....K..bc.LM....",
+"....NOPQRSTU....",
+"....VWzzXYZK....",
+"......i0R1......",
+".......2c......."};
diff --git a/navit/xpm/bar.xpm b/navit/xpm/bar.xpm
new file mode 100644
index 000000000..c4da0cc26
--- /dev/null
+++ b/navit/xpm/bar.xpm
@@ -0,0 +1,52 @@
+/* XPM */
+static char * bar_xpm[] = {
+"14 16 33 1",
+" c None",
+". c #FFFFFF",
+"+ c #F3F5F9",
+"@ c #AAC0EC",
+"# c #99B4E9",
+"$ c #97B2E9",
+"% c #ACC2ED",
+"& c #F5F8FD",
+"* c #B3C6EB",
+"= c #3869CF",
+"- c #2D63D3",
+"; c #2F65D3",
+"> c #B0C2E8",
+", c #F7F7F7",
+"' c #8FA1C4",
+") c #3D6ED1",
+"! c #3166D3",
+"~ c #3368D4",
+"{ c #3066D3",
+"] c #4172D5",
+"^ c #AFC0E4",
+"/ c #FBFBFB",
+"( c #B9CBEE",
+"_ c #4374D7",
+": c #BACCF0",
+"< c #4474D7",
+"[ c #B8CAEE",
+"} c #8CAAE6",
+"| c #95B0E8",
+"1 c #BDC8DF",
+"2 c #688FDF",
+"3 c #B0BBD2",
+"4 c #F4F4F3",
+" ............ ",
+"+@#########$%&",
+".*=-;;;;;;;=>.",
+" ,')!~~~~{]^/ ",
+" ,(_;~~{):. ",
+" .(]{{]*. ",
+" .(<<[. ",
+" .}}. ",
+" .$|. ",
+" .||. ",
+" .||. ",
+" .||. ",
+" .||. ",
+" .||. ",
+" .||. ",
+" ,12234 "};
diff --git a/navit/xpm/bus.xpm b/navit/xpm/bus.xpm
new file mode 100644
index 000000000..ec7460d41
--- /dev/null
+++ b/navit/xpm/bus.xpm
@@ -0,0 +1,165 @@
+/* XPM */
+static char *bus[] = {
+/* columns rows colors chars-per-pixel */
+"30 12 147 2",
+" c #0C0C0C",
+". c #0E0E0E",
+"X c #101010",
+"o c gray8",
+"O c #161616",
+"+ c gray10",
+"@ c #1D1D1D",
+"# c #1E1E1E",
+"$ c gray14",
+"% c gray15",
+"& c gray17",
+"* c #323232",
+"= c gray21",
+"- c #3A3A3A",
+"; c #3B3C3C",
+": c gray27",
+"> c #464646",
+", c #565656",
+"< c #5B5B5B",
+"1 c #5D6262",
+"2 c #606060",
+"3 c #6B6D6D",
+"4 c #6E7777",
+"5 c #008080",
+"6 c #018080",
+"7 c #018181",
+"8 c #028181",
+"9 c #038181",
+"0 c #038282",
+"q c #048282",
+"w c #058282",
+"e c #068383",
+"r c #078383",
+"t c #088484",
+"y c #0A8585",
+"u c #0B8686",
+"i c #0C8686",
+"p c #0D8686",
+"a c #0F8787",
+"s c #108888",
+"d c #148A8A",
+"f c #158A8A",
+"g c #168A8A",
+"h c #178B8B",
+"j c #188C8C",
+"k c #198C8C",
+"l c #1A8D8D",
+"z c #1B8D8D",
+"x c #1C8D8D",
+"c c #1E8E8E",
+"v c #1E8F8F",
+"b c #1F8F8F",
+"n c #208F8F",
+"m c #219090",
+"M c #229191",
+"N c #259191",
+"B c #279393",
+"V c #289393",
+"C c #299494",
+"Z c #2B9595",
+"A c #2C9595",
+"S c #329999",
+"D c #359A9A",
+"F c #379A9A",
+"G c #389B9B",
+"H c #3A9898",
+"J c #3B9D9D",
+"K c #3F9898",
+"L c #3C9D9D",
+"P c #3D9E9E",
+"I c #3F9F9F",
+"U c #469494",
+"Y c #469797",
+"T c #4E9494",
+"R c #549393",
+"E c #579393",
+"W c #42A0A0",
+"Q c #43A0A0",
+"! c #43A1A1",
+"~ c #44A0A0",
+"^ c #46A2A2",
+"/ c #4AA4A4",
+"( c #4BA5A5",
+") c #4CA5A5",
+"_ c #4EA6A6",
+"` c #57A3A3",
+"' c #52A8A8",
+"] c #59ACAC",
+"[ c #5AACAC",
+"{ c #5FAEAE",
+"} c #62A7A7",
+"| c #64B1B1",
+" . c #66B2B2",
+".. c #7EAAAA",
+"X. c #77BABA",
+"o. c #7BBCBC",
+"O. c #7DBEBE",
+"+. c #7EBEBE",
+"@. c gray51",
+"#. c #868686",
+"$. c gray53",
+"%. c gray54",
+"&. c #8D8D8D",
+"*. c #889A9A",
+"=. c #9F9F9F",
+"-. c #86A0A0",
+";. c #80ABAB",
+":. c gray72",
+">. c #B8BBBB",
+",. c #8CC4C4",
+"<. c #8FC6C6",
+"1. c #9CCCCC",
+"2. c #A0CECE",
+"3. c #A3D0D0",
+"4. c #A5D1D1",
+"5. c #A6D2D2",
+"6. c #A8D2D2",
+"7. c #AED5D5",
+"8. c #AFD6D6",
+"9. c #B0D7D7",
+"0. c #B1D7D7",
+"q. c #B8DADA",
+"w. c #B9DBDB",
+"e. c #BFDEDE",
+"r. c #C3C3C3",
+"t. c gray81",
+"y. c #C0DFDF",
+"u. c #D7DDDD",
+"i. c #C6E1E1",
+"p. c #C9E3E3",
+"a. c #D0E6E6",
+"s. c #D6E9E9",
+"d. c #D7EAEA",
+"f. c #DBE7E7",
+"g. c #D8EAEA",
+"h. c #DBECEC",
+"j. c #DDECEC",
+"k. c #E4E4E4",
+"l. c #E1EEEE",
+"z. c #E6F1F1",
+"x. c #EAF3F3",
+"c. c #EEF5F5",
+"v. c gray94",
+"b. c #F0F6F6",
+"n. c #F6F9F9",
+"m. c #F9FAFA",
+"M. c gray99",
+/* pixels */
+"b.^ h h j d j h h d j j d d d d j d d d j d d d j d j d h _ ",
+"a.l j Y ! Y W u Z Y ! Y D e P ! ! Y M u ^ Y W G t G ! Y N 8.",
+"w.s ' m.m.m.b.n 5.m.m.m.9.d l.m.M.M. .Z m.m.m.w.v e.m.n.[ e.",
+"9.u O.M.M.M.s.h p.M.M.M.<.v z.M.M.M.] Y M.M.M.5.M p.M.x.P 2.",
+"3.u X.e.e.e.<.h 1.e.e.e. .v 9.e.e.e.P / e.e.e.o.v 2.e.2.b +.",
+",.0 e t t t r 7 r e u r t 0 t t u r 7 e e u e e 0 t u e 7 _ ",
+"{ 7 7 7 7 7 5 5 7 5 5 5 5 5 7 7 5 5 5 5 5 5 7 7 7 7 7 5 7 S ",
+"J s K R T H 7 7 5 5 5 5 5 5 7 7 5 5 7 N U E Y l 7 7 7 7 5 V ",
+"Z } 1 X # 4 _ 5 5 5 7 5 5 5 5 5 7 7 M -.& ; ..p 5 5 5 7 M ",
+"P *.. :.%.+ ..n l l l l h l l h j j ` > , r.= 3 Y l l l l V ",
+"h.:.o @.2 $ u.g.g.g.s.g.s.s.s.s.s.s.g.< - &.% #.l.d.s.s.s.s.",
+"M.v.#.# * =.M.M.M.M.M.M.M.M.M.M.M.M.M.t.> O < k.M.M.M.M.M.M."
+};
diff --git a/navit/xpm/cafe.xpm b/navit/xpm/cafe.xpm
new file mode 100644
index 000000000..a61aebc14
--- /dev/null
+++ b/navit/xpm/cafe.xpm
@@ -0,0 +1,25 @@
+/* XPM */
+static char * cafe_xpm[] = {
+"16 16 6 1",
+" c None",
+". c #FFFFFF",
+"+ c #0000FF",
+"@ c #FEFEFE",
+"# c #000000",
+"$ c #808080",
+" .............. ",
+".++++++++++++++.",
+".++++++++++++++.",
+".++@@@@@@@@@@++.",
+".++@@.####.@@++.",
+".++@##....##@++.",
+".++@#######$#++.",
+".++@#######$#++.",
+".++@########@++.",
+".++@.######.@++.",
+".++#..####.@#++.",
+".++@########@++.",
+".++@@@@@@@@@@++.",
+".++++++++++++++.",
+".++++++++++++++.",
+" .............. "};
diff --git a/navit/xpm/camping.xpm b/navit/xpm/camping.xpm
new file mode 100644
index 000000000..86ff7d466
--- /dev/null
+++ b/navit/xpm/camping.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static char *camping[]={
+"16 16 5 1",
+". c None",
+"b c #000000",
+"a c #0000ff",
+"c c #c6c6c6",
+"# c #ffffff",
+".##############.",
+"#aaaaaaaaaaaaaa#",
+"#aaaaaaaaaaaaaa#",
+"#aa####bb####aa#",
+"#aa###cbbc###aa#",
+"#aa###b##b###aa#",
+"#aa##cb##bc##aa#",
+"#aa##bc##cb##aa#",
+"#aa#cb#bb#bc#aa#",
+"#aa#bccbbccb#aa#",
+"#aacb#bbbb#bcaa#",
+"#aabbbbbbbbbbaa#",
+"#aa##########aa#",
+"#aaaaaaaaaaaaaa#",
+"#aaaaaaaaaaaaaa#",
+".##############."};
diff --git a/navit/xpm/car_dealer.xpm b/navit/xpm/car_dealer.xpm
new file mode 100644
index 000000000..892f10b26
--- /dev/null
+++ b/navit/xpm/car_dealer.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static char *car_dealer[]={
+"16 16 7 1",
+". c None",
+"c c #000000",
+"a c #0000ff",
+"b c #7f7f7f",
+"d c #bfbfbf",
+"e c #f6f6fa",
+"# c #ffffff",
+".##############.",
+"#aaaaaaaaaaaaaa#",
+"#a############a#",
+"#a####bccb####a#",
+"#a##dccccccd##a#",
+"#a#####cc#####a#",
+"#a##dccccccd##a#",
+"#a####bccbe###a#",
+"#a#####cc#####a#",
+"#a####dccd####a#",
+"#a####dccd####a#",
+"#a####bccb####a#",
+"#a####bccb####a#",
+"#a############a#",
+"#aaaaaaaaaaaaaa#",
+".##############."};
diff --git a/navit/xpm/church.xpm b/navit/xpm/church.xpm
new file mode 100644
index 000000000..6f6b609be
--- /dev/null
+++ b/navit/xpm/church.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static char *church[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 4 1",
+" c black",
+". c #2F2F2F",
+"X c #B1B1B1",
+"o c gray100",
+/* pixels */
+"ooooooo..ooooooo",
+"ooooooo..ooooooo",
+"ooooooo..ooooooo",
+"oooo...XX...oooo",
+"oooo...XX...oooo",
+"ooooooo..ooooooo",
+"ooooooo..ooooooo",
+"ooooooo..ooooooo",
+"oooo oooo",
+"oooo oooo",
+"oooo oooo",
+"oooo oooo",
+"oooo oooo",
+"oooo oooo",
+"oooo oooo",
+"oooo oooo"
+};
diff --git a/navit/xpm/cinema.xpm b/navit/xpm/cinema.xpm
new file mode 100644
index 000000000..f926d155d
--- /dev/null
+++ b/navit/xpm/cinema.xpm
@@ -0,0 +1,116 @@
+/* XPM */
+static char * cinema_xpm[] = {
+"12 16 97 2",
+" c None",
+". c #FFFFFF",
+"+ c #F6F6F6",
+"@ c #D1D1D1",
+"# c #F8F8F8",
+"$ c #CCE9F1",
+"% c #AADBE7",
+"& c #78C5D9",
+"* c #67A1AF",
+"= c #696969",
+"- c #DDDDDD",
+"; c #707070",
+"> c #7B8E93",
+", c #4299AF",
+"' c #5F8F9B",
+") c #466D76",
+"! c #525252",
+"~ c #0E0E0E",
+"{ c #B3B3B3",
+"] c #FDFDFD",
+"^ c #7C7C7C",
+"/ c #2F2F2F",
+"( c #2D2D2D",
+"_ c #111111",
+": c #101010",
+"< c #2B2B2B",
+"[ c #303030",
+"} c #989898",
+"| c #212121",
+"1 c #6B7F83",
+"2 c #679CAA",
+"3 c #6AB3C5",
+"4 c #4BB1CA",
+"5 c #2CA5C3",
+"6 c #757575",
+"7 c #646464",
+"8 c #FCFCFC",
+"9 c #606060",
+"0 c #3E9FB7",
+"a c #66797E",
+"b c #DCDCDC",
+"c c #0D0D0D",
+"d c #72A3AF",
+"e c #3CABC7",
+"f c #69909A",
+"g c #ECECEC",
+"h c #F3F3F3",
+"i c #666666",
+"j c #739097",
+"k c #60A8BA",
+"l c #7C9EA6",
+"m c #5A7278",
+"n c #404648",
+"o c #282828",
+"p c #0A0A0A",
+"q c #CCCCCC",
+"r c #3B3B3B",
+"s c #161616",
+"t c #333333",
+"u c #384B50",
+"v c #5C5C5C",
+"w c #AEAEAE",
+"x c #464646",
+"y c #6C9CA8",
+"z c #69ACBD",
+"A c #4BACC4",
+"B c #34A8C5",
+"C c #A6A6A6",
+"D c #78C1D3",
+"E c #576F75",
+"F c #858585",
+"G c #C5C5C5",
+"H c #414141",
+"I c #5FA8BA",
+"J c #7D959B",
+"K c #EAEAEA",
+"L c #E4E4E4",
+"M c #658B95",
+"N c #70AAB9",
+"O c #588894",
+"P c #707A7C",
+"Q c #4C4C4C",
+"R c #1E1E1E",
+"S c #4E4E4E",
+"T c #191919",
+"U c #345158",
+"V c #3A6B77",
+"W c #AAAAAA",
+"X c #828282",
+"Y c #585858",
+"Z c #619BAA",
+"` c #79BDCE",
+" . c #56B7CF",
+".. c #89CDDD",
+"+. c #BDBDBD",
+"@. c #DAEEF2",
+"#. c #EEF8FA",
+" . . . + @ # ",
+" . . . $ % & * = - . ",
+"# ; > , , ' ) ! ~ { . ",
+"] ^ / ( _ : < ! [ } . ",
+". > | 1 2 3 4 5 6 7 . ",
+"8 { 9 0 5 5 5 5 a ( . ",
+"8 b c d 5 5 5 e f 7 g . ",
+" h i j k l m n o p q . ",
+" . r ~ p s t u m v w . ",
+" . 6 x y z A B 4 n = . ",
+" . C x D 5 5 5 5 E F # ",
+" . G H I 5 5 5 5 J < K ",
+" . L r M N O P Q R S @ ",
+" . + r T : _ / U V o W ",
+" . X Y Z ` ...% +.K ",
+" . W } @.#.. . . . . "};
diff --git a/navit/xpm/cursor.xpm b/navit/xpm/cursor.xpm
new file mode 100644
index 000000000..efa2690b1
--- /dev/null
+++ b/navit/xpm/cursor.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char * cursor[] = {
+"22 22 2 1",
+" c None",
+". c #0000FF",
+" ",
+" ",
+" ",
+" .. ",
+" .. .. ",
+" .. .. ",
+" . . ",
+" . . ",
+" . ... . ",
+" . ... . . ",
+" . ... . . ",
+" . .. . . ",
+" . . . ",
+" . . . ",
+" . . . ",
+" . . . ",
+" .. .. ",
+" .. .. ",
+" .. ",
+" ",
+" ",
+" "};
+
diff --git a/navit/xpm/dumping-station.xpm b/navit/xpm/dumping-station.xpm
new file mode 100644
index 000000000..c58d14247
--- /dev/null
+++ b/navit/xpm/dumping-station.xpm
@@ -0,0 +1,112 @@
+/* XPM */
+static char * dumping_station_xpm[] = {
+"16 16 93 2",
+" c #899EBF",
+". c #5170A1",
+"+ c #516FA2",
+"@ c #526FA1",
+"# c #748CB4",
+"$ c #516FA1",
+"% c #5270A1",
+"& c #AEBBD1",
+"* c #5C78A6",
+"= c #325692",
+"- c #5572A3",
+"; c #FBFCFD",
+"> c #FFFFFF",
+", c #FEFEFE",
+"' c #F8F9FB",
+") c #EEF1F6",
+"! c #DFE4EE",
+"~ c #E3E7EF",
+"{ c #F1F3F7",
+"] c #506EA0",
+"^ c #899BBD",
+"/ c #8399BD",
+"( c #A9B9D1",
+"_ c #C1CCDC",
+": c #BDC9D9",
+"< c #8DA0C1",
+"[ c #8196BA",
+"} c #8498BC",
+"| c #6D86B0",
+"1 c #315693",
+"2 c #889CBE",
+"3 c #325593",
+"4 c #F8F9FA",
+"5 c #46679B",
+"6 c #879CBC",
+"7 c #9EAEC8",
+"8 c #47669B",
+"9 c #DCE2E9",
+"0 c #FFFFFE",
+"a c #FFFEFE",
+"b c #FDFEFE",
+"c c #FEFFFD",
+"d c #748DB6",
+"e c #DDE2EC",
+"f c #CFD6E3",
+"g c #B8C4D6",
+"h c #F9FAFC",
+"i c #325691",
+"j c #DAE0EB",
+"k c #FBFBFC",
+"l c #D2DBE5",
+"m c #C9D3E0",
+"n c #C3CDDC",
+"o c #F3F5F8",
+"p c #E1E6EE",
+"q c #9FAEC7",
+"r c #CCD5E1",
+"s c #CBD4E1",
+"t c #CAD3E0",
+"u c #5876A5",
+"v c #6D86AD",
+"w c #48679C",
+"x c #6F88B0",
+"y c #6983AC",
+"z c #49679C",
+"A c #E8ECF2",
+"B c #D6DEE8",
+"C c #4D6B9E",
+"D c #647DA9",
+"E c #5572A2",
+"F c #49679B",
+"G c #94A6C4",
+"H c #9CACC8",
+"I c #A0B0CA",
+"J c #D5DCE7",
+"K c #CAD3E1",
+"L c #BDC7DA",
+"M c #BDC8DA",
+"N c #DCE2EA",
+"O c #FFFEFF",
+"P c #5F7AA7",
+"Q c #AAB9D0",
+"R c #A1B2CD",
+"S c #7A91B5",
+"T c #375994",
+"U c #335792",
+"V c #FEFFFE",
+"W c #7990B5",
+"X c #AEBCD1",
+"Y c #98AAC5",
+"Z c #BCC7D8",
+"` c #FAFAFA",
+" . c #F3F3F3",
+" . + @ # @ @ + @ $ @ @ % % % & ",
+"* = = - ; > , ' > ) ! ~ { ] = ^ ",
+"* = = / ; ( _ > : < [ } > | 1 2 ",
+"* = 3 } 4 5 6 > 7 8 5 5 9 | 1 2 ",
+"* = 3 } 0 a b > , a a , c | 1 2 ",
+"* = d e > > > f g h > > c | 1 2 ",
+"* i j k l m n o p q r s t u 1 2 ",
+"v w x y z w z A B C D E z z F G ",
+"> > > > > > > > > > H I > > > > ",
+"> > > > > > > J K K L M K K N O ",
+"> > > > > > > P i i Q R = i S 0 ",
+"> > > > > > > P = = T U = = S V ",
+"> > > > > > > P = = = = = = W V ",
+"> > > > > > > X Y Y Y Y Y Y Z 0 ",
+"> > > > > > > V V V V V V V > > ",
+"` > > > > > > > > > > > > > > ."};
diff --git a/navit/xpm/exit.xpm b/navit/xpm/exit.xpm
new file mode 100644
index 000000000..81491a0f3
--- /dev/null
+++ b/navit/xpm/exit.xpm
@@ -0,0 +1,78 @@
+/* XPM */
+static char * exit_xpm[] = {
+"16 16 59 1",
+" c None",
+". c #4F4FD1",
+"+ c #9292E2",
+"@ c #CCCCF2",
+"# c #0000BC",
+"$ c #0A0AB9",
+"% c #2E2EC2",
+"& c #1E1EBD",
+"* c #2424C2",
+"= c #1010BE",
+"- c #3030C5",
+"; c #1C1CBD",
+"> c #7D7DD8",
+", c #F9F9F9",
+"' c #BABAEA",
+") c #E0E0E8",
+"! c #2020C4",
+"~ c #D7D7F0",
+"{ c #FBFBFB",
+"] c #8B8BD9",
+"^ c #BEBEE7",
+"/ c #FFFFFF",
+"( c #C2C2F2",
+"_ c #3C3CC0",
+": c #9C9CE3",
+"< c #DEDEEE",
+"[ c #F4F4FC",
+"} c #F7F7F7",
+"| c #2323C6",
+"1 c #1212C2",
+"2 c #C0C0F0",
+"3 c #F2F2FA",
+"4 c #F0F0F8",
+"5 c #2929C0",
+"6 c #6E6EDB",
+"7 c #B1B1E3",
+"8 c #5B5BD1",
+"9 c #8888D6",
+"0 c #0505BE",
+"a c #2020C6",
+"b c #9E9EE7",
+"c c #AEAEE4",
+"d c #6161D2",
+"e c #DBDBF4",
+"f c #AEAEE1",
+"g c #7272DB",
+"h c #2929C7",
+"i c #9F9FD2",
+"j c #A5A5DE",
+"k c #6161D5",
+"l c #E6E6FA",
+"m c #E9E9FA",
+"n c #8E8ED0",
+"o c #C6C6E6",
+"p c #0909BF",
+"q c #1616C3",
+"r c #1A1AC4",
+"s c #0E0EC0",
+"t c #0F0FC1",
+" .++++++++++++. ",
+".@############@.",
+"+##############+",
+"+###$%&*#=%%-;#+",
+"+###>,')#!~,{]#+",
+"+###^/(/_:<[}|#+",
+"+##1}/2/34567##+",
+"+##8//'//9#0a##+",
+"+##b//c//d#####+",
+"+##e//f//g#####+",
+"+#h///i//j#####+",
+"+#klmlnlmo#####+",
+"+#pqrqsqrt#####+",
+"+##############+",
+".@############@.",
+" .++++++++++++. "};
diff --git a/navit/xpm/fastfood.xpm b/navit/xpm/fastfood.xpm
new file mode 100644
index 000000000..033e6c9dc
--- /dev/null
+++ b/navit/xpm/fastfood.xpm
@@ -0,0 +1,188 @@
+/* XPM */
+static char *fastfood[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 166 2",
+" c black",
+". c #181614",
+"X c #1B1A18",
+"o c #251606",
+"O c #2E2B27",
+"+ c #3E3E3E",
+"@ c #4F351B",
+"# c #5F380F",
+"$ c #53371A",
+"% c #4D3E2E",
+"& c #443D35",
+"* c #5A3F23",
+"= c #49423A",
+"- c #4A4138",
+"; c #514232",
+": c #5C4C3B",
+"> c #5F503F",
+", c #714212",
+"< c #774917",
+"1 c #7D4F1E",
+"2 c #614528",
+"3 c #6E4B24",
+"4 c #604E3A",
+"5 c #694E31",
+"6 c #6D5134",
+"7 c #4C4843",
+"8 c #534D47",
+"9 c #5C5042",
+"0 c #5C5145",
+"q c #5F5244",
+"w c #5E5346",
+"e c #58534E",
+"r c #585858",
+"t c gray35",
+"y c #5A5A5A",
+"u c #5B5B5B",
+"i c #5D5A58",
+"p c gray37",
+"a c #605447",
+"s c #675A4C",
+"d c #605B55",
+"f c #625C57",
+"g c #675F56",
+"h c #745C43",
+"j c #715D48",
+"k c #676058",
+"l c #6E6051",
+"z c #6A655F",
+"x c #71675C",
+"c c #7E6851",
+"v c #626262",
+"b c #646464",
+"n c #676767",
+"m c #6E6862",
+"M c #686868",
+"N c #696968",
+"B c #6A6A6A",
+"V c #6C6C6C",
+"C c #6D6D6D",
+"Z c #6E6D6C",
+"A c #6F6E6D",
+"S c #746E67",
+"D c #706C69",
+"F c #706F6D",
+"G c #76716B",
+"H c #7B746D",
+"J c #727272",
+"K c gray46",
+"L c #777776",
+"P c #787877",
+"I c #7B7875",
+"U c gray48",
+"Y c #7C7C7C",
+"T c #8B5317",
+"R c #885219",
+"E c #965918",
+"W c #975A19",
+"Q c #815424",
+"! c #A5611A",
+"~ c #A6621B",
+"^ c #A7631B",
+"/ c #A9651C",
+"( c #85725D",
+") c #87725C",
+"_ c #8E7A65",
+"` c #807870",
+"' c #CF7B21",
+"] c #8E8274",
+"[ c #9A856F",
+"{ c #838383",
+"} c gray52",
+"| c #868686",
+" . c gray53",
+".. c #8B8681",
+"X. c #8A8885",
+"o. c #8B8B8B",
+"O. c #8E8C89",
+"+. c #8D8D8D",
+"@. c #8F8F8E",
+"#. c gray56",
+"$. c #92908D",
+"%. c #94908D",
+"&. c #909090",
+"*. c #919090",
+"=. c gray57",
+"-. c #939392",
+";. c gray58",
+":. c #989898",
+">. c gray60",
+",. c #9B9B9B",
+"<. c gray61",
+"1. c #9D9D9D",
+"2. c #9F9F9F",
+"3. c #A1A1A0",
+"4. c #A4A4A4",
+"5. c #A7A7A7",
+"6. c #A8A8A7",
+"7. c #AAA9A7",
+"8. c #A9A9A9",
+"9. c #AAAAAA",
+"0. c #AEAEAE",
+"q. c #AFAFAF",
+"w. c #B1B0AF",
+"e. c gray69",
+"r. c #B1B1B1",
+"t. c #B2B2B2",
+"y. c gray71",
+"u. c #B6B6B6",
+"i. c gray72",
+"p. c #BBBBBB",
+"a. c gray74",
+"s. c gray75",
+"d. c #C3BEB9",
+"f. c #C1C1C1",
+"g. c #C3C3C3",
+"h. c #C6C4C2",
+"j. c gray77",
+"k. c gray79",
+"l. c #CBCBCB",
+"z. c #CDCDCD",
+"x. c #CECECE",
+"c. c #D0D0D0",
+"v. c gray82",
+"b. c #D2D2D2",
+"n. c LightGray",
+"m. c gray83",
+"M. c #D5D5D5",
+"N. c gray84",
+"B. c #D7D7D7",
+"V. c #D8D8D8",
+"C. c gray85",
+"Z. c #DDDDDD",
+"A. c gray87",
+"S. c #DFDFDF",
+"D. c #E1DEDB",
+"F. c #E2E2E2",
+"G. c #E4E4E4",
+"H. c gray90",
+"J. c #E7E7E7",
+"K. c gray91",
+"L. c gray93",
+"P. c gray95",
+"I. c #F4F4F4",
+"U. c gray97",
+"Y. c gray100",
+"T. c None",
+/* pixels */
+"T.T.@ s 3 T.T.T.T.T.T.T.T.T.T.T.",
+"T.^ 1 g 4 < T.T.T.T.T.T.T.T.T.T.",
+"2 k l i = a = Q T.T.T.T.T.T.T.T.",
+"& C 5. .r ;.n O T.T.T.T.T.T.T.T.",
+"] r.>.o.&.2.f.0 T.T.T.T.T.T.T.T.",
+"[ I.Y.Y.Y.Y.A.5 f C F 7 * T.T.T.",
+"_ K.Y.Y.Y.P.M ` I 7.-.X.x > W T.",
+"8 w.c.l.y.M r.y.8.8.B.c.l.7.c T.",
+"% h.c.l.y.o.m.x.F.c.n.g.B.K.%.R ",
+"$ D.Y.Y.x.;.p.U.A.m.F.H.t.L.$.h ",
+", d.Y.Y.C C >.>.5.m.m.c.a.2.P z ",
+"^ H m.H.p r L >.o. . .J #.&.e 6 ",
+"' ..a.r.>.C r #.q.v + i P v i T ",
+"T.9 G 3.&.M w.2. . .#.v Y 2.a E ",
+"T.# o . X 0 O.@.r.f.f.i. .D : T.",
+"T.T.T.T.T.^ j ( S L C m ( ; T.T."
+};
diff --git a/navit/xpm/firebrigade.xpm b/navit/xpm/firebrigade.xpm
new file mode 100644
index 000000000..482f86c6f
--- /dev/null
+++ b/navit/xpm/firebrigade.xpm
@@ -0,0 +1,84 @@
+/* XPM */
+static char *dummy[]={
+"16 10 71 2",
+"Qt c None",
+".T c #0e101a",
+".S c #11111d",
+".R c #121220",
+".I c #141524",
+".Q c #151725",
+".A c #1a1d2c",
+".5 c #1b1c2b",
+".0 c #202439",
+".H c #222636",
+"#a c #262637",
+".8 c #2a2a41",
+".E c #313648",
+".B c #393a4d",
+".J c #3f4352",
+".F c #42475c",
+".G c #434658",
+".D c #454b5d",
+".P c #474856",
+".4 c #4b5265",
+".C c #4c5269",
+".W c #525664",
+".3 c #53535e",
+".e c #555586",
+".2 c #555765",
+".f c #565797",
+".a c #6060f6",
+".V c #646d7e",
+".1 c #666d82",
+".U c #6b707d",
+".r c #737585",
+".i c #7c7d88",
+".c c #82838d",
+"## c #868593",
+".d c #898992",
+".# c #8a8afd",
+".O c #8a90a3",
+".s c #9096a0",
+".k c #9799a5",
+".v c #99a0af",
+".K c #9eaab6",
+".m c #aaabb3",
+".9 c #ccccd5",
+".j c #d2d2d6",
+".u c #d6d6d9",
+".b c #d9dce3",
+"#b c #e0e0e2",
+".n c #ecedee",
+".w c #f0f0f3",
+".h c #f4f5f8",
+"#. c #fbfbfc",
+".N c #fe5558",
+".q c #fec4c7",
+".y c #ff0005",
+".Y c #ff050a",
+".z c #ff0a0f",
+".Z c #ff191e",
+"#d c #ff3d41",
+".M c #ff4246",
+".6 c #ff474b",
+".p c #ff5154",
+"#c c #ff676a",
+".7 c #ff6a6d",
+"#e c #ff8082",
+".x c #ffacae",
+".g c #ffd4d5",
+".X c #ffddde",
+".o c #ffe2e3",
+".L c #ffe9e9",
+".l c #fffbfb",
+".t c #ffffff",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt",
+"QtQtQtQt.#.aQtQtQtQtQtQtQtQtQtQt",
+"Qt.b.c.d.e.f.bQtQtQtQtQtQt.gQtQt",
+".h.i.j.j.k.l.m.nQtQtQtQt.o.p.qQt",
+".r.s.t.u.v.t.w.k.j.nQtQt.x.y.z.q",
+".A.B.C.D.E.F.G.H.I.J.K.L.M.y.y.N",
+".F.O.P.Q.R.S.T.T.U.V.W.X.Y.y.Y.Z",
+".B.0.1.2.2.2.3.2.4.5.sQt.Z.6.7.z",
+".i.8.9#.#.#.#.#.###a#bQt.p#c#d#e",
+"QtQtQtQtQtQtQtQtQtQtQtQtQtQtQtQt"};
diff --git a/navit/xpm/flag_bk_tr.xpm b/navit/xpm/flag_bk_tr.xpm
new file mode 100644
index 000000000..a115ecd3e
--- /dev/null
+++ b/navit/xpm/flag_bk_tr.xpm
@@ -0,0 +1,27 @@
+/* XPM */
+static char *flag_bk_tr[] = {
+"22 22 2 1 0 21",
+" c None",
+"+ c #000000",
+"+++++++ ",
+"+ +++++++++ ",
+"+ +++ +++++++++ ",
+"+ +++ +++ +++ ",
+"++++ +++ +++ ",
+"++++ +++ +++ ",
+"++++ +++ +++ + ",
+"+ ++++++ +++ + ",
+"+ +++ ++++++ + ",
+"+ +++ +++ +++ ",
+"++++ +++ +++ ",
+"++++ +++ +++ ",
+"++++++++++ +++ + ",
+"+ +++++++++ + ",
+"+ ++++++ ",
+"+ ",
+"+ ",
+"+ ",
+"+ ",
+"+ ",
+"+ ",
+"+ "};
diff --git a/navit/xpm/flag_bk_wh.xpm b/navit/xpm/flag_bk_wh.xpm
new file mode 100644
index 000000000..6b87fa8d0
--- /dev/null
+++ b/navit/xpm/flag_bk_wh.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char *flag_bk_wh[]={
+"22 22 3 1 0 21",
+" c None",
+"+ c #000000",
+"* c #ffffff",
+"+++++++ ",
+"+***+++++++++ ",
+"+***+++***+++++++++ ",
+"+***+++***+++***+++ ",
+"++++******+++***+++ ",
+"++++***+++******+++ ",
+"++++***+++***+++**+ ",
+"+***++++++***+++**+ ",
+"+***+++***++++++**+ ",
+"+***+++***+++***+++ ",
+"++++******+++***+++ ",
+"++++***+++******+++ ",
+"++++++++++***+++**+ ",
+"+ +++++++++**+ ",
+"+ ++++++ ",
+"+ ",
+"+ ",
+"+ ",
+"+ ",
+"+ ",
+"+ ",
+"+ "};
diff --git a/navit/xpm/flag_bl_wh.xpm b/navit/xpm/flag_bl_wh.xpm
new file mode 100644
index 000000000..7fa9856f7
--- /dev/null
+++ b/navit/xpm/flag_bl_wh.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char *flag_bl_wh[]={
+"22 22 3 1 0 21",
+" c None",
+"+ c #0000ff",
+"* c #ffffff",
+"+++++++ ",
+"+***+++++++++ ",
+"+***+++***+++++++++ ",
+"+***+++***+++***+++ ",
+"++++******+++***+++ ",
+"++++***+++******+++ ",
+"++++***+++***+++**+ ",
+"+***++++++***+++**+ ",
+"+***+++***++++++**+ ",
+"+***+++***+++***+++ ",
+"++++******+++***+++ ",
+"++++***+++******+++ ",
+"++++++++++***+++**+ ",
+"+ +++++++++**+ ",
+"+ ++++++ ",
+"+ ",
+"+ ",
+"+ ",
+"+ ",
+"+ ",
+"+ ",
+"+ "};
diff --git a/navit/xpm/flag_wh_bk.xpm b/navit/xpm/flag_wh_bk.xpm
new file mode 100644
index 000000000..4564f8ffb
--- /dev/null
+++ b/navit/xpm/flag_wh_bk.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static char *flag_bk_wh[]={
+"22 22 3 1 0 21",
+" c None",
+"+ c #ffffff",
+"* c #000000",
+"+++++++ ",
+"+***+++++++++ ",
+"+***+++***+++++++++ ",
+"+***+++***+++***+++ ",
+"++++******+++***+++ ",
+"++++***+++******+++ ",
+"++++***+++***+++**+ ",
+"+***++++++***+++**+ ",
+"+***+++***++++++**+ ",
+"+***+++***+++***+++ ",
+"++++******+++***+++ ",
+"++++***+++******+++ ",
+"++++++++++***+++**+ ",
+"+ +++++++++**+ ",
+"+ ++++++ ",
+"+ ",
+"+ ",
+"+ ",
+"+ ",
+"+ ",
+"+ ",
+"+ "};
diff --git a/navit/xpm/fuel.xpm b/navit/xpm/fuel.xpm
new file mode 100644
index 000000000..7b9f5f842
--- /dev/null
+++ b/navit/xpm/fuel.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static char *fuel[]={
+"16 16 7 1",
+". c None",
+"d c #000000",
+"a c #0000ff",
+"c c #7f7f7f",
+"e c #d1d2d3",
+"b c #fefefe",
+"# c #ffffff",
+".##############.",
+"#aaaaaaaaaaaaaa#",
+"#aaaaaaaaaaaaaa#",
+"#aabbbbbbbbbbaa#",
+"#aabbbcdddcbbaa#",
+"#aabbed#bbdbbaa#",
+"#aabbed#bbdbbaa#",
+"#aabbccddddbbaa#",
+"#aabbccddddbbaa#",
+"#aabeecddddbbaa#",
+"#aabcecddddbbaa#",
+"#aabccedddcbbaa#",
+"#aabbbbbbbbbbaa#",
+"#aaaaaaaaaaaaaa#",
+"#aaaaaaaaaaaaaa#",
+".##############."};
diff --git a/navit/xpm/gc_event.xpm b/navit/xpm/gc_event.xpm
new file mode 100644
index 000000000..cdcb2daa9
--- /dev/null
+++ b/navit/xpm/gc_event.xpm
@@ -0,0 +1,41 @@
+/* XPM */
+static char *gc_event[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 19 1",
+" c #393000",
+". c #393041",
+"X c #396541",
+"o c #7B3041",
+"O c #7B6541",
+"+ c #7B008B",
+"@ c #7B308B",
+"# c #7B658B",
+"$ c #399541",
+"% c #7B9541",
+"& c #7B958B",
+"* c none",
+"= c #BD9541",
+"- c #838383",
+"; c #BD95B4",
+": c #BDCAB4",
+"> c #FFCA8B",
+", c #C5C5C5",
+"< c gray100",
+/* pixels */
+"****************",
+"****************",
+"*****+$&&%o*****",
+"***$O>>>>>>=.***",
+"** >><<<<<<<>X**",
+"*X><<,,,,,,,<<.*",
+"*%><<--;;;;;<<:-",
+"*%><<<<,,,,,<<<+",
+"*%><<<<----;<<:-",
+"*o:<<<<<<<<<<< *",
+"** ,<<<<<<<<< **",
+"***#X;<<<<<<X***",
+"*****-+%&o&%****",
+"**********X@****",
+"**********+*****",
+"****************"
+};
diff --git a/navit/xpm/gc_multi.xpm b/navit/xpm/gc_multi.xpm
new file mode 100644
index 000000000..e81a8c472
--- /dev/null
+++ b/navit/xpm/gc_multi.xpm
@@ -0,0 +1,50 @@
+/* XPM */
+static char *gc_multi[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 28 1",
+" c black",
+". c #003000",
+"X c #393000",
+"o c #390041",
+"O c #393041",
+"+ c #396500",
+"@ c #396541",
+"# c #7B3000",
+"$ c #7B0041",
+"% c #7B6500",
+"& c #414141",
+"* c #7B008B",
+"= c #7B308B",
+"- c #7B658B",
+"; c #7B9500",
+": c #7B9541",
+"> c #7B958B",
+", c #7B95B4",
+"< c #FF3000",
+"1 c none",
+"2 c #BD9500",
+"3 c #BDCA00",
+"4 c #FF9500",
+"5 c #FFCA00",
+"6 c yellow",
+"7 c #838383",
+"8 c #BDCAB4",
+"9 c gray100",
+/* pixels */
+"1111111111111111",
+"1111111111111111",
+"1111=;######%..1",
+"11- %2222222;3+1",
+"117;%%%%%%%;X:*1",
+"111@99&2456X 9*1",
+"111O-%4<4;;& 9$1",
+"11-;4<4;;;,9 @11",
+"1.#222X;-999o111",
+"1+;%%; 9999@1111",
+"1OX%X9&99>@11111",
+"1.9899&9X>111111",
+"1=:>:>X=11111111",
+"1111111111111111",
+"1111111111111111",
+"1111111111111111"
+};
diff --git a/navit/xpm/gc_mystery.xpm b/navit/xpm/gc_mystery.xpm
new file mode 100644
index 000000000..7857292ae
--- /dev/null
+++ b/navit/xpm/gc_mystery.xpm
@@ -0,0 +1,40 @@
+/* XPM */
+static char *gc_mystery[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 18 1",
+" c black",
+". c #000041",
+"X c #003041",
+"o c #396500",
+"O c #7B0041",
+"+ c #414141",
+"@ c #00308B",
+"# c #0030B4",
+"$ c #7B008B",
+"% c #7B658B",
+"& c #399500",
+"* c #009541",
+"= c #0095B4",
+"- c #7B95B4",
+"; c none",
+": c #838383",
+"> c #BD95B4",
+", c #C5C5C5",
+/* pixels */
+";;;;;;;;;;;;;;;;",
+";;;;;:$$O:;;;;;;",
+";;;;+X###%o;;;;;",
+";;;:@#XX@#-o;;;;",
+";;;*#X,;:@#-;;;;",
+";;;*#%O;;X#%;;;;",
+";;;>X#%,;X#&;;;;",
+";;;;>*$;*#o;;;;;",
+";;;;;;;+X+;;;;;;",
+";;;;;;,X$;;;;;;;",
+";;;;;;$ :;;;;;;;",
+";;;;;;,+,;;;;;;;",
+";;;;;:.#+:;;;;;;",
+";;;;;:X=+:;;;;;;",
+";;;;;;:$:;;;;;;;",
+";;;;;;;;;;;;;;;;"
+};
diff --git a/navit/xpm/gc_question.xpm b/navit/xpm/gc_question.xpm
new file mode 100644
index 000000000..14186d50f
--- /dev/null
+++ b/navit/xpm/gc_question.xpm
@@ -0,0 +1,25 @@
+/* XPM */
+static char *gc_question[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 3 1",
+" c black",
+". c none",
+"X c gray100",
+/* pixels */
+".....XXXX.......",
+"....XX XX......",
+"....X X......",
+"....X X......",
+".XXXXX XXXX....",
+"X X....",
+"X XXX..",
+"X XX X X.",
+".X..X X",
+".X..X X",
+"X XX X X.",
+"X XXX..",
+"X XX X....",
+"X X..X X....",
+"X XX X....",
+".XXXXX..XXX....."
+};
diff --git a/navit/xpm/gc_reference.xpm b/navit/xpm/gc_reference.xpm
new file mode 100644
index 000000000..8f559a3bd
--- /dev/null
+++ b/navit/xpm/gc_reference.xpm
@@ -0,0 +1,40 @@
+/* XPM */
+static char *gc_reference[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 18 1",
+" c #00656A",
+". c #00658B",
+"X c #39658B",
+"o c #39958B",
+"O c #3995B4",
+"+ c #7B958B",
+"@ c #7B95B4",
+"# c #7BCAB4",
+"$ c #7BCAD5",
+"% c none",
+"& c #B4B4B4",
+"* c #BDCAD5",
+"= c #BDCAFF",
+"- c #C5C5C5",
+"; c #D5D5D5",
+": c #FFFFD5",
+"> c #E6E6E6",
+", c gray100",
+/* pixels */
+"%%%%%%%%%%%%%%%%",
+"%%%%%**&$*;%%%%%",
+"%%%%@#*=;-#@%%%%",
+"%%%@*,>,>,>*@%%%",
+"%%@*,,,,,,>>*%%%",
+"%*#,,,>$*>,,>@;%",
+"%&*,,*o. O>,>**%",
+"%$>,>@.X..*,,;$%",
+"%&>,>@ .X $,,;*%",
+"%$*,:*X..o>,,*$%",
+"%*#,,;*@@;,,>#*%",
+"%%@*,,>>,,,,*@%%",
+"%%%@*,,,,,,*+%%%",
+"%%%%@#*>>*#@%%%%",
+"%%%%%*&&$&*%%%%%",
+"%%%%%%%%%%%%%%%%"
+};
diff --git a/navit/xpm/gc_stages.xpm b/navit/xpm/gc_stages.xpm
new file mode 100644
index 000000000..a9b14e93b
--- /dev/null
+++ b/navit/xpm/gc_stages.xpm
@@ -0,0 +1,45 @@
+/* XPM */
+static char *gc_stages[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 23 1",
+" c black",
+". c #802000",
+"X c #804000",
+"o c #A04000",
+"O c #A06000",
+"+ c #804040",
+"@ c #806040",
+"# c #A06040",
+"$ c #C06040",
+"% c #A08040",
+"& c #C08040",
+"* c #808080",
+"= c #A08080",
+"- c #A0A0A4",
+"; c #C08080",
+": c #C0A080",
+"> c #E0A080",
+", c #C0A0C0",
+"< c #C0C080",
+"1 c #C0C0C0",
+"2 c #C0DCC0",
+"3 c #FFFBF0",
+"4 c gray100",
+/* pixels */
+" ",
+" 41-:3444434434 ",
+" 3#..#244444444 ",
+" 1X.X.;43444344 ",
+" 1X.X.%4442:=14 ",
+" 3@.oX%433#..@3 ",
+" 4:Xo##34-.X..1 ",
+" 43&#&:33:..XX1 ",
+" 442<33,31XXoX1 ",
+" 3441+X#42#OX$3 ",
+" 4443=&:33&&&>3 ",
+" 44433334333434 ",
+" 44434444,++*34 ",
+" 444444431%#:44 ",
+" 44444443332334 ",
+" "
+};
diff --git a/navit/xpm/gc_tradi.xpm b/navit/xpm/gc_tradi.xpm
new file mode 100644
index 000000000..ee4ced7a7
--- /dev/null
+++ b/navit/xpm/gc_tradi.xpm
@@ -0,0 +1,41 @@
+/* XPM */
+static char *gc_tradi[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 19 1",
+" c black",
+". c #003000",
+"X c #393000",
+"o c #393041",
+"O c #396500",
+"+ c #396541",
+"@ c #414141",
+"# c #7B6541",
+"$ c #7B308B",
+"% c #7B658B",
+"& c #399541",
+"* c #7B9541",
+"= c #7B958B",
+"- c none",
+"; c #838383",
+": c #BD95B4",
+"> c #BDCAB4",
+", c #C5C5C5",
+"< c gray100",
+/* pixels */
+"----------------",
+"----------------",
+"----------------",
+"-------%X+@++ -",
+"------oOOXO+oo+-",
+"----+@OXO*oo@>$-",
+"--&@*+#*@oo;<<=-",
+"-.@@@@@o ;<<<<*-",
+"-X@@@oo@<<<<<+--",
+"-+ oo@<%<<<:+---",
+"-X<,<<<#<<+-----",
+"-.<<<<<%=+------",
+"--&====+--------",
+"----------------",
+"----------------",
+"----------------"
+};
diff --git a/navit/xpm/gc_webcam.xpm b/navit/xpm/gc_webcam.xpm
new file mode 100644
index 000000000..3f7441d5b
--- /dev/null
+++ b/navit/xpm/gc_webcam.xpm
@@ -0,0 +1,44 @@
+/* XPM */
+static char *gc_webcam[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 22 1",
+" c black",
+". c #393000",
+"X c #393041",
+"o c #006500",
+"O c #396541",
+"+ c #7B3041",
+"@ c #414141",
+"# c #7B6541",
+"$ c #7B008B",
+"% c #7B308B",
+"& c #7B658B",
+"* c #7B9541",
+"= c #7B958B",
+"- c #7BCA8B",
+"; c #BD308B",
+": c #BD30B4",
+"> c none",
+", c #838383",
+"< c #BD95B4",
+"1 c #BDCAB4",
+"2 c #C5C5C5",
+"3 c gray100",
+/* pixels */
+">>>>>>:$$;>>>>>>",
+">>>>>.1333=2>>>>",
+">>>>.3322331,>>>",
+">>>O33 @@ 13->>>",
+">>>X3@2,&,X312>>",
+">>>*3&2<<,X31,>>",
+">>>O3#3,<< 3<,>>",
+">>>O3<,3<@&3O,>>",
+">>>,O32##<3<&>>>",
+">>>>&X1333O+>>>>",
+">>>>>>OXXO>>>>>>",
+">>>>>>: @:>>>>>>",
+">>>>>>:.=:>>>>>>",
+">>>>>&*<=@%>>>>>",
+">>>>oO<<<O@ >>>>",
+">>>>>>>>>>>>>>>>"
+};
diff --git a/navit/xpm/golf.xpm b/navit/xpm/golf.xpm
new file mode 100644
index 000000000..637387cc3
--- /dev/null
+++ b/navit/xpm/golf.xpm
@@ -0,0 +1,275 @@
+/* XPM */
+static char * golf_xpm[] = {
+"16 16 256 2",
+" c #3D3D3D",
+". c #696969",
+"+ c #393939",
+"@ c #474747",
+"# c #3A3223",
+"$ c #0D0D0D",
+"% c #060606",
+"& c #4A412F",
+"* c #5A5A5A",
+"= c #555555",
+"- c #15110B",
+"; c #514632",
+"> c #121212",
+", c #221D13",
+"' c #6E5C3B",
+") c #4D3E22",
+"! c #292929",
+"~ c #161616",
+"{ c #2B2B2B",
+"] c #222222",
+"^ c #564B37",
+"/ c #1E1E1E",
+"( c #242424",
+"_ c #29251B",
+": c #202020",
+"< c #090909",
+"[ c #1C1C1C",
+"} c #110E08",
+"| c #020202",
+"1 c #181818",
+"2 c #1A1A1A",
+"3 c #080807",
+"4 c #0F0C07",
+"5 c #010101",
+"6 c #ADADAD",
+"7 c #65583D",
+"8 c #FEFEFE",
+"9 c #484848",
+"0 c #909090",
+"a c #292317",
+"b c #3C3424",
+"c c #504631",
+"d c #4C3D21",
+"e c #62573F",
+"f c #6E5D3C",
+"g c #867552",
+"h c #886D36",
+"i c #6C6C6C",
+"j c #F7F7F7",
+"k c #FDFDFD",
+"l c #A2A2A2",
+"m c #FAFAFA",
+"n c #FBFBFB",
+"o c #6D6D6D",
+"p c #C7C7C7",
+"q c #F1F1F1",
+"r c #989898",
+"s c #FFCE6D",
+"t c #D4D4D4",
+"u c #262626",
+"v c #F6F6F6",
+"w c #F5F5F5",
+"x c #B1B1B1",
+"y c #FFD278",
+"z c #ACACAC",
+"A c #505050",
+"B c #D1D1D1",
+"C c #BEBEBE",
+"D c #BDBDBD",
+"E c #B0B0B0",
+"F c #9A9A9A",
+"G c #404040",
+"H c #8F8F8F",
+"I c #A3A3A3",
+"J c #F3F3F3",
+"K c #635840",
+"L c #4C4C4C",
+"M c #878787",
+"N c #FCFCFC",
+"O c #CDCDCD",
+"P c #D7D7D7",
+"Q c #4D4D4D",
+"R c #A1A1A1",
+"S c #C3C3C3",
+"T c #373737",
+"U c #F0F0F0",
+"V c #F4F4F4",
+"W c #E1E1E1",
+"X c #F2F2F2",
+"Y c #DBDBDB",
+"Z c #B2B2B2",
+"` c #A9A9A9",
+" . c #424242",
+".. c #BFBFBF",
+"+. c #7D7D7D",
+"@. c #D0D0D0",
+"#. c #EAEAEA",
+"$. c #8B8B8B",
+"%. c #2C2C2C",
+"&. c #898989",
+"*. c #AEAEAE",
+"=. c #F9F9F9",
+"-. c #272115",
+";. c #5C5C5C",
+">. c #D8D8D8",
+",. c #DFDFDF",
+"'. c #494949",
+"). c #B3B3B3",
+"!. c #2F2F2F",
+"~. c #888888",
+"{. c #515151",
+"]. c #9D9D9D",
+"^. c #6F6F6F",
+"/. c #2F281B",
+"(. c #434343",
+"_. c #2D271B",
+":. c #F5C86E",
+"<. c #6B6B6B",
+"[. c #A18D63",
+"}. c #DCB568",
+"|. c #5B4D32",
+"1. c #554729",
+"2. c #F2C469",
+"3. c #D2D2D2",
+"4. c #BA9E66",
+"5. c #86734E",
+"6. c #FACB6F",
+"7. c #D0AF6D",
+"8. c #FDCB69",
+"9. c #9E9E9E",
+"0. c #A5A5A5",
+"a. c #666666",
+"b. c #B7B7B7",
+"c. c #777777",
+"d. c #927B4D",
+"e. c #5C5038",
+"f. c #E6E6E6",
+"g. c #6E6E6E",
+"h. c #6A6A6A",
+"i. c #040403",
+"j. c #9B7E43",
+"k. c #67583A",
+"l. c #999999",
+"m. c #EFEFEF",
+"n. c #3E3729",
+"o. c #62553A",
+"p. c #CBCBCB",
+"q. c #828282",
+"r. c #FACC6E",
+"s. c #D5B370",
+"t. c #524732",
+"u. c #443B29",
+"v. c #DCDCDC",
+"w. c #93805A",
+"x. c #ABABAB",
+"y. c #BBBBBB",
+"z. c #C1C1C1",
+"A. c #6C5B3A",
+"B. c #DDB86D",
+"C. c #756341",
+"D. c #BCBCBC",
+"E. c #483F2D",
+"F. c #8B7854",
+"G. c #F9C866",
+"H. c #FDCD6F",
+"I. c #787878",
+"J. c #B49455",
+"K. c #E7BE6B",
+"L. c #716348",
+"M. c #E2BA6C",
+"N. c #62563F",
+"O. c #847351",
+"P. c #A88D55",
+"Q. c #AE8F50",
+"R. c #A28B5E",
+"S. c #E3E3E3",
+"T. c #C8C8C8",
+"U. c #D2B06C",
+"V. c #A7A7A7",
+"W. c #303030",
+"X. c #201B12",
+"Y. c #4E3F23",
+"Z. c #9B9B9B",
+"`. c #CECECE",
+" + c #5F533D",
+".+ c #5F543E",
+"++ c #9B8457",
+"@+ c #848484",
+"#+ c #727272",
+"$+ c #65583E",
+"%+ c #66583E",
+"&+ c #EAC06C",
+"*+ c #ECC068",
+"=+ c #8C8C8C",
+"-+ c #FECC6A",
+";+ c #322E26",
+">+ c #939393",
+",+ c #B5B5B5",
+"'+ c #C6C6C6",
+")+ c #F5C971",
+"!+ c #D5D5D5",
+"~+ c #776748",
+"{+ c #959595",
+"]+ c #534832",
+"^+ c #C3A363",
+"/+ c #AA8B4D",
+"(+ c #AD8E4F",
+"_+ c #7F7F7F",
+":+ c #0C0B09",
+"<+ c #F8F8F8",
+"[+ c #7A7A7A",
+"}+ c #444444",
+"|+ c #403828",
+"1+ c #A38851",
+"2+ c #443C2D",
+"3+ c #FECC66",
+"4+ c #EBEBEB",
+"5+ c #957E4F",
+"6+ c #DADADA",
+"7+ c #BFA166",
+"8+ c #636363",
+"9+ c #504227",
+"0+ c #CCCCCC",
+"a+ c #D3B372",
+"b+ c #757575",
+"c+ c #988256",
+"d+ c #B9B9B9",
+"e+ c #AC9363",
+"f+ c #C2C2C2",
+"g+ c #64573D",
+"h+ c #AFAFAF",
+"i+ c #605031",
+"j+ c #E8E8E8",
+"k+ c #E9E9E9",
+"l+ c #E5E5E5",
+"m+ c #705E3D",
+"n+ c #D3D3D3",
+"o+ c #565656",
+"p+ c #B8B8B8",
+"q+ c #B6B6B6",
+"r+ c #A6A6A6",
+"s+ c #584D36",
+"t+ c #5B4F37",
+"u+ c #5E523A",
+"v+ c #353535",
+"w+ c #969696",
+"x+ c #979797",
+"y+ c #8D8D8D",
+"z+ c #4B422F",
+"A+ c #5D5D5D",
+"B+ c #7B7B7B",
+"C+ c #020201",
+"D+ c #FFCF6F",
+"E+ c #FFCC66",
+"F+ c #FFFFFF",
+"G+ c #000000",
+"G+G+G+G+G+G+G+G+G+G+G+G+G+G+G+G+",
+"G+G+G+G+F+F+F+F+F+F+F+F+v.G+G+G+",
+"G+G+G+G+G+G+O n G+5 k+F+z G+G+G+",
+"G+G+G+G+G+G+F+F+G+F+8 F+G+G+G+G+",
+"G+G+G+G+G+G+G+G+F+W 3 F+G+G+G+G+",
+"G+G+G+G+G+G+G+F+F+j F+G+G+G+G+G+",
+"G+G+G+G+G+G+r F+F+F+G+G+G+G+G+G+",
+"G+G+G+G+G+G+l F+F+6 G+G+G+G+G+G+",
+"G+G+G+G+G+G+l F+F+6 G+G+G+G+G+G+",
+"G+G+G+G+G+G+6 F+F+6 G+G+G+G+G+G+",
+"G+G+G+G+G+G+*.F+F+6 G+G+G+G+G+G+",
+"G+G+G+G+G+G+j F+F+6 G+G+G+G+G+G+",
+"G+G+G+G+G+k F+| F+6 G+G+G+G+G+G+",
+"G+G+G+G+F+w 5 G+F+6 G+G+G+G+G+G+",
+"G+G+G+G+G+G+G+G+F+].G+G+G+G+G+G+",
+"G+G+G+G+G+G+G+G+G+G+G+G+G+G+G+G+"};
diff --git a/navit/xpm/heliport.xpm b/navit/xpm/heliport.xpm
new file mode 100644
index 000000000..ef350c08c
--- /dev/null
+++ b/navit/xpm/heliport.xpm
@@ -0,0 +1,19 @@
+/* XPM */
+static char * heliport_xpm[] = {
+"20 12 4 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #000070",
+" .+. ",
+" ...... .+. ",
+".++++++....+.. ",
+" ......+++++++......",
+". ..++...++++++",
+"@. .+@@@@@......",
+"@. .+@@@@ @@@. ",
+"@@....@@@@@@ @. ",
+"@@@@@@@@@@@@ @.",
+"........@@@@ @.",
+" .@@@@@ @@.",
+" ..@@@@@@@. "};
diff --git a/navit/xpm/highway_exit.xpm b/navit/xpm/highway_exit.xpm
new file mode 100644
index 000000000..7d433052f
--- /dev/null
+++ b/navit/xpm/highway_exit.xpm
@@ -0,0 +1,65 @@
+/* XPM */
+static char * highway_exit_xpm[] = {
+"16 16 46 1",
+" c None",
+". c #035E9F",
+"+ c #77A8CB",
+"@ c #D4E3EE",
+"# c #337CB1",
+"$ c #CFE0EC",
+"% c #4688B8",
+"& c #8DB6D3",
+"* c #A5C5DC",
+"= c #488AB9",
+"- c #4588B8",
+"; c #B0CDE1",
+"> c #8EB7D4",
+", c #DEEAF2",
+"' c #5C97C1",
+") c #5592BE",
+"! c #7EACCE",
+"~ c #E6EFF5",
+"{ c #F5F8FB",
+"] c #2E79AF",
+"^ c #FFFFFF",
+"/ c #166AA6",
+"( c #EAF1F7",
+"_ c #8CB5D3",
+": c #2674AC",
+"< c #83B0CF",
+"[ c #76A7CB",
+"} c #5894BF",
+"| c #FEFEFE",
+"1 c #1469A5",
+"2 c #0A63A2",
+"3 c #74A6CA",
+"4 c #EFF4F8",
+"5 c #3880B3",
+"6 c #EEF4F8",
+"7 c #72A5C9",
+"8 c #CADDEB",
+"9 c #ACCADF",
+"0 c #2272AB",
+"a c #3C82B4",
+"b c #3B81B4",
+"c c #045F9F",
+"d c #196CA7",
+"e c #1B6DA8",
+"f c #367EB2",
+"g c #1C6EA8",
+"................",
+"................",
+"................",
+"................",
+"................",
+"................",
+"+@@@#$%&*=@-@@@;",
+">,').!~{])^/](_:",
+">~<[.}|~1)^2.~3.",
+">4;;56789)^2.~3.",
+"0aaa:bcdaeac.fg.",
+"................",
+"................",
+"................",
+"................",
+"................"};
diff --git a/navit/xpm/hospital.xpm b/navit/xpm/hospital.xpm
new file mode 100644
index 000000000..44ac27407
--- /dev/null
+++ b/navit/xpm/hospital.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static char *hospital[]={
+"16 16 5 1",
+". c None",
+"a c #0000ff",
+"c c #e32b2b",
+"b c #fdfefe",
+"# c #ffffff",
+".##############.",
+"#aaaaaaaaaaaaaa#",
+"#aaaaaaaaaaaaaa#",
+"#aabbbb###bbbaa#",
+"#aabbb#cc#bbbaa#",
+"#aabbb#cc##bbaa#",
+"#aa####cc####aa#",
+"#aa#cccccccc#aa#",
+"#aa#cccccccc#aa#",
+"#aa####cc####aa#",
+"#aabbb#cc#bbbaa#",
+"#aabbb#cc#bbbaa#",
+"#aabbb###bbbbaa#",
+"#aaaaaaaaaaaaaa#",
+"#aaaaaaaaaaaaaa#",
+".##############."};
diff --git a/navit/xpm/hotel.xpm b/navit/xpm/hotel.xpm
new file mode 100644
index 000000000..c371b95a1
--- /dev/null
+++ b/navit/xpm/hotel.xpm
@@ -0,0 +1,26 @@
+/* XPM */
+static char *hotel[]={
+"16 16 7 1",
+". c None",
+"b c #000000",
+"a c #0000ff",
+"d c #555566",
+"c c #727283",
+"e c #ededef",
+"# c #ffffff",
+".##############.",
+"#aaaaaaaaaaaaaa#",
+"#aaaaaaaaaaaaaa#",
+"#aa##########aa#",
+"#aa#b########aa#",
+"#aa#bc#######aa#",
+"#aa#bdc####b#aa#",
+"#aa#bcdccccb#aa#",
+"#aa#bbbbbbbb#aa#",
+"#aa#b######b#aa#",
+"#aa#e########aa#",
+"#aa##########aa#",
+"#aa##########aa#",
+"#aaaaaaaaaaaaaa#",
+"#aaaaaaaaaaaaaa#",
+".##############."};
diff --git a/navit/xpm/information.xpm b/navit/xpm/information.xpm
new file mode 100644
index 000000000..08ea57982
--- /dev/null
+++ b/navit/xpm/information.xpm
@@ -0,0 +1,70 @@
+/* XPM */
+static char * information_xpm[] = {
+"16 16 51 1",
+" c #156907",
+". c #1D6E0F",
+"+ c #83B07C",
+"@ c #A7C7A2",
+"# c #55934B",
+"$ c #A7C6A2",
+"% c #FDFDFD",
+"& c #FAFCFA",
+"* c #4C8D42",
+"= c #1E6F11",
+"- c #F8FBF8",
+"; c #A0C39B",
+"> c #1F6F12",
+", c #A0C29B",
+"' c #B2CDAE",
+") c #FBFCFB",
+"! c #508F45",
+"~ c #217014",
+"{ c #93BA8C",
+"] c #B5D0B1",
+"^ c #5E9855",
+"/ c #75A970",
+"( c #D5E5D5",
+"_ c #D5E5D4",
+": c #D9E7D8",
+"< c #DBE8DA",
+"[ c #6FA368",
+"} c #1A6C0C",
+"| c #F4F8F3",
+"1 c #83B17D",
+"2 c #E4EEE2",
+"3 c #82AF7B",
+"4 c #E3EDE1",
+"5 c #7FAD78",
+"6 c #80AE79",
+"7 c #DFEBDE",
+"8 c #84B17E",
+"9 c #DFEADD",
+"0 c #1B6C0D",
+"a c #EFF4ED",
+"b c #A0C29A",
+"c c #186B0A",
+"d c #2E7C24",
+"e c #93BB8F",
+"f c #E3EDE3",
+"g c #E2EDE2",
+"h c #DCE9DC",
+"i c #DDEADD",
+"j c #D6E5D6",
+"k c #599754",
+"l c #25741A",
+" .+@# ",
+" $%%&* ",
+" =-%%%; ",
+" >&%%%, ",
+" '%%)! ",
+" ~{]^ ",
+" /(_:<[ ",
+" }|%%%1 ",
+" 2%%%3 ",
+" 4%%%5 ",
+" 4%%%6 ",
+" 7%%%8 ",
+" 9%%%3 ",
+" 0a%%%b ",
+" cdefghijkl ",
+" "};
diff --git a/navit/xpm/level_crossing.xpm b/navit/xpm/level_crossing.xpm
new file mode 100644
index 000000000..83b2d7161
--- /dev/null
+++ b/navit/xpm/level_crossing.xpm
@@ -0,0 +1,16 @@
+/* XPM */
+static char * level_crossing_xpm[] = {
+"11 11 2 1",
+" c None",
+". c #797774",
+". .",
+".. ..",
+" .. .. ",
+" .. .. ",
+" .. .. ",
+" ... ",
+" .. .. ",
+" .. .. ",
+" .. .. ",
+".. ..",
+". ."};
diff --git a/navit/xpm/library.xpm b/navit/xpm/library.xpm
new file mode 100644
index 000000000..c91306312
--- /dev/null
+++ b/navit/xpm/library.xpm
@@ -0,0 +1,34 @@
+/* XPM */
+static char *library[] = {
+/* columns rows colors chars-per-pixel */
+"8 16 12 1",
+" c black",
+". c gray25",
+"X c #464646",
+"o c #808080",
+"O c gray56",
+"+ c #BCBCBC",
+"@ c gray75",
+"# c gainsboro",
+"$ c #FBFBFB",
+"% c gray99",
+"& c gray100",
+"* c None",
+/* pixels */
+"*** * ",
+"** X&X ",
+"* @&&.o ",
+" @&@ @& ",
+" .. &@@ ",
+" && @.& ",
+" && &o@ ",
+" && O@@ ",
+" && @.@ ",
+" && #&& ",
+" && &&& ",
+" && &&. ",
+" && &X *",
+" && X **",
+" && ***",
+". ****"
+};
diff --git a/navit/xpm/mini_roundabout.xpm b/navit/xpm/mini_roundabout.xpm
new file mode 100644
index 000000000..562b5e1dd
--- /dev/null
+++ b/navit/xpm/mini_roundabout.xpm
@@ -0,0 +1,18 @@
+/* XPM */
+static char * mini_roundabout_xpm[] = {
+"13 13 2 1",
+" c None",
+". c #000000",
+" ",
+" ",
+" ..... ",
+" .. .. ",
+" .. .. ",
+" . . . ",
+" . ... . ",
+" . . . ",
+" .. .. ",
+" .. .. ",
+" ..... ",
+" ",
+" "};
diff --git a/navit/xpm/museum.xpm b/navit/xpm/museum.xpm
new file mode 100644
index 000000000..bf5b84cb3
--- /dev/null
+++ b/navit/xpm/museum.xpm
@@ -0,0 +1,67 @@
+/* XPM */
+static char * museum_xpm[] = {
+"16 15 49 1",
+" c None",
+". c #FFFFFF",
+"+ c #EEEEEE",
+"@ c #A2A2A2",
+"# c #565656",
+"$ c #3A3A3A",
+"% c #878787",
+"& c #DADADA",
+"* c #E6E6E6",
+"= c #949494",
+"- c #454545",
+"; c #080808",
+"> c #000000",
+", c #313131",
+"' c #B5B5B5",
+") c #9C9C9C",
+"! c #909090",
+"~ c #9B9B9B",
+"{ c #6D6D6D",
+"] c #3E3E3E",
+"^ c #B9B9B9",
+"/ c #F8F8F8",
+"( c #F3F3F3",
+"_ c #CACACA",
+": c #747474",
+"< c #141414",
+"[ c #F0F0F0",
+"} c #515151",
+"| c #646464",
+"1 c #1A1A1A",
+"2 c #ABABAB",
+"3 c #121212",
+"4 c #5D5D5D",
+"5 c #686868",
+"6 c #1E1E1E",
+"7 c #8C8C8C",
+"8 c #626262",
+"9 c #222222",
+"0 c #353535",
+"a c #C6C6C6",
+"b c #0F0F0F",
+"c c #7C7C7C",
+"d c #ECECEC",
+"e c #4D4D4D",
+"f c #494949",
+"g c #8A8A8A",
+"h c #7D7D7D",
+"i c #B2B2B2",
+"j c #BCBCBC",
+" ...... ",
+" ...+@#$%&... ",
+" .*=-;>>>>>,%&. ",
+".&;>>>>>>>>>>>'.",
+" .)!!!!!!!!!!~. ",
+" .{]^./--(._]:. ",
+" .{<[..}|. .12. ",
+" .%3. .45. .62. ",
+" .71. .|8. .62. ",
+" .!<. .||. .92. ",
+" .@3. .5|. .92. ",
+" .53[.*0-..abc. ",
+".[;>!._>>&.!>9. ",
+".defg_^hh^_i==. ",
+".[^^^^^^^^^^^j/ "};
diff --git a/navit/xpm/nav_left_1.xpm b/navit/xpm/nav_left_1.xpm
new file mode 100644
index 000000000..18b9a7716
--- /dev/null
+++ b/navit/xpm/nav_left_1.xpm
@@ -0,0 +1,69 @@
+/* XPM */
+static char * turn_left_90_v2_sv_xpm[] = {
+"64 64 2 1",
+" c None",
+". c #000000",
+" . ",
+" ............. . ",
+" ........................ ",
+" ................................. ",
+" ............................... ",
+" ............................ ",
+" .......................... ",
+" ........................ ",
+" ...................... ",
+" ...................... ",
+" ....................... ",
+" ........................ ",
+" ......................... ",
+" ......................... ",
+" .......................... ",
+" .......................... ",
+" .......................... ",
+" .......................... ",
+" ........................... ",
+" ....... ................. ",
+" ...... ................ ",
+" .... ................ ",
+" ... .............. ",
+" .. ............. ",
+" .. ............. ",
+" . ............ ",
+" ........... ",
+" ............ ",
+" ........... ",
+" ........... ",
+" .......... ",
+" .......... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... "};
diff --git a/navit/xpm/nav_left_2.xpm b/navit/xpm/nav_left_2.xpm
new file mode 100644
index 000000000..b5012f47c
--- /dev/null
+++ b/navit/xpm/nav_left_2.xpm
@@ -0,0 +1,69 @@
+/* XPM */
+static char * turn_left_v2_sv_xpm[] = {
+"64 64 2 1",
+" c None",
+". c #000000",
+" ",
+" .. ",
+" ..... ",
+" ...... ",
+" ......... ",
+" ........... ",
+" ............. ",
+" ................ ",
+" ........................ ",
+" ................................. ",
+" ....................................... ",
+" ............................................. ",
+" ................................................. ",
+" ................................................... ",
+" .................................................. ",
+" ................................................ ",
+" .............................................. ",
+" ............................................ ",
+" ................ ....................... ",
+" ............. .................. ",
+" .......... ............... ",
+" ........ ............. ",
+" ..... ............. ",
+" ... ............ ",
+" ........... ",
+" .......... ",
+" ........... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" ........... ",
+" ........... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" .......... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" .......... "};
diff --git a/navit/xpm/nav_right_1.xpm b/navit/xpm/nav_right_1.xpm
new file mode 100644
index 000000000..bcf16278a
--- /dev/null
+++ b/navit/xpm/nav_right_1.xpm
@@ -0,0 +1,69 @@
+/* XPM */
+static char * turn_right_90_v2_sv_xpm[] = {
+"64 64 2 1",
+" c None",
+". c #000000",
+" .. ",
+" ............... ",
+" ......................... ",
+" ................................. ",
+" ............................... ",
+" ............................ ",
+" .......................... ",
+" ........................ ",
+" ...................... ",
+" ....................... ",
+" ....................... ",
+" ........................ ",
+" ......................... ",
+" ......................... ",
+" .......................... ",
+" .......................... ",
+" .......................... ",
+" ........................... ",
+" ........................... ",
+" ................. ....... ",
+" ................ ...... ",
+" ............... ..... ",
+" ............... ... ",
+" ............. ... ",
+" ............. .. ",
+" ............ . ",
+" ........... ",
+" ............ ",
+" ........... ",
+" ........... ",
+" .......... ",
+" .......... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+".......... ",
+".......... ",
+".......... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... ",
+"........... "};
diff --git a/navit/xpm/nav_right_2.xpm b/navit/xpm/nav_right_2.xpm
new file mode 100644
index 000000000..5d3088a79
--- /dev/null
+++ b/navit/xpm/nav_right_2.xpm
@@ -0,0 +1,69 @@
+/* XPM */
+static char * turn_rightv2_sv_xpm[] = {
+"64 64 2 1",
+" c None",
+". c #000000",
+" . ",
+" .. ",
+" ..... ",
+" ...... ",
+" ......... ",
+" ............ ",
+" ............. ",
+" ................ ",
+" ........................ ",
+" ................................. ",
+" ....................................... ",
+" ............................................. ",
+" .................................................. ",
+" ................................................... ",
+" .................................................. ",
+" ................................................ ",
+" .............................................. ",
+" ............................................ ",
+" ....................... ............... ",
+" .................. ............ ",
+" ............... ......... ",
+" ............. ........ ",
+" ............. ..... ",
+" ........... ... ",
+" ........... ",
+" ........... ",
+" ........... ",
+" .......... ",
+" .......... ",
+" .......... ",
+"........... ",
+"........... ",
+"........... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... ",
+".......... "};
diff --git a/navit/xpm/nav_straight.xpm b/navit/xpm/nav_straight.xpm
new file mode 100644
index 000000000..dbbfc0c2a
--- /dev/null
+++ b/navit/xpm/nav_straight.xpm
@@ -0,0 +1,69 @@
+/* XPM */
+static char * turn_straight_sv_xpm[] = {
+"64 64 2 1",
+" c None",
+". c #000000",
+" ",
+" . ",
+" . ",
+" .. ",
+" ... ",
+" .... ",
+" ..... ",
+" ..... ",
+" ...... ",
+" ....... ",
+" ....... ",
+" ........ ",
+" ......... ",
+" ......... ",
+" ........... ",
+" ........... ",
+" ............ ",
+" ............. ",
+" ............. ",
+" .............. ",
+" ............... ",
+" ............... ",
+" ................ ",
+" ................. ",
+" .................. ",
+" ................... ",
+" ................... ",
+" .................... ",
+" ..................... ",
+" ..................... ",
+" ...................... ",
+" ....................... ",
+" ....................... ",
+" ......................... ",
+" ......................... ",
+" .......................... ",
+" ........................... ",
+" .... ............ .... ",
+" .. ............ ... ",
+" . ............ . ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ............ ",
+" ........... "};
diff --git a/navit/xpm/parking.xpm b/navit/xpm/parking.xpm
new file mode 100644
index 000000000..505ac6815
--- /dev/null
+++ b/navit/xpm/parking.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static char *parking[]={
+"16 16 5 1",
+". c None",
+"a c #0000ff",
+"b c #8080ff",
+"c c #f6f6fa",
+"# c #ffffff",
+".##############.",
+"#aaaaaaaaaaaaaa#",
+"#aaa######baaaa#",
+"#aaa##cccc#baaa#",
+"#aaa##aaaab#baa#",
+"#aaa##aaaab#baa#",
+"#aaa##aaaab#baa#",
+"#aaa######cbaaa#",
+"#aaa##cc##baaaa#",
+"#aaa##aaaaaaaaa#",
+"#aaa##aaaaaaaaa#",
+"#aaa##aaaaaaaaa#",
+"#aaa##aaaaaaaaa#",
+"#aaa##aaaaaaaaa#",
+"#aaaaaaaaaaaaaa#",
+".##############."};
diff --git a/navit/xpm/peak.xpm b/navit/xpm/peak.xpm
new file mode 100644
index 000000000..a95b6ffb3
--- /dev/null
+++ b/navit/xpm/peak.xpm
@@ -0,0 +1,13 @@
+/* XPM */
+static char * peak_xpm[] = {
+"8 8 2 1",
+" c None",
+". c #FF00FF",
+" ",
+" .. ",
+" .. ",
+" .... ",
+" .... ",
+" ...... ",
+" ...... ",
+"........"};
diff --git a/navit/xpm/pharmacy.xpm b/navit/xpm/pharmacy.xpm
new file mode 100644
index 000000000..b5b1aa57a
--- /dev/null
+++ b/navit/xpm/pharmacy.xpm
@@ -0,0 +1,39 @@
+/* XPM */
+static char *pharmacy[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 17 1",
+" c #00CC00",
+". c #01CC01",
+"X c #02CC02",
+"o c #04CD04",
+"O c #1CD21C",
+"+ c #40D940",
+"@ c #41D941",
+"# c #77E477",
+"$ c #80E680",
+"% c #82E682",
+"& c #9CEB9C",
+"* c #BFF2BF",
+"= c #C0F2C0",
+"- c #DAF8DA",
+"; c #E7FAE7",
+": c #FDFFFD",
+"> c gray100",
+/* pixels */
+"# O-",
+" ;>>>>>>>>>>>>$$",
+" > $$$@ $$$",
+" > >>>$ $$$",
+" > >>>% $$$",
+" > oo>>>% $$$",
+" >$>>>>>>>>>>$$$",
+" >$>>>>>>>>>>$$$",
+" >$>>>>>>>>>>$$$",
+" >@$$$>>>=%%$$$$",
+" > >>>$ $$$",
+" > o>>>$ $$$",
+" > >>>% $$$",
+" >$$$$$$$$$$$=$$",
+"O$$$$$$$$$$$$%@&",
+"-$$$$$$$$$$$$#&>"
+};
diff --git a/navit/xpm/picnic.xpm b/navit/xpm/picnic.xpm
new file mode 100644
index 000000000..b27299662
--- /dev/null
+++ b/navit/xpm/picnic.xpm
@@ -0,0 +1,66 @@
+/* XPM */
+static char *picnic[] = {
+/* columns rows colors chars-per-pixel */
+"16 15 45 1",
+" c #000023",
+". c #060629",
+"X c #0A0A2D",
+"o c #141436",
+"O c #1B1B3E",
+"+ c #1F1F41",
+"@ c #262648",
+"# c #28284A",
+"$ c #29294C",
+"% c #2B2B4D",
+"& c #353558",
+"* c #37375A",
+"= c #404062",
+"- c #454567",
+"; c #48486B",
+": c #4A4A6C",
+"> c #4C4C6F",
+", c #535375",
+"< c #2727C6",
+"1 c #646486",
+"2 c #666688",
+"3 c #68688B",
+"4 c #737396",
+"5 c #7B7B9D",
+"6 c #7E7EA1",
+"7 c #4D4DCF",
+"8 c #8181A4",
+"9 c #8A8AAD",
+"0 c #8C8CAE",
+"q c #9898BB",
+"w c #9A9ABC",
+"e c #A6A6C9",
+"r c #AFAFD2",
+"t c #B4B4D6",
+"y c #B9B9DB",
+"u c #BDBDDF",
+"i c #B5B5E8",
+"p c #C2C2E4",
+"a c #C9C9EF",
+"s c #CECEF1",
+"d c #CFCFF1",
+"f c #D0D0F2",
+"g c #D1D1F2",
+"h c #F6F6FC",
+"j c None",
+/* pixels */
+"jjgggggdgddgddjj",
+"jadgggdgdggggddj",
+"ddgq,,,,,,,,,gdd",
+"dgd4 .ddd",
+"dddie* :: 6eddd",
+"ddddt+ yy wddgd",
+"dddd3 #pd2 +ddgg",
+"d>%%. o#%o .%%%0",
+"d@ . 6",
+"ddd- =dgdd0 ddd",
+"dgd Xqddddd% 2dd",
+"gg6 *dddddd* ,dd",
+"gg8,4gddgggi,,td",
+"jgggdgddggggdddj",
+"jjdgggggggggddjj"
+};
diff --git a/navit/xpm/police.xpm b/navit/xpm/police.xpm
new file mode 100644
index 000000000..c2ffb2634
--- /dev/null
+++ b/navit/xpm/police.xpm
@@ -0,0 +1,82 @@
+/* XPM */
+static char * police_xpm[] = {
+"16 16 63 1",
+" c None",
+". c #035E9F",
+"+ c #2372AB",
+"@ c #0761A0",
+"# c #98BDD7",
+"$ c #7BABCC",
+"% c #176BA6",
+"& c #629BC3",
+"* c #D4E3EE",
+"= c #B4CFE2",
+"- c #4E8DBB",
+"; c #2E79AF",
+"> c #BFD6E6",
+", c #488AB9",
+"' c #A8C7DD",
+") c #BBD4E5",
+"! c #C0D7E7",
+"~ c #C3D9E8",
+"{ c #347DB1",
+"] c #307BB0",
+"^ c #5793BF",
+"/ c #8AB4D2",
+"( c #1167A4",
+"_ c #9EC1DA",
+": c #A5C5DC",
+"< c #99BDD8",
+"[ c #699FC6",
+"} c #D3E3EE",
+"| c #74A6CA",
+"1 c #7AAACC",
+"2 c #649CC4",
+"3 c #92B9D5",
+"4 c #518FBC",
+"5 c #2976AD",
+"6 c #D5E4EF",
+"7 c #1268A5",
+"8 c #1E6FA9",
+"9 c #6CA1C7",
+"0 c #5290BD",
+"a c #E8F0F6",
+"b c #6AA0C6",
+"c c #C2D8E8",
+"d c #0A63A2",
+"e c #1368A5",
+"f c #CBDEEB",
+"g c #88B3D1",
+"h c #E0EBF3",
+"i c #5B96C0",
+"j c #C4D9E8",
+"k c #196CA7",
+"l c #3C82B4",
+"m c #0B63A2",
+"n c #2D79AF",
+"o c #045F9F",
+"p c #73A5C9",
+"q c #C6DBE9",
+"r c #ACCADF",
+"s c #93BAD5",
+"t c #E3EDF4",
+"u c #0C64A2",
+"v c #B9D2E4",
+"w c #E5EEF5",
+"x c #377FB2",
+"................",
+"..............+.",
+"............@#$%",
+"............&*=-",
+"..........;>,')!",
+"..........~{]^/(",
+"........,/_:<[..",
+"........(}|12...",
+"......34.567....",
+"....890abcd.....",
+"...efghijk......",
+"..5l6mcno.......",
+".pqrst/.........",
+"u*v9............",
+".+w,............",
+"..x+............"};
diff --git a/navit/xpm/post.xpm b/navit/xpm/post.xpm
new file mode 100644
index 000000000..399e73ef5
--- /dev/null
+++ b/navit/xpm/post.xpm
@@ -0,0 +1,25 @@
+/* XPM */
+static char *dummy[]={
+"16 16 6 1",
+". c None",
+"# c #000000",
+"a c #3f3f3f",
+"b c #7f7f7f",
+"d c #bfbfbf",
+"c c #ffffff",
+"................",
+"................",
+"................",
+"..############..",
+"..abccccccccba..",
+"..bcbdccccbbcb..",
+"..bccdbdbbcccb..",
+"..bccccdcccccb..",
+"..bccccccccccb..",
+"..bccccccccccb..",
+"..############..",
+"................",
+"................",
+"................",
+"................",
+"................"};
diff --git a/navit/xpm/restaurant.xpm b/navit/xpm/restaurant.xpm
new file mode 100644
index 000000000..730fcc941
--- /dev/null
+++ b/navit/xpm/restaurant.xpm
@@ -0,0 +1,73 @@
+/* XPM */
+static char *tst[]={
+"16 16 54 1",
+". c None",
+"o c #000000",
+"a c #0000ff",
+"v c #161717",
+"X c #181919",
+"V c #191a1a",
+"S c #1a1b1b",
+"M c #1b1c1c",
+"T c #1c1d1d",
+"F c #1e1f1f",
+"Q c #1f2020",
+"L c #212222",
+"y c #292a2a",
+"G c #2b2c2c",
+"Z c #3f3f3f",
+"g c #3f4040",
+"z c #4d4e4e",
+"D c #4e4f4f",
+"s c #505050",
+"n c #606161",
+"A c #6b6c6c",
+"E c #6d6d6d",
+"r c #6f6f6f",
+"t c #6f7070",
+"l c #737373",
+"w c #7b7b7b",
+"h c #7e7e7e",
+"P c #7f7f7f",
+"W c #818181",
+"B c #858686",
+"k c #888888",
+"K c #8f9090",
+"H c #909090",
+"q c #919292",
+"Y c #929393",
+"J c #9a9b9b",
+"f c #9c9c9c",
+"u c #a8a8a8",
+"N c #b1b2b2",
+"m c #bfbfbf",
+"p c #dedede",
+"i c #e8e8e8",
+"I c #f3f3f3",
+"x c #f8f8f8",
+"O c #f9f9f9",
+"C c #fafafa",
+"U c #fcfcfc",
+"e c #fcfcfe",
+"c c #fcfdfe",
+"b c #fcfdff",
+"R c #fdfdfd",
+"d c #fdfdff",
+"j c #fefefe",
+"# c #ffffff",
+".##############.",
+"#aaaaaaaaaaaaaa#",
+"#a#bcddddde#d#a#",
+"#a#fghi##jklm#a#",
+"#a#nooop#qrst#a#",
+"#a#uoovwxyzAB#a#",
+"#a#CDovEmFGHj#a#",
+"#a##IJKLMNO###a#",
+"#a####PQFPR###a#",
+"#a##jPSmmTPU##a#",
+"#a#RPVP##PMPC#a#",
+"#a#WXY####uVP#a#",
+"#a#oPj#####Po#a#",
+"#a############a#",
+"#PZmaaaaaaaaaaa#",
+".##############."};
diff --git a/navit/xpm/restroom.xpm b/navit/xpm/restroom.xpm
new file mode 100644
index 000000000..597c0d615
--- /dev/null
+++ b/navit/xpm/restroom.xpm
@@ -0,0 +1,134 @@
+/* XPM */
+static char * restroom_xpm[] = {
+"16 16 115 2",
+" c None",
+". c #262CA6",
+"+ c #2C32A8",
+"@ c #6D71C2",
+"# c #3A3FAE",
+"$ c #2A30A8",
+"% c #8689CB",
+"& c #484DB4",
+"* c #3C42AF",
+"= c #9699D4",
+"- c #FEFEFE",
+"; c #CACBE8",
+"> c #2E34A9",
+", c #E0E0F1",
+"' c #4E53B6",
+") c #FCFCFD",
+"! c #EDEEF6",
+"~ c #2D33A9",
+"{ c #8286CB",
+"] c #FCFCFC",
+"^ c #ACAFDC",
+"/ c #484DB3",
+"( c #F6F7FA",
+"_ c #E4E5F3",
+": c #2C31A8",
+"< c #484EB4",
+"[ c #A0A2D7",
+"} c #B4B6E0",
+"| c #A3A6D8",
+"1 c #4F54B6",
+"2 c #6065BD",
+"3 c #A8ABDB",
+"4 c #BBBDE2",
+"5 c #B2B4DF",
+"6 c #A1A4D8",
+"7 c #272DA6",
+"8 c #D0D1EA",
+"9 c #FFFEFE",
+"0 c #FFFFFF",
+"a c #FFFFFE",
+"b c #DADBEE",
+"c c #E1E1F1",
+"d c #BEBFE3",
+"e c #3D42AF",
+"f c #DFE0F0",
+"g c #E8E8F4",
+"h c #EEEFF7",
+"i c #CED0E9",
+"j c #474CB3",
+"k c #262CA5",
+"l c #E9EAF6",
+"m c #E7E8F4",
+"n c #E7E7F4",
+"o c #C6C6E6",
+"p c #7D80C9",
+"q c #B8B9E0",
+"r c #FEFEFD",
+"s c #AEB0DD",
+"t c #898CCE",
+"u c #AAADDC",
+"v c #A9ACDB",
+"w c #C8C9E8",
+"x c #BDBFE2",
+"y c #B6B9E0",
+"z c #B0B2DE",
+"A c #CBCDE8",
+"B c #AAACDB",
+"C c #CBCCE9",
+"D c #8184CA",
+"E c #C8C9E7",
+"F c #CED0EA",
+"G c #7A7EC8",
+"H c #E3E4F2",
+"I c #A8AADA",
+"J c #A7AADA",
+"K c #C5C7E6",
+"L c #343AAC",
+"M c #F9F9FB",
+"N c #3B41AE",
+"O c #3439AB",
+"P c #9B9ED5",
+"Q c #DDDEF0",
+"R c #777BC6",
+"S c #3036AA",
+"T c #4A50B4",
+"U c #A7AADB",
+"V c #DADBEF",
+"W c #E6E7F4",
+"X c #A9ACDC",
+"Y c #5156B7",
+"Z c #2F34AA",
+"` c #CCCEEA",
+" . c #F6F6FA",
+".. c #767AC6",
+"+. c #AAADDB",
+"@. c #A5A8DA",
+"#. c #C0C2E4",
+"$. c #E0E1F0",
+"%. c #AAAEDC",
+"&. c #A6A9DA",
+"*. c #C0C3E5",
+"=. c #AAAEDB",
+"-. c #A7A9DA",
+";. c #A0A3D6",
+">. c #9598D3",
+",. c #B8BAE0",
+"'. c #9498D2",
+"). c #C9CAE8",
+"!. c #F2F3F8",
+"~. c #7276C4",
+"{. c #282EA6",
+"]. c #2A2FA7",
+"^. c #292FA7",
+"/. c #7074C3",
+"(. c #4248B1",
+". . + @ # . . $ % . . . & * . . ",
+". . = - ; . . > , . . ' ) ! ~ . ",
+". . { ] ^ . . > , . . / ( _ : . ",
+". < [ } | 1 . > , . 2 3 4 5 6 ' ",
+"7 8 9 0 a b . > , . c 0 0 0 0 d ",
+"e f g 0 h i j > , k l m 0 a n o ",
+"p q - 0 r s t > , . g u 0 a v w ",
+"x y 0 0 0 z A > , . g u 0 a B C ",
+"D E 0 0 0 F G > , k H I 0 a J K ",
+"L M 0 0 0 ] N > , . O P Q M R S ",
+"T U Q V W X Y Z , . . P ` .... ",
+". . +.@.#.. . > $.. . P ` .... ",
+". . %.&.*.. . > , . . P ` .... ",
+". . =.-.*.. . > , . . P ` .... ",
+". . ;.>.,.. . > , . . '.).!.~.. ",
+". . {.. ].. . ^./.. . S * (.+ . "};
diff --git a/navit/xpm/shopping.xpm b/navit/xpm/shopping.xpm
new file mode 100644
index 000000000..7a892d36d
--- /dev/null
+++ b/navit/xpm/shopping.xpm
@@ -0,0 +1,20 @@
+/* XPM */
+static char * shopping_xpm[] = {
+"14 14 3 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+" ... ",
+".+++......... ",
+".+..+++++++++.",
+" .+.........+.",
+" .+.+.+.+.+.+.",
+" .+.........+.",
+" .+..+.+.+.+. ",
+" .+.......+. ",
+" .++++++++. ",
+" ........ ",
+" .+....... ",
+" .++++++++. ",
+" .++....++. ",
+" .. .. "};
diff --git a/navit/xpm/skiing.xpm b/navit/xpm/skiing.xpm
new file mode 100644
index 000000000..e62bbd5b0
--- /dev/null
+++ b/navit/xpm/skiing.xpm
@@ -0,0 +1,139 @@
+/* XPM */
+static char *skiing[] = {
+/* columns rows colors chars-per-pixel */
+"32 32 101 2",
+" c #000000030000",
+". c #000001430000",
+"X c #000002470000",
+"o c #0000034C0000",
+"O c #0000057D0000",
+"+ c #000006C60000",
+"@ c #000007920000",
+"# c #0000084A0000",
+"$ c #000009AD0000",
+"% c #00000A890000",
+"& c #00000B5E0000",
+"* c #00000C9B0000",
+"= c #00000E7E0000",
+"- c #00000FB70000",
+"; c #000010F30000",
+": c #000011AC0000",
+"> c #000012800000",
+", c #000013A40000",
+"< c #0000147A0000",
+"1 c #000015510000",
+"2 c #000017790000",
+"3 c #000018EC0000",
+"4 c #000019C80000",
+"5 c #00001AA40000",
+"6 c #00001BBA0000",
+"7 c #00001C600000",
+"8 c #00001D780000",
+"9 c #00001EB60000",
+"0 c #00001FAB0000",
+"q c #000020C70000",
+"w c #000021AB0000",
+"e c #000023EA0000",
+"r c #000024840000",
+"t c #000025800000",
+"y c #000026560000",
+"u c #000028F00000",
+"i c #000029DE0000",
+"p c #00002BBB0000",
+"a c #00002CD30000",
+"s c #00002D9D0000",
+"d c #00002F090000",
+"f c #00002F830000",
+"g c #000030C90000",
+"h c #000033850000",
+"j c #000034550000",
+"k c #000035CD0000",
+"l c #000037470000",
+"z c #000038850000",
+"x c #000039830000",
+"c c #00003B910000",
+"v c #00003CC80000",
+"b c #00003D6B0000",
+"n c #00003F540000",
+"m c #000040DF0000",
+"M c #000041E80000",
+"N c #000043FD0000",
+"B c #000044B00000",
+"V c #000045D40000",
+"C c #000046E20000",
+"Z c #000049040000",
+"A c #000049D10000",
+"S c #00004AE40000",
+"D c #00004D0F0000",
+"F c #00004EE20000",
+"G c #000052920000",
+"H c #000053B00000",
+"J c #000054CF0000",
+"K c #0000555F0000",
+"L c #000056810000",
+"P c #000058C80000",
+"I c #000059EE0000",
+"U c #00005C200000",
+"Y c #00005CD30000",
+"T c #00005DCC0000",
+"R c #000060580000",
+"E c #0000621F0000",
+"W c #000064AB0000",
+"Q c #000069120000",
+"! c #000069FD0000",
+"~ c #00006BD70000",
+"^ c #00006CF50000",
+"/ c #00006E050000",
+"( c #00006EF50000",
+") c #00006FE70000",
+"_ c #0000721D0000",
+"` c #000073640000",
+"' c #000074070000",
+"] c #000074AB0000",
+"[ c #000075F50000",
+"{ c #000077090000",
+"} c #000077E70000",
+"| c #000079130000",
+" . c #000079DC0000",
+".. c #00007A840000",
+"X. c #00007BD50000",
+"o. c #00007CD40000",
+"O. c #00007E280000",
+"+. c #00007F280000",
+"@. c #00007FD40000",
+"#. c #000080800000",
+"$. c None",
+/* pixels */
+"$.$.@.@.@.@.@.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.$.$.",
+"$.@.@. #.#.$.",
+"@.@. #.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#. #.#.",
+"@. @.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#. #.",
+"#. #.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#. #.",
+"#. #.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#. #.",
+"#. #.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#. #.",
+"#. #.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#. #.",
+"#. #.#.#.#.#.#.#.#.#.#.#.#.#.#.@.@.@.@.@.@.@.@.#.#.#.#.#.#. #.",
+"#. #.#.#.#.#.#.#.#.#.#.#.#.#.#.#.@.@.@.#.@.@.@.#.#.#.#.#.#. #.",
+"#. #.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.@.@.#.#.@.@.#.@.@.#.#.#. #.",
+"#. #.#.#.#.#.#.#.#.#.#.#.#.#.#.@.@.Q F A v h v o.@.@.@.#.#. #.",
+"#. #.#.#.#.#.#.#.#.#.#.#.#.#.#.#.' v > * * * 1 A j c ) #.#. #.",
+"#. #.#.#.#.#.#.#.#.#.#.#.#.#.#.#.o.K t # @ > # q @ * c #.#. #.",
+"#. #.#.#.#.#.#.#.#.#.#.#.#.#.#.@.@.] B > * 3 # 1 q #.#. #.",
+"#. #.#.#.#.#.#.#.#.#.#.#.#.#.#.@.) B q * > * * q # v #.#. #.",
+"#. #.#.#.#.#.#.#.@.@.@.@.@.@.@.) v > * 1 # 7 3 7 j @.@. #.",
+"#. #.#.#.#.#.#.#.@.@.@.@.@.@.@.G 1 # > * # 7 7 7 @.@. #.",
+"#. #.#.#.#.@.#.#.#.@.@.@.#.@.@.B * * 3 # 1 3 7 @ j #.#. #.",
+"#. #.#.#.#.@.@.#.#.@.@...) ] ..c @ 1 1 i G I K # # E #.#. #.",
+"#. #.#.@.@.@.@.#.#.#.#.Q v A I t > 1 3 U @.@.U @ q o.#.#. #.",
+"#. #.#.@.@.@.@.#.#.#.#.E c c h > @ > 1 s ..@.] B # B @.#.#. #.",
+"#. #.#.o.@.@.@.#.#.#.#.] ' U t 1 3 > m ..@.) h * ' @.#.#. #.",
+"#. #.#.) ' ..@.#.#.#.#...U t @ @ 7 t t B U ' I 7 s #.#.#.#. #.",
+"#. #.#.c m F W ) ) ' ] G 3 @ 7 v K ..' K m j 1 K @.@.@.#. #.",
+"#. #.#...W A h i s v c 1 # t I o.@.@.@.@.o.I q o.@.@.@.#. #.",
+"#. #.#.@.@.o.@.@...U B s q t v K ) ] ....o.o.@.@.@.@.@.#.#. #.",
+"#. #.#.@.@.@.@.@.@.@.#.@.@.) F j q 7 h A W ..o.o.o.] ] #.#. #.",
+"#. #.@.#.#.#.#.#.#.#.#.#.#.#.@.@...E B s q q j h 7 E #. #.",
+"#.#. #.#.#.#.#.#.#.#.#.#.#.#.@.@.@.@.@.@.@.@.@.@.@.#. #.#.",
+"$.#.#. #.#.$.",
+"$.$.#.#.#.#.#.#.#.#.#.#.#.#.@.@.@.@.@.@.@.@.@.@.@.@.#.#.#.#.$.$."
+};
diff --git a/navit/xpm/sports.xpm b/navit/xpm/sports.xpm
new file mode 100644
index 000000000..567f8bb92
--- /dev/null
+++ b/navit/xpm/sports.xpm
@@ -0,0 +1,95 @@
+/* XPM */
+static char *sports[] = {
+/* columns rows colors chars-per-pixel */
+"16 16 73 1",
+" c black",
+". c #010101",
+"X c #000200",
+"o c #020202",
+"O c #0C0C0C",
+"+ c #001B00",
+"@ c #001C00",
+"# c #0D150D",
+"$ c #1E1E1E",
+"% c #002100",
+"& c #002300",
+"* c #003A00",
+"= c #003F00",
+"- c #1F251F",
+"; c #212D21",
+": c gray17",
+"> c #213421",
+", c gray19",
+"< c #343434",
+"1 c #393939",
+"2 c gray23",
+"3 c gray24",
+"4 c #054105",
+"5 c #004C00",
+"6 c #0E4E0E",
+"7 c #005100",
+"8 c #005B00",
+"9 c #025F02",
+"0 c #0B510B",
+"q c #006700",
+"w c #006D00",
+"e c #007A00",
+"r c #007D00",
+"t c #007E00",
+"y c #007F00",
+"u c #205720",
+"i c gray25",
+"p c #444444",
+"a c gray27",
+"s c #4E4E4E",
+"d c gray32",
+"f c #5B5B5B",
+"g c #5D5D5D",
+"h c #5D6B5D",
+"j c #606660",
+"k c #6D6D6D",
+"l c gray43",
+"z c #6F6F6F",
+"x c gray46",
+"c c #777777",
+"v c gray47",
+"b c gray50",
+"n c #008000",
+"m c #808080",
+"M c #808B80",
+"N c #838A83",
+"B c #828E82",
+"V c gray55",
+"C c #A7A7A7",
+"Z c #ADAEAD",
+"A c gray70",
+"S c #B6B6B6",
+"D c #C5C5C5",
+"F c #C8C8C8",
+"G c gray84",
+"H c #DADADA",
+"J c #DFDFDF",
+"K c gray91",
+"L c gray98",
+"P c gray99",
+"I c #FEFEFE",
+"U c gray100",
+"Y c None",
+/* pixels */
+"Y Y",
+" nnnnnnnnnnnn ",
+" nnnnnnnnnnnnnn ",
+" nnnny74*5ennnn ",
+" nnn9>SKdih8nnn ",
+" nnw#aIIxPIhqnn ",
+" nn& gk< zJ2@nn ",
+" nn-fII$ mk nn ",
+" nnZmIDs,3IH2nn ",
+" nnMi2vIIvFbNnn ",
+" nn6 <GPa :unn ",
+" nny&OCSV +ynn ",
+" nnny0BAS;=yynn ",
+" nnnnnnnnnynnnn ",
+" nnnnnnnnnnnn ",
+"Y Y"
+};
diff --git a/navit/xpm/swimming.xpm b/navit/xpm/swimming.xpm
new file mode 100644
index 000000000..72f371591
--- /dev/null
+++ b/navit/xpm/swimming.xpm
@@ -0,0 +1,138 @@
+/* XPM */
+static char * swimming_xpm[] = {
+"16 16 119 2",
+" c None",
+". c #262CA6",
+"+ c #242CA6",
+"@ c #242DA7",
+"# c #232EA8",
+"$ c #232DA7",
+"% c #2131AB",
+"& c #2032AC",
+"* c #2233AB",
+"= c #2031AB",
+"- c #222EA8",
+"; c #222FA8",
+"> c #1C33AC",
+", c #222EA7",
+"' c #0E44BC",
+") c #0B4CC2",
+"! c #5584BF",
+"~ c #B9C7D9",
+"{ c #EFF3F5",
+"] c #5987BF",
+"^ c #1243BD",
+"/ c #1C36AF",
+"( c #1E33AC",
+"_ c #1E33AB",
+": c #1B34AD",
+"< c #1937AE",
+"[ c #1B35AD",
+"} c #7B94B7",
+"| c #B3C1D3",
+"1 c #A4B7CE",
+"2 c #658ABD",
+"3 c #C0CEDE",
+"4 c #EEF1F4",
+"5 c #3778C9",
+"6 c #1D34AE",
+"7 c #212FA9",
+"8 c #3B69BD",
+"9 c #7190B9",
+"0 c #1048BC",
+"a c #212FA8",
+"b c #1935AF",
+"c c #1A35AE",
+"d c #1C35AD",
+"e c #2436AB",
+"f c #2230A9",
+"g c #0F46C0",
+"h c #183BB5",
+"i c #2051BC",
+"j c #E5EBEF",
+"k c #E3E9EF",
+"l c #2348B6",
+"m c #2446B4",
+"n c #F5F7F7",
+"o c #FEFFFB",
+"p c #93A8C1",
+"q c #1141B6",
+"r c #1A34AD",
+"s c #1E2FA8",
+"t c #173AB2",
+"u c #173CB4",
+"v c #2869C3",
+"w c #8799C4",
+"x c #D2D8E7",
+"y c #FEFEFE",
+"z c #D3DCE5",
+"A c #2739AC",
+"B c #EBF0F1",
+"C c #FDFEFA",
+"D c #869DBA",
+"E c #1F33AB",
+"F c #123CB4",
+"G c #1838B0",
+"H c #1A37AE",
+"I c #5A80B7",
+"J c #BDCAD9",
+"K c #F9FBF9",
+"L c #FCFDFB",
+"M c #FCFCFC",
+"N c #FCFCFA",
+"O c #C0CCDA",
+"P c #266DC4",
+"Q c #437ABF",
+"R c #084EC2",
+"S c #1D33AB",
+"T c #1837AF",
+"U c #3355B1",
+"V c #AFBED1",
+"W c #7C96B6",
+"X c #A8B9CE",
+"Y c #6B8DB7",
+"Z c #A2B6CC",
+"` c #7291B8",
+" . c #9BB0C9",
+".. c #7391B7",
+"+. c #93AAC3",
+"@. c #3E78C0",
+"#. c #1441B7",
+"$. c #1A3AAF",
+"%. c #0349BD",
+"&. c #2A37A8",
+"*. c #516BAE",
+"=. c #7E96B4",
+"-. c #6788B5",
+";. c #8098B6",
+">. c #6588B7",
+",. c #859CB9",
+"'. c #6C8DB6",
+"). c #7A96B6",
+"!. c #6C8BB6",
+"~. c #7E97B6",
+"{. c #5F84B7",
+"]. c #7790B3",
+"^. c #4375B9",
+"/. c #708CB2",
+"(. c #2F64B3",
+"_. c #1B35AC",
+":. c #252CA6",
+"<. c #2130A9",
+"[. c #1F32AB",
+". . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . + ",
+"@ # $ # % & * & & = - + - $ ; > ",
+", - ' ) ! ~ { ] ^ . = / ( _ . : ",
+"< [ } | 1 2 3 4 5 6 7 8 9 0 a b ",
+"c d e f g h i j k l m n o p q . ",
+"r s t u v w x y y z A B C D E F ",
+"G H I J K L y M y N O P Q R S T ",
+". U V W X Y Z ` ...+.@.#._ $.%.",
+"&.*.=.-.;.>.,.'.).!.~.{.].^./.(.",
+"_.:.. . :.:.<.[.<.# ; ; - - , , ",
+":.. . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . ",
+":.. . . . . . . . . . . . . . . "};
diff --git a/navit/xpm/telephone.xpm b/navit/xpm/telephone.xpm
new file mode 100644
index 000000000..c788ef8c2
--- /dev/null
+++ b/navit/xpm/telephone.xpm
@@ -0,0 +1,38 @@
+/* XPM */
+static char * telephone_xpm[] = {
+"9 10 25 1",
+" c None",
+". c #FFFFFF",
+"+ c #F5F5F5",
+"@ c #838383",
+"# c #464646",
+"$ c #555555",
+"% c #EEEEEE",
+"& c #161616",
+"* c #404040",
+"= c #757575",
+"- c #DFDFDF",
+"; c #000000",
+"> c #C8C8C8",
+", c #FAFAFA",
+"' c #E9E9E9",
+") c #0F0F0F",
+"! c #9B9B9B",
+"~ c #373737",
+"{ c #262626",
+"] c #A1A1A1",
+"^ c #A9A9A9",
+"/ c #E4E4E4",
+"( c #535353",
+"_ c #7F7F7F",
+": c #D4D4D4",
+" ..++. ",
+"..@#$.. ",
+".%&*=.. ",
+".-;>,. ",
+".')!... ",
+"..~{,... ",
+"..];^./..",
+" .+({_(].",
+" ..+(;{_.",
+" ...-:.."};
diff --git a/navit/xpm/theater.xpm b/navit/xpm/theater.xpm
new file mode 100644
index 000000000..9581bc701
--- /dev/null
+++ b/navit/xpm/theater.xpm
@@ -0,0 +1,72 @@
+/* XPM */
+static char * theater_xpm[] = {
+"16 15 54 1",
+" c None",
+". c #FFFFFF",
+"+ c #CFCFCF",
+"@ c #808080",
+"# c #D8D8D8",
+"$ c #F7F7F7",
+"% c #F5F5F5",
+"& c #DEDEDE",
+"* c #A2A2A2",
+"= c #393939",
+"- c #606060",
+"; c #9D9D9D",
+"> c #929292",
+", c #E5E5E5",
+"' c #4F4F4F",
+") c #5A5A5A",
+"! c #474747",
+"~ c #3F3F3F",
+"{ c #8B8B8B",
+"] c #979797",
+"^ c #767676",
+"/ c #E9E9E9",
+"( c #000000",
+"_ c #575757",
+": c #494949",
+"< c #232323",
+"[ c #050505",
+"} c #2E2E2E",
+"| c #333333",
+"1 c #EBEBEB",
+"2 c #7D7D7D",
+"3 c #BABABA",
+"4 c #BEBEBE",
+"5 c #666666",
+"6 c #1D1D1D",
+"7 c #AAAAAA",
+"8 c #2B2B2B",
+"9 c #505050",
+"0 c #B7B7B7",
+"a c #272727",
+"b c #121212",
+"c c #161616",
+"d c #D6D6D6",
+"e c #9A9A9A",
+"f c #C3C3C3",
+"g c #6D6D6D",
+"h c #0A0A0A",
+"i c #343434",
+"j c #454545",
+"k c #6B6B6B",
+"l c #EEEEEE",
+"m c #787878",
+"n c #0C0C0C",
+"o c #CACACA",
+" ... ..++.",
+" .. .+@#$%&*=-.",
+".;>. .,'')'!!)~%",
+".{]^$./!(_(=@==%",
+".{.*---:<][}}_|1",
+".23*4.,567!83#94",
+"&2/>&/0)a^:@bc'3",
+"def3@#g='(}](h9/",
+".g..),.$'}c]@ij%",
+".k70_l*1<:@>7mk.",
+".@7}fmk9{:2n8~+.",
+".#g8(|_o.m:9=@. ",
+" .-7k_7. .*>d$ ",
+" .+9^)$ ... ",
+" .%/% "};
diff --git a/navit/xpm/tower.xpm b/navit/xpm/tower.xpm
new file mode 100644
index 000000000..2bf27687d
--- /dev/null
+++ b/navit/xpm/tower.xpm
@@ -0,0 +1,35 @@
+/* XPM */
+static char *tower[] = {
+/* columns rows colors chars-per-pixel */
+"10 16 13 1",
+" c black",
+". c #131313",
+"X c gray8",
+"o c #1B1B1B",
+"O c #1E1E1E",
+"+ c #252525",
+"@ c gray15",
+"# c gray21",
+"$ c gray25",
+"% c #797979",
+"& c #AEAEAE",
+"* c #D7D7D7",
+"= c gray100",
+/* pixels */
+"==========",
+"====%%====",
+"===& &===",
+"===&oo&===",
+"===* *===",
+"==== ====",
+"==== ====",
+"====##====",
+"====$#====",
+"====o@====",
+"====OO====",
+"====.X====",
+"====@@====",
+"====..====",
+"==== ====",
+"==== ===="
+};
diff --git a/navit/xpm/townhall.xpm b/navit/xpm/townhall.xpm
new file mode 100644
index 000000000..150b26f96
--- /dev/null
+++ b/navit/xpm/townhall.xpm
@@ -0,0 +1,109 @@
+/* XPM */
+static char * townhall_xpm[] = {
+"16 18 88 1",
+" c None",
+". c #BF0000",
+"+ c #CE0000",
+"@ c #A80000",
+"# c #C20000",
+"$ c #5C652F",
+"% c #5D6630",
+"& c #808C42",
+"* c #818D42",
+"= c #5B642F",
+"- c #5D662F",
+"; c #808C41",
+"> c #5B632E",
+", c #111208",
+"' c #2B2F16",
+") c #535A2A",
+"! c #535B2B",
+"~ c #535C2A",
+"{ c #545C2B",
+"] c #555C2B",
+"^ c #555D2B",
+"/ c #535B2A",
+"( c #292D14",
+"_ c #454C23",
+": c #565F2C",
+"< c #5D6730",
+"[ c #5A632E",
+"} c #424822",
+"| c #363B1C",
+"1 c #414621",
+"2 c #4A5026",
+"3 c #484F25",
+"4 c #454B23",
+"5 c #495026",
+"6 c #484E25",
+"7 c #444922",
+"8 c #3A401D",
+"9 c #32361A",
+"0 c #484D2A",
+"a c #888888",
+"b c #66685F",
+"c c #4E542D",
+"d c #72736F",
+"e c #6C6E66",
+"f c #51582E",
+"g c #6E6E68",
+"h c #80807F",
+"i c #4C512B",
+"j c #272B14",
+"k c #6B743E",
+"l c #9E9E9E",
+"m c #7D7E76",
+"n c #75803C",
+"o c #8F8F8F",
+"p c #7E7E7A",
+"q c #7F8B41",
+"r c #81827E",
+"s c #6A743C",
+"t c #75716C",
+"u c #68665D",
+"v c #7C5A20",
+"w c #6E531E",
+"x c #33371E",
+"y c #505730",
+"z c #9A9A9A",
+"A c #75766E",
+"B c #58602D",
+"C c #78571E",
+"D c #684F1D",
+"E c #5C6430",
+"F c #7B7C78",
+"G c #989898",
+"H c #50572E",
+"I c #4B5227",
+"J c #5D6531",
+"K c #67695B",
+"L c #5A5D45",
+"M c #59602E",
+"N c #564A1F",
+"O c #554B20",
+"P c #5D6430",
+"Q c #5F624E",
+"R c #626454",
+"S c #5C6431",
+"T c #444A23",
+"U c #373C1C",
+"V c #434922",
+"W c #393E1D",
+" .+ ",
+" @# ",
+" ",
+" $% ",
+" $&**&= ",
+" -&******;> ",
+",')!~~{{{{]^^/( ",
+"_:<<<<<<<<<<<<[}",
+" |123456}3578 ",
+" 90abcdefghij ",
+" klmnopqrls ",
+" klmnopqrls ",
+" klmnopqrls ",
+" klmntuqrls ",
+" klmnvwqrls ",
+" xyzABCDEFGH ",
+" IJKLMNOPQRST ",
+"UV_4444444444_VW"};
diff --git a/navit/xpm/traffic_signals.xpm b/navit/xpm/traffic_signals.xpm
new file mode 100644
index 000000000..e98567951
--- /dev/null
+++ b/navit/xpm/traffic_signals.xpm
@@ -0,0 +1,139 @@
+/* XPM */
+static char * traffic_signals_xpm[] = {
+"16 16 120 2",
+" c None",
+". c #FBF9F9",
+"+ c #D2D2D2",
+"@ c #CCCCCC",
+"# c #C5C2C2",
+"$ c #C4BFBD",
+"% c #D3CFC9",
+"& c #DDDDDC",
+"* c #FFFEFC",
+"= c #F0EFEF",
+"- c #2D2B2B",
+"; c #3D1618",
+"> c #5F0101",
+", c #5F0205",
+"' c #42221E",
+") c #5B5A59",
+"! c #EEECEC",
+"~ c #0C0505",
+"{ c #8C0007",
+"] c #E90002",
+"^ c #E80103",
+"/ c #5A0202",
+"( c #433D3A",
+"_ c #F0EDED",
+": c #490E0D",
+"< c #CF0006",
+"[ c #F70301",
+"} c #F20200",
+"| c #9A0300",
+"1 c #483937",
+"2 c #EFEAEA",
+"3 c #250A09",
+"4 c #8B0202",
+"5 c #E70401",
+"6 c #E00004",
+"7 c #520002",
+"8 c #4D3E3F",
+"9 c #FCFAFA",
+"0 c #EDE4E4",
+"a c #0D0606",
+"b c #1F0603",
+"c c #843B01",
+"d c #652703",
+"e c #110302",
+"f c #423939",
+"g c #F9F8F8",
+"h c #EEE8E9",
+"i c #171408",
+"j c #8D9202",
+"k c #E7ED02",
+"l c #E1E602",
+"m c #5F5900",
+"n c #5C4644",
+"o c #F7F6F6",
+"p c #EFE9E9",
+"q c #362F06",
+"r c #C8CB02",
+"s c #F9FE02",
+"t c #F8FD03",
+"u c #ABB100",
+"v c #635045",
+"w c #F8F8F8",
+"x c #2C2509",
+"y c #B9BE04",
+"z c #F5FF03",
+"A c #F8FE02",
+"B c #929C00",
+"C c #624E48",
+"D c #EEE9E9",
+"E c #110906",
+"F c #4C5001",
+"G c #BBC401",
+"H c #A1A603",
+"I c #2D2D05",
+"J c #5F494C",
+"K c #0C0908",
+"L c #013703",
+"M c #058301",
+"N c #017306",
+"O c #002303",
+"P c #5E464A",
+"Q c #081C04",
+"R c #029A07",
+"S c #02D204",
+"T c #02D104",
+"U c #027403",
+"V c #524843",
+"W c #FCFCFC",
+"X c #EFEBE9",
+"Y c #0C2906",
+"Z c #02AB03",
+"` c #00D108",
+" . c #02D307",
+".. c #029705",
+"+. c #383E37",
+"@. c #FDFDFD",
+"#. c #EFEDEB",
+"$. c #0A170A",
+"%. c #067905",
+"&. c #02C005",
+"*. c #02B704",
+"=. c #095003",
+"-. c #4A3F3E",
+";. c #F7F7F7",
+">. c #F1EEEB",
+",. c #252321",
+"'. c #0B1A07",
+"). c #104809",
+"!. c #123F09",
+"~. c #101208",
+"{. c #565454",
+"]. c #FEFEFE",
+"^. c #FCFAF8",
+"/. c #CCCAC8",
+"(. c #C4C2C1",
+"_. c #C5C1C1",
+":. c #C6C2C2",
+"<. c #C4C3C3",
+"[. c #DCDBDB",
+"}. c #FFFEFE",
+" . + @ # $ % & * ",
+" = - ; > , ' ) ",
+" ! ~ { ] ^ / ( ",
+" _ : < [ } | 1 ",
+" 2 3 4 5 6 7 8 9 ",
+" 0 a b c d e f g ",
+" h i j k l m n o ",
+" p q r s t u v w ",
+" p x y z A B C ",
+" D E F G H I J ",
+" D K L M N O P ",
+" D Q R S T U V W ",
+" X Y Z ` ...+.@. ",
+" #.$.%.&.*.=.-.;. ",
+" >.,.'.).!.~.{.]. ",
+" ^./.(._.:.<.[.}. "};
diff --git a/navit/xpm/trailerpark.xpm b/navit/xpm/trailerpark.xpm
new file mode 100644
index 000000000..6864ea8f4
--- /dev/null
+++ b/navit/xpm/trailerpark.xpm
@@ -0,0 +1,110 @@
+/* XPM */
+static char * trailerpark_xpm[] = {
+"16 16 91 1",
+" c #325692",
+". c #335692",
+"+ c #335592",
+"@ c #325592",
+"# c #325591",
+"$ c #335690",
+"% c #335593",
+"& c #8195B7",
+"* c #BCC7D9",
+"= c #C4CEDE",
+"- c #CCD5E3",
+"; c #D3DAE3",
+"> c #D8DEE8",
+", c #DDE3EB",
+"' c #DFE5EC",
+") c #D9E1E9",
+"! c #D5DCE6",
+"~ c #D2D8E2",
+"{ c #CAD3E0",
+"] c #C1CCDB",
+"^ c #8D9FBD",
+"/ c #345590",
+"( c #F3F5F8",
+"_ c #FEFEFD",
+": c #FDFEFD",
+"< c #FDFFFD",
+"[ c #FFFFFF",
+"} c #FEFFFE",
+"| c #FCFFFC",
+"1 c #FDFEFE",
+"2 c #DFE5EB",
+"3 c #F6F9FA",
+"4 c #C0C9DA",
+"5 c #3B5B94",
+"6 c #3A5B93",
+"7 c #B3C0D5",
+"8 c #FCFDFE",
+"9 c #3D5C92",
+"0 c #C9D1DE",
+"a c #335591",
+"b c #BCC8DA",
+"c c #B1BED4",
+"d c #FBFDFE",
+"e c #355791",
+"f c #C8D0DD",
+"g c #DFE4EB",
+"h c #CED6E1",
+"i c #6A83AC",
+"j c #6B83AC",
+"k c #C4CFDF",
+"l c #FFFFFE",
+"m c #FCFDFD",
+"n c #6C84AC",
+"o c #6A83AD",
+"p c #D6DCE4",
+"q c #FFFEFE",
+"r c #E0E6ED",
+"s c #99AAC5",
+"t c #D1DAE4",
+"u c #FEFEFE",
+"v c #355793",
+"w c #37588E",
+"x c #F6F8FA",
+"y c #F4F7F8",
+"z c #869AB9",
+"A c #E3EBF0",
+"B c #95A7C1",
+"C c #E0E5ED",
+"D c #DEE4EB",
+"E c #788FB7",
+"F c #A9BAD2",
+"G c #ADBBD1",
+"H c #91A4C2",
+"I c #C7D1DE",
+"J c #3D5F94",
+"K c #D0D7E2",
+"L c #7C92B6",
+"M c #8FA1C1",
+"N c #5C79A6",
+"O c #92A2C2",
+"P c #A6B5CB",
+"Q c #B7C2D4",
+"R c #C3CCDB",
+"S c #325693",
+"T c #3E5E98",
+"U c #546FA1",
+"V c #395994",
+"W c #7087B1",
+"X c #3F5F99",
+"Y c #345593",
+"Z c #345592",
+" . ++@#$%+++ ",
+" .&*=-;>,')!~{]^",
+" /(_:<:[}|<__:12",
+" $34567[89666502",
+" a3b+.c[de+.++fg",
+" a3hijklmniiiopg",
+" a3[[[}[[[[[[lqg",
+" a3[[[[l[l[[[[lg",
+" a3[[[[rstu[[[lg",
+"vwxuuuyzABCuuuuD",
+"EFGGGGHIJKLGGGGM",
+"NO PQR% S",
+"TU VWX S",
+" Y Z % S",
+" S",
+" ++++++++++++++."};
diff --git a/navit/xpm/unknown.xpm b/navit/xpm/unknown.xpm
new file mode 100644
index 000000000..8f6835f22
--- /dev/null
+++ b/navit/xpm/unknown.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"13 14 3 1",
+/* colors */
+" c yellow",
+". c blue",
+"X c None",
+/* pixels */
+" ",
+" ........... ",
+" ... ... ",
+" .. ..... .. ",
+" ........ .. ",
+" ........ .. ",
+" ...... ... ",
+" ..... ..... ",
+" ..... ..... ",
+" ........... ",
+" ..... ..... ",
+" ........... ",
+" ........... ",
+" "
+};
diff --git a/navit/zipfile.h b/navit/zipfile.h
new file mode 100644
index 000000000..695576d35
--- /dev/null
+++ b/navit/zipfile.h
@@ -0,0 +1,55 @@
+#ifndef __ZIPFILE_H__
+
+struct zip_lfh {
+ int ziplocsig;
+ short zipver;
+ short zipgenfld;
+ short zipmthd;
+ short ziptime;
+ short zipdate;
+ int zipcrc;
+ unsigned int zipsize;
+ unsigned int zipuncmp;
+ unsigned short zipfnln;
+ unsigned short zipxtraln;
+ char zipname[0];
+} __attribute__ ((packed));
+
+struct zip_cd {
+ int zipcensig;
+ char zipcver;
+ char zipcos;
+ char zipcvxt;
+ char zipcexos;
+ short zipcflg;
+ short zipcmthd;
+ short ziptim;
+ short zipdat;
+ int zipccrc;
+ unsigned int zipcsiz;
+ unsigned int zipcunc;
+ unsigned short zipcfnl;
+ unsigned short zipcxtl;
+ unsigned short zipccml;
+ unsigned short zipdsk;
+ unsigned short zipint;
+ unsigned int zipext;
+ unsigned int zipofst;
+ char zipcfn[0];
+} __attribute__ ((packed));
+
+struct zip_eoc {
+ int zipesig;
+ unsigned short zipedsk;
+ unsigned short zipecen;
+ unsigned short zipenum;
+ unsigned short zipecenn;
+ unsigned int zipecsz;
+ unsigned int zipeofst;
+ short zipecoml;
+ char zipecom[0];
+} __attribute__ ((packed));
+
+#define __ZIPFILE_H__
+
+#endif