summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Perrier <bubulle@debian.org>2012-10-07 13:27:36 +0100
committerChristian Perrier <bubulle@debian.org>2012-10-07 13:27:36 +0100
commit99f5c8bf63a674faf8c507aea7425b935814548a (patch)
treeb3202c295c4bb71ec09e3748d49b43a9fec6b4cd /src
gpsdrive (2.10~pre4-6.dfsg-5.2) unstable; urgency=low
* Non-maintainer upload [ Allison Randal ] * Disable optional mapnik libraries, gpsdrive is incompatible with APIs of mapnik version 2.0.0. * debian/patches/107-fix-disable-mapnik.dpatch: Fix known bug with gpsdrive-2.10pre4 when disabling Mapnik library. # imported from the archive
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt168
-rw-r--r--src/LatLong-UTMconversion.c176
-rw-r--r--src/LatLong-UTMconversion.h15
-rw-r--r--src/Makefile.am92
-rw-r--r--src/Makefile.in770
-rw-r--r--src/battery.c858
-rw-r--r--src/battery.h42
-rw-r--r--src/download_map.c1005
-rw-r--r--src/download_map.h61
-rw-r--r--src/draw_grid.c258
-rw-r--r--src/friends.c693
-rw-r--r--src/friendsd.c611
-rw-r--r--src/geometry.c143
-rw-r--r--src/gettext.h265
-rw-r--r--src/gps_handler.c994
-rw-r--r--src/gps_handler.h62
-rw-r--r--src/gpsdrive-nosql.spec46
-rw-r--r--src/gpsdrive.c3453
-rw-r--r--src/gpsdrive.h418
-rw-r--r--src/gpsdrive.spec74
-rw-r--r--src/gpsdrive.spec.fc5130
-rw-r--r--src/gpsdrive_config.c612
-rw-r--r--src/gpsdrive_config.h111
-rw-r--r--src/gpskismet.c368
-rw-r--r--src/gpskismet.h32
-rw-r--r--src/gpsmisc.c500
-rw-r--r--src/gpsnasamap.c362
-rw-r--r--src/gpsproto.h105
-rw-r--r--src/gpssql.c634
-rw-r--r--src/gui.c867
-rw-r--r--src/gui.h108
-rw-r--r--src/icons.c393
-rw-r--r--src/icons.h49
-rw-r--r--src/import_map.c835
-rw-r--r--src/import_map.h59
-rw-r--r--src/lib_map/CMakeLists.txt36
-rw-r--r--src/lib_map/Makefile.am23
-rw-r--r--src/lib_map/Makefile.in606
-rw-r--r--src/lib_map/map.h212
-rw-r--r--src/lib_map/map_draw.c473
-rw-r--r--src/lib_map/map_gpsmisc.c182
-rw-r--r--src/lib_map/map_load.c574
-rw-r--r--src/lib_map/map_port.c484
-rw-r--r--src/lib_map/map_port_cpp.cpp123
-rw-r--r--src/lib_map/map_priv.h92
-rw-r--r--src/lib_map/map_render.c1208
-rw-r--r--src/lib_map/map_render_cpp.cpp45
-rw-r--r--src/lib_map/map_transform.c591
-rw-r--r--src/main_gui.c1850
-rw-r--r--src/main_gui.h50
-rw-r--r--src/map_handler.c1052
-rw-r--r--src/map_handler.h6
-rw-r--r--src/map_projection.c345
-rw-r--r--src/mapnik.cpp462
-rw-r--r--src/mapnik.h34
-rw-r--r--src/navigation.c36
-rw-r--r--src/navigation_gui.c32
-rw-r--r--src/nmea_handler.c875
-rw-r--r--src/nmea_handler.h50
-rw-r--r--src/poi.c1392
-rw-r--r--src/poi.h113
-rw-r--r--src/poi_gui.c1346
-rw-r--r--src/poi_gui.h37
-rw-r--r--src/routes.c1135
-rw-r--r--src/routes.h65
-rw-r--r--src/settings.c2223
-rw-r--r--src/settings_gui.c32
-rw-r--r--src/speech_out.c662
-rw-r--r--src/speech_out.h45
-rw-r--r--src/speech_strings.c368
-rw-r--r--src/speech_strings.h83
-rw-r--r--src/splash.c654
-rw-r--r--src/splash.h40
-rw-r--r--src/track.c357
-rw-r--r--src/track.h51
-rw-r--r--src/unit_test.c887
-rw-r--r--src/util/CMakeLists.txt44
-rw-r--r--src/util/Makefile.am51
-rw-r--r--src/util/Makefile.in599
-rw-r--r--src/util/gmapview.c601
-rw-r--r--src/util/gps.c60
-rw-r--r--src/util/mmapview.c762
-rw-r--r--src/util/qmapview.cpp633
-rw-r--r--src/util/wmapview.c653
-rw-r--r--src/util/worldgen.c126
-rw-r--r--src/waypoint.c1087
-rw-r--r--src/waypoint.h52
-rw-r--r--src/wlan.c490
-rw-r--r--src/wlan.h75
89 files changed, 39533 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..803730c
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,168 @@
+project(gpsdrive_src)
+
+add_subdirectory(lib_map)
+add_subdirectory(util)
+
+find_package(Gettext REQUIRED)
+find_package(X11 REQUIRED)
+find_package(GTK2 REQUIRED)
+find_package(GDAL REQUIRED)
+find_package(PNG REQUIRED)
+find_package(Fontconfig REQUIRED)
+find_package(MySQL REQUIRED)
+find_package(XML2 REQUIRED)
+find_package(Boost REQUIRED)
+find_package(Qt4 REQUIRED)
+find_package(Freetype2 REQUIRED)
+
+if (WITH_MAPNIK)
+ find_package(Mapnik REQUIRED)
+endif (WITH_MAPNIK)
+
+
+set(GPSDRIVE_PUBLIC_INCLUDE_DIRS
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_BINARY_DIR}
+ CACHE INTERNAL "gpsdrive public include directories"
+)
+
+set(GPSDRIVE_PRIVATE_INCLUDE_DIRS
+ ${LIBMAP_PUBLIC_INCLUDE_DIRS}
+ ${GTK2_INCLUDE_DIRS}
+ ${PNG_INCLUDE_DIRS}
+ ${MYSQL_INCLUDE_DIR}
+ ${GDAL_INCLUDE_DIRS}
+ ${XML2_INCLUDE_DIRS}
+ ${MAPNIK_INCLUDE_DIRS}
+ ${FREETYPE2_INCLUDE_DIRS}
+ ${BOOST_INCLUDE_DIRS}
+ ${QT_QTGUI_INCLUDE_DIR}
+)
+
+set(GPSDRIVE_LINK_LIBRARIES
+ gpsdrive
+ map
+ crypt
+ ${GDAL_LIBRARIES}
+ ${FONTCONFIG_LIBRARIES}
+ ${GETTEXT_LIBRARIES}
+ ${GTK2_LIBRARIES}
+ ${GDAL_LIBRARIES}
+ ${PNG_LIBRARIES}
+ ${XML2_LIBRARIES}
+ ${MAPNIK_LIBRARIES}
+ ${FREETYPE_LIBRARIES}
+ ${BOOST_FILESYSTEM_LIBRARY}
+ ${QT_QTGUI_LIBRARY}
+)
+
+set(gpsdrive_SRCS
+ battery.c
+ battery.h
+ download_map.c
+ draw_grid.c
+ friends.c
+ geometry.c
+ gettext.h
+ gpsdrive.c
+ gpsdrive_config.c
+ gps_handler.c
+ gps_handler.h
+ gpskismet.c
+ gpsmisc.c
+ gpsnasamap.c
+ gpssql.c
+ gui.c
+ gui.h
+ icons.c
+ icons.h
+ import_map.c
+ LatLong-UTMconversion.c
+ main_gui.c
+ map_handler.c
+ map_projection.c
+ navigation.c
+ navigation_gui.c
+ nmea_handler.c
+ poi.c
+ poi_gui.c
+ poi.h
+ routes.c
+ settings.c
+ settings_gui.c
+ speech_out.c
+ speech_out.h
+ speech_strings.c
+ splash.c
+ streets.c
+ track.c
+ track.h
+ unit_test.c
+ waypoint.c
+ wlan.c
+)
+
+if (WITH_MAPNIK)
+ set(gpsdrive_SRCS
+ ${gpsdrive_SRCS}
+ mapnik.cpp
+ )
+endif (WITH_MAPNIK)
+
+SET(garmin_SRCS
+ garmin_application.cpp
+ garmin_application.h
+ garmin_command.h
+ garmin_data.cpp
+ garmin_data.h
+ garmin_error.h
+ garmin_legacy.cpp
+ garmin_legacy.h
+ garmin_link.cpp
+ garmin_link.h
+ garmin_packet.h
+ garmin_phys.h
+ garmin_serial.h
+ garmin_serial_unix.cpp
+ garmin_serial_unix.h
+ garmin_types.h
+ garmin_util.cpp
+ garmin_util.h
+ gpsdrivegarble.cpp
+)
+
+# gpsdrive i18n
+MACRO_GENERATE_PO_FILES(${CMAKE_SOURCE_DIR}/po ${APPLICATION_NAME} gpsdrive_SRCS)
+
+SET(friendsd_SRCS
+ friendsd.c
+ gpsdrive.h
+)
+
+include_directories(
+ ${GPSDRIVE_PUBLIC_INCLUDE_DIRS}
+ ${GPSDRIVE_PRIVATE_INCLUDE_DIRS}
+)
+
+add_executable(gpsdrive ${gpsdrive_SRCS} ${garmin_SRCS})
+add_executable(friendsd ${friendsd_SRCS})
+
+target_link_libraries(${GPSDRIVE_LINK_LIBRARIES})
+
+if (DBUS_FOUND)
+ target_link_libraries(gpsdrive ${DBUS_LIBRARIES})
+endif (DBUS_FOUND)
+
+target_link_libraries(friendsd
+ crypt
+ ${GTK2_LIBRARIES}
+)
+
+install(
+ TARGETS
+ gpsdrive
+ friendsd
+ DESTINATION
+ ${BIN_INSTALL_DIR}
+)
+
diff --git a/src/LatLong-UTMconversion.c b/src/LatLong-UTMconversion.c
new file mode 100644
index 0000000..d716fd4
--- /dev/null
+++ b/src/LatLong-UTMconversion.c
@@ -0,0 +1,176 @@
+//LatLong- UTM conversion.cpp
+//Lat Long - UTM, UTM - Lat Long conversions
+//This file originated from http://www.gpsy.com/gpsinfo/geotoutm/
+// converted to C code by Russell Harding Jan, 2004 -- hardingr at cunap dot com
+
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "LatLong-UTMconversion.h"
+
+
+/*Reference ellipsoids derived from Peter H. Dana's website-
+ http://www.utexas.edu/depts/grg/gcraft/notes/datum/elist.html
+ Department of Geography, University of Texas at Austin
+ Internet: pdana@mail.utexas.edu
+ 3/22/95
+
+ Source
+ Defense Mapping Agency. 1987b. DMA Technical Report: Supplement to Department of Defense World Geodetic System
+ 1984 Technical Report. Part I and II. Washington, DC: Defense Mapping Agency
+*/
+const double PI = 3.14159265;
+const double FOURTHPI = 3.14159265 / 4.0;
+const double deg2rad = 3.14159265 / 180.0;
+const double rad2deg = 180.0 / 3.14159265;
+
+
+
+
+void
+LLtoUTM (const float Lat, const float Long,
+ float *UTMNorthing, float *UTMEasting, int *UTMZone)
+{
+ //converts lat/long to UTM coords. Equations from USGS Bulletin 1532
+ //East Longitudes are positive, West longitudes are negative.
+ //North latitudes are positive, South latitudes are negative
+ //Lat and Long are in decimal degrees
+ //Written by Chuck Gantz- chuck.gantz@globalstar.com
+
+ // float a = ellipsoid[ReferenceEllipsoid].EquatorialRadius;
+ float a = 6378137.0;
+ // float eccSquared = ellipsoid[ReferenceEllipsoid].eccentricitySquared;
+ float eccSquared = 0.00669438;
+ float k0 = 0.9996;
+
+ float LongOrigin;
+ float eccPrimeSquared;
+ float N, T, C, A, M;
+
+ //Make sure the longitude is between -180.00 .. 179.9
+ float LongTemp = (Long + 180) - (int) ((Long + 180) / 360) * 360 - 180; // -180.00 .. 179.9;
+
+ float LatRad = Lat * deg2rad;
+ float LongRad = LongTemp * deg2rad;
+ float LongOriginRad;
+ float Test;
+ int ZoneNumber;
+
+ ZoneNumber = (int) ((LongTemp + 180) / 6) + 1;
+
+ if (Lat >= 56.0 && Lat < 64.0 && LongTemp >= 3.0 && LongTemp < 12.0)
+ ZoneNumber = 32;
+
+ // Special zones for Svalbard
+ if (Lat >= 72.0 && Lat < 84.0)
+ {
+ if (LongTemp >= 0.0 && LongTemp < 9.0)
+ ZoneNumber = 31;
+ else if (LongTemp >= 9.0 && LongTemp < 21.0)
+ ZoneNumber = 33;
+ else if (LongTemp >= 21.0 && LongTemp < 33.0)
+ ZoneNumber = 35;
+ else if (LongTemp >= 33.0 && LongTemp < 42.0)
+ ZoneNumber = 37;
+ }
+ LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3; //+3 puts origin in middle of zone
+ LongOriginRad = LongOrigin * deg2rad;
+
+ //compute the UTM Zone from the latitude and longitude
+ // sprintf(UTMZone, "%f%c", ZoneNumber, UTMLetterDesignator(Lat));
+
+ *UTMZone = ZoneNumber;
+
+ eccPrimeSquared = (eccSquared) / (1 - eccSquared);
+
+ N = a / sqrt (1 - eccSquared * sin (LatRad) * sin (LatRad));
+ T = tan (LatRad) * tan (LatRad);
+ C = eccPrimeSquared * cos (LatRad) * cos (LatRad);
+ A = cos (LatRad) * (LongRad - LongOriginRad);
+
+ M = a * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 -
+ 5 * eccSquared * eccSquared * eccSquared / 256) * LatRad -
+ (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 +
+ 45 * eccSquared * eccSquared * eccSquared / 1024) * sin (2 *
+ LatRad)
+ + (15 * eccSquared * eccSquared / 256 +
+ 45 * eccSquared * eccSquared * eccSquared / 1024) *
+ sin (4 * LatRad) -
+ (35 * eccSquared * eccSquared * eccSquared / 3072) * sin (6 *
+ LatRad));
+
+ *UTMEasting = (float) (k0 * N * (A + (1 - T + C) * A * A * A / 6
+ + (5 - 18 * T + T * T + 72 * C -
+ 58 * eccPrimeSquared) * A * A *
+ A * A * A / 120) + 500000.0);
+
+ Test = (float) (k0 *
+ (M +
+ N * tan (LatRad) * (A * A / 2 +
+ (5 - T + 9 * C +
+ 4 * C * C) * A * A * A * A /
+ 24 + (61 - 58 * T + T * T +
+ 600 * C -
+ 330 * eccPrimeSquared) *
+ A * A * A * A * A * A / 720)));
+ // *UTMNorthing = (float)(k0*(M+N*tan(LatRad)*(A*A/2+(5-T+9*C+4*C*C)*A*A*A*A/24
+ // + (61-58*T+T*T+600*C-330*eccPrimeSquared)*A*A*A*A*A*A/720)));
+ *UTMNorthing = Test;
+ if (Lat < 0)
+ *UTMNorthing += 10000000.0; //10000000 meter offset for southern hemisphere
+}
+
+char
+UTMLetterDesignator (float Lat)
+{
+ //This routine determines the correct UTM letter designator for the given latitude
+ //returns 'Z' if latitude is outside the UTM limits of 84N to 80S
+ //Written by Chuck Gantz- chuck.gantz@globalstar.com
+ char LetterDesignator;
+
+ if ((84 >= Lat) && (Lat >= 72))
+ LetterDesignator = 'X';
+ else if ((72 > Lat) && (Lat >= 64))
+ LetterDesignator = 'W';
+ else if ((64 > Lat) && (Lat >= 56))
+ LetterDesignator = 'V';
+ else if ((56 > Lat) && (Lat >= 48))
+ LetterDesignator = 'U';
+ else if ((48 > Lat) && (Lat >= 40))
+ LetterDesignator = 'T';
+ else if ((40 > Lat) && (Lat >= 32))
+ LetterDesignator = 'S';
+ else if ((32 > Lat) && (Lat >= 24))
+ LetterDesignator = 'R';
+ else if ((24 > Lat) && (Lat >= 16))
+ LetterDesignator = 'Q';
+ else if ((16 > Lat) && (Lat >= 8))
+ LetterDesignator = 'P';
+ else if ((8 > Lat) && (Lat >= 0))
+ LetterDesignator = 'N';
+ else if ((0 > Lat) && (Lat >= -8))
+ LetterDesignator = 'M';
+ else if ((-8 > Lat) && (Lat >= -16))
+ LetterDesignator = 'L';
+ else if ((-16 > Lat) && (Lat >= -24))
+ LetterDesignator = 'K';
+ else if ((-24 > Lat) && (Lat >= -32))
+ LetterDesignator = 'J';
+ else if ((-32 > Lat) && (Lat >= -40))
+ LetterDesignator = 'H';
+ else if ((-40 > Lat) && (Lat >= -48))
+ LetterDesignator = 'G';
+ else if ((-48 > Lat) && (Lat >= -56))
+ LetterDesignator = 'F';
+ else if ((-56 > Lat) && (Lat >= -64))
+ LetterDesignator = 'E';
+ else if ((-64 > Lat) && (Lat >= -72))
+ LetterDesignator = 'D';
+ else if ((-72 > Lat) && (Lat >= -80))
+ LetterDesignator = 'C';
+ else
+ LetterDesignator = 'Z'; //This is here as an error flag to show that the Latitude is outside the UTM limits
+
+ return LetterDesignator;
+}
diff --git a/src/LatLong-UTMconversion.h b/src/LatLong-UTMconversion.h
new file mode 100644
index 0000000..6659a73
--- /dev/null
+++ b/src/LatLong-UTMconversion.h
@@ -0,0 +1,15 @@
+//LatLong- UTM conversion..h
+//definitions for lat/long to UTM and UTM to lat/lng conversions
+//This file originated from http://www.gpsy.com/gpsinfo/geotoutm/
+// converted to C code by Russell Harding Jan, 2004 -- hardingr at cunap dot com
+
+
+
+#ifndef LATLONGCONV
+#define LATLONGCONV
+
+void LLtoUTM(const float Lat, const float Long,
+ float *UTMNorthing, float *UTMEasting, int* UTMZone);
+char UTMLetterDesignator(float Lat);
+
+#endif
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..86d357c
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,92 @@
+if HAVE_GDAL
+SUBDIRS = lib_map util
+endif
+DIST_SUBDIRS = lib_map util
+
+if WITH_MAPNIK
+MAPNIK_LIBS=-lmapnik
+else
+MAPNIK_LIBS=
+endif
+
+# TODO: It's a really really bad Idea to hardcode these include Files
+DEFS=@DEFS@ -I. -I$(srcdir) -I.. \
+ -DLOCALEDIR=\"${localedir}\" -DDATADIR=\"${datadir}\" \
+ -DLIBDIR=\"${libdir}\" \
+ -DFRIENDSSERVERVERSION=\"${FRIENDSSERVERVERSION}\" \
+ ${NOGARMIN} ${NOPLUGINS} ${AMAPNIK}\
+ -I/usr/include/ \
+ -I/usr/local/include \
+ -I/opt/boost_1_35/include/boost-1_35 \
+ -I/usr/local/include/freetype2 \
+ -I/usr/include/freetype2 \
+ -I. \
+ -L/usr/local/lib
+
+# -I/usr/include/dbus-1.0/
+
+
+includedir = lib_map
+
+if DISABLEGARMIN
+PRG1=
+else
+#PRG1=garble
+PRG1=
+endif
+
+bin_PROGRAMS = $(PRG1) gpsdrive friendsd2
+LIBS=$(DBUS_LIBS) $(DBUS_GLIB_LIBS) -lfreetype $(MAPNIK_LIBS)
+
+if HAVE_DBUS
+INCLUDES = $(DBUS_CFLAGS) -DDBUS_API_SUBJECT_TO_CHANGE=1
+endif
+
+gpsdrive_LDADD=@LIBS@ $(LIBADD_DL)
+
+PRGS = gpsdrive.c splash.c splash.h gpsdrive_config.c gpsdrive_config.h \
+ navigation.c \
+ speech_out.c speech_out.h\
+ friends.c \
+ battery.c track.c poi.c wlan.c waypoint.c draw_grid.c settings.c \
+ battery.h track.h poi.h wlan.h waypoint.h gpsdrive.h \
+ gpssql.c gpskismet.c gpskismet.h icons.c icons.h \
+ gui.c gui.h poi_gui.c poi_gui.h \
+ main_gui.c main_gui.h \
+ navigation_gui.c settings_gui.c \
+ LatLong-UTMconversion.c LatLong-UTMconversion.h \
+ gpsnasamap.c gpsmisc.c geometry.c \
+ map_handler.c map_handler.h gpsproto.h \
+ import_map.c import_map.h\
+ routes.c routes.h \
+ download_map.c download_map.h \
+ map_projection.c \
+ speech_strings.c speech_strings.h \
+ gps_handler.c gps_handler.h nmea_handler.c nmea_handler.h \
+ unit_test.c \
+ mapnik.cpp mapnik.h \
+ ../config.h gettext.h
+# lib_map/lib_map.a
+
+if DISABLEGARMIN
+else
+#PRGS += garmin_data.cpp \
+# garmin_serial_unix.cpp garmin_application.cpp garmin_link.cpp \
+# garmin_util.cpp gpsdrivegarble.cpp garmin_legacy.cpp garmin_link.h\
+# garmin_serial_unix.h garmin_application.h garmin_packet.h garmin_types.h \
+# garmin_command.h garmin_phys.h garmin_util.h garmin_error.h garmin_serial.h\
+# garmin_legacy.h garmin_data.h
+endif
+gpsdrive_SOURCES= $(PRGS)
+
+
+if DISABLEGARMIN
+else
+#garble_SOURCES= garble.cpp garmin_legacy.cpp garmin_data.cpp \
+# garmin_serial_unix.cpp garmin_application.cpp garmin_link.cpp garmin_util.cpp
+endif
+
+friendsd2_SOURCES=friendsd.c
+friendsd2_LDADD = @LIBS@ $(LDADD) $(LIBINTL)
+
+EXTRA_DIST = gpsdrive.spec gpsdrive-nosql.spec gpsdrive.spec.fc5 CMakeLists.txt
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..e1c8ffc
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,770 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = $(am__EXEEXT_1) gpsdrive$(EXEEXT) friendsd2$(EXEEXT)
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_perl_modules.m4 \
+ $(top_srcdir)/m4/ac_check_socketlen_t.m4 \
+ $(top_srcdir)/m4/aq_check_gdal.m4 $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__EXEEXT_1 =
+am__installdirs = "$(DESTDIR)$(bindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_friendsd2_OBJECTS = friendsd.$(OBJEXT)
+friendsd2_OBJECTS = $(am_friendsd2_OBJECTS)
+am__DEPENDENCIES_1 =
+friendsd2_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__objects_1 = gpsdrive.$(OBJEXT) splash.$(OBJEXT) \
+ gpsdrive_config.$(OBJEXT) navigation.$(OBJEXT) \
+ speech_out.$(OBJEXT) friends.$(OBJEXT) battery.$(OBJEXT) \
+ track.$(OBJEXT) poi.$(OBJEXT) wlan.$(OBJEXT) \
+ waypoint.$(OBJEXT) draw_grid.$(OBJEXT) settings.$(OBJEXT) \
+ gpssql.$(OBJEXT) gpskismet.$(OBJEXT) icons.$(OBJEXT) \
+ gui.$(OBJEXT) poi_gui.$(OBJEXT) main_gui.$(OBJEXT) \
+ navigation_gui.$(OBJEXT) settings_gui.$(OBJEXT) \
+ LatLong-UTMconversion.$(OBJEXT) gpsnasamap.$(OBJEXT) \
+ gpsmisc.$(OBJEXT) geometry.$(OBJEXT) map_handler.$(OBJEXT) \
+ import_map.$(OBJEXT) routes.$(OBJEXT) download_map.$(OBJEXT) \
+ map_projection.$(OBJEXT) speech_strings.$(OBJEXT) \
+ gps_handler.$(OBJEXT) nmea_handler.$(OBJEXT) \
+ unit_test.$(OBJEXT) mapnik.$(OBJEXT)
+am_gpsdrive_OBJECTS = $(am__objects_1)
+gpsdrive_OBJECTS = $(am_gpsdrive_OBJECTS)
+gpsdrive_DEPENDENCIES = $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(friendsd2_SOURCES) $(gpsdrive_SOURCES)
+DIST_SOURCES = $(friendsd2_SOURCES) $(gpsdrive_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-exec-recursive install-info-recursive \
+ install-recursive installcheck-recursive installdirs-recursive \
+ pdf-recursive ps-recursive uninstall-info-recursive \
+ uninstall-recursive
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkgdatadir = @pkgdatadir@
+ACLOCAL = @ACLOCAL@
+AMAPNIK = @AMAPNIK@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_GLIB_LIBS = @DBUS_GLIB_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+
+# TODO: It's a really really bad Idea to hardcode these include Files
+DEFS = @DEFS@ -I. -I$(srcdir) -I.. \
+ -DLOCALEDIR=\"${localedir}\" -DDATADIR=\"${datadir}\" \
+ -DLIBDIR=\"${libdir}\" \
+ -DFRIENDSSERVERVERSION=\"${FRIENDSSERVERVERSION}\" \
+ ${NOGARMIN} ${NOPLUGINS} ${AMAPNIK}\
+ -I/usr/include/ \
+ -I/usr/local/include \
+ -I/opt/boost_1_35/include/boost-1_35 \
+ -I/usr/local/include/freetype2 \
+ -I/usr/include/freetype2 \
+ -I. \
+ -L/usr/local/lib
+
+DEPDIR = @DEPDIR@
+DISABLEGARMIN_FALSE = @DISABLEGARMIN_FALSE@
+DISABLEGARMIN_TRUE = @DISABLEGARMIN_TRUE@
+DISABLEPLUGINS_FALSE = @DISABLEPLUGINS_FALSE@
+DISABLEPLUGINS_TRUE = @DISABLEPLUGINS_TRUE@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRIENDSSERVERVERSION = @FRIENDSSERVERVERSION@
+GDAL_CFLAGS = @GDAL_CFLAGS@
+GDAL_CONFIG = @GDAL_CONFIG@
+GDAL_LDADD = @GDAL_LDADD@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GLIB_MKENUMS = @GLIB_MKENUMS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GOBJECT_QUERY = @GOBJECT_QUERY@
+GREP = @GREP@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+HAVE_DBUS_FALSE = @HAVE_DBUS_FALSE@
+HAVE_DBUS_TRUE = @HAVE_DBUS_TRUE@
+HAVE_GDAL_FALSE = @HAVE_GDAL_FALSE@
+HAVE_GDAL_TRUE = @HAVE_GDAL_TRUE@
+HAVE_GTK_FALSE = @HAVE_GTK_FALSE@
+HAVE_GTK_TRUE = @HAVE_GTK_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBADD_DL = @LIBADD_DL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = $(DBUS_LIBS) $(DBUS_GLIB_LIBS) -lfreetype $(MAPNIK_LIBS)
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NOGARMIN = @NOGARMIN@
+NOPLUGINS = @NOPLUGINS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PCRE_CONFIG = @PCRE_CONFIG@
+PERL = @PERL@
+PERL_PACKAGE_DIR = @PERL_PACKAGE_DIR@
+PKGCONFIG_CFLAGS = @PKGCONFIG_CFLAGS@
+PKGCONFIG_LIBS = @PKGCONFIG_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+POSUB = @POSUB@
+POW_LIB = @POW_LIB@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WITH_MAPNIK_FALSE = @WITH_MAPNIK_FALSE@
+WITH_MAPNIK_TRUE = @WITH_MAPNIK_TRUE@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XML_CFLAGS = @XML_CFLAGS@
+XML_LIBS = @XML_LIBS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+
+# -I/usr/include/dbus-1.0/
+includedir = lib_map
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+@HAVE_GDAL_TRUE@SUBDIRS = lib_map util
+DIST_SUBDIRS = lib_map util
+@WITH_MAPNIK_FALSE@MAPNIK_LIBS =
+@WITH_MAPNIK_TRUE@MAPNIK_LIBS = -lmapnik
+#PRG1=garble
+@DISABLEGARMIN_FALSE@PRG1 =
+@DISABLEGARMIN_TRUE@PRG1 =
+@HAVE_DBUS_TRUE@INCLUDES = $(DBUS_CFLAGS) -DDBUS_API_SUBJECT_TO_CHANGE=1
+gpsdrive_LDADD = @LIBS@ $(LIBADD_DL)
+PRGS = gpsdrive.c splash.c splash.h gpsdrive_config.c gpsdrive_config.h \
+ navigation.c \
+ speech_out.c speech_out.h\
+ friends.c \
+ battery.c track.c poi.c wlan.c waypoint.c draw_grid.c settings.c \
+ battery.h track.h poi.h wlan.h waypoint.h gpsdrive.h \
+ gpssql.c gpskismet.c gpskismet.h icons.c icons.h \
+ gui.c gui.h poi_gui.c poi_gui.h \
+ main_gui.c main_gui.h \
+ navigation_gui.c settings_gui.c \
+ LatLong-UTMconversion.c LatLong-UTMconversion.h \
+ gpsnasamap.c gpsmisc.c geometry.c \
+ map_handler.c map_handler.h gpsproto.h \
+ import_map.c import_map.h\
+ routes.c routes.h \
+ download_map.c download_map.h \
+ map_projection.c \
+ speech_strings.c speech_strings.h \
+ gps_handler.c gps_handler.h nmea_handler.c nmea_handler.h \
+ unit_test.c \
+ mapnik.cpp mapnik.h \
+ ../config.h gettext.h
+
+# lib_map/lib_map.a
+
+#PRGS += garmin_data.cpp \
+# garmin_serial_unix.cpp garmin_application.cpp garmin_link.cpp \
+# garmin_util.cpp gpsdrivegarble.cpp garmin_legacy.cpp garmin_link.h\
+# garmin_serial_unix.h garmin_application.h garmin_packet.h garmin_types.h \
+# garmin_command.h garmin_phys.h garmin_util.h garmin_error.h garmin_serial.h\
+# garmin_legacy.h garmin_data.h
+gpsdrive_SOURCES = $(PRGS)
+
+#garble_SOURCES= garble.cpp garmin_legacy.cpp garmin_data.cpp \
+# garmin_serial_unix.cpp garmin_application.cpp garmin_link.cpp garmin_util.cpp
+friendsd2_SOURCES = friendsd.c
+friendsd2_LDADD = @LIBS@ $(LDADD) $(LIBINTL)
+EXTRA_DIST = gpsdrive.spec gpsdrive-nosql.spec gpsdrive.spec.fc5 CMakeLists.txt
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .cpp .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+friendsd2$(EXEEXT): $(friendsd2_OBJECTS) $(friendsd2_DEPENDENCIES)
+ @rm -f friendsd2$(EXEEXT)
+ $(LINK) $(friendsd2_LDFLAGS) $(friendsd2_OBJECTS) $(friendsd2_LDADD) $(LIBS)
+gpsdrive$(EXEEXT): $(gpsdrive_OBJECTS) $(gpsdrive_DEPENDENCIES)
+ @rm -f gpsdrive$(EXEEXT)
+ $(CXXLINK) $(gpsdrive_LDFLAGS) $(gpsdrive_OBJECTS) $(gpsdrive_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LatLong-UTMconversion.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/battery.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/download_map.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/draw_grid.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/friends.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/friendsd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geometry.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gps_handler.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsdrive.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsdrive_config.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpskismet.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsmisc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpsnasamap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpssql.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icons.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/import_map.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main_gui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map_handler.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map_projection.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mapnik.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/navigation.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/navigation_gui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nmea_handler.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poi.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poi_gui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/routes.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/settings.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/settings_gui.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/speech_out.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/speech_strings.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splash.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/track.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unit_test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/waypoint.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wlan.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(mkdir_p) "$(distdir)/$$subdir" \
+ || exit 1; \
+ distdir=`$(am__cd) $(distdir) && pwd`; \
+ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+ (cd $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$top_distdir" \
+ distdir="$$distdir/$$subdir" \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(PROGRAMS)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \
+ clean clean-binPROGRAMS clean-generic clean-libtool \
+ clean-recursive ctags ctags-recursive distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-recursive distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-data install-data-am install-exec install-exec-am \
+ install-info install-info-am install-man install-strip \
+ installcheck installcheck-am installdirs installdirs-am \
+ maintainer-clean maintainer-clean-generic \
+ maintainer-clean-recursive mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool mostlyclean-recursive \
+ pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+ uninstall-binPROGRAMS uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/battery.c b/src/battery.c
new file mode 100644
index 0000000..6afb2e6
--- /dev/null
+++ b/src/battery.c
@@ -0,0 +1,858 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+/*
+ *
+ * Power-related (battery, APM) functions.
+ *
+ * This module exports an interface that is operating system independent.
+ * The supported OSes are Linux, FreeBSD and NetBSD.
+ *
+ * Code modularization and support for FreeBSD by Marco Molteni
+ * <molter@gufi.org>.
+ *
+ * NetBSD support by Berndt Josef Wulf
+ * <wulf@netbsd.org>
+ */
+
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <gpsdrive.h>
+#include <icons.h>
+#include <config.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <gpsdrive_config.h>
+
+/* APM is i386-specific. */
+#if defined(__FreeBSD__) && defined(__i386__)
+#include <fcntl.h>
+#include <machine/apm_bios.h>
+#endif /* __FreeBSD__ && __i386__ */
+
+#if defined (__NetBSD__) || (__OpenBSD__)
+#include <fcntl.h>
+#include <machine/apmvar.h>
+#include <sys/ioctl.h>
+#endif /* __NetBSD__ */
+
+
+#include "battery.h"
+
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+#if GTK_MINOR_VERSION < 2
+#define gdk_draw_pixbuf _gdk_draw_pixbuf
+#endif
+
+#include <speech_out.h>
+#include <speech_strings.h>
+#include "gui.h"
+
+extern gint mydebug;
+extern gint debug;
+extern color_struct colors;
+
+/* Global Values */
+gchar cputempstring[20] = "??";
+gchar batstring[20] = "??";
+gchar dir_proc[200] = "/proc"; // make it flexible for unit -tests
+GtkWidget *tempeventbox = NULL, *batteventbox = NULL;
+GtkTooltips *tooltip_temperature = NULL;
+GtkTooltips *tooltip_battery = NULL;
+
+/* --------------------*/
+gint batlevel = 125;
+gint battime = 0;
+gint batlevel_old = 125; /* battery level, range 0..100 */
+gint batloading = FALSE;
+gint bnatloading_old = FALSE; /* is the battery charging? */
+gint batcharge = FALSE;
+gint cputemp = -99;
+
+static gchar gradsym[] = "\xc2\xb0";
+extern GtkWidget *tempeventbox, *batteventbox;
+extern GtkTooltips *tooltip_temperature;
+static GdkPixbuf *img_powercharges = NULL, *img_powercord =
+ NULL, *img_battery = NULL;
+GtkWidget *frame_battery = NULL;
+GtkWidget *frame_temperature = NULL;
+GtkWidget *drawing_battery = NULL, *drawing_temp = NULL;
+
+#ifdef __linux__
+/* ******************************************************************
+ * Return TRUE on success, FALSE on error.
+ */
+static int
+battery_get_values_linux_apm (int *blevel, int *bloading, int *bcharge)
+{
+ FILE *battery = NULL;
+ gint i;
+ gint ret = FALSE;
+ gint p_bat_full = 0;
+ gint p_bat_current = 0;
+ gchar b[200];
+ char fn[200];
+ *bcharge = FALSE;
+ *bloading = FALSE;
+
+ if (mydebug > 99)
+ fprintf (stderr, "battery_get_values_linux_apm()\n");
+
+ // -------------------------------------------- apm
+ g_snprintf (fn, sizeof (fn), dir_proc);
+ g_strlcat (fn, "/apm", sizeof (fn));
+ battery = fopen (fn, "r");
+ if (battery != NULL)
+ {
+ int count = 0;
+ if (mydebug > 99)
+ fprintf (stderr, "battery_get_values_linux_apm(): APM\n");
+
+ count = fscanf (battery, "%s %s %s %x %s %x %d%% %s %s",
+ b, b, b, bloading, b, &i, blevel, b, b);
+ /* 1.16 1.2 0x03 0x01 0x00 0x01 99% -1 ? */
+ fclose (battery);
+
+ if (9 != count)
+ {
+ if (mydebug > 9)
+ fprintf (stderr, "Wrong Number (%d) of values in %s\n",
+ count, fn);
+ ret = FALSE;
+ }
+ else
+ {
+ ret = TRUE;
+ }
+
+ /*
+ * Bit 7 is set if we have a battery (laptop). If it isn't set,
+ * (desktop) then we don't want to display the battery.
+ */
+ if ((i & 0x80) != 0)
+ ret = FALSE;
+
+ };
+
+ if (mydebug > 60)
+ fprintf (stderr,
+ "battery_get_values_linux_apm(): p_bat_full: %d, "
+ "p_bat_current:%d\n", p_bat_full, p_bat_current);
+ if (p_bat_current != 0)
+ *blevel = (int) (((double) p_bat_current / p_bat_full) * 100.0);
+ /* fprintf(stderr,"blevel: %d\n",*blevel); */
+
+ return ret;
+
+}
+
+
+
+/* ******************************************************************
+ * we try if we have acpi
+ */
+static int
+battery_get_values_linux_acpi (int *blevel, int *bloading, int *bcharge,
+ int *btime)
+{
+ FILE *battery = NULL;
+ gint e, e1;
+ gint ret = FALSE;
+ gint p_bat_full = 0;
+ gint p_bat_current = 0;
+ gint p_bat_rate = 0;
+ gint vtemp;
+ gchar b[200], t[200], t2[200], t3[200];
+ DIR *dir;
+ struct dirent *ent;
+ char fn[200];
+ *bcharge = FALSE;
+ *bloading = FALSE;
+ gchar line[200];
+
+ g_snprintf (fn, sizeof (fn), dir_proc);
+ g_strlcat (fn, "/acpi/battery/", sizeof (fn));
+ dir = opendir (fn);
+ if (dir != NULL)
+ {
+ if (mydebug > 99)
+ fprintf (stderr, "battery_get_values_linux(): ACPI\n");
+ while ((ent = readdir (dir)) != NULL)
+ {
+ if (ent->d_name[0] != '.')
+ {
+ // ---------------------- /acpi/.../info
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/%s/info",
+ dir_proc, ent->d_name);
+ battery = fopen (fn, "r");
+ if (battery != NULL)
+ {
+ if (mydebug > 99)
+ fprintf (stderr,
+ "battery_get_values_linux(): found file %s\n",
+ fn);
+ while (fgets (line, sizeof (line), battery))
+ {
+ if (strcasestr (line, "last full"))
+ {
+ sscanf (line, "%s %s %s %s %[^\n]", t, t2, b, t3,
+ b);
+ e1 = sscanf (t3, "\n%d\n", &vtemp);
+ if (e1 == 1)
+ p_bat_full += vtemp;
+ ret = TRUE;
+ }
+ }
+ fclose (battery);
+ }
+ else
+ {
+ if (mydebug > 99)
+ fprintf (stderr,
+ "battery_get_values_linux(): missing File: '%s'\n",
+ fn);
+ }
+
+
+ // ---------------------- /acpi/.../state
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/%s/state",
+ dir_proc, ent->d_name);
+ battery = fopen (fn, "r");
+ if (NULL != battery)
+ {
+ if (mydebug > 30)
+ fprintf (stderr,
+ "battery_get_values_linux(): found file %s\n",
+ fn);
+ while (fgets (line, sizeof (line), battery))
+ {
+ if (strcasestr (line, "remaining capacity"))
+ {
+ e = sscanf (line,
+ "%s %s %s %s %[^\n]", t, t2, t3, b, b);
+
+ e1 = sscanf (t3, "\n%d\n", &vtemp);
+ if (e1 == 1)
+ p_bat_current += vtemp;
+ ret = TRUE;
+ }
+
+ if (strcasestr (line, "present rate"))
+ {
+ e = sscanf (line, "%s %s %d %s", t, t2, &vtemp, b);
+ p_bat_rate += vtemp;
+ }
+
+ sscanf (line, "%s%[^\n]", t, t2);
+ if (mydebug > 30)
+ fprintf (stderr,
+ "battery_get_values_linux(): line: %s",
+ line);
+ if (strstr (t, "Status:"))
+ {
+ if (strstr (t2, "on-line"))
+ *bloading = TRUE;
+ else
+ *bloading = FALSE;
+ ret = TRUE;
+ }
+ if (strstr (t, "charging"))
+ {
+ /* assume we are charging, unless
+ * discharging or unknown. */
+ *bloading = TRUE;
+ *bcharge = TRUE;
+ if ((strstr (t2, "discharging")) != NULL)
+ {
+ *bcharge = FALSE;
+ *bloading = FALSE;
+ }
+ if ((strstr (t2, "unknown")) != NULL)
+ *bcharge = FALSE;
+ ret = TRUE;
+ }
+ }
+ fclose (battery);
+ } // if open(...state)
+ else
+ {
+ if (mydebug > 99)
+ fprintf (stderr,
+ "battery_get_values_linux(): missing File: '%s'\n",
+ fn);
+ }
+ }; // if ent->d_name[0] != '.'
+ };
+ closedir (dir);
+ }
+
+ if (mydebug > 60)
+ fprintf (stderr, "battery_get_values_linux(): "
+ "p_bat_full: %d, p_bat_current:%d p_bat_rate: %d\n",
+ p_bat_full, p_bat_current, p_bat_rate);
+ if (p_bat_current != 0)
+ *blevel = (int) (((double) p_bat_current / p_bat_full) * 100.0);
+
+ if (p_bat_rate != 0)
+ {
+ *btime = (int) (((double) p_bat_current / p_bat_rate * 60));
+ }
+
+ return ret;
+}
+
+/* ******************************************************************
+ * JH Added temperature readout code here
+ */
+static int
+temperature_get_values_linux (int *temper)
+{
+ FILE *temperature = NULL;
+ gint havetemperature = FALSE;
+ DIR *dir;
+ struct dirent *ent;
+ char fn[200];
+ gchar b[200];
+
+ /* search for temperature file */
+ temperature = NULL;
+ g_snprintf (fn, sizeof (fn), dir_proc);
+ g_strlcat (fn, "/acpi/thermal_zone/", sizeof (fn));
+ dir = opendir (fn);
+ if (dir != NULL)
+ {
+ while (!havetemperature && (ent = readdir (dir)) != NULL)
+ {
+ if (ent->d_name[0] != '.'
+ && strcmp(ent->d_name,"THRS"))
+ {
+ g_snprintf (fn, sizeof (fn), dir_proc);
+ g_strlcat (fn, "/acpi/thermal_zone/", sizeof (fn));
+ g_strlcat (fn, ent->d_name, sizeof (fn));
+ g_strlcat (fn, "/temperature", sizeof (fn));
+ if (mydebug > 30)
+ fprintf (stderr, "checking File %s\n", fn);
+ temperature = fopen (fn, "r");
+ if (temperature != NULL)
+ {
+ havetemperature = TRUE;
+ // ############### SigSeg Was HERE ??!!
+ int count = fscanf (temperature, "%s %d %s", b,
+ temper, b);
+ if (3 != count)
+ {
+ if (mydebug > 9)
+ fprintf (stderr,
+ "Wrong Number (%d) of values in %s\n",
+ count, fn);
+ havetemperature = FALSE;
+ }
+ fclose (temperature);
+ }
+ }
+ }
+ closedir (dir);
+ }
+ return havetemperature;
+}
+#endif /* Linux */
+
+
+/* ******************************************************************
+ * Return TRUE on success, FALSE on error.
+ */
+#if defined(__FreeBSD__) && defined(__i386__)
+static int
+battery_get_values_fbsd (int *blevel, int *bloading)
+{
+ int fd;
+ struct apm_info ai;
+
+ *blevel = -1;
+ *bloading = FALSE;
+
+ if ((fd = open ("/dev/apm", O_RDONLY)) == -1)
+ {
+ if (mydebug > 30)
+ fprintf (stderr, "gpsdrive: open(/dev/apm): %s\n", strerror (errno));
+ return FALSE;
+ }
+ if (ioctl (fd, APMIO_GETINFO, &ai) == -1)
+ {
+ if (mydebug > 30)
+ fprintf (stderr,
+ "gpsdrive: ioctl(APMIO_GETINFO): %s\n", strerror (errno));
+ close (fd);
+ return FALSE;
+ }
+
+ /*
+ * Battery level. If unknown or error we fail.
+ */
+ if (ai.ai_batt_life >= 0 && ai.ai_batt_life <= 100)
+ {
+ *blevel = ai.ai_batt_life;
+ }
+ else
+ {
+ if (ai.ai_batt_life == 255)
+ {
+ fprintf (stderr, "gpsdrive: battery level is unknown\n");
+ }
+ else
+ {
+ fprintf (stderr, "gpsdrive: battery level is invalid\n");
+ }
+ close (fd);
+ return FALSE;
+ }
+
+ /*
+ * Is the battery charging? If unknown or error we fail.
+ */
+ if (ai.ai_acline == 1)
+ { /* on-line */
+ *bloading = TRUE;
+ }
+ else if (ai.ai_acline == 0)
+ { /* off-line */
+ *bloading = FALSE;
+ }
+ else
+ {
+ if (ai.ai_acline == 255)
+ { /* unknown */
+ fprintf (stderr, "gpsdrive: battery charging status is unknown\n");
+ }
+ else
+ { /* error */
+ fprintf (stderr, "gpsdrive: battery charging status is invalid\n");
+ }
+ close (fd);
+ return FALSE;
+ }
+ close (fd);
+ return TRUE;
+}
+#endif /* __FreeBSD__ && __i386__ */
+
+/* ******************************************************************
+ * Return TRUE on success, FALSE on error.
+ */
+#if defined( __NetBSD__ ) || defined (__OpenBSD__)
+static int
+battery_get_values_nbsd (int *blevel, int *bloading)
+{
+ int fd;
+ struct apm_power_info ai;
+
+ memset (&ai, 0, sizeof (ai));
+
+ *blevel = -1;
+ *bloading = FALSE;
+
+ if ((fd = open ("/dev/apm", O_RDONLY)) == -1)
+ {
+ if (mydebug > 30)
+ fprintf (stderr, "gpsdrive: open(/dev/apm): %s\n", strerror (errno));
+ return FALSE;
+ }
+ if (ioctl (fd, APM_IOC_GETPOWER, &ai) == -1)
+ {
+ if (mydebug > 30)
+ fprintf (stderr,
+ "gpsdrive: ioctl(APM_IOC_GETPOWER): %s\n", strerror (errno));
+ close (fd);
+ return FALSE;
+ }
+
+ /*
+ * Battery level. If unknown or error we fail.
+ */
+ if (ai.battery_life <= 100)
+ {
+ *blevel = ai.battery_life;
+ }
+ else
+ {
+ if (ai.battery_life == 255)
+ {
+ fprintf (stderr, "gpsdrive: battery level is unknown\n");
+ }
+ else
+ {
+ fprintf (stderr, "gpsdrive: battery level is invalid\n");
+ }
+ close (fd);
+ return FALSE;
+ }
+
+ /*
+ * Is the battery charging? If unknown or error we fail.
+ */
+ if (ai.ac_state == APM_AC_ON)
+ { /* on-line */
+ *bloading = TRUE;
+ }
+ else if (ai.ac_state == APM_AC_OFF)
+ { /* off-line */
+ *bloading = FALSE;
+ }
+ else
+ {
+ if (ai.ac_state == APM_AC_UNKNOWN)
+ { /* unknown */
+ fprintf (stderr, "gpsdrive: battery charging status is unknown\n");
+ }
+ else
+ { /* error */
+ fprintf (stderr, "gpsdrive: battery charging status is invalid\n");
+ }
+ close (fd);
+ return FALSE;
+ }
+ close (fd);
+ return TRUE;
+}
+#endif /* __NetBSD__ */
+
+
+/* ******************************************************************
+ * code to display temperature meter (JH)
+ */
+int
+expose_display_temperature ()
+{
+ static GdkGC *temkontext = NULL;
+ GdkDrawable *mydrawable;
+
+ extern GtkWidget *drawing_temp;
+
+ extern GdkPixbuf *temimage;
+ gint havetemperature = temperature_get_values ();
+ if (!havetemperature)
+ return FALSE;
+
+ mydrawable = drawing_temp->window;
+ if (temkontext == NULL)
+ temkontext = gdk_gc_new (mydrawable);
+ gdk_gc_set_foreground (temkontext, &colors.mygray);
+ gdk_draw_rectangle (mydrawable, temkontext, 1, 0, 0, 25, 50);
+ if (temimage == NULL)
+ temimage = read_icon ("gauge.png",1);
+ gdk_gc_set_function (temkontext, GDK_AND);
+ gdk_draw_pixbuf (mydrawable, temkontext, temimage, 0,
+ 0, 0, 0, 17, 50, GDK_RGB_DITHER_NONE, 0, 0);
+ gdk_gc_set_function (temkontext, GDK_COPY);
+ /* gdk_pixbuf_unref (temimage); */
+ gdk_gc_set_foreground (temkontext, &colors.mygray);
+ /* We want to limit cputemp (79<cputemp< 40) */
+ if (cputemp > 79)
+ cputemp = 79;
+ if (cputemp < 40)
+ cputemp = 40;
+ gdk_draw_rectangle (mydrawable, temkontext, 1, 6, 1, 5, 79 - cputemp);
+
+ return TRUE;
+}
+
+/* ******************************************************************
+ * display battery meter
+ */
+int
+expose_display_battery ()
+{
+ static GdkGC *battkontext = NULL;
+ GdkDrawable *mydrawable;
+ gchar bbuf[200];
+
+ extern GdkPixbuf *batimage;
+
+ extern GdkPixbuf *temimage;
+
+ gint havebattery = battery_get_values ();
+
+ if (!havebattery)
+ return FALSE;
+
+ mydrawable = drawing_battery->window;
+ if (battkontext == NULL)
+ battkontext = gdk_gc_new (mydrawable);
+
+ gdk_gc_set_foreground (battkontext, &colors.mygray);
+ gdk_draw_rectangle (mydrawable, battkontext, 1, 0, 0, 25, 50);
+ gdk_gc_set_foreground (battkontext, &colors.black);
+ gdk_draw_rectangle (mydrawable, battkontext, 0, 19, 0, 6, 50);
+
+ /* JH added limit to batlevel */
+ if (batlevel > 99)
+ batlevel = 99;
+ if (batlevel > 40)
+ gdk_gc_set_foreground (battkontext, &colors.green);
+ else
+ {
+ if (batlevel > 25)
+ gdk_gc_set_foreground (battkontext, &colors.yellow);
+ else
+ {
+ if (batlevel > 15)
+ gdk_gc_set_foreground (battkontext, &colors.orange);
+ else
+ gdk_gc_set_foreground (battkontext, &colors.red);
+ }
+ }
+ gdk_draw_rectangle (mydrawable, battkontext, 1, 20,
+ 50 - batlevel / 2, 5, batlevel / 2);
+
+ if (img_powercharges == NULL)
+ {
+ img_powercharges = read_icon ("powercharges.png",1);
+ img_powercord = read_icon ("powercord.png",1);
+ img_battery = read_icon ("battery.png",1);
+ }
+
+ if (batcharge)
+ batimage = img_powercharges;
+ else
+ {
+ if (batloading)
+ batimage = img_powercord;
+ else
+ batimage = img_battery;
+ }
+
+
+ gdk_gc_set_function (battkontext, GDK_AND);
+ gdk_draw_pixbuf (mydrawable, battkontext, batimage, 0,
+ 0, 0, 0, 17, 50, GDK_RGB_DITHER_NONE, 0, 0);
+ gdk_gc_set_function (battkontext, GDK_COPY);
+
+ /* gdk_pixbuf_unref (batimage); */
+
+ if (((batlevel - 1) / 10 != (batlevel_old - 1) / 10) && (!batloading))
+ {
+ if (mydebug > 30)
+ g_print ("\nBattery: %d%%\n", batlevel);
+
+ /* This is for Festival, so we cannot use gettext() for i18n */
+ g_snprintf (bbuf, sizeof (bbuf),
+ speech_remaining_battery[voicelang], batlevel);
+ speech_out_speek (bbuf);
+
+ batlevel_old = batlevel;
+ }
+ return TRUE;
+}
+
+
+/* ******************************************************************
+ * Return TRUE on success, FALSE on error.
+ */
+int
+battery_get_values (void)
+{
+ gint havebattery = FALSE; /* Battery level and loading flag */
+
+ if ( ! local_config.enableapm )
+ {
+ return FALSE;
+ }
+#if defined(__linux__)
+ havebattery =
+ battery_get_values_linux_acpi (&batlevel, &batloading, &batcharge,
+ &battime);
+ if (!havebattery)
+ havebattery =
+ battery_get_values_linux_apm (&batlevel, &batloading, &batcharge);
+#elif defined(__FreeBSD__) && defined(__i386__)
+ havebattery = battery_get_values_fbsd (&batlevel, &batloading);
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+ havebattery = battery_get_values_nbsd (&batlevel, &batloading);
+#else
+ /* add support for your favourite OS here */
+ return FALSE;
+#endif
+
+ if (havebattery)
+ {
+ g_snprintf (batstring, sizeof (batstring), "%s %d%%", "Batt", batlevel);
+ if (battime)
+ g_snprintf (batstring, sizeof (batstring), "%s %d%%, %d min",
+ "Batt", batlevel, battime);
+
+ if (NULL == tooltip_battery)
+ tooltip_battery = gtk_tooltips_new ();
+
+ if (tooltip_battery != NULL && batteventbox != NULL)
+ gtk_tooltips_set_tip (GTK_TOOLTIPS
+ (tooltip_battery),
+ batteventbox, batstring, NULL);
+ }
+ else
+ {
+ g_snprintf (batstring, sizeof (batstring), "no Battery");
+ }
+
+ if (mydebug > 20)
+ fprintf (stderr, "battery_get_values() Have battery: %d\n", havebattery);
+ if (mydebug > 30)
+ fprintf (stderr, "battery_get_values(): batstring %s\n", batstring);
+
+ return havebattery;
+}
+
+
+/* ******************************************************************
+ * Return TRUE on success, FALSE on error.
+ */
+int
+temperature_get_values (void)
+{
+ gint havetemperature = FALSE;
+
+ if ( ! local_config.enableapm )
+ {
+ return havetemperature;
+ }
+
+ // g_snprintf (dir_proc,sizeof(dir_proc),"/proc");
+
+#if defined(__linux__)
+ havetemperature = temperature_get_values_linux (&cputemp);
+#else
+ /* add support for your favourite OS here */
+ return FALSE;
+#endif
+
+ if (havetemperature)
+ {
+ g_snprintf (cputempstring, sizeof (cputempstring),
+ "%s %d%sC", "CPU-Temp", cputemp, gradsym);
+ if (mydebug > 30)
+ fprintf (stderr, "cputempstring %s\n", cputempstring);
+
+
+
+ if (NULL == tooltip_temperature)
+ tooltip_temperature = gtk_tooltips_new ();
+
+ if (tooltip_temperature != NULL && tempeventbox != NULL)
+ gtk_tooltips_set_tip (GTK_TOOLTIPS
+ (tooltip_temperature),
+ tempeventbox, cputempstring, NULL);
+ }
+ else
+ {
+ g_snprintf (cputempstring, sizeof (batstring),
+ "no CPU Temperature available");
+ }
+ if (mydebug > 20)
+ fprintf (stderr, "temp: %d\n", havetemperature);
+
+ return havetemperature;
+
+}
+
+
+/* ******************************************************************
+ */
+void
+create_battery_widget (GtkWidget * hbox_displays)
+{
+ if (!battery_get_values ())
+ return;
+
+ if (NULL == drawing_battery)
+ {
+ GtkWidget *alignment3;
+
+ drawing_battery = gtk_drawing_area_new ();
+ gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_battery), 27, 52);
+ frame_battery = gtk_frame_new (_("Bat."));
+ batteventbox = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (batteventbox), drawing_battery);
+ alignment3 = gtk_alignment_new (0.5, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (alignment3), batteventbox);
+ gtk_container_add (GTK_CONTAINER (frame_battery), alignment3);
+ gtk_box_pack_start (GTK_BOX (hbox_displays),
+ frame_battery, FALSE, FALSE, 1 * PADDING);
+ if (battery_get_values ())
+ gtk_signal_connect (GTK_OBJECT
+ (drawing_battery),
+ "expose_event",
+ GTK_SIGNAL_FUNC (expose_display_battery), NULL);
+
+ }
+}
+
+/* ******************************************************************
+ */
+void
+create_temperature_widget (GtkWidget * hbox_displays)
+{
+ if (!temperature_get_values ())
+ return;
+
+ if (mydebug > 20)
+ fprintf (stderr, "create_temperature_widget:\n");
+
+ /* drawing area for cpu temp meter */
+ if (NULL == drawing_temp)
+ {
+ GtkWidget *alignment4;
+
+ drawing_temp = gtk_drawing_area_new ();
+ gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_temp), 15, 52);
+ frame_temperature = gtk_frame_new (_("TC"));
+ tempeventbox = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (tempeventbox), drawing_temp);
+ alignment4 = gtk_alignment_new (0.5, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (alignment4), tempeventbox);
+ gtk_container_add (GTK_CONTAINER (frame_temperature), alignment4);
+ gtk_box_pack_start (GTK_BOX (hbox_displays),
+ frame_temperature, FALSE, FALSE, 1 * PADDING);
+ if (temperature_get_values ())
+ gtk_signal_connect (GTK_OBJECT (drawing_temp),
+ "expose_event",
+ GTK_SIGNAL_FUNC
+ (expose_display_temperature), NULL);
+
+
+ };
+
+}
diff --git a/src/battery.h b/src/battery.h
new file mode 100644
index 0000000..c471597
--- /dev/null
+++ b/src/battery.h
@@ -0,0 +1,42 @@
+/***********************************************************************
+
+Copyright (c) 2001,2002 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+
+#ifndef GPSDRIVE_BATTERY_H
+#define GPSDRIVE_BATTERY_H
+
+/*
+ * See battery.c for details.
+ */
+
+
+int battery_get_values(void);
+int temperature_get_values(void);
+int expose_display_battery();
+int expose_display_temperature();
+void create_battery_widget (GtkWidget * hbox2);
+void create_temperature_widget (GtkWidget * hbox2);
+
+
+#endif /* GPSDRIVE_BATTERY_H */
diff --git a/src/download_map.c b/src/download_map.c
new file mode 100644
index 0000000..ce7b6a0
--- /dev/null
+++ b/src/download_map.c
@@ -0,0 +1,1005 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+/*
+ $Log$
+ Revision 1.6 2006/08/02 07:48:24 tweety
+ rename variable mapdir --> local_config_mapdir
+
+ Revision 1.5 2006/08/01 06:06:50 tweety
+ try to reduce errors while downloading maps from expedia
+
+ Revision 1.4 2006/05/09 08:29:52 tweety
+ move proxy fetching from environment to download_map.c
+
+ Revision 1.3 2006/02/17 20:54:34 tweety
+ http://bugzilla.gpsdrive.cc/show_bug.cgi?id=73
+ Downloading maps doesn't allow Longitude select by mouse
+
+ Revision 1.2 2006/02/05 16:38:05 tweety
+ reading floats with scanf looks at the locale LANG=
+ so if you have a locale de_DE set reading way.txt results in clearing the
+ digits after the '.'
+ For now I set the LC_NUMERIC always to en_US, since there we have . defined for numbers
+
+ Revision 1.1 2006/02/05 15:01:59 tweety
+ extract map downloading
+
+ Revision 1.0 2006/01/03 14:24:10 tweety
+*/
+
+
+/* Include Dateien */
+#include "../config.h"
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <signal.h>
+#include <termios.h>
+#include <unistd.h>
+#include <math.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <errno.h>
+
+#include <dlfcn.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+#include "gettext.h"
+
+#include <dirent.h>
+
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+
+#if GTK_MINOR_VERSION < 2
+#define gdk_draw_pixbuf _gdk_draw_pixbuf
+#endif
+
+
+#include <gpsdrive.h>
+#include <map_handler.h>
+#include "gpsdrive_config.h"
+
+extern GtkWidget *frame_statusbar;
+extern gint timeoutcount;
+extern gint haveproxy, proxyport;
+extern gchar proxy[256];
+extern gint mydebug;
+extern mapsstruct *maps;
+extern struct timeval timeout;
+extern int havenasa;
+extern gint slistsize;
+extern gchar *slist[];
+extern GtkWidget *cover;
+extern gint scaleprefered;
+extern gdouble milesconv;
+extern coordinate_struct coords;
+extern currentstatus_struct current;
+
+char actualhostname[200];
+
+gint dlsock = -1;
+int expedia_de = 0;
+gint expedia = TRUE;
+GtkWidget *downloadwindow;
+
+GtkWidget *radio1, *radio2;
+gint downloadwindowactive=0;
+gint downloadactive=0;
+gchar writebuff[2000];
+fd_set readmask;
+gchar *dlbuff;
+gint downloadfilelen=0;
+gchar *dlpstart;
+gint nrmaps = 0, dldiff;
+gint dlcount;
+GtkWidget *myprogress;
+GtkWidget *dl_text_lat, *dl_text_lon, *dl_text_scale;
+gdouble new_dl_lon, new_dl_lat;
+gint new_dl_scale;
+
+gint downloadaway_cb (GtkWidget * widget, guint datum);
+gint dlscale_cb (GtkWidget * widget, guint datum);
+
+/* *****************************************************************************
+ */
+gint
+dlstatusaway_cb (GtkWidget * widget, guint datum)
+{
+ downloadwindowactive = downloadactive = FALSE;
+
+ return FALSE;
+}
+
+/* *****************************************************************************
+ */
+char *
+getexpediaurl (GtkWidget * widget)
+{
+ struct sockaddr_in server;
+ struct hostent *server_data;
+ gchar str[100], sn[1000];
+ gchar tmpbuff[9000];
+ gint e;
+ static char url[8000];
+
+ /* open socket to port80 */
+ if ((dlsock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ perror (_("can't open socket for port 80"));
+ if (expedia_de)
+ g_snprintf (str, sizeof (str),
+ _("Connecting to %s FAILED!"),
+ (expedia) ? WEBSERVER4 : WEBSERVER);
+ else
+ g_snprintf (str, sizeof (str),
+ _("Connecting to %s FAILED!"),
+ (expedia) ? WEBSERVER2 : WEBSERVER);
+ gtk_statusbar_pop (GTK_STATUSBAR (frame_statusbar),
+ current.statusbar_id);
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar), current.statusbar_id, str);
+ gtk_widget_destroy (downloadwindow);
+ gtk_timeout_add (3000, (GtkFunction) dlstatusaway_cb, widget);
+ close (dlsock);
+ return (NULL);
+ }
+
+ server.sin_family = AF_INET;
+ /* We retrieve the IP address of the server from its name: */
+ if (haveproxy)
+ g_strlcpy (sn, proxy, sizeof (sn));
+ else
+ {
+ if (expedia_de)
+ g_strlcpy (sn, (expedia) ? WEBSERVER4 : WEBSERVER,
+ sizeof (sn));
+ else
+ g_strlcpy (sn, (expedia) ? WEBSERVER2 : WEBSERVER,
+ sizeof (sn));
+ }
+ if ((server_data = gethostbyname (sn)) == NULL)
+ {
+ perror (_("Can't resolve webserver address"));
+ if (expedia_de)
+ g_snprintf (str, sizeof (str),
+ _("Connecting to %s FAILED!"),
+ (expedia) ? WEBSERVER4 : WEBSERVER);
+ else
+ g_snprintf (str, sizeof (str),
+ _("Connecting to %s FAILED!"),
+ (expedia) ? WEBSERVER2 : WEBSERVER);
+ gtk_statusbar_pop (GTK_STATUSBAR (frame_statusbar), current.statusbar_id);
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar), current.statusbar_id, str);
+ gtk_widget_destroy (downloadwindow);
+ gtk_timeout_add (3000, (GtkFunction) dlstatusaway_cb, widget);
+ close (dlsock);
+ return (NULL);
+ }
+ memcpy (&server.sin_addr, server_data->h_addr, server_data->h_length);
+ server.sin_port = htons (proxyport);
+ /* We initiate the connection */
+ if (connect (dlsock, (struct sockaddr *) &server, sizeof server) < 0)
+ {
+ perror (_("unable to connect to Website"));
+ if (expedia_de)
+ g_snprintf (str, sizeof (str),
+ _("Connecting to %s FAILED!"),
+ (expedia) ? WEBSERVER4 : WEBSERVER);
+ else
+ g_snprintf (str, sizeof (str),
+ _("Connecting to %s FAILED!"),
+ (expedia) ? WEBSERVER2 : WEBSERVER);
+ gtk_statusbar_pop (GTK_STATUSBAR (frame_statusbar), current.statusbar_id);
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar), current.statusbar_id, str);
+ gtk_widget_destroy (downloadwindow);
+ gtk_timeout_add (3000, (GtkFunction) dlstatusaway_cb, widget);
+ close (dlsock);
+ return (NULL);
+ }
+
+ if ( write (dlsock, writebuff, strlen (writebuff))<0){
+ close (dlsock);
+ return (NULL);
+ };
+
+ FD_ZERO (&readmask);
+ FD_SET (dlsock, &readmask);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 100000;
+ if (select (FD_SETSIZE, &readmask, NULL, NULL, &timeout) < 0)
+ {
+ perror ("select() call");
+ }
+
+ g_strlcpy (url, "Fehler!!!!", sizeof (url));
+ memset (tmpbuff, 0, 8192);
+ if ((e = read (dlsock, tmpbuff, 8000)) < 0)
+ perror (_("read from Webserver"));
+ if ( mydebug > 3 )
+ g_print ("Loaded %d Bytes\n", e);
+ if (e > 0)
+ g_strlcpy (url, tmpbuff, sizeof (url));
+ else
+ {
+ perror ("getexpediaurl");
+ fprintf (stderr, "error while reading from exedia\n");
+ close (dlsock);
+ return (NULL);
+ // exit (1);
+ }
+ close (dlsock);
+ return url;
+
+}
+
+/* *****************************************************************************
+ */
+gint
+downloadstart_cb (GtkWidget * widget, guint datum)
+{
+ struct sockaddr_in server;
+ struct hostent *server_data;
+ gchar str[100], sn[1000];
+
+
+ downloadfilelen = 0;
+ downloadactive = TRUE;
+ if (!expedia)
+ g_snprintf (str, sizeof (str), _("Connecting to %s"),
+ WEBSERVER);
+ if (expedia)
+ {
+ if (expedia_de)
+ g_snprintf (str, sizeof (str), _("Connecting to %s"),
+ WEBSERVER4);
+ else
+ g_snprintf (str, sizeof (str), _("Connecting to %s"),
+ WEBSERVER2);
+ }
+
+ gtk_statusbar_pop (GTK_STATUSBAR (frame_statusbar), current.statusbar_id);
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar), current.statusbar_id, str);
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+ /* open socket to port80 */
+ if ((dlsock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ perror (_("can't open socket for port 80"));
+ if (!expedia)
+ g_snprintf (str, sizeof (str),
+ _("Connecting to %s FAILED!"), WEBSERVER);
+ if (expedia)
+ {
+ if (expedia_de)
+ g_snprintf (str, sizeof (str),
+ _("Connecting to %s FAILED!"),
+ WEBSERVER4);
+ else
+ g_snprintf (str, sizeof (str),
+ _("Connecting to %s FAILED!"),
+ WEBSERVER2);
+ }
+
+ gtk_statusbar_pop (GTK_STATUSBAR (frame_statusbar), current.statusbar_id);
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar), current.statusbar_id, str);
+ gtk_widget_destroy (downloadwindow);
+ gtk_timeout_add (6000, (GtkFunction) dlstatusaway_cb, widget);
+ return (FALSE);
+ }
+
+ server.sin_family = AF_INET;
+ /* We retrieve the IP address of the server from its name: */
+ if (haveproxy)
+ g_strlcpy (sn, proxy, sizeof (sn));
+ else
+ {
+ if (expedia)
+ {
+ if (expedia_de)
+ g_strlcpy (sn, WEBSERVER4, sizeof (sn));
+ else
+ g_strlcpy (sn, WEBSERVER2, sizeof (sn));
+ }
+
+ if (!expedia)
+ g_strlcpy (sn, WEBSERVER, sizeof (sn));
+ }
+
+ if (expedia == TRUE && haveproxy == FALSE)
+ g_strlcpy (sn, actualhostname, sizeof (sn));
+
+ if ((server_data = gethostbyname (sn)) == NULL)
+ {
+ perror (_("Can't resolve webserver address"));
+ if (!expedia)
+ g_snprintf (str, sizeof (str),
+ _("Connecting to %s FAILED!"), WEBSERVER);
+ if (expedia)
+ {
+ if (expedia_de)
+ g_snprintf (str, sizeof (str),
+ _("Connecting to %s FAILED!"),
+ WEBSERVER4);
+ else
+ g_snprintf (str, sizeof (str),
+ _("Connecting to %s FAILED!"),
+ WEBSERVER2);
+ }
+
+ gtk_statusbar_pop (GTK_STATUSBAR (frame_statusbar), current.statusbar_id);
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar), current.statusbar_id, str);
+ gtk_widget_destroy (downloadwindow);
+ gtk_timeout_add (3000, (GtkFunction) dlstatusaway_cb, widget);
+ return (FALSE);
+ }
+ memcpy (&server.sin_addr, server_data->h_addr, server_data->h_length);
+ server.sin_port = htons (proxyport);
+ /* We initiate the connection */
+ if (connect (dlsock, (struct sockaddr *) &server, sizeof server) < 0)
+ {
+ perror (_("unable to connect to Website"));
+ if (!expedia)
+ g_snprintf (str, sizeof (str),
+ _("Connecting to %s FAILED!"), WEBSERVER);
+ if (expedia)
+ {
+ if (expedia_de)
+ g_snprintf (str, sizeof (str),
+ _("Connecting to %s FAILED!"),
+ WEBSERVER4);
+ else
+ g_snprintf (str, sizeof (str),
+ _("Connecting to %s FAILED!"),
+ WEBSERVER2);
+ }
+
+ gtk_statusbar_pop (GTK_STATUSBAR (frame_statusbar), current.statusbar_id);
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar), current.statusbar_id, str);
+ gtk_widget_destroy (downloadwindow);
+ gtk_timeout_add (3000, (GtkFunction) dlstatusaway_cb, widget);
+ return (FALSE);
+ }
+
+ write (dlsock, writebuff, strlen (writebuff));
+ dlbuff = g_new0 (gchar, 8192);
+ dlpstart = NULL;
+ dldiff = dlcount = 0;
+ if (!expedia)
+ g_snprintf (str, sizeof (str), _("Now connected to %s"),
+ WEBSERVER);
+ if (expedia)
+ {
+ if (expedia_de)
+ g_snprintf (str, sizeof (str),
+ _("Now connected to %s"), WEBSERVER4);
+ else
+ g_snprintf (str, sizeof (str),
+ _("Now connected to %s"), WEBSERVER2);
+ }
+
+ gtk_statusbar_pop (GTK_STATUSBAR (frame_statusbar), current.statusbar_id);
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar), current.statusbar_id, str);
+ gtk_timeout_add (100, (GtkFunction) downloadslave_cb, widget);
+ return TRUE;
+}
+
+gint
+downloadslave_cb (GtkWidget * widget, guint datum)
+{
+ gchar tmpbuff[9000], str[100], *p;
+ gint e, fd;
+ gchar nn[] = "\r\n\r\n";
+ gdouble f;
+
+ if (!downloadwindowactive)
+ return FALSE;
+
+
+ FD_ZERO (&readmask);
+ FD_SET (dlsock, &readmask);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 100000;
+ if (select (FD_SETSIZE, &readmask, NULL, NULL, &timeout) < 0)
+ {
+ perror ("select() call");
+ }
+
+ if (FD_ISSET (dlsock, &readmask))
+ {
+ memset (tmpbuff, 0, 8192);
+ if ((e = read (dlsock, tmpbuff, 8000)) < 0)
+ perror (_("read from Webserver"));
+ if ( mydebug > 3 )
+ g_print ("Loaded %d Bytes\n", e);
+ if (e > 0)
+ {
+ /* in dlbuff we have all download data */
+ memcpy ((dlbuff + dlcount), tmpbuff, e);
+ /* in dlcount we have the number of download bytes */
+ dlcount += e;
+ /* now we try to get the filelength and begin of the gif image data */
+ if (dlpstart == NULL)
+ {
+ /* CONTENT-LENGTH string should hopefully be in the first 4kB */
+ memcpy (tmpbuff, dlbuff, 4096);
+ /* We make of this a null terminated string */
+ tmpbuff[4096] = 0;
+ g_strup (tmpbuff);
+ p = strstr (tmpbuff, "CONTENT-LENGTH:");
+ if (p != NULL)
+ {
+ sscanf (p, "%s %d", str,
+ &downloadfilelen);
+ /* now we look for 2 cr/lf which is the end of the header */
+ dlpstart = strstr (tmpbuff, nn);
+ dldiff = dlpstart - tmpbuff + 4;
+ /* g_print("content-length: %d\n", downloadfilelen); */
+ }
+ else if (dlcount > 1000)
+ {
+ /* Seems there is no CONTENT-LENGTH field in expedia.com */
+ dlpstart = strstr (tmpbuff, nn);
+ dldiff = dlpstart - tmpbuff + 4;
+ downloadfilelen = 200000;
+ /* g_print("\ncontent-length: %d", downloadfilelen); */
+ }
+ }
+ /* Now we have the length and begin of the gif image data */
+ if ((downloadfilelen != 0) && (dlpstart != NULL))
+ {
+ dlbuff = g_renew (gchar, dlbuff,
+ dlcount + 8192);
+ f = (dlcount -
+ dldiff) / (gdouble) downloadfilelen;
+ if (f > 1.0)
+ f = 1.0;
+ gtk_progress_bar_update (GTK_PROGRESS_BAR
+ (myprogress), f);
+ g_snprintf (str, sizeof (str),
+ _("Downloaded %d kBytes"),
+ (dlcount - dldiff) / 1024);
+ gtk_statusbar_pop (GTK_STATUSBAR (frame_statusbar),
+ current.statusbar_id);
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar),
+ current.statusbar_id, str);
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+ }
+
+ }
+ if ((e == 0) || ((downloadfilelen + dldiff) == dlcount))
+ {
+
+ if (downloadfilelen == 0)
+ g_snprintf (str, sizeof (str),
+ _("Download FAILED!"));
+ else
+ g_snprintf (str, sizeof (str),
+ _("Download finished, got %dkB"),
+ dlcount / 1024);
+ gtk_statusbar_pop (GTK_STATUSBAR (frame_statusbar), current.statusbar_id);
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar), current.statusbar_id,
+ str);
+ close (dlsock);
+ if (downloadfilelen != 0)
+ {
+ gchar map_filename[1024];
+ gchar map_file_w_path[1024];
+
+ g_snprintf( map_filename, sizeof (map_filename),
+ "expedia/map_%d_%5.3f_%5.3f.gif",
+ new_dl_scale,new_dl_lat,new_dl_lon);
+
+ if ( local_config.dir_maps[strlen (local_config.dir_maps) - 1] != '/' )
+ g_strlcat( local_config.dir_maps, "/",sizeof (local_config.dir_maps) );
+
+ g_snprintf (map_file_w_path, sizeof (map_file_w_path),
+ "%s%s",local_config.dir_maps,map_filename);
+
+ if ( mydebug > 1 ) {
+ g_print("Saving Map File to: '%s'\n",
+ map_file_w_path);
+ }
+
+ // Create directory
+ struct stat buf;
+ gchar map_dir[1024];
+ g_snprintf (map_dir, sizeof (map_dir),
+ "%s%s",local_config.dir_maps,"expedia");
+ if ( stat(map_dir,&buf) )
+ {
+ printf("Try creating %s\n",map_dir);
+ if ( mkdir (map_dir, 0700) )
+ {
+ printf("Error creating %s\n",map_dir);
+ }
+ }
+
+ fd = open (map_file_w_path,
+ O_RDWR | O_TRUNC | O_CREAT, 0644);
+ if (fd < 1)
+ {
+ perror (map_filename);
+ gtk_timeout_add (3000,(GtkFunction) dlstatusaway_cb, widget);
+
+ return FALSE;
+ }
+ write (fd, dlbuff + dldiff, dlcount - dldiff);
+ close (fd);
+ /* g_free (maps); */
+ loadmapconfig ();
+ maps = g_renew (mapsstruct, maps,
+ (nrmaps + 2));
+ g_strlcpy ((maps + nrmaps)->filename,map_filename, 200);
+ (maps + nrmaps)->map_dir = add_map_dir (map_filename);
+ (maps + nrmaps)->hasbbox = FALSE;
+ (maps + nrmaps)->lat = new_dl_lat;
+ (maps + nrmaps)->lon = new_dl_lon;
+ (maps + nrmaps)->scale =new_dl_scale;
+ nrmaps++;
+ havenasa = -1;
+ savemapconfig ();
+ }
+ downloadwindowactive = FALSE;
+ gtk_widget_destroy (downloadwindow);
+ gtk_timeout_add (3000, (GtkFunction) dlstatusaway_cb, widget);
+
+ return FALSE;
+ }
+ }
+ else
+ {
+
+ return TRUE;
+ }
+
+
+ return TRUE;
+}
+
+/* *****************************************************************************
+ */
+gint
+downloadsetparm (GtkWidget * widget, guint datum)
+{
+ G_CONST_RETURN gchar *s;
+ gchar lon[100], lat[100], hostname[100], region[10];
+ gdouble f;
+ gint ns;
+
+ char sctext[40];
+
+ if (!downloadwindowactive)
+ return TRUE;
+
+ s = gtk_entry_get_text (GTK_ENTRY (dl_text_lat));
+ coordinate_string2gdouble(s, &new_dl_lat);
+ if ( mydebug > 3 )
+ g_print("new map lat: %s\n",s);
+
+ s = gtk_entry_get_text (GTK_ENTRY (dl_text_lon));
+ coordinate_string2gdouble(s,&new_dl_lon);
+ if ( mydebug > 3 )
+ g_print("new map lon: %s\n",s);
+
+ s = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (dl_text_scale)->entry));
+ new_dl_scale = strtol (s, NULL, 0);
+ if ( mydebug > 3 )
+ g_print("new map scale: %d\n",new_dl_scale);
+
+ if (datum == 0)
+ return TRUE;
+ if (expedia)
+ {
+ if (expedia_de)
+ g_snprintf (hostname, sizeof (hostname), "%s",
+ WEBSERVER4);
+ else
+ g_snprintf (hostname, sizeof (hostname), "%s",
+ WEBSERVER2);
+ }
+
+ if (!expedia)
+ g_snprintf (hostname, sizeof (hostname), "%s", WEBSERVER);
+
+ if (expedia)
+ {
+ int scales[11] =
+ { 1, 3, 6, 12, 25, 50, 150, 800, 2000, 7000, 12000 };
+ int i, found = 5;
+ double di = 999999;
+ f = new_dl_scale;
+ ns = f / EXPEDIAFACT;
+ for (i = 0; i < 11; i++)
+ if (abs (ns - scales[i]) < di)
+ {
+ di = abs (ns - scales[i]);
+ found = i;
+ }
+ ns = scales[found];
+ g_snprintf (sctext, sizeof (sctext), "%d", ns);
+ new_dl_scale = (int) (ns * EXPEDIAFACT);
+ }
+ if ( mydebug > 0 )
+ printf ("sctext: %s,new map scale: %d\n", sctext, new_dl_scale);
+
+ if (!expedia)
+ g_snprintf (writebuff, sizeof (writebuff),
+ "GET http://%s/gif?&CT=%s:%s:%s&IC=&W=1280&H=1024&FAM=myblast&LB="
+ " HTTP/1.0\r\n"
+ "User-Agent: Wget/1.6\r\n"
+ "Host: %s\r\n"
+ "Accept: */*\r\n"
+ "Connection: Keep-Alive\r\n"
+ "\r\n",
+ WEBSERVER, lat, lon, sctext, hostname);
+ if (expedia)
+ {
+ if (new_dl_lon > (-30))
+ {
+ g_strlcpy (region, "EUR0809", sizeof (region));
+ expedia_de = TRUE;
+ }
+ else
+ {
+ g_strlcpy (region, "USA0409", sizeof (region));
+ expedia_de = FALSE;
+ }
+
+
+ if (expedia_de)
+ g_snprintf (writebuff, sizeof (writebuff),
+ "GET http://%s/pub/agent.dll?"
+ "qscr=mrdt&ID=3XNsF.&CenP=%f,%f&Lang=%s&Alti=%s"
+ "&Size=1280,1024&Offs=0.000000,0.000000& HTTP/1.1\r\n"
+ "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)\r\n"
+ "Host: %s\r\nAccept: */*\r\nCookie: jscript=1\r\n\r\n",
+ WEBSERVER4, new_dl_lat, new_dl_lon, region, sctext,
+ hostname);
+ else
+ g_snprintf (writebuff, sizeof (writebuff),
+ "GET http://%s/pub/agent.dll?qscr=mrdt&ID=3XNsF.&CenP=%f,%f&Lang=%s&Alti=%s"
+ "&Size=1280,1024&Offs=0.000000,0.000000& HTTP/1.1\r\n"
+ "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)\r\n"
+ "Host: %s\r\nAccept: */*\r\nCookie: jscript=1\r\n\r\n",
+ WEBSERVER2, new_dl_lat, new_dl_lon, region, sctext,
+ hostname);
+ }
+
+ if ( mydebug > 0 )
+ g_print ("Download URL: %s\n", writebuff);
+
+ if (!expedia)
+ downloadstart_cb (widget, 0);
+ else
+ {
+ char url[2000], url2[2000], hn[200], *p;
+
+ p = getexpediaurl (widget);
+ if (p == NULL)
+ {
+ return FALSE;
+ }
+
+ g_strlcpy (url, p, sizeof (url));
+ if ( mydebug > 3 )
+ printf ("%s\n", url);
+ p = strstr (url, "Location: ");
+ if (p == NULL)
+ {
+ if ( mydebug > 0 )
+ printf ("http data error, could not find 'Location:' sub string\n");
+ return FALSE;
+ }
+ g_strlcpy (url2, (p + 10), sizeof (url2));
+ p = strstr (url2, "\n");
+ if (p == NULL)
+ {
+ if ( mydebug > 0 )
+ printf ("http data error, could not find new line\n");
+ return FALSE;
+ }
+
+ url2[p - url2] = 0;
+ if ( mydebug > 3 )
+ printf ("**********\n%s\n", url2);
+ g_strlcpy (hn, (url2 + 7), sizeof (hn));
+ p = strstr (hn, "/");
+ if (p == NULL)
+ {
+ if ( mydebug > 0 )
+ printf ("http request error, could not find forward slash\n");
+ return FALSE;
+ }
+
+ hn[p - hn] = 0;
+ g_strlcpy (url, (url2 + strlen (hn) + 7), sizeof (url));
+ url[strlen (url) - 1] = 0;
+ g_strlcpy (actualhostname, hn, sizeof (actualhostname));
+ if ( mydebug > 3 )
+ printf ("hn: %s, url: %s\n", hn, url);
+
+ if (haveproxy == TRUE)
+ {
+ // Format the GET request correctly for the proxy server
+ g_snprintf (url2, sizeof (url2),
+ "GET http://%s/%s HTTP/1.1\r\n", hn, url);
+ }
+ else
+ {
+ g_snprintf (url2, sizeof (url2),
+ "GET %s HTTP/1.1\r\n", url);
+ }
+
+ g_strlcat (url2, "Host: ", sizeof (url2));
+ g_strlcat (url2, hn, sizeof (url2));
+ g_strlcat (url2, "\r\n", sizeof (url2));
+ g_strlcat (url2,
+ "User-Agent: Mozilla/5.0 Galeon/1.2.8 (X11; Linux i686; U;) Gecko/20030317\r\n",
+ sizeof (url2));
+ g_strlcat (url2,
+ "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1\r\n",
+ sizeof (url2));
+ g_strlcat (url2, "Accept-Language: de, en;q=0.50\r\n",
+ sizeof (url2));
+ g_strlcat (url2,
+ "Accept-Encoding: gzip, deflate, compress;q=0.9\r\n",
+ sizeof (url2));
+ g_strlcat (url2,
+ "Accept-Charset: ISO-8859-15, utf-8;q=0.66, *;q=0.66\r\n",
+ sizeof (url2));
+ g_strlcat (url2, "Keep-Alive: 300\r\n", sizeof (url2));
+ g_strlcat (url2, "Connection: keep-alive\r\n\r\n",
+ sizeof (url2));
+
+ g_strlcpy (writebuff, url2, sizeof (writebuff));
+ if ( mydebug > 3 )
+ printf ("\nurl2:\n%s\n**********\n\n%s\n-----------------\n", url2, writebuff);
+
+ downloadstart_cb (widget, 0);
+
+ /* exit (1); */
+ }
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ */
+gint
+download_cb (GtkWidget * widget, guint datum)
+{
+ GtkWidget *mainbox;
+ GtkWidget *knopf2, *knopf, *knopf_lat, *knopf_lon, *knopf_scale,
+ *knopf_help_text;
+ GtkWidget *table, *table2, *knopf8;
+ gchar buff[300];
+ GList *list = NULL;
+ gint i;
+ gchar scalewanted_str[100];
+
+ for (i = 0; i < slistsize; i++)
+ list = g_list_append (list, slist[i]);
+
+ downloadwindow = gtk_dialog_new ();
+ gtk_window_set_title (GTK_WINDOW (downloadwindow),
+ _("Select coordinates and scale"));
+ gtk_container_set_border_width (GTK_CONTAINER (downloadwindow), 5);
+ mainbox = gtk_vbox_new (TRUE, 2);
+ knopf = gtk_button_new_with_label (_("Download map"));
+ gtk_signal_connect (GTK_OBJECT (knopf), "clicked",
+ GTK_SIGNAL_FUNC (downloadsetparm), (gpointer) 1);
+ knopf2 = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+ gtk_signal_connect_object (GTK_OBJECT (knopf2), "clicked",
+ GTK_SIGNAL_FUNC
+ (downloadaway_cb),
+ GTK_OBJECT (downloadwindow));
+ gtk_signal_connect_object (GTK_OBJECT (downloadwindow),
+ "delete_event",
+ GTK_SIGNAL_FUNC (downloadaway_cb),
+ GTK_OBJECT (downloadwindow));
+ cover = gtk_entry_new ();
+ gtk_editable_set_editable (GTK_EDITABLE (cover), FALSE);
+ gtk_signal_connect (GTK_OBJECT (cover), "changed",
+ GTK_SIGNAL_FUNC (downloadsetparm), (gpointer) 0);
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (downloadwindow)->
+ action_area), knopf, TRUE, TRUE, 2);
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (downloadwindow)->
+ action_area), knopf2, TRUE, TRUE, 2);
+ GTK_WIDGET_SET_FLAGS (knopf, GTK_CAN_DEFAULT);
+ GTK_WIDGET_SET_FLAGS (knopf2, GTK_CAN_DEFAULT);
+ table = gtk_table_new (8, 2, FALSE);
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (downloadwindow)->vbox),
+ table, TRUE, TRUE, 2);
+ knopf_lat = gtk_label_new (_("Latitude"));
+ gtk_table_attach_defaults (GTK_TABLE (table), knopf_lat, 0, 1, 0, 1);
+ knopf_lon = gtk_label_new (_("Longitude"));
+ gtk_table_attach_defaults (GTK_TABLE (table), knopf_lon, 0, 1, 1, 2);
+ knopf8 = gtk_label_new (_("Map covers"));
+ gtk_table_attach_defaults (GTK_TABLE (table), knopf8, 0, 1, 2, 3);
+ gtk_table_attach_defaults (GTK_TABLE (table), cover, 1, 2, 2, 3);
+
+ knopf_scale = gtk_label_new (_("Scale"));
+ gtk_table_attach_defaults (GTK_TABLE (table), knopf_scale, 0, 1, 3, 4);
+ dl_text_lat = gtk_entry_new ();
+ gtk_signal_connect (GTK_OBJECT (dl_text_lat), "changed",
+ GTK_SIGNAL_FUNC (downloadsetparm), (gpointer) 0);
+
+ gtk_table_attach_defaults (GTK_TABLE (table), dl_text_lat, 1, 2, 0, 1);
+ coordinate2gchar(buff, sizeof(buff), coords.current_lat, TRUE,
+ local_config.coordmode);
+ gtk_entry_set_text (GTK_ENTRY (dl_text_lat), buff);
+ dl_text_lon = gtk_entry_new ();
+ gtk_signal_connect (GTK_OBJECT (dl_text_lon), "changed",
+ GTK_SIGNAL_FUNC (downloadsetparm), (gpointer) 0);
+ gtk_table_attach_defaults (GTK_TABLE (table), dl_text_lon, 1, 2, 1, 2);
+ coordinate2gchar(buff, sizeof(buff), coords.current_lon, FALSE,
+ local_config.coordmode);
+ gtk_entry_set_text (GTK_ENTRY (dl_text_lon), buff);
+ dl_text_scale = gtk_combo_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), dl_text_scale, 1, 2, 3, 4);
+ gtk_combo_set_popdown_strings (GTK_COMBO (dl_text_scale), (GList *) list);
+ g_snprintf (scalewanted_str, sizeof (scalewanted_str), "%d",
+ local_config.scale_wanted);
+ gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (dl_text_scale)->entry),
+ scalewanted_str);
+ gtk_signal_connect (GTK_OBJECT (GTK_COMBO (dl_text_scale)->entry),
+ "changed", GTK_SIGNAL_FUNC (downloadsetparm),
+ (gpointer) 0);
+
+ table2 = gtk_table_new (2, 1, FALSE); //nested table w/ three columns
+ gtk_table_attach_defaults (GTK_TABLE (table), table2, 0, 3, 5, 6);
+ gtk_widget_show (table2);
+
+ if (!haveproxy)
+ g_snprintf (buff, sizeof (buff), "%s",
+ _("You can also select the position\n"
+ "with a mouse click on the map."));
+ else
+ g_snprintf (buff, sizeof (buff), "%s\n\n%s %s %d",
+ _("You can also select the position\n"
+ "with a mouse click on the map."),
+ _("Using Proxy and port:"), proxy, proxyport);
+ knopf_help_text = gtk_label_new (buff);
+ gtk_table_attach_defaults (GTK_TABLE (table), knopf_help_text, 0, 2, 6, 7);
+
+ myprogress = gtk_progress_bar_new ();
+ gtk_progress_set_format_string (GTK_PROGRESS (myprogress), "%p%%");
+ gtk_progress_set_show_text (GTK_PROGRESS (myprogress), TRUE);
+ gtk_progress_bar_update (GTK_PROGRESS_BAR (myprogress), 0.0);
+ gtk_table_attach_defaults (GTK_TABLE (table), myprogress, 0, 2, 7, 8);
+ gtk_label_set_justify (GTK_LABEL (knopf_lat), GTK_JUSTIFY_RIGHT);
+ gtk_label_set_justify (GTK_LABEL (knopf_lon), GTK_JUSTIFY_RIGHT);
+ gtk_label_set_justify (GTK_LABEL (knopf_scale), GTK_JUSTIFY_RIGHT);
+
+ gtk_window_set_default (GTK_WINDOW (downloadwindow), knopf);
+
+ gtk_window_set_position (GTK_WINDOW (downloadwindow),
+ GTK_WIN_POS_CENTER);
+ gtk_widget_show_all (downloadwindow);
+ downloadwindowactive = TRUE;
+ downloadsetparm (NULL, 0);
+
+ /* cursor = gdk_cursor_new (GDK_CROSS); */
+ /* gdk_window_set_cursor (map_drawingarea->window, cursor); */
+ return TRUE;
+}
+
+/* *****************************************************************************
+ * cancel button pressed or widget destroy in download_cb
+ */
+gint
+downloadaway_cb (GtkWidget * widget, guint datum)
+{
+ downloadwindowactive = downloadactive = FALSE;
+ gtk_widget_destroy (widget);
+ expose_mini_cb (NULL, 0);
+
+ /* gdk_window_set_cursor (map_drawingarea->window, 0); */
+ /* gdk_cursor_destroy (cursor); */
+ return FALSE;
+}
+
+
+/* *****************************************************************************
+ */
+gint
+dlscale_cb (GtkWidget * widget, guint datum)
+{
+ G_CONST_RETURN gchar *sc;
+ gchar t[100], t2[10];
+ gdouble f;
+ /* PORTING */
+ sc = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (dl_text_scale)->entry));
+
+ f = g_strtod (sc, NULL);
+
+ g_strlcpy (t2, "km", sizeof (t2));
+
+ if (local_config.distmode == DIST_MILES)
+ g_strlcpy (t2, "mi", sizeof (t2));
+ if (local_config.distmode == DIST_NAUTIC)
+ g_strlcpy (t2, "nmi", sizeof (t2));
+
+ g_snprintf (t, sizeof (t), "%.3f x %.3f %s",
+ milesconv * 1.280 * f / PIXELFACT,
+ milesconv * 1.024 * f / PIXELFACT, t2);
+ gtk_entry_set_text (GTK_ENTRY (cover), t);
+ return TRUE;
+}
+
+/* *****************************************************************************
+ * Get http_proxy Variable from envirenment
+ */
+void get_proxy_from_env()
+{ // Set http_proxy
+ gint i;
+ gchar s1[100], s2[100];
+ const gchar *http_proxy;
+ gchar *p;
+ http_proxy = g_getenv ("HTTP_PROXY");
+ if (http_proxy == NULL)
+ http_proxy = g_getenv ("http_proxy");
+
+ if (http_proxy)
+ {
+ p = (char *) http_proxy;
+ g_strdelimit (p, ":/", ' ');
+
+ i = sscanf (p, "%s %s %d", s1, s2, &proxyport);
+ if (i == 3)
+ {
+ haveproxy = TRUE;
+ g_strlcpy (proxy, s2, sizeof (proxy));
+ if ( mydebug > 0 )
+ g_print (_("Using proxy: %s on port %d\n"),
+ proxy, proxyport);
+ }
+ else
+ {
+ g_print (_
+ ("\nInvalid enviroment variable HTTP_PROXY, "
+ "must be in format: http://proxy.provider.de:3128"));
+ }
+ }
+}
diff --git a/src/download_map.h b/src/download_map.h
new file mode 100644
index 0000000..1f731f1
--- /dev/null
+++ b/src/download_map.h
@@ -0,0 +1,61 @@
+/***********************************************************************
+
+Copyright (c) 2001,2002 Fritz Ganter <ganter@ganter.at>
+
+Website: www.kraftvoll.at/software
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+/*
+$Log$
+Revision 1.2 2006/05/09 08:29:52 tweety
+move proxy fetching from environment to download_map.c
+
+Revision 1.1 2006/02/05 15:01:59 tweety
+extract map downloading
+
+Revision 1.2 2005/04/02 12:10:12 tweety
+2005.03.30 by Oddgeir Kvien <oddgeir@oddgeirkvien.com>
+Canges made to import a map with one point and enter the scale
+
+Revision 1.1 2005/03/27 21:25:46 tweety
+separating map_import from gpsdrive.c
+
+
+*/
+
+
+#ifndef GPSDRIVE_DOWNLOAD_MAP_H
+#define GPSDRIVE_DOWNLOAD_MAP_H
+
+#include <gtk/gtk.h>
+
+/*
+ * See download_map.c for details.
+ */
+
+char *getexpediaurl (GtkWidget * widget);
+gint downloadstart_cb (GtkWidget * widget, guint datum);
+gint downloadslave_cb (GtkWidget * widget, guint datum);
+gint downloadsetparm (GtkWidget * widget, guint datum);
+gint defaultserver_cb (GtkWidget * widget, guint datum);
+gint download_cb (GtkWidget * widget, guint datum);
+void get_proxy_from_env();
+
+
+#endif /* GPSDRIVE_DOWNLOAD_MAP_H */
diff --git a/src/draw_grid.c b/src/draw_grid.c
new file mode 100644
index 0000000..1e4e561
--- /dev/null
+++ b/src/draw_grid.c
@@ -0,0 +1,258 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+/*
+ * draw_grid module:
+ */
+
+#include "config.h"
+#include "gettext.h"
+#include "gpsdrive.h"
+#include "icons.h"
+#include <fcntl.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include "routes.h"
+#include "import_map.h"
+#include "download_map.h"
+#include "gui.h"
+#include "main_gui.h"
+
+#include "gettext.h"
+#include <speech_strings.h>
+#include <speech_out.h>
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+
+extern GtkWidget *mylist;
+extern gint maploaded;
+extern gint isnight, disableisnight;
+extern color_struct colors;
+extern currentstatus_struct current;
+extern gint mydebug;
+extern GtkWidget *map_drawingarea;
+extern glong mapscale;
+extern GdkGC *kontext_map;
+
+extern gdouble earthr;
+extern gchar *displaytext;
+extern GTimer *timer, *disttimer;
+extern gdouble gbreit, glang, olddist;
+extern GtkWidget *messagewindow;
+extern gint onemousebutton;
+extern gint real_screen_x, real_screen_y, real_psize, real_smallmenu;
+extern GdkDrawable *drawable;
+extern gchar oldfilename[2048];
+extern GdkGC *kontext;
+
+/* *****************************************************************************
+ * Draw Text (lat/lon) into Grid
+ */
+void
+draw_grid_text (GtkWidget * widget, gdouble posx, gdouble posy, gchar * txt)
+{
+ /* prints in pango */
+ PangoFontDescription *pfd;
+ PangoLayout *grid_label_layout;
+ gint width, height;
+
+ grid_label_layout = gtk_widget_create_pango_layout (map_drawingarea, txt);
+
+ pfd = pango_font_description_from_string ("Sans 6");
+
+ pango_layout_set_font_description (grid_label_layout, pfd);
+ pango_layout_get_pixel_size (grid_label_layout, &width, &height);
+ gdk_gc_set_function (kontext_map, GDK_XOR);
+ gdk_gc_set_background (kontext_map, &colors.white);
+ gdk_gc_set_foreground (kontext_map, &colors.mygray);
+
+ gdk_draw_layout_with_colors (drawable, kontext_map, posx - width / 2,
+ posy - height / 2, grid_label_layout, &colors.black,
+ NULL);
+
+ if (grid_label_layout != NULL)
+ g_object_unref (G_OBJECT (grid_label_layout));
+ /* freeing PangoFontDescription, cause it has been copied by prev. call */
+ pango_font_description_free (pfd);
+
+}
+
+/* *****************************************************************************
+ */
+/*
+ * Draw a grid over the map
+ */
+void
+draw_grid (GtkWidget * widget)
+{
+ int count;
+ gdouble step;
+ gdouble lat, lon;
+ gdouble lat_ul, lon_ul;
+ gdouble lat_ll, lon_ll;
+ gdouble lat_ur, lon_ur;
+ gdouble lat_lr, lon_lr;
+
+ gdouble lat_min, lon_min;
+ gdouble lat_max, lon_max;
+
+ if ( mydebug >50 )
+ fprintf(stderr , "draw_grid()\n");
+
+
+ // calculate the start and stop for lat/lon according to the displayed section
+ calcxytopos (0, 0, &lat_ul, &lon_ul, current.zoom);
+ calcxytopos (0, SCREEN_Y, &lat_ll, &lon_ll, current.zoom);
+ calcxytopos (SCREEN_X, 0, &lat_ur, &lon_ur, current.zoom);
+ calcxytopos (SCREEN_X, SCREEN_Y, &lat_lr, &lon_lr, current.zoom);
+
+ // add more lines as the scale increases
+
+ // Calculate distance between grid lines
+ step = (gdouble) current.mapscale / 2000000.0 / current.zoom;
+ gchar precission[10];
+ gint iteration_count =0;
+ do {
+ if (step >= 1) g_snprintf (precission, sizeof (precission), "%%.0f");
+ else if (step >= .1) g_snprintf (precission, sizeof (precission), "%%.1f");
+ else if (step >= .01) g_snprintf (precission, sizeof (precission), "%%.2f");
+ else if (step >= .001) g_snprintf (precission, sizeof (precission), "%%.3f");
+ else if (step >= .0001) g_snprintf (precission, sizeof (precission), "%%.4f");
+ else g_snprintf (precission, sizeof (precission), "%%.5f");
+
+ if (current.mapscale < 5000000)
+ {
+ lat_min = min (lat_ll, lat_ul) - step;
+ lat_max = max (lat_lr, lat_ur) + step;
+ lon_min = min (lon_ll, lon_ul) - step;
+ lon_max = max (lon_lr, lon_ur) + step;
+ }
+ else
+ {
+ lat_min = -90;
+ lat_max = 90;
+ lon_min = -180;
+ lon_max = 180;
+ }
+ lat_min = floor (lat_min / step) * step;
+ lon_min = floor (lon_min / step) * step;
+
+ if ( mydebug > 20 )
+ printf ("Draw Grid: (%.2f,%.2f) - (%.2f,%.2f) Step %f for Scale %ld Zoom %d\n", lat_min, lon_min, lat_max, lon_max, step,
+ current.mapscale, current.zoom);
+ if ( mydebug > 40 )
+ {
+ printf ("Draw Grid: (%.2f) Iterations for lat\n", (lat_max-lat_min)/step);
+ printf ("Draw Grid: (%.2f) Iterations for lon\n", (lon_max-lon_min)/step);
+ }
+
+ // limit number of grid iterations to 100 iterations
+ iteration_count = ((lat_max-lat_min)/step) * ((lon_max-lon_min)/step);
+ if ( iteration_count > 100 ) {
+ step = step * 2;
+ }
+ } while ( iteration_count > 100 );
+
+ // Loop over desired lat/lon
+ count = 0;
+ for (lon = lon_min; lon <= lon_max; lon = lon + step)
+ {
+ for (lat = lat_min; lat <= lat_max; lat = lat + step)
+ {
+ gdouble posxdest11, posydest11;
+ gdouble posxdest12, posydest12;
+ gdouble posxdest21, posydest21;
+ gdouble posxdest22, posydest22;
+ gdouble posxdist, posydist;
+ gchar str[200];
+
+ count++;
+ calcxy (&posxdest11, &posydest11, lon, max(-90,lat) , current.zoom);
+ calcxy (&posxdest12, &posydest12, lon, min( 90,lat + step), current.zoom);
+ calcxy (&posxdest21, &posydest21, lon + step, max(-90,lat), current.zoom);
+ calcxy (&posxdest22, &posydest22, lon + step, min( 90,lat + step), current.zoom);
+
+ if (((posxdest11 >= 0) && (posxdest11 < SCREEN_X) &&
+ (posydest11 >= 0) && (posydest11 < SCREEN_Y))
+ ||
+ ((posxdest22 >= 0) && (posxdest22 < SCREEN_X) &&
+ (posydest22 >= 0) && (posydest22 < SCREEN_Y))
+ ||
+ ((posxdest21 >= 0) && (posxdest21 < SCREEN_X) &&
+ (posydest21 >= 0) && (posydest21 < SCREEN_Y))
+ ||
+ ((posxdest12 >= 0) && (posxdest12 < SCREEN_X) &&
+ (posydest12 >= 0) && (posydest12 < SCREEN_Y)))
+ {
+ // TODO: add linethickness 2 for Mayor Lines
+ // Set Drawing Mode
+ gdk_gc_set_function (kontext_map, GDK_XOR);
+ gdk_gc_set_foreground (kontext_map, &colors.darkgrey);
+ gdk_gc_set_line_attributes (kontext_map, 1, GDK_LINE_SOLID, 0, 0);
+
+ gdk_draw_line (drawable, kontext_map, posxdest11,
+ posydest11, posxdest21,
+ posydest21);
+ gdk_draw_line (drawable, kontext_map, posxdest11,
+ posydest11, posxdest12,
+ posydest12);
+
+ // Text lon
+ g_snprintf (str, sizeof (str), precission,lon);
+
+ posxdist = (posxdest12 - posxdest11) / 4;
+ posydist = (posydest12 - posydest11) / 4;
+ draw_grid_text (widget,
+ posxdest11 + posxdist,
+ posydest11 + posydist, str);
+
+ // Text lat
+ g_snprintf (str, sizeof (str), precission,lat);
+
+ posxdist = (posxdest21 - posxdest11) / 4;
+ posydist = (posydest21 - posydest11) / 4;
+ draw_grid_text (widget,
+ posxdest11 + posxdist,
+ posydest11 + posydist-5, str);
+ }
+ }
+ }
+ if ( mydebug > 30 )
+ printf ("draw_grid loops: %d\n", count);
+}
diff --git a/src/friends.c b/src/friends.c
new file mode 100644
index 0000000..a948b2b
--- /dev/null
+++ b/src/friends.c
@@ -0,0 +1,693 @@
+/* friendsd client
+ * Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+ *
+ * Website: www.gpsdrive.de
+ *
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * *********************************************************************
+ */
+
+
+/*
+ * inet.h - Definitions for TCP and UDP client/server programs.
+ */
+#include <config.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_LINUX_INET_H
+#include "linux/inet.h"
+#endif
+#include <unistd.h>
+#include <time.h>
+#include <gpsdrive.h>
+#include <gpsdrive_config.h>
+#include <math.h>
+#include "gui.h"
+#include "poi.h"
+#include "main_gui.h"
+
+#define SERV_UDP_PORT 50123
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+/* #define SERV_HOST_ADDR "213.203.231.23" */
+#define SERV_HOST_ADDR "127.0.0.1"
+
+extern int maxfriends;
+extern friendsstruct *friends, *fserver;
+int actualfriends = 0;
+extern int messagenumber;
+extern long int maxfriendssecs;
+extern gint zone;
+extern gdouble milesconv;
+extern GtkWidget *map_drawingarea;
+extern GdkPixbuf *friendsimage, *friendspixbuf;
+extern int usesql;
+extern gint mydebug;
+extern gint friends_poi_id[TRAVEL_N_MODES];
+extern poi_type_struct poi_type_list[poi_type_list_max];
+extern color_struct colors;
+extern coordinate_struct coords;
+extern currentstatus_struct current;
+extern GdkGC *kontext_map;
+
+/*
+ * conn.c
+ */
+int sockfd = -1;
+int pleasepollme = 0;
+extern GtkItemFactory *item_factory;
+extern int debug, statuslock;
+extern GtkWidget *frame_statusbar;
+extern int errno;
+extern gchar messagename[40], messagesendtext[1024], messageack[100];
+
+#define MAXLINE 512
+
+void
+setnonblocking (int sock)
+{
+ int opts;
+
+ opts = fcntl (sock, F_GETFL);
+ if (opts < 0)
+ {
+ perror ("fcntl(F_GETFL)");
+ exit (EXIT_FAILURE);
+ }
+ opts = (opts | O_NONBLOCK);
+ if (fcntl (sock, F_SETFL, opts) < 0)
+ {
+ perror ("fcntl(F_SETFL)");
+ exit (EXIT_FAILURE);
+ }
+ return;
+}
+
+
+/* ****************************************************************************
+ * Friends agent
+ */
+gint
+friendsagent_cb (GtkWidget * widget, guint * datum)
+{
+ time_t tii;
+ gchar buf[MAXMESG], buf2[40], la[20], lo[20], num[5];
+ gint i;
+
+ if ( mydebug >50 ) fprintf(stderr , "friendsagent_cb()\n");
+
+ /* Don't allow spaces in name */
+ for (i = 0; (size_t) i < strlen (local_config.friends_name); i++)
+ if (local_config.friends_name[i] == ' ')
+ local_config.friends_name[i] = '_';
+
+ /* send position to friendsserver */
+
+ if (local_config.showfriends)
+ {
+ if (strlen (messagesendtext) > 0)
+ {
+ /* send message to server */
+ if (messagenumber < 99)
+ messagenumber++;
+ else
+ messagenumber = 0;
+ current.needtosave = TRUE;
+ g_snprintf (num, sizeof (num), "%02d", messagenumber);
+ g_strlcpy (buf2, local_config.friends_id,
+ sizeof (buf2));
+ buf2[0] = 'M';
+ buf2[1] = 'S';
+ buf2[2] = 'G';
+ buf2[3] = num[0];
+ buf2[4] = num[1];
+ g_snprintf (buf, sizeof (buf), "SND: %s %s %s\n",
+ buf2, messagename, messagesendtext);
+ if ( mydebug > 3 )
+ fprintf (stderr, "friendsagent: sending to"
+ " %s:\nfriendsagent: %s\n",
+ local_config.friends_serverip, buf);
+ if (sockfd != -1)
+ close (sockfd);
+ sockfd = -1;
+ friends_sendmsg (local_config.friends_serverip, buf);
+ g_snprintf (messageack, sizeof (messageack),
+ "SND: %s", buf2);
+ }
+ else
+ {
+ /* send position to server */
+ if (gui_status.posmode)
+ {
+ g_snprintf (la, sizeof (la), "%10.6f",
+ coords.posmode_lat);
+ g_snprintf (lo, sizeof (lo), "%10.6f",
+ coords.posmode_lon);
+ }
+ else
+ {
+ g_snprintf (la, sizeof (la), "%10.6f",
+ coords.current_lat);
+ g_snprintf (lo, sizeof (lo), "%10.6f",
+ coords.current_lon);
+ }
+ g_strdelimit (la, ",", '.');
+ g_strdelimit (lo, ",", '.');
+ tii = time (NULL);
+ g_snprintf (buf, sizeof (buf),
+ "POS: %s %s %s %s %ld %.0f %.0f %d",
+ local_config.friends_id,
+ local_config.friends_name, la, lo, tii,
+ current.groundspeed / milesconv,
+ 180.0 * current.heading / M_PI,
+ local_config.travelmode);
+ if ( mydebug > 3 )
+ fprintf (stderr,
+ "friendsagent: sending to"
+ " %s:\nfriendsagent: %s\n",
+ local_config.friends_serverip, buf);
+ if (sockfd != -1)
+ close (sockfd);
+ sockfd = -1;
+ friends_sendmsg (local_config.friends_serverip, buf);
+ }
+ }
+
+ return TRUE;
+}
+
+
+/* ****************************************************************************
+ * Insert or update data coming from friendsd in database or way.txt file
+ */
+void
+update_friends_data (friendsstruct *cf)
+{
+ glong current_poi_id = 0;
+ gchar *result = NULL;
+
+ if (usesql)
+ {
+ //(cf)->id,
+ //(cf)->name,
+ //(cf)->lat,
+ //(cf)->lon,
+ //(cf)->timesec,
+ //(cf)->speed,
+ //(cf)->heading,
+ //(cf)->type,
+
+ /* check, if friend is already present in database */
+ current_poi_id = getsqlextradata (NULL, "friends_id",
+ (cf)->id, result);
+ if (current_poi_id)
+ {
+ if (mydebug > 30)
+ fprintf (stderr, "--------> updating friend"
+ " with poi_id = %ld\n", current_poi_id);
+ updatesqldata (current_poi_id, strtod((cf)->lat, NULL),
+ strtod((cf)->lon, NULL), (cf)->name,
+ (cf)->type, (cf)->timesec, 10);
+ updatesqlextradata (&current_poi_id,
+ "speed", (cf)->speed);
+ updatesqlextradata (&current_poi_id,
+ "heading", (cf)->heading);
+ }
+ else
+ {
+ // TODO: create new entry
+ current_poi_id = insertsqldata (strtod((cf)->lat, NULL),
+ strtod((cf)->lon, NULL), (cf)->name, (cf)->type,
+ (cf)->timesec, 10);
+ insertsqlextradata (&current_poi_id,
+ "friends_id", (cf)->id);
+ insertsqlextradata (&current_poi_id,
+ "speed", (cf)->speed);
+ insertsqlextradata (&current_poi_id,
+ "heading", (cf)->heading);
+ }
+ }
+ else
+ {
+ // TODO: add entry to way.txt file
+ return;
+ }
+}
+
+
+int
+friends_sendmsg (char *serverip, char *message)
+{
+ int n, nosent, endflag, e;
+ char recvline[MAXLINE + 1];
+ int i, fc, type;
+ struct sockaddr_in cli_addr;
+ struct sockaddr_in serv_addr;
+ struct sockaddr *pserv_addr;
+ socklen_t servlen;
+ friendsstruct *f;
+ char msgname[40], msgid[40], msgtext[1024];
+
+ if (serverip == NULL)
+ {
+ fprintf (stderr, "error in friends_sendmsg: serverip=NULL\n");
+ return 0;
+ }
+
+ if (message != NULL)
+ if (strlen (message) == 0)
+ {
+ fprintf (stderr, "error in friends_sendmsg: message=empty\n");
+ return 0;
+ }
+
+ f = friends;
+ g_strlcpy (msgname, "", sizeof (msgname));
+ g_strlcpy (msgtext, "", sizeof (msgtext));
+
+ /* skip if we already have an sockfd */
+ if (message != NULL)
+ if (sockfd == -1)
+ {
+ bzero ((char *) &serv_addr, sizeof (serv_addr));
+ serv_addr.sin_family = AF_INET;
+
+ serv_addr.sin_addr.s_addr = inet_addr (serverip);
+ serv_addr.sin_port = htons (SERV_UDP_PORT);
+ pserv_addr = (struct sockaddr *) &serv_addr;
+
+ if ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ perror ("friendsclient local socket");
+ return (1);
+ }
+ setnonblocking (sockfd);
+
+ servlen = sizeof (serv_addr);
+ bzero ((char *) &cli_addr, sizeof (cli_addr));
+
+ cli_addr.sin_family = AF_INET;
+ cli_addr.sin_addr.s_addr = htons (INADDR_ANY);
+ cli_addr.sin_port = htons (0);
+
+ if (bind
+ (sockfd, (struct sockaddr *) &cli_addr, sizeof (cli_addr)) < 0)
+ {
+ perror ("friendsclient bind local address");
+ return (2);
+ }
+
+ n = strlen (message);
+ /* printf ("sending...\n"); */
+ if ((nosent =
+ sendto (sockfd, message, n, 0, pserv_addr, servlen)) != n)
+ {
+ perror ("friendsclient sendto");
+ return (3);
+ }
+ else
+ {
+ pleasepollme = TRUE;
+ }
+
+ /* end skip if we already have an sockfd */
+
+ /* return, so we read the next time */
+ return 0;
+ }
+ endflag = i = 0;
+
+ fc = 0;
+ do
+ {
+ n = recvfrom (sockfd, recvline, MAXLINE, 0 /* MSG_WAITALL */ ,
+ (struct sockaddr *) 0, (socklen_t *) 0);
+ if (n < 0)
+ {
+ i++;
+ usleep (100000);
+ fprintf (stderr, "errno %d:", errno);
+ perror ("recv");
+ }
+ else
+ i = 0;
+ if (n > 0)
+ {
+ if ((strncmp (recvline, "$END:$", 6)) == 0)
+ endflag = 1;
+ recvline[n] = 0;
+ /* if (debug) */
+ /* printf ("received...%d bytes: %s\n=======\n", n, recvline); */
+ /* scanning reply */
+ if ((strncmp (recvline, "POS: ", 5)) == 0)
+ {
+ e = sscanf (recvline,
+ "POS: %s %s %s %s %s %s %s %d",
+ (f + fc)->id, (f + fc)->name,
+ (f + fc)->lat, (f + fc)->lon,
+ (f + fc)->timesec,
+ (f + fc)->speed, (f + fc)->heading,
+ &type);
+ /* printf("\nreceived %d arguments\n",e); */
+ if (type == TRAVEL_CAR)
+ g_snprintf ((f + fc)->type, sizeof ((f + fc)->type),
+ "people.friendsd.car");
+ else if (type == TRAVEL_AIRPLANE)
+ g_snprintf ((f + fc)->type, sizeof ((f + fc)->type),
+ "people.friendsd.airplane");
+ else if (type == TRAVEL_BIKE)
+ g_snprintf ((f + fc)->type, sizeof ((f + fc)->type),
+ "people.friendsd.bike");
+ else if (type == TRAVEL_BOAT)
+ g_snprintf ((f + fc)->type, sizeof ((f + fc)->type),
+ "people.friendsd.boat");
+ else if (type == TRAVEL_WALK)
+ g_snprintf ((f + fc)->type, sizeof ((f + fc)->type),
+ "people.friendsd.walk");
+ else
+ g_snprintf ((f + fc)->type, sizeof ((f + fc)->type),
+ "people.friendsd");
+
+ update_friends_data ((f + fc));
+ fc++;
+ }
+ if ((strncmp (recvline, "SRV: ", 5)) == 0)
+ {
+ e = sscanf (recvline,
+ "SRV: %s %s %s %s %s %s %s",
+ fserver->id, fserver->name,
+ fserver->lat, fserver->lon,
+ fserver->timesec, fserver->speed, fserver->heading);
+ /* printf("\nreceived %d arguments\n",e); */
+ }
+ if ((strncmp (recvline, "SND: ", 5)) == 0)
+ {
+ if ((strlen (messageack) > 0)
+ &&
+ (strncmp (recvline, messageack, strlen (messageack)) == 0))
+ {
+ g_strlcpy (messagename, "", sizeof (messagename));
+ g_strlcpy (messageack, "", sizeof (messageack));
+ g_strlcpy (messagesendtext, "", sizeof (messagesendtext));
+// wi = gtk_item_factory_get_item
+// (item_factory, N_("/Misc. Menu/Messages"));
+// gtk_widget_set_sensitive (wi, TRUE);
+ gtk_statusbar_pop (GTK_STATUSBAR (frame_statusbar),
+ current.statusbar_id);
+ statuslock = FALSE;
+ }
+ else
+ {
+ e = sscanf (recvline,
+ "SND: %s %s %[^\n]", msgid, msgname, msgtext);
+ if (e == 3)
+ if (strcmp ((msgname), (local_config.friends_name)) == 0)
+ {
+ int j, k = 0, fsmessage = 0;
+
+ g_strlcpy (msgname, _("unknown"), sizeof (msgname));
+ if (strcmp ((msgid + 5), ((fserver->id) + 5)) == 0)
+ {
+ g_snprintf
+ (msgname, sizeof (msgname), fserver->name);
+ fsmessage = TRUE;
+ }
+ for (j = 0; j < fc; j++)
+ if (strcmp ((msgid + 5), (((f + j)->id) + 5)) == 0)
+ g_strlcpy
+ (msgname, (f + j)->name, sizeof (msgname));
+ for (j = 0; j < (int) strlen (recvline); j++)
+ {
+ if (*(recvline + j) == ' ')
+ k++;
+ if (k >= 3)
+ break;
+ }
+ g_strlcpy (msgtext,
+ (recvline + j + 1), sizeof (msgtext));
+ /* if (debug) */
+ /* fprintf (stderr, "\ne: %d, received from %s: %s\n", */
+ /* e, msgname, msgtext); */
+ message_cb (msgid, msgname, msgtext, fsmessage);
+ }
+ }
+ }
+
+ if (debug)
+ fprintf (stderr, "%s", recvline);
+
+ }
+ /* printf("\ni: %d, endflag: %d\n",i,endflag); */
+ }
+ while ((n > 0) && (!endflag));
+
+ /* printf("\nafter while i: %d, endflag: %d\n",i,endflag); */
+ if (endflag)
+ {
+ close (sockfd);
+ sockfd = -1;
+ pleasepollme = FALSE;
+ if (fc != 0)
+ maxfriends = fc;
+ }
+
+
+ return 0;
+}
+
+
+int
+friends_init ()
+{
+
+ char *key, buf2[20];
+ int f, i, j;
+ long int r;
+ time_t ti, tii;
+
+ if ((strcmp (local_config.friends_id, "XXX")) == 0)
+ {
+ r = 0x12345678;
+ f = open ("/dev/random", O_RDONLY);
+ if (f >= 0)
+ {
+ read (f, &r, 4);
+ close (f);
+ }
+ tii = ti = time (NULL);
+ ti = ti & 0xffffff;
+ r += ti;
+
+ g_snprintf (buf2, sizeof (buf2), "$1$%08lx$", r);
+ key = "havenocrypt";
+#ifdef HAVE_CRYPT_H
+ key = crypt ("fritz", buf2);
+ g_strlcpy (local_config.friends_id, (key + 12), sizeof (local_config.friends_id));
+#else
+ r = r * r;
+ g_snprintf (local_config.friends_id, sizeof (local_config.friends_id),
+ "nocrypt%015ld", labs (r));
+#endif
+ printf ("\nKey: %s,id: %s %Zu bytes, time: %ld\n", key,
+ local_config.friends_id, strlen (local_config.friends_id), ti);
+ current.needtosave = TRUE;
+ }
+ friends = malloc (MAXLISTENTRIES * sizeof (friendsstruct));
+ fserver = malloc (1 * sizeof (friendsstruct));
+
+ /* store poitype ids for friends */
+ for (i = 0; i < TRAVEL_N_MODES; i++)
+ {
+ friends_poi_id[i] = -1;
+ }
+ j = 0;
+ for (i = 0; i < poi_type_list_max; i++)
+ {
+ if (mydebug > 30)
+ {
+ fprintf (stderr,
+ "friends_init: Checking POI-Type: %d - %s\n",
+ i, poi_type_list[i].name);
+ }
+
+ if (g_str_has_prefix (poi_type_list[i].name, "people.friendsd"))
+ {
+ friends_poi_id[j] = poi_type_list[i].poi_type_id;
+ if (mydebug > 30)
+ {
+ fprintf (stderr,
+ "friends_init: \t\t\tType %d is friend!\n",
+ friends_poi_id[j]);
+ }
+ j++;
+ if (j >= TRAVEL_N_MODES)
+ break;
+ }
+ }
+
+ return (0);
+}
+
+
+/* *****************************************************************************
+ */
+void
+drawfriends (void)
+{
+ gint i;
+ gdouble posxdest, posydest, clong, clat, heading;
+ gint width, height;
+ struct tm *t;
+ time_t ti, tif;
+
+ actualfriends = 0;
+ /* g_print("Maxfriends: %d\n",maxfriends); */
+ for (i = 0; i < maxfriends; i++)
+ {
+
+ /* return if too old */
+ ti = time (NULL);
+ tif = atol ((friends + i)->timesec);
+ if (!(tif > 1000000000))
+ fprintf (stderr,
+ "Format error! timesec: %s, Name: %s, i: %d\n",
+ (friends + i)->timesec, (friends + i)->name, i);
+ if ((ti - local_config.friends_maxsecs) > tif)
+ continue;
+ actualfriends++;
+ coordinate_string2gdouble ((friends + i)->lon, &clong);
+ coordinate_string2gdouble ((friends + i)->lat, &clat);
+
+ calcxy (&posxdest, &posydest, clong, clat, current.zoom);
+
+ /* If Friend is visible inside SCREEN display him/her */
+ if ((posxdest >= 0) && (posxdest < SCREEN_X))
+ {
+
+ if ((posydest >= 0) && (posydest < SCREEN_Y))
+ {
+
+ gdk_draw_pixbuf (drawable, kontext_map,
+ friendspixbuf, 0, 0,
+ posxdest - 18, posydest - 12,
+ 39, 24, GDK_RGB_DITHER_NONE, 0, 0);
+
+ /* draw pointer to direction */
+ heading =
+ strtod ((friends + i)->heading, NULL) * M_PI / 180.0;
+ draw_posmarker
+ (posxdest, posydest, heading, &colors.blue, 1, FALSE, FALSE);
+
+ { /* print friends name / speed on map */
+ PangoFontDescription *pfd;
+ PangoLayout *wplabellayout;
+ gchar txt[200], txt2[100], s1[10];
+ time_t sec;
+ char *as, day[20], dispname[40];
+ int speed, ii;
+
+ sec = atol ((friends + i)->timesec);
+ sec += 3600 * zone;
+ t = gmtime (&sec);
+
+ as = asctime (t);
+ sscanf (as, "%s", day);
+ sscanf ((friends + i)->speed, "%d", &speed);
+
+ /* replace _ with spaces in name */
+ g_strlcpy (dispname, (friends + i)->name, sizeof (dispname));
+ for (ii = 0; (size_t) ii < strlen (dispname); ii++)
+ if (dispname[ii] == '_')
+ dispname[ii] = ' ';
+
+ g_snprintf (txt, sizeof (txt),
+ "%s, %d ", dispname, (int) (speed * milesconv));
+ if (local_config.distmode == DIST_MILES)
+ g_snprintf (s1, sizeof (s1), "%s", _("mi/h"));
+ else if (local_config.distmode == DIST_NAUTIC)
+ g_snprintf (s1, sizeof (s1), "%s", _("knots"));
+ else
+ g_snprintf (s1, sizeof (s1), "%s", _("km/h"));
+ g_strlcat (txt, s1, sizeof (txt));
+ g_snprintf (txt2, sizeof (txt2),
+ "\n%s, %2d:%02d\n", day, t->tm_hour, t->tm_min);
+ g_strlcat (txt, txt2, sizeof (txt));
+ wplabellayout =
+ gtk_widget_create_pango_layout (map_drawingarea, txt);
+ if (local_config.guimode == GUI_PDA)
+ pfd = pango_font_description_from_string ("Sans 8");
+ else
+ if (local_config.guimode == GUI_CAR)
+ pfd = pango_font_description_from_string ("Sans 8");
+ else
+ pfd = pango_font_description_from_string
+ (local_config.font_friends);
+ pango_layout_set_font_description (wplabellayout, pfd);
+ pango_layout_get_pixel_size (wplabellayout, &width, &height);
+ gdk_gc_set_foreground (kontext_map, &colors.textbacknew);
+ /* gdk_draw_rectangle (drawable, kontext_map, 1, posxdest + 18,
+ * posydest - height/2 , width + 2,
+ * height + 2);
+ */
+
+ gdk_draw_layout_with_colors (drawable,
+ kontext_map,
+ posxdest + 21,
+ posydest - height / 2 + 1,
+ wplabellayout, &colors.black, NULL);
+ gdk_draw_layout_with_colors (drawable,
+ kontext_map,
+ posxdest + 20,
+ posydest - height / 2,
+ wplabellayout, &colors.friends, NULL);
+
+ if (wplabellayout != NULL)
+ g_object_unref (G_OBJECT (wplabellayout));
+ /* freeing PangoFontDescription, cause it has been copied by prev. call */
+ pango_font_description_free (pfd);
+
+ }
+
+
+ }
+ }
+ }
+}
diff --git a/src/friendsd.c b/src/friendsd.c
new file mode 100644
index 0000000..e6dddb1
--- /dev/null
+++ b/src/friendsd.c
@@ -0,0 +1,611 @@
+/* ******************************************************************
+ * friendsd server
+ * Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+ *
+ * Website: www.gpsdrive.de
+ *
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * *********************************************************************
+ $Log$
+ Revision 1.6 2006/01/03 14:24:10 tweety
+ eliminate compiler Warnings
+ try to change all occurences of longi -->lon, lati-->lat, ...i
+ use drawicon(posxdest,posydest,"w-lan.open") instead of using a seperate variable
+ rename drawgrid --> do_draw_grid
+ give the display frames usefull names frame_lat, ...
+ change handling of WP-types to lowercase
+ change order for directories reading icons
+ always read inconfile
+
+ Revision 1.5 2005/11/05 19:52:17 tweety
+ Fix Bufferoverflow
+ http://seclists.org/lists/fulldisclosure/2005/Nov/0129.html
+
+ Revision 1.4 2005/04/20 23:33:49 tweety
+ reformatted source code with anjuta
+ So now we have new indentations
+
+ Revision 1.3 2005/04/13 19:58:31 tweety
+ renew indentation to 4 spaces + tabstop=8
+
+ Revision 1.2 2005/04/10 21:50:49 tweety
+ reformatting c-sources
+
+ Revision 1.1.1.1 2004/12/23 16:03:24 commiter
+ Initial import, straight from 2.10pre2 tar.gz archive
+
+ Revision 1.21 2004/02/08 17:16:25 ganter
+ replacing all strcat with g_strlcat to avoid buffer overflows
+
+ Revision 1.20 2004/02/08 16:35:10 ganter
+ replacing all sprintf with g_snprintf to avoid buffer overflows
+
+ Revision 1.19 2004/02/06 22:29:24 ganter
+ updated README and man page
+
+ Revision 1.18 2004/01/26 11:55:19 ganter
+ just indented some files
+
+ Revision 1.17 2004/01/22 07:13:27 ganter
+ ...
+
+ Revision 1.16 2004/01/22 06:44:12 ganter
+ ...
+
+ Revision 1.15 2004/01/22 06:38:02 ganter
+ working on friendsd
+
+ Revision 1.14 2004/01/22 05:49:22 ganter
+ friendsd now sends a receiving acknoledge
+
+ Revision 1.13 2004/01/12 21:52:02 ganter
+ added friends message service
+
+ Revision 1.12 2004/01/11 17:35:48 ganter
+ drop entries which are older than 1 week
+
+ Revision 1.11 2004/01/01 09:07:31 ganter
+ v2.06
+ trip info is now live updated
+ added cpu temperature display for acpi
+ added tooltips for battery and temperature
+
+ Revision 1.10 2003/10/10 06:50:53 ganter
+ added security patch for friendsd
+
+ Revision 1.9 2003/09/17 12:05:14 ganter
+ 2.05pre1
+ fixed malloc problem in friends server
+ force name in friendsmode to replace space with underscore
+
+ Revision 1.8 2003/07/25 12:17:14 ganter
+ 2.00
+
+ Revision 1.7 2003/06/01 17:27:33 ganter
+ v2.0pre8
+ friendsmode works fine and can be set in settings menu
+
+ Revision 1.6 2003/05/31 20:12:35 ganter
+ new UDP friendsserver build in, needs some work
+
+ Revision 1.3 2003/05/31 18:25:57 ganter
+ starting buildin new server and client
+
+ Revision 1.2 2003/05/30 15:35:16 ganter
+ testing
+
+*/
+
+
+#include "../config.h"
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <time.h>
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
+
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+#define SERV_UDP_PORT 50123
+
+/* maximum age of data (1 week) */
+#define MAXSEC 7*24*3600
+
+/* max age of messages (2 days) */
+#define MAXMSGTIME 48*3600
+
+char *pname;
+
+/*
+ * conn.c
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#ifdef HAVE_LINUX_INET_H
+#include "linux/inet.h"
+#endif
+#include <fcntl.h>
+#include <netdb.h>
+#include <gpsdrive.h>
+
+
+
+struct
+{
+ char id[31];
+ char txt[1024];
+ long int times;
+} *list;
+
+static int listnum = 0, messagecounter = 0;
+char serverid[31];
+char serverstring[40];
+
+void
+dg_echo (int sockfd, struct sockaddr *pcli_addr, int maxclilen)
+{
+ int n, e, i, nosent, l, newclient;
+ char mesg[MAXMESG], txt[MAXMESG + 20];
+ char *fromaddr, hname[256];
+ struct in_addr iaddr;
+ socklen_t clilen;
+ struct hostent *hostname;
+ struct sockaddr_in sin;
+ char id[31], name[41], lat[41], lon[41], timesec[41], speed[11],
+ heading[11];
+ char msgname[40], msgtext[1024], ackid[40];
+
+ for (;;)
+ {
+ clilen = maxclilen;
+ memset (mesg, 0, MAXMESG);
+ n = recvfrom (sockfd, mesg, MAXMESG, 0, pcli_addr, &clilen);
+
+ if (n < 0)
+ {
+ perror ("recvfrom");
+ }
+ else
+ {
+ /* got string */
+ g_strlcpy (msgname, "", sizeof (msgname));
+ g_strlcpy (msgtext, "", sizeof (msgtext));
+ newclient = 1;
+
+ if ((strncmp (mesg, "SND: ", 5)) == 0)
+ {
+ e = sscanf (mesg, "SND: %s %s %[^\n]", id,
+ msgname, msgtext);
+ if (e == 3)
+ {
+ fprintf (stderr,
+ "\ne: %d received for %s: %s\n",
+ e, msgname, msgtext);
+ for (i = 0; i < listnum; i++)
+ {
+ /* id is already here */
+ if ((strcmp
+ ((list + i)->id,
+ id)) == 0)
+ {
+ newclient = 0;
+ strncpy ((list +
+ i)->txt,
+ mesg,
+ MAXMESG - 1);
+ (list + i)->times =
+ time (NULL) -
+ MAXSEC +
+ MAXMSGTIME;
+ }
+ }
+ if (newclient)
+ {
+ /* new id found */
+ listnum++;
+ if (listnum >= MAXLISTENTRIES)
+ listnum = 0;
+ strncpy ((list + i)->txt,
+ mesg, MAXMESG - 1);
+ strncpy ((list + i)->id, id,
+ 30);
+ (list + i)->times =
+ time (NULL) - MAXSEC +
+ MAXMSGTIME;
+ }
+ }
+ }
+ if ((strncmp (mesg, "POS: ", 5)) == 0)
+ {
+ /* found POS string */
+
+ e = sscanf (mesg,
+ "POS: %30s %40s %40s %40s %40s %10s %10s",
+ id, name, lat, lon, timesec,
+ speed, heading);
+ /* printf("\nGot %d arguments\n",e); */
+ if ((e == 7)
+ && (strstr (id, "queryqueryqueryqueryqu")
+ == NULL))
+ {
+ /* string is a POS string */
+ for (i = 0; i < listnum; i++)
+ {
+ /* id is already here */
+ if ((strcmp
+ ((list + i)->id,
+ id)) == 0)
+ {
+ newclient = 0;
+ strncpy ((list +
+ i)->txt,
+ mesg, 200);
+ (list + i)->times =
+ atol
+ (timesec);
+ }
+ }
+
+ if (newclient)
+ {
+ /* new id found */
+ listnum++;
+ if (listnum >= MAXLISTENTRIES)
+ listnum = 0;
+ strncpy ((list + i)->txt,
+ mesg, 200);
+ strncpy ((list + i)->id, id,
+ 30);
+ (list + i)->times =
+ atol (timesec);
+ }
+ }
+ }
+ /* send ack message to sender and delete messages where we got an ACK */
+ if ((strncmp (mesg, "ACK: ", 5)) == 0)
+ {
+ char recname[80], tmp[80], msgname[80];
+ g_strlcpy (recname, "", sizeof (recname));
+ e = sscanf (mesg, "ACK: %s ", ackid);
+ if (e == 1)
+ for (i = 0; i < listnum; i++)
+ {
+ if ((strcmp
+ ((list + i)->id,
+ ackid)) == 0)
+ {
+ int j, own;
+ char sid[40];
+ /* find sender of orig message (msgname) */
+ if (strcmp
+ ((ackid + 5),
+ (serverid +
+ 5)) == 0)
+ own = 1;
+ else
+ own = 0;
+
+ if (own)
+ {
+ /* its the ack for myself, delete from list */
+ for (j = i;
+ j <
+ listnum;
+ j++)
+ *(list
+ +
+ j) =
+ *
+ (list
+ +
+ j +
+ 1);
+ listnum--;
+ fprintf (stderr, "ack for my OWN msg %s, deleting entry\n", ackid);
+ break;
+ }
+ else
+ {
+ for (j = 0;
+ j <
+ listnum;
+ j++)
+ if (strcmp ((ackid + 5), (((list + j)->id) + 5)) == 0)
+ {
+ e = sscanf ((list + j)->txt, "POS: %s %s", tmp, msgname);
+ break;
+ }
+ /* find receiver of message (recname) */
+ e = sscanf ((list + i)->txt, "SND: %s %s", tmp, recname);
+ g_snprintf
+ (sid,
+ sizeof
+ (sid),
+ "MSG%02d%s",
+ messagecounter++,
+ (serverid
+ +
+ 5));
+ g_snprintf ((list + i)->id, sizeof (list->id), sid);
+ g_snprintf ((list + i)->txt, sizeof (list->txt), "SND: %s %s \nConfirmation:\n The user %s has read your message!", sid, msgname, recname);
+ (list +
+ i)->times =
+ time (NULL) -
+ MAXSEC +
+ MAXMSGTIME;
+ fprintf (stderr, "received acknoledge for msg %s, deleting entry\n", ackid);
+ }
+
+ }
+ }
+ }
+
+ /* sort out entries older than MAXSEC seconds */
+ for (i = 0; i < listnum; i++)
+ {
+ time_t tii;
+
+ if ((strncmp ((list + i)->txt, "SRV:", 4)) !=
+ 0)
+ {
+ tii = time (NULL);
+ if ((tii - (list + i)->times) >
+ MAXSEC)
+ {
+ int j;
+ for (j = i; j < listnum; j++)
+ *(list + j) =
+ *(list + j +
+ 1);
+ listnum--;
+ }
+ }
+ }
+ }
+
+ memcpy (&iaddr, (pcli_addr->sa_data + 2), 4);
+ fromaddr = inet_ntoa (iaddr);
+
+ bzero ((caddr_t *) & sin, sizeof (sin)); /* clear out the structure */
+ sin.sin_family = AF_INET;
+
+ sin.sin_addr.s_addr = inet_addr (fromaddr);
+
+
+
+ hostname = gethostbyaddr ((char *) &(sin.sin_addr),
+ sizeof (sin.sin_addr),
+ (int) sin.sin_family);
+
+
+ if (hostname == NULL)
+ {
+ perror ("hostname");
+ g_strlcpy (hname, "unknown", sizeof (hname));
+ }
+ else
+ g_strlcpy (hname, hostname->h_name, sizeof (hname));
+
+ mesg[n - 1] = 0;
+
+ for (i = -1; i <= listnum; i++)
+ {
+ if (i == -1)
+ g_strlcpy (txt, "$START:$", sizeof (txt));
+ else if (i == listnum)
+ g_strlcpy (txt, "$END:$", sizeof (txt));
+ else
+ g_strlcpy (txt, (list + i)->txt,
+ sizeof (txt));
+
+ g_strlcat (txt, "\n", sizeof (txt));
+ l = strlen (txt);
+ if (i == -1)
+ fprintf (stderr,
+ "%d clients, last: %s[%s]:\n",
+ listnum, hname, fromaddr);
+
+ fprintf (stderr, "%s",txt);
+ /* printf ("sende\n%s, Laenge %d, clilen %d", txt, l,clilen); */
+ if ((nosent =
+ sendto (sockfd, txt, l, 0, pcli_addr,
+ clilen)) != l)
+ {
+ perror ("sendto");
+ return;
+ }
+ }
+ fprintf (stderr, "\n");
+ }
+}
+
+
+
+/*
+ * server.c
+ */
+
+
+
+
+void
+ignore_pipe (void)
+{
+ struct sigaction sig;
+
+ sig.sa_handler = SIG_IGN;
+ sig.sa_flags = 0;
+ sigemptyset (&sig.sa_mask);
+ sigaction (SIGPIPE, &sig, NULL);
+}
+
+void
+setnonblocking (int sock)
+{
+ int opts;
+
+ opts = fcntl (sock, F_GETFL);
+ if (opts < 0)
+ {
+ perror ("fcntl(F_GETFL)");
+ exit (EXIT_FAILURE);
+ }
+ opts = (opts | O_NONBLOCK);
+ if (fcntl (sock, F_SETFL, opts) < 0)
+ {
+ perror ("fcntl(F_SETFL)");
+ exit (EXIT_FAILURE);
+ }
+ return;
+}
+
+int
+friends_init ()
+{
+
+ char *key, buf2[20];
+ int f;
+ long int r;
+ time_t ti, tii;
+ char t_friendsidstring[31];
+ r = 0x12345678;
+ f = open ("/dev/random", O_RDONLY);
+ if (f >= 0)
+ {
+ read (f, &r, 4);
+ close (f);
+ }
+ tii = ti = time (NULL);
+ ti = ti & 0xffffff;
+ r += ti;
+
+ g_snprintf (buf2, sizeof (buf2), "$1$%08lx$", r);
+ key = "havenocrypt";
+#ifdef HAVE_CRYPT_H
+ key = crypt ("servr", buf2);
+ g_strlcpy (t_friendsidstring, (key + 12), sizeof (t_friendsidstring));
+#else
+ r = r * r;
+ g_snprintf (t_friendsidstring, sizeof (t_friendsidstring),
+ "nocrypt%015ld", labs (r));
+#endif
+ printf ("\nKey: %s,id: %s %Zu bytes, time: %ld\n", key,
+ t_friendsidstring, strlen (t_friendsidstring), ti);
+
+ g_strlcpy (serverid, t_friendsidstring, sizeof (serverid));
+ return (0);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int sockfd, bindno, i;
+ struct sockaddr_in serv_addr, cli_addr;
+
+
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ bind_textdomain_codeset (PACKAGE, "utf8");
+ textdomain (GETTEXT_PACKAGE);
+ textdomain (NULL);
+ pname = argv[0];
+ g_strlcpy (serverstring, "Friendsserver", sizeof (serverstring));
+
+ if (geteuid () == 0)
+ {
+ fprintf (stderr, _("server: please don't run me as root\n"));
+ exit (1);
+ }
+ i = getopt (argc, argv, "n:h?");
+ switch (i)
+ {
+ case 'n':
+ g_strlcpy (serverstring, optarg, sizeof (serverstring));
+ break;
+ case 'h':
+ case '?':
+ printf (_
+ ("\nUsage:\n %s -n servername\nprovides a name for your server\n"),
+ pname);
+ exit (0);
+ break;
+ }
+ fprintf (stderr,
+ "\nGpsDrive v%s friendsd server Version 2, listening on UDP port %d...\n",
+ VERSION, SERV_UDP_PORT);
+ ignore_pipe ();
+
+ friends_init ();
+ list = malloc (MAXLISTENTRIES * sizeof (*list));
+
+ /* make the first entry */
+ g_snprintf ((list + listnum)->id, sizeof (list->id), serverid);
+ g_snprintf ((list + listnum)->txt, sizeof (list->txt),
+ "SRV: %s %s 53.566593 9.948155 %d 0 0", serverid,
+ serverstring, (int) time (NULL));
+ (list + listnum)->times = time (NULL);
+ listnum++;
+
+ /* printf ("\nsizeoflist: %d\n", sizeof (*list)); */
+ if ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ fprintf (stderr, "server: errno = %d\n", errno);
+ fprintf (stderr, "server: can't open datagram socket\n");
+ exit (1);
+ }
+ /* setnonblocking(sockfd); */
+
+ fprintf (stderr, "server: sockfd = %d\n", sockfd);
+ bzero ((char *) &serv_addr, sizeof (serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = htonl (INADDR_ANY);
+ serv_addr.sin_port = htons (SERV_UDP_PORT);
+
+ if ((bindno =
+ bind (sockfd, (struct sockaddr *) &serv_addr,
+ sizeof (serv_addr))) < 0)
+ {
+ fprintf (stderr, "server: errno = %d\n", errno);
+ fprintf (stderr, "server: can't bind local address\n");
+ exit (2);
+ }
+
+ fprintf (stderr, "server: bindno = %d\n", bindno);
+
+ dg_echo (sockfd, (struct sockaddr *) &cli_addr, sizeof (cli_addr));
+ return 0;
+}
diff --git a/src/geometry.c b/src/geometry.c
new file mode 100644
index 0000000..45b6e69
--- /dev/null
+++ b/src/geometry.c
@@ -0,0 +1,143 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ *********************************************************************
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <math.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gpsdrive.h>
+#include <config.h>
+#include <math.h>
+
+
+/* variables */
+extern gint ignorechecksum, mydebug;
+extern gint real_screen_x, real_screen_y, real_psize, real_smallmenu;
+extern gint SCREEN_X_2, SCREEN_Y_2;
+extern gdouble posx, posy;
+extern gint haveposcount, blink, gblink, xoff, yoff;
+
+
+/* ******************************************************************
+ * liang-barsky line clipping
+ */
+int clipt(gdouble d, gdouble n, gdouble *te, gdouble *tl)
+{
+ gdouble t;
+ int ac = 1;
+
+ if (d > 0.0) {
+ t = n / d;
+ if (t > *tl) {
+ ac = 0;
+ } else if (t > *te) {
+ *te = t;
+ }
+ } else if (d < 0.0) {
+ t = n / d;
+ if (t < *te) {
+ ac = 0;
+ } else if (t < *tl) {
+ *tl = t;
+ }
+ } else {
+ if (n > 0.0) {
+ ac = 0;
+ }
+ }
+ return ac;
+}
+
+static int clip_pointxy(gdouble x, gdouble y,
+ gdouble xg1, gdouble yg1,
+ gdouble xg2, gdouble yg2)
+{
+ return ((x >= xg1) && (x <= xg2) && (y >= yg1) && (y <= yg2));
+}
+
+
+/* ******************************************************************
+ */
+gint
+line_crosses_rectangle(gdouble x0, gdouble y0, gdouble x1, gdouble y1,
+ gdouble xg1, gdouble yg1,
+ gdouble xg2, gdouble yg2 )
+{
+ gdouble te = 0.0;
+ gdouble tl = 1.0;
+ gdouble dx = (x1 - x0);
+ gdouble dy = (y1 - y0);
+
+ if (dx == 0.0 &&
+ dy == 0.0 &&
+ clip_pointxy(x1, y1,
+ xg1, yg1,
+ xg2, yg2)
+ ) {
+ return 1;
+ }
+ if (clipt(dx, xg1 - x0, &te, &tl)) {
+ if (clipt(-dx, x0 - xg2, &te, &tl)) {
+ if (clipt(dy, yg1 - y0, &te, &tl)) {
+ if (clipt(-dy, y0 - yg2, &te, &tl)) {
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/* ******************************************************************
+ * Find the shortest distance from a point to a line-segment
+ */
+gdouble
+distance_line_point(gdouble x1, gdouble y1, gdouble x2, gdouble y2,
+ gdouble xp, gdouble yp)
+{
+
+ //if ( mydebug >0 )
+ // fprintf( stderr, "distance_line_point(%g,%g, %g,%g, %g,%g)\n", x1, y1, x2, y2, xp, yp);
+
+ gdouble dx1p = x1 - xp;
+ gdouble dx21 = x2 - x1;
+ gdouble dy1p = y1 - yp;
+ gdouble dy21 = y2 - y1;
+ gdouble frac = dx21*dx21 + dy21*dy21;
+
+ gdouble lambda = -(dx1p*dx21 + dy1p*dy21) / frac;
+ //if ( mydebug > 10 ) printf ("distance_line_point(): lambda_1: %g\n",lambda);
+ lambda = min(max(lambda,0.0),1.0);
+
+ //if ( mydebug > 10 ) printf ("distance_line_point(): lambda: %g\n",lambda);
+
+ gdouble xsep = dx1p + lambda*dx21;
+ gdouble ysep = dy1p + lambda*dy21;
+ return sqrt(xsep*xsep + ysep*ysep);
+}
diff --git a/src/gettext.h b/src/gettext.h
new file mode 100644
index 0000000..8874d9b
--- /dev/null
+++ b/src/gettext.h
@@ -0,0 +1,265 @@
+/* Convenience header for conditional use of GNU <libintl.h>.
+ Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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. */
+
+#ifndef _LIBGETTEXT_H
+#define _LIBGETTEXT_H 1
+
+/* NLS can be disabled through the configure --disable-nls option. */
+#if ENABLE_NLS
+
+/* Get declarations of GNU message catalog functions. */
+# include <libintl.h>
+
+/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
+ the gettext() and ngettext() macros. This is an alternative to calling
+ textdomain(), and is useful for libraries. */
+# ifdef DEFAULT_TEXT_DOMAIN
+# undef gettext
+# define gettext(Msgid) \
+ dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
+# undef ngettext
+# define ngettext(Msgid1, Msgid2, N) \
+ dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
+# endif
+
+#else
+
+/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
+ chokes if dcgettext is defined as a macro. So include it now, to make
+ later inclusions of <locale.h> a NOP. We don't include <libintl.h>
+ as well because people using "gettext.h" will not include <libintl.h>,
+ and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
+ is OK. */
+#if defined(__sun)
+# include <locale.h>
+#endif
+
+/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
+ <libintl.h>, which chokes if dcgettext is defined as a macro. So include
+ it now, to make later inclusions of <libintl.h> a NOP. */
+#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
+# include <cstdlib>
+# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
+# include <libintl.h>
+# endif
+#endif
+
+/* Disabled NLS.
+ The casts to 'const char *' serve the purpose of producing warnings
+ for invalid uses of the value returned from these functions.
+ On pre-ANSI systems without 'const', the config.h file is supposed to
+ contain "#define const". */
+# define gettext(Msgid) ((const char *) (Msgid))
+# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
+# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
+# define ngettext(Msgid1, Msgid2, N) \
+ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
+# define dngettext(Domainname, Msgid1, Msgid2, N) \
+ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
+# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
+ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
+# define textdomain(Domainname) ((const char *) (Domainname))
+# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
+# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
+
+#endif
+
+/* A pseudo function call that serves as a marker for the automated
+ extraction of messages, but does not call gettext(). The run-time
+ translation is done at a different place in the code.
+ The argument, String, should be a literal string. Concatenated strings
+ and other string expressions won't work.
+ The macro's expansion is not parenthesized, so that it is suitable as
+ initializer for static 'char[]' or 'const char[]' variables. */
+#define gettext_noop(String) String
+
+/* The separator between msgctxt and msgid in a .mo file. */
+#define GETTEXT_CONTEXT_GLUE "\004"
+
+/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
+ MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
+ short and rarely need to change.
+ The letter 'p' stands for 'particular' or 'special'. */
+#ifdef DEFAULT_TEXT_DOMAIN
+# define pgettext(Msgctxt, Msgid) \
+ pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+#else
+# define pgettext(Msgctxt, Msgid) \
+ pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+#endif
+#define dpgettext(Domainname, Msgctxt, Msgid) \
+ pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
+ pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
+#ifdef DEFAULT_TEXT_DOMAIN
+# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
+ npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+#else
+# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
+ npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+#endif
+#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
+ npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
+ npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+pgettext_aux (const char *domain,
+ const char *msg_ctxt_id, const char *msgid,
+ int category)
+{
+ const char *translation = dcgettext (domain, msg_ctxt_id, category);
+ if (translation == msg_ctxt_id)
+ return msgid;
+ else
+ return translation;
+}
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+npgettext_aux (const char *domain,
+ const char *msg_ctxt_id, const char *msgid,
+ const char *msgid_plural, unsigned long int n,
+ int category)
+{
+ const char *translation =
+ dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
+ if (translation == msg_ctxt_id || translation == msgid_plural)
+ return (n == 1 ? msgid : msgid_plural);
+ else
+ return translation;
+}
+
+/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
+ can be arbitrary expressions. But for string literals these macros are
+ less efficient than those above. */
+
+#include <string.h>
+
+#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
+ (__GNUC__ >= 3 || __GNUG__ >= 2 /* || __STDC_VERSION__ >= 199901L */ )
+
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+#include <stdlib.h>
+#endif
+
+#define pgettext_expr(Msgctxt, Msgid) \
+ dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
+#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
+ dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+dcpgettext_expr (const char *domain,
+ const char *msgctxt, const char *msgid,
+ int category)
+{
+ size_t msgctxt_len = strlen (msgctxt) + 1;
+ size_t msgid_len = strlen (msgid) + 1;
+ const char *translation;
+#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+ char msg_ctxt_id[msgctxt_len + msgid_len];
+#else
+ char buf[1024];
+ char *msg_ctxt_id =
+ (msgctxt_len + msgid_len <= sizeof (buf)
+ ? buf
+ : (char *) malloc (msgctxt_len + msgid_len));
+ if (msg_ctxt_id != NULL)
+#endif
+ {
+ memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
+ msg_ctxt_id[msgctxt_len - 1] = '\004';
+ memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
+ translation = dcgettext (domain, msg_ctxt_id, category);
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+ if (msg_ctxt_id != buf)
+ free (msg_ctxt_id);
+#endif
+ if (translation != msg_ctxt_id)
+ return translation;
+ }
+ return msgid;
+}
+
+#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
+ dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
+#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
+ dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+dcnpgettext_expr (const char *domain,
+ const char *msgctxt, const char *msgid,
+ const char *msgid_plural, unsigned long int n,
+ int category)
+{
+ size_t msgctxt_len = strlen (msgctxt) + 1;
+ size_t msgid_len = strlen (msgid) + 1;
+ const char *translation;
+#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+ char msg_ctxt_id[msgctxt_len + msgid_len];
+#else
+ char buf[1024];
+ char *msg_ctxt_id =
+ (msgctxt_len + msgid_len <= sizeof (buf)
+ ? buf
+ : (char *) malloc (msgctxt_len + msgid_len));
+ if (msg_ctxt_id != NULL)
+#endif
+ {
+ memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
+ msg_ctxt_id[msgctxt_len - 1] = '\004';
+ memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
+ translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+ if (msg_ctxt_id != buf)
+ free (msg_ctxt_id);
+#endif
+ if (!(translation == msg_ctxt_id || translation == msgid_plural))
+ return translation;
+ }
+ return (n == 1 ? msgid : msgid_plural);
+}
+
+#endif /* _LIBGETTEXT_H */
diff --git a/src/gps_handler.c b/src/gps_handler.c
new file mode 100644
index 0000000..475146d
--- /dev/null
+++ b/src/gps_handler.c
@@ -0,0 +1,994 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+#include "../config.h"
+
+#include "config.h"
+#include "gettext.h"
+#include "gpsdrive.h"
+#include "icons.h"
+#include "gps_handler.h"
+#include "nmea_handler.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <math.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <dlfcn.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+#include "gpsdrive_config.h"
+#include "gui.h"
+
+#include "gettext.h"
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+#ifdef DBUS_ENABLE
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus-glib.h>
+static DBusHandlerResult dbus_signal_handler (
+ DBusConnection* connection, DBusMessage* message);
+static DBusHandlerResult dbus_handle_gps_fix (DBusMessage* message);
+#endif
+
+extern gint mydebug;
+gint gps_handler_debug = 0;
+
+
+extern gint maploaded;
+extern gint isnight, disableisnight;
+
+extern gchar utctime[20], loctime[20];
+extern gint forcehavepos;
+extern gint havepos, haveposcount;
+extern gint blink, gblink, xoff, yoff;
+extern gint zone;
+extern gint oldsatfix, oldsatsanz;
+extern gdouble precision, gsaprecision;
+extern gchar localedecimal;
+extern gdouble gbreit, glang, milesconv, olddist;
+extern gchar mapfilename[1024];
+extern gdouble posx, posy;
+extern gint satlist[MAXSATS][4], satlistdisp[MAXSATS][4], satbit;
+extern gint newsatslevel;
+extern gint satfix, usedgps;
+extern gint sats_used, sats_in_view;
+extern gchar *buffer, *big;
+extern fd_set readmask;
+extern struct timeval timeout;
+extern gdouble earthr;
+extern GTimer *timer, *disttimer;
+extern int newdata;
+extern pthread_mutex_t mutex;
+extern int didrootcheck;
+extern gint timeoutcount;
+extern gint simpos_timeout;
+extern int timerto;
+extern GtkWidget *drawing_gps;
+extern GtkWidget *satslabel1, *satslabel2, *satslabel3;
+extern GdkPixbuf *satsimage;
+extern gchar dgpsserver[80], dgpsport[10];
+extern gchar gpsdservername[200];
+extern GtkWidget *frame_statusbar;
+extern GtkWidget *pixmapwidget, *gotowindow;
+extern gint statuslock, gpson;
+extern gint earthmate;
+extern coordinate_struct coords;
+extern currentstatus_struct current;
+
+// ---------------------- NMEA
+extern gint haveRMCsentence;
+extern gdouble NMEAsecs;
+extern gint NMEAoldsecs;
+extern FILE *nmeaout;
+/* if we get data from gpsd in NMEA format haveNMEA is TRUE */
+extern gchar nmeamodeandport[50];
+extern gint haveNMEA;
+
+#ifdef DBUS_ENABLE
+gint useDBUS;
+DBusError dbuserror;
+DBusConnection* connection;
+struct dbus_gps_fix {
+ gdouble time; /* Time as time_t with optional fractional seconds */
+ gint32 mode; /* Fix type
+ * 0 = Not seen. 1 = No fix. 2/3 = 2D/3D fix
+ * We use -1 to identify that the current fix
+ * is * already processed */
+ gdouble ept; /* Expected time uncertainty */
+ gdouble latitude; /* Latitude in degrees (valid if mode >= 2) */
+ gdouble longitude; /* Longitude in degrees (valid if mode >= 2) */
+ gdouble eph; /* Horizontal position uncertainty, meters */
+ gdouble altitude; /* Altitude in meters (valid if mode == 3) */
+ gdouble epv; /* Vertical position uncertainty, meters */
+ gdouble track; /* Course made good (relative to true north) */
+ gdouble epd; /* Track uncertainty, degrees */
+ gdouble speed; /* Speed over ground, meters/sec */
+ gdouble eps; /* Speed uncertainty, meters/sec */
+ gdouble climb; /* Vertical speed, meters/sec */
+ gdouble epc; /* Vertical speed uncertainty */
+};
+struct dbus_gps_fix dbus_old_fix, dbus_current_fix;
+#ifndef NAN
+#define NAN (0.0/0.0)
+#endif
+#endif
+int nmeaverbose = 0;
+gint bigp = 0, bigpGGA = 0, bigpRME = 0, bigpGSA = 0, bigpGSV = 0;
+gint lastp = 0, lastpGGA = 0, lastpRME = 0, lastpGSA = 0, lastpGSV = 0;
+gint sock = -1;
+
+gint convertGSV (char *f);
+
+
+/* *****************************************************************************
+ */
+void
+gpsd_close ()
+{
+ if (sock != -1)
+ close (sock);
+}
+
+/* *****************************************************************************
+ */
+#ifdef DBUS_ENABLE
+void
+init_dbus_current_fix()
+{
+ // Preserve the time
+ dbus_current_fix.mode = 0;
+ dbus_current_fix.ept = NAN;
+ dbus_current_fix.latitude = NAN;
+ dbus_current_fix.longitude = NAN;
+ dbus_current_fix.eph = NAN;
+ dbus_current_fix.altitude = NAN;
+ dbus_current_fix.epv = NAN;
+ dbus_current_fix.track = NAN;
+ dbus_current_fix.epd = NAN;
+ dbus_current_fix.speed = NAN;
+ dbus_current_fix.eps = NAN;
+ dbus_current_fix.climb = NAN;
+ dbus_current_fix.epc = NAN;
+}
+
+void init_dbus(){
+ haveNMEA = TRUE;
+
+ memset(&dbus_old_fix, 0, sizeof(struct dbus_gps_fix));
+ init_dbus_current_fix();
+ dbus_current_fix.time = 0.0; // Time is not set in init_dbus_current_time
+
+ dbus_error_init (&dbuserror);
+
+ connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbuserror);
+ if (dbus_error_is_set (&dbuserror)) {
+ g_print ("%s: %s", dbuserror.name, dbuserror.message);
+ exit(0);
+ }
+
+ dbus_bus_add_match (connection, "type='signal'", &dbuserror);
+ if (dbus_error_is_set (&dbuserror)) {
+ g_print (_("unable to add match for signals %s: %s"), dbuserror.name, dbuserror.message);
+ exit(0);
+ }
+
+ if (!dbus_connection_add_filter (connection, (DBusHandleMessageFunction)dbus_signal_handler, NULL, NULL)) {
+ g_print (_("unable to register filter with the connection"));
+ exit(0);
+ }
+
+ g_strlcpy (nmeamodeandport,
+ _("DBUS Mode"), sizeof (nmeamodeandport));
+ dbus_connection_setup_with_g_main (connection, NULL);
+}
+
+#endif
+
+/* ******************************************************************
+ * Initialize nmea socket to
+ * look if we have an open socket "sock" and close it
+ * the try to reconnect to gpsd
+ * If we're successfull we set
+ * nmeamodeandport = "Sting with description of connection"
+ * sock = the open socket
+ * if we're not successfull we set
+ * simmode = TRUE
+ * haveNMEA = FALSE
+ */
+void
+init_nmea_socket ()
+{
+ struct sockaddr_in server;
+ struct hostent *server_data;
+ {
+ /* open socket to port */
+ if (sock != -1)
+ {
+ close (sock);
+ sock = -1;
+ }
+ sock = socket (AF_INET, SOCK_STREAM, 0);
+ if (sock < 0)
+ {
+ perror (_("can't open socket for port "));
+ fprintf (stderr, "error: %d\n", errno);
+ if (local_config.simmode == SIM_AUTO)
+ current.simmode = TRUE;
+ haveNMEA = FALSE;
+ newsatslevel = TRUE;
+ if (simpos_timeout == 0)
+ simpos_timeout =
+ gtk_timeout_add (300, (GtkFunction) simulated_pos, 0);
+ memset (satlist, 0, sizeof (satlist));
+ memset (satlistdisp, 0, sizeof (satlist));
+ sats_used = sats_in_view = 0;
+ if (satsimage != NULL)
+ g_object_unref (satsimage);
+ satsimage = NULL;
+ return;
+ }
+ server.sin_family = AF_INET;
+ /* We retrieve the IP address of the server from its name: */
+ if ((server_data = gethostbyname (SERVERNAME)) == NULL)
+ {
+ fprintf (stderr,
+ _("\nCannot connect to %s: unknown host\n"), SERVERNAME);
+ exit (1);
+ }
+ memcpy (&server.sin_addr, server_data->h_addr, server_data->h_length);
+ server.sin_port = htons (SERVERPORT2);
+
+ /* We initiate the connection */
+ if (connect (sock, (struct sockaddr *) &server, sizeof server) < 0)
+ {
+ server.sin_port = htons (SERVERPORT); /* We try second port */
+ /* We initiate the connection */
+ if (connect (sock, (struct sockaddr *) &server, sizeof server) < 0)
+ {
+ haveNMEA = FALSE;
+ if (local_config.simmode == SIM_AUTO)
+ current.simmode = TRUE;
+ }
+ else
+ {
+ timeoutcount = 0;
+ haveNMEA = TRUE;
+ if (local_config.simmode == SIM_AUTO)
+ current.simmode = FALSE;
+ g_strlcpy (nmeamodeandport,
+ _("NMEA Mode, Port 2222"), sizeof (nmeamodeandport));
+ g_strlcat (nmeamodeandport, "/", sizeof (nmeamodeandport));
+ g_strlcat (nmeamodeandport, gpsdservername,
+ sizeof (nmeamodeandport));
+ }
+ }
+ else
+ {
+ g_strlcpy (nmeamodeandport, _("NMEA Mode, Port 2947"),
+ sizeof (nmeamodeandport));
+ g_strlcat (nmeamodeandport, "/", sizeof (nmeamodeandport));
+ g_strlcat (nmeamodeandport, gpsdservername, sizeof (nmeamodeandport));
+ write (sock, "R\n", 2);
+ timeoutcount = 0;
+ haveNMEA = TRUE;
+ if (local_config.simmode == SIM_AUTO)
+ current.simmode = FALSE;
+ }
+ }
+}
+
+
+/* ******************************************************************
+ */
+gint
+initgps ()
+{
+
+#ifdef DBUS_ENABLE
+ if (useDBUS) {
+ init_dbus();
+ } else
+#endif
+
+ init_nmea_socket ();
+ /* We test for gpsd serving */
+
+ if (haveNMEA)
+ {
+ if (local_config.simmode == SIM_AUTO)
+ current.simmode = FALSE;
+ if (simpos_timeout != 0)
+ {
+ gtk_timeout_remove (simpos_timeout);
+ simpos_timeout = 0;
+ }
+ }
+
+ return FALSE; /* to remove timer */
+}
+
+
+/* *****************************************************************************
+ */
+#ifdef DBUS_ENABLE
+static DBusHandlerResult dbus_signal_handler (
+ DBusConnection* connection, DBusMessage* message) {
+ /* dummy, need to use the variable for some reason */
+ connection = NULL;
+
+ if (dbus_message_is_signal (message, "org.gpsd", "fix"))
+ return dbus_handle_gps_fix (message);
+ /*
+ * ignore all other messages
+ */
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+void
+dbus_process_fix(gint early)
+{
+ struct tm time;
+ time_t ttime;
+
+ if (!early && (dbus_current_fix.mode==-1)) {
+ /* We have handled this one, so clean the mode and bail out */
+ dbus_current_fix.mode = 0;
+ return;
+ }
+
+ /*
+ * Handle the data
+ */
+ /* Set utctime */
+ ttime = dbus_current_fix.time;
+ gmtime_r (&ttime, &time);
+ g_snprintf (utctime, sizeof (utctime), "%02d:%02d.%02d ", time.tm_hour, time.tm_min, time.tm_sec);
+ g_snprintf (loctime, sizeof (loctime), "%02d:%02d ", (time.tm_hour+zone+24)%24, time.tm_min);
+ NMEAsecs = dbus_current_fix.time; // Use this value to judge timeout
+ /* Bail out if we have no fix */
+ current.gpsfix = 0; // Handled later.
+ if (dbus_current_fix.mode>1) {
+ current.gpsfix = dbus_current_fix.mode;
+ haveRMCsentence = TRUE;
+ satfix = 1;
+ haveposcount++;
+ if (haveposcount == 3)
+ rebuildtracklist();
+ } else {
+ current.gpsfix = 1;
+ haveRMCsentence = FALSE;
+ satfix = 0;
+ haveposcount = 0;
+ dbus_old_fix = dbus_current_fix;
+ init_dbus_current_fix();
+ if (early)
+ dbus_current_fix.mode = -1;
+ storepoint();
+ return;
+ }
+ /* Handle latitude */
+ if (!gui_status.posmode && !current.simmode)
+ coords.current_lat = dbus_current_fix.latitude;
+ /* Handle longitude */
+ if (!gui_status.posmode && !current.simmode)
+ coords.current_lon = dbus_current_fix.longitude;
+ /* Handle speed */
+ if (__finite(dbus_current_fix.speed))
+ groundspeed = dbus_current_fix.speed * 3.6; // Convert m/s to km/h
+ else if (dbus_old_fix.mode>1) {
+ gdouble timediff = dbus_current_fix.time-dbus_old_fix.time;
+ groundspeed = (timediff>0)?(calcdist2(dbus_old_fix.longitude, dbus_old_fix.latitude) * 3600 / timediff) : 0.0;
+ }
+ /* Handle bearing */
+ if (__finite(dbus_current_fix.track))
+ direction = dbus_current_fix.track * M_PI / 180; // Convert to radians
+ else if (dbus_old_fix.mode>1) {
+ gdouble lon2 = coords.current_lon * M_PI / 180;
+ gdouble lon1 = dbus_old_fix.longitude * M_PI / 180;
+ gdouble lat2 = coords.current_lat * M_PI /180;
+ gdouble lat1 = dbus_old_fix.latitude * M_PI / 180;
+ if ((lat1 != lat2) || (lon1 != lon2))
+ direction = atan2(sin(lon2-lon1)*cos(lat2),
+ cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon2-lon1));
+ }
+ if ( mydebug + gps_handler_debug > 80 )
+ g_print("gps_handler: DBUS fix: %6.0f %10.6f/%10.6f sp:%5.2f(%5.2f) crs:%5.1f(%5.2f)\n", dbus_current_fix.time,
+ dbus_current_fix.latitude, dbus_current_fix.longitude, dbus_current_fix.speed, groundspeed,
+ dbus_current_fix.track, direction * 180 / M_PI);
+ /* Handle altitude */
+ if (dbus_current_fix.mode>2) {
+ current.gpsfix = 3;
+ current.altitude = dbus_current_fix.altitude;
+ }
+ /* Handle positional error */
+ precision = dbus_current_fix.eph;
+
+ dbus_old_fix = dbus_current_fix;
+ init_dbus_current_fix();
+ if (early)
+ dbus_current_fix.mode = -1;
+ storepoint();
+}
+
+static DBusHandlerResult dbus_handle_gps_fix (DBusMessage* message) {
+ DBusMessageIter iter;
+ //double temp_time;
+ //char b[100];
+ struct dbus_gps_fix fix;
+ //gint32 mode;
+ //gdouble dump;
+
+ if (!dbus_message_iter_init (message, &iter)) {
+ /* we have a problem */
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+ /* Fill the fix struct */
+ fix.time = floor(dbus_message_iter_get_double (&iter));
+ dbus_message_iter_next (&iter);
+ fix.mode = dbus_message_iter_get_int32 (&iter);
+ dbus_message_iter_next (&iter);
+ fix.ept = dbus_message_iter_get_double (&iter);
+ dbus_message_iter_next (&iter);
+ fix.latitude = dbus_message_iter_get_double (&iter);
+ dbus_message_iter_next (&iter);
+ fix.longitude = dbus_message_iter_get_double (&iter);
+ dbus_message_iter_next (&iter);
+ fix.eph = dbus_message_iter_get_double (&iter);
+ dbus_message_iter_next (&iter);
+ fix.altitude = dbus_message_iter_get_double (&iter);
+ dbus_message_iter_next (&iter);
+ fix.epv = dbus_message_iter_get_double (&iter);
+ dbus_message_iter_next (&iter);
+ fix.track = dbus_message_iter_get_double (&iter);
+ dbus_message_iter_next (&iter);
+ fix.epd = dbus_message_iter_get_double (&iter);
+ dbus_message_iter_next (&iter);
+ fix.speed = dbus_message_iter_get_double (&iter);
+ dbus_message_iter_next (&iter);
+ fix.eps = dbus_message_iter_get_double (&iter);
+ dbus_message_iter_next (&iter);
+ fix.climb = dbus_message_iter_get_double (&iter);
+ dbus_message_iter_next (&iter);
+ fix.epc = dbus_message_iter_get_double (&iter);
+
+ if ( mydebug + gps_handler_debug > 80 ) {
+ g_print("gps_handler: DBUS raw: ti:%6.0f mode:%d ept:%f %10.6f/%10.6f eph:%f\n", fix.time, fix.mode, fix.ept, fix.latitude, fix.longitude, fix.eph);
+ g_print(" alt:%6.2f epv:%f crs:%5.1f edp:%f sp:%5.2f eps:%f cl:%f epc:%f\n", fix.altitude, fix.epv, fix.track, fix.epd, fix.speed, fix.eps, fix.climb, fix.epc);
+ }
+
+ /* Unfortunately gpsd dbus data is sometimes split over several messages */
+ /* so we have to accumulate them... */
+
+ if (fix.time!=dbus_current_fix.time)
+ dbus_process_fix(FALSE);
+ // if mode is -1 we already processed it, so bail out
+ if (dbus_current_fix.mode==-1)
+ return DBUS_HANDLER_RESULT_HANDLED;
+ dbus_current_fix.time = fix.time;
+ if (__finite(fix.latitude))
+ if (__isnan(dbus_current_fix.latitude) || (fix.mode>dbus_current_fix.mode))
+ dbus_current_fix.latitude = fix.latitude;
+ if (__finite(fix.longitude))
+ if (__isnan(dbus_current_fix.longitude) || (fix.mode>dbus_current_fix.mode))
+ dbus_current_fix.longitude = fix.longitude;
+ if (__finite(fix.eph))
+ if (__isnan(dbus_current_fix.eph) || (fix.mode>dbus_current_fix.mode))
+ dbus_current_fix.eph = fix.eph;
+ if (__finite(fix.altitude))
+ if (__isnan(dbus_current_fix.altitude) || (fix.mode>dbus_current_fix.mode))
+ dbus_current_fix.altitude = fix.altitude;
+ if (__finite(fix.track))
+ if (__isnan(dbus_current_fix.track) || (fix.mode>dbus_current_fix.mode))
+ dbus_current_fix.track = fix.track;
+ if (__finite(fix.speed))
+ if (__isnan(dbus_current_fix.speed) || (fix.mode>dbus_current_fix.mode))
+ dbus_current_fix.speed = fix.speed;
+ if (fix.mode>dbus_current_fix.mode)
+ dbus_current_fix.mode = fix.mode;
+
+ /* Do an early process if we have all important data to prevent lag. */
+ /* We do not consider positional error and altitude important for gpsdrive =) */
+ /* To soothe everybody, usually a valid altitude comes with the fix */
+ if ((dbus_current_fix.mode>1) && __finite(dbus_current_fix.latitude) && __finite(dbus_current_fix.longitude)
+ && __finite(dbus_current_fix.track) && __finite(dbus_current_fix.speed))
+ dbus_process_fix(TRUE);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+#endif
+
+gint
+get_position_data_cb (GtkWidget * widget, guint * datum)
+{
+ gint e = 0, j = 0, i = 0, found = 0, foundGSV = 0, foundGGA =
+ 0, foundGSA = 0, foundRME = 0;
+ gdouble secs = 0, tx, ty, lastdirection;
+ typedef struct
+ {
+ gchar *a1;
+ gchar *a2;
+ gchar *a3;
+ }
+ argument;
+ argument *argumente;
+ char tok[1000];
+ int tilimit;
+
+ if (current.importactive)
+ return TRUE;
+
+
+ if ((timeoutcount > 30 - mydebug - gps_handler_debug))
+ g_print ("*** %d. timeout getting data from GPS-Receiver!\n",
+ timeoutcount);
+
+ tilimit = 10;
+
+ if (timeoutcount > tilimit) initgps();
+
+ if (timeoutcount > tilimit)
+ {
+ gtk_statusbar_pop (GTK_STATUSBAR (frame_statusbar), current.statusbar_id);
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar), current.statusbar_id,
+ _("Timeout getting data from GPS-Receiver!"));
+ current.gpsfix = 0;
+ haveposcount = 0;
+ memset (satlist, 0, sizeof (satlist));
+ memset (satlistdisp, 0, sizeof (satlist));
+ }
+
+
+ argumente = NULL;
+ if (!haveRMCsentence)
+ {
+ secs = NMEAsecs;
+
+ if (secs >= 1.0)
+ {
+ tx = (2 * earthr * M_PI / 360) * cos (M_PI * coords.current_lat /
+ 180.0) *
+ (coords.current_lon - coords.old_lon);
+ ty = (2 * earthr * M_PI / 360) * (coords.current_lat - coords.old_lat);
+#define MINMOVE 4.0
+ if (((fabs (tx)) > MINMOVE) || (((fabs (ty)) > MINMOVE)))
+ {
+ lastdirection = current.heading;
+ if (ty == 0)
+ current.heading = 0.0;
+ else
+ current.heading = atan (tx / ty);
+ if (!finite (current.heading))
+ current.heading = lastdirection;
+ if (ty < 0)
+ current.heading = M_PI + current.heading;
+ if (current.heading >= (2 * M_PI))
+ current.heading -= 2 * M_PI;
+ if (current.heading < 0)
+ current.heading += 2 * M_PI;
+
+ current.groundspeed = milesconv * sqrt (tx * tx + ty * ty) * 3.6 / secs;
+ coords.old_lat = coords.current_lat;
+ coords.old_lon = coords.current_lon;
+ }
+ else if (secs > 4.0)
+ current.groundspeed = 0.0;
+
+ if (current.groundspeed > 2000)
+ current.groundspeed = 0;
+ if (current.groundspeed < 3.6)
+ current.groundspeed = 0;
+
+ if ( mydebug + gps_handler_debug > 80 )
+ g_print ("gps_handler: Time: %f\n", secs);
+ }
+
+ /* display status line */
+ if (gui_status.posmode)
+ display_status (_("Press middle mouse button for navigation"));
+
+ }
+
+ /* only if we have no NMEA, means no measured position */
+ if (!haveNMEA)
+ {
+ /* display status line */
+ if (!current.simmode)
+ display_status (_("No GPS used"));
+ else if (maploaded && !gui_status.posmode)
+ display_status (_("Simulation mode"));
+ else if (gui_status.posmode)
+ display_status (_("Press middle mouse button for sim mode"));
+
+
+ return TRUE;
+ }
+
+#ifdef DBUS_ENABLE
+ if (useDBUS) {
+ if (NMEAoldsecs == floor(NMEAsecs)) {
+ timeoutcount++;
+ return TRUE;
+ }
+ NMEAoldsecs = floor(NMEAsecs);
+ timeoutcount = 0;
+ if (current.gpsfix > 1) {
+ if (gui_status.posmode)
+ display_status (_("Press middle mouse button for navigation"));
+ else
+ display_status (nmeamodeandport);
+ } else
+ display_status(_("Not enough satellites in view!"));
+ } else {
+#endif
+ /* this is the NMEA reading part. data comes from port 2222 served by gpsd */
+ FD_ZERO (&readmask);
+ FD_SET (sock, &readmask);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 100000;
+ if (select (FD_SETSIZE, &readmask, NULL, NULL, &timeout) < 0)
+ {
+ timeoutcount++;
+ perror ("select() call");
+ }
+ if (FD_ISSET (sock, &readmask))
+ {
+ if ((e = read (sock, buffer, 2000)) <= 0) {
+ perror ("read from gpsd connection");
+ timeoutcount ++;
+ }
+ buffer[e] = 0;
+ if ((bigp + e) < MAXBIG)
+ {
+ if (mydebug + gps_handler_debug>30)
+ g_print ("gps_handler: gpsd: !!bigp:%d, e: %d!! , strlen big:%Zu\n"
+ , bigp, e, strlen (big));
+ g_strlcat (big, buffer, MAXBIG);
+ bigp += e;
+ bigpGSA = bigpRME = bigpGSV = bigpGGA = bigp;
+
+ for (i = bigp; i > lastp; i--)
+ {
+ if (big[i] == '$')
+ {
+ /* collect string for position data $GPRMC */
+ if ((big[i + 3] == 'R')
+ && (big[i + 4] == 'M') && (big[i + 5] == 'C'))
+ {
+ found = 0;
+ if ( mydebug + gps_handler_debug > 80 )
+ g_print ("gps_handler: gpsd: found #RMC#\n");
+ for (j = i; j <= bigp; j++)
+ if (big[j] == 13)
+ {
+ found = j;
+ break;
+ }
+ if (found != 0)
+ {
+ strncpy (tok, (big + i), found - i);
+ tok[found - i] = 0;
+ lastp = found;
+ timeoutcount = 0;
+
+ /* we have the $GPRMC string completed, now parse it */
+ if (checksum (tok) == TRUE)
+ convertRMC (tok);
+
+ /* display the position and map in the statusline */
+ if (current.gpsfix > 1)
+ {
+ if (gui_status.posmode)
+ display_status
+ (_
+ ("Press middle mouse button for navigation"));
+ else
+ display_status (nmeamodeandport);
+ }
+ else
+ display_status
+ (_("Not enough satellites in view!"));
+ }
+ }
+ }
+ }
+
+ /* collect string for satellite data $GPGSV */
+ for (i = bigpGSV; i > lastpGSV; i--)
+ {
+ if (big[i] == '$')
+ {
+
+ if ((big[i + 3] == 'G')
+ && (big[i + 4] == 'S') && (big[i + 5] == 'V'))
+ {
+ foundGSV = 0;
+ if ( mydebug + gps_handler_debug > 80 )
+ g_print ("gpsd: found #GSV#, bigpGSV: %d\n", bigpGSV);
+ for (j = i; j <= bigpGSV; j++)
+ if (big[j] == 13)
+ {
+ foundGSV = j;
+ break;
+ }
+ if (foundGSV != 0)
+ {
+ gint lenstr;
+ lenstr = foundGSV - i;
+ if ((lenstr) > 200)
+ {
+ g_print
+ ("Error in line %d, found GSV=%d,i=%d, diff=%d\n",
+ __LINE__, foundGSV, i, lenstr);
+ lenstr = 200;
+ }
+ if (i > foundGSV)
+ {
+ g_print
+ ("Error in line %d, found GSV=%d,i=%d, diff=%d\n",
+ __LINE__, foundGSV, i, lenstr);
+ lenstr = 0;
+ }
+ if (lenstr < 0)
+ {
+ g_print
+ ("Error in line %d, foundGSV=%d,i=%d, lenstr=%d\n",
+ __LINE__, foundGSV, i, lenstr);
+ lenstr = 0;
+ }
+ if (lenstr != 0)
+ {
+ strncpy (tok, (big + i), lenstr);
+ tok[lenstr] = 0;
+
+ if (checksum (tok) == TRUE)
+ {
+ if ((convertGSV (tok)) == TRUE)
+ lastpGSV = foundGSV;
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ /* collect string for altitude from $GPGGA if available */
+ for (i = bigpGGA; i > lastpGGA; i--)
+ {
+ if (big[i] == '$')
+ {
+
+ if ((big[i + 3] == 'G')
+ && (big[i + 4] == 'G') && (big[i + 5] == 'A'))
+ {
+ foundGGA = 0;
+ if ( mydebug + gps_handler_debug > 80 )
+ g_print ("gps_handler: gpsd: found #GGA#\n");
+ timeoutcount = 0;
+
+ for (j = i; j <= bigpGGA; j++)
+ if (big[j] == 13)
+ {
+ foundGGA = j;
+ break;
+ }
+ if (foundGGA != 0)
+ {
+ gint lenstr;
+ lenstr = foundGGA - i;
+ if ((lenstr) > 200)
+ {
+ g_print
+ ("Error in line %d, foundGGA=%d,i=%d, diff=%d\n",
+ __LINE__, foundGGA, i, lenstr);
+ lenstr = 200;
+ }
+ if (i > foundGGA)
+ {
+ g_print
+ ("Error in line %d, foundGGA=%d,i=%d, diff=%d\n",
+ __LINE__, foundGGA, i, lenstr);
+ lenstr = 0;
+ }
+ if (lenstr != 0)
+ {
+ strncpy (tok, (big + i), lenstr);
+ tok[lenstr] = 0;
+ lastpGGA = foundGGA;
+
+ if (checksum (tok) == TRUE)
+ convertGGA (tok);
+ if (current.gpsfix > 1)
+ {
+ if (gui_status.posmode)
+ display_status
+ (_
+ ("Press middle mouse button for navigation"));
+ else
+ display_status (nmeamodeandport);
+ }
+ else
+ display_status
+ (_("Not enough satellites in view!"));
+
+ }
+ }
+ }
+ }
+ }
+
+ /* collect string for precision from $PGRME if available */
+ for (i = bigpRME; i > lastpRME; i--)
+ {
+ if (big[i] == '$')
+ {
+
+ if ((big[i + 1] == 'P')
+ && (big[i + 2] == 'G')
+ && (big[i + 3] == 'R')
+ && (big[i + 4] == 'M') && (big[i + 5] == 'E'))
+ {
+ foundRME = 0;
+ if ( mydebug + gps_handler_debug > 80 )
+ g_print ("gps_handler: gpsd: found #RME#\n");
+ for (j = i; j <= bigpRME; j++)
+ if (big[j] == 13)
+ {
+ foundRME = j;
+ break;
+ }
+ if (foundRME != 0)
+ {
+ gint lenstr;
+ lenstr = foundRME - i;
+ if ((lenstr) > 200)
+ {
+ g_print
+ ("Error in line %d, foundRME=%d,i=%d, diff=%d\n",
+ __LINE__, foundRME, i, lenstr);
+ lenstr = 200;
+ }
+ if (i > foundRME)
+ {
+ g_print
+ ("Error in line %d, foundRME=%d,i=%d, diff=%d\n",
+ __LINE__, foundRME, i, lenstr);
+ lenstr = 0;
+ }
+ if (lenstr != 0)
+ {
+ strncpy (tok, (big + i), lenstr);
+ tok[lenstr] = 0;
+ lastpRME = foundRME;
+
+ if (checksum (tok) == TRUE)
+ convertRME (tok);
+ }
+ }
+ }
+ }
+ }
+
+ /* collect string for precision from $GPGSA if available */
+ for (i = bigpGSA; i > lastpGSA; i--)
+ {
+ if (big[i] == '$')
+ {
+
+ if ((big[i + 1] == 'G')
+ && (big[i + 2] == 'P')
+ && (big[i + 3] == 'G')
+ && (big[i + 4] == 'S') && (big[i + 5] == 'A'))
+ {
+ foundGSA = 0;
+ if ( mydebug + gps_handler_debug > 80 )
+ g_print ("gps_handler: gpsd: found #GSA#\n");
+ for (j = i; j <= bigpGSA; j++)
+ if (big[j] == 13)
+ {
+ foundGSA = j;
+ break;
+ }
+ if (foundGSA != 0)
+ {
+ gint lenstr;
+ lenstr = foundGSA - i;
+ if ((lenstr) > 200)
+ {
+ g_print
+ ("Error in line %d, foundGSA=%d,i=%d, diff=%d\n",
+ __LINE__, foundGSA, i, lenstr);
+ lenstr = 200;
+ }
+ if (i > foundGSA)
+ {
+ g_print
+ ("Error in line %d, foundGSA=%d,i=%d, diff=%d\n",
+ __LINE__, foundGSA, i, lenstr);
+ lenstr = 0;
+ }
+ if (lenstr != 0)
+ {
+ strncpy (tok, (big + i), lenstr);
+ tok[lenstr] = 0;
+ lastpGSA = foundGSA;
+
+ if (checksum (tok) == TRUE)
+ convertGSA (tok);
+ }
+ }
+ }
+ }
+ }
+
+
+
+ if ( mydebug + gps_handler_debug > 80 )
+ {
+ g_print ("gps_handler: gpsd: size:%d lastp: %d \n", e, lastp);
+ g_print ("gps_handler: gpsd: buffer: %s\n", buffer);
+ }
+
+ }
+ else
+ {
+ lastp = lastpGGA = lastpGSV = lastpRME = lastpGSA = 0;
+ bigp = e;
+ g_strlcpy (big, buffer, MAXBIG);
+ }
+
+ }
+ else
+ {
+ timeoutcount++;
+ }
+#ifdef DBUS_ENABLE
+ }
+#endif
+
+
+ return (TRUE);
+}
diff --git a/src/gps_handler.h b/src/gps_handler.h
new file mode 100644
index 0000000..e21e91a
--- /dev/null
+++ b/src/gps_handler.h
@@ -0,0 +1,62 @@
+/***********************************************************************
+
+Copyright (c) 2001,2002 Fritz Ganter <ganter@ganter.at>
+
+Website: www.kraftvoll.at/software
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+/*
+$Log$
+Revision 1.5 2006/08/08 08:19:32 tweety
+rename callback startgpsd_cb
+
+Revision 1.4 2006/02/05 16:38:05 tweety
+reading floats with scanf looks at the locale LANG=
+so if you have a locale de_DE set reading way.txt results in clearing the
+digits after the '.'
+For now I set the LC_NUMERIC always to en_US, since there we have . defined for numbers
+
+Revision 1.3 1994/06/10 02:11:00 tweety
+move nmea handling to it's own file Part 1
+
+Revision 1.2 2005/10/10 13:17:52 tweety
+DBUS Support for connecting to gpsd
+you need to use ./configure --enable-dbus to enable it during compile
+Author: "Belgabor" <belgabor@gmx.de>
+
+Revision 1.1 2005/08/13 10:16:02 tweety
+extract all/some gps_handling parts to File src/gps_handler.c
+
+
+*/
+
+
+#ifndef GPS_HANDLER_H
+#define GPS_HANDLER_H
+
+
+#include <gtk/gtk.h>
+
+gint initgps ();
+void gpsd_close();
+
+int garblemain (int argc, char **argv);
+
+
+#endif /* GPS_HANDLER_H */
diff --git a/src/gpsdrive-nosql.spec b/src/gpsdrive-nosql.spec
new file mode 100644
index 0000000..f26e3bd
--- /dev/null
+++ b/src/gpsdrive-nosql.spec
@@ -0,0 +1,46 @@
+#
+#
+#
+Summary: gpsdrive is a GPS based navigation tool
+Name: gpsdrive
+Version: 1.31
+Release: 1
+Copyright: GPL
+Group: Tools
+Source: %{name}-%{version}.tar.gz
+Vendor: Fritz Ganter <ganter@ganter.at>
+Packager: Fritz Ganter <ganter@ganter.at>
+BuildRoot: %{_builddir}/%{name}-root
+%define _prefix /usr
+%description
+Gpsdrive is a map-based navigation system. It displays your position on a zoomable map provided from a NMEA-capable GPS receiver. The maps are autoselected for the best resolution, depending of your position, and the displayed image can be zoomed. Maps can be downloaded from the Internet with one mouse click. The program provides information about speed, direction, bearing, arrival time, actual position, and target position. Speech output is also available.
+See http://gpsdrive.kraftvoll.at for new releases.
+%prep
+%setup
+CFLAGS="$RPM_OPT_FLAGS" ./configure --disable-mysql --prefix=%{_prefix} --mandir=%{_mandir}
+
+
+%build
+make
+%install
+rm -rf $RPM_BUILD_ROOT
+make DESTDIR=$RPM_BUILD_ROOT install-strip
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+rm -rf %{_builddir}/%{name}-%{version}
+%files
+%defattr (-,root,root)
+%doc GPS-receivers INSTALL AUTHORS COPYING TODO README LEEME LISEZMOI README.FreeBSD README.gpspoint2gspdrive FAQ.gpsdrive FAQ.gpsdrive.fr README.SQL create.sql NMEA.txt wp2sql README.kismet
+%doc %{_mandir}/de/man1/gpsdrive.1.gz
+%doc %{_mandir}/es/man1/gpsdrive.1.gz
+%doc %{_mandir}/man1/gpsdrive.1.gz
+
+%{_libdir}/*
+%{_bindir}/*
+
+%dir %{_prefix}/share/gpsdrive
+%{_prefix}/share/gpsdrive/gpsdrivesplash.png
+%{_prefix}/share/gpsdrive/friendsicon.png
+%{_prefix}/share/locale/*/LC_MESSAGES/*
+
diff --git a/src/gpsdrive.c b/src/gpsdrive.c
new file mode 100644
index 0000000..920192e
--- /dev/null
+++ b/src/gpsdrive.c
@@ -0,0 +1,3453 @@
+/***********************************************************************
+
+Copyright (c) 2001-2006 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+***********************************************************************/
+
+/* *****************************************************************************
+ Contributors:
+ <molter@gufi.org>.
+ <wulf@netbsd.org>
+ Aart Koelewijn <aart@mtack.xs4all.nl>
+ Belgabor <belgabor@gmx.de>
+ Blake Swadling <blake@swadling.com>
+ Christoph Metz <loom@mopper.de>
+ Chuck Gantz- chuck.gantz@globalstar.com
+ Dan Egnor <egnor@ofb.net>
+ Daniel Hiepler <rigid@akatash.de>
+ Darazs Attila <zumi@freestart.hu>
+ Fritz Ganter <ganter@ganter.at>
+ Guenther Meyer <d.s.e@sordidmusic.com>
+ J.D. Schmidt <jdsmobile@gmail.com>
+ Jan-Benedict Glaw <jbglaw@lug-owl.de>
+ Joerg Ostertag <gpsdrive@ostertag.name>
+ John Hay <jhay@icomtek.csir.co.za>
+ Johnny Cache <johnycsh@hick.org>
+ Miguel Angelo Rozsas <miguel@rozsas.xx.nom.br>
+ Mike Auty
+ Oddgeir Kvien <oddgeir@oddgeirkvien.com>
+ Oliver Kuehlert <Oliver.Kuehlert@mpi-hd.mpg.de>
+ Olli Salonen <olli@cabbala.net>
+ Philippe De Swert
+ Richard Scheffenegger <rscheff@chello.at>
+ Rob Stewart <rob@groupboard.com>
+ Russell Harding <hardingr@billingside.com>
+ Russell Mirov <russell.mirov@sun.com>
+ Wilfried Hemp <Wilfried.Hemp@t-online.de>
+ pdana@mail.utexas.edu
+ timecop@japan.co.jp
+*/
+
+/* Include Dateien */
+#include "../config.h"
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <signal.h>
+#include <termios.h>
+#include <unistd.h>
+#include <math.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <gpsdrive_config.h>
+/* #include <gpskismet.h> <-- prototypes are declared also in gpsproto.h */
+
+#include <dlfcn.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+
+#include <locale.h>
+
+#include "gettext.h"
+
+#include <dirent.h>
+
+#include <getopt.h>
+
+#include "LatLong-UTMconversion.h"
+#include "gpsdrive.h"
+#include "battery.h"
+#include "poi.h"
+#include "wlan.h"
+#include "track.h"
+#include "waypoint.h"
+#include "routes.h"
+#include "gps_handler.h"
+#include "nmea_handler.h"
+#include <speech_strings.h>
+#include <speech_out.h>
+
+#include "import_map.h"
+#include "download_map.h"
+#include "icons.h"
+#include "gui.h"
+#include "poi_gui.h"
+#include "main_gui.h"
+
+#include "mapnik.h"
+
+
+/* Defines for gettext I18n */
+#include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+
+#if GTK_MINOR_VERSION < 2
+#define gdk_draw_pixbuf _gdk_draw_pixbuf
+#endif
+
+
+
+/***************************************************************************/
+/***************************************************************************/
+/***************************************************************************/
+
+/* global variables */
+gint timeoutcount;
+GtkWidget *pixmapwidget, *gotowindow;
+GtkWidget *messagewindow;
+gint debug = 0;
+gint do_unit_test = FALSE;
+gchar *buffer = NULL, *big = NULL;
+struct timeval timeout;
+extern gdouble wp_saved_target_lat;
+extern gdouble wp_saved_target_lon;
+extern gdouble wp_saved_posmode_lat;
+extern gdouble wp_saved_posmode_lon;
+coordinate_struct coords;
+currentstatus_struct current;
+
+gdouble long_diff = 0, lat_diff = 0;
+GdkGC *kontext_map;
+
+extern GtkWidget *drawing_minimap;
+
+// TODO: should be moved away...
+extern GtkWidget *drawing_gps, *drawing_compass;
+extern GdkGC *kontext_compass, *kontext_gps, *kontext_minimap;
+extern GdkDrawable *drawable_compass, *drawable_gps, *drawable_minimap;
+
+GtkWidget *miles;
+GdkDrawable *drawable;
+gint haveposcount, blink, gblink, xoff, yoff, crosstoggle = 0;
+gdouble pixelfact, posx, posy;
+GdkPixbuf *image = NULL, *tempimage = NULL, *pixbuf_minimap = NULL;
+
+extern GdkPixbuf *friendsimage, *friendspixbuf;
+
+extern mapsstruct *maps;
+
+extern GtkWidget *drawing_battery, *drawing_temp;
+
+extern GtkWidget *map_drawingarea;
+
+
+/* action=1: radar (speedtrap) */
+wpstruct *wayp;
+
+friendsstruct *friends, *fserver;
+
+/* socket for friends */
+extern int sockfd;
+
+
+gchar oldfilename[2048];
+GString *tempmapfile;
+gdouble earthr;
+/*Earth radius calibrated with GARMIN III */
+/* gdouble R = 6383254.445; */
+
+
+#define R earthr
+
+
+gint maploaded = FALSE;
+gint iszoomed;
+static gchar const rcsid[] =
+ "$Id: gpsdrive.c 1656 2007-09-15 00:39:08Z loom $";
+gint thisline;
+gint maxwp, maxfriends = 0;
+GtkStyle *style = NULL;
+GtkRcStyle *mainstyle;
+gint satlist[MAXSATS][4], satlistdisp[MAXSATS][4], satbit = 0;
+GtkWidget *mylist;
+
+extern gchar mapfilename[2048];
+
+gdouble milesconv;
+gdouble gbreit, glang, olddist = 99999.0;
+GTimer *timer, *disttimer;
+gint gcount;
+gchar localedecimal;
+gchar language[] = "en";
+
+extern gint downloadwindowactive;
+extern gint downloadactive;
+
+GtkWidget *add_wp_name_text, *wptext2;
+gchar oldangle[100];
+
+// Uncomment this (or add a make flag?) to only have scales for expedia maps
+//#define EXPEDIA_SCALES_ONLY
+
+#ifdef EXPEDIA_SCALES_ONLY
+gint slistsize = 12;
+gchar *slist[] = { "5000", "15000", "20000", "50000",
+ "100000", "200000", "750000", "3000000", "7500000", "75000000",
+ "88067900","90000000"
+};
+gint nlist[] = { 5000, 15000, 20000, 50000,
+ 100000, 200000, 750000, 3000000, 7500000, 75000000,
+ 88067900,90000000
+};
+#else
+gint slistsize = 32;
+gchar *slist[] = { "1000", "1500", "2000", "3000", "5000", "7500",
+ "10000", "15000", "20000", "30000", "50000", "75000",
+ "100000", "150000", "200000", "300000", "500000", "750000",
+ "1000000", "1500000", "2000000", "3000000", "5000000", "7500000",
+ "10000000", "15000000", "20000000", "30000000", "50000000", "75000000",
+ "88067900","90000000"
+};
+gint nlist[] = { 1000, 1500, 2000, 3000, 5000, 7500,
+ 10000, 15000, 20000, 30000, 50000, 75000,
+ 100000, 150000, 200000, 300000, 500000, 750000,
+ 1000000, 1500000, 2000000, 3000000, 5000000, 7500000,
+ 10000000, 15000000, 20000000, 30000000, 50000000, 75000000,
+ 88067900,90000000
+};
+#endif
+
+
+GtkWidget *label_map_filename;
+GtkWidget *label_timedest;
+GtkWidget *wp_bt;
+GtkWidget *bestmap_bt, *poi_draw_bt, *wlan_draw_bt;
+
+GtkWidget *track_bt;
+GtkWidget *savetrack_bt;
+GtkWidget *loadtrack_bt;
+GdkSegment *track, *trackshadow;
+glong tracknr;
+trackcoordstruct *trackcoord;
+extern glong trackcoordnr, tracklimit, trackcoordlimit,old_trackcoordnr;
+gchar savetrackfn[256];
+
+gint havespeechout, hours, minutes, speechcount = 0;
+gchar lastradar[40], lastradar2[40];
+gint foundradar;
+gdouble radarbearing;
+gint errortextmode = TRUE;
+gint haveproxy, proxyport;
+gchar proxy[256], hostname[256];
+
+/*** Mod by Arms */
+gint real_screen_x, real_screen_y, real_psize, real_smallmenu;
+gint SCREEN_X_2, SCREEN_Y_2;
+gint showallmaps = TRUE;
+/* guint selwptimeout; */
+extern gint setwpactive;
+gint selected_wp_mode = FALSE;
+gint onemousebutton = FALSE;
+
+
+GtkWidget *askwindow;
+extern time_t maptxtstamp;
+gint simpos_timeout = 0;
+gint setdefaultpos = TRUE;
+extern gint markwaypoint;
+GtkWidget *addwaypointwindow;
+gint oldbat = 125, oldloading = FALSE;
+gint bat, loading;
+typedef struct
+{
+ gchar n[200];
+}
+namesstruct;
+namesstruct *names;
+gchar gpsdservername[200], setpositionname[80];
+gint newsatslevel = TRUE;
+GtkWidget *mapdirbt;
+GtkWidget *slowcpubt;
+GtkWidget *add_wp_lon_text, *add_wp_lat_text;
+
+gdouble precision = (-1.0), gsaprecision = (-1.0);
+gint oldsatfix = 0, oldsatsanz = -1, havealtitude = FALSE;
+gint satfix = 0, usedgps = FALSE;
+gchar dgpsserver[80], dgpsport[10];
+GtkWidget *posbt;
+GtkWidget *mapnik_bt;
+GtkWidget *cover;
+extern gint PSIZE;
+extern gint needreloadmapconfig;
+GdkPixbuf *batimage = NULL;
+GdkPixbuf *temimage = NULL;
+GdkPixbuf *satsimage = NULL;
+gint sats_used = 0, sats_in_view = 0;
+gint numgrids = 4, scroll = TRUE;
+gint satposmode = FALSE;
+gint printoutsats = FALSE;
+extern gchar *displaytext;
+gint isnight = FALSE, disableisnight;
+gint nighttimer;
+GtkWidget *setupentry[50], *setupentrylabel[50];
+gchar utctime[20], loctime[20];
+gint redrawtimeout;
+gint borderlimit;
+gint pdamode = FALSE;
+gint exposecounter = 0, exposed = FALSE;
+gdouble tripodometer, tripavspeed, triptime, tripmaxspeed, triptmp;
+gint tripavspeedcount;
+gdouble trip_lon, trip_lat;
+gint lastnotebook = 0;
+GtkWidget *settingsnotebook;
+gint useflite = FALSE;
+extern gint zone;
+gint ignorechecksum = FALSE;
+gint friends_poi_id[TRAVEL_N_MODES];
+
+/* Give more debug informations */
+gint mydebug = 0;
+
+char dbhost[MAXDBNAME], dbuser[MAXDBNAME], dbpass[MAXDBNAME];
+char dbtable[MAXDBNAME], dbname[MAXDBNAME],wlantable[MAXDBNAME];
+char poitypetable[MAXDBNAME];
+char wp_typelist[MAXPOITYPES][50];
+double dbdistance;
+gint usesql = FALSE, dbusedist = FALSE;
+extern gint sqlselects[MAXPOITYPES], kismetsock, havekismet;
+
+extern GdkPixbuf *kismetpixbuf, *iconpixbuf[50];
+gint earthmate = FALSE;
+
+extern GdkPixbuf *posmarker_img;
+
+extern gint wptotal, wpselected;
+
+extern routestatus_struct route;
+extern color_struct colors;
+
+GdkFont *font_wplabel;
+gchar font_text[100];
+
+gint drawmarkercounter = 0, loadpercent = 10, globruntime = 30;
+extern int pleasepollme;
+
+
+gint forcehavepos = FALSE;
+extern gchar cputempstring[20], batstring[20];
+extern GtkWidget *tempeventbox, *batteventbox;
+GtkWidget *sateventbox = NULL;
+GtkWidget *satsvbox, *satshbox, *satslabel1eventbox;
+GtkWidget *satslabel2eventbox, *satslabel3eventbox;
+GtkWidget *satslabel1, *satslabel2, *satslabel3;
+GtkWidget *frame_map_area;
+GtkWidget *frame_wp;
+GtkWidget *frame_poi,*frame_track, *lab1;
+GtkWidget *menubar;
+gchar messagename[40], messagesendtext[1024], messageack[100];
+gint statuslock = 0, gpson = FALSE;
+int messagenumber = 0, didrootcheck = 0;
+int timerto = 0;
+GtkTextBuffer *getmessagebuffer;
+
+int newdata = FALSE;
+extern pthread_mutex_t mutex;
+//int mapistopo = FALSE;
+extern int havenasa;
+int nosplash = FALSE;
+int havedefaultmap = TRUE;
+
+int storetz = FALSE;
+int egnoson = 0, egnosoff = 0;
+
+// ---------------------- for nmea_handler.c
+extern gint haveRMCsentence;
+extern gchar nmeamodeandport[50];
+extern gdouble NMEAsecs;
+extern gint NMEAoldsecs;
+extern FILE *nmeaout;
+/* if we get data from gpsd in NMEA format haveNMEA is TRUE */
+extern gint haveNMEA;
+#ifdef DBUS_ENABLE
+extern gint useDBUS;
+#endif
+extern int nmeaverbose;
+extern gint bigp , bigpGGA , bigpRME , bigpGSA, bigpGSV;
+extern gint lastp, lastpGGA, lastpRME, lastpGSA, lastpGSV;
+
+extern GtkWidget *main_window;
+extern GtkWidget *frame_statusbar;
+extern GtkWidget *main_table;
+
+void sql_load_lib();
+void unit_test(void);
+void drawdownloadrectangle (gint big);
+void draw_grid (GtkWidget * widget);
+
+
+gchar geometry[80];
+gint usegeometry = FALSE;
+
+/*
+ * ****************************************************************************
+ * ****************************************************************************
+ * ****************************************************************************
+*/
+
+
+
+/* ******************************************************************
+ * Check dirs and files
+ */
+void check_and_create_files(){
+ gchar file_path[2048];
+ struct stat buf;
+
+ if ( mydebug >5 ) fprintf(stderr , " check_and_create_files()\n");
+
+ // Create .gpsdrive dir if not exist
+ g_snprintf (file_path, sizeof (file_path),"%s",local_config.dir_home);
+ if(stat(file_path,&buf))
+ {
+ if ( mkdir (file_path, 0700) )
+ {
+ printf("Error creating %s\n",file_path);
+ } else {
+ printf("created %s\n",file_path);
+ }
+ }
+
+ // Create maps/ Directory if not exist
+ g_strlcpy (file_path, local_config.dir_maps, sizeof (file_path));
+ if(stat(file_path,&buf))
+ {
+ if ( mkdir (file_path, 0700) )
+ {
+ printf("Error creating %s\n",file_path);
+ } else {
+ printf("created %s\n",file_path);
+ }
+ }
+
+ // map_koord.txt
+ // Copy from system if not exist
+ g_snprintf (file_path, sizeof (file_path),
+ "%s/map_koord.txt",
+ local_config.dir_maps);
+ if ( stat (file_path, &buf) ) {
+ gchar copy_command[2048];
+ g_snprintf (copy_command, sizeof (copy_command),
+ "cp %s/gpsdrive/map_koord.txt %s",
+ (gchar *) DATADIR,
+ file_path);
+ if ( system (copy_command))
+ {
+ fprintf(stderr,"Error Creating %s\nwith command: '%s'\n",
+ file_path,copy_command);
+ exit(-1);
+ }
+ else
+ fprintf(stderr,"Created map_koord.txt %s\n",file_path);
+ };
+
+
+}
+
+
+
+
+/* *****************************************************************************
+ */
+void
+display_status (char *message)
+{
+ gchar tok[200];
+
+ if ( mydebug >20 )
+ fprintf(stderr , "display_status(%s)\n",message);
+
+ if (downloadactive)
+ return;
+ if (current.importactive)
+ return;
+ if (statuslock)
+ return;
+ g_snprintf (tok, sizeof (tok), "%s", message);
+ gtk_statusbar_pop (GTK_STATUSBAR (frame_statusbar), current.statusbar_id);
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar), current.statusbar_id, tok);
+}
+
+
+/* *****************************************************************************
+ */
+gint
+lightoff (GtkWidget * widget, guint * datum)
+{
+ disableisnight = FALSE;
+ /* gtk_widget_modify_bg (main_window, GTK_STATE_NORMAL, &colors.nightmode); */
+ return FALSE;
+}
+
+/* *****************************************************************************
+ */
+gint
+lighton (void)
+{
+ disableisnight = TRUE;
+ /* nighttimer = gtk_timeout_add (30000, (GtkFunction) lightoff, 0); */
+
+ /* gtk_widget_restore_default_style(main_window); */
+ return TRUE;
+}
+
+/* *****************************************************************************
+ */
+gint
+tripreset ()
+{
+ tripodometer = tripavspeed = triptime = tripmaxspeed = triptmp = 0.0;
+ tripavspeedcount = 0;
+ trip_lat = coords.current_lat;
+ trip_lon = coords.current_lon;
+ triptime = time (NULL);
+
+ return TRUE;
+}
+
+/* ******************************************************************
+ * TODO: This is a strange collection of function calls
+ * TODO: put them where they belong
+ */
+gint
+testconfig_cb (GtkWidget * widget, guint * datum)
+{
+ if ( mydebug >50 ) fprintf(stderr , "testconfig_cb()\n");
+
+#ifdef MAKETHISTEST
+ test_loaded_map_names();
+#endif
+
+ friendsagent_cb (NULL, 0);
+ tripreset ();
+ gtk_timeout_add (TRIPMETERTIMEOUT * 1000, (GtkFunction) dotripmeter,
+ NULL);
+
+ return FALSE;
+}
+
+/* *****************************************************************************
+ * display upper status line
+ * speak how long it takes till we reach our destination
+ */
+void
+display_status2 ()
+{
+ //gchar s2[100];
+ gchar buf[200];
+ gint h, m;
+ gdouble secs, v;
+
+ if ( mydebug >50 ) fprintf(stderr , "display_status2()\n");
+
+ if (downloadactive)
+ return;
+ if (current.importactive)
+ return;
+ secs = g_timer_elapsed (disttimer, 0);
+ h = hours;
+ m = minutes;
+ if (secs >= 300.0)
+ {
+ g_timer_stop (disttimer);
+ g_timer_start (disttimer);
+ v = 3600.0 * (olddist - current.dist) / secs;
+ h = current.dist / v;
+ m = 60 * (current.dist / v - h);
+ if (mydebug)
+ g_print ("secs: %.0fs,v:%.0f,h:%d,m:%d\n", secs, v, h,
+ m);
+ if ((m < 0) || (h > 99))
+ {
+ h = 99;
+ m = 99;
+ }
+ olddist = current.dist;
+ hours = h;
+ minutes = m;
+
+
+ if( !local_config.mute )
+ {
+ if( hours < 99 )
+ {
+ if( hours > 0 )
+ {
+ if( 1 == hours )
+ {
+ g_snprintf(
+ buf, sizeof(buf), speech_arrival_one_hour_mins[voicelang],
+ minutes );
+ }
+ else
+ {
+ g_snprintf(
+ buf, sizeof(buf), speech_arrival_hours_mins[voicelang], hours,
+ minutes );
+ }
+ }
+ else
+ {
+ g_snprintf(
+ buf, sizeof(buf), speech_arrival_mins[voicelang], minutes );
+ }
+
+ speech_out_speek( buf );
+ }
+ }
+ }
+
+
+ if ( mydebug > 10 )
+ {
+ if (current.gpsfix > 1)
+ g_print ("***Position: %f %f***\n", coords.current_lat,
+ coords.current_lon);
+ else
+ g_print ("***no valid Position:\n");
+ }
+
+
+
+}
+
+
+/* *****************************************************************************
+ * draw the marker on the map
+ * calculate CPU load: loadpercent
+ * check night mode switching
+ * check for new map
+ * TODO: eventually split this callback or rename it
+ */
+gint
+drawmarker_cb (GtkWidget * widget, guint * datum)
+{
+ static struct timeval tv1, tv2;
+ struct timezone tz;
+ long runtime, runtime2;
+
+ if ( mydebug >50 ) fprintf(stderr , "drawmacker_cb()\n");
+
+ if (current.importactive)
+ return TRUE;
+
+ if ((!disableisnight) && (!downloadwindowactive))
+ {
+ if ( (local_config.nightmode == NIGHT_ON) ||
+ (local_config.nightmode == NIGHT_AUTO && isnight)
+ )
+ {
+ switch_nightmode (TRUE);
+ }
+ }
+
+ if ( local_config.nightmode == NIGHT_OFF
+ || disableisnight || downloadwindowactive
+ )
+ {
+ switch_nightmode (FALSE);
+ }
+
+
+ gettimeofday (&tv1, &tz);
+ runtime2 = tv1.tv_usec - tv2.tv_usec;
+ if (tv1.tv_sec != tv2.tv_sec)
+ runtime2 += 1000000l * (tv1.tv_sec - tv2.tv_sec);
+
+ /* we test if we have to load a new map because we are outside
+ * the currently loaded map
+ */
+ test_and_load_newmap ();
+
+ /* g_print("drawmarker_cb %d\n",drawmarkercounter++); */
+ exposed = FALSE;
+ /* The position calculation is made in expose_cb() */
+ //gtk_widget_draw (map_drawingarea, NULL); /* this calls expose handler */
+
+ if (!exposed)
+ expose_cb (NULL, 0);
+
+ gtk_widget_queue_draw_area (drawing_compass, 0,0,100,100);
+ //expose_compass (NULL, 0);
+
+ gettimeofday (&tv2, &tz);
+ runtime = tv2.tv_usec - tv1.tv_usec;
+ if (tv2.tv_sec != tv1.tv_sec)
+ runtime += 1000000l * (tv2.tv_sec - tv1.tv_sec);
+ globruntime = runtime / 1000;
+ loadpercent = (int) (100.0 * (float) runtime / (runtime + runtime2));
+ if ( mydebug>30 )
+ g_print ("Rechenzeit: %dms, %d%%\n", (int) (runtime / 1000),
+ loadpercent);
+
+ return FALSE;
+}
+
+
+/* *****************************************************************************
+ * Try to produce only given CPU load
+ */
+gint
+calldrawmarker_cb (GtkWidget * widget, guint * datum)
+{
+ gint period;
+
+ if ( mydebug >50 ) fprintf(stderr , "calldrawmarker_cb()\n");
+
+ if (local_config.maxcpuload < 1)
+ local_config.maxcpuload = 1;
+ if (local_config.maxcpuload > 95)
+ local_config.maxcpuload = 95;
+ if (!haveNMEA)
+ expose_gpsfix (NULL, 0);
+ if (pleasepollme)
+ {
+ pleasepollme++;
+ if (pleasepollme > 10)
+ {
+ pleasepollme = 1;
+ friends_sendmsg (local_config.friends_serverip, NULL);
+ }
+ }
+ period = 10 * globruntime / (10 * local_config.maxcpuload);
+ drawmarkercounter++;
+ /* g_print("period: %d, drawmarkercounter %d\n", period, drawmarkercounter); */
+
+
+ if (local_config.MapnikStatusInt > 0 && drawmarkercounter >= 3) {
+ drawmarkercounter = 0;
+ drawmarker_cb (NULL, NULL);
+ return TRUE;
+ }
+ if (((drawmarkercounter > period) || (drawmarkercounter > 50))
+ && (drawmarkercounter >= 3))
+ {
+ drawmarkercounter = 0;
+ drawmarker_cb (NULL, NULL);
+ }
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ * Master agent
+ */
+gint
+masteragent_cb (GtkWidget * widget, guint * datum)
+{
+ gchar buffer[200];
+
+ if ( mydebug >50 ) fprintf(stderr , "masteragent_cb()\n");
+
+ if (current.needtosave)
+ writeconfig ();
+
+
+ map_koord_check_and_reload();
+
+ testifnight ();
+
+
+ if (!didrootcheck)
+ if (getuid () == 0)
+ {
+ g_snprintf (buffer, sizeof (buffer),
+ "<span weight=\"bold\">%s</span>\n%s",
+ _("Warning!"),
+ _
+ ("You should not start GpsDrive as user root!!!"));
+ popup_warning (NULL, buffer);
+ didrootcheck = TRUE;
+ }
+
+ /* Check for changed way.txt and reload if changed */
+ check_and_reload_way_txt();
+
+ if (tracknr > (tracklimit - 1000))
+ {
+ g_print ("tracklimit: %ld", tracklimit);
+ track = g_renew (GdkSegment, track, tracklimit + 100000);
+ trackshadow =
+ g_renew (GdkSegment, trackshadow,
+ tracklimit + 100000);
+ tracklimit += 100000;
+ }
+ if (trackcoordnr > (trackcoordlimit - 1000))
+ {
+ trackcoord =
+ g_renew (trackcoordstruct, trackcoord,
+ trackcoordlimit + 100000);
+ trackcoordlimit += 100000;
+ }
+
+
+
+ return TRUE;
+}
+
+/* *****************************************************************************
+ * add new trackpoint to 'trackcoordstruct list' to draw track on image
+ */
+gint
+storetrack_cb (GtkWidget * widget, guint * datum)
+{
+ if ( mydebug >50 )
+ fprintf(stderr , "storetrack_cb()\n");
+
+ if (gui_status.posmode)
+ return TRUE;
+
+#ifdef DBUS_ENABLE
+ /* If we use DBUS track points are usually stored by the DBUS signal handler */
+ /* Only store them by timer if we are in position mode */
+ if ( useDBUS && !current.simmode )
+ return TRUE;
+#endif
+
+ storepoint();
+
+ return TRUE;
+}
+
+void
+storepoint ()
+{
+ gint so;
+ gchar buf3[35];
+ time_t t;
+ struct tm *ts;
+ /* g_print("Havepos: %d\n", current.gpsfix); */
+ if ((!current.simmode && current.gpsfix < 2) || gui_status.posmode /* ||((!local_config.simmode &&haveposcount<3)) */ ) /* we have no valid position */
+ {
+ (trackcoord + trackcoordnr)->lon = 1001.0;
+ (trackcoord + trackcoordnr)->lat = 1001.0;
+ (trackcoord + trackcoordnr)->alt = 1001.0;
+ }
+ else
+ {
+ (trackcoord + trackcoordnr)->lon = coords.current_lon;
+ (trackcoord + trackcoordnr)->lat = coords.current_lat;
+ (trackcoord + trackcoordnr)->alt = current.altitude;
+ if (local_config.savetrack) do_incremental_save();
+ }
+
+
+ /* The double storage seems to be silly, but I have to use */
+ /* gdk_draw_segments instead of gdk_draw_lines. */
+ /* gkd_draw_lines is dog slow because of a gdk-bug. */
+
+ if (tracknr == 0)
+ {
+ if ((trackcoord + trackcoordnr)->lon < 1000.0)
+ {
+ (track + tracknr)->x1 = posx;
+ (track + tracknr)->y1 = posy;
+ (trackshadow + tracknr)->x1 = posx + SHADOWOFFSET;
+ (trackshadow + tracknr)->y1 = posy + SHADOWOFFSET;
+ tracknr++;
+ }
+ }
+ else
+ {
+ if ((trackcoord + trackcoordnr)->lon < 1000.0)
+ {
+ if ((posx != (track + tracknr - 1)->x2)
+ || (posy != (track + tracknr - 1)->y2))
+ {
+ /* so=(int)(((trackcoord + trackcoordnr)->alt))>>5; */
+ so = SHADOWOFFSET;
+ (track + tracknr)->x1 =
+ (track + tracknr - 1)->x2 = posx;
+ (track + tracknr)->y1 =
+ (track + tracknr - 1)->y2 = posy;
+ (trackshadow + tracknr)->x1 =
+ (trackshadow + tracknr - 1)->x2 =
+ posx + so;
+ (trackshadow + tracknr)->y1 =
+ (trackshadow + tracknr - 1)->y2 =
+ posy + so;
+ tracknr += 1;
+ }
+ }
+ else
+ tracknr = tracknr & ((glong) - 2);
+ }
+ time (&t);
+ ts = localtime (&t);
+ strncpy (buf3, asctime (ts), 32);
+ buf3[strlen (buf3) - 1] = '\0'; /* get rid of \n */
+ g_strlcpy ((trackcoord + trackcoordnr)->postime, buf3, 30);
+ trackcoordnr++;
+}
+
+/* *****************************************************************************
+ * show satelite information
+ * TODO: change color of sat BARs if the reception is bad/acceptable/good to red/yellow/green
+ */
+gint
+expose_sats_cb (GtkWidget * widget, guint * datum)
+{
+ gint k, i, yabs, h, j, l;
+ gchar t[10], t1[20], buf[300], txt[10];
+ static GdkPixbufAnimation *anim = NULL;
+ static GdkPixbufAnimationIter *animiter = NULL;
+ GTimeVal timeresult;
+#define SATX 5
+ /* draw satellite level (field strength) only in NMEA modus */
+return TRUE;
+ //if ( mydebug >50 )
+ fprintf(stderr , "expose_sats_cb()\n");
+
+
+ if (haveNMEA)
+ {
+ gdk_gc_set_foreground (kontext_gps, &colors.lcd);
+
+ gdk_draw_rectangle (drawable_gps, kontext_gps, 1, 3, 0,
+ PSIZE + 2, PSIZE + 5);
+ gdk_gc_set_line_attributes (kontext_gps, 1, 0, 0, 0);
+ gdk_gc_set_foreground (kontext_gps, &colors.black);
+ gdk_draw_rectangle (drawable_gps, kontext_gps, 0, 3, 0,
+ PSIZE + 2, PSIZE + 5);
+
+ gdk_gc_set_foreground (kontext_gps, &colors.lcd);
+
+ if (!satposmode)
+ {
+ if (current.gpsfix > 1)
+ gdk_gc_set_foreground (kontext_gps, &colors.green);
+ else
+ gdk_gc_set_foreground (kontext_gps, &colors.red);
+ gdk_gc_set_line_attributes (kontext_gps, 2, 0, 0, 0);
+ for (i = 3; i < (PSIZE + 5); i += 3)
+ gdk_draw_line (drawable_gps, kontext_gps, 4, i,
+ PSIZE + 4, i);
+
+
+ gdk_gc_set_foreground (kontext_gps, &colors.lcd2);
+ gdk_gc_set_line_attributes (kontext_gps, 5, 0, 0, 0);
+ k = 0;
+ for (i = 0; i < 16; i++)
+ {
+ if (i > 5)
+ yabs = 2 + PSIZE;
+ else
+ yabs = 1 + PSIZE / 2;
+ h = PSIZE / 2 - 2;
+ gdk_draw_line (drawable_gps, kontext_gps,
+ 6 + 7 * k + SATX, yabs,
+ 6 + 7 * k + SATX, yabs - h);
+ k++;
+ if (k > 5)
+ k = 0;
+ }
+ }
+ if (satfix == 1) /* normal Fix */
+ gdk_gc_set_foreground (kontext_gps, &colors.black);
+ else
+ {
+ if (satfix == 0) /* no Fix */
+ gdk_gc_set_foreground (kontext_gps, &colors.textback);
+ else /* Differntial Fix */
+ gdk_gc_set_foreground (kontext_gps, &colors.blue);
+ }
+ j = k = 0;
+
+ if (satposmode)
+ {
+ gdk_gc_set_line_attributes (kontext_gps, 1, 0, 0, 0);
+ gdk_gc_set_foreground (kontext_gps, &colors.lcd2);
+ gdk_draw_arc (drawable_gps, kontext_gps, 0, 4,
+ 4, PSIZE, PSIZE, 105 * 64, 330 * 64);
+ gdk_draw_arc (drawable_gps, kontext_gps, 0,
+ 5 + PSIZE / 4, 4 + PSIZE / 4, PSIZE / 2,
+ PSIZE / 2, 0, 360 * 64);
+ gdk_gc_set_foreground (kontext_gps, &colors.darkgrey);
+ {
+ /* prints in pango */
+ PangoFontDescription *pfd;
+ PangoLayout *wplabellayout;
+ gint width;
+
+ wplabellayout =
+ gtk_widget_create_pango_layout
+ (drawing_gps, "N");
+ //KCFX
+ if (local_config.guimode == GUI_PDA)
+ pfd = pango_font_description_from_string ("Sans 7");
+ else
+ if (local_config.guimode == GUI_CAR)
+ pfd = pango_font_description_from_string ("Sans 7");
+ else
+ pfd = pango_font_description_from_string ("Sans bold 10");
+ pango_layout_set_font_description
+ (wplabellayout, pfd);
+
+ gdk_draw_layout_with_colors (drawable_gps,
+ kontext_gps,
+ 0 + (PSIZE) / 2,
+ -2,
+ wplabellayout,
+ &colors.grey, NULL);
+ pango_layout_get_pixel_size (wplabellayout,
+ &width, NULL);
+ /* printf ("w: %d\n", width); */
+ if (wplabellayout != NULL)
+ g_object_unref (G_OBJECT
+ (wplabellayout));
+ /* freeing PangoFontDescription, cause it has been copied by prev. call */
+ pango_font_description_free (pfd);
+
+ }
+
+ /* gdk_draw_text (drawable_gps, font_verysmalltext, kontext_gps,
+ * 2 + (PSIZE) / 2, 9, "N", 1);
+ */
+ gdk_gc_set_foreground (kontext_gps, &colors.lcd2);
+
+ }
+
+ for (i = 0; i < MAXSATS; i++)
+ if (satlistdisp[i][0] != 0)
+ {
+ if ((satlistdisp[i][1] > 30)
+ && (printoutsats))
+ g_print ("%d %d\n", satlistdisp[i][3],
+ satlistdisp[i][2]);
+ if (satposmode)
+ {
+ gint x, y;
+ gdouble el, az;
+ el = (90.0 - satlistdisp[i][2]);
+ az = DEG2RAD(satlistdisp[i][3]);
+
+ x = (PSIZE / 2) +
+ sin (az) * (el / 90.0) *
+ (PSIZE / 2);
+ y = (PSIZE / 2) -
+ cos (az) * (el / 90.0) *
+ (PSIZE / 2);
+ l = (satlistdisp[i][1] / 6);
+ if (l > 7)
+ l = 7;
+ switch (l & 7)
+ {
+ case 0:
+ case 1:
+ gdk_gc_set_foreground
+ (kontext_gps, &colors.textback);
+ break;
+ case 2:
+ case 3:
+ gdk_gc_set_foreground
+ (kontext_gps, &colors.red);
+ break;
+ case 4:
+ case 5:
+ case 6:
+ gdk_gc_set_foreground
+ (kontext_gps, &colors.yellow);
+ break;
+ case 7:
+ gdk_gc_set_foreground
+ (kontext_gps, &colors.green2);
+ break;
+ }
+ gdk_draw_arc (drawable_gps, kontext_gps,
+ 1, 2 + x, 2 + y, 5, 5,
+ 0, 360 * 64);
+
+ }
+ else
+ {
+ if (j > 5)
+ yabs = PSIZE + 2;
+ else
+ yabs = 1 + PSIZE / 2;
+ h = satlistdisp[i][1] - 30;
+ if (h < 0)
+ h = 1;
+ if (h > 19)
+ h = 19;
+ gdk_draw_line (drawable_gps, kontext_gps,
+ 6 + 7 * k + SATX, yabs,
+ 6 + 7 * k + SATX,
+ yabs -
+ (PSIZE / 2) * h /
+ (PSIZE / 2 - 5));
+ k++;
+ if (k > 5)
+ k = 0;
+ j++;
+ }
+ }
+ newsatslevel = FALSE;
+ g_snprintf (txt, sizeof (txt), "%d/%d", sats_used, sats_in_view);
+ gtk_entry_set_text (GTK_ENTRY (satslabel1), txt);
+ if ((precision > 0.0) && (satfix != 0))
+ {
+ if (local_config.distmode == DIST_MILES || local_config.distmode == DIST_NAUTIC)
+ g_snprintf (t1, sizeof (t1), "%.0fft",
+ precision * 3.2808399);
+ else
+ g_snprintf (t1, sizeof (t1), "%.0fm",
+ precision);
+ g_snprintf (t, sizeof (t), "%s", t1);
+ }
+ else
+ g_snprintf (t, sizeof (t), "n/a");
+
+ gtk_entry_set_text (GTK_ENTRY (satslabel2), t);
+ if ((gsaprecision > 0.0) && (satfix != 0))
+ {
+ g_snprintf (t1, sizeof (t1), "%.1f", gsaprecision);
+ g_snprintf (t, sizeof (t), "%s", t1);
+ }
+ else
+ g_snprintf (t, sizeof (t), "n/a");
+ gtk_entry_set_text (GTK_ENTRY (satslabel3), t);
+
+ g_strlcpy (buf, "", sizeof (buf));
+ if ( mydebug > 30 )
+ g_print ("gpsd: Satfix: %d\n", satfix);
+
+ if (satfix != oldsatfix)
+ {
+ if( !local_config.mute && local_config.sound_gps )
+ {
+ if( 0 == satfix )
+ {
+ g_snprintf( buf, sizeof(buf), speech_gps_lost[voicelang] );
+ }
+ else if( 1 == satfix )
+ {
+ if( 2 == oldsatfix )
+ {
+ g_snprintf( buf, sizeof(buf), speech_diff_gps_lost[voicelang] );
+ }
+ else
+ {
+ g_snprintf( buf, sizeof(buf), speech_gps_good[voicelang] );
+ }
+ }
+ else if( 2 == satfix )
+ {
+ g_snprintf( buf, sizeof(buf), speech_diff_gps_found[voicelang] );
+ }
+
+ speech_out_speek( buf );
+ }
+
+ oldsatfix = satfix;
+ }
+ }
+ else
+ {
+ if (satsimage == NULL)
+ {
+ gchar mappath[2048];
+
+ g_snprintf (mappath, sizeof (mappath),
+ "data/pixmaps/gpsdriveanim.gif");
+ anim = gdk_pixbuf_animation_new_from_file (mappath,
+ NULL);
+ if ( anim == NULL ) {
+ g_snprintf (mappath, sizeof (mappath),
+ "%s/gpsdrive/%s", DATADIR,
+ "pixmaps/gpsdriveanim.gif");
+ anim = gdk_pixbuf_animation_new_from_file (mappath,
+ NULL);
+ }
+ if (anim == NULL)
+ fprintf (stderr,
+ _
+ ("\nWarning: unable to load gpsdriveanim.gif!\n"
+ "Please install the program as root with:\nmake install\n\n"));
+ g_get_current_time (&timeresult);
+ if (animiter != NULL)
+ g_object_unref (animiter);
+ animiter =
+ gdk_pixbuf_animation_get_iter (anim,
+ &timeresult);
+ satsimage =
+ gdk_pixbuf_animation_iter_get_pixbuf
+ (animiter);
+ }
+ if (gdk_pixbuf_animation_iter_advance (animiter, NULL))
+ satsimage =
+ gdk_pixbuf_animation_iter_get_pixbuf
+ (animiter);
+ gdk_gc_set_function (kontext_gps, GDK_AND);
+ gdk_draw_pixbuf (drawable_gps, kontext_gps, satsimage, 0, 0,
+ SATX, 0, 50, 50, GDK_RGB_DITHER_NONE, 0, 0);
+ gdk_gc_set_function (kontext_gps, GDK_COPY);
+ }
+ return TRUE;
+}
+
+
+/*
+ * Draw the scale bar ( |-------------| ) into the map. Also add a textual
+ * description of the currently used scale.
+ */
+void
+draw_scalebar (void)
+{
+ gchar scale_txt[100];
+ gdouble factor[] = { 1.0, 2.5, 5.0, };
+ gint exponent = 0;
+ gdouble remains = 0.0;
+ gint used_factor = 0;
+ gint i;
+ gint min_bar_length = SCREEN_X / 8; /* 1/8 of the display width */
+ const gint dist_x = 20; /* distance to the right */
+ const gint dist_y = 20; /* distance to bottom */
+ const gint frame_width = 5; /* grey pixles around the scale bar */
+ gint bar_length;
+ gchar *format;
+ gchar *symbol;
+ gdouble approx_displayed_value;
+ gdouble conversion;
+ gint l;
+ // gint text_length_pixel;
+
+ /*
+ * We want a bar with at least (min_bar_length) pixles in
+ * length. Calculate the displayed value of this bar is whatever
+ * metric is requested.
+ *
+ * The bar length' value l (in m), divided by "conversion", will
+ * result in what to display to the user, in terms of "symbol".
+ */
+ approx_displayed_value /* m */ = min_bar_length * current.mapscale
+ / PIXELFACT / current.zoom;
+
+ if (local_config.distmode == DIST_NAUTIC) {
+ conversion /* m/nmi */ = 1000.0 /* m/km */ / KM2NAUTIC /* nmi/km */;
+ symbol = "nmi";
+ format = "%.2lf %s";
+ } else if (local_config.distmode == DIST_METRIC) {
+ conversion /* m/m */ = 1.0 /* m/m */;
+ symbol = "m";
+ format = "%.0lf %s";
+ if (approx_displayed_value / conversion > 1000) {
+ conversion /* m/km */ = 1000.0;
+ symbol = "km";
+ format = "%.0lf %s";
+ }
+ } else if (local_config.distmode == DIST_MILES) {
+ conversion /* m/yd */ = 1000.0 /* m/km */
+ / 1760.0 /* yd/mi */
+ / KM2MILES /* mi/km */;
+ symbol = "yd";
+ format = "%.0lf %s";
+ if (approx_displayed_value / conversion > 1760.0) {
+ conversion /* m/mi */ = 1000.0 /* m/km */
+ / KM2MILES /* mi/km */;
+ symbol = "mi";
+ format = "%.0lf %s";
+ }
+ } else
+ return;
+
+ /*
+ * Now find a well-formed value that is about the expected size
+ * of the scale bar, or a bit longer.
+ */
+ for (i = 0; i < ARRAY_SIZE (factor); i++) {
+ gdouble rest;
+ gdouble log_value;
+
+ log_value = log10 (min_bar_length * current.mapscale / PIXELFACT
+ / conversion / current.zoom / factor[i]);
+
+ if ((rest = log_value - floor (log_value)) >= remains) {
+ remains = rest;
+ used_factor = i;
+ exponent = (gint) floor (log_value) + 1;
+ }
+ }
+ bar_length = factor[used_factor] * pow (10.0, exponent)
+ * conversion / (current.mapscale / PIXELFACT) * current.zoom;
+
+ g_snprintf (scale_txt, sizeof (scale_txt), format, factor[used_factor]
+ * pow (10.0, exponent),
+ symbol);
+
+ /* Now bar_length is the length of the scaler-bar in pixel
+ * and scale_txt is the text for the scaler Bar. For example "10 Km"
+ */
+
+ l = (SCREEN_X - 40) - (strlen (scale_txt) * 15);
+
+ /* Draw greyish rectangle as background for the scale bar */
+ gdk_gc_set_function (kontext_map, GDK_OR);
+ gdk_gc_set_foreground (kontext_map, &colors.mygray);
+ //gdk_gc_set_foreground (kontext_map, &textback);
+ gdk_draw_rectangle (drawable, kontext_map, 1,
+ SCREEN_X - dist_x - bar_length - frame_width,
+ SCREEN_Y - dist_y - 2 * frame_width,
+ bar_length + 2 * frame_width,
+ dist_y + 1 * frame_width);
+ gdk_gc_set_function (kontext_map, GDK_COPY);
+ gdk_gc_set_foreground (kontext_map, &colors.black);
+
+ /* Print the meaning of the scale bar ("10 km") */
+ PangoLayout *scalebar_layout;
+ PangoFontDescription *pfd_scalebar;
+
+ if (local_config.guimode == GUI_PDA)
+ pfd_scalebar = pango_font_description_from_string ("Sans 8");
+ else
+ pfd_scalebar = pango_font_description_from_string ("Sans 11");
+
+ scalebar_layout = gtk_widget_create_pango_layout
+ (map_drawingarea, scale_txt);
+ pango_layout_set_font_description (scalebar_layout, pfd_scalebar);
+
+ gdk_draw_layout_with_colors (drawable, kontext_map,
+ l, SCREEN_Y - dist_y -1 ,
+ scalebar_layout, &colors.black, NULL);
+ if (scalebar_layout != NULL)
+ g_object_unref (G_OBJECT (scalebar_layout));
+
+ /* Print the actual scale bar lines */
+ gdk_gc_set_line_attributes (kontext_map, 2, 0, 0, 0);
+ /* horizontal */
+ gdk_draw_line (drawable, kontext_map,
+ (SCREEN_X - dist_x) - bar_length, SCREEN_Y - dist_y,
+ (SCREEN_X - dist_x), SCREEN_Y - dist_y );
+ /* left */
+ gdk_draw_line (drawable, kontext_map,
+ (SCREEN_X - dist_x) - bar_length, SCREEN_Y - dist_y - frame_width,
+ (SCREEN_X - dist_x) - bar_length, SCREEN_Y - dist_y + 10- frame_width);
+ /* right */
+ gdk_draw_line (drawable, kontext_map,
+ (SCREEN_X - dist_x), SCREEN_Y - dist_y - frame_width,
+ (SCREEN_X - dist_x), SCREEN_Y - dist_y + 10 - frame_width);
+
+}
+
+/*******************************************************************************
+ * Draw the zoom level into the map.
+ */
+void
+draw_zoomlevel (void)
+{
+ gchar zoom_scale_txt[5];
+
+ /* draw zoom factor */
+ g_snprintf (zoom_scale_txt, sizeof (zoom_scale_txt),
+ "%dx", current.zoom);
+ gdk_gc_set_function (kontext_map, GDK_OR);
+ gdk_gc_set_foreground (kontext_map, &colors.mygray);
+ gdk_draw_rectangle (drawable, kontext_map, 1, (SCREEN_X - 30), 0, 30, 30);
+ gdk_gc_set_function (kontext_map, GDK_COPY);
+
+ gdk_gc_set_foreground (kontext_map, &colors.blue);
+
+ /* prints in pango */
+ PangoFontDescription *pfd;
+ PangoLayout *layout_zoom;
+ gint cx, cy;
+ layout_zoom = gtk_widget_create_pango_layout
+ (map_drawingarea, zoom_scale_txt);
+ pfd = pango_font_description_from_string ("Sans 9");
+ pango_layout_set_font_description (layout_zoom, pfd);
+ pango_layout_get_pixel_size (layout_zoom, &cx, &cy);
+ gdk_draw_layout_with_colors (drawable, kontext_map,
+ SCREEN_X-15-cx/2, 15-cy/2, layout_zoom, &colors.blue, NULL);
+ if (layout_zoom != NULL)
+ g_object_unref (G_OBJECT (layout_zoom));
+ /* freeing PangoFontDescription, cause it has been copied by prev. call */
+ pango_font_description_free (pfd);
+}
+
+
+/*******************************************************************************
+ * Draw the filename of the current map into the map.
+ */
+void
+draw_infotext (gchar *text)
+{
+ gchar mfmap_filename[60];
+ PangoFontDescription *pfd;
+ PangoLayout *layout_filename;
+ gint cx, cy;
+
+ strncpy (mfmap_filename, text, 59);
+ mfmap_filename[59] = 0;
+ layout_filename = gtk_widget_create_pango_layout
+ (map_drawingarea, mfmap_filename);
+ pfd = pango_font_description_from_string ("Sans 9");
+ pango_layout_set_font_description (layout_filename, pfd);
+ pango_layout_get_pixel_size (layout_filename, &cx, &cy);
+
+ gdk_gc_set_function (kontext_map, GDK_OR);
+ gdk_gc_set_foreground (kontext_map, &colors.mygray);
+ gdk_draw_rectangle (drawable, kontext_map, 1,
+ 0, SCREEN_Y-cy-10, cx+10, SCREEN_Y);
+ gdk_gc_set_function (kontext_map, GDK_COPY);
+ gdk_gc_set_foreground (kontext_map, &colors.blue);
+
+ gdk_draw_layout_with_colors (drawable, kontext_map,
+ 5, SCREEN_Y-cy-5, layout_filename, &colors.blue, NULL);
+ if (layout_filename != NULL)
+ g_object_unref (G_OBJECT (layout_filename));
+ /* freeing PangoFontDescription, cause it has been copied by prev. call */
+ pango_font_description_free (pfd);
+}
+
+
+/* *****************************************************************************
+ * draw the markers on the map
+ * And many more
+ * TODO: sort out
+ */
+gint
+drawmarker (GtkWidget * widget, guint * datum)
+{
+ gdouble posxdest, posydest, posxmarker, posymarker;
+ gint k;
+
+ gblink = !gblink;
+ /* g_print("simmode: %d, nmea %d\n", current.simmode,haveNMEA); */
+
+ if (current.importactive)
+ return TRUE;
+
+ if (local_config.showgrid)
+ draw_grid (widget);
+
+ if (usesql)
+ {
+ poi_draw_list (FALSE);
+ wlan_draw_list ();
+ }
+
+ if (local_config.showwaypoints)
+ draw_waypoints ();
+
+ drawtracks ();
+
+ if (route.show)
+ draw_route ();
+
+ if (local_config.showfriends && !usesql)
+ drawfriends ();
+
+ if (havekismet)
+ readkismet ();
+
+ if (local_config.showscalebar)
+ draw_scalebar ();
+
+ if (local_config.showzoom && local_config.guimode != GUI_PDA)
+ draw_zoomlevel ();
+
+ if (mydebug > 10 && !local_config.MapnikStatusInt)
+ draw_infotext (g_path_get_basename (mapfilename));
+
+ if (havekismet && (kismetsock>=0))
+ {
+ gdk_draw_pixbuf (drawable, kontext_map, kismetpixbuf, 0, 0,
+ 10, SCREEN_Y - 42,
+ 36, 20, GDK_RGB_DITHER_NONE, 0, 0);
+ }
+
+ if (local_config.savetrack)
+ {
+ k = 100;
+ gdk_gc_set_foreground (kontext_map, &colors.white);
+ gdk_draw_rectangle (drawable, kontext_map, 1, 10,
+ SCREEN_Y - 21, k + 3, 14);
+ gdk_gc_set_foreground (kontext_map, &colors.red);
+ {
+ /* prints in pango */
+ PangoFontDescription *pfd;
+ PangoLayout *wplabellayout;
+
+ wplabellayout =
+ gtk_widget_create_pango_layout (map_drawingarea,
+ savetrackfn);
+ //KCFX
+ if (local_config.guimode == GUI_PDA)
+ pfd = pango_font_description_from_string
+ ("Sans 7");
+ else
+ if (local_config.guimode == GUI_CAR)
+ pfd = pango_font_description_from_string
+ ("Sans 7");
+ else
+ pfd = pango_font_description_from_string
+ ("Sans 10");
+ pango_layout_set_font_description (wplabellayout,
+ pfd);
+
+ gdk_draw_layout_with_colors (drawable, kontext_map,
+ 14, SCREEN_Y - 22,
+ wplabellayout, &colors.red,
+ NULL);
+ if (wplabellayout != NULL)
+ g_object_unref (G_OBJECT (wplabellayout));
+ /* freeing PangoFontDescription, cause it has been
+ copied by prev. call */
+ pango_font_description_free (pfd);
+ }
+
+
+ /* gdk_draw_text (drawable, smallfont_s_text, kontext_map,
+ * 11, SCREEN_Y - 10, savetrackfn,
+ * strlen (savetrackfn));
+ */
+
+ /* gdk_draw_text (drawable, font_s_text, kontext_map, 10, */
+ /* SCREEN_Y - 10, savetrackfn, strlen (savetrackfn)); */
+ }
+
+ if (gui_status.posmode)
+ {
+ blink = TRUE;
+ }
+
+ if (current.gpsfix > 1 || blink)
+ {
+ if (gui_status.posmode)
+ {
+ gdk_gc_set_foreground (kontext_map, &colors.blue);
+ gdk_gc_set_line_attributes (kontext_map, 4, 0, 0, 0);
+ gdk_draw_rectangle (drawable, kontext_map, 0, posx - 10,
+ posy - 10, 20, 20);
+ }
+ else
+ {
+ if (local_config.showshadow)
+ {
+ draw_posmarker (
+ posx + SHADOWOFFSET,
+ posy + SHADOWOFFSET,
+ current.heading, &colors.darkgrey,
+ local_config.posmarker, TRUE, FALSE);
+ }
+
+ /* draw pointer to destination */
+ draw_posmarker (posx, posy, current.bearing,
+ &colors.black, 1, FALSE, FALSE);
+
+
+ /* draw pointer to direction of motion */
+ draw_posmarker (posx, posy, current.heading,
+ &colors.orange2, local_config.posmarker,
+ FALSE, TRUE);
+ }
+ if (markwaypoint)
+ {
+ calcxy (&posxmarker, &posymarker,
+ coords.wp_lon, coords.wp_lat, current.zoom);
+
+ gdk_gc_set_foreground (kontext_map, &colors.green);
+ gdk_gc_set_line_attributes (kontext_map, 5, 0, 0, 0);
+ gdk_draw_arc (drawable, kontext_map, 0, posxmarker - 10,
+ posymarker - 10, 20, 20, 0, 360 * 64);
+ }
+ /* If we are in position mode we set direction to zero to see where is the */
+ /* target */
+ if (gui_status.posmode)
+ current.heading = 0.0;
+
+ display_status2 ();
+
+ }
+
+
+ /* draw + sign at destination */
+ calcxy (&posxdest, &posydest, coords.target_lon,
+ coords.target_lat, current.zoom);
+ if (local_config.showshadow)
+ {
+ /* draw + sign at destination */
+ draw_posmarker (
+ posxdest + SHADOWOFFSET, posydest + SHADOWOFFSET,
+ 0, &colors.darkgrey, 3, TRUE, FALSE);
+ }
+ if (crosstoggle)
+ draw_posmarker (posxdest, posydest, 0, &colors.blue, 3, FALSE, FALSE);
+ else
+ draw_posmarker (posxdest, posydest, 0, &colors.red, 3, FALSE, FALSE);
+ crosstoggle = !crosstoggle;
+
+
+ /* display messages on map */
+ display_dsc ();
+
+ // TODO: move all status updates to the update function...
+ update_statusdisplay ();
+
+
+
+
+/* if (local_config.normalnull == 0.0)
+
+ g_snprintf (s3, sizeof (s3),
+ "<span color=\"%s\" font_family=\"Arial\" weight=\"bold\" size=\"15000\">%s</span><span color=\"%s\" font_family=\"Arial\" weight=\"bold\" size=\"10000\">%s</span>",
+ local_config.color_dashboard, s2, local_config.color_dashboard, s2a);
+ else
+ g_snprintf (s3, sizeof (s3),
+ "<span color=\"%s\" font_family=\"Arial\" weight=\"bold\" size=\"15000\">%s</span><span color=\"%s\" font_family=\"Arial\" weight=\"bold\" size=\"10000\">%s</span>"
+ "<span color=\"red\" font_family=\"Arial\" weight=\"bold\" size=\"8000\">\nNN %+.1f</span>",
+ local_config.color_dashboard, s2, local_config.color_dashboard, s2a,
+ local_config.normalnull);
+
+*/
+
+ if (current.simmode)
+ blink = TRUE;
+ else
+ {
+ if (current.gpsfix < 2)
+ blink = !blink;
+ }
+
+ if (newsatslevel)
+ expose_gpsfix (NULL, 0);
+
+ if (downloadwindowactive)
+ {
+ drawdownloadrectangle (1);
+ expose_mini_cb (NULL, 0);
+ }
+
+ /* force to say new direction */
+ if (!strcmp (oldangle, "XXX"))
+ speech_out_cb (NULL, 0);
+
+ return (TRUE);
+}
+
+
+/* *****************************************************************************
+ * Copy Image from loaded map
+ */
+gint
+expose_mini_cb (GtkWidget * widget, guint * datum)
+{
+ if (mydebug >50)
+ fprintf (stdout, "expose_mini_cb()\n");
+
+ /* draw the minimap */
+ if (!pixbuf_minimap)
+ return TRUE;
+ if (local_config.guimode == GUI_CAR)
+ return TRUE;
+
+
+ drawable_minimap = drawing_minimap->window;
+ if (!drawable_minimap) {
+ return 0;
+ }
+ kontext_minimap = gdk_gc_new (drawable_minimap);
+
+ if (SMALLMENU == 0)
+ {
+ gdk_draw_pixbuf (drawing_minimap->window,
+ kontext_minimap, pixbuf_minimap, 0, 0, 0, 0, 128, 103,
+ GDK_RGB_DITHER_NONE, 0, 0);
+
+ /* if (local_config.nightmode && (isnight&& !disableisnight)) */
+ /* { */
+ /* gdk_gc_set_function (kontext_minimap, GDK_AND); */
+ /* gdk_gc_set_foreground (kontext_minimap, &colors.nightmode); */
+ /* gdk_draw_rectangle (drawing_minimap->window, kontext_minimap, 1, 0, 0, 128, */
+ /* 103); */
+ /* gdk_gc_set_function (kontext_minimap, GDK_COPY); */
+ /* } */
+ gdk_gc_set_foreground (kontext_minimap, &colors.red);
+ gdk_gc_set_line_attributes (kontext_minimap, 1, 0, 0, 0);
+
+ gdk_draw_rectangle (drawing_minimap->window,
+ kontext_minimap, 0,
+ (64 - (SCREEN_X_2 / 10) / current.zoom) +
+ xoff / (current.zoom * 10),
+ (50 - (SCREEN_Y_2 / 10) / current.zoom) +
+ yoff / (current.zoom * 10),
+ SCREEN_X / (current.zoom * 10),
+ SCREEN_Y / (current.zoom * 10));
+ drawdownloadrectangle (0);
+ }
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ */
+gint
+expose_compass (GtkWidget *widget, guint *datum)
+{
+ gdouble t_x1off, t_y1off, t_x2off, t_y2off;
+ PangoFontDescription *pfd_compass;
+ PangoLayout *layout_compass;
+ gint i, cx, cy, nx, ny, sx, sy, wx, wy, ex, ey;
+ GdkPoint poly[16];
+ gdouble w, b;
+ /* This is the size fo the compass in pixels. Mabye this should
+ * depend on the frame size or the gui mode */
+ const gint size = 100;
+ const gint diam = size/2-12;
+
+ if (mydebug >50)
+ fprintf (stdout, "expose_compass()\n");
+
+ drawable_compass = drawing_compass->window;
+ kontext_compass = gdk_gc_new (drawable_compass);
+ pfd_compass = pango_font_description_from_string ("Sans 8");
+
+ gdk_gc_set_foreground (kontext_compass, &colors.lightorange);
+ gdk_gc_set_line_attributes (kontext_compass, 1, 0, 0, 0);
+ gdk_draw_arc (drawable_compass, kontext_compass, TRUE,
+ 12, 12, size-24, size-24, 0, 360 * 64);
+ gdk_gc_set_foreground (kontext_compass, &colors.black);
+ gdk_draw_arc (drawable_compass, kontext_compass, FALSE,
+ 12, 12, size-24, size-24, 0, 360 * 64);
+ gdk_draw_arc (drawable_compass, kontext_compass, FALSE,
+ 6+size/4, 6+size/4, size/2-12, size/2-12, 0, 360 * 64);
+
+ w = - current.heading;
+
+ t_x1off = cos(w + M_PI_2);
+ t_y1off = sin(w + M_PI_2);
+ t_x2off = cos(w);
+ t_y2off = sin(w);
+ if (t_x1off < 0)
+ {
+ nx = 0; sx = -1;
+ wy = 1; ey = 0;
+ }
+ else
+ {
+ nx = 1; sx = 0;
+ wy = 0; ey = -1;
+ }
+ if (t_y1off < 0)
+ {
+ ny = 0; sy = -1;
+ wx = 0; ex = -1;
+ }
+ else
+ {
+ ny = 1; sy = 0;
+ wx = 1; ex = 0;
+ }
+
+ /* draw compass cross and scale */
+ for (i=0; i<4; i++)
+ {
+ gdk_draw_line (drawable_compass, kontext_compass,
+ size/2+0.8*diam*cos(w+M_PI/4+i*M_PI_2),
+ size/2+0.8*diam*sin(w+M_PI/4+i*M_PI_2),
+ size/2+1.0*diam*cos(w+M_PI/4+i*M_PI_2),
+ size/2+1.0*diam*sin(w+M_PI/4+i*M_PI_2));
+ }
+ gdk_draw_line (drawable_compass, kontext_compass,
+ size/2-diam*t_x2off, size/2-diam*t_y2off,
+ size/2+diam*t_x2off, size/2+diam*t_y2off);
+ gdk_draw_line (drawable_compass, kontext_compass,
+ size/2, size/2,
+ size/2+diam*t_x1off, size/2+diam*t_y1off);
+ gdk_gc_set_foreground (kontext_compass, &colors.green);
+ gdk_gc_set_line_attributes (kontext_compass, 2, 0, 0, 0);
+ gdk_draw_line (drawable_compass, kontext_compass,
+ size/2, size/2,
+ size/2-diam*t_x1off, size/2-diam*t_y1off);
+
+ /* draw direction labels */
+ layout_compass = gtk_widget_create_pango_layout
+ (drawing_compass, _("N"));
+ pango_layout_set_font_description (layout_compass, pfd_compass);
+ pango_layout_get_pixel_size (layout_compass, &cx, &cy);
+ gdk_draw_layout_with_colors ( drawable_compass, kontext_compass,
+ size/2-diam*t_x1off-cx*nx, size/2-diam*t_y1off-cy*ny,
+ layout_compass, &colors.red, NULL);
+
+ pango_layout_set_text (layout_compass, _("S"), -1);
+ pango_layout_get_pixel_size (layout_compass, &cx, &cy);
+ gdk_draw_layout_with_colors ( drawable_compass, kontext_compass,
+ size/2+diam*t_x1off+cx*sx, size/2+diam*t_y1off+cy*sy,
+ layout_compass, &colors.red, NULL);
+
+ pango_layout_set_text (layout_compass, _("W"), -1);
+ pango_layout_get_pixel_size (layout_compass, &cx, &cy);
+ gdk_draw_layout_with_colors ( drawable_compass, kontext_compass,
+ size/2-diam*t_x2off-cx*wx, size/2-diam*t_y2off-cx*wy,
+ layout_compass, &colors.red, NULL);
+
+ pango_layout_set_text (layout_compass, _("E"), -1);
+ pango_layout_get_pixel_size (layout_compass, &cx, &cy);
+ gdk_draw_layout_with_colors ( drawable_compass, kontext_compass,
+ size/2+diam*t_x2off+cx*ex, size/2+diam*t_y2off+cy*ey,
+ layout_compass, &colors.red, NULL);
+
+ if (layout_compass != NULL)
+ g_object_unref (G_OBJECT (layout_compass));
+ pango_font_description_free (pfd_compass);
+
+ /* draw heading pointer */
+ gdk_gc_set_foreground (kontext_compass, &colors.blue);
+ poly[0].x = size/2;
+ poly[0].y = size/2-1.1*diam;
+ poly[1].x = size/2+0.3*diam;
+ poly[1].y = size/2+0.8*diam;
+ poly[2].x = size/2;
+ poly[2].y = size/2+0.6*diam;
+ poly[3].x = size/2-0.3*diam;
+ poly[3].y = size/2+0.8*diam;
+ poly[4].x = poly[0].x;
+ poly[4].y = poly[0].y;
+ gdk_draw_polygon (drawable_compass, kontext_compass, TRUE, poly, 5);
+
+ /* draw bearing pointer */
+ b = current.bearing - current.heading;
+ if (b > 2*M_PI)
+ b -= 2*M_PI;
+ gdk_gc_set_foreground (kontext_compass, &colors.red);
+ poly[0].x = size/2-0.8*diam*cos(b + M_PI_2);
+ poly[0].y = size/2-1.0*diam*sin(b + M_PI_2);
+ poly[1].x = size/2
+ - 0.2*diam*cos(b + M_PI) + 0.6*diam*cos(b + M_PI_2);
+ poly[1].y = size/2
+ - 0.2*diam*sin(b + M_PI) + 0.6*diam*sin(b + M_PI_2);
+ poly[2].x = size/2+0.4*diam*cos(b + M_PI_2);
+ poly[2].y = size/2+0.4*diam*sin(b + M_PI_2);
+ poly[3].x = size/2
+ +0.2*diam*cos(b + M_PI) +0.6*diam*cos(b + M_PI_2);
+ poly[3].y = size/2
+ +0.2*diam*sin(b + M_PI) +0.6*diam*sin(b + M_PI_2);
+ poly[4].x = poly[0].x;
+ poly[4].y = poly[0].y;
+ gdk_draw_polygon (drawable_compass, kontext_compass, TRUE, poly, 5);
+
+return TRUE;
+}
+
+
+/* *****************************************************************************
+ * Copy Image from loaded map
+ */
+gint
+expose_cb (GtkWidget * widget, guint * datum)
+{
+ gint x, y, i, oldxoff, oldyoff, xoffmax, yoffmax, ok, okcount;
+ gdouble tx, ty;
+ gchar name[40], *tn;
+
+ if (mydebug >50) printf ("expose_cb()\n");
+
+ /* g_print("\nexpose_cb %d",exposecounter++); */
+
+ /* fprintf (stderr, "lat: %f long: %f\n", coords.current_lat, coords.current_lon); */
+ if (exposed && local_config.guimode == GUI_PDA)
+ return TRUE;
+
+
+
+ errortextmode = FALSE;
+ if (!current.importactive)
+ {
+ /* We don't need to draw anything if there is no map yet */
+ if (!maploaded)
+ {
+ display_status (_("No map available for this position!"));
+ /* return TRUE; */
+ }
+
+ if (gui_status.posmode)
+ {
+ coords.current_lon = coords.posmode_lon;
+ coords.current_lat = coords.posmode_lat;
+ }
+
+
+ /* get pos for current position */
+ calcxy (&posx, &posy, coords.current_lon,
+ coords.current_lat, current.zoom);
+
+ /* do this because calcxy already substracted xoff and yoff */
+ posx = posx + xoff;
+ posy = posy + yoff;
+
+ /* Calculate Angle to destination */
+ tx = (2 * R * M_PI / 360) * cos (DEG2RAD (coords.current_lat))
+ * (coords.target_lon - coords.current_lon);
+ ty = (2 * R * M_PI / 360)
+ * (coords.target_lat - coords.current_lat);
+ current.bearing = atan (tx / ty);
+
+ if (TRUE)
+ {
+ /* correct the value to be < 2*PI */
+ if (ty < 0)
+ current.bearing += M_PI;
+ if (current.bearing >= (2 * M_PI))
+ current.bearing -= 2 * M_PI;
+ if (current.bearing < 0)
+ current.bearing += 2 * M_PI;
+ }
+
+ if (local_config.showfriends && current.target[0] == '*')
+ for (i = 0; i < maxfriends; i++)
+ {
+ g_strlcpy (name, "*", sizeof (name));
+
+ g_strlcat (name, (friends + i)->name,
+ sizeof (name));
+ tn = g_strdelimit (name, "_", ' ');
+ if ((strcmp (current.target, tn)) == 0)
+ {
+ coordinate_string2gdouble((friends + i)->lat, &coords.target_lat);
+ coordinate_string2gdouble((friends + i)->lon, &coords.target_lon);
+ }
+ }
+
+ /* Calculate distance to destination */
+ current.dist = calcdist (coords.target_lon, coords.target_lat);
+
+ if ( display_background_map() )
+ {
+ /* correct the shift of the map */
+ oldxoff = xoff;
+ oldyoff = yoff;
+ /* now we test if the marker fits into the map and set the shift of the
+ * little SCREEN_XxSCREEN_Y region in relation to the real 1280x1024 map
+ */
+ okcount = 0;
+ do
+ {
+ ok = TRUE;
+ okcount++;
+ x = posx - xoff;
+ y = posy - yoff;
+
+ if (x < borderlimit)
+ xoff -= 2 * borderlimit;
+ if (x > (SCREEN_X - borderlimit))
+ xoff += 2 * borderlimit;
+ if (y < borderlimit)
+ yoff -= 2 * borderlimit;
+ if (y > (SCREEN_Y - borderlimit))
+ yoff += 2 * borderlimit;
+
+ if (x < borderlimit)
+ ok = FALSE;
+ if (x > (SCREEN_X - borderlimit))
+ ok = FALSE;
+ if (y < borderlimit)
+ ok = FALSE;
+ if (y > (SCREEN_Y - borderlimit))
+ ok = FALSE;
+ if (okcount > 2000)
+ {
+ g_print ("\nloop detected, please report!\n");
+ ok = TRUE;
+ }
+ }
+ while (!ok);
+
+ xoffmax = (640 * current.zoom) - SCREEN_X_2;
+ yoffmax = (512 * current.zoom) - SCREEN_Y_2;
+ if (xoff > xoffmax)
+ xoff = xoffmax;
+ if (xoff < -xoffmax)
+ xoff = -xoffmax;
+ if (yoff > yoffmax)
+ yoff = yoffmax;
+ if (yoff < -yoffmax)
+ yoff = -yoffmax;
+
+ /* we only need to create a new region if the shift is not changed */
+ if ((oldxoff != xoff) || (oldyoff != yoff))
+ iszoomed = FALSE;
+ if ( mydebug>30 )
+ {
+ g_print ("x: %d xoff: %d oldxoff: %d Zoom: %d xoffmax: %d\n", x, xoff, oldxoff, current.zoom, xoffmax);
+ g_print ("y: %d yoff: %d oldyoff: %d Zoom: %d yoffmax: %d\n", y, yoff, oldyoff, current.zoom, yoffmax);
+ }
+ posx = posx - xoff;
+ posy = posy - yoff;
+ }
+ }
+
+
+ /* zoom from to 1280x1024 map to the SCREEN_XxSCREEN_Y region */
+ if (!iszoomed)
+ {
+ rebuildtracklist ();
+
+ if (tempimage == NULL)
+ tempimage =
+ gdk_pixbuf_new (GDK_COLORSPACE_RGB, 0, 8,
+ 1280, 1024);
+
+ if (maploaded)
+ {
+ /* g_print ("\nmap loaded, do gdk_pixbuf_scale\n"); */
+ gdk_pixbuf_scale (image, tempimage, 0, 0, 1280, 1024,
+ 640 - xoff - 640 * current.zoom,
+ 512 - yoff - 512 * current.zoom,
+ current.zoom, current.zoom,
+ GDK_INTERP_BILINEAR);
+
+ /* image=gdk_pixbuf_scale_simple(tempimage,640 - xoff - 640 * current.zoom,
+ * 512 - yoff - 512
+ * * current.zoom,
+ * GDK_INTERP_BILINEAR);
+ */
+
+ }
+
+ if ( mydebug > 0 )
+ g_print ("map zoomed!\n");
+ iszoomed = TRUE;
+ expose_mini_cb (NULL, 0);
+
+ }
+
+ gdk_draw_pixbuf (drawable, kontext_map, tempimage,
+ 640 - SCREEN_X_2,
+ 512 - SCREEN_Y_2, 0, 0,
+ SCREEN_X, SCREEN_Y, GDK_RGB_DITHER_NONE, 0, 0);
+
+ if ((!disableisnight) && (!downloadwindowactive))
+ {
+ if (local_config.nightmode && isnight)
+ {
+ gdk_gc_set_function (kontext_map, GDK_AND);
+ gdk_gc_set_foreground (kontext_map, &colors.nightmode);
+ gdk_draw_rectangle (drawable, kontext_map, 1, 0, 0,
+ SCREEN_X, SCREEN_Y);
+ gdk_gc_set_function (kontext_map, GDK_COPY);
+ }
+ }
+
+ drawmarker (0, 0);
+
+ gdk_draw_pixmap (map_drawingarea->window, kontext_map, drawable, 0,
+ 0, 0, 0, SCREEN_X, SCREEN_Y);
+ exposed = TRUE;
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ * This is called in simulation mode, it moves the position to the
+ * selected destination
+ */
+gint
+simulated_pos (GtkWidget * widget, guint * datum)
+{
+ gdouble ACCELMAX, ACCEL;
+ gdouble secs, tx, ty, lastdirection;
+
+ if (mydebug >50) printf ("simulated_pos()\n");
+
+ if (!current.simmode)
+ return TRUE;
+
+ ACCELMAX = 0.00002 + current.dist / 30000.0;
+ ACCEL = ACCELMAX / 20.0;
+ long_diff += ACCEL * sin (current.bearing);
+ lat_diff += ACCEL * cos (current.bearing);
+ if (long_diff > ACCELMAX)
+ long_diff = ACCELMAX;
+ if (long_diff < -ACCELMAX)
+ long_diff = -ACCELMAX;
+ if (lat_diff > ACCELMAX)
+ lat_diff = ACCELMAX;
+ if (lat_diff < -ACCELMAX)
+ lat_diff = -ACCELMAX;
+
+
+ coords.current_lat += lat_diff;
+ coords.current_lon += long_diff;
+ secs = g_timer_elapsed (timer, 0);
+ if (secs >= 1.0)
+ {
+ g_timer_stop (timer);
+ g_timer_start (timer);
+ tx = (2 * R * M_PI / 360) * cos (M_PI * coords.current_lat / 180.0) *
+ (coords.current_lon - coords.old_lon);
+ ty = (2 * R * M_PI / 360) * (coords.current_lat - coords.old_lat);
+#define MINSPEED 1.0
+ if (((fabs (tx)) > MINSPEED) || (((fabs (ty)) > MINSPEED)))
+ {
+ lastdirection = current.heading;
+ if (ty == 0)
+ current.heading = 0.0;
+ else
+ current.heading = atan (tx / ty);
+ if (!finite (current.heading))
+ current.heading = lastdirection;
+
+ if (ty < 0)
+ current.heading = M_PI + current.heading;
+ if (current.heading >= (2 * M_PI))
+ current.heading -= 2 * M_PI;
+ if (current.heading < 0)
+ current.heading += 2 * M_PI;
+ current.groundspeed =
+ milesconv * sqrt (tx * tx +
+ ty * ty) * 3.6 / secs;
+ }
+ else
+ current.groundspeed = 0.0;
+ if (current.groundspeed > 999)
+ current.groundspeed = 999;
+ coords.old_lat = coords.current_lat;
+ coords.old_lon = coords.current_lon;
+ if (mydebug>30)
+ g_print ("Time: %f\n", secs);
+ }
+
+ return TRUE;
+}
+
+
+
+/* *****************************************************************************
+ * switching sat level/sat position display
+ */
+gint
+satpos_cb (GtkWidget * widget, guint datum)
+{
+ satposmode = !satposmode;
+ current.needtosave = TRUE;
+ expose_sats_cb (NULL, 0);
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ * should I use DGPS-IP?
+ */
+gint
+usedgps_cb (GtkWidget * widget, guint datum)
+{
+ usedgps = !usedgps;
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* *****************************************************************************
+ */
+gint
+earthmate_cb (GtkWidget * widget, guint datum)
+{
+ earthmate = !earthmate;
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ */
+gint
+dotripmeter (GtkWidget * widget, guint datum)
+{
+ gdouble d;
+
+ d = calcdist (trip_lon, trip_lat);
+ trip_lon = coords.current_lon;
+ trip_lat = coords.current_lat;
+ if (!((d >= 0.0) && (d < (2000.0 * TRIPMETERTIMEOUT / 3600.0))))
+ {
+ fprintf (stderr,
+ _
+ ("distance jump is more then 2000km/h speed, ignoring\n"));
+ return TRUE;
+ }
+ /* we want always have metric system stored */
+ d /= milesconv;
+ tripodometer += d;
+ if (current.groundspeed / milesconv > tripmaxspeed)
+ tripmaxspeed = current.groundspeed / milesconv;
+ tripavspeedcount++;
+ tripavspeed += current.groundspeed / milesconv;
+ return TRUE;
+}
+
+
+
+
+/* *****************************************************************************
+ * Update the checkbox for Pos-Mode
+ */
+void
+update_posbt()
+{
+ if ( mydebug > 1 )
+ g_print ("posmode=%d\n", gui_status.posmode);
+
+ if (gui_status.posmode)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (posbt), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (posbt), FALSE);
+}
+
+/* ****************************************************************************
+ * toggle checkbox for Pos-Mode
+ */
+gint
+pos_cb (GtkWidget *widget, guint datum)
+{
+
+ if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (posbt)) )
+ gui_status.posmode = TRUE;
+ else
+ gui_status.posmode = FALSE;
+
+ set_cursor_style(CURSOR_DEFAULT);
+
+ /* if waypoint select mode is enabled and waypoint
+ * selected then take target_lat/lon
+ * and save current_lon/lat for cancel */
+ if (setwpactive && selected_wp_mode)
+ {
+ coords.posmode_lon = coords.target_lon;
+ coords.posmode_lat = coords.target_lat;
+ wp_saved_posmode_lon = coords.current_lon;
+ wp_saved_posmode_lat = coords.current_lat;
+ }
+ else
+ {
+ coords.posmode_lon = coords.current_lon;
+ coords.posmode_lat = coords.current_lat;
+ }
+
+ return TRUE;
+}
+
+
+
+/* *****************************************************************************
+ */
+gint
+accepttext (GtkWidget * widget, gpointer data)
+{
+ GtkTextIter start, end;
+ gchar *p;
+
+ gtk_text_buffer_get_bounds (getmessagebuffer, &start, &end);
+
+ gtk_text_buffer_apply_tag_by_name (getmessagebuffer, "word_wrap",
+ &start, &end);
+
+ p = gtk_text_buffer_get_text (getmessagebuffer, &start, &end, FALSE);
+
+ strncpy (messagesendtext, p, 300);
+ messagesendtext[301] = 0;
+ if ( mydebug > 8 )
+ fprintf (stderr, "friends: message:\n%s\n", messagesendtext);
+ gtk_widget_destroy (widget);
+// wi = gtk_item_factory_get_item (item_factory,
+// N_("/Menu/Messages"));
+ statuslock = TRUE;
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar),
+ current.statusbar_id,
+ _("Sending message to friends server..."));
+// gtk_widget_set_sensitive (wi, FALSE);
+ return TRUE;
+}
+
+/* *****************************************************************************
+ */
+gint
+textstatus (GtkWidget * widget, gpointer * datum)
+{
+ gint i;
+ GtkTextIter start, end;
+ gchar str[20];
+
+ gtk_text_buffer_get_bounds (getmessagebuffer, &start, &end);
+ gtk_text_buffer_apply_tag_by_name (getmessagebuffer, "word_wrap",
+ &start, &end);
+ i = gtk_text_iter_get_offset (&end);
+ if (i >= 300)
+ {
+ gdk_beep ();
+ /* gtk_text_buffer_delete (getmessagebuffer, &end-1, &end); */
+ }
+ g_snprintf (str, sizeof (str), "%d/300", i);
+
+ gtk_statusbar_pop (GTK_STATUSBAR (frame_statusbar),
+ current.statusbar_id);
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar),
+ current.statusbar_id, str);
+ return TRUE;
+}
+
+/* *****************************************************************************
+ */
+gint
+setmessage_cb (GtkWidget * widget, guint datum)
+{
+ gchar b[100];
+ gchar *p;
+ int i;
+ gchar titlestr[60];
+ static GtkWidget *window = NULL;
+ GtkWidget *ok, *cancel;
+ GtkWidget *vpaned;
+ GtkWidget *view1;
+ GtkWidget *sw, *hbox, *vbox;
+ GtkTextIter iter;
+ gchar pre[180];
+ time_t t;
+ struct tm *ts;
+
+ p = b;
+
+ gtk_clist_get_text (GTK_CLIST (mylist), datum, 0, &p);
+ g_strlcpy (messagename, p, sizeof (messagename));
+ for (i = 0; (size_t) i < strlen (messagename); i++)
+ if (messagename[i] == ' ')
+ messagename[i] = '_';
+
+ gtk_widget_destroy (GTK_WIDGET (messagewindow));
+
+
+ /* create window to enter text */
+
+ window = gtk_dialog_new ();
+ gtk_window_set_transient_for (GTK_WINDOW (window),
+ GTK_WINDOW (main_window));
+
+ cancel = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+ gtk_signal_connect_object ((GTK_OBJECT (window)), "delete_event",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy),
+ GTK_OBJECT (window));
+ gtk_signal_connect_object ((GTK_OBJECT (window)), "destroy",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy),
+ GTK_OBJECT (window));
+
+ ok = gtk_button_new_from_stock (GTK_STOCK_APPLY);
+ gtk_window_set_default_size (GTK_WINDOW (window), 320, 240);
+ g_snprintf (titlestr, sizeof (titlestr), "%s %s", _("Message for:"),
+ messagename);
+ gtk_window_set_title (GTK_WINDOW (window), titlestr);
+ gtk_container_set_border_width (GTK_CONTAINER (window), 0);
+ vpaned = gtk_vpaned_new ();
+ gtk_container_set_border_width (GTK_CONTAINER (vpaned), 5);
+
+ vbox = gtk_vbox_new (FALSE, 3);
+ hbox = gtk_hbutton_box_new ();
+
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (window)->vbox), vbox, TRUE, TRUE, 2);
+ gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 3);
+
+ /* gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 3); */
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (window)->action_area),
+ hbox, TRUE, TRUE, 2);
+
+ gtk_box_pack_start (GTK_BOX (hbox), ok, TRUE, TRUE, 3);
+ gtk_box_pack_start (GTK_BOX (hbox), cancel, TRUE, TRUE, 3);
+ view1 = gtk_text_view_new ();
+
+ getmessagebuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view1));
+ g_signal_connect (GTK_TEXT_BUFFER (getmessagebuffer),
+ "changed", G_CALLBACK (textstatus), frame_statusbar);
+
+ gtk_text_buffer_get_iter_at_offset (getmessagebuffer, &iter, 0);
+
+ gtk_text_buffer_create_tag (getmessagebuffer, "word_wrap",
+ "wrap_mode", GTK_WRAP_WORD, NULL);
+ gtk_text_buffer_insert_with_tags_by_name (getmessagebuffer, &iter,
+ "", -1, "word_wrap", NULL);
+
+ time (&t);
+ ts = localtime (&t);
+ g_snprintf (pre, sizeof (pre), _("Date: %s"), asctime (ts));
+ gtk_text_buffer_insert (getmessagebuffer, &iter, pre, -1);
+
+ gtk_signal_connect_object ((GTK_OBJECT (ok)), "clicked",
+ GTK_SIGNAL_FUNC (accepttext),
+ GTK_OBJECT (window));
+
+ gtk_signal_connect_object ((GTK_OBJECT (cancel)), "clicked",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy),
+ GTK_OBJECT (window));
+// gtk_tooltips_set_tip (GTK_TOOLTIPS (tooltips), ok,
+// _
+// ("Sends your text to to selected computer using //the friends server"),
+// NULL);
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ gtk_paned_add1 (GTK_PANED (vpaned), sw);
+
+ gtk_container_add (GTK_CONTAINER (sw), view1);
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ gtk_widget_show_all (window);
+
+
+ return TRUE;
+}
+
+
+
+/* *****************************************************************************
+ * Select recipient for message to a mobile target over friendsd
+ */
+gint
+sel_message_cb (GtkWidget * widget, guint datum)
+{
+ GtkWidget *window;
+ gchar *tabeltitel1[] = {
+ _("Name"), _("Latitude"), _("Longitude"), _("Distance"),
+ NULL
+ };
+ GtkWidget *scrwindow, *vbox, *button;
+
+ window = gtk_dialog_new ();
+ /* gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, TRUE); */
+ gtk_window_set_transient_for (GTK_WINDOW (window),
+ GTK_WINDOW (main_window));
+ messagewindow = window;
+ gtk_window_set_title (GTK_WINDOW (window),
+ _("Please select message recipient"));
+
+ gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
+
+ if (local_config.guimode == GUI_PDA)
+ gtk_window_set_default_size (GTK_WINDOW (window),
+ real_screen_x, real_screen_y);
+ else
+ gtk_window_set_default_size (GTK_WINDOW (window), 400, 360);
+
+ mylist = gtk_clist_new_with_titles (4, tabeltitel1);
+
+ gtk_signal_connect_object (GTK_OBJECT
+ (GTK_CLIST (mylist)),
+ "click-column",
+ GTK_SIGNAL_FUNC (setsortcolumn),
+ GTK_OBJECT (window));
+
+ gtk_signal_connect (GTK_OBJECT (GTK_CLIST (mylist)),
+ "select-row",
+ GTK_SIGNAL_FUNC (setmessage_cb),
+ GTK_OBJECT (mylist));
+
+
+ button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+ gtk_window_set_default (GTK_WINDOW (window), button);
+ gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC
+ (gtk_widget_destroy), GTK_OBJECT (window));
+ gtk_signal_connect_object (GTK_OBJECT (window),
+ "delete_event",
+ GTK_SIGNAL_FUNC
+ (gtk_widget_destroy), GTK_OBJECT (window));
+
+ insertwaypoints (TRUE);
+ gtk_clist_set_column_justification (GTK_CLIST (mylist), 3,
+ GTK_JUSTIFY_RIGHT);
+ gtk_clist_set_column_auto_resize (GTK_CLIST (mylist), 0, TRUE);
+ gtk_clist_set_column_auto_resize (GTK_CLIST (mylist), 1, TRUE);
+ gtk_clist_set_column_auto_resize (GTK_CLIST (mylist), 2, TRUE);
+ gtk_clist_set_column_auto_resize (GTK_CLIST (mylist), 3, TRUE);
+
+
+ scrwindow = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (scrwindow), mylist);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW
+ (scrwindow),
+ (GtkPolicyType)
+ GTK_POLICY_AUTOMATIC,
+ (GtkPolicyType) GTK_POLICY_AUTOMATIC);
+ vbox = gtk_vbox_new (FALSE, 2 * PADDING);
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (window)->vbox), vbox, TRUE, TRUE, 2);
+ gtk_box_pack_start (GTK_BOX (vbox), scrwindow, TRUE, TRUE,
+ 2 * PADDING);
+
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (window)->action_area),
+ button, TRUE, TRUE, 2);
+
+ gtk_widget_show_all (window);
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ */
+gint
+sel_target_cb (GtkWidget * widget, guint datum)
+{
+ GtkWidget *window;
+ gchar *tabeltitel1[] = { "#",
+ _("Name"), _("Type"), _("Latitude"), _("Longitude"), _("Distance"),
+ NULL
+ };
+ GtkWidget *scrwindow, *vbox, *button, *hbox, *deletebt;
+ GtkTooltips *tooltips;
+
+ if (setwpactive)
+ return TRUE;
+
+ /* save old target/posmode for cancel event */
+ wp_saved_target_lat = coords.target_lat;
+ wp_saved_target_lon = coords.target_lon;
+ if (gui_status.posmode) {
+ wp_saved_posmode_lat = coords.posmode_lat;
+ wp_saved_posmode_lon = coords.posmode_lon;
+ }
+
+
+ setwpactive = TRUE;
+ window = gtk_dialog_new ();
+ /* gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, TRUE); */
+ gotowindow = window;
+ gtk_window_set_transient_for (GTK_WINDOW (window),
+ GTK_WINDOW (main_window));
+
+ if (datum == 1)
+ {
+ gtk_window_set_modal (GTK_WINDOW (window), TRUE);
+ gtk_window_set_title (GTK_WINDOW (window),
+ _("Select reference point"));
+ }
+ else
+ gtk_window_set_title (GTK_WINDOW (window),
+ _("Please select your destination"));
+ if (local_config.guimode == GUI_PDA)
+ gtk_window_set_default_size (GTK_WINDOW (window),
+ real_screen_x, real_screen_y);
+ else
+ gtk_window_set_default_size (GTK_WINDOW (window), 400, 360);
+
+ mylist = gtk_clist_new_with_titles (6, tabeltitel1);
+ if (datum == 1)
+ gtk_signal_connect (GTK_OBJECT (GTK_CLIST (mylist)),
+ "select-row",
+ GTK_SIGNAL_FUNC (setrefpoint_cb),
+ GTK_OBJECT (mylist));
+ else
+ {
+ gtk_signal_connect (GTK_OBJECT (GTK_CLIST (mylist)),
+ "select-row",
+ GTK_SIGNAL_FUNC (setwp_cb),
+ GTK_OBJECT (mylist));
+ /* gtk_signal_connect (GTK_OBJECT (mylist), "button-release-event", */
+ /* GTK_SIGNAL_FUNC (click_clist), NULL); */
+ }
+
+ gtk_signal_connect (GTK_OBJECT
+ (GTK_CLIST (mylist)),
+ "click-column", GTK_SIGNAL_FUNC (setsortcolumn),
+ 0);
+
+ if (datum != 1)
+ {
+ if (route.active)
+ create_route_button =
+ gtk_button_new_with_label (_("Edit route"));
+ else
+ create_route_button =
+ gtk_button_new_with_label (_("Create route"));
+ GTK_WIDGET_SET_FLAGS (create_route_button, GTK_CAN_DEFAULT);
+ gtk_signal_connect (GTK_OBJECT (create_route_button),
+ "clicked",
+ GTK_SIGNAL_FUNC (create_route_cb), 0);
+ }
+
+ deletebt = gtk_button_new_from_stock (GTK_STOCK_DELETE);
+ GTK_WIDGET_SET_FLAGS (deletebt, GTK_CAN_DEFAULT);
+ gtk_signal_connect (GTK_OBJECT (deletebt), "clicked",
+ GTK_SIGNAL_FUNC (delwp_cb), 0);
+
+ gotobt = gtk_button_new_from_stock (GTK_STOCK_JUMP_TO);
+ GTK_WIDGET_SET_FLAGS (gotobt, GTK_CAN_DEFAULT);
+ gtk_signal_connect (GTK_OBJECT (gotobt), "clicked",
+ GTK_SIGNAL_FUNC (jumpwp_cb), 0);
+ /* disable jump button when in routingmode */
+ if (route.active) gtk_widget_set_sensitive (gotobt, FALSE);
+
+ /* button = gtk_button_new_with_label (_("Close")); */
+ button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+ gtk_window_set_default (GTK_WINDOW (window), button);
+ gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC
+ (sel_targetweg_cb), GTK_OBJECT (window));
+ gtk_signal_connect_object (GTK_OBJECT (window),
+ "delete_event",
+ GTK_SIGNAL_FUNC
+ (sel_targetweg_cb), GTK_OBJECT (window));
+ /* sel_target_destroy event */
+ gtk_signal_connect (GTK_OBJECT(window),
+ "destroy",
+ GTK_SIGNAL_FUNC(sel_target_destroy_cb),
+ 0);
+
+ /* Font aendern falls PDA-Mode und Touchscreen */
+ if (local_config.guimode == GUI_PDA ||
+ local_config.guimode == GUI_CAR )
+ {
+ if (onemousebutton)
+ {
+ /* Change default font throughout the widget */
+ PangoFontDescription *font_desc;
+ font_desc = pango_font_description_from_string ("Sans 20");
+ gtk_widget_modify_font (mylist, font_desc);
+ pango_font_description_free (font_desc);
+ }
+ }
+
+ insertwaypoints (FALSE);
+ gtk_clist_set_column_justification (GTK_CLIST (mylist), 5,
+ GTK_JUSTIFY_RIGHT);
+ gtk_clist_set_column_justification (GTK_CLIST (mylist), 0,
+ GTK_JUSTIFY_RIGHT);
+ gtk_clist_set_column_auto_resize (GTK_CLIST (mylist), 0, TRUE);
+ gtk_clist_set_column_auto_resize (GTK_CLIST (mylist), 1, TRUE);
+ gtk_clist_set_column_auto_resize (GTK_CLIST (mylist), 2, TRUE);
+ gtk_clist_set_column_auto_resize (GTK_CLIST (mylist), 3, TRUE);
+ gtk_clist_set_column_auto_resize (GTK_CLIST (mylist), 4, TRUE);
+ gtk_clist_set_column_auto_resize (GTK_CLIST (mylist), 5, TRUE);
+
+ scrwindow = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (scrwindow), mylist);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW
+ (scrwindow),
+ (GtkPolicyType)
+ GTK_POLICY_AUTOMATIC,
+ (GtkPolicyType) GTK_POLICY_AUTOMATIC);
+ vbox = gtk_vbox_new (FALSE, 2 * PADDING);
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (window)->vbox), vbox, TRUE, TRUE, 2);
+ gtk_box_pack_start (GTK_BOX (vbox), scrwindow, TRUE, TRUE,
+ 2 * PADDING);
+ hbox = gtk_hbutton_box_new ();
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (window)->action_area),
+ hbox, TRUE, TRUE, 2);
+
+ if (datum != 1)
+ {
+ gtk_box_pack_start (GTK_BOX (hbox), create_route_button, TRUE,
+ TRUE, 2 * PADDING);
+ gtk_box_pack_start (GTK_BOX (hbox), deletebt, TRUE, TRUE,
+ 2 * PADDING);
+ gtk_box_pack_start (GTK_BOX (hbox), gotobt, TRUE, TRUE,
+ 2 * PADDING);
+ }
+ gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 2 * PADDING);
+ /* gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER); */
+
+ /* I remove this, because you can sort by mouseclick now */
+ /* selwptimeout = gtk_timeout_add (30000, (GtkFunction) reinsertwp_cb, 0); */
+ tooltips = gtk_tooltips_new ();
+ if (!route.edit)
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (tooltips),
+ create_route_button,
+ _
+ ("Create a route using some waypoints from this list"),
+ NULL);
+ if (setwpactive)
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (tooltips), deletebt,
+ _
+ ("Delete the selected waypoint from the waypoint list"),
+ NULL);
+ if (setwpactive)
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (tooltips), gotobt,
+ _("Jump to the selected waypoint"),
+ NULL);
+
+ gtk_widget_show_all (window);
+
+ return TRUE;
+}
+
+
+
+/* *****************************************************************************
+ */
+void
+usage ()
+{
+
+ g_print ("%s%s%s%s%s%s%s%s"
+#ifdef DBUS_ENABLE
+ "%s"
+#endif
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ "\nCopyright (c) 2001-2006 Fritz Ganter <ganter@ganter.at>"
+ "\n Website: http://www.gpsdrive.de\n\n",
+ _("-v show version\n"),
+ _("-h print this help\n"),
+ _("-d turn on debug info\n"),
+ _("-D X set debug Level to X\n"),
+ _("-T do some internal unit Tests(don't start gpsdrive)\n"),
+ _("-e use Festival-Lite (flite) for speech output\n"),
+ _("-o serial device, pty master, or file for NMEA *output*\n"),
+ _("-f X Select friends server, X is i.e. friendsd.gpsdrive.de\n"),
+#ifdef DBUS_ENABLE
+ _("-X Use DBUS for communication with gpsd. This disables serial and socket communication\n"),
+#endif
+ _("-l LANG Select language of the voice,\n"
+ " LANG may be english, spanish or german\n"),
+ _("-s HEIGHT set height of the screen, if autodetection\n"
+ " don't satisfy you, X is i.e. 768,600,480,200\n"),
+ _("-r WIDTH set width of the screen, only with -s\n"),
+ _("-1 have only 1 button mouse, for example using touchscreen\n"),
+ _("-a display APM Stuff ( battery status, Temperature)\n"),
+ _("-b Server Servername for NMEA server (if gpsd runs on another host)\n"),
+ _("-c WP set start position in simulation mode to waypoint name WP\n"),
+ _("-x create separate window for menu\n"),
+ _("-M mode set guimode to desktop, pda or car\n"),
+ _("-i ignore NMEA checksum (risky, only for broken GPS receivers\n"),
+ _("-q disable SQL support\n"),
+ _("-F force display of position even it is invalid\n"),
+ _("-S don't show splash screen\n"),
+ _("-P start in Pos Mode\n"),
+ _("-W x set x to 1 to switch WAAS/EGNOS on, set to 0 to switch off\n"),
+ _("-H ALT correct altitude, adding this value (ALT) to altitude\n"),
+ _("-C file set config file (--config-file)\n"));
+
+}
+
+/* *****************************************************************************
+ * Load track file and displays it
+ */
+gint
+loadtrack_cb (GtkWidget * widget, gpointer datum)
+{
+ GtkWidget *fdialog;
+ gchar buf[1000];
+ GtkWidget *ok_button;
+ GtkWidget *cancel_button;
+
+ fdialog = gtk_file_chooser_dialog_new (_("Select a track file"),
+ GTK_WINDOW (main_window),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ NULL, NULL);
+
+ gtk_window_set_modal (GTK_WINDOW (fdialog), TRUE);
+
+ cancel_button = gtk_dialog_add_button (GTK_DIALOG (fdialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ ok_button = gtk_dialog_add_button (GTK_DIALOG (fdialog), GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT);
+
+ gtk_signal_connect (GTK_OBJECT
+ (ok_button),
+ "clicked", GTK_SIGNAL_FUNC (gettrackfile),
+ GTK_OBJECT (fdialog));
+ gtk_signal_connect_object (GTK_OBJECT
+ (cancel_button), "clicked",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy),
+ GTK_OBJECT (fdialog));
+
+
+ g_strlcpy (buf, local_config.dir_home, sizeof (buf));
+ g_strlcat (buf, "tracks/", sizeof (buf));
+ g_strlcat (buf, "track*.sav", sizeof (buf));
+
+ gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (fdialog), buf);
+
+ gtk_widget_show (fdialog);
+
+ return TRUE;
+}
+
+/* *****************************************************************************
+ * on a USR2 signal, re-start the GPS connection
+ */
+void
+usr2handler (int sig)
+{
+ g_print ("\ngot SIGUSR2\n");
+ initgps ();
+}
+
+/*
+ * parse command arguments
+ */
+int
+parse_cmd_args(int argc, char *argv[], gint *screen_height, gint *screen_width) {
+ int i = 0;
+ /* parse cmd args */
+ /* long options for use of --geometry and -g */
+ int option_index = 0;
+ static struct option long_options[] =
+ {
+ {"geometry", required_argument, 0, 'g'},
+ {"config-file", required_argument, 0, 'C'},
+ {0, 0, 0, 0}
+ };
+ do
+ {
+ /* long options plus --geometry and -g */
+ i = getopt_long (argc, argv,
+ "W:ESA:ab:c:X1qivPdD:TFepC:H:hnf:l:t:s:o:r:g:M:?",
+ long_options, &option_index);
+ switch (i)
+ {
+ case 'C':
+ g_strlcpy(local_config.config_file, optarg, sizeof(local_config.config_file));
+ if (!g_file_test(local_config.config_file, G_FILE_TEST_EXISTS)) {
+ fprintf(stderr,"Config file '%s' not found.\n", local_config.config_file);
+ exit(-1);
+ }
+ case 'a':
+ local_config.enableapm = TRUE;
+ break;
+ case 'S':
+ nosplash = TRUE;
+ break;
+ case 'E':
+ nmeaverbose = TRUE;
+ break;
+ case 'q':
+ usesql = FALSE;
+ break;
+ case 'd':
+ debug = TRUE;
+ break;
+ case 'D':
+ mydebug = strtol (optarg, NULL, 0);
+ debug = TRUE;
+ break;
+ case 'T':
+ do_unit_test = TRUE;
+ break;
+ case 'e':
+ useflite = TRUE;
+ break;
+ case 'i':
+ ignorechecksum = TRUE;
+ g_print ("\nWARNING: NMEA checksum test switched off!\n\n");
+ break;
+ case 'X':
+#ifdef DBUS_ENABLE
+ useDBUS = TRUE;
+#else
+ g_print ("\nWARNING: You need to enable DBUS support with './configure --enable-dbus'!\n");
+#endif
+ break;
+ case 'M':
+ if (!strcmp(optarg, "desktop"))
+ local_config.guimode = GUI_DESKTOP;
+ else if (!strcmp(optarg, "car"))
+ local_config.guimode = GUI_CAR;
+ else if (!strcmp(optarg, "pda"))
+ local_config.guimode = GUI_PDA;
+ else {
+ fprintf(stderr,"%s-mode not supported.\n", optarg);
+ exit(-1);
+ }
+ break;
+ case '1':
+ onemousebutton = TRUE;
+ break;
+ case 'v':
+ printf ("\ngpsdrive (c) 2001-2006 Fritz Ganter <ganter@ganter.at>\n" "\nVersion %s\n%s\n\n", VERSION, rcsid);
+ exit (0);
+ break;
+ case 'b':
+ g_strlcpy (gpsdservername, optarg,
+ sizeof (gpsdservername));
+ break;
+ case 'c':
+ g_strlcpy (setpositionname, optarg,
+ sizeof (setpositionname));
+ break;
+ case 'f':
+ break;
+ case 's':
+ *screen_height = strtol (optarg, NULL, 0);
+ break;
+ case 'W':
+ switch (strtol (optarg, NULL, 0))
+ {
+ case 0:
+ egnosoff = TRUE;
+ break;
+ case 1:
+ egnoson = TRUE;
+ break;
+ }
+ break;
+ case 'l':
+ if (!strcmp (optarg, "english"))
+ voicelang = english;
+ else if (!strcmp (optarg, "german"))
+ voicelang = german;
+ else if (!strcmp (optarg, "spanish"))
+ voicelang = spanish;
+ else
+ {
+ usage ();
+ g_print (_
+ ("\nYou can currently only choose between "
+ "english, spanish and german\n\n"));
+ exit (0);
+ }
+ break;
+ case 'o':
+ nmeaout = opennmea (optarg);
+ break;
+ case 'h':
+ usage ();
+ exit (0);
+ break;
+ case 'H':
+ local_config.normalnull = strtol (optarg, NULL, 0);
+ break;
+ case '?':
+ usage ();
+ exit (0);
+ break;
+ case 'r':
+ *screen_width = strtol (optarg, NULL, 0);
+ break;
+ case 'F':
+ forcehavepos = TRUE;
+ break;
+ case 'P':
+ gui_status.posmode = TRUE;
+ break;
+ /* Allows command line declaration of -g or --geometry */
+ case 'g':
+ g_strlcpy (geometry, optarg, sizeof (geometry));
+ usegeometry = TRUE;
+ break;
+ }
+ }
+ while (i != -1);
+ return 0;
+}
+
+
+/*******************************************************************************
+ * *
+ * Main program *
+ * *
+ *******************************************************************************/
+int
+main (int argc, char *argv[])
+{
+
+ gchar buf[500];
+
+ current.needtosave = FALSE;
+
+ gint i, screen_height, screen_width;
+
+ struct tm *lt;
+ time_t local_time, gmt_time;
+ /* GtkAccelGroup *accel_group; */
+
+ gdouble f;
+
+ tzset ();
+ gmt_time = time (NULL);
+
+ lt = gmtime (&gmt_time);
+ local_time = mktime (lt);
+ zone = lt->tm_isdst + (gmt_time - local_time) / 3600;
+ /* fprintf(stderr,"\n zeitzone: %d\n",zone); */
+
+
+ /* zone = st->tm_gmtoff / 3600; */
+ /* initialize variables */
+ /* Munich */
+ srand (gmt_time);
+ f = 0.02 * (0.5 - rand () / (RAND_MAX + 1.0));
+ coords.current_lat = coords.zero_lat = 48.13706 + f;
+ f = 0.02 * (0.5 - rand () / (RAND_MAX + 1.0));
+ coords.current_lon = coords.zero_lon = 11.57532 + f;
+ /* zero_lat and zero_lon are overwritten by config file, */
+ tripreset ();
+
+ g_strlcpy (dgpsserver, "dgps.wsrcc.com", sizeof (dgpsserver));
+ g_strlcpy (dgpsport, "2104", sizeof (dgpsport));
+ g_strlcpy (gpsdservername, "127.0.0.1", sizeof (gpsdservername));
+ g_strlcpy (current.target, " ", sizeof (current.target));
+ g_strlcpy (utctime, "n/a", sizeof (utctime));
+ g_strlcpy (oldangle, "none", sizeof (oldangle));
+ pixelfact = MAPSCALE / PIXELFACT;
+ g_strlcpy (oldfilename, "", sizeof (oldfilename));
+ maploaded = FALSE;
+ haveNMEA = FALSE;
+ current.gpsfix = 0;
+ gblink = blink = FALSE;
+ haveposcount = debug = 0;
+ current.heading = current.bearing = 0.0;
+ current.zoom = 1;
+ iszoomed = FALSE;
+#ifdef DBUS_ENABLE
+ useDBUS = FALSE;
+#endif
+
+
+
+
+ signal (SIGUSR2, usr2handler);
+ timer = g_timer_new ();
+ disttimer = g_timer_new ();
+ g_timer_start (timer);
+ g_timer_start (disttimer);
+ memset (satlist, 0, sizeof (satlist));
+ memset (satlistdisp, 0, sizeof (satlist));
+ buffer = g_new (char, 2010);
+ big = g_new (char, MAXBIG + 10);
+
+ timeoutcount = lastp = bigp = bigpRME = bigpGSA = bigpGSV = bigpGGA = 0;
+ lastp = lastpGGA = lastpGSV = lastpRME = lastpGSA = 0;
+ gcount = xoff = yoff = 0;
+ hours = minutes = 99;
+ milesconv = 1.0;
+ g_strlcpy (messagename, "", sizeof (messagename));
+ g_strlcpy (messageack, "", sizeof (messageack));
+ g_strlcpy (messagesendtext, "", sizeof (messagesendtext));
+
+ downloadwindowactive = downloadactive = current.importactive = FALSE;
+ g_strlcpy (lastradar, "", sizeof (lastradar));
+ g_strlcpy (lastradar2, "", sizeof (lastradar2));
+ g_strlcpy (dbhost, "localhost", sizeof (dbhost));
+ g_strlcpy (dbuser, "gast", sizeof (dbuser));
+ g_strlcpy (dbpass, "gast", sizeof (dbpass));
+ g_strlcpy (dbname, "geoinfo", sizeof (dbname));
+ g_strlcpy (dbtable, "poi", sizeof (dbtable));
+ g_strlcpy (wlantable, "wlan", sizeof (wlantable));
+ g_strlcpy (poitypetable, "poi_type", sizeof (poitypetable));
+ dbdistance = 2000.0;
+ dbusedist = TRUE;
+ g_strlcpy (loctime, "n/a", sizeof (loctime));
+ voicelang = english;
+ track = g_new0 (GdkSegment, 100000);
+ trackshadow = g_new0 (GdkSegment, 100000);
+ tracknr = 0;
+ trackcoord = g_new0 (trackcoordstruct, 100000);
+ trackcoordnr = 0;
+ tracklimit = trackcoordlimit = 100000;
+ init_route_list ();
+
+ earthr = calcR (coords.current_lat);
+
+ /* all default values must be set BEFORE readconfig! */
+ g_strlcpy (setpositionname, "", sizeof (setpositionname));
+
+ /* setup signal handler */
+ signal (SIGUSR1, signalposreq);
+
+ sql_load_lib();
+ /* I18l */
+
+ /* Detect the language for voice output */
+ {
+ gchar **lstr, lstr2[200];
+ gchar *localestring;
+
+ localestring = setlocale (LC_ALL, "");
+ if (localestring == NULL)
+ localestring = setlocale (LC_MESSAGES, "");
+ if (localestring != NULL)
+ {
+ lstr = g_strsplit (localestring, ";", 50);
+ g_strlcpy (lstr2, "", 50);
+ for (i = 0; i < 50; i++)
+ if (lstr[i] != NULL)
+ {
+ if ((strstr (lstr[i], "LC_MESSAGES")) != NULL)
+ {
+ g_strlcpy (lstr2, lstr[i], 50);
+ break;
+ }
+ }
+ else
+ {
+ g_strlcpy (lstr2, lstr[i - 1], 50);
+ break;
+ }
+ g_strfreev (lstr);
+ }
+
+ /* detect voicelang */
+ if ((strstr (lstr2, "de_")) != NULL)
+ voicelang = german;
+ else if ((strstr (lstr2, "es_")) != NULL)
+ voicelang = spanish;
+ else
+ voicelang = english;
+
+ /* get language, used for POI titles and descriptions */
+ if (!g_strlcpy (language,lstr2,3))
+ g_strlcpy (language, "en", sizeof(language));
+
+ /* needed for right decimal delimiter ('.' or ',') */
+ // setlocale(LC_NUMERIC, "en_US");
+ setlocale(LC_NUMERIC, "C");
+ }
+
+ /* init config struct with default values */
+ config_init ();
+
+ check_and_create_files();
+
+ /* we need to parse command args 2 times, because we need the config file param */
+ parse_cmd_args(argc, argv, &screen_height, &screen_width);
+
+ /* update config struct with settings from config file if possible */
+ readconfig ();
+
+ if (local_config.simmode == SIM_ON)
+ current.simmode = TRUE;
+
+ real_screen_x = 640;
+ real_screen_y = 512;
+ coords.target_lon = coords.current_lon + 0.00001;
+ coords.target_lat = coords.current_lat + 0.00001;
+
+
+ /* load waypoints before locale is set! */
+ /* Attention! In this file the decimal point is always a '.' !! */
+
+ /* load mapfile configurations */
+ /* Attention! In this file the decimal point is that what locale says,
+ * i.e. '.' in english, ',' in german!!
+ */
+ loadmapconfig ();
+
+ /* PORTING */
+ {
+ gchar *p;
+ p = bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ bind_textdomain_codeset (PACKAGE, "utf8");
+ p = textdomain (GETTEXT_PACKAGE);
+ p = textdomain (NULL);
+ }
+
+ /* Setting locale for correct Umlauts */
+ gtk_set_locale ();
+
+ /* initialization for GTK+ */
+ gtk_init (&argc, &argv);
+
+ /* Needed 4 hours to find out that this is IMPORTANT!!!! */
+ gdk_rgb_init ();
+ screen_height = gdk_screen_height ();
+ if ( mydebug >5 )
+ fprintf(stderr , "gdk screen height : %d\n", screen_height);
+ screen_width = gdk_screen_width ();
+ if ( mydebug >5 )
+ fprintf(stderr , "gdk screen width : %d\n", screen_width);
+
+ /* 2. run see comment at first run */
+ parse_cmd_args(argc, argv, &screen_height, &screen_width);
+
+ if ( mydebug >99 )
+ fprintf(stderr , "options parsed\n");
+
+ /* print version info */
+ if ( mydebug > 0 )
+ printf ("\ngpsdrive (c) 2001-2006 Fritz Ganter"
+ " <ganter@ganter.at>\n\nVersion %s\n%s\n\n", VERSION, rcsid);
+
+ /* show splash screen */
+ if (!nosplash)
+ show_splash ();
+
+ init_lat2RadiusArray();
+
+ gethostname (hostname, 256);
+ proxyport = 80;
+ haveproxy = FALSE;
+
+ get_proxy_from_env();
+
+ { // Set locale for the use of atof()
+ gchar buf[5];
+ sprintf(buf,"%.1f",1.2);
+ localedecimal=buf[1];
+ }
+
+ /* init sql support */
+ if (usesql)
+ usesql = sqlinit ();
+
+ /* Create toplevel window */
+
+ get_window_sizing (geometry, usegeometry, screen_height, screen_width);
+
+ if ( mydebug >19 )
+ fprintf(stderr , "screen size %d,%d\n",SCREEN_X,SCREEN_Y);
+
+ if (!useflite)
+ havespeechout = speech_out_init ();
+ else
+ havespeechout = TRUE;
+
+ if (!useflite)
+ switch (voicelang)
+ {
+ case english:
+ speech_out_speek_raw (FESTIVAL_ENGLISH_INIT);
+ break;
+ case spanish:
+ speech_out_speek_raw (FESTIVAL_SPANISH_INIT);
+ break;
+ case german:
+ speech_out_speek_raw (FESTIVAL_GERMAN_INIT);
+ break;
+ }
+
+ if (usesql)
+ {
+ getsqldata ();
+ }
+ else
+ loadwaypoints ();
+
+
+ /* set start position for simulation mode
+ * (only available in waypoints mode) */
+ if (strlen (setpositionname) > 0 && !usesql)
+ {
+ for (i = 0; i < maxwp; i++)
+ {
+ if (!(strcasecmp ((wayp + i)->name, setpositionname)))
+ {
+ coords.current_lat = (wayp + i)->lat;
+ coords.current_lon = (wayp + i)->lon;
+ coords.target_lon = coords.current_lon + 0.001;
+ coords.target_lat = coords.current_lat + 0.001;
+ }
+ }
+ }
+
+
+ /* gtk_window_set_default (GTK_WINDOW (main_window), zoomin_bt); */
+ /* if we want NMEA mode, gpsd must be running and we connect to port 2222 */
+ /* An alternate gpsd server may be on 2947, we try it also */
+
+ initgps ();
+
+ if (usesql)
+ {
+ initkismet ();
+ get_poi_type_id_for_wlan();
+ };
+
+
+ if( havekismet )
+ {
+ g_print (_("\nkismet server found\n"));
+ g_snprintf( buf, sizeof(buf), speech_kismet_found[voicelang] );
+ speech_out_speek (buf);
+ }
+
+
+
+
+ // Frame --- Sat levels
+ /* Area for field strength, we have data only in NMEA mode */
+// gtk_signal_connect (GTK_OBJECT (drawing_sats), "expose_event",
+// GTK_SIGNAL_FUNC (expose_sats_cb), NULL);
+// gtk_widget_add_events (GTK_WIDGET (drawing_sats),
+// GDK_BUTTON_PRESS_MASK);
+// gtk_signal_connect (GTK_OBJECT (drawing_sats), "button-press-event",
+// GTK_SIGNAL_FUNC (satpos_cb), NULL);
+
+
+ /* all position calculations are made in the expose callback */
+// g_signal_connect (GTK_OBJECT (map_drawingarea),
+// "expose_event", GTK_SIGNAL_FUNC (expose_cb), NULL);
+
+
+#ifdef MAPNIK
+ /*
+ * init mapnik before gui
+ */
+ if (gen_mapnik_config_xml_ysn(local_config.mapnik_xml_file, (char*) g_get_user_name())) {
+ init_mapnik(local_config.mapnik_xml_file);
+ } else {
+ fprintf(stderr,"Could not init Mapnik!\n");
+ local_config.MapnikStatusInt = 0; // <-- disable mapnik
+ }
+#endif
+
+
+ if (havespeechout)
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar),
+ current.statusbar_id, _("Using speech output"));
+
+ //temperature_get_values ();
+ //battery_get_values ();
+
+ g_strlcpy (mapfilename, "***", sizeof (mapfilename));
+ /* set the timers */
+ timerto =
+ gtk_timeout_add (TIMER,
+ (GtkFunction) get_position_data_cb,
+ NULL);
+ gtk_timeout_add (WATCHWPTIMER, (GtkFunction) watchwp_cb, NULL);
+
+ redrawtimeout =
+ gtk_timeout_add (200, (GtkFunction) calldrawmarker_cb, NULL);
+
+ /* if we started in simulator mode we have a little move roboter */
+ if (current.simmode)
+ simpos_timeout =
+ gtk_timeout_add (300, (GtkFunction) simulated_pos, 0);
+ if (nmeaout)
+ gtk_timeout_add (1000, (GtkFunction) write_nmea_cb, NULL);
+ gtk_timeout_add (10000, (GtkFunction) testconfig_cb, 0);
+ gtk_timeout_add (600000, (GtkFunction) speech_saytime_cb, 0);
+ gtk_timeout_add (1000, (GtkFunction) storetrack_cb, 0);
+ gtk_timeout_add (10000, (GtkFunction) masteragent_cb, 0);
+ gtk_timeout_add (15000, (GtkFunction) getsqldata, 0);
+// if ( battery_get_values () )
+// gtk_timeout_add (5000, (GtkFunction) expose_display_battery,
+// NULL);
+
+// if ( temperature_get_values () )
+// gtk_timeout_add (5000, (GtkFunction) expose_display_temperature,
+// NULL);
+
+ gtk_timeout_add (15000, (GtkFunction) friendsagent_cb, 0);
+
+ if (havespeechout)
+ {
+ speech_saytime_cb (NULL, 1);
+ gtk_timeout_add (SPEECHOUTINTERVAL,
+ (GtkFunction) speech_out_cb, 0);
+ }
+
+ current.needtosave = FALSE;
+
+ /* do all the basic initalisation for the specific sections */
+ poi_init ();
+ gui_init ();
+ friends_init ();
+ route_init ();
+
+ wlan_init ();
+
+ load_friends_icon ();
+
+ update_posbt();
+
+ /*
+ * setup TERM signal handler so that we can save evrything nicely when the
+ * machine is shutdown.
+ */
+ void termhandler (int sig)
+ {
+ gtk_main_quit ();
+ }
+ signal (SIGTERM, termhandler);
+
+
+ /* gtk2 requires these functions in the order below do not change */
+ if (usegeometry) {
+ GdkGeometry size_hints = {200, 200, 0, 0, 200, 200, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST};
+
+ gtk_window_set_geometry_hints(GTK_WINDOW (main_window), main_window, &size_hints,
+ GDK_HINT_MIN_SIZE |
+ GDK_HINT_BASE_SIZE |
+ GDK_HINT_RESIZE_INC);
+
+ if (!gtk_window_parse_geometry(GTK_WINDOW (main_window), geometry)) {
+ fprintf(stderr, "Failed to parse %s\n", geometry);
+ }
+ }
+
+ // ==================================================================
+ // Unit Tests
+ if ( do_unit_test ) {
+ unit_test();
+ }
+
+ /* Mainloop */
+ gtk_main ();
+
+
+ g_timer_destroy (timer);
+ writeconfig ();
+ gdk_pixbuf_unref (friendspixbuf);
+
+
+ unlink ("/tmp/cammain.pid");
+ unlink ("/tmp/gpsdrivetext.out");
+ unlink ("/tmp/gpsdrivepos");
+ if (local_config.savetrack)
+ savetrackfile (2);
+ sqlend ();
+ free (friends);
+ free (fserver);
+ free_route_list ();
+ if (kismetsock != -1)
+ close (kismetsock);
+ gpsd_close();
+ if (sockfd != -1)
+ close (sockfd);
+ speech_out_close ();
+ cleanup_nasa_mapfile ();
+ fprintf (stderr, _("\n\nThank you for using GpsDrive!\n\n"));
+
+ if ( do_unit_test ) {
+ printf ("\n\nAll Unit Tests successfull\n\n");
+ exit(0);
+ }
+
+ return 0;
+}
diff --git a/src/gpsdrive.h b/src/gpsdrive.h
new file mode 100644
index 0000000..792a437
--- /dev/null
+++ b/src/gpsdrive.h
@@ -0,0 +1,418 @@
+/***********************************************************************
+
+Copyright (c) 2001,2002 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+***********************************************************************/
+
+#ifndef GPSDRIVE_GPSDRIVE_H
+#define GPSDRIVE_GPSDRIVE_H
+
+#include <gmodule.h>
+#include <gdk/gdktypes.h>
+#include "gtk/gtk.h"
+#include "mysql/mysql.h"
+#include "gpsproto.h"
+
+/* adapt this section for the size of your screen */
+
+/* width of the map on screen, default is 640 */
+#define SCREEN_X real_screen_x
+/* height of the map on screen, default is 512 */
+#define SCREEN_Y real_screen_y
+
+/* set this to 0 for normal use, 1 for small screens */
+#define SMALLMENU real_smallmenu
+/*** Mod by Arms */
+#define PADDING 1
+/*** Mod by Arms */
+#define XMINUS 60
+/*** Mod by Arms (move) */
+#define YMINUS 67
+
+/*** Number of elements in an array */
+#define ARRAY_SIZE(x) ((sizeof (x))/(sizeof ((x)[0])))
+
+
+/* Coordinate formats */
+enum
+{
+ LATLON_DEGDEC,
+ LATLON_DMS,
+ LATLON_MINDEC,
+ LATLON_N_FORMATS
+};
+
+/* Distance formats */
+enum
+{
+ DIST_MILES,
+ DIST_METRIC,
+ DIST_NAUTIC,
+ DIST_N_FORMATS
+};
+
+/* Altitude formats */
+enum
+{
+ ALT_FEET,
+ ALT_METERS,
+ ALT_YARDS,
+ ALT_N_FORMATS
+};
+
+/* Nightmode settings */
+enum
+{
+ NIGHT_OFF,
+ NIGHT_ON,
+ NIGHT_AUTO,
+};
+
+/* Simulationmode settings */
+enum
+{
+ SIM_OFF,
+ SIM_ON,
+ SIM_AUTO,
+};
+
+/* Definiton for travelmode used in local_config */
+enum
+{
+ TRAVEL_CAR,
+ TRAVEL_BIKE,
+ TRAVEL_WALK,
+ TRAVEL_BOAT,
+ TRAVEL_AIRPLANE,
+ TRAVEL_N_MODES
+};
+
+/* GUI Modes */
+enum
+{
+ GUI_DESKTOP,
+ GUI_PDA,
+ GUI_XWIN,
+ GUI_CAR,
+ GUI_N_FORMATS
+};
+
+
+/* size of the bearing pointer, default is 50 */
+//#define PSIZE real_psize
+
+
+/***************************************************************************/
+/***************************************************************************/
+/***************************************************************************/
+
+#define MAXBIG 50000
+
+/* How often do we redraw the screen (in milliseconds) */
+#define REDRAWTIMER 300
+/* How often do we ask for positioning data */
+#define TIMER 500
+
+#define MAXSHOWNWP 100
+
+/* timer for watching waypoints (Radar) */
+#define WATCHWPTIMER 2000
+
+/* If speech output is used, the intervall of spoken messages in milliseconds */
+#define SPEECHOUTINTERVAL 10000
+
+/* defines offset and color of the shadows */
+#define SHADOWOFFSET 7
+
+#define ROUTEREACH (0.02+10*current.groundspeed/(3600*milesconv))
+/* #define ROUTEREACH 0.05 */
+
+#define SERVERNAME gpsdservername
+
+#define SERVERPORT 2222
+#define SERVERPORT2 2947
+
+
+#define MAPSCALE 20000
+/* Mapscale / pixelfact is meter / pixel */
+#define PIXELFACT 2817.947378
+#define KM2MILES 0.62137119 /* international_mile / km */
+#define KM2NAUTIC 0.5399568 /* nautic_mile / km */
+
+#define MAXMESG 8192
+
+
+#define LOCALTESTXXX
+#ifdef LOCALTEST
+#define WEBSERVER "wuffi.ganter.at"
+#else
+// R.I.P. Borged by Microsoft, April, 2003:
+// #define WEBSERVER "www.mapblast.com"
+#define WEBSERVER "www.vicinity.com"
+#endif
+/* #define WEBSERVER2 "msrvmaps.mappoint.net" */
+#define WEBSERVER2 "www.expedia.com"
+#define WEBSERVER3 "host21.216.235.245.nedatavault.net"
+#define WEBSERVER4 "www.expedia.de"
+
+#define FESTIVAL_ENGLISH_INIT "(voice_ked_diphone)\n"
+#define FESTIVAL_GERMAN_INIT "(voice_german_de3_os)\n"
+#define FESTIVAL_SPANISH_INIT "(voice_el_diphone)\n"
+#define EXPEDIAFACT 3950
+/* #define EXPEDIAFACT 1378.6 */
+#define MAXLISTENTRIES 500
+#define TRIPMETERTIMEOUT 5
+
+#define USIZE_X 15
+#define USIZE_Y 24
+
+/*
+$PSRF103,05,00,00,01*21 VTG off
+$PSRF103,05,00,01,01*20 VTG on
+$PSRF108,1*33 WAAS/EGNOS on
+$PSRF108,0*32 WAAS/EGNOS off
+
+*/
+#define EGNOSON "$PSRF108,1*33\r\n"
+#define EGNOSOFF "$PSRF108,0*32\r\n"
+
+
+/* highest satellite number
+ * WAAS/EGNOS sats are higher than the others.
+ * Current highest known is "Anik" PRN=138
+ * GPGSV (should) reports PRN number, so MAXSATS refers to PRN as well.
+ * note SatID = PRN-87.
+ */
+#define MAXSATS 160
+
+
+/* Maximum number of waypoint types and also userdefined icons */
+#define MAXPOITYPES 500
+
+#define MAXDBNAME 30
+
+#define TOOLTIP_DELAY 1000
+
+#define DEG2RAD(x) (x*M_PI/180.0)
+#define RAD2DEG(x) (x/M_PI*180.0)
+
+#define ZOOM_MIN 1
+#define ZOOM_MAX 16
+
+#define DEGREE "\xc2\xb0"
+
+/*
+ * Declarations.
+ */
+
+extern gchar savetrackfn[256];
+
+extern gint real_screen_x;
+extern gint real_screen_y;
+
+extern GdkGC *kontext;
+extern GdkDrawable *drawable;
+extern GtkWidget *track_bt;
+
+
+gint line_crosses_rectangle(gdouble li_lat1, gdouble li_lon1, gdouble li_lat2, gdouble li_lon2,
+ gdouble sq_lat1, gdouble sq_lon1, gdouble sq_lat2, gdouble sq_lon2);
+gdouble distance_line_point(gdouble x1, gdouble y1, gdouble x2, gdouble y2,
+ gdouble xp, gdouble yp);
+
+
+char * (*dl_mysql_error)(MYSQL *mysql);
+MYSQL * (*dl_mysql_init)(MYSQL *mysql);
+MYSQL * (*dl_mysql_real_connect)(MYSQL *mysql, const char *host,
+ const char *user,
+ const char *passwd,
+ const char *db,
+ unsigned int port,
+ const char *unix_socket,
+ unsigned int clientflag);
+void (*dl_mysql_close)(MYSQL *sock);
+int (*dl_mysql_query)(MYSQL *mysql, const char *q);
+my_ulonglong (*dl_mysql_affected_rows)(MYSQL *mysql);
+MYSQL_RES * (*dl_mysql_store_result)(MYSQL *mysql);
+MYSQL_ROW (*dl_mysql_fetch_row)(MYSQL_RES *result);
+void (*dl_mysql_free_result)(MYSQL_RES *result);
+my_bool (*dl_mysql_eof)(MYSQL_RES *res);
+gint addwaypoint_cb (GtkWidget * widget, gpointer datum);
+gint importaway_cb (GtkWidget * widget, guint datum);
+gint scaler_cb (GtkAdjustment * adj, gdouble * datum);
+gint mapclick_cb (GtkWidget * widget, GdkEventButton * event);
+gint scalerbt_cb (GtkWidget * widget, guint datum);
+gint pos_cb (GtkWidget * widget, guint datum);
+gint toggle_mapnik_cb (GtkWidget * widget, guint datum);
+gint streets_draw_cb (GtkWidget * widget, guint datum);
+
+// TODO: Some of these should be moved, once all the gui stuff is finally moved
+GtkWidget *find_poi_bt;
+
+/* I didn't want to start a friends.h ;-) */
+void drawfriends (void);
+/* End of friends.h stuff */
+
+void test_and_load_newmap ();
+void map_koord_check_and_reload();
+void coordinate_string2gdouble (const gchar * text,gdouble * dec);
+void do_incremental_save();
+glong addwaypoint (gchar * wp_name, gchar * wp_type, gchar * wp_comment, gdouble wp_lat, gdouble wp_lon, gint save_in_db);
+gdouble lat2radius (gdouble lat);
+gdouble lat2radius_pi_180 (gdouble lat);
+
+void draw_text_with_box (gdouble posx, gdouble posy, gchar * name);
+int posxy_on_screen (gdouble posx, gdouble posy);
+
+
+void init_lat2RadiusArray();
+int display_background_map ();
+
+typedef struct
+{
+ char id[30];
+ char name[40];
+ char type[40];
+ char lat[40], lon[40];
+ char timesec[40], speed[10], heading[10];
+}
+friendsstruct;
+
+/* struct for current route status */
+typedef struct
+{
+ gint active;
+ gint edit;
+ gint pointer;
+ gint show;
+ gint items;
+ gdouble distance;
+ gboolean forcenext;
+}
+routestatus_struct;
+
+/* struct for all coordinates that have to be used globally */
+typedef struct
+{
+/* current position */
+ gdouble current_lon;
+ gdouble current_lat;
+/* target position */
+ gdouble target_lon;
+ gdouble target_lat;
+/* saved "current position" while in pos mode */
+ gdouble posmode_lon;
+ gdouble posmode_lat;
+
+/* ### What's the exact usage of for these variables???
+ * TODO: Maybe they should be renamed to something more useful */
+ gdouble zero_lon;
+ gdouble zero_lat;
+ gdouble old_lon;
+ gdouble old_lat;
+ gdouble wp_lat;
+ gdouble wp_lon;
+}
+coordinate_struct;
+
+/* struct for data about current position/movement/status data */
+typedef struct
+{
+ gdouble groundspeed;
+ gdouble heading; /* heading in radians */
+ gdouble bearing; /* bearing in radians */
+ gdouble altitude; /* current altitude */
+ glong mapscale; /* scale of map shown */
+ gint zoom; /* map zoom level */
+ gchar target[80]; /* name of current target */
+ gdouble dist; /* distance to selected target */
+ gint statusbar_id; /* context_id of current statusbar message */
+ gboolean simmode; /* Status of Simulation mode */
+ gint gpsfix; /* Status of GPS:
+ * 0: No GPS, 1: No Fix, 2: 2D Fix, 3: 3D Fix */
+ gboolean needtosave; /* flag if config has to be saved */
+ gboolean importactive;
+ GtkTreeIter poitype_iter;
+ gchar poifilter[5000]; /* sql string for filtering the POI display */
+}
+currentstatus_struct;
+
+
+
+#ifndef min
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+#ifndef max
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+
+
+typedef struct
+{
+ gchar filename[200];
+ gdouble lat;
+ gdouble lon;
+ gint hasbbox;
+ gdouble minlat;
+ gdouble minlon;
+ gdouble maxlat;
+ gdouble maxlon;
+ glong scale;
+ gint map_dir;
+}
+mapsstruct;
+
+typedef struct
+{
+ gchar name[40];
+ gdouble lat;
+ gdouble lon;
+ gdouble dist;
+ gchar typ[40];
+ gint wlan;
+ gint action;
+ gint sqlnr;
+ gint proximity;
+ gchar comment[80];
+}
+wpstruct;
+
+enum map_projections {
+ proj_undef,
+ proj_top,
+ proj_map,
+ proj_googlesat,
+ proj_mapnik
+};
+extern enum map_projections map_proj;
+
+
+typedef struct
+{
+ gchar name[200];
+ GtkWidget *checkbox;
+ int to_be_displayed;
+ int count;
+}
+map_dir_struct;
+
+#endif /* GPSDRIVE_GPSDRIVE_H */
diff --git a/src/gpsdrive.spec b/src/gpsdrive.spec
new file mode 100644
index 0000000..c1754ea
--- /dev/null
+++ b/src/gpsdrive.spec
@@ -0,0 +1,74 @@
+#
+#
+#
+Summary: gpsdrive is a GPS based navigation tool
+Name: gpsdrive
+Version: 2.10pre2
+Release: 1
+Copyright: GPL
+Group: Tools
+Source: %{name}-%{version}.tar.gz
+Vendor: Fritz Ganter <ganter@ganter.at>
+Packager: Fritz Ganter <ganter@ganter.at>
+BuildRoot: %{_tmppath}/%{name}-root
+%define _prefix /usr
+%description
+Gpsdrive is a map-based navigation system. It displays your position on a zoomable map provided from a NMEA-capable GPS receiver. The maps are autoselected for the best resolution, depending of your position, and the displayed image can be zoomed. Maps can be downloaded from the Internet with one mouse click. The program provides information about speed, direction, bearing, arrival time, actual position, and target position. Speech output is also available. MySQL is supported.
+See http://www.gpsdrive.de for new releases.
+%prep
+%setup
+
+
+%build
+export CFLAGS="$RPM_OPT_FLAGS"
+export CXXFLAGS="$RPM_OPT_FLAGS"
+./configure --prefix=%{_prefix} --mandir=%{_mandir}
+make
+%install
+rm -rf $RPM_BUILD_ROOT
+make DESTDIR=$RPM_BUILD_ROOT install-strip
+
+%clean
+if [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ]; then
+rm -rf $RPM_BUILD_ROOT
+fi
+rm -rf %{_builddir}/%{name}-%{version}
+
+%files
+%defattr (-,root,root)
+%doc GPS-receivers INSTALL AUTHORS COPYING TODO README LEEME LISEZMOI README.FreeBSD README.gpspoint2gspdrive FAQ.gpsdrive FAQ.gpsdrive.fr README.SQL create.sql NMEA.txt wp2sql README.kismet LISEZMOI.kismet LISEZMOI.SQL
+%doc %{_mandir}/de/man1/gpsdrive.1.gz
+%doc %{_mandir}/es/man1/gpsdrive.1.gz
+%doc %{_mandir}/man1/gpsdrive.1.gz
+
+%{_libdir}/*
+%{_bindir}/*
+
+%dir %{_prefix}/share/gpsdrive
+%{_prefix}/share/gpsdrive/gpsdrivesplash.png
+%{_prefix}/share/gpsdrive/gpsdrivemini.png
+%{_prefix}/share/gpsdrive/friendsicon.png
+%{_prefix}/share/gpsdrive/gpsicon.png
+%{_prefix}/share/gpsdrive/gpsiconbt.png
+%{_prefix}/share/gpsdrive/gpsdriveanim.gif
+%{_prefix}/share/gpsdrive/top_GPSWORLD.jpg
+%{_prefix}/share/locale/*/LC_MESSAGES/*
+%{_prefix}/share/gpsdrive/AUTHORS
+%{_prefix}/share/gpsdrive/CREDITS
+%{_prefix}/share/gpsdrive/FAQ.gpsdrive
+%{_prefix}/share/gpsdrive/FAQ.gpsdrive.fr
+%{_prefix}/share/gpsdrive/GPS-receivers
+%{_prefix}/share/gpsdrive/LEEME
+%{_prefix}/share/gpsdrive/LISEZMOI
+%{_prefix}/share/gpsdrive/NMEA.txt
+%{_prefix}/share/gpsdrive/README
+%{_prefix}/share/gpsdrive/README.FreeBSD
+%{_prefix}/share/gpsdrive/README.SQL
+%{_prefix}/share/gpsdrive/README.gpspoint2gspdrive
+%{_prefix}/share/gpsdrive/README.kismet
+%{_prefix}/share/gpsdrive/TODO
+%{_prefix}/share/gpsdrive/README.nasamaps
+%{_prefix}/share/gpsdrive/create.sql
+%{_prefix}/share/gpsdrive/wp2sql
+%{_datadir}/applications/gpsdrive.desktop
+%{_prefix}/share/pixmaps/gpsicon.png
diff --git a/src/gpsdrive.spec.fc5 b/src/gpsdrive.spec.fc5
new file mode 100644
index 0000000..5f4239e
--- /dev/null
+++ b/src/gpsdrive.spec.fc5
@@ -0,0 +1,130 @@
+# -*- rpm-spec -*-
+
+# gpsdrive RPM spec file for Fedora Core 5. This is in the tarball
+# distribution and CVS as gpsdrive.spec.fc5. Copy it into place as
+# gpsdrive.spec. Then run "make dist-bzip2" and copy/move the result
+# to your SOURCES directory. You will need to set up a %packager macro
+# for yourself, as well as signature data if you want to sign your
+# RPMs.
+
+# This spec file may well work on older versions of Fedora; I haven't
+# tried it. You will probably have to adjust the minimum version
+# requirements below for both building and running.
+
+Summary: Gpsdrive is a GPS based navigation tool
+Name: gpsdrive
+Version: 2.10.pre3.20061202
+Release: 1
+License: GPL
+Group: Amusements/Graphics
+Source: %{name}-%{version}.tar.bz2
+Url: http://www.gpsdrive.de
+BuildRoot: %{_tmppath}/%{name}-buildroot
+Vendor: The gpsdrive team
+
+
+# The version numbers are those for Fedora Core 5 as distributed. You
+# may be able to use older versions.
+
+PreReq: libgcc >= 4.1.0-3
+PreReq: gdal >= 1.3.1-2
+PreReq: gtk2 >= 2.8.15-1
+PreReq: ImageMagick >= 6.2.5.4-4.2.1
+PreReq: libart_lgpl >= 2.3.17-2.2.1
+# PreReq: mysql >= 5.0.22-1.FC5.1
+PreReq: pcre >= 6.3-1.2.1
+
+# These version numbers are as found on Fedora Core 5 as updated when
+# I worked on this, say early August 2006. Again, earlier versions may
+# work.
+
+BuildPreReq: autoconf >= 2.59-7
+BuildPreReq: gcc >= 4.1.1-1.fc5
+BuildPreReq: gcc-c++ >= 4.1.1-1.fc5
+BuildPreReq: gdal-devel >= 1.3.1-2
+BuildPreReq: gettext >= 0.14.5-3
+BuildPreReq: gettext-devel >= 0.14.5-3
+BuildPreReq: gtk2-devel >= 2.8.20-1
+# BuildPreReq: ImageMagick-devel >= 6.2.5.4-4.2.1.fc5.3
+BuildPreReq: libart_lgpl-devel >= 2.3.17-2.2.1
+# BuildPreReq: libgcc-devel >= 4.1.1-1.fc5
+BuildPreReq: libtool >= 1.5.22-2.3
+BuildPreReq: libtool-ltdl >= 1.5.22-2.3
+BuildPreReq: libtool-ltdl-devel >= 1.5.22-2.3
+BuildPreReq: mysql-devel >= 5.0.22-1.FC5.1
+BuildPreReq: pcre-devel >= 6.3-1.2.1
+
+%define _prefix /usr
+%description
+
+Gpsdrive is a map-based navigation system. It displays on a zoomable
+map your position, as provided by a NMEA-capable GPS receiver or by
+gpsd (http://gpsd.berlios.de/). The maps are autoselected for the best
+resolution, depending of your position. Maps can be downloaded from
+the Internet. The program provides information about speed, direction,
+bearing, arrival time, actual position, and target position. Speech
+output from Festival (http://www.cstr.ed.ac.uk/projects/festival/) is
+also available. MySQL and Kismet (http://www.kismetwireless.net/) are
+supported.
+
+This RPM package represents subversion version 1114.
+
+There is more setup to do. Please read the man page and the README
+files in /usr/share/doc/gpsdrive.
+
+%prep
+%setup
+
+
+%build
+export CFLAGS="$RPM_OPT_FLAGS"
+export CXXFLAGS="$RPM_OPT_FLAGS"
+#./configure --prefix=%{_prefix} --mandir=%{_mandir}
+%configure --mandir=%{_mandir}
+make
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make DESTDIR=$RPM_BUILD_ROOT install
+
+%clean
+if [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ]; then
+rm -rf $RPM_BUILD_ROOT
+fi
+rm -rf %{_builddir}/%{name}-%{version}
+
+%files
+%defattr (-,root,root)
+%doc Documentation/CREDITS Documentation/LEEME Documentation/README.Fedora Documentation/README.mysql Documentation/TODO Documentation/LISEZMOI Documentation/README.FreeBSD Documentation/README.nasamaps Documentation/FAQ.gpsdrive Documentation/LISEZMOI.FreeBSD Documentation/README.gpspoint2gspdrive Documentation/FAQ.gpsdrive.fr Documentation/LISEZMOI.kismet Documentation/NMEA.txt Documentation/README.kismet Documentation/README.SQL Documentation/GPS-receivers Documentation/LISEZMOI.SQL Documentation/README.Bluetooth Documentation/README.lib_map
+
+# Documentation/README.Upgrade Documentation/README.OpenStreetMap-Vektordata
+
+%doc %{_mandir}/de/man1/gpsdrive.1.gz
+%doc %{_mandir}/es/man1/gpsdrive.1.gz
+%doc %{_mandir}/man1/gpsdrive.1.gz
+%doc %{_mandir}/man1/geo-code.1.gz
+%doc %{_mandir}/man1/geo-nearest.1.gz
+%doc %{_mandir}/man1/garble.1.gz
+%doc %{_mandir}/man1/geoinfo.1.gz
+
+%{_libdir}/*
+%{_bindir}/*
+
+%{_datadir}/applications/gpsdrive.desktop
+
+%{_prefix}/share/gpsdrive
+%{_prefix}/share/map-icons/classic
+%{_prefix}/share/map-icons/square.big
+%{_prefix}/share/map-icons/square.small
+
+%{_prefix}/share/locale/*/LC_MESSAGES/*
+
+%changelog
+* Sun Nov 5 2006 Charles Curley <ccurley@charlesc.localdomain> - 2.10pre3.20061105-1
+- Greatly simplified the %files section by using the %dir macro.
+
+* Sat Aug 26 2006 Charles Curley <ccurley@charlesc.localdomain> - 2.10pre3.20060826-1
+- First changelog entry. Massive updates since Fritz Ganter's
+ versions, mostly to bring it up to modern RPM (v 4.4 or so)
+ standards.
+
diff --git a/src/gpsdrive_config.c b/src/gpsdrive_config.c
new file mode 100644
index 0000000..8cb6427
--- /dev/null
+++ b/src/gpsdrive_config.c
@@ -0,0 +1,612 @@
+/*******************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <splash.h>
+#include <string.h>
+#include <stdlib.h>
+#include <config.h>
+#include <gpsdrive.h>
+#include <poi.h>
+#include <wlan.h>
+#include <time.h>
+#include <speech_out.h>
+#include <icons.h>
+#include <gpsdrive_config.h>
+#include <speech_strings.h>
+#include "main_gui.h"
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+extern gint max_display_map;
+extern map_dir_struct *display_map;
+
+extern gint displaymap_top, displaymap_map;
+extern gint mydebug;
+extern gint setdefaultpos;
+extern gint usedgps;
+extern gdouble milesconv;
+extern gint satposmode, printoutsats;
+extern gint real_screen_x, real_screen_y, real_psize, real_smallmenu,
+lastnotebook;
+#define MAXDBNAME 30
+extern char dbhost[MAXDBNAME], dbuser[MAXDBNAME], dbpass[MAXDBNAME];
+extern char dbtable[MAXDBNAME], dbname[MAXDBNAME];
+extern double dbdistance;
+extern int dbusedist;
+extern gint earthmate, zone;
+extern long int maxfriendssecs;
+extern int messagenumber;
+extern int sockfd, showsid, storetz;
+extern coordinate_struct coords;
+extern currentstatus_struct current;
+#define KM2MILES 0.62137119
+
+local_gpsdrive_config local_config;
+
+
+/* write the configurationfile */
+void
+writeconfig ()
+{
+ FILE *fp;
+ gchar str[40];
+ gint i;
+
+ if ( mydebug > 0 )
+ printf ("Write config %s\n", local_config.config_file);
+
+
+
+ fp = fopen (local_config.config_file, "w");
+ if (fp == NULL)
+ {
+ fprintf (stderr,"Error saving config file %s ...\n", local_config.config_file);
+ return;
+ }
+
+ fprintf (fp, "showwaypoints = ");
+ if (local_config.showwaypoints)
+ fprintf (fp, "1\n");
+ else
+ fprintf (fp, "0\n");
+
+ fprintf (fp, "travelmode = %d\n", local_config.travelmode);
+
+ fprintf (fp, "showtrack = ");
+ if (local_config.showtrack)
+ fprintf (fp, "1\n");
+ else
+ fprintf (fp, "0\n");
+
+ fprintf (fp, "mutespeechoutput = ");
+ if (local_config.mute)
+ fprintf (fp, "1\n");
+ else
+ fprintf (fp, "0\n");
+
+ fprintf (fp, "showtopomaps = ");
+ if (displaymap_top)
+ fprintf (fp, "1\n");
+ else
+ fprintf (fp, "0\n");
+
+ fprintf (fp, "showstreetmaps = ");
+ if (displaymap_map)
+ fprintf (fp, "1\n");
+ else
+ fprintf (fp, "0\n");
+
+ fprintf (fp, "autobestmap = ");
+ if (local_config.autobestmap)
+ fprintf (fp, "1\n");
+ else
+ fprintf (fp, "0\n");
+
+ fprintf (fp, "units = ");
+ if (local_config.distmode == DIST_MILES)
+ fprintf (fp, "miles\n");
+ else
+ {
+ if (local_config.distmode == DIST_METRIC)
+ fprintf (fp, "metric\n");
+ else
+ fprintf (fp, "nautic\n");
+ }
+
+ fprintf (fp, "savetrack = ");
+ if (local_config.savetrack)
+ fprintf (fp, "1\n");
+ else
+ fprintf (fp, "0\n");
+
+ fprintf (fp, "scalewanted = %d\n", local_config.scale_wanted);
+
+ g_snprintf (str, sizeof (str), "%.6f", coords.current_lon);
+ g_strdelimit (str, ",", '.');
+ fprintf (fp, "lastlong = %s\n", str);
+
+ g_snprintf (str, sizeof (str), "%.6f", coords.current_lat);
+ g_strdelimit (str, ",", '.');
+ fprintf (fp, "lastlat = %s\n", str);
+
+ fprintf (fp, "shadow = ");
+ if (local_config.showshadow)
+ fprintf (fp, "1\n");
+ else
+ fprintf (fp, "0\n");
+
+ fprintf (fp, "waypointfile = ");
+ fprintf (fp, "%s\n", local_config.wp_file);
+
+ fprintf (fp, "usedgps = ");
+ if (usedgps == 0)
+ fprintf (fp, "0\n");
+ else
+ fprintf (fp, "1\n");
+
+ fprintf (fp, "mapdir = ");
+ fprintf (fp, "%s\n", local_config.dir_maps);
+ if (local_config.MapnikStatusInt > 1) { /* 2 = active, so store it as 1 */
+ fprintf (fp, "mapnik = %d\n", 1);
+ } else {
+ fprintf (fp, "mapnik = %d\n", 0);
+ }
+
+
+ fprintf (fp, "simfollow = %d\n", local_config.simmode);
+
+ fprintf (fp, "satposmode = ");
+ if (satposmode == 0)
+ fprintf (fp, "0\n");
+ else
+ fprintf (fp, "1\n");
+
+ fprintf (fp, "printoutsats = ");
+ if (printoutsats == 0)
+ fprintf (fp, "0\n");
+ else
+ fprintf (fp, "1\n");
+
+ fprintf (fp, "minsecmode = %d\n",local_config.coordmode);
+
+ fprintf (fp, "posmarker = %d\n", local_config.posmarker);
+
+ fprintf (fp, "nightmode = ");
+ fprintf (fp, "%d\n", local_config.nightmode);
+
+ fprintf (fp, "cpuload = %d\n", local_config.maxcpuload);
+
+ fprintf (fp, "lastnotebook = ");
+ fprintf (fp, "%d\n", lastnotebook);
+
+ fprintf (fp, "dbhostname = %s\n", dbhost);
+ fprintf (fp, "dbname = %s\n", dbname);
+ fprintf (fp, "dbuser = %s\n", dbuser);
+ fprintf (fp, "dbpass = %s\n", dbpass);
+ fprintf (fp, "dbtable = %s\n", dbtable);
+ fprintf (fp, "dbdistance = %.1f\n", dbdistance);
+ fprintf (fp, "dbusedist = %d\n", dbusedist);
+ fprintf (fp, "earthmate = %d\n", earthmate);
+
+ fprintf (fp, "font_bigtext = %s\n", local_config.font_dashboard);
+ fprintf (fp, "font_wplabel = %s\n", local_config.font_wplabel);
+ fprintf (fp, "font_friends = %s\n", local_config.font_friends);
+
+ fprintf (fp, "friendsserverip = %s\n", local_config.friends_serverip);
+ fprintf (fp, "friendsserverfqn = %s\n", local_config.friends_serverfqn);
+ fprintf (fp, "friendsname = %s\n", local_config.friends_name);
+ fprintf (fp, "friendsidstring = %s\n", local_config.friends_id);
+ fprintf (fp, "usefriendsserver = %d\n", local_config.showfriends);
+ fprintf (fp, "maxfriendssecs = %ld\n", local_config.friends_maxsecs);
+ fprintf (fp, "poi_results_max = %d\n", local_config.poi_results_max);
+ fprintf (fp, "poi_searchradius = %0.1f\n",
+ local_config.poi_searchradius);
+ fprintf (fp, "storetz = %d\n", storetz);
+ if (storetz)
+ fprintf (fp, "timezone = %d\n", zone);
+ fprintf (fp, "dashboard_1 = %d\n", local_config.dashboard_1);
+ fprintf (fp, "dashboard_2 = %d\n", local_config.dashboard_2);
+ fprintf (fp, "dashboard_3 = %d\n", local_config.dashboard_3);
+ fprintf (fp, "dashboard_4 = %d\n", local_config.dashboard_4);
+ fprintf (fp, "bigcolor = %s\n", local_config.color_dashboard);
+ fprintf (fp, "trackcolor = %s\n", local_config.color_track);
+ fprintf (fp, "routecolor = %s\n", local_config.color_route);
+ fprintf (fp, "friendscolor = %s\n", local_config.color_friends);
+ fprintf (fp, "wplabelcolor = %s\n", local_config.color_wplabel);
+ fprintf (fp, "messagenumber = %d\n", messagenumber);
+ fprintf (fp, "showssid = %d\n", showsid);
+ fprintf (fp, "sound_direction = %d\n", local_config.sound_direction);
+ fprintf (fp, "sound_distance = %d\n", local_config.sound_distance);
+ fprintf (fp, "sound_speed = %d\n", local_config.sound_speed);
+ fprintf (fp, "sound_gps = %d\n", local_config.sound_gps);
+ fprintf (fp, "icon_theme = %s\n", local_config.icon_theme);
+ fprintf (fp, "poi_filter = %s\n", local_config.poi_filter);
+
+ fprintf (fp, "draw_grid = %d\n", local_config.showgrid);
+ fprintf (fp, "show_zoom = %d\n", local_config.showzoom);
+ fprintf (fp, "show_scalebar = %d\n", local_config.showscalebar);
+ fprintf (fp, "draw_poi = %d\n", local_config.showpoi);
+ fprintf (fp, "draw_poilabel = %d\n", local_config.showpoilabel);
+ fprintf (fp, "draw_wlan = %d\n", local_config.showwlan);
+ for ( i = 0; i < max_display_map; i++)
+ {
+ fprintf (fp, "display_map_%s = %d\n",
+ display_map[i].name,
+ display_map[i].to_be_displayed);
+ }
+
+
+
+ fclose (fp);
+ current.needtosave = FALSE;
+}
+
+/* read the configurationfile */
+void
+readconfig ()
+{
+ FILE *fp;
+ gchar par1[40], par2[1000], buf[1000];
+ gint e;
+
+ // open Config File
+ fp = fopen (local_config.config_file, "r");
+ if (fp == NULL)
+ return;
+
+ // mydebug is not set, because getopt was not run yet
+ // So you won't see this Debug Output
+ if ( mydebug > 0 )
+ fprintf (stderr,"reading config file %s ...\n", local_config.config_file);
+
+ while ((fgets (buf, 1000, fp)) > 0)
+ {
+ g_strlcpy (par1, "", sizeof (par1));
+ g_strlcpy (par2, "", sizeof (par2));
+ e = sscanf (buf, "%s = %[^\n]", par1, par2);
+
+ if ( mydebug > 1 )
+ fprintf ( stderr,"%d [%s] = [%s]\n", e, par1, par2);
+
+ if (e == 2)
+ {
+ if ( (strcmp(par1, "showwaypoints")) == 0)
+ local_config.showwaypoints = atoi (par2);
+ else if ( (strcmp(par1, "showtrack")) == 0)
+ local_config.showtrack = atoi (par2);
+ else if ( (strcmp(par1, "travelmode")) == 0)
+ local_config.travelmode = atoi (par2);
+ else if ( (strcmp(par1, "mutespeechoutput")) == 0)
+ local_config.mute = atoi (par2);
+ else if ( (strcmp(par1, "showtopomaps")) == 0)
+ displaymap_top = atoi (par2);
+ else if ( (strcmp(par1, "showstreetmaps")) == 0)
+ displaymap_map = atoi (par2);
+ /* To set the right sensitive flags bestmap_cb is called later */
+ else if ( (strcmp(par1, "autobestmap")) == 0)
+ local_config.autobestmap = atoi (par2);
+ else if ( (strcmp(par1, "units")) == 0)
+ {
+ if ( (strcmp(par2, "miles")) == 0)
+ {
+ local_config.distmode = DIST_MILES;
+ milesconv = KM2MILES;
+ }
+ else
+ {
+ if ( (strcmp(par2, "metric")) == 0)
+ {
+ local_config.distmode = DIST_METRIC;
+ milesconv = 1.0;
+ }
+ else if ( (strcmp(par2, "nautic")) == 0)
+ {
+ local_config.distmode = DIST_NAUTIC;
+ milesconv = KM2NAUTIC;
+ }
+ }
+ }
+ else if ( (strcmp(par1, "dashboard_1")) == 0)
+ local_config.dashboard_1 = atoi (par2);
+ else if ( (strcmp(par1, "dashboard_2")) == 0)
+ local_config.dashboard_2 = atoi (par2);
+ else if ( (strcmp(par1, "dashboard_3")) == 0)
+ local_config.dashboard_3 = atoi (par2);
+ else if ( (strcmp(par1, "dashboard_4")) == 0)
+ local_config.dashboard_4 = atoi (par2);
+ else if ( (strcmp(par1, "savetrack")) == 0)
+ local_config.savetrack = atoi (par2);
+ else if ( (strcmp(par1, "scalewanted")) == 0)
+ local_config.scale_wanted = atoi (par2);
+ else if ( (strcmp(par1, "lastlong")) == 0)
+ coordinate_string2gdouble(par2,
+ &coords.current_lon);
+ else if ( (strcmp(par1, "lastlat")) == 0)
+ coordinate_string2gdouble(par2,
+ &coords.current_lat);
+ /*
+ else if ( (strcmp(par1, "setdefaultpos")) == 0)
+ setdefaultpos = atoi (par2);
+ */
+ else if ( (strcmp(par1, "shadow")) == 0)
+ local_config.showshadow = atoi (par2);
+ else if ( (strcmp(par1, "waypointfile")) == 0)
+ g_strlcpy (local_config.wp_file, par2,
+ sizeof (local_config.wp_file));
+ else if ( (strcmp(par1, "usedgps")) == 0)
+ usedgps = atoi (par2);
+ else if ( (strcmp(par1, "mapdir")) == 0)
+ g_strlcpy (local_config.dir_maps, par2,
+ sizeof (local_config.dir_maps));
+ else if ( (strcmp(par1, "mapnik")) == 0)
+ local_config.MapnikStatusInt = atoi (par2);
+ else if ( (strcmp(par1, "simfollow")) == 0)
+ local_config.simmode = atoi (par2);
+ else if ( (strcmp(par1, "satposmode")) == 0)
+ satposmode = atoi (par2);
+ else if ( (strcmp(par1, "printoutsats")) == 0)
+ printoutsats = atoi (par2);
+ else if ( (strcmp(par1, "minsecmode")) == 0)
+ local_config.coordmode = atoi (par2);
+ else if ( (strcmp(par1, "posmarker")) == 0)
+ local_config.posmarker = atoi (par2);
+ else if ( (strcmp(par1, "nightmode")) == 0)
+ local_config.nightmode = atoi (par2);
+ else if ( (strcmp(par1, "cpuload")) == 0)
+ local_config.maxcpuload = atoi (par2);
+ else if ( (strcmp(par1, "lastnotebook")) == 0)
+ lastnotebook = atoi (par2);
+ else if ( (strcmp(par1, "dbhostname")) == 0)
+ {
+ g_strlcpy (dbhost, par2, sizeof (dbhost));
+ g_strstrip (dbhost);
+ }
+ else if ( (strcmp(par1, "dbname")) == 0)
+ g_strlcpy (dbname, par2, sizeof (dbname));
+ else if ( (strcmp(par1, "dbuser")) == 0)
+ g_strlcpy (dbuser, par2, sizeof (dbuser));
+ else if ( (strcmp(par1, "dbpass")) == 0)
+ g_strlcpy (dbpass, par2, sizeof (dbpass));
+ else if ( (strcmp(par1, "dbtable")) == 0)
+ {
+ if ( (strcmp(par2, "waypoints")) == 0)
+ g_strlcpy (dbtable, "poi", sizeof (dbtable));
+ else
+ g_strlcpy (dbtable, par2, sizeof (dbtable));
+ }
+ else if ( (strcmp(par1, "dbname")) == 0)
+ g_strlcpy (dbname, par2, sizeof (dbname));
+ else if ( (strcmp(par1, "dbdistance")) == 0)
+ dbdistance = g_strtod (par2, 0);
+ else if ( (strcmp(par1, "dbusedist")) == 0)
+ dbusedist = atoi (par2);
+ else if ( (strcmp(par1, "earthmate")) == 0)
+ earthmate = atoi (par2);
+
+ else if ( (strcmp(par1, "font_bigtext")) == 0)
+ g_strlcpy (local_config.font_dashboard, par2,
+ sizeof (local_config.font_dashboard));
+ else if ( (strcmp(par1, "font_wplabel")) == 0)
+ g_strlcpy (local_config.font_wplabel, par2,
+ sizeof (local_config.font_wplabel));
+ else if ( (strcmp(par1, "font_friends")) == 0)
+ g_strlcpy (local_config.font_friends, par2,
+ sizeof (local_config.font_friends));
+
+ else if ( (strcmp(par1, "friendsserverip")) == 0)
+ g_strlcpy (local_config.friends_serverip, par2,
+ sizeof (local_config.friends_serverip));
+ else if ( (strcmp(par1, "friendsserverfqn")) == 0)
+ g_strlcpy (local_config.friends_serverfqn, par2,
+ sizeof (local_config.friends_serverfqn));
+ else if ( (strcmp(par1, "friendsname")) == 0)
+ g_strlcpy (local_config.friends_name, par2,
+ sizeof (local_config.friends_name));
+ else if ( (strcmp(par1, "friendsidstring")) == 0)
+ g_strlcpy (local_config.friends_id, par2, sizeof
+ (local_config.friends_id));
+ else if ( (strcmp(par1, "usefriendsserver")) == 0)
+ local_config.showfriends = atoi (par2);
+ else if ( (strcmp(par1, "maxfriendssecs")) == 0)
+ local_config.friends_maxsecs = atoi (par2);
+ else if ( (strcmp(par1, "poi_results_max")) == 0)
+ local_config.poi_results_max = atoi (par2);
+ else if ( (strcmp(par1, "poi_searchradius")) == 0)
+ local_config.poi_searchradius =
+ g_strtod (par2, NULL);
+ else if ( (strcmp(par1, "storetz")) == 0)
+ storetz = atoi (par2);
+ else if ( storetz && (strcmp(par1, "timezone")) == 0)
+ zone = atoi (par2);
+ else if ( (strcmp(par1, "bigcolor")) == 0)
+ g_strlcpy (local_config.color_dashboard, par2,
+ sizeof (local_config.color_dashboard));
+ else if ( (strcmp(par1, "trackcolor")) == 0)
+ g_strlcpy (local_config.color_track, par2,
+ sizeof (local_config.color_track));
+ else if ( (strcmp(par1, "routecolor")) == 0)
+ g_strlcpy (local_config.color_route, par2,
+ sizeof (local_config.color_route));
+ else if ( (strcmp(par1, "friendscolor")) == 0)
+ g_strlcpy (local_config.color_friends, par2,
+ sizeof (local_config.color_friends));
+ else if ( (strcmp(par1, "wplabelcolor")) == 0)
+ g_strlcpy (local_config.color_wplabel, par2,
+ sizeof (local_config.color_wplabel));
+ else if ( (strcmp(par1, "messagenumber")) == 0)
+ messagenumber = atoi (par2);
+ else if ( (strcmp(par1, "showssid")) == 0)
+ showsid = atoi (par2);
+ else if ( (strcmp(par1, "sound_direction")) == 0)
+ local_config.sound_direction = atoi (par2);
+ else if ( (strcmp(par1, "sound_distance")) == 0)
+ local_config.sound_distance = atoi (par2);
+ else if ( (strcmp(par1, "sound_speed")) == 0)
+ local_config.sound_speed = atoi (par2);
+ else if ( (strcmp(par1, "sound_gps")) == 0)
+ local_config.sound_gps = atoi (par2);
+ else if ( (strcmp(par1, "icon_theme")) == 0)
+ g_strlcpy (local_config.icon_theme, par2,
+ sizeof (local_config.icon_theme));
+ else if ( (strcmp(par1, "poi_filter")) == 0)
+ g_strlcpy (local_config.poi_filter, par2,
+ sizeof (local_config.poi_filter));
+ else if ( (strcmp(par1, "draw_grid")) == 0)
+ local_config.showgrid = atoi (par2);
+ else if ( (strcmp(par1, "show_zoom")) == 0)
+ local_config.showzoom = atoi (par2);
+ else if ( (strcmp(par1, "show_scalebar")) == 0)
+ local_config.showscalebar = atoi (par2);
+ else if ( (strcmp(par1, "draw_poi")) == 0)
+ local_config.showpoi = atoi (par2);
+ else if ( (strcmp(par1, "draw_poilabel")) == 0)
+ local_config.showpoilabel = atoi (par2);
+ else if ( (strcmp(par1, "draw_wlan")) == 0)
+ local_config.showwlan = atoi (par2);
+ else if ( ! strncmp(par1, "display_map_",12) )
+ {
+ // printf ("display_map: %s %s\n",par1,par2);
+ max_display_map += 1;
+ display_map = g_renew(map_dir_struct, display_map, max_display_map);
+ g_strlcpy (display_map[max_display_map-1].name,
+ (par1+12),sizeof (display_map[max_display_map-1].name));
+ display_map[max_display_map-1].to_be_displayed = atoi (par2);
+ }
+ else
+ fprintf (stderr, "ERROR: Unknown Config Parameter '%s=%s'\n",par1,par2);
+ } /* if e==2 */
+ }
+
+ if ( mydebug > 1 )
+ fprintf ( stderr,"\nreading config file finished\n");
+ fclose (fp);
+
+ if (local_config.guimode == GUI_PDA)
+ {
+ g_strlcpy (local_config.font_dashboard, "Sans bold 12",
+ sizeof (local_config.font_dashboard));
+ g_strlcpy (local_config.font_wplabel, "Sans 8", sizeof
+ (local_config.font_wplabel));
+ }
+}
+
+/* init configuration with defined default values */
+void
+config_init ()
+{
+ gchar *hd;
+ local_config.travelmode = TRAVEL_CAR;
+ local_config.distmode = DIST_METRIC;
+ local_config.altmode = ALT_METERS;
+ local_config.coordmode = LATLON_DEGDEC;
+ local_config.guimode = GUI_DESKTOP;
+ local_config.simmode = SIM_OFF;
+ local_config.enableapm = FALSE;
+ local_config.dashboard_1 = DASH_DIST;
+ local_config.dashboard_2 = DASH_SPEED;
+ local_config.dashboard_3 = DASH_ALT;
+ local_config.dashboard_4 = DASH_TIME;
+ local_config.MapnikStatusInt = 0;
+ local_config.nightmode = NIGHT_OFF;
+ local_config.posmarker = 0;
+ local_config.maxcpuload = 40;
+ local_config.showgrid = FALSE;
+ local_config.showshadow = FALSE;
+ local_config.showzoom = TRUE;
+ local_config.showscalebar = TRUE;
+ local_config.showwaypoints = TRUE;
+ local_config.showpoi = TRUE;
+ local_config.showpoilabel = FALSE;
+ local_config.showtooltips = TRUE;
+ local_config.sound_direction = TRUE;
+ local_config.sound_distance = TRUE;
+ local_config.sound_speed = TRUE;
+ local_config.sound_gps = TRUE;
+ local_config.showaddwpbutton = FALSE;
+ local_config.showfriends = FALSE;
+ local_config.scale_wanted = 100000;
+ local_config.autobestmap = 1;
+
+ /* set POI related stuff */
+ local_config.poi_results_max = 200;
+ local_config.poi_searchradius = 10.0;
+ g_strlcpy (local_config.icon_theme,
+ "square.big", sizeof (local_config.icon_theme));
+
+ /* set friends stuff */
+ local_config.friends_maxsecs = 1209600;
+ g_strlcpy (local_config.friends_name, "",
+ sizeof (local_config.friends_name));
+ g_strlcpy (local_config.friends_id,
+ "XXX", sizeof (local_config.friends_id));
+ g_strlcpy (local_config.friends_serverfqn,
+ "friendsd.gpsdrive.de", sizeof (local_config.friends_serverfqn));
+ g_strlcpy (local_config.friends_serverip,
+ "127.0.0.1", sizeof (local_config.friends_serverip));
+
+ /* set colors and fonts */
+ g_strlcpy (local_config.color_track,
+ "#0000ff", sizeof (local_config.color_track));
+ g_strlcpy (local_config.color_route,
+ "#00ff00", sizeof (local_config.color_route));
+ g_strlcpy (local_config.color_friends,
+ "#ffa500", sizeof (local_config.color_friends));
+ g_strlcpy (local_config.color_wplabel,
+ "#00ffff", sizeof (local_config.color_wplabel));
+ g_strlcpy (local_config.color_dashboard,
+ "#0000ff", sizeof (local_config.color_dashboard));
+ g_strlcpy (local_config.font_dashboard,
+ "Sans bold 26", sizeof (local_config.font_dashboard));
+ g_strlcpy (local_config.font_wplabel,
+ "Sans 11", sizeof (local_config.font_wplabel));
+ g_strlcpy (local_config.font_friends,
+ "Sans bold 11", sizeof (local_config.font_friends));
+
+ /* set files and directories (~/.gpsdrive) */
+ hd = (gchar *) g_get_home_dir ();
+ g_strlcpy (local_config.dir_home, hd, sizeof (local_config.dir_home));
+ g_strlcat (local_config.dir_home, "/.gpsdrive/",
+ sizeof (local_config.dir_home));
+ g_snprintf (local_config.dir_maps, sizeof (local_config.dir_maps),
+ "%s%s",local_config.dir_home,"maps/");
+ g_snprintf (local_config.wp_file, sizeof (local_config.wp_file),
+ "%s%s", local_config.dir_home, "way.txt");
+ g_snprintf(local_config.mapnik_xml_file, sizeof(local_config.mapnik_xml_file),
+ "%s%s", local_config.dir_home, "osm.xml");
+ g_snprintf(local_config.config_file, sizeof(local_config.config_file),
+ "%s%s", local_config.dir_home, "gpsdriverc");
+
+ /* kismet default values */
+ g_strlcpy(local_config.kismet_servername, "localhost", sizeof(local_config.kismet_servername));
+ local_config.kismet_serverport = 2501;
+}
diff --git a/src/gpsdrive_config.h b/src/gpsdrive_config.h
new file mode 100644
index 0000000..2821823
--- /dev/null
+++ b/src/gpsdrive_config.h
@@ -0,0 +1,111 @@
+/*******************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+#ifndef GPSDRIVE_CONFIG_H
+#define GPSDRIVE_CONFIG_H
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <config.h>
+#include <gmodule.h>
+#include <gdk/gdktypes.h>
+#include "gtk/gtk.h"
+#include "mysql/mysql.h"
+#include "gpsproto.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+void writeconfig ();
+void readconfig ();
+void config_init ();
+typedef struct
+{
+ gchar config_file[500];
+ gint travelmode;
+ gint distmode;
+ gint altmode;
+ gint coordmode;
+ gint nightmode;
+ gint guimode;
+ gint enableapm;
+ gint maxcpuload;
+ gint posmarker;
+ gchar wp_file[500];
+ gchar mapnik_xml_file[500];
+ gchar dir_home[500];
+ gchar dir_maps[500];
+ gchar icon_theme[500];
+ gchar poi_filter[2000];
+ guint poi_results_max;
+ gdouble poi_searchradius;
+ int MapnikStatusInt; /* 0 = disable, 1 = enable, 2 = active */
+ gint simmode;
+ gboolean showgrid;
+ gboolean showshadow;
+ gboolean showzoom;
+ gboolean showscalebar;
+ gboolean showwaypoints;
+ gboolean showpoi;
+ gboolean showpoilabel;
+ gboolean showwlan;
+ gboolean showtooltips;
+ gboolean showaddwpbutton;
+ gboolean showfriends;
+ gboolean showtrack;
+ gboolean savetrack;
+ gboolean autobestmap;
+ gint scale_wanted;
+ gboolean sound_direction;
+ gboolean sound_distance;
+ gboolean sound_speed;
+ gboolean sound_gps;
+ gboolean mute;
+ glong friends_maxsecs;
+ gchar friends_name[40];
+ gchar friends_id[40];
+ gchar friends_serverfqn[255];
+ gchar friends_serverip[20];
+ gchar color_track[40];
+ gchar color_route[40];
+ gchar color_friends[40];
+ gchar color_wplabel[40];
+ gchar color_dashboard[40];
+ gchar font_friends[100];
+ gchar font_wplabel[100];
+ gchar font_dashboard[100];
+ gint dashboard_1;
+ gint dashboard_2;
+ gint dashboard_3;
+ gint dashboard_4;
+ gdouble normalnull;
+ gchar kismet_servername[500];
+ gint kismet_serverport;
+}
+local_gpsdrive_config;
+
+extern local_gpsdrive_config local_config;
+
+#endif /* GPSDRIVE_CONFIG_H */
diff --git a/src/gpskismet.c b/src/gpskismet.c
new file mode 100644
index 0000000..abc660b
--- /dev/null
+++ b/src/gpskismet.c
@@ -0,0 +1,368 @@
+/****************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ *********************************************************************
+
+
+reads info from kismet server and insert waypoints into database
+
+*****************************************************************/
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <gpsdrive.h>
+#include "gpsdrive_config.h"
+/* #include <gpskismet.h> */
+#include <poi.h>
+#include <speech_out.h>
+#include <speech_strings.h>
+#include <time.h>
+#include <errno.h>
+
+#define MAXDBNAME 30
+extern char dbhost[MAXDBNAME], dbuser[MAXDBNAME], dbpass[MAXDBNAME];
+extern char wlantable[MAXDBNAME], dbname[MAXDBNAME];
+extern double dbdistance;
+extern int usesql;
+extern int mydebug, debug, dbusedist;
+extern poi_type_struct poi_type_list[poi_type_list_max];
+extern void wlan_rebuild_list();
+extern void wlan_draw_list();
+
+extern MYSQL mysql;
+MYSQL_RES *res;
+MYSQL_ROW row;
+
+static char macaddr[30], name[120], tbuf[1024], lastmacaddr[30];
+static int nettype, channel, wep, cloaked;
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+/* variables */
+int kismetsock = -1, havekismet;
+static char kbuffer[20210];
+static int bc = 0;
+fd_set kismetreadmask;
+struct timeval kismettimeout;
+static char lat[30], lon[30], bestlat[30], bestlon[30];
+
+time_t last_initkismet=0;
+
+
+int
+readkismet (void)
+{
+ signed char c;
+ char q[1200], buf[300], tname[80], sqllat[30], sqllon[30];
+ int e, r, have, i, j, sqlid = 0;
+
+ // If Kismet server connection failed, Try to reconnect
+ // after at least 30 seconds
+ if ((kismetsock<0) && ((time(NULL) - last_initkismet) > 30)) {
+ if (debug) g_print(_("trying to re-connect to kismet server\n"));
+ initkismet();
+ if (kismetsock>=0) g_print(_("Kismet server connection re-established\n"));
+ if (debug) g_print(_("done trying to re-connect: socket=%d\n"), kismetsock);
+ }
+
+ if (kismetsock < 0) return FALSE;
+
+ do
+ {
+ e = 0;
+ FD_ZERO (&kismetreadmask);
+ FD_SET (kismetsock, &kismetreadmask);
+ kismettimeout.tv_sec = 0;
+ kismettimeout.tv_usec = 10000;
+
+ if (select
+ (FD_SETSIZE, &kismetreadmask, NULL, NULL, &kismettimeout) < 0)
+ {
+ perror ("readkismet: select() call");
+ return FALSE;
+ }
+
+ if ((have = FD_ISSET (kismetsock, &kismetreadmask)))
+ {
+ int bytesread;
+ bytesread=0;
+ while ((e = read (kismetsock, &c, 1)) > 0)
+ {
+ bytesread++;
+ if (c != '\n')
+ *(kbuffer + bc++) = c;
+ else
+ {
+ c = -1;
+ g_strlcat (kbuffer, "\n", sizeof (kbuffer));
+ /* g_print("\nfinished: %d",bc); */
+ break;
+ }
+ if (bc > 20000)
+ {
+ bc = 0;
+ g_print ("kbuffer overflow!\n");
+ }
+
+ }
+
+ // the file descriptor was ready for read but no data available...
+ // this means the connection was lost.
+ if (bytesread==0) {
+ g_print(_("Kismet server connection lost\n"));
+ close(kismetsock);
+ kismetsock=-1;
+ return FALSE;
+ }
+ }
+
+ if (c == -1)
+ {
+ /* have read a line */
+ bc = c = 0;
+ if ((strstr (kbuffer, "*NETWORK:")) == kbuffer)
+ {
+ if (debug)
+ g_print ("\nkbuffer:%s\n", kbuffer);
+ e = sscanf (kbuffer,
+ "%s %s %d \001%255[^\001]\001 %d"
+ " %d %s %s %s %s %d %[^\n]",
+ tbuf, macaddr, &nettype, name, &channel,
+ &wep, lat, lon, bestlat, bestlon, &cloaked, tbuf);
+
+ }
+ if (e == 11)
+ {
+ if (mydebug >10)
+ g_print
+ ("\ne: %d mac: %s nettype: %d name: %s channel: %d wep: %d "
+ "lat: %s lon: %s bestlat: %s bestlon: %s cloaked: %d\n", e, macaddr,
+ nettype, name, channel, wep, lat, lon, bestlat, bestlon, cloaked);
+
+ /* insert waypoint only if we had not just inserted it */
+ /* if ((strcmp (lastmacaddr, macaddr)) != 0) */
+ {
+ /* g_strlcpy (lastmacaddr, macaddr); */
+ g_snprintf (q, sizeof (q),
+ "select wlan_id,lat,lon from %s where macaddr='%s'",
+ wlantable, macaddr);
+ if (debug)
+ g_print ("\nquery: %s\n", q);
+ if (dl_mysql_query (&mysql, q))
+ exiterr (3);
+ if (!(res = dl_mysql_store_result (&mysql)))
+ exiterr (4);
+ r = 0;
+ while ((row = dl_mysql_fetch_row (res)))
+ {
+ sqlid = atol (row[0]);
+ g_strlcpy (sqllat, row[1], sizeof (sqllat));
+ g_strlcpy (sqllon, row[2], sizeof (sqllon));
+
+ r++;
+ }
+
+ if (r > 1)
+ g_print
+ ("\n\a\a*** ERROR: duplicate macaddr in database ***\n");
+
+ dl_mysql_free_result (res);
+ if (debug)
+ g_print ("\nnum fields: %d", r);
+
+ if ((strcmp (name, "<no ssid>")) == 0)
+ g_strlcpy (name, "no_ssid", sizeof (name));
+ g_strdelimit (name, " ", '_');
+ /* escape ' */
+ j = 0;
+ for (i = 0; i <= (int) strlen (name); i++)
+ {
+ if (name[i] != '\'' && name[i] != '\\' && name[i] != '\"')
+ tname[j++] = name[i];
+ else
+ {
+ tname[j++] = '\\';
+ tname[j++] = name[i];
+ if (debug)
+ g_print ("Orig SSID: %s\nEscaped SSID: %s\n", name,
+ tname);
+ }
+ }
+
+
+ /* we have it in the database, but update bestlat and bestlong */
+ if (r > 0)
+ if ((strcmp (sqllat, lat) !=
+ 0) && (strcmp (sqllon, lon) != 0))
+ {
+ if ((atol (bestlat) != 0.0) && (atol (bestlon) != 0))
+ if ((strcmp
+ (lat,
+ "90.000000")
+ != 0) && (strcmp (lon, "180.000000") != 0))
+ {
+ if (debug)
+ g_print
+ ("*** This is a changed waypoint: %s [%s]\n",
+ name, macaddr);
+
+ g_snprintf
+ (q,
+ sizeof
+ (q),
+ "UPDATE %s SET "
+ "essid='%s',macaddr='%s',nettype='%d',lat='%s',lon='%s',wep='%d',cloaked='%d' "
+ "WHERE wlan_id='%d'",
+ wlantable,
+ tname,
+ macaddr,
+ nettype,
+ bestlat,
+ bestlon,
+ wep, cloaked, sqlid);
+ if (debug)
+ printf ("\nquery: %s\n", q);
+ if (dl_mysql_query (&mysql, q))
+ exiterr (3);
+ // Redraw all WLANs:
+ wlan_rebuild_list ();
+ wlan_draw_list ();
+ }
+ }
+
+
+ /* this is a new network, we store it in the database */
+ if ((r == 0)
+ && (strcmp (lat, "90.000000") !=
+ 0) && (strcmp (lon, "180.000000") != 0))
+ {
+ g_strlcpy (lastmacaddr, macaddr, sizeof (lastmacaddr));
+ if (debug)
+ g_print ("*** This is a new waypoint: %s [%s]\n", name,
+ macaddr);
+
+
+ g_snprintf (q, sizeof (q),
+ "INSERT INTO %s (essid,macaddr,nettype,lat,lon,wep,cloaked)"
+ " VALUES ('%s','%s','%d','%s','%s','%d','%d')",
+ wlantable,
+ tname, macaddr, nettype, lat, lon, wep, cloaked);
+ if (debug)
+ printf ("\nquery: %s\n", q);
+ if (dl_mysql_query (&mysql, q))
+ exiterr (3);
+
+ // Redraw all WLANs:
+ wlan_rebuild_list ();
+ wlan_draw_list ();
+
+ g_strdelimit (name, "_", ' ');
+
+ g_snprintf (buf, sizeof (buf),
+ speech_found_access_point[voicelang],
+ (wep) ? speech_access_closed[voicelang] :
+ speech_access_open[voicelang], name, channel);
+ speech_out_speek (buf);
+ /* if (debug) */
+ /* printf (_("rows inserted: %d\n"), r); */
+ getsqldata ();
+ }
+ }
+ }
+
+ memset (kbuffer, 0, 20000);
+ g_strlcpy (kbuffer, "", sizeof (kbuffer));
+ }
+
+ }
+ while (have != 0);
+
+ wlan_rebuild_list ();
+
+ return TRUE;
+}
+
+int
+initkismet (void)
+{
+ struct sockaddr_in server;
+ struct hostent *server_data;
+ char buf[180];
+
+ last_initkismet=time(NULL);
+
+ if (debug) g_print(_("Trying Kismet server\n"));
+
+ g_strlcpy (lastmacaddr, "", sizeof (lastmacaddr));
+ /* open socket to port */
+ if ((kismetsock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ perror (_("can't open socket for port "));
+ return -1;
+ }
+ server.sin_family = AF_INET;
+ /* We retrieve the IP address of the server from its name: */
+ if ((server_data = gethostbyname(local_config.kismet_servername)) == NULL)
+ {
+ fprintf (stderr, "%s: unknown host", local_config.kismet_servername);
+ close (kismetsock);
+ kismetsock=-1;
+ return -1;
+ }
+ memcpy (&server.sin_addr, server_data->h_addr, server_data->h_length);
+ server.sin_port = htons (local_config.kismet_serverport);
+ /* We initiate the connection */
+ if (connect (kismetsock, (struct sockaddr *) &server, sizeof server) < 0)
+ {
+ close (kismetsock);
+ kismetsock=-1;
+ return -1;
+ }
+ else
+ {
+ havekismet = TRUE;
+ g_strlcpy (buf,
+ "!0 ENABLE NETWORK bssid,type,ssid,channel,wep,minlat,minlon,bestlat,bestlon,cloaked\n",
+ sizeof (buf));
+ write (kismetsock, buf, strlen (buf));
+ }
+
+ return TRUE;
+}
diff --git a/src/gpskismet.h b/src/gpskismet.h
new file mode 100644
index 0000000..5a56096
--- /dev/null
+++ b/src/gpskismet.h
@@ -0,0 +1,32 @@
+/****************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ *********************************************************************
+
+
+reads info from kismet server and insert waypoints into database
+
+*****************************************************************/
+
+int readkismet(void);
+int initkismet(void);
+
diff --git a/src/gpsmisc.c b/src/gpsmisc.c
new file mode 100644
index 0000000..8723c00
--- /dev/null
+++ b/src/gpsmisc.c
@@ -0,0 +1,500 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ *********************************************************************
+
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <math.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gpsdrive.h>
+#include <config.h>
+#include <math.h>
+#include "gpsdrive_config.h"
+
+#include <locale.h>
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+
+/* variables */
+extern gint ignorechecksum, mydebug;
+extern gint real_screen_x, real_screen_y, real_psize, real_smallmenu;
+extern gint SCREEN_X_2, SCREEN_Y_2;
+extern gdouble posx, posy;
+extern gint haveposcount, blink, gblink, xoff, yoff;
+extern gdouble milesconv;
+static gchar gradsym[] = "\xc2\xb0";
+gdouble lat2RadiusArray[101];
+extern coordinate_struct coords;
+
+
+/* **********************************************************************
+ * Build array for earth radii
+ */
+void
+init_lat2RadiusArray(){
+ int i;
+ for (i = 0; i <= 100; i++)
+ lat2RadiusArray[i] = calcR (i);
+}
+
+/* **********************************************************************
+ * Estimate the Earth radius in meter for given lat in Degrees
+ */
+gdouble
+lat2radius (gdouble lat)
+{
+ lat = fabs(lat);
+
+ // the known undef values
+ if ( lat > 999 )
+ lat=0;
+
+ while (lat > 360)
+ {
+ lat = lat - 360.0;
+ };
+
+
+ if (lat > 180)
+ {
+ if (mydebug > 20)
+ fprintf (stderr, "ERROR: lat2radius(lat %f) out of bound\n", lat);
+ };
+
+ if (lat > 90 && lat < 180.0)
+ {
+ lat = 180.0 - lat;
+ }
+
+ if (lat > 90)
+ {
+ if (mydebug > 20)
+ fprintf (stderr, "ERROR: lat2radius(lat %f) still out of bound\n", lat);
+ return 1;
+ };
+
+ return lat2RadiusArray[(int) (lat)];
+}
+
+
+/* **********************************************************************
+ * Estimate the Earth radius in (meter * PI/180 ) for given lat in Degrees
+ */
+gdouble
+lat2radius_pi_180 (gdouble lat)
+{
+ return ( lat2radius (lat) * M_PI / 180.0);
+}
+
+/* ******************************************************************
+ * calculate Earth radius in meter for given lat in Degrees
+ */
+gdouble
+calcR (gdouble lat)
+{
+ gdouble a = 6378.137, r, sc, x, y, z;
+ gdouble e2 = 0.08182 * 0.08182;
+ gdouble lat_pi;
+ /* the radius of curvature of an ellipsoidal Earth in the plane of
+ * the meridian is given by
+ *
+ * R' = a * (1 - e^2) / (1 - e^2 * (sin(lat))^2)^(3/2)
+ *
+ * where a is the equatorial radius,
+ *
+ * b is the polar radius, and
+ * e is the eccentricity of the ellipsoid = sqrt(1 - b^2/a^2)
+ *
+ * a = 6378.137 km (3963 mi) Equatorial radius (surface to center distance)
+ * b = 6356.752 km (3950 mi) Polar radius (surface to center distance)
+ * e = 0.08182 Eccentricity
+ */
+
+ lat_pi = lat * M_PI / 180.0;
+ sc = sin (lat_pi);
+ x = a * (1.0 - e2);
+ z = 1.0 - e2 * sc * sc;
+ y = pow (z, 1.5);
+ r = x / y;
+
+ r = r * 1000.0;
+ // g_print("R(%f)=%f\n",lat,r);
+ return r;
+}
+
+
+/* ******************************************************************
+ * calculate distance from (lat/lon) to current position
+ */
+gdouble
+calcdist2 (gdouble lon, gdouble lat)
+{
+ double a, a1, a2, c, d, dlon, dlat, sa, radiant = M_PI / 180;
+
+
+ dlon = radiant * (coords.current_lon - lon);
+ dlat = radiant * (coords.current_lat - lat);
+
+ if ((dlon == 0.0) && (dlat == 0.0))
+ return 0.0;
+
+ a1 = sin (dlat / 2);
+ a2 = sin (dlon / 2);
+ a = (a1 * a1) +
+ cos (lat * radiant) * cos (coords.current_lat * radiant) * a2 * a2;
+ sa = sqrt (a);
+ if (sa <= 1.0)
+ c = 2 * asin (sa);
+ else
+ c = 2 * asin (1.0);
+ d = (lat2radius (coords.current_lat) + lat2radius (lat)) * c / 2.0;
+ return milesconv * d / 1000.0;
+}
+
+/* ******************************************************************
+ * calculate distance between two given coordinates (lon1/lat1, lon2/lat2)
+ * (much more precise than calcdist2)
+ * if from_current is TRUE, lon2/lat2 ist replaced by the current position
+ */
+gdouble
+calc_wpdist (gdouble lon1, gdouble lat1, gdouble lon2, gdouble lat2, gint from_current)
+{
+ gdouble a = 6378137.0;
+ gdouble f = 1.0 / 298.25722210088;
+ gdouble glat1, glat2, glon1, glon2;
+ gdouble radiant = M_PI / 180;
+ gdouble r, tu1, tu2, cu1, su1, cu2, s, baz, faz, x, sx, cx, sy, cy, y;
+ gdouble sa, c2a, cz, e, c, d;
+ gdouble eps = 0.5e-13;
+
+ /* if (local_config.maxcpuload<10)
+ * {
+ * r = calcdist2 (lon, lat);
+ * return r;
+ * }
+ */
+
+ if (from_current)
+ {
+ lon2 = coords.current_lon;
+ lat2 = coords.current_lat;
+ }
+
+ if (((lat1 - lat2) == 0.0) && ((lon1 - lon2) == 0.0))
+ return 0.0;
+
+ glat1 = radiant * lat2;
+ glat2 = radiant * lat1;
+ glon1 = radiant * lon2;
+ glon2 = radiant * lon1;
+
+ r = 1.0 - f;
+ tu1 = r * sin (glat1) / cos (glat1);
+ tu2 = r * sin (glat2) / cos (glat2);
+ cu1 = 1.0 / sqrt (tu1 * tu1 + 1.0);
+ su1 = cu1 * tu1;
+
+ cu2 = 1.0 / sqrt (tu2 * tu2 + 1.0);
+ s = cu1 * cu2;
+ baz = s * tu2;
+ faz = baz * tu1;
+ x = glon2 - glon1;
+
+ do
+ {
+ sx = sin (x);
+ cx = cos (x);
+ tu1 = cu2 * sx;
+ tu2 = baz - su1 * cu2 * cx;
+ sy = sqrt (tu1 * tu1 + tu2 * tu2);
+
+ cy = s * cx + faz;
+ y = atan2 (sy, cy);
+ sa = s * sx / sy;
+ c2a = -sa * sa + 1.0;
+ cz = faz + faz;
+
+ if (c2a > 0)
+ cz = -cz / c2a + cy;
+ e = cz * cz * 2.0 - 1.0;
+ c = ((-3.0 * c2a + 4.0) * f + 4.0) * c2a * f / 16.0;
+ d = x;
+
+ x = ((e * cy * c + cz) * sy * c + y) * sa;
+ x = (1.0 - c) * x * f + glon2 - glon1;
+ }
+ while (fabs (d - x) > eps);
+
+ faz = atan2 (tu1, tu2);
+ baz = atan2 (cu1 * sx, baz * cx - su1 * cu2) + M_PI;
+ x = sqrt ((1.0 / r / r - 1.0) * c2a + 1.0) + 1.0;
+ x = (x - 2.0) / x;
+ c = 1.0 - x;
+ c = (x * x / 4.0 + 1.0) / c;
+ d = (0.375 * x * x - 1.0) * x;
+ x = e * cy;
+ s = 1.0 - e - e;
+ s = ((((sy * sy * 4.0 - 3.0) * s * cz * d / 6.0 - x) * d / 4.0 +
+ cz) * sy * d + y) * c * a * r;
+
+ return milesconv * s / 1000.0;
+}
+
+
+/* ******************************************************************
+ * calculate distance from (lat/lon) to current position
+ * (convenience replacement for calcdist, which is now in calc_wpdist)
+ */
+gdouble
+calcdist (gdouble lon, gdouble lat)
+{
+ return calc_wpdist (lon, lat, 0, 0, TRUE);
+}
+
+
+/* ******************************************************************
+ * This is an internally used function to create pixmaps.
+ */
+GdkPixbuf *
+create_pixbuf (const gchar * filename)
+{
+ gchar pathname[200];
+ GdkPixbuf *pixbuf;
+ GError *error = NULL;
+
+ if (!filename || !filename[0])
+ return NULL;
+
+
+ g_snprintf (pathname, sizeof (pathname), "%s/gpsdrive/%s", DATADIR,
+ filename);
+
+ pixbuf = gdk_pixbuf_new_from_file (pathname, &error);
+ if (!pixbuf)
+ {
+ fprintf (stderr, "Failed to load pixbuf file: %s: %s\n",
+ pathname, error->message);
+ if (pathname[0])
+ {
+ if (mydebug > 5)
+ fprintf (stderr, _("Couldn't find pixmap file: %s"), pathname);
+ else
+ g_warning (_("Couldn't find pixmap file: %s"), pathname);
+ return NULL;
+ }
+ }
+ return pixbuf;
+}
+
+
+
+/* *****************************************************************************
+ * Convert a coordinate to a gchar
+ * mode is either LATLON_DMS, LATLON MINDEC or LATLON_DEGDEC
+ * By Oddgeir Kvien, to adopt for 3-way lat/lon display
+ */
+void
+coordinate2gchar (gchar * buff, gint buff_size, gdouble pos, gint islat,
+ gint mode)
+{
+ gint grad, min, minus = FALSE;
+ gdouble minf, sec;
+ grad = (gint) pos;
+ if (pos < 0)
+ {
+ grad = -grad;
+ pos = -pos;
+ minus = TRUE;
+ }
+
+ minf = (pos - (gdouble) grad) * 60.0;
+ min = (gint) minf;
+ sec = (minf - (gdouble) min) * 60.0;
+ switch (mode)
+ {
+ case LATLON_DMS:
+ if (islat)
+ g_snprintf (buff, buff_size, "%d%s%.2d'%05.2f''%c", grad, gradsym,
+ min, sec, (minus) ? 'S' : 'N');
+ else
+ g_snprintf (buff, buff_size, "%d%s%.2d'%05.2f''%c", grad, gradsym,
+ min, sec, (minus) ? 'W' : 'E');
+ break;
+
+ case LATLON_MINDEC:
+ if (islat)
+ g_snprintf (buff, buff_size, "%d%s%.3f'%c", grad, gradsym, minf,
+ (minus) ? 'S' : 'N');
+ else
+ g_snprintf (buff, buff_size, "%d%s%.3f'%c", grad, gradsym, minf,
+ (minus) ? 'W' : 'E');
+ break;
+
+ case LATLON_DEGDEC:
+ if (islat)
+ g_snprintf (buff, buff_size, "%8.5f%s%c", pos, gradsym,
+ (minus) ? 'S' : 'N');
+ else
+ g_snprintf (buff, buff_size, "%8.5f%s%c", pos, gradsym,
+ (minus) ? 'W' : 'E');
+ break;
+ }
+}
+
+/* *****************************************************************************
+ * convert a coordinate in an gchar into a gdouble decimal value
+ * Sideeffect inside text all , are replaced by .
+ */
+void
+coordinate_string2gdouble (const gchar * intext, gdouble * dec)
+{
+ gint grad;
+ gdouble sec;
+ gint min;
+ // gdouble dec = -1002.0;
+ gchar s2=' ';
+ gdouble fmin;
+ gchar text[50];
+
+ g_strlcpy(text,intext,sizeof(text));
+
+ *dec = -1002.0;
+
+ setlocale(LC_NUMERIC, "C");
+
+ // HACK: Fix usage of , and . inside Float-strings
+ g_strdelimit (text, ",", '.');
+
+ /*
+ * Handle either DegMinSec or MinDec formats
+ */
+ if (4 == sscanf (text, "%d\xc2\xb0%d'%lf''%c", &grad, &min, &sec, &s2))
+ {
+ /* sscanf(s1,"%f",&sec); */
+ *dec = grad + min / 60.0 + sec / 3600.0;
+ }
+ else if (3 == sscanf (text, "%d\xc2\xb0%lf'%c", &grad, &fmin, &s2))
+ {
+ *dec = grad + fmin / 60.0;
+ }
+ else if (2 == sscanf (text, "%lf\xc2\xb0%c", dec, &s2))
+ {
+ }
+ else if (1 == sscanf (text, "%lf", dec))
+ {
+ /* Is already decimal */
+ }
+ else
+ {
+ /* TODO: handle bad format gracefully */
+ fprintf (stderr,
+ "ERROR BAD FORMAT in coordinate_string2gdouble(%s)-->%f\n",
+ text, *dec);
+ }
+
+ if (s2 == 'W')
+ *dec *= -1.0;
+ if (s2 == 'S')
+ *dec *= -1.0;
+
+ if (mydebug > 99)
+ fprintf (stderr, "coordinate_string2gdouble('%s')-->%f\n", text, *dec);
+}
+
+/* *****************************************************************************
+ */
+void
+checkinput (gchar * text)
+{
+ if (mydebug > 50)
+ fprintf (stderr, "checkinput(%s)\n", text);
+ gdouble dec;
+ coordinate_string2gdouble (text, &dec);
+ g_snprintf (text, 20, "%.6f", dec);
+ if (mydebug > 50)
+ fprintf (stderr, "checkinput -->'%s'\n", text);
+}
+
+
+/* ******************************************************************
+ * Find File in the local directories, User Directories or System Directories
+ */
+gint
+file_location(gchar * filename, gchar *file_location){
+ struct stat buf;
+ gchar mappath[2048];
+
+ g_snprintf (mappath, sizeof (mappath), "%s%s", local_config.dir_maps, filename);
+ g_snprintf (mappath, sizeof (mappath), "data/maps/%s", filename);
+ g_snprintf (mappath, sizeof (mappath), "%s/gpsdrive/maps/%s", DATADIR, filename);
+ g_snprintf (filename, sizeof (filename), "./data/pixmaps/%s", filename);
+
+ g_strlcpy (mappath, local_config.dir_home, sizeof (mappath));
+ if ( stat (mappath, &buf) ) {
+ printf("Success\n");
+ //if (buf.st_mtime != waytxtstamp)
+ }
+ return TRUE;
+}
+
+/* ******************************************************************
+ * This is an internally used function to create pixmaps.
+ */
+GtkWidget *
+create_pixmap (GtkWidget * widget, const gchar * filename)
+{
+ gchar pathname[200];
+ GtkWidget *pixmap = NULL;
+
+ if (!filename || !filename[0])
+ return gtk_image_new ();
+
+ g_snprintf (pathname, sizeof (pathname), "%s/gpsdrive/%s", DATADIR,
+ filename);
+
+
+ pixmap = gtk_image_new_from_file (pathname);
+ if (!pixmap)
+ {
+ if (mydebug > 5)
+ fprintf (stderr, _("Couldn't find pixmap file: %s"), pathname);
+ else
+ g_warning (_("Couldn't find pixmap file: %s"), pathname);
+ return gtk_image_new ();
+ }
+
+ return pixmap;
+}
diff --git a/src/gpsnasamap.c b/src/gpsnasamap.c
new file mode 100644
index 0000000..6406ed9
--- /dev/null
+++ b/src/gpsnasamap.c
@@ -0,0 +1,362 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ *********************************************************************
+
+$Log$
+Revision 1.6 2006/08/02 12:18:36 tweety
+forgot one sed for homedir and mapdir
+
+Revision 1.5 2006/08/02 07:48:24 tweety
+rename variable mapdir --> local_config_mapdir
+
+Revision 1.4 2005/04/20 23:33:49 tweety
+reformatted source code with anjuta
+So now we have new indentations
+
+Revision 1.3 2005/04/13 19:58:31 tweety
+renew indentation to 4 spaces + tabstop=8
+
+Revision 1.2 2005/04/10 21:50:50 tweety
+reformatting c-sources
+
+Revision 1.1.1.1 2004/12/23 16:03:24 commiter
+Initial import, straight from 2.10pre2 tar.gz archive
+
+Revision 1.15 2004/02/08 17:16:25 ganter
+replacing all strcat with g_strlcat to avoid buffer overflows
+
+Revision 1.14 2004/02/08 16:35:10 ganter
+replacing all sprintf with g_snprintf to avoid buffer overflows
+
+Revision 1.13 2004/02/06 22:29:24 ganter
+updated README and man page
+
+Revision 1.12 2004/02/04 14:47:10 ganter
+added GPGSA sentence for PDOP (Position Dilution Of Precision).
+
+Revision 1.11 2004/02/03 07:11:21 ganter
+working on problems if gpsdrive is not installed
+
+Revision 1.10 2004/02/01 22:48:01 ganter
+added output to gpsnasamap.c
+
+Revision 1.9 2004/02/01 05:24:59 ganter
+missing nasamaps should now really work!
+upload again 2.08pre9!
+
+Revision 1.8 2004/02/01 05:10:12 ganter
+fixed bug if 1 nasamap is missing
+
+Revision 1.7 2004/02/01 01:57:03 ganter
+it seems that nasamaps now working fine
+
+Revision 1.6 2004/01/31 14:48:03 ganter
+pre8
+
+Revision 1.5 2004/01/31 13:43:57 ganter
+nasamaps are working better, but still bugs
+
+Revision 1.4 2004/01/31 08:27:22 ganter
+i hope the nasa maps work all over the world
+I expect it works not in australia, will see after i get a little bit sleep
+
+Revision 1.3 2004/01/31 06:24:21 ganter
+nasa maps at lon=0 works now
+
+Revision 1.2 2004/01/31 04:16:49 ganter
+...
+
+Revision 1.1 2004/01/31 04:11:01 ganter
+oh, forgot to add to CVS
+
+Revision 1.1 2004/01/30 22:20:44 ganter
+convnasamap creates mapfiles from the big nasa map files
+
+
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <math.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gpsdrive.h>
+#include "gpsdrive_config.h"
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+static char mybuffer[10000];
+static GtkWidget *nasawindow = NULL;
+extern int debug;
+static int fdin_w, fdin_e;
+static char outfilename[100], inputfilename_e[255], inputfilename_w[255];
+static int havenasamaps;
+int
+init_nasa_mapfile ()
+{
+
+ havenasamaps = FALSE;
+
+ if (local_config.dir_maps[strlen (local_config.dir_maps) - 1] != '/')
+ g_strlcat (local_config.dir_maps, "/", sizeof (local_config.dir_maps));
+
+
+ g_snprintf (outfilename, sizeof (outfilename), "%stop_NASA_IMAGE.ppm",
+ local_config.dir_maps);
+
+ g_snprintf (inputfilename_e, sizeof (inputfilename_e),
+ "%snasamaps/top_nasamap_east.raw", local_config.dir_home);
+
+ g_snprintf (inputfilename_w, sizeof (inputfilename_w),
+ "%snasamaps/top_nasamap_west.raw", local_config.dir_home);
+
+ fdin_e = open (inputfilename_e, O_RDONLY);
+ if (fdin_e >= 0)
+ havenasamaps = TRUE;
+ fdin_w = open (inputfilename_w, O_RDONLY);
+ if (fdin_w >= 0)
+ havenasamaps = TRUE;
+
+ return 0;
+}
+
+void
+cleanup_nasa_mapfile ()
+{
+ if (fdin_w >= 0)
+ close (fdin_w);
+ if (fdin_e >= 0)
+ close (fdin_e);
+}
+
+int
+create_nasa_mapfile (double lat, double lon, int test, char *fn)
+{
+ /* lat,lon= koordinates */
+ /* test= test if maps are present */
+ /* fn = filename of the generated file */
+ int fdout, uc = 0;
+ int scale, e, xsize_e, xsize_w;
+ int xstart, ystart, y, x_w, x_e;
+ double mylon;
+ GtkWidget *myprogress, *text, *vbox;
+ char textbuf[40];
+
+ if (!havenasamaps)
+ return -1;
+
+ scale = 2614061;
+ mylon = lon;
+
+ g_strlcpy (fn, "nofile.sorry", 255);
+
+ /* return if no map found */
+ if (lon > 0)
+ {
+ xstart = (int) (21600.0 * (lon / 180.0));
+ if (((xstart < 1280) || (xstart > 20320)) && (fdin_w < 0))
+ return -1;
+ if (fdin_e < 0)
+ return -1;
+ }
+ else
+ {
+ lon = 180.0 + lon;
+ xstart = (int) (21600.0 * (lon / 180.0));
+ if (((xstart < 1280) || (xstart > 20320)) && (fdin_e < 0))
+ return -1;
+ if (fdin_w < 0)
+ return -1;
+ }
+
+ if (!test)
+ {
+ fdout = open (outfilename, O_RDWR | O_TRUNC | O_CREAT, 0644);
+ if (fdout < 0)
+ {
+ fprintf (stderr,
+ _("could not create output map file %s!\n"),
+ outfilename);
+ return -1;
+ }
+
+ nasawindow = gtk_window_new (GTK_WINDOW_POPUP);
+ vbox = gtk_vbox_new (FALSE, 6);
+ gtk_container_add (GTK_CONTAINER (nasawindow), vbox);
+
+ gtk_window_set_position (GTK_WINDOW (nasawindow),
+ GTK_WIN_POS_CENTER);
+
+ /* g_signal_connect (window, "destroy", */
+ /* G_CALLBACK (gtk_widget_destroyed), &window); */
+
+ gtk_window_set_title (GTK_WINDOW (nasawindow),
+ _("Creating map..."));
+ gtk_container_set_border_width (GTK_CONTAINER (nasawindow),
+ 20);
+
+ myprogress = gtk_progress_bar_new ();
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (myprogress),
+ 0.0);
+ gtk_box_pack_start (GTK_BOX (vbox), myprogress, TRUE, TRUE,
+ 2);
+ text = gtk_label_new (_
+ ("Creating a temporary map from NASA satellite images"));
+ gtk_box_pack_start (GTK_BOX (vbox), text, TRUE, TRUE, 2);
+
+ /* gtk_widget_show_all (nasawindow); */
+ gtk_widget_show_all (nasawindow);
+ if (debug)
+ fprintf (stdout,
+ _
+ ("converting map for latitude: %f and longitude: %f ...\n"),
+ lat, lon);
+
+ /* if (lon < 0.0) */
+ /* lon = 180.0 + lon; */
+ g_strlcpy (fn, "top_NASA_IMAGE.ppm", 255);
+
+
+ g_snprintf (mybuffer, sizeof (mybuffer),
+ "P6\n# CREATOR: GpsDrive\n1280 1024\n255\n");
+
+ e = write (fdout, mybuffer, strlen (mybuffer));
+ uc = e;
+ lon = mylon;
+ xstart = (int) (21600.0 * (lon / 180.0));
+
+ ystart = 3 * 21600 * (int) (10800 - 10800.0 * (lat / 90.0));
+
+ /* fprintf (stdout, "xstart: %d, ystart: %d\n", xstart, ystart); */
+ xstart -= 640;
+ ystart = ystart - 512 * 21600 * 3;
+
+ x_w = x_e = -1;
+ xsize_w = xsize_e = 1280;
+
+ if (xstart < 0)
+ {
+ x_w = 21600 + xstart;
+ x_e = 1280 - x_w;
+
+ if (x_e < -20320)
+ x_e = -1;
+ else if (x_e < 0)
+ x_e = 0;
+
+ if (x_w < -20320)
+ x_w = -1;
+ else if (x_w < 0)
+ x_w = 0;
+ xsize_w = 21600 - x_w;
+ xsize_e = 1280 - xsize_w;
+ }
+ else if (xstart > 20320)
+ {
+ x_w = (xstart + 1280) - 21600;
+ x_e = 1280 - x_w;
+ if (x_e < 20320)
+ x_e = -1;
+ if (x_e < 0)
+ x_e = 0;
+ xsize_w = x_w;
+ xsize_e = 1280 - xsize_w;
+ }
+ else
+ {
+ if (mylon >= 0.0)
+ x_e = xstart;
+ else
+ x_w = xstart;
+ }
+ if (xsize_w > 1280)
+ xsize_w = 1280;
+ if (xsize_e > 1280)
+ xsize_e = 1280;
+ x_w *= 3;
+ x_e *= 3;
+
+ for (y = 0; y < 1024; y++)
+ {
+ if ((y % 32) == 0)
+ {
+ gtk_progress_bar_set_fraction
+ (GTK_PROGRESS_BAR (myprogress),
+ y / 1024.0);
+ g_snprintf (textbuf, sizeof (textbuf), "%d%%",
+ (int) (100.0 * y / 1024));
+ gtk_progress_bar_set_text (GTK_PROGRESS_BAR
+ (myprogress),
+ textbuf);
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+
+ }
+
+ if (x_w != -3)
+ {
+ e = lseek (fdin_w,
+ x_w + ystart + y * 21600 * 3,
+ SEEK_SET);
+ e = read (fdin_w, mybuffer, xsize_w * 3);
+ e = write (fdout, mybuffer, xsize_w * 3);
+ uc += e;
+ }
+ if (x_e != -3)
+ {
+ e = lseek (fdin_e,
+ x_e + ystart + y * 21600 * 3,
+ SEEK_SET);
+ e = read (fdin_e, mybuffer, xsize_e * 3);
+ e = write (fdout, mybuffer, xsize_e * 3);
+ uc += e;
+ }
+ }
+ /* fprintf (stderr, "wrote %d bytes (%.1f MB) to mapfile\n", uc, */
+ /* uc / (1024.0 * 1024.0)); */
+
+ gtk_widget_destroy (GTK_WIDGET (nasawindow));
+ close (fdout);
+ g_strlcpy (mybuffer, g_basename (outfilename),
+ sizeof (mybuffer));
+ fprintf (stdout,
+ _
+ ("\nYou can permanently add this map file with following line in your\nmap_koord.txt (rename the file!):\n"));
+ fprintf (stdout, "\n%s %f %f %d\n", mybuffer, lat, lon,
+ scale);
+
+ } /* End of if !test */
+
+
+ return scale;
+}
diff --git a/src/gpsproto.h b/src/gpsproto.h
new file mode 100644
index 0000000..667dacf
--- /dev/null
+++ b/src/gpsproto.h
@@ -0,0 +1,105 @@
+/* *********************************************************************** */
+/* Prototypes */
+int initkismet (void);
+void get_poi_type_id_for_wlan();
+int readkismet (void);
+int deletesqldata (int index);
+glong insertsqldata (double lat, double lon, char *name, char *typ, char *comment, int source);
+gint insertsqlextradata (glong *poi_id, gchar *field_name, gchar *field_entry);
+glong updatesqldata (glong poi_id, double lat, double lon, char *name, char *typ, char *comment, int source);
+gint updatesqlextradata (glong *poi_id, gchar *field_name, gchar *field_entry);
+glong getsqlextradata (glong *poi_id, gchar *field_name, gchar *field_entry, gchar *result);
+int sqlinit (void);
+void sqlend (void);
+int getsqldata ();
+int loadmap (char *filename);
+gint zoom_cb (GtkWidget * widget, guint datum);
+void show_splash (void);
+int garblemain (int argc, char **argv);
+void display_status (char *message);
+gint drawmarker (GtkWidget * widget, guint * datum);
+gint downloadslave_cb (GtkWidget * widget, guint datum);
+gint downloadstart_cb (GtkWidget * widget, guint datum);
+gint downloadsetparm (GtkWidget * widget, guint datum);
+void savemapconfig ();
+gint loadmapconfig ();
+void loadwaypoints ();
+void savewaypoints ();
+void storepoint();
+void speech_out_speek (char *text);
+gint speech_out_init ();
+gdouble calcdist (gdouble lon, gdouble lat);
+gdouble calcdist2 (gdouble lon, gdouble lat);
+gdouble calc_wpdist (gdouble lon1, gdouble lat1, gdouble lon2, gdouble lat2, gint from_current);
+gint speech_saytime_cb (GtkWidget * widget, guint datum);
+gint help_cb (GtkWidget * widget, guint datum);
+gint sel_target_cb (GtkWidget * widget, guint datum);
+gint import1_cb (GtkWidget * widget, guint datum);
+
+gint friendsagent_cb (GtkWidget * widget, guint * datum);
+gint addwaypoint_cb (GtkWidget * widget, gpointer datum);
+void writeconfig ();
+void readconfig ();
+gint create_route_cb (GtkWidget * widget, guint datum);
+void insertroutepoints ();
+void setroutetarget ();
+gint initgps ();
+gint defaultserver_cb (GtkWidget * widget, guint datum);
+gint expose_sats_cb (GtkWidget * widget, guint * datum);
+gint usedgps_cb (GtkWidget * widget, guint datum);
+void saytargettext (gchar * filename, gchar * target);
+void display_dsc (void);
+void coordinate2gchar (gchar * text, gint buff_size, gdouble pos, gint islat, gint mode);
+void checkinput (gchar * text);
+void mintodecimal (gchar * text);
+void mainsetup (void);
+void testifnight (void);
+void infos (void);
+gint removesetutc (GtkWidget * widget, guint datum);
+gint nav_doit (GtkWidget * widget, guint * datum);
+gint expose_cb (GtkWidget * widget, guint * datum);
+gint expose_compass (GtkWidget * widget, guint * datum);
+gint dotripmeter (GtkWidget * widget, guint datum);
+void trip (void);
+gint expose_mini_cb (GtkWidget * widget, guint * datum);
+void speech_out_speek_raw (char *text);
+void setup_poi (void);
+gint tripreset ();
+int friends_sendmsg (char *serverip, char *message);
+int friends_init ();
+void friendssetup (void);
+char *getexpediaurl ();
+gint quit_program_cb (GtkWidget * widget, gpointer datum);
+gint loadtrack_cb (GtkWidget * widget, gpointer datum);
+gint about_cb (GtkWidget * widget, guint datum);
+gint settings_main_cb (GtkWidget *widget, guint datum);
+gint sel_message_cb (GtkWidget * widget, guint datum);
+gint setmessage_cb (GtkWidget * widget, guint datum);
+void signalposreq ();
+gint reinsertwp_cb (GtkWidget * widget, guint datum);
+GdkPixbuf *create_pixbuf (const gchar * filename);
+gint simulated_pos (GtkWidget * widget, guint * datum);
+void speech_out_close (void);
+int create_nasa_mapfile (double lat, double lon, int test, char *fn);
+int init_nasa_mapfile ();
+void cleanup_nasa_mapfile ();
+gint checksum (gchar * text);
+gint earthmate_cb (GtkWidget * widget, guint datum);
+void daylights (void);
+gint setutc (GtkWidget * widget, guint datum);
+G_MODULE_EXPORT gint modulesetup ();
+gint message_cb (char *msgid, char *name, char *text, int fs);
+void exiterr (int exitcode);
+void calcxy (gdouble * posx, gdouble * posy, gdouble lon, gdouble lat, gint zoom);
+void minimap_xy2latlon(gint x, gint y, gdouble *lon, gdouble *lat, gdouble *dif);
+void rebuildtracklist (void);
+gint error_popup (gpointer datum);
+void calcxymini (gdouble * posx, gdouble * posy, gdouble lon, gdouble lat,
+ gint zoom);
+gdouble calcR (gdouble lat);
+void calcxytopos (int , int , gdouble *, gdouble *, int );
+gint navi_cb (GtkWidget * widget, guint datum);
+GtkWidget* create_pixmap(GtkWidget *widget, const gchar *filename);
+gint speech_out_cb (GtkWidget * widget, guint * datum);
+gchar *escape_sql_string (const gchar *data);
+
diff --git a/src/gpssql.c b/src/gpssql.c
new file mode 100644
index 0000000..fe11891
--- /dev/null
+++ b/src/gpssql.c
@@ -0,0 +1,634 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ *********************************************************************
+*/
+
+#include "../config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <gpsdrive.h>
+#include <ctype.h>
+#include <dlfcn.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+#include <icons.h>
+#include <poi.h>
+
+#define MAXDBNAME 30
+extern char dbhost[MAXDBNAME], dbuser[MAXDBNAME], dbpass[MAXDBNAME];
+extern char dbtable[MAXDBNAME], dbname[MAXDBNAME], poitypetable[MAXDBNAME];
+extern double dbdistance;
+extern int usesql;
+extern int mydebug, dbusedist;
+extern GtkWidget *trackbt, *wpbt;
+extern GdkPixbuf *friendsimage, *friendspixbuf;
+extern poi_type_struct poi_type_list[poi_type_list_max];
+
+gint wptotal = 0, wpselected = 0;
+
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+
+/*****************************************************************
+change this functions if you want to implement another database
+******************************************************************/
+
+
+#include "mysql/mysql.h"
+
+MYSQL mysql;
+MYSQL_RES *res;
+MYSQL_ROW row;
+//res = NULL; // Set res as default NULL
+
+/* ******************************************************************
+ */
+void
+exiterr (int exitcode)
+{
+
+ fprintf (stderr, "Error while using mysql\n");
+ fprintf (stderr, "%s\n", dl_mysql_error (&mysql));
+ exit (exitcode);
+}
+
+
+/* ******************************************************************
+ * remove route and friendsd data at shutdown
+ */
+gint
+cleanupsqldata ()
+{
+ gchar q[200];
+ gint r, i;
+
+ if (!usesql)
+ return 0;
+
+ for (i = 0; i < poi_type_list_max; i++)
+ {
+ if (
+ strncmp (poi_type_list[i].name,"waypoint.routepoint", 19) == 0 ||
+ strncmp (poi_type_list[i].name,"people.friendsd", 15) == 0)
+ {
+ g_snprintf (q, sizeof (q),
+ "DELETE FROM %s WHERE poi_type_id=\"%d\";",
+ dbtable, poi_type_list[i].poi_type_id);
+ if (mydebug > 50)
+ g_print ("query: %s\n", q);
+ if (dl_mysql_query (&mysql, q))
+ exiterr (3);
+ r = dl_mysql_affected_rows (&mysql);
+ if (mydebug > 50)
+ g_print (_("rows deleted: %d\n"), r);
+ }
+ }
+
+ return 0;
+}
+
+
+/* ******************************************************************
+ */
+int
+sqlinit (void)
+{
+ if (!usesql)
+ return 0;
+
+ if (!(dl_mysql_init (&mysql)))
+ exiterr (1);
+
+ if (!
+ (dl_mysql_real_connect
+ (&mysql, dbhost, dbuser, dbpass, dbname, 0, NULL, 0)))
+ {
+ fprintf (stderr, "%s\n", dl_mysql_error (&mysql));
+ return FALSE;
+ }
+ /* if ( mydebug > 50 ) */
+ printf (_("SQL: connected to %s as %s using %s\n"), dbhost, dbuser, dbname);
+ return TRUE;
+}
+
+/* ******************************************************************
+ */
+void
+sqlend (void)
+{
+ if (!usesql)
+ return;
+ cleanupsqldata ();
+ dl_mysql_close (&mysql);
+}
+
+
+/* ******************************************************************
+ * escape special characters in sql string.
+ * returned string has to be freed after usage!
+ */
+gchar
+*escape_sql_string (const gchar *data)
+{
+ gint i, j, length;
+ gchar *tdata = NULL;
+
+ length = strlen (data);
+ tdata = g_malloc (length*2 + 1);
+ j = 0;
+ for (i = 0; i <= length; i++)
+ {
+ if (data[i] == '\'' || data[i] == '\\' || data[i] == '\"')
+ tdata[j++] = '\\';
+ tdata[j++] = data[i];
+ }
+
+ if (mydebug > 50)
+ g_print ("escape_sql_string:\tOrig. name : %s\nescape_sql_string:\tEscaped name : %s\n", data, tdata);
+
+ return tdata;
+}
+
+
+/* ******************************************************************
+ * insert poi data into poi table
+ */
+glong
+insertsqldata (double lat, double lon, gchar *name, gchar *typ, gchar *comment, gint src)
+{
+ gchar q[200], lats[20], lons[20];
+ gchar *tname, *ttyp, *tcomment;
+ gint pt_id;
+ glong r;
+
+ if (!usesql)
+ return 0;
+ g_snprintf (lats, sizeof (lats), "%.6f", lat);
+ g_strdelimit (lats, ",", '.');
+ g_snprintf (lons, sizeof (lons), "%.6f", lon);
+ g_strdelimit (lons, ",", '.');
+
+ /* escape ' */
+ tname = escape_sql_string (name);
+ ttyp = escape_sql_string (typ);
+ tcomment = escape_sql_string (comment);
+
+ /* get poi_type_id for chosen poi_type from poi_type table */
+ pt_id = poi_type_id_from_name (ttyp);
+
+ /* set source_id at value for 'user entered data'if none is given */
+ if (!src)
+ src = 3;
+
+ g_snprintf (q, sizeof (q),
+ "INSERT INTO %s (name,lat,lon,poi_type_id,comment,source_id,last_modified) VALUES ('%s','%s','%s','%d','%s','%d',NOW())",
+ dbtable, tname, lats, lons, pt_id, tcomment, src);
+ if (mydebug > 50)
+ printf ("query: %s\n", q);
+ if (dl_mysql_query (&mysql, q))
+ exiterr (3);
+ r = dl_mysql_affected_rows (&mysql);
+ if (mydebug > 50)
+ printf (_("rows inserted: %ld\n"), r);
+
+ g_snprintf (q, sizeof (q), "SELECT LAST_INSERT_ID()");
+ if (mydebug > 50)
+ printf ("insertsqldata: query: %s\n", q);
+ if (dl_mysql_query (&mysql, q))
+ exiterr (3);
+ if (!(res = dl_mysql_store_result (&mysql)))
+ {
+ dl_mysql_free_result (res);
+ res = NULL;
+ fprintf (stderr, "insert_sql_data: Error in store results: %s\n",
+ dl_mysql_error (&mysql));
+ return -1;
+ }
+ r = 0;
+ while ((row = dl_mysql_fetch_row (res)))
+ {
+ r = strtol (row[0], NULL, 10); /* last index */
+ }
+
+ if (mydebug > 50)
+ printf (_("last index: %ld\n"), r);
+
+ g_free (ttyp);
+ g_free (tname);
+ g_free (tcomment);
+
+ return r;
+}
+
+
+/* ******************************************************************
+ * update poi data in poi table
+ */
+glong
+updatesqldata (glong poi_id, double lat, double lon, gchar *name, gchar *typ, gchar *comment, gint src)
+{
+ gchar q[200], lats[20], lons[20];
+ gchar *tname, *ttyp, *tcomment;
+ gint pt_id;
+ glong r;
+
+ if (!usesql)
+ return 0;
+ g_snprintf (lats, sizeof (lats), "%.6f", lat);
+ g_strdelimit (lats, ",", '.');
+ g_snprintf (lons, sizeof (lons), "%.6f", lon);
+ g_strdelimit (lons, ",", '.');
+
+ /* escape ' */
+ tname = escape_sql_string (name);
+ ttyp = escape_sql_string (typ);
+ tcomment = escape_sql_string (comment);
+
+ /* get poi_type_id for chosen poi_type from poi_type table */
+ pt_id = poi_type_id_from_name (ttyp);
+
+ /* set source_id at value for 'user entered data'if none is given */
+ if (!src)
+ src = 3;
+
+ g_snprintf (q, sizeof (q),
+ "UPDATE %s SET name='%s', lat='%s', lon='%s', poi_type_id='%d', comment='%s', source_id='%d', last_modified=NOW() WHERE poi_id=%ld", dbtable, tname, lats, lons, pt_id, tcomment, src, poi_id);
+ if (mydebug > 50)
+ printf ("update query: %s\n", q);
+ if (dl_mysql_query (&mysql, q))
+ exiterr (3);
+ r = dl_mysql_affected_rows (&mysql);
+ if (mydebug > 50)
+ printf (_("rows updated: %ld\n"), r);
+
+ return r;
+}
+
+
+/* ******************************************************************
+ * insert additional poi data into poi_extra table
+ */
+int
+insertsqlextradata (glong *poi_id, gchar *field_name, gchar *field_entry)
+{
+ char q[9000];
+ gchar *tentry;
+ int r;
+
+ /* escape ' */
+ tentry = escape_sql_string (field_entry);
+
+ g_snprintf (q, sizeof (q),
+ "INSERT INTO poi_extra (poi_id, field_name, entry) VALUES ('%ld','%s','%s')", *poi_id, field_name, tentry);
+ if (mydebug > 50)
+ printf ("query: %s\n", q);
+ if (dl_mysql_query (&mysql, q))
+ exiterr (3);
+ r = dl_mysql_affected_rows (&mysql);
+ if (mydebug > 50)
+ printf (_("rows inserted: %d\n"), r);
+
+ g_snprintf (q, sizeof (q), "SELECT LAST_INSERT_ID()");
+ if (mydebug > 50)
+ printf ("insertsqldata: query: %s\n", q);
+ if (dl_mysql_query (&mysql, q))
+ exiterr (3);
+ if (!(res = dl_mysql_store_result (&mysql)))
+ {
+ dl_mysql_free_result (res);
+ res = NULL;
+ fprintf (stderr, "insertsqlextradata: Error in store results: %s\n",
+ dl_mysql_error (&mysql));
+ return -1;
+ }
+ r = 0;
+ while ((row = dl_mysql_fetch_row (res)))
+ {
+ r = strtol (row[0], NULL, 10); /* last index */
+ }
+
+ if (mydebug > 50)
+ printf (_("last index: %d\n"), r);
+ return r;
+}
+
+/* ******************************************************************
+ * update additional poi data in poi_extra table
+ */
+int
+updatesqlextradata (glong *poi_id, gchar *field_name, gchar *field_entry)
+{
+ char q[9000];
+ gchar *tentry, *tfield;
+ int r;
+
+ /* escape ' */
+ tfield = escape_sql_string (field_name);
+ tentry = escape_sql_string (field_entry);
+
+ g_snprintf (q, sizeof (q),
+ "UPDATE poi_extra SET entry='%s' WHERE (poi_id=%ld AND field_name='%s')", tentry, *poi_id, field_name);
+ if (mydebug > 50)
+ printf ("update query: %s\n", q);
+ if (dl_mysql_query (&mysql, q))
+ exiterr (3);
+ r = dl_mysql_affected_rows (&mysql);
+ if (mydebug > 50)
+ printf (_("rows updated: %d\n"), r);
+
+ return r;
+}
+
+
+/* ******************************************************************
+ * get additional poi data from poi_extra table
+ *
+ * You have to set at least two parameters; set the one you are
+ * asking for to NULL.
+ * The return value is the poi_id.
+ */
+glong
+getsqlextradata (glong *poi_id, gchar *field_name, gchar *field_entry, gchar *result)
+{
+ gchar sql_query[5000];
+ glong result_id = 0;
+
+ if (field_entry == NULL)
+ {
+ g_snprintf (sql_query, sizeof (sql_query),
+ "SELECT poi_id,entry FROM poi_extra "
+ "WHERE (poi_id='%ld' AND field_name='%s') LIMIT 1;",
+ *poi_id, field_name);
+ }
+ else if (poi_id == NULL)
+ {
+ g_snprintf (sql_query, sizeof (sql_query),
+ "SELECT poi_id FROM poi_extra "
+ "WHERE (field_name='%s' AND entry='%s') LIMIT 1;",
+ field_name, field_entry);
+ }
+ else if (field_name == NULL)
+ {
+ g_snprintf (sql_query, sizeof (sql_query),
+ "SELECT poi_id,field_id FROM poi_extra "
+ "WHERE (poi_id='%ld' AND entry='%s') LIMIT 1;",
+ *poi_id, field_entry);
+ }
+ else
+ return 0;
+
+ if (mydebug > 20)
+ printf ("getsqlextradata: mysql query: %s\n", sql_query);
+
+ if (dl_mysql_query (&mysql, sql_query))
+ {
+ fprintf (stderr, "getsqlextradata: Error in query: %s\n",
+ dl_mysql_error (&mysql));
+ return 0;
+ }
+ res = dl_mysql_store_result (&mysql);
+ row = dl_mysql_fetch_row (res);
+ if (!row)
+ return 0;
+ else
+ {
+ result_id = strtol (row[0], NULL, 10);
+ if (row[1])
+ result = g_strdup (row[1]);
+ }
+ dl_mysql_free_result (res);
+ res = NULL;
+ return result_id;
+}
+
+
+/* ******************************************************************
+ */
+int
+deletesqldata (int index)
+{
+ char q[200];
+ int r;
+
+ if (!usesql)
+ return 0;
+ g_snprintf (q, sizeof (q), "DELETE FROM %s WHERE poi_id='%d'", dbtable, index);
+ if (mydebug > 50)
+ g_print ("query: %s\n", q);
+
+ if (dl_mysql_query (&mysql, q))
+ exiterr (3);
+ r = dl_mysql_affected_rows (&mysql);
+ if (mydebug > 50)
+ g_print (_("rows deleted: %d\n"), r);
+ return 0;
+}
+
+
+/* ******************************************************************
+ */
+int
+getsqldata ()
+{
+ if (!usesql)
+ return FALSE;
+
+ poi_rebuild_list();
+
+ return TRUE;
+}
+
+/* *****************************************************************************
+ * Load mysql libraries and connect to function calls
+ */
+void
+sql_load_lib ()
+{
+ void *handle;
+ char *error;
+
+ usesql = TRUE;
+ // It seems like this doesn't work on cygwin unless the dlopen comes first..-jc
+ if (usesql)
+ {
+ handle = dlopen ("/usr/local/lib/libmysqlclient.dll", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("libmysqlclient.so", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("libmysqlclient.so.17", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("libmysqlclient.so.16", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("libmysqlclient.so.15", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("libmysqlclient.so.14", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("libmysqlclient.so.12", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("libmysqlclient.so.10", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/opt/lib/mysql/libmysqlclient.so", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/opt/lib/mysql/libmysqlclient.so.10", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/opt/mysql/lib/libmysqlclient.so", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/opt/mysql/lib/libmysqlclient.so.10", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/sw/lib/libmysqlclient.dylib", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/usr/lib/libmysqlclient.so", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/usr/lib/libmysqlclient.so.12", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/usr/lib/libmysqlclient.so.10", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/usr/lib/mysql/libmysqlclient.so", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/usr/lib/mysql/libmysqlclient.so.12", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/usr/lib/mysql/libmysqlclient.so.10", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/usr/local/lib/libmysqlclient.so", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/usr/local/lib/libmysqlclient.so.10", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/usr/local/lib/mysql/libmysqlclient.so", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen
+ ("/usr/local/lib/mysql/libmysqlclient.so.10", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/usr/local/mysql/libmysqlclient.so", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen ("/usr/local/mysql/libmysqlclient.so.10", RTLD_LAZY);
+ if (!handle)
+ handle = dlopen
+ ("@PREFIX@/lib/mysql/libmysqlclient.10.dylib", RTLD_LAZY);
+
+ if (handle)
+ {
+ // Clear previous errors
+ dlerror ();
+
+ dl_mysql_error = dlsym (handle, "mysql_error");
+ if ((error = dlerror ()) != NULL)
+ {
+ fprintf (stderr, "%s\n", error);
+ usesql = FALSE;
+ }
+
+ dl_mysql_init = dlsym (handle, "mysql_init");
+ if ((error = dlerror ()) != NULL)
+ {
+ fprintf (stderr, "%s\n", error);
+ usesql = FALSE;
+ }
+
+
+ dl_mysql_real_connect = dlsym (handle, "mysql_real_connect");
+ if ((error = dlerror ()) != NULL)
+ {
+ fprintf (stderr, "%s\n", error);
+ usesql = FALSE;
+ }
+
+
+ dl_mysql_close = dlsym (handle, "mysql_close");
+ if ((error = dlerror ()) != NULL)
+ {
+ fprintf (stderr, "%s\n", error);
+ usesql = FALSE;
+ }
+
+
+ dl_mysql_query = dlsym (handle, "mysql_query");
+ if ((error = dlerror ()) != NULL)
+ {
+ fprintf (stderr, "%s\n", error);
+ usesql = FALSE;
+ }
+
+
+ dl_mysql_affected_rows = dlsym (handle, "mysql_affected_rows");
+ if ((error = dlerror ()) != NULL)
+ {
+ fprintf (stderr, "%s\n", error);
+ usesql = FALSE;
+ }
+
+
+ dl_mysql_store_result = dlsym (handle, "mysql_store_result");
+ if ((error = dlerror ()) != NULL)
+ {
+ fprintf (stderr, "%s\n", error);
+ usesql = FALSE;
+ }
+
+
+ dl_mysql_fetch_row = dlsym (handle, "mysql_fetch_row");
+ if ((error = dlerror ()) != NULL)
+ {
+ fprintf (stderr, "%s\n", error);
+ usesql = FALSE;
+ }
+
+
+ dl_mysql_free_result = dlsym (handle, "mysql_free_result");
+ if ((error = dlerror ()) != NULL)
+ {
+ fprintf (stderr, "%s\n", error);
+ usesql = FALSE;
+ }
+
+
+ dl_mysql_eof = dlsym (handle, "mysql_eof");
+ if ((error = dlerror ()) != NULL)
+ {
+ fprintf (stderr, "%s\n", error);
+ usesql = FALSE;
+ }
+ }
+ else if ((error = dlerror ()) != NULL)
+ {
+ fprintf (stderr, _("\nlibmysqlclient.so not found.\n"));
+ usesql = FALSE;
+ }
+ /* dlclose(handle); */
+ }
+ if (!usesql)
+ fprintf (stderr, _("\nMySQL support disabled.\n"));
+
+}
diff --git a/src/gui.c b/src/gui.c
new file mode 100644
index 0000000..418ad58
--- /dev/null
+++ b/src/gui.c
@@ -0,0 +1,867 @@
+/*
+**********************************************************************
+
+Copyright (c) 2001-2007 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+
+Copyright (c) 2007 Ross Scanlon <ross@theinternethost.com.au>
+
+Website: www.4x4falcon.com/gpsdrive/
+
+Disclaimer: Please do not use for navigation.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+**********************************************************************
+*/
+
+ /*
+ * gui.c
+ * The purpose of this module is to do the setup
+ * and resizing of user interface for gspdrive
+ */
+
+ /*
+ 4 Feb 2007 Version 0.1
+ Move sizing of window to this file from gpsdrive.c
+ */
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <math.h>
+#include <gpsdrive.h>
+#include <icons.h>
+#include <config.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <gdk/gdktypes.h>
+#include "gtk/gtk.h"
+#include "gettext.h"
+#include "gpsdrive.h"
+#include "gpsdrive_config.h"
+#include "gui.h"
+#include "poi.h"
+#include "poi_gui.h"
+#include "main_gui.h"
+#include "routes.h"
+#include "track.h"
+
+/* Defines for gettext I18n */
+#include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+#define PFSIZE 15
+
+extern gint do_unit_test;
+
+ /* External Values */
+
+extern gint mydebug;
+extern gint debug;
+
+extern GtkTreeStore *poi_types_tree;
+extern GtkListStore *poi_result_tree;
+extern GtkListStore *route_list_tree;
+
+extern gdouble wp_saved_target_lat;
+extern gdouble wp_saved_target_lon;
+extern gdouble wp_saved_posmode_lat;
+extern gdouble wp_saved_posmode_lon;
+extern gint usesql;
+extern color_struct colors;
+extern currentstatus_struct current;
+
+extern GtkWidget *poi_types_window;
+
+// Some of these shouldn't be necessary, when all the gui stuff is finally moved
+extern GtkWidget *find_poi_bt;
+extern GtkWidget *map_drawingarea;
+extern GdkGC *kontext_map;
+
+extern gint real_screen_x, real_screen_y, real_psize, real_smallmenu;
+extern gint SCREEN_X_2, SCREEN_Y_2;
+
+GdkColormap *colmap;
+color_struct colors;
+guistatus_struct gui_status;
+
+GdkPixbuf *posmarker_img, *targetmarker_img;
+GdkCursor *cursor_cross;
+GdkCursor *cursor_watch;
+
+gint PSIZE;
+
+extern gint borderlimit;
+
+extern gdouble posx, posy;
+
+GtkWidget *main_window;
+
+
+/* included from freedesktop.org source, copyright as below do not change anything in between here and function get_window_sizing */
+
+/*
+
+Copyright 1985, 1986, 1987,1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+/* $XFree86: xc/lib/X11/ParseGeom.c,v 1.2 2001/10/28 03:32:30 tsi Exp $ */
+
+/*
+ #include "Xlibint.h"
+ #include "Xutil.h"
+*/
+
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+
+#ifdef notdef
+/*
+ *Returns pointer to first char ins search which is also in what, else NULL.
+ */
+static char *strscan (search, what)
+ char *search, *what;
+{
+ int i, len = strlen (what);
+ char c;
+
+ while ((c = *(search++)) != NULL)
+ for (i = 0; i < len; i++)
+ if (c == what [i])
+ return (--search);
+ return (NULL);
+}
+#endif
+
+/*
+ * XParseGeometry parses strings of the form
+ * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
+ * width, height, xoffset, and yoffset are unsigned integers.
+ * Example: "=80x24+300-49"
+ * The equal sign is optional.
+ * It returns a bitmask that indicates which of the four values
+ * were actually found in the string. For each value found,
+ * the corresponding argument is updated; for each value
+ * not found, the corresponding argument is left unchanged.
+ */
+
+static int
+ReadInteger(char *string, char **NextString)
+{
+ register int Result = 0;
+ int Sign = 1;
+
+ if (*string == '+')
+ string++;
+ else if (*string == '-')
+ {
+ string++;
+ Sign = -1;
+ }
+ for (; (*string >= '0') && (*string <= '9'); string++)
+ {
+ Result = (Result * 10) + (*string - '0');
+ }
+ *NextString = string;
+ if (Sign >= 0)
+ return (Result);
+ else
+ return (-Result);
+}
+
+int XParseGeometry (
+ _Xconst char *string,
+ int *x,
+ int *y,
+ unsigned int *width, /* RETURN */
+ unsigned int *height) /* RETURN */
+{
+ int mask = NoValue;
+ register char *strind;
+ unsigned int tempWidth = 0, tempHeight = 0;
+ int tempX = 0, tempY = 0;
+ char *nextCharacter;
+
+ if ( (string == NULL) || (*string == '\0')) return(mask);
+ if (*string == '=')
+ string++; /* ignore possible '=' at beg of geometry spec */
+
+ strind = (char *)string;
+ if (*strind != '+' && *strind != '-' && *strind != 'x') {
+ tempWidth = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return (0);
+ strind = nextCharacter;
+ mask |= WidthValue;
+ }
+
+ if (*strind == 'x' || *strind == 'X') {
+ strind++;
+ tempHeight = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return (0);
+ strind = nextCharacter;
+ mask |= HeightValue;
+ }
+
+ if ((*strind == '+') || (*strind == '-')) {
+ if (*strind == '-') {
+ strind++;
+ tempX = -ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return (0);
+ strind = nextCharacter;
+ mask |= XNegative;
+
+ }
+ else
+ { strind++;
+ tempX = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return(0);
+ strind = nextCharacter;
+ }
+ mask |= XValue;
+ if ((*strind == '+') || (*strind == '-')) {
+ if (*strind == '-') {
+ strind++;
+ tempY = -ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return(0);
+ strind = nextCharacter;
+ mask |= YNegative;
+
+ }
+ else
+ {
+ strind++;
+ tempY = ReadInteger(strind, &nextCharacter);
+ if (strind == nextCharacter)
+ return(0);
+ strind = nextCharacter;
+ }
+ mask |= YValue;
+ }
+ }
+
+ /* If strind isn't at the end of the string the it's an invalid
+ geometry specification. */
+
+ if (*strind != '\0') return (0);
+
+ if (mask & XValue)
+ *x = tempX;
+ if (mask & YValue)
+ *y = tempY;
+ if (mask & WidthValue)
+ *width = tempWidth;
+ if (mask & HeightValue)
+ *height = tempHeight;
+ return (mask);
+}
+
+
+/* do not change the above */
+
+/****
+ function get_window_sizing
+ This creates the main window sizing from either --geometry or based on screen size if no --geometry
+ as at 4 February 2007 will also use -s -r from command line but will be removed eventually
+****/
+
+int get_window_sizing (gchar *geom, gint usegeom, gint screen_height, gint screen_width) {
+
+ int ret;
+ uint width, height;
+ int x, y;
+
+
+
+ if ( mydebug >= 0 ) {
+ fprintf (stderr, "Creating main window\n");
+ }
+
+ /*** do we have geometry from the command line ***/
+
+ if (usegeom) {
+
+ ret = XParseGeometry (geom, &x, &y, &width, &height);
+
+
+ /* if geometry returns a width then use that otherwise use default for 640x480 */
+
+ if (ret & WidthValue) {
+ real_screen_x = width;
+ }
+ else {
+ real_screen_x = 630;
+ }
+
+ /* if geometry returns a height then use that otherwise use default for 640x480 */
+
+ if (ret & HeightValue) {
+ real_screen_y = height;
+ }
+ else {
+ real_screen_y = screen_height - YMINUS;
+ }
+ }
+ else {
+
+ /** from gpsdrive.c line 4773 to 4814 */
+
+ PSIZE = 50;
+ SMALLMENU = 0;
+ if (screen_height >= 1024) /* > 1280x1024 */
+ {
+ real_screen_x = min(1280,screen_width-300);
+ real_screen_y = min(1024,screen_height-200);
+ if ( mydebug > 0 )
+ g_print ("Set real Screen size to %d,%d\n",
+ real_screen_x,real_screen_y);
+
+ }
+ else if (screen_height >= 768) /* 1024x768 */
+ {
+ real_screen_x = 800;
+ real_screen_y = 540;
+ }
+ else if (screen_height >= 750) /* 1280x800 */
+ {
+ real_screen_x = 1140;
+ real_screen_y = 600;
+ }
+ else if (screen_height >= 480) /* 640x480 */
+ {
+ if (screen_width == 0)
+ real_screen_x = 630;
+ else
+ real_screen_x = screen_width - XMINUS;
+ real_screen_y = screen_height - YMINUS;
+ }
+ else if (screen_height < 480)
+ {
+ if (screen_width == 0)
+ real_screen_x = 220;
+ else
+ real_screen_x = screen_width - XMINUS;
+ real_screen_y = screen_height - YMINUS;
+ PSIZE = 25;
+ SMALLMENU = 1;
+ }
+ } /*** if usegeom */
+
+ /** from gpsdrive.c line 4824 to 4857 */
+
+ if ((local_config.guimode == GUI_XWIN) && (screen_width != 0))
+ {
+ real_screen_x += XMINUS - 10;
+ real_screen_y += YMINUS - 30;
+ }
+
+ if ( ((screen_width == 240) && (screen_height == 320))
+ || ((screen_height == 240) && (screen_width == 320)) )
+ {
+ local_config.guimode = GUI_PDA;
+ // SMALLMENU = 1;
+ real_screen_x = screen_width - 8;
+ real_screen_y = screen_height - 70;
+ }
+ if (local_config.guimode == GUI_PDA)
+ {
+ g_print ("\nPDA mode\n");
+ }
+
+ if (real_screen_x < real_screen_y)
+ borderlimit = real_screen_x / 5;
+ else
+ borderlimit = real_screen_y / 5;
+
+ if (borderlimit < 30)
+ borderlimit = 30;
+
+ SCREEN_X_2 = SCREEN_X / 2;
+ SCREEN_Y_2 = SCREEN_Y / 2;
+ PSIZE = 50;
+ posx = SCREEN_X_2;
+ posy = SCREEN_Y_2;
+
+ if ( mydebug > 10 ) {
+ g_print ("Set real Screen size to %d,%d\n", real_screen_x,real_screen_y);
+ }
+
+ if ( mydebug > 10 ) {
+ g_print ("Screen size is %d,%d\n", screen_width,screen_height);
+ }
+
+ return 0;
+}
+
+
+/* *****************************************************************************
+ * Generic Callback to handle toggle- and checkbuttons
+ */
+int
+toggle_button_cb (GtkWidget *button, gboolean *value)
+{
+ *value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+
+ /* workaround for sav track button, should be changed */
+ if (value == &local_config.savetrack)
+ savetrackfile (1);
+
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ * Popup: Are you sure, y/n
+ */
+gint popup_yes_no (GtkWindow *parent, gchar *message)
+{
+ GtkDialog *dialog_yesno;
+ gint response_id;
+ gchar *question = "Are you sure?";
+
+ if (mydebug >10)
+ fprintf (stderr, "POPUP: Question\n");
+
+ dialog_yesno = GTK_DIALOG (gtk_message_dialog_new (parent,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_YES_NO,
+ "%s", question));
+ response_id = gtk_dialog_run (dialog_yesno);
+ gtk_widget_destroy (GTK_WIDGET (dialog_yesno));
+ return response_id;
+}
+
+/* *****************************************************************************
+ * Popup: Warning, ok
+ */
+gint popup_warning (GtkWindow *parent, gchar *message)
+{
+ GtkDialog *dialog_warning;
+ gchar warning[80];
+
+ if (mydebug >10)
+ fprintf (stderr, "POPUP: Warning\n");
+
+ if (!parent)
+ parent = GTK_WINDOW (main_window);
+ if (message)
+ g_strlcpy (warning, message, sizeof (warning));
+ else
+ g_strlcpy (warning, _("Press OK to continue!"),
+ sizeof (warning));
+
+ dialog_warning = GTK_DIALOG (gtk_message_dialog_new (parent,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_OK,
+ "%s", warning));
+
+ gdk_beep ();
+
+ g_signal_connect_swapped (dialog_warning, "response",
+ G_CALLBACK (gtk_widget_destroy), dialog_warning);
+ return TRUE;
+}
+
+/* *****************************************************************************
+ * Popup: Error, ok
+ */
+gint popup_error (GtkWindow *parent, gchar *message)
+{
+ GtkDialog *dialog_error;
+ gint response_id;
+ gchar error[80];
+
+ if (mydebug >10)
+ fprintf (stderr, "POPUP: Error\n");
+
+ if (!parent)
+ parent = GTK_WINDOW (main_window);
+ if (message)
+ g_strlcpy (error, message, sizeof (error));
+ else
+ g_strlcpy (error,
+ _("An error has occured.\nPress OK to continue!"),
+ sizeof (error));
+
+ dialog_error = GTK_DIALOG (gtk_message_dialog_new (parent,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ "%s", error));
+
+ gdk_beep ();
+
+ response_id = gtk_dialog_run (dialog_error);
+ gtk_widget_destroy (GTK_WIDGET (dialog_error));
+ return response_id;
+}
+
+/* *****************************************************************************
+ * Button: Add new Waypoint
+ */
+void create_button_add_wp (void)
+{
+ GtkWidget *add_wp_bt;
+ gchar imagefile[400];
+ GdkPixbuf *pixmap = NULL;
+
+ local_config.showaddwpbutton = TRUE; // TODO: add this to settings
+
+ if (local_config.showaddwpbutton)
+ {
+ g_snprintf (imagefile, sizeof (imagefile), "%s/gpsdrive/%s", DATADIR, "pixmaps/add_waypoint.png");
+ pixmap = gdk_pixbuf_new_from_file (imagefile, NULL);
+ if (imagefile == NULL)
+ {
+ fprintf (stderr, _("\nWarning: unable to open 'add waypoint' picture\nPlease install the program as root with:\nmake install\n\n"));
+ return;
+ }
+
+ add_wp_bt = gtk_button_new ();
+ gtk_button_set_relief (GTK_BUTTON (add_wp_bt), GTK_RELIEF_NONE);
+ gtk_button_set_image (GTK_BUTTON (add_wp_bt), GTK_WIDGET (pixmap));
+ gtk_container_add (GTK_CONTAINER (map_drawingarea), add_wp_bt);
+ gtk_widget_show_all (add_wp_bt);
+ return;
+ }
+ else
+ {
+ return;
+ }
+}
+
+
+/* *****************************************************************************
+ * parse the color string allocate the color
+ */
+static void
+init_color (gchar *tcolname, GdkColor *tcolor)
+{
+ gdk_color_parse (tcolname, tcolor);
+ gdk_colormap_alloc_color (colmap, tcolor, FALSE, TRUE);
+}
+
+/* *****************************************************************************
+ * get color string from GdkColor struct
+ * (needed to save settings in config file)
+ * returned string has to be freed after usage!
+ */
+gchar
+*get_colorstring (GdkColor *tcolor)
+{
+ guint r, g, b;
+ gchar *cstring;
+
+ r = tcolor->red / 256;
+ g = tcolor->green / 256;
+ b = tcolor->blue / 256;
+
+ cstring = g_malloc (sizeof (gchar)*7+1);
+ g_snprintf (cstring, 8, "#%02x%02x%02x", r, g, b);
+
+ if (mydebug > 20)
+ fprintf (stderr, "get_colorstring result: %s\n", cstring);
+
+ return cstring;
+}
+
+/* *****************************************************************************
+ * switch nightmode on or off
+ *
+ * TODO:
+ * Currently the Nightmode is represented by changing only the map
+ * colors, but the rest of the GUI stays the same.
+ * Maybe we should switch the gtk-theme instead, so that the complete
+ * GUI changes the colors. But this has time until after the 2007 release.
+ */
+gint switch_nightmode (gboolean value)
+{
+ if (value && !gui_status.nightmode)
+ {
+ gtk_widget_modify_bg (main_window, GTK_STATE_NORMAL,
+ &colors.nightmode);
+ gui_status.nightmode = TRUE;
+ //if (mydebug > 4)
+ fprintf (stderr, "setting to night view\n");
+ return TRUE;
+ }
+ else if (!value && gui_status.nightmode)
+ {
+ gtk_widget_modify_bg (main_window, GTK_STATE_NORMAL,
+ &colors.defaultcolor);
+ gui_status.nightmode = FALSE;
+ //if (mydebug > 4)
+ fprintf (stderr, "setting to daylight view\n");
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/* *****************************************************************************
+ * Draw position marker, also showing direction
+ * style sets the pinter style to be drawn:
+ * 0 = full circle position pointer
+ * 1 = only arrow pointer
+ * 2 = only light crosshair pointer
+ * 3 = plus sign
+ */
+gboolean
+draw_posmarker (
+ gdouble posx, gdouble posy,
+ gdouble direction, GdkColor *color, gint style,
+ gboolean shadow, gboolean outline)
+{
+ gdouble w;
+ GdkPoint poly[16];
+
+ if (shadow)
+ gdk_gc_set_function (kontext_map, GDK_AND);
+ else
+ gdk_gc_set_function (kontext_map, GDK_COPY);
+
+ gdk_gc_set_foreground (kontext_map, color);
+
+ w = direction + M_PI;
+
+ if (style == 0 && shadow == FALSE)
+ {
+ /* draw position icon */
+ gdk_draw_pixbuf (drawable, kontext_map, posmarker_img,
+ 0, 0, posx - 15, posy - 15,
+ -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
+ }
+
+ if (style == 0 && shadow == TRUE)
+ {
+ /* draw shadow of position icon */
+ gdk_draw_arc (drawable, kontext_map, TRUE, posx-15, posy-15,
+ 30, 30, 0, 360 * 64);
+ }
+
+ if (style == 0 || style == 1)
+ {
+ /* draw arrow pointer */
+ gdk_gc_set_line_attributes (kontext_map, 3, 0, 0, 0);
+ poly[0].x =
+ posx + PFSIZE * (cos (w + M_PI_2));
+ poly[0].y =
+ posy + PFSIZE * (sin (w + M_PI_2));
+ poly[1].x = posx
+ + PFSIZE / 2 * (cos (w + M_PI))
+ - PFSIZE / 1.5 * (cos (w + M_PI_2));
+ poly[1].y = posy
+ + PFSIZE / 2 * (sin (w + M_PI))
+ - PFSIZE / 1.5 * (sin (w + M_PI_2));
+ poly[2].x = posx;
+ poly[2].y = posy;
+ poly[3].x = posx
+ - PFSIZE / 2 * (cos (w + M_PI))
+ - PFSIZE / 1.5 * (cos (w + M_PI_2));
+ poly[3].y = posy
+ - PFSIZE / 2 * (sin (w + M_PI))
+ - PFSIZE / 1.5 * (sin (w + M_PI_2));
+ poly[4].x = poly[0].x;
+ poly[4].y = poly[0].y;
+ gdk_draw_polygon (drawable, kontext_map, TRUE,
+ (GdkPoint *) poly, 5);
+ /* draw outline */
+ if (outline)
+ {
+ gdk_gc_set_foreground (kontext_map, &colors.lightorange);
+ gdk_gc_set_line_attributes (kontext_map, 1, 0, 0, 0);
+ gdk_draw_polygon (drawable, kontext_map, FALSE,
+ (GdkPoint *) poly, 5);
+ }
+ }
+
+ if (style == 2)
+ {
+ /* draw crosshair pointer */
+ gdk_gc_set_line_attributes (kontext_map, 3, 0, 0, 0);
+ gdk_draw_line (drawable, kontext_map,
+ posx + PFSIZE * 0.5 * (cos (w + M_PI)),
+ posy + PFSIZE * 0.5 * (sin (w + M_PI)),
+ posx - PFSIZE * 0.5 * (cos (w + M_PI)),
+ posy - PFSIZE * 0.5 * (sin (w + M_PI)));
+ gdk_draw_line (drawable, kontext_map, posx, posy,
+ posx + PFSIZE * (cos (w + M_PI_2)),
+ posy + PFSIZE * (sin (w + M_PI_2)));
+ }
+
+ if (style == 3)
+ {
+ /* draw + sign at position */
+ gdk_gc_set_line_attributes (kontext_map, 4, 0, 0, 0);
+ gdk_draw_line (drawable, kontext_map, posx + 1,
+ posy + 1 - 10, posx + 1, posy + 1 - 2);
+ gdk_draw_line (drawable, kontext_map, posx + 1,
+ posy + 1 + 2, posx + 1, posy + 1 + 10);
+ gdk_draw_line (drawable, kontext_map, posx + 1 + 10,
+ posy + 1, posx + 1 + 2, posy + 1);
+ gdk_draw_line (drawable, kontext_map, posx + 1 - 2,
+ posy + 1, posx + 1 - 10, posy + 1);
+ }
+
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ * GUI Init Main
+ * This will call all the necessary functions to init the graphical interface
+ */
+int gui_init (void)
+{
+ GdkRectangle rectangle = {0, 0, SCREEN_X, SCREEN_Y};
+
+ /* init colors */
+ colmap = gdk_colormap_get_system ();
+ init_color (local_config.color_track, &colors.track);
+ init_color (local_config.color_route, &colors.route);
+ init_color (local_config.color_friends, &colors.friends);
+ init_color (local_config.color_wplabel, &colors.wplabel);
+ init_color (local_config.color_dashboard, &colors.dashboard);
+
+ init_color ("#a0a0a0", &colors.shadow);
+ // TODO: see gui.h
+ init_color ("#a00000", &colors.nightmode);
+ init_color ("#000000", &colors.black);
+ init_color ("#ff0000", &colors.red);
+ init_color ("#ffffff", &colors.white);
+ init_color ("#0000ff", &colors.blue);
+ init_color ("#8b958b", &colors.lcd);
+ init_color ("#737d6a", &colors.lcd2);
+ init_color ("#ffff00", &colors.yellow);
+ init_color ("#00b000", &colors.green);
+ init_color ("#00ff00", &colors.green2);
+ init_color ("#d5d5d5", &colors.mygray);
+ init_color ("#a5a5a5", &colors.textback);
+ init_color ("#4076cf", &colors.textbacknew);
+ init_color ("#c0c0c0", &colors.grey);
+ init_color ("#f06000", &colors.orange);
+ init_color ("#f0995f", &colors.lightorange);
+ init_color ("#ff8000", &colors.orange2);
+ init_color ("#a0a0a0", &colors.darkgrey);
+ init_color ("#d0d0d0", &colors.lightgrey);
+
+ gtk_window_set_auto_startup_notification (TRUE);
+
+ /* init poi search dialog (cached) */
+ create_window_poi_lookup();
+
+ // TODO: use real values for geometry
+ create_main_window(NULL, 0);
+
+ // TODO: create_button_add_wp();
+
+ posmarker_img = read_icon ("posmarker.png", 0);
+ targetmarker_img = read_icon ("targetmarker.png", 0);
+
+
+// the following lines habe been moved from gpsdrive.c to here.
+// maybe something has to be sorted out:
+{
+ drawable =
+ gdk_pixmap_new (map_drawingarea->window, SCREEN_X, SCREEN_Y, -1);
+ kontext_map = gdk_gc_new (main_window->window);
+
+ gdk_gc_set_clip_origin (kontext_map, 0, 0);
+ rectangle.width = SCREEN_X;
+ rectangle.height = SCREEN_Y;
+
+ gdk_gc_set_clip_rectangle (kontext_map, &rectangle);
+
+ /* fill window with color */
+ gdk_gc_set_function (kontext_map, GDK_COPY);
+ gdk_gc_set_foreground (kontext_map, &colors.lcd2);
+ gdk_draw_rectangle (map_drawingarea->window, kontext_map, 1, 0, 0,
+ SCREEN_X, SCREEN_Y);
+ {
+ GtkStyle *style;
+ style = gtk_rc_get_style (main_window);
+ colors.defaultcolor = style->bg[GTK_STATE_NORMAL];
+ }
+}
+
+ /* set cross cursor for map posmode */
+ cursor_cross = gdk_cursor_new(GDK_TCROSS);
+ /* set watch cursor used e.g. when rendering a mapnik map*/
+ cursor_watch = gdk_cursor_new(GDK_WATCH);
+ return 0;
+}
+
+/*
+ * function to set cursors styles
+ */
+gint
+set_cursor_style(int cursor) {
+ switch(cursor) {
+ case CURSOR_DEFAULT:
+ /* different cursors in posmode */
+ if (gui_status.posmode == TRUE)
+ gdk_window_set_cursor (map_drawingarea->window, cursor_cross);
+ else
+ gdk_window_set_cursor (map_drawingarea->window, NULL);
+ break;
+ case CURSOR_WATCH:
+ gdk_window_set_cursor(map_drawingarea->window, cursor_watch);
+ }
+ /* update all events to fastly switch cursor */
+ while (gtk_events_pending())
+ gtk_main_iteration();
+ return 0;
+}
diff --git a/src/gui.h b/src/gui.h
new file mode 100644
index 0000000..e93c5c7
--- /dev/null
+++ b/src/gui.h
@@ -0,0 +1,108 @@
+/***********************************************************************
+
+Copyright (c) 2001-2006 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Copyright (c) 2007 Ross Scanlon <ross@theinternethost.com.au>
+Website: www.4x4falcon.com
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ *********************************************************************
+
+***********************************************************************/
+
+#ifndef GPSDRIVE_GUI_H
+#define GPSDRIVE_GUI_H
+
+
+gint popup_yes_no (GtkWindow *parent, gchar *message);
+gint popup_warning (GtkWindow *parent, gchar *message);
+gint popup_error (GtkWindow *parent, gchar *message);
+
+int toggle_button_cb (GtkWidget *button, gboolean *value);
+
+gint switch_nightmode (gboolean value);
+
+gchar *get_colorstring (GdkColor *tcolor);
+
+int get_window_sizing (gchar *geom, gint usegeom, gint screen_height, gint screen_width);
+
+gboolean draw_posmarker
+ (gdouble posx, gdouble posy, gdouble direction,
+ GdkColor *color, gint style, gboolean shadow, gboolean outline);
+
+
+int gui_init (void);
+
+gint set_cursor_style(int cursor);
+
+typedef struct
+{
+ GdkColor track;
+ GdkColor route;
+ GdkColor friends;
+ GdkColor wplabel;
+ GdkColor dashboard;
+
+ // TODO: Check, which of these colors are really needed.
+ // The reason is that defined colors should only be used where it is
+ // really important (e.g. inside the map window), the rest should be
+ // left to the selected gtk theme.
+ GdkColor nightmode;
+ GdkColor defaultcolor;
+ GdkColor red;
+ GdkColor black;
+ GdkColor white;
+ GdkColor blue;
+ GdkColor nightcolor;
+ GdkColor lcd;
+ GdkColor lcd2;
+ GdkColor yellow;
+ GdkColor green;
+ GdkColor green2;
+ GdkColor mygray;
+ GdkColor textback;
+ GdkColor textbacknew;
+ GdkColor grey;
+ GdkColor orange;
+ GdkColor orange2;
+ GdkColor lightorange;
+ GdkColor darkgrey;
+ GdkColor lightgrey;
+ GdkColor shadow;
+} color_struct;
+
+typedef struct
+{
+ guint width;
+ guint height;
+ gboolean nightmode;
+ gboolean posmode;
+} guistatus_struct;
+
+/* gpsdrive cursors */
+enum {
+ CURSOR_DEFAULT,
+ CURSOR_WATCH
+};
+
+extern guistatus_struct gui_status;
+
+
+#endif /* GPSDRIVE_GUI_H */
diff --git a/src/icons.c b/src/icons.c
new file mode 100644
index 0000000..3a96340
--- /dev/null
+++ b/src/icons.c
@@ -0,0 +1,393 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+***********************************************************************/
+
+/* Include Dateien */
+#include "../config.h"
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <signal.h>
+#include <termios.h>
+#include <unistd.h>
+#include <math.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <dirent.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <gpsdrive_config.h>
+
+#include "gettext.h"
+
+#include "LatLong-UTMconversion.h"
+#include "gpsdrive.h"
+#include "battery.h"
+#include "track.h"
+#include "poi.h"
+#include "icons.h"
+#include "gui.h"
+#include "main_gui.h"
+
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+
+#if GTK_MINOR_VERSION < 2
+#define gdk_draw_pixbuf _gdk_draw_pixbuf
+#endif
+
+
+#define MAX_ICONS MAXPOITYPES
+
+extern gint do_unit_test;
+extern gint debug;
+extern gint mydebug;
+extern color_struct colors;
+extern poi_type_struct poi_type_list[poi_type_list_max];
+extern int poi_type_list_count;
+extern GdkGC *kontext_map;
+
+GdkPixbuf *friendsimage = NULL;
+GdkPixbuf *friendspixbuf = NULL;
+GdkPixbuf *kismetpixbuf;
+
+icons_buffer_struct icons_buffer[MAX_ICONS];
+gint icons_buffer_max = MAX_ICONS;
+gint icons_buffer_last = 0;
+
+/***************************************************************************/
+/***************************************************************************/
+/***************************************************************************/
+
+
+/* *****************************************************************************
+ * draw a + Sign and its shaddow */
+void
+draw_plus_sign (gdouble posxdest, gdouble posydest)
+{
+ gdk_gc_set_line_attributes (kontext_map, 1, 0, 0, 0);
+ if (local_config.showshadow)
+ { /* draw shadow of + sign */
+ gdk_gc_set_foreground (kontext_map, &colors.darkgrey);
+ gdk_gc_set_function (kontext_map, GDK_AND);
+ gdk_draw_line (drawable, kontext_map,
+ posxdest + 1 + SHADOWOFFSET,
+ posydest + 1 - 5 + SHADOWOFFSET, posxdest + 1 + SHADOWOFFSET, posydest + 1 + 5 + SHADOWOFFSET);
+ gdk_draw_line (drawable, kontext_map,
+ posxdest + 1 + 5 + SHADOWOFFSET,
+ posydest + 1 + SHADOWOFFSET, posxdest + 1 - 5 + SHADOWOFFSET, posydest + 1 + SHADOWOFFSET);
+ gdk_gc_set_function (kontext_map, GDK_COPY);
+ }
+
+ /* draw + sign at destination */
+ gdk_gc_set_foreground (kontext_map, &colors.red);
+ gdk_draw_line (drawable, kontext_map, posxdest + 1, posydest + 1 - 5, posxdest + 1, posydest + 1 + 5);
+ gdk_draw_line (drawable, kontext_map, posxdest + 1 + 5, posydest + 1, posxdest + 1 - 5, posydest + 1);
+
+}
+
+/* *****************************************************************************
+ * draw a small + Sign and its shaddow */
+void
+draw_small_plus_sign (gdouble posxdest, gdouble posydest)
+{
+ gdk_gc_set_line_attributes (kontext_map, 1, 0, 0, 0);
+ if (local_config.showshadow)
+ { /* draw shadow of + sign */
+ gdk_gc_set_foreground (kontext_map, &colors.darkgrey);
+ gdk_gc_set_function (kontext_map, GDK_AND);
+ gdk_draw_line (drawable, kontext_map,
+ posxdest + 1 + SHADOWOFFSET,
+ posydest + 1 - 2 + SHADOWOFFSET, posxdest + 1 + SHADOWOFFSET, posydest + 1 + 2 + SHADOWOFFSET);
+ gdk_draw_line (drawable, kontext_map,
+ posxdest + 1 + 2 + SHADOWOFFSET,
+ posydest + 1 + SHADOWOFFSET, posxdest + 1 - 2 + SHADOWOFFSET, posydest + 1 + SHADOWOFFSET);
+ gdk_gc_set_function (kontext_map, GDK_COPY);
+ }
+
+ /* draw + sign at destination */
+ gdk_gc_set_foreground (kontext_map, &colors.red);
+ gdk_draw_line (drawable, kontext_map, posxdest + 1, posydest + 1 - 2, posxdest + 1, posydest + 1 + 2);
+ gdk_draw_line (drawable, kontext_map, posxdest + 1 + 2, posydest + 1, posxdest + 1 - 2, posydest + 1);
+
+}
+
+
+/* -----------------------------------------------------------------------------
+ *
+*/
+int
+drawicon (gint posxdest, gint posydest, char *icon_name)
+{
+ int symbol = 0, aux = -1, i;
+ int wx, wy;
+ gchar icon[80];
+
+ //printf("drawicon %d %d %s\n", posxdest, posydest,icon_name);
+
+ g_strlcpy (icon, icon_name, sizeof (icon));
+
+ /* sweep through all icons and look for icon */
+ for (i = 0; i < icons_buffer_last; i++)
+ if ((strcmp (icon, icons_buffer[i].name)) == 0)
+ {
+ if ((posxdest >= 0) && (posxdest < SCREEN_X) && (posydest >= 0) && (posydest < SCREEN_Y))
+ {
+ wx = gdk_pixbuf_get_width (icons_buffer[i].icon);
+ wy = gdk_pixbuf_get_height (icons_buffer[i].icon);
+ gdk_draw_pixbuf (drawable, kontext_map,
+ (icons_buffer + i)->icon, 0, 0,
+ posxdest - wx / 2, posydest - wy / 2, wx, wy, GDK_RGB_DITHER_NONE, 0, 0);
+ aux = i;
+ }
+ return 99999;
+ }
+
+ if (symbol == 0)
+ {
+ draw_plus_sign (posxdest, posydest);
+ return 0;
+ }
+
+ return symbol;
+}
+
+/* -----------------------------------------------------------------------------
+ * load icon into pixbuff from either system directory or user directory
+ * if force is set we exit on non success
+*/
+GdkPixbuf *
+read_icon (gchar * icon_name, int force)
+{
+ gchar filename[1024];
+ gchar icon_filename[1024];
+ GdkPixbuf *icons_buffer = NULL;
+ if (mydebug > 50)
+ fprintf (stderr, "read_icon(%s,%d)\n", icon_name, force);
+
+ typedef struct
+ {
+ gchar *path;
+ gchar *option;
+ } path_definition;
+ path_definition available_path[] = {
+ {"", NULL},
+ {"./data/map-icons/", NULL},
+ {"../data/map-icons/", NULL},
+ {"./data/pixmaps/", NULL},
+ {"../data/pixmaps/", NULL},
+ {"%spixmaps/", (gchar *) local_config.dir_home},
+ {"%smap-icons/", (gchar *) local_config.dir_home},
+ {"%s/map-icons/", (gchar *) DATADIR},
+ {"%s/gpsdrive/pixmaps/", (gchar *) DATADIR},
+ {"%s/map-icons/", "/usr/share"},
+ {"%s/gpsdrive/pixmaps/", "/usr/share"},
+ {"END", NULL}
+ };
+
+ gint i;
+ for (i = 0; strncmp (available_path[i].path, "END", sizeof (available_path[i].path)); i++)
+ {
+ g_snprintf (filename, sizeof (filename), available_path[i].path, available_path[i].option);
+ g_snprintf (icon_filename, sizeof (icon_filename), "%s%s", filename, icon_name);
+ if (mydebug > 75)
+ fprintf (stderr, "read_icon(%s): Try\t%s\n", icon_name, icon_filename);
+ icons_buffer = gdk_pixbuf_new_from_file (icon_filename, NULL);
+ if (NULL != icons_buffer)
+ {
+ if (mydebug > 20)
+ fprintf (stderr, "read_icon(%s): FOUND\t%s\n", icon_name, icon_filename);
+ return icons_buffer;
+ }
+ }
+
+ if (NULL == icons_buffer && force)
+ {
+ fprintf (stderr, "read_icon: No Icon '%s' found\n", icon_name);
+ if (strstr (icon_name, "Old") == NULL)
+ {
+ fprintf (stderr, _("Please install the program as root with:\n" "make install\n\n"));
+
+ fprintf (stderr, "I searched in :\n");
+ for (i = 0; strncmp (available_path[i].path, "END", sizeof (available_path[i].path)); i++)
+ {
+ g_snprintf (filename, sizeof (filename), available_path[i].path, available_path[i].option);
+ g_snprintf (icon_filename, sizeof (icon_filename), "%s%s", filename, icon_name);
+ fprintf (stderr, "\t%s\n", icon_filename);
+ }
+
+ exit (-1);
+ }
+ }
+
+ return icons_buffer;
+}
+
+
+/* *******************************************************
+ * read icon in the selected theme.
+ * this includes reducing the icon path if this icon is not found
+ * until the first parent icon is found
+ */
+
+GdkPixbuf *
+read_themed_icon (gchar * icon_name)
+{
+ gchar themed_icon_filename[2048];
+ gchar icon_file_name[2048];
+ GdkPixbuf *icon = NULL;
+
+ if (0 >= (int) strlen (icon_name))
+ {
+ fprintf (stderr, "read_themed_icon([%s] '%s') => Empy Icon name requested\n", local_config.icon_theme, icon_name);
+ return NULL;
+ }
+
+ g_strlcpy (icon_file_name, icon_name, sizeof (icon_file_name));
+ g_strdelimit (icon_file_name, ".", '/');
+
+ char *p_pos;
+ do
+ {
+ g_snprintf (themed_icon_filename, sizeof (themed_icon_filename),
+ "%s/%s.png", local_config.icon_theme, icon_file_name);
+ if (mydebug > 90)
+ fprintf (stderr, "read_themed_icon([%s] %s) => Themed File %s\n",
+ local_config.icon_theme, icon_name, themed_icon_filename);
+ icon = read_icon (themed_icon_filename, 0);
+ if (icon != NULL)
+ return icon;
+
+ p_pos = rindex (icon_file_name, '/');
+ if (p_pos)
+ {
+ p_pos[0] = '\0';
+ if (mydebug > 6)
+ fprintf (stderr, "read_themed_icon([%s] %s) reduced to => %s\n",
+ local_config.icon_theme, icon_name, icon_file_name);
+ }
+ }
+ while (p_pos != NULL);
+ if (NULL == icon)
+ {
+ fprintf (stderr, "read_themed_icon([%s] %s): No Icon '%s' found for theme %s\n",
+ local_config.icon_theme, icon_name, icon_name, local_config.icon_theme);
+ //exit (-1);
+ }
+ return NULL;
+}
+
+/* -----------------------------------------------------------------------------
+*/
+void
+load_friends_icon (void)
+{
+ friendsimage = read_icon ("friendsicon.png", 1);
+ friendspixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 1, 8, 39, 24);
+ gdk_pixbuf_scale (friendsimage, friendspixbuf, 0, 0, 39, 24, 0, 0, 1, 1, GDK_INTERP_BILINEAR);
+}
+
+/* ----------------------------------------------------------------------------- */
+/* warning: still modifies icon_name
+ */
+void
+load_user_icon (char icon_name[200])
+{
+ int i;
+ char path[1024];
+ for (i = 0; i < (int) strlen (icon_name); i++)
+ icon_name[i] = tolower (icon_name[i]);
+
+ g_snprintf (path, sizeof (path), "%sicons/%s.png", local_config.dir_home, icon_name);
+ icons_buffer[icons_buffer_last].icon = gdk_pixbuf_new_from_file (path, NULL);
+
+ if (icons_buffer[icons_buffer_last].icon == NULL)
+ {
+ g_snprintf (path, sizeof (path), "%s/map-icons/%s.png", DATADIR, icon_name);
+ icons_buffer[icons_buffer_last].icon = gdk_pixbuf_new_from_file (path, NULL);
+ }
+
+ if ((icons_buffer + icons_buffer_last)->icon != NULL)
+ {
+ for (i = 0; i < (int) strlen (icon_name); i++)
+ icon_name[i] = tolower (icon_name[i]);
+ if ((strcmp (icon_name, "wlan") == 0) || (strcmp (icon_name, "wlan-wep") == 0))
+ {
+ fprintf (stderr, _("Loaded user defined icon %s\n"), path);
+ }
+ else
+ {
+ g_strlcpy ((icons_buffer + icons_buffer_last)->name, icon_name, sizeof (icons_buffer->name));
+ fprintf (stderr, _("Loaded user defined icon %s\n"), path);
+ icons_buffer_last++;
+ }
+ if (mydebug > 3)
+ fprintf (stderr, "Icon for %s loaded:%s\n", icon_name, path);
+ }
+ else
+ {
+ if (mydebug > 3)
+ fprintf (stderr, "No Icon for %s loaded\n", icon_name);
+ }
+}
+
+
+/* *****************************************************************************
+ * draw wlan Waypoints
+ */
+void
+drawwlan (gint posxdest, gint posydest, gint wlan)
+{
+ /* wlan=0: no wlan, 1:open wlan, 2:WEP crypted wlan */
+
+ if (wlan == 0)
+ return;
+
+ if ((posxdest >= 0) && (posxdest < SCREEN_X))
+ {
+ if ((posydest >= 0) && (posydest < SCREEN_Y))
+ {
+ if (wlan == 1)
+ drawicon (posxdest, posydest, "wlan.open");
+ else
+ drawicon (posxdest, posydest, "wlan.wep");
+ }
+ }
+}
diff --git a/src/icons.h b/src/icons.h
new file mode 100644
index 0000000..b5bbfcb
--- /dev/null
+++ b/src/icons.h
@@ -0,0 +1,49 @@
+/***********************************************************************
+
+Copyright (c) 2001,2002 Fritz Ganter <ganter@ganter.at>
+
+Website: www.kraftvoll.at/software
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+#ifndef GPSDRIVE_ICONS_H
+#define GPSDRIVE_ICONS_H
+
+/*
+ * See icons.c for details.
+ */
+
+
+void drawwlan (gint posxdest, gint posydest, gint wlan);
+int drawicon (gint posxdest, gint posydest, char *ic);
+void load_friends_icon (void);
+void load_user_icon( char icon_name[200] );
+void draw_plus_sign ( gdouble posxdest, gdouble posydest );
+void draw_small_plus_sign ( gdouble posxdest, gdouble posydest );
+GdkPixbuf *read_themed_icon (gchar * icon_symbol);
+GdkPixbuf * read_icon(char * icon_name,int force);
+
+typedef struct
+{
+ GdkPixbuf *icon;
+ char name[40];
+}
+icons_buffer_struct;
+
+#endif /* GPSDRIVE_ICONS_H */
diff --git a/src/import_map.c b/src/import_map.c
new file mode 100644
index 0000000..03f9184
--- /dev/null
+++ b/src/import_map.c
@@ -0,0 +1,835 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+/*
+ $Log$
+ Revision 1.18 2006/10/30 12:01:49 hamish
+ spelling and conversion notes in comments
+
+ Revision 1.17 2006/08/02 12:18:36 tweety
+ forgot one sed for homedir and mapdir
+
+ Revision 1.16 2006/08/02 07:48:24 tweety
+ rename variable mapdir --> local_config_mapdir
+
+ Revision 1.15 2006/04/03 23:43:45 tweety
+ rename adj --> scaler_adj
+ rearrange code for some of the _cb
+ streets_draw_cb
+ poi_draw_cb
+ move map_dir_struct definition to src/gpsdrive.h
+ remove some of the history parts in the Files
+ save and read settings for display_map like "display_map_<name> = 1"
+ increase limit for displayed streets
+ change color of de.Strassen.Allgemein to x555555
+ OSM.pm make non way segments to Strassen.Allgemein
+ WDB check if yountryname is valid
+
+ Revision 1.14 2006/02/17 20:54:34 tweety
+ http://bugzilla.gpsdrive.cc/show_bug.cgi?id=73
+ Downloading maps doesn't allow Longitude select by mouse
+
+ Revision 1.13 2006/02/05 16:38:06 tweety
+ reading floats with scanf looks at the locale LANG=
+ so if you have a locale de_DE set reading way.txt results in clearing the
+ digits after the '.'
+ For now I set the LC_NUMERIC always to en_US, since there we have . defined for numbers
+
+ Revision 1.12 2006/01/03 14:24:10 tweety
+ eliminate compiler Warnings
+ try to change all occurences of longi -->lon, lati-->lat, ...i
+ use drawicon(posxdest,posydest,"w-lan.open") instead of using a seperate variable
+ rename drawgrid --> do_draw_grid
+ give the display frames usefull names frame_lat, ...
+ change handling of WP-types to lowercase
+ change order for directories reading icons
+ always read inconfile
+
+ Revision 1.11 2006/01/01 20:11:42 tweety
+ add option -P for Posmode on start
+
+ Revision 1.10 2005/11/05 18:30:40 tweety
+ fix sigseg in import_map Code
+ VS: ----------------------------------------------------------------------
+
+ Revision 1.9 2005/10/19 07:22:21 tweety
+ Its now possible to choose units for displaying coordinates also in
+ Deg.decimal, "Deg Min Sec" and "Deg Min.dec"
+ Author: Oddgeir Kvien <oddgeir@oddgeirkvien.com>
+
+ Revision 1.8 2005/04/20 23:33:49 tweety
+ reformatted source code with anjuta
+ So now we have new indentations
+
+ Revision 1.7 2005/04/13 19:58:31 tweety
+ renew indentation to 4 spaces + tabstop=8
+
+ Revision 1.6 2005/04/10 21:50:50 tweety
+ reformatting c-sources
+
+ Revision 1.5 2005/04/02 12:10:12 tweety
+ 2005.03.30 by Oddgeir Kvien <oddgeir@oddgeirkvien.com>
+ Canges made to import a map with one point and enter the scale
+
+
+ 2005.03.30 by Oddgeir Kvien <oddgeir@oddgeirkvien.com>
+ Canges made to import a map with one point and enter the scale
+
+
+ Revision 1.4 2005/03/28 18:05:42 tweety
+ Von: Darazs Attila <zumi@freestart.hu>
+ added zoom correction for map import Function
+
+ Revision 1.3 2005/03/28 17:59:38 tweety
+ corrected an Error in position calculation by Darazs Attila <zumi@freestart.hu>
+
+ Revision 1.2 2005/03/27 21:51:14 tweety
+ make x/y Fields editable, to improve map import
+
+ Revision 1.1 2005/03/27 21:25:46 tweety
+ separating map_import from gpsdrive.c
+
+*/
+/*
+ * poi_ support module: display
+ */
+
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "gpsdrive.h"
+#include "import_map.h"
+#include "config.h"
+#include "gettext.h"
+#include "icons.h"
+#include "gui.h"
+#include "gpsdrive_config.h"
+
+
+
+#include "gettext.h"
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+
+
+extern gint maploaded;
+extern gint isnight, disableisnight;
+extern gint debug, mydebug;
+extern gint usesql;
+extern GtkWidget *dl_text_lat, *dl_text_lon, *wptext1, *wptext2;
+GtkWidget *dltext4,*dltext3;
+extern gdouble gbreit, glang, milesconv, olddist;
+extern GTimer *timer, *disttimer;
+extern gint gcount, milesflag, downloadwindowactive;
+extern gint havepos, haveposcount, blink, gblink, xoff, yoff;
+extern GtkWidget *status, *pixmapwidget,
+ *gotowindow;
+extern GtkWidget *messagewindow, *routewindow, *downloadbt;
+extern gint SCREEN_X_2, SCREEN_Y_2;
+extern GtkWidget *mylist, *myroutelist, *destframe;
+extern mapsstruct *maps;
+extern gint iszoomed;
+extern gint isnight, disableisnight;
+extern gint nrmaps, dldiff;
+extern int havenasa, sortcolumn, sortflag;
+extern gint onemousebutton;
+extern gchar oldfilename[1024];
+extern GtkWidget *posbt, *cover;
+extern coordinate_struct coords;
+extern currentstatus_struct current;
+
+typedef struct
+{
+ gdouble lon;
+ gdouble lat;
+ gint x;
+ gint y;
+}
+impstruct;
+impstruct imports[3];
+extern gdouble earthr;
+#define R earthr
+GtkWidget *dltext5, *dltext6, *dltext7, *scale_input;
+gchar importfilename[1024];
+
+
+/* *****************************************************************************
+ set reference point for map calibration */
+gint
+setrefpoint_cb (GtkWidget * widget, guint datum)
+{
+ gchar b[100];
+ gchar *p = NULL;
+ p = b;
+ gtk_clist_get_text (GTK_CLIST (mylist), datum, 1, &p);
+ gtk_entry_set_text (GTK_ENTRY (dltext4), p);
+ gtk_clist_get_text (GTK_CLIST (mylist), datum, 2, &p);
+ gtk_entry_set_text (GTK_ENTRY (dl_text_lat), p);
+
+ gtk_clist_get_text (GTK_CLIST (mylist), datum, 3, &p);
+ gtk_entry_set_text (GTK_ENTRY (dl_text_lon), p);
+
+ return TRUE;
+}
+
+/* *****************************************************************************
+ */
+gint
+nimmfile (GtkWidget * widget, gpointer datum)
+{
+ G_CONST_RETURN gchar *buf = NULL;
+
+ buf = gtk_file_selection_get_filename (datum);
+ gtk_entry_set_text (GTK_ENTRY (dltext7), g_basename (buf));
+ g_strlcpy (importfilename, g_basename (buf), sizeof (importfilename));
+
+ gtk_widget_destroy (datum);
+ loadmap ((char *) g_basename (buf));
+ return (TRUE);
+}
+
+/* *****************************************************************************
+ */
+gint
+importfb_cb (GtkWidget * widget, guint datum)
+{
+ GtkWidget *fdialog;
+ gchar buf[1000];
+ fdialog = gtk_file_selection_new (_("Select a map file"));
+ gtk_window_set_modal (GTK_WINDOW (fdialog), TRUE);
+
+ gtk_signal_connect (GTK_OBJECT
+ (GTK_FILE_SELECTION (fdialog)->ok_button),
+ "clicked", GTK_SIGNAL_FUNC (nimmfile),
+ GTK_OBJECT (fdialog));
+ gtk_signal_connect_object (GTK_OBJECT
+ (GTK_FILE_SELECTION (fdialog)->
+ cancel_button), "clicked",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy),
+ GTK_OBJECT (fdialog));
+
+
+ g_strlcpy (buf, local_config.dir_home, sizeof (buf));
+
+ gtk_file_selection_complete (GTK_FILE_SELECTION (fdialog), buf);
+ gtk_widget_show (fdialog);
+ xoff = 0;
+ yoff = 0;
+ current.zoom = 1;
+ iszoomed = FALSE;
+
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ */
+gint
+importshift_cb (GtkWidget * widget, guint datum)
+{
+ switch (datum)
+ {
+ case 1:
+ yoff -= SCREEN_Y_2;
+ break;
+ case 4:
+ yoff += SCREEN_Y_2;
+ break;
+ case 2:
+ xoff -= SCREEN_X_2;
+ break;
+ case 3:
+ xoff += SCREEN_X_2;
+ break;
+ }
+ iszoomed = FALSE;
+ expose_cb (NULL, 0);
+ expose_mini_cb (NULL, 0);
+
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ */
+gint
+import1_cb (GtkWidget * widget, guint datum)
+{
+ GtkWidget *mainbox, *window;
+ GtkWidget *knopf2, *knopf, *knopf3, *knopf4, *knopf6,
+ *knopf_scale_finish, *scale_txt;
+ GtkWidget *table, *knopf9, *knopf10, *knopf11, *s1, *s2, *s3, *s4;
+ GtkWidget *s5, *s6;
+ gchar buff[1300];
+ GtkWidget *text;
+ GtkWidget *hbox;
+ gchar *thetext1 = _("How to calibrate your own maps? "
+ "First, the map file\nmust be copied into the");
+ gchar *thetext1a = _("\ndirectory as .gif, .jpg or .png file "
+ "and must have\nthe size 1280x1024. The file names must be\n"
+ "map_* for street maps or top_* for topographical maps!\n"
+ "Load the file, select coordinates "
+ "from waypoint list or\ntype them in. "
+ "Then click on the accept button.");
+ gchar *thetext2 =
+ _("Now do the same for your second point and click on the\n"
+ "finish button. The map can be used now.");
+
+
+ window = gtk_dialog_new ();
+
+ if (datum == 1)
+ gtk_window_set_title (GTK_WINDOW (window), _("Import Assistant. Step 1"));
+ else
+ gtk_window_set_title (GTK_WINDOW (window), _("Import Assistant. Step 2"));
+
+ gtk_container_set_border_width (GTK_CONTAINER (window), 5);
+ mainbox = gtk_vbox_new (TRUE, 2);
+
+ if (datum == 1)
+ {
+ knopf = gtk_button_new_with_label (_("Accept first point"));
+ gtk_signal_connect_object (GTK_OBJECT (knopf), "clicked",
+ GTK_SIGNAL_FUNC (import2_cb),
+ GTK_OBJECT (window));
+
+ knopf_scale_finish =
+ gtk_button_new_with_label (_("Accept Scale and Finish"));
+ gtk_signal_connect_object (GTK_OBJECT (knopf_scale_finish), "clicked",
+ GTK_SIGNAL_FUNC (import_scale_cb),
+ GTK_OBJECT (window));
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
+ knopf_scale_finish, TRUE, TRUE, 2);
+ }
+ else
+ {
+ knopf = gtk_button_new_with_label (_("Finish"));
+ gtk_signal_connect_object (GTK_OBJECT (knopf), "clicked",
+ GTK_SIGNAL_FUNC (import3_cb),
+ GTK_OBJECT (window));
+ }
+
+ knopf2 = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+ gtk_signal_connect_object (GTK_OBJECT (knopf2), "clicked",
+ GTK_SIGNAL_FUNC
+ (importaway_cb), GTK_OBJECT (window));
+ gtk_signal_connect_object (GTK_OBJECT (window),
+ "delete_event",
+ GTK_SIGNAL_FUNC
+ (importaway_cb), GTK_OBJECT (window));
+
+ s1 = gtk_button_new_with_label (_("Go up"));
+ gtk_signal_connect (GTK_OBJECT (s1), "clicked",
+ GTK_SIGNAL_FUNC (importshift_cb), (gpointer) 1);
+ s2 = gtk_button_new_with_label (_("Go left"));
+ gtk_signal_connect (GTK_OBJECT (s2), "clicked",
+ GTK_SIGNAL_FUNC (importshift_cb), (gpointer) 2);
+ s3 = gtk_button_new_with_label (_("Go right"));
+ gtk_signal_connect (GTK_OBJECT (s3), "clicked",
+ GTK_SIGNAL_FUNC (importshift_cb), (gpointer) 3);
+ s4 = gtk_button_new_with_label (_("Go down"));
+ gtk_signal_connect (GTK_OBJECT (s4), "clicked",
+ GTK_SIGNAL_FUNC (importshift_cb), (gpointer) 4);
+ s5 = gtk_button_new_with_label (_("Zoom in"));
+ gtk_signal_connect (GTK_OBJECT (s5), "clicked", GTK_SIGNAL_FUNC (zoom_cb),
+ (gpointer) 1);
+ s6 = gtk_button_new_with_label (_("Zoom out"));
+ gtk_signal_connect (GTK_OBJECT (s6), "clicked", GTK_SIGNAL_FUNC (zoom_cb),
+ (gpointer) 2);
+
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), knopf, TRUE,
+ TRUE, 2);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), knopf2,
+ TRUE, TRUE, 2);
+ GTK_WIDGET_SET_FLAGS (knopf, GTK_CAN_DEFAULT);
+ GTK_WIDGET_SET_FLAGS (knopf2, GTK_CAN_DEFAULT);
+ table = gtk_table_new (7, 4, TRUE);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), table, TRUE, TRUE,
+ 2);
+ knopf3 = gtk_label_new (_("Latitude"));
+ gtk_table_attach_defaults (GTK_TABLE (table), knopf3, 0, 1, 0, 1);
+ knopf4 = gtk_label_new (_("Longitude"));
+ gtk_table_attach_defaults (GTK_TABLE (table), knopf4, 0, 1, 1, 2);
+ knopf9 = gtk_label_new (_("Screen X"));
+ gtk_table_attach_defaults (GTK_TABLE (table), knopf9, 2, 3, 0, 1);
+ knopf10 = gtk_label_new (_("Screen Y"));
+ gtk_table_attach_defaults (GTK_TABLE (table), knopf10, 2, 3, 1, 2);
+
+
+ if (datum == 1)
+ {
+ scale_txt = gtk_label_new (_("Scale"));
+ gtk_table_attach_defaults (GTK_TABLE (table), scale_txt, 0, 1, 2, 3);
+ scale_input = gtk_entry_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), scale_input, 1, 2, 2, 3);
+ }
+
+ knopf6 = gtk_button_new_with_label (_("Browse POIs"));
+ gtk_signal_connect (GTK_OBJECT (knopf6), "clicked",
+ GTK_SIGNAL_FUNC (sel_target_cb), (gpointer) 1);
+
+
+ gtk_table_attach_defaults (GTK_TABLE (table), knopf6, 0, 1, 3, 4);
+ dl_text_lat = gtk_entry_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), dl_text_lat, 1, 2, 0, 1);
+ coordinate2gchar (buff, sizeof (buff), coords.current_lat, TRUE,
+ local_config.coordmode);
+ gtk_entry_set_text (GTK_ENTRY (dl_text_lat), buff);
+ dl_text_lon = gtk_entry_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), dl_text_lon, 1, 2, 1, 2);
+ coordinate2gchar (buff, sizeof (buff), coords.current_lon, FALSE,
+ local_config.coordmode);
+ gtk_entry_set_text (GTK_ENTRY (dl_text_lon), buff);
+
+
+ dltext5 = gtk_entry_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), dltext5, 3, 4, 0, 1);
+
+ dltext6 = gtk_entry_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), dltext6, 3, 4, 1, 2);
+
+ dltext4 = gtk_entry_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), dltext4, 1, 2, 3, 4);
+ dltext7 = gtk_entry_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), dltext7, 3, 4, 3, 4);
+
+ if (datum == 1)
+ {
+ knopf11 = gtk_button_new_with_label (_("Browse filename"));
+ gtk_signal_connect_object (GTK_OBJECT (knopf11), "clicked",
+ GTK_SIGNAL_FUNC (importfb_cb), 0);
+ gtk_table_attach_defaults (GTK_TABLE (table), knopf11, 2, 3, 3, 4);
+ }
+ else
+ gtk_entry_set_text (GTK_ENTRY (dltext7), importfilename);
+
+
+ gtk_entry_set_editable (GTK_ENTRY (dltext7), FALSE);
+ gtk_entry_set_editable (GTK_ENTRY (dltext4), FALSE);
+ /*
+ * gtk_entry_set_editable (GTK_ENTRY (dltext5), FALSE);
+ * gtk_entry_set_editable (GTK_ENTRY (dltext6), FALSE);
+ */
+
+ text = gtk_label_new ("");
+
+
+ if (datum == 1)
+ g_snprintf (buff, sizeof (buff),
+ "<span font_family=\"Arial\" size=\"10000\">%s <span color=\"red\"> %s</span> %s</span>",
+ thetext1, local_config.dir_maps, thetext1a);
+ else
+ g_snprintf (buff, sizeof (buff),
+ "<span font_family=\"Arial\" size=\"10000\">%s</span>",
+ thetext2);
+
+ gtk_label_set_text (GTK_LABEL (text), buff);
+ gtk_label_set_use_markup (GTK_LABEL (text), TRUE);
+
+ hbox = gtk_hbox_new (FALSE, 3);
+ gtk_box_pack_start (GTK_BOX (hbox), text, TRUE, TRUE, 0);
+ /* gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0); */
+
+ gtk_table_attach_defaults (GTK_TABLE (table), hbox, 2, 4, 4, 7);
+ gtk_table_attach_defaults (GTK_TABLE (table), s1, 0, 1, 4, 5);
+ gtk_table_attach_defaults (GTK_TABLE (table), s5, 1, 2, 4, 5);
+ gtk_table_attach_defaults (GTK_TABLE (table), s2, 0, 1, 5, 6);
+ gtk_table_attach_defaults (GTK_TABLE (table), s3, 1, 2, 5, 6);
+ gtk_table_attach_defaults (GTK_TABLE (table), s4, 0, 1, 6, 7);
+ gtk_table_attach_defaults (GTK_TABLE (table), s6, 1, 2, 6, 7);
+
+ gtk_table_set_row_spacings (GTK_TABLE (table), 3);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 3);
+ /* gtk_label_set_justify (GTK_LABEL (knopf6), GTK_JUSTIFY_RIGHT); */
+ /* gtk_label_set_justify (GTK_LABEL (knopf3), GTK_JUSTIFY_RIGHT); */
+ /* gtk_label_set_justify (GTK_LABEL (knopf4), GTK_JUSTIFY_RIGHT); */
+ /* gtk_label_set_justify (GTK_LABEL (knopf6), GTK_JUSTIFY_RIGHT); */
+ gtk_window_set_default (GTK_WINDOW (window), knopf);
+ gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
+ gtk_widget_show_all (window);
+ current.importactive = TRUE;
+
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ * Import map with one point and given scale
+ */
+gint
+import_scale_cb (GtkWidget * widget, gpointer datum)
+{
+ G_CONST_RETURN gchar *s = NULL;
+ gdouble dx_pix, dy_pix, x, y, maxx, maxy, dx_m, dy_m, m_pr_pix, lat, lon;
+ gdouble dlat, dlon, lat_pr_m, lon_pr_m, scale, latcenter, longcenter;
+ maxx = 1280;
+ maxy = 1024;
+
+ s = gtk_entry_get_text (GTK_ENTRY (dl_text_lat));
+ coordinate_string2gdouble (s, &lat);
+
+ s = gtk_entry_get_text (GTK_ENTRY (dl_text_lon));
+ coordinate_string2gdouble (s, &lon);
+
+ s = gtk_entry_get_text (GTK_ENTRY (dltext5));
+ x = strtol (s, NULL, 0);
+
+ s = gtk_entry_get_text (GTK_ENTRY (dltext6));
+ y = strtol (s, NULL, 0);
+
+ s = gtk_entry_get_text (GTK_ENTRY (scale_input));
+ coordinate_string2gdouble (s, &scale);
+
+ if (debug)
+ {
+ g_print ("Import: scale: %g\n", scale);
+ g_print ("Import: scale: lat: %g, lon: %g\n", lat, lon);
+ g_print ("Import: scale: x: %g, y: %g\n", x, y);
+ }
+
+ gtk_widget_destroy (widget);
+
+ /* Calc coordinates */
+ // distance from selected point on map to center in pixels
+ dx_pix = maxx / 2 - x;
+ dy_pix = y - maxy / 2;
+
+ // calculate meter pr pixel of map
+ m_pr_pix = scale / PIXELFACT;
+ // g_print ("dx_pix %g, dy_pix %g, m_pr_pix %g\n", dx_pix, dy_pix, m_pr_pix);
+
+ // distance from selected point on map to center in meters
+ dx_m = dx_pix * m_pr_pix;
+ dy_m = dy_pix * m_pr_pix;
+ // g_print ("dx_m %g, dy_m %g\n", dx_m, dy_m);
+
+ // length of 1 deg lat and lon in meters
+ // lat_pr_m = 360.0/(2.0*M_PI*R);
+ /* This should be the correct length, but using this formulas gives me
+ * a nautical mile that are 1857.85 m which are wrong. Therefore I am
+ * hardcoding it to a nautical mile that are 1851.85 m
+ * HB: shouldn't this be 1852.0 ?!?
+ */
+ lat_pr_m = 1.0 / (1851.85 * 60.0);
+ lon_pr_m = lat_pr_m / cos (M_PI * lat / 180.0);
+ /*
+ * g_print ("R %g, M_PI %g lat_pr_m %g, lon_pr_m %g, meter pr deg lat %g\n",
+ * R, M_PI, lat_pr_m, lon_pr_m, 1.0/lat_pr_m);
+ */
+
+ // distance in deg from selected point on map to center
+ dlat = dy_m * lat_pr_m;
+ dlon = dx_m * lon_pr_m;
+ // g_print ("dlat %g, dlon %g\n", dlat, dlon);
+
+ // map mid point in deg
+ latcenter = lat + dlat;
+ longcenter = lon + dlon;
+ // g_print ("Import: scale: %g, latcenter: %g, loncenter: %g\n", scale, latcenter, longcenter);
+
+ if (strlen (importfilename) > 4)
+ {
+ maps = g_renew (mapsstruct, maps, (nrmaps + 2));
+ g_strlcpy ((maps + nrmaps)->filename, importfilename, 200);
+ (maps + nrmaps)->lat = latcenter;
+ (maps + nrmaps)->lon = longcenter;
+ (maps + nrmaps)->scale = scale;
+ nrmaps++;
+ havenasa = -1;
+
+ savemapconfig ();
+ }
+
+ current.importactive = FALSE;
+ g_strlcpy (oldfilename, "XXXAFHSGFAERGXXXXXX", sizeof (oldfilename));
+ return TRUE;
+}
+
+
+gint
+import2_cb (GtkWidget * widget, gpointer datum)
+{
+ G_CONST_RETURN gchar *s = NULL;
+
+ s = gtk_entry_get_text (GTK_ENTRY (dl_text_lat));
+ coordinate_string2gdouble (s, &imports[0].lat);
+ s = gtk_entry_get_text (GTK_ENTRY (dl_text_lon));
+ coordinate_string2gdouble (s, &imports[0].lon);
+ s = gtk_entry_get_text (GTK_ENTRY (dltext5));
+ imports[0].x = strtol (s, NULL, 0);
+ s = gtk_entry_get_text (GTK_ENTRY (dltext6));
+ imports[0].y = strtol (s, NULL, 0);
+
+
+ if (debug)
+ {
+ fprintf (stderr, "Import: lat:%g,lon:%g x:%d,y:%d\n",
+ imports[0].lat, imports[0].lon, imports[0].x, imports[0].y);
+ }
+
+ gtk_widget_destroy (widget);
+
+ import1_cb (NULL, 2);
+
+ return TRUE;
+}
+
+gint
+import3_cb (GtkWidget * widget, gpointer datum)
+{
+ G_CONST_RETURN gchar *s = NULL;
+ gdouble tx, ty, scale, latmax, latmin, latcenter, longmax, longmin;
+ gdouble longcenter;
+ gdouble px, py;
+
+ s = gtk_entry_get_text (GTK_ENTRY (dl_text_lat));
+ coordinate_string2gdouble (s, &imports[1].lat);
+
+ s = gtk_entry_get_text (GTK_ENTRY (dl_text_lon));
+ coordinate_string2gdouble (s, &imports[1].lon);
+
+ s = gtk_entry_get_text (GTK_ENTRY (dltext5));
+ imports[1].x = strtol (s, NULL, 0);
+
+ s = gtk_entry_get_text (GTK_ENTRY (dltext6));
+ imports[1].y = strtol (s, NULL, 0);
+
+ gtk_widget_destroy (widget);
+
+ /* Calc coordinates and scale */
+
+ tx = (2 * R * M_PI / 360) * cos (M_PI * imports[0].lat / 180.0) *
+ (imports[0].lon - imports[1].lon);
+ ty = (2 * R * M_PI / 360) * (imports[0].lat - imports[1].lat);
+ /* ty is meter */
+ px = abs (imports[0].x - imports[1].x);
+ py = abs (imports[0].y - imports[1].y);
+ if (px > py)
+ scale = fabs (tx) * PIXELFACT / px;
+ else
+ scale = fabs (ty) * PIXELFACT / py;
+ px = imports[0].x - imports[1].x;
+ py = imports[0].y - imports[1].y;
+ py = -py;
+
+ latmin = imports[0].lat - (imports[0].lat - imports[1].lat) * (1024 -
+ imports
+ [0].y) / py;
+ latmax = latmin + (imports[0].lat - imports[1].lat) * 1024.0 / py;
+ latcenter = (latmax + latmin) / 2.0;
+
+ longmin =
+ imports[0].lon - imports[0].x * (imports[0].lon - imports[1].lon) / px;
+
+ longmax = longmin + 1280.0 * (imports[0].lon - imports[1].lon) / px;
+ longcenter = (longmax + longmin) / 2.0;
+
+ if (debug)
+ g_print ("Import: scale: %g, latmitte: %g, latmin: %g, "
+ "latmax: %g\n longmin: %g, longmax: %g, longmitte: %g\n",
+ scale, latcenter, latmin, latmax, longmin, longmax, longcenter);
+
+ if (strlen (importfilename) > 4)
+ {
+ maps = g_renew (mapsstruct, maps, (nrmaps + 2));
+ g_strlcpy ((maps + nrmaps)->filename, importfilename, 200);
+ (maps + nrmaps)->lat = latcenter;
+ (maps + nrmaps)->lon = longcenter;
+ (maps + nrmaps)->scale = scale;
+ nrmaps++;
+ havenasa = -1;
+
+ savemapconfig ();
+ }
+
+ current.importactive = FALSE;
+ g_strlcpy (oldfilename, "XXXAFHSGFAERGXXXXXX", sizeof (oldfilename));
+
+ return TRUE;
+}
+
+/*
+ * handle map scrolling event
+ * ie zoom in / out
+ */
+gint
+mapscroll_cb (GtkWidget *widget, GdkEventScroll *event) {
+ switch(event->direction) {
+ case(GDK_SCROLL_UP): /* zoom in */
+ scalerbt_cb (NULL, 2);
+ break;
+ case(GDK_SCROLL_DOWN): /* zoom out */
+ scalerbt_cb (NULL, 1);
+ break;
+ case(GDK_SCROLL_LEFT): /* blank */
+ break;
+ case(GDK_SCROLL_RIGHT): /* blank */
+ break;
+ }
+ return TRUE;
+}
+
+gint
+mapclick_cb (GtkWidget * widget, GdkEventButton * event)
+{
+ gint x, y;
+ gdouble lon, lat;
+ GdkModifierType state;
+ gchar s[200];
+
+ /* printf("bin in mapclick\n"); */
+
+ if (event->button)
+ gdk_window_get_pointer (event->window, &x, &y, &state);
+ else
+ {
+ x = event->x;
+ y = event->y;
+ state = event->state;
+ }
+ if (state == 0)
+ return 0;
+ calcxytopos (x, y, &lat, &lon, current.zoom);
+ if (mydebug)
+ {
+ fprintf (stderr, "Mouse click at x:%d,y:%d -->lat:%f,lon:%f \n", x, y,lat,lon);
+ }
+
+ if (downloadwindowactive || current.importactive)
+ {
+ if (downloadwindowactive)
+ {
+ coordinate2gchar (s, sizeof (s), lat, TRUE,
+ local_config.coordmode);
+ gtk_entry_set_text (GTK_ENTRY (dl_text_lat), s);
+ coordinate2gchar (s, sizeof (s), lon, FALSE,
+ local_config.coordmode);
+ gtk_entry_set_text (GTK_ENTRY (dl_text_lon), s);
+ downloadsetparm (NULL, 0);
+ }
+ else
+ {
+ g_snprintf (s, sizeof (s), "%d",
+ x / current.zoom + (640 - SCREEN_X_2 / current.zoom) + xoff
+ / current.zoom);
+ gtk_entry_set_text (GTK_ENTRY (dltext5), s);
+ g_snprintf (s, sizeof (s), "%d",
+ y / current.zoom + (512 - SCREEN_Y_2 / current.zoom) + yoff
+ / current.zoom);
+ gtk_entry_set_text (GTK_ENTRY (dltext6), s);
+
+ }
+
+ }
+ else
+ {
+ /* g_print("\nstate: %x x:%d y:%d", state, x, y); */
+ //vali = (GTK_ADJUSTMENT (scaler_adj)->value);
+ /* Left mouse button + shift key */
+ if ((state & (GDK_BUTTON1_MASK | GDK_SHIFT_MASK)) ==
+ (GDK_BUTTON1_MASK | GDK_SHIFT_MASK))
+ {
+ scalerbt_cb (NULL, 2);
+ return TRUE;
+ }
+ /* Add mouse position as waypoint */
+ /* Left mouse button + control key */
+ if ((state & (GDK_BUTTON1_MASK | GDK_CONTROL_MASK)) ==
+ (GDK_BUTTON1_MASK | GDK_CONTROL_MASK))
+ {
+ coords.wp_lat = lat;
+ coords.wp_lon = lon;
+ addwaypoint_cb (NULL, 0);
+ return TRUE;
+ }
+ /* Add current position as waypoint */
+ /* Right mouse button + control key */
+ if ((state & (GDK_BUTTON3_MASK | GDK_CONTROL_MASK)) ==
+ (GDK_BUTTON3_MASK | GDK_CONTROL_MASK))
+ {
+ coords.wp_lat = coords.current_lat;
+ coords.wp_lon = coords.current_lon;
+
+ addwaypoint_cb (NULL, 0);
+ return TRUE;
+ }
+ /* Right mouse button + shift key */
+ if ((state & (GDK_BUTTON3_MASK | GDK_SHIFT_MASK)) ==
+ (GDK_BUTTON3_MASK | GDK_SHIFT_MASK))
+ {
+ scalerbt_cb (NULL, 1);
+ return TRUE;
+ }
+
+ /* Left mouse button */
+ if ((state & GDK_BUTTON1_MASK) == GDK_BUTTON1_MASK)
+ {
+ if (gui_status.posmode)
+ {
+ coords.posmode_lon = lon;
+ coords.posmode_lat = lat;
+ rebuildtracklist ();
+ }
+ }
+ /* Middle mouse button */
+ if ((state & GDK_BUTTON2_MASK) == GDK_BUTTON2_MASK)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (posbt), FALSE);
+
+ rebuildtracklist ();
+ }
+ /* Right mouse button */
+ if ((state & GDK_BUTTON3_MASK) == GDK_BUTTON3_MASK)
+ {
+ /* set as target */
+ /* only if RIGHT mouse button clicked */
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (posbt), FALSE);
+ rebuildtracklist ();
+ g_strlcpy (current.target, _("SELECTED"), sizeof (current.target));
+// g_snprintf (s, sizeof (s), "%s: %s", _("To"), current.target);
+// gtk_frame_set_label (GTK_FRAME (destframe), s);
+ coords.target_lat = lat;
+ coords.target_lon = lon;
+ g_timer_stop (disttimer);
+ g_timer_start (disttimer);
+ olddist = current.dist;
+ }
+ }
+
+ /* g_print("\nx: %d, y: %d", x, y); */
+ return TRUE;
+}
diff --git a/src/import_map.h b/src/import_map.h
new file mode 100644
index 0000000..12daa32
--- /dev/null
+++ b/src/import_map.h
@@ -0,0 +1,59 @@
+/***********************************************************************
+
+Copyright (c) 2001,2002 Fritz Ganter <ganter@ganter.at>
+
+Website: www.kraftvoll.at/software
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+/*
+$Log$
+Revision 1.2 2005/04/02 12:10:12 tweety
+2005.03.30 by Oddgeir Kvien <oddgeir@oddgeirkvien.com>
+Canges made to import a map with one point and enter the scale
+
+Revision 1.1 2005/03/27 21:25:46 tweety
+separating map_import from gpsdrive.c
+
+
+*/
+
+
+#ifndef GPSDRIVE_IMPORT_MAP_H
+#define GPSDRIVE_IMPORT_MAP_H
+
+#include <gtk/gtk.h>
+
+/*
+ * See import_map.c for details.
+ */
+
+gint importfb_cb (GtkWidget * widget, guint datum);
+gint importshift_cb (GtkWidget * widget, guint datum);
+gint import1_cb (GtkWidget * widget, guint datum);
+gint import2_cb (GtkWidget * widget, gpointer datum);
+gint import3_cb (GtkWidget * widget, gpointer datum);
+gint setrefpoint_cb (GtkWidget * widget, guint datum);
+gint mapscroll_cb (GtkWidget * widget, GdkEventScroll * event);
+gint mapclick_cb (GtkWidget * widget, GdkEventButton * event);
+gint importshift_cb (GtkWidget * widget, guint datum);
+gint importshift_cb (GtkWidget * widget, guint datum);
+gint import_scale_cb(GtkWidget * widget, gpointer datum);
+
+
+#endif /* GPSDRIVE_IMPORT_MAP_H */
diff --git a/src/lib_map/CMakeLists.txt b/src/lib_map/CMakeLists.txt
new file mode 100644
index 0000000..b514c3f
--- /dev/null
+++ b/src/lib_map/CMakeLists.txt
@@ -0,0 +1,36 @@
+PROJECT(libmap)
+
+set(LIBMAP_PUBLIC_INCLUDE_DIRS
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ CACHE INTERNAL "gpsdrive public include directories"
+)
+
+include_directories(
+ ${LIBMAP_PUBLIC_INCLUDE_DIRS}
+)
+
+# GTK
+if (GTK_FOUND)
+ include_directories(${GTK_INCLUDE_DIR})
+endif (GTK_FOUND)
+
+# GDAL
+if (GDAL_FOUND)
+ include_directories(${GDAL_INCLUDE_DIR})
+endif (GDAL_FOUND)
+
+set(libmap_SRCS
+ map_draw.c
+ map_gpsmisc.c
+ map_load.c
+ map_port.c
+ map_render.c
+ map_transform.c
+ map_port_cpp.cpp
+ map_render_cpp.cpp
+ map.h
+ map_priv.h
+)
+
+ADD_LIBRARY(map STATIC ${libmap_SRCS})
+
diff --git a/src/lib_map/Makefile.am b/src/lib_map/Makefile.am
new file mode 100644
index 0000000..54aeea7
--- /dev/null
+++ b/src/lib_map/Makefile.am
@@ -0,0 +1,23 @@
+lib_map_dir = $(datadir)/gpsdrive
+lib_mapdir = $(datadir)/gpsdrive
+lib_map_a_SOURCES= \
+ map_draw.c map_gpsmisc.c map_load.c map_port.c map_render.c \
+ map_transform.c \
+ map_port_cpp.cpp map_render_cpp.cpp \
+ map.h map_priv.h
+
+
+if HAVE_GDAL
+MAPDIR = ../../data/maps
+
+lib_map_a_LIBRARIES=lib_map.a
+lib_map_adir=$(datadir)/gpsdrive
+lib_map_a_CXXFLAGS = \
+ $(lib_map_cflags)\
+ $(PREFIX) $(PLUGINPATH) \
+ $(PKGDATAPATH) $(GDAL_CFLAGS) \
+ $(CXXFLAGS) $(EXTRA_CXXFLAGS)
+endif
+
+
+EXTRA_DIST = $(lib_map_la_SOURCES) map.h CMakeLists.txt
diff --git a/src/lib_map/Makefile.in b/src/lib_map/Makefile.in
new file mode 100644
index 0000000..95bdddb
--- /dev/null
+++ b/src/lib_map/Makefile.in
@@ -0,0 +1,606 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/lib_map
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_perl_modules.m4 \
+ $(top_srcdir)/m4/ac_check_socketlen_t.m4 \
+ $(top_srcdir)/m4/aq_check_gdal.m4 $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(lib_map_adir)"
+lib_map_aLIBRARIES_INSTALL = $(INSTALL_DATA)
+LIBRARIES = $(lib_map_a_LIBRARIES)
+ARFLAGS = cru
+lib_map_a_AR = $(AR) $(ARFLAGS)
+lib_map_a_LIBADD =
+am_lib_map_a_OBJECTS = map_draw.$(OBJEXT) map_gpsmisc.$(OBJEXT) \
+ map_load.$(OBJEXT) map_port.$(OBJEXT) map_render.$(OBJEXT) \
+ map_transform.$(OBJEXT) lib_map_a-map_port_cpp.$(OBJEXT) \
+ lib_map_a-map_render_cpp.$(OBJEXT)
+lib_map_a_OBJECTS = $(am_lib_map_a_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(lib_map_a_SOURCES)
+DIST_SOURCES = $(lib_map_a_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkgdatadir = @pkgdatadir@
+ACLOCAL = @ACLOCAL@
+AMAPNIK = @AMAPNIK@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_GLIB_LIBS = @DBUS_GLIB_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISABLEGARMIN_FALSE = @DISABLEGARMIN_FALSE@
+DISABLEGARMIN_TRUE = @DISABLEGARMIN_TRUE@
+DISABLEPLUGINS_FALSE = @DISABLEPLUGINS_FALSE@
+DISABLEPLUGINS_TRUE = @DISABLEPLUGINS_TRUE@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRIENDSSERVERVERSION = @FRIENDSSERVERVERSION@
+GDAL_CFLAGS = @GDAL_CFLAGS@
+GDAL_CONFIG = @GDAL_CONFIG@
+GDAL_LDADD = @GDAL_LDADD@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GLIB_MKENUMS = @GLIB_MKENUMS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GOBJECT_QUERY = @GOBJECT_QUERY@
+GREP = @GREP@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+HAVE_DBUS_FALSE = @HAVE_DBUS_FALSE@
+HAVE_DBUS_TRUE = @HAVE_DBUS_TRUE@
+HAVE_GDAL_FALSE = @HAVE_GDAL_FALSE@
+HAVE_GDAL_TRUE = @HAVE_GDAL_TRUE@
+HAVE_GTK_FALSE = @HAVE_GTK_FALSE@
+HAVE_GTK_TRUE = @HAVE_GTK_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBADD_DL = @LIBADD_DL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NOGARMIN = @NOGARMIN@
+NOPLUGINS = @NOPLUGINS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PCRE_CONFIG = @PCRE_CONFIG@
+PERL = @PERL@
+PERL_PACKAGE_DIR = @PERL_PACKAGE_DIR@
+PKGCONFIG_CFLAGS = @PKGCONFIG_CFLAGS@
+PKGCONFIG_LIBS = @PKGCONFIG_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+POSUB = @POSUB@
+POW_LIB = @POW_LIB@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WITH_MAPNIK_FALSE = @WITH_MAPNIK_FALSE@
+WITH_MAPNIK_TRUE = @WITH_MAPNIK_TRUE@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XML_CFLAGS = @XML_CFLAGS@
+XML_LIBS = @XML_LIBS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+lib_map_dir = $(datadir)/gpsdrive
+lib_mapdir = $(datadir)/gpsdrive
+lib_map_a_SOURCES = \
+ map_draw.c map_gpsmisc.c map_load.c map_port.c map_render.c \
+ map_transform.c \
+ map_port_cpp.cpp map_render_cpp.cpp \
+ map.h map_priv.h
+
+@HAVE_GDAL_TRUE@MAPDIR = ../../data/maps
+@HAVE_GDAL_TRUE@lib_map_a_LIBRARIES = lib_map.a
+@HAVE_GDAL_TRUE@lib_map_adir = $(datadir)/gpsdrive
+@HAVE_GDAL_TRUE@lib_map_a_CXXFLAGS = \
+@HAVE_GDAL_TRUE@ $(lib_map_cflags)\
+@HAVE_GDAL_TRUE@ $(PREFIX) $(PLUGINPATH) \
+@HAVE_GDAL_TRUE@ $(PKGDATAPATH) $(GDAL_CFLAGS) \
+@HAVE_GDAL_TRUE@ $(CXXFLAGS) $(EXTRA_CXXFLAGS)
+
+EXTRA_DIST = $(lib_map_la_SOURCES) map.h CMakeLists.txt
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cpp .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/lib_map/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/lib_map/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-lib_map_aLIBRARIES: $(lib_map_a_LIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(lib_map_adir)" || $(mkdir_p) "$(DESTDIR)$(lib_map_adir)"
+ @list='$(lib_map_a_LIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(lib_map_aLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(lib_map_adir)/$$f'"; \
+ $(lib_map_aLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(lib_map_adir)/$$f"; \
+ else :; fi; \
+ done
+ @$(POST_INSTALL)
+ @list='$(lib_map_a_LIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ p=$(am__strip_dir) \
+ echo " $(RANLIB) '$(DESTDIR)$(lib_map_adir)/$$p'"; \
+ $(RANLIB) "$(DESTDIR)$(lib_map_adir)/$$p"; \
+ else :; fi; \
+ done
+
+uninstall-lib_map_aLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_map_a_LIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(lib_map_adir)/$$p'"; \
+ rm -f "$(DESTDIR)$(lib_map_adir)/$$p"; \
+ done
+
+clean-lib_map_aLIBRARIES:
+ -test -z "$(lib_map_a_LIBRARIES)" || rm -f $(lib_map_a_LIBRARIES)
+lib_map.a: $(lib_map_a_OBJECTS) $(lib_map_a_DEPENDENCIES)
+ -rm -f lib_map.a
+ $(lib_map_a_AR) lib_map.a $(lib_map_a_OBJECTS) $(lib_map_a_LIBADD)
+ $(RANLIB) lib_map.a
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_map_a-map_port_cpp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_map_a-map_render_cpp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map_draw.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map_gpsmisc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map_load.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map_port.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map_render.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map_transform.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+.cpp.o:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+lib_map_a-map_port_cpp.o: map_port_cpp.cpp
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_map_a_CXXFLAGS) $(CXXFLAGS) -MT lib_map_a-map_port_cpp.o -MD -MP -MF "$(DEPDIR)/lib_map_a-map_port_cpp.Tpo" -c -o lib_map_a-map_port_cpp.o `test -f 'map_port_cpp.cpp' || echo '$(srcdir)/'`map_port_cpp.cpp; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/lib_map_a-map_port_cpp.Tpo" "$(DEPDIR)/lib_map_a-map_port_cpp.Po"; else rm -f "$(DEPDIR)/lib_map_a-map_port_cpp.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='map_port_cpp.cpp' object='lib_map_a-map_port_cpp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_map_a_CXXFLAGS) $(CXXFLAGS) -c -o lib_map_a-map_port_cpp.o `test -f 'map_port_cpp.cpp' || echo '$(srcdir)/'`map_port_cpp.cpp
+
+lib_map_a-map_port_cpp.obj: map_port_cpp.cpp
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_map_a_CXXFLAGS) $(CXXFLAGS) -MT lib_map_a-map_port_cpp.obj -MD -MP -MF "$(DEPDIR)/lib_map_a-map_port_cpp.Tpo" -c -o lib_map_a-map_port_cpp.obj `if test -f 'map_port_cpp.cpp'; then $(CYGPATH_W) 'map_port_cpp.cpp'; else $(CYGPATH_W) '$(srcdir)/map_port_cpp.cpp'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/lib_map_a-map_port_cpp.Tpo" "$(DEPDIR)/lib_map_a-map_port_cpp.Po"; else rm -f "$(DEPDIR)/lib_map_a-map_port_cpp.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='map_port_cpp.cpp' object='lib_map_a-map_port_cpp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_map_a_CXXFLAGS) $(CXXFLAGS) -c -o lib_map_a-map_port_cpp.obj `if test -f 'map_port_cpp.cpp'; then $(CYGPATH_W) 'map_port_cpp.cpp'; else $(CYGPATH_W) '$(srcdir)/map_port_cpp.cpp'; fi`
+
+lib_map_a-map_render_cpp.o: map_render_cpp.cpp
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_map_a_CXXFLAGS) $(CXXFLAGS) -MT lib_map_a-map_render_cpp.o -MD -MP -MF "$(DEPDIR)/lib_map_a-map_render_cpp.Tpo" -c -o lib_map_a-map_render_cpp.o `test -f 'map_render_cpp.cpp' || echo '$(srcdir)/'`map_render_cpp.cpp; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/lib_map_a-map_render_cpp.Tpo" "$(DEPDIR)/lib_map_a-map_render_cpp.Po"; else rm -f "$(DEPDIR)/lib_map_a-map_render_cpp.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='map_render_cpp.cpp' object='lib_map_a-map_render_cpp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_map_a_CXXFLAGS) $(CXXFLAGS) -c -o lib_map_a-map_render_cpp.o `test -f 'map_render_cpp.cpp' || echo '$(srcdir)/'`map_render_cpp.cpp
+
+lib_map_a-map_render_cpp.obj: map_render_cpp.cpp
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_map_a_CXXFLAGS) $(CXXFLAGS) -MT lib_map_a-map_render_cpp.obj -MD -MP -MF "$(DEPDIR)/lib_map_a-map_render_cpp.Tpo" -c -o lib_map_a-map_render_cpp.obj `if test -f 'map_render_cpp.cpp'; then $(CYGPATH_W) 'map_render_cpp.cpp'; else $(CYGPATH_W) '$(srcdir)/map_render_cpp.cpp'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/lib_map_a-map_render_cpp.Tpo" "$(DEPDIR)/lib_map_a-map_render_cpp.Po"; else rm -f "$(DEPDIR)/lib_map_a-map_render_cpp.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='map_render_cpp.cpp' object='lib_map_a-map_render_cpp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_map_a_CXXFLAGS) $(CXXFLAGS) -c -o lib_map_a-map_render_cpp.obj `if test -f 'map_render_cpp.cpp'; then $(CYGPATH_W) 'map_render_cpp.cpp'; else $(CYGPATH_W) '$(srcdir)/map_render_cpp.cpp'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(lib_map_adir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-lib_map_aLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-lib_map_aLIBRARIES
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-lib_map_aLIBRARIES
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-lib_map_aLIBRARIES clean-libtool ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am \
+ install-lib_map_aLIBRARIES install-man install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-info-am \
+ uninstall-lib_map_aLIBRARIES
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/lib_map/map.h b/src/lib_map/map.h
new file mode 100644
index 0000000..398fa9c
--- /dev/null
+++ b/src/lib_map/map.h
@@ -0,0 +1,212 @@
+//
+// Copyright (c) 2005 -- Daniel Wallner
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#include <gdal.h>
+#include <cpl_conv.h>
+#include <ogr_srs_api.h>
+
+#ifdef HAVE_CAIRO
+#include <cairo.h>
+#endif
+
+#ifdef HAVE_GTK
+#include <gtk/gtk.h>
+#endif
+
+#ifdef HAVE_QUARTZ
+#include <Carbon/Carbon.h>
+#endif
+
+#ifdef WIN32
+#include <Windows.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{
+ int gblink;
+ int blink;
+ int milesflag;
+ int metricflag;
+ int nauticflag;
+ int pdamode;
+ int drawgrid;
+ int zoomscale;
+ int havepos;
+ int posmode;
+ int shadow;
+ int markwaypoint;
+
+#ifdef HAVE_GTK
+ GdkColor red;
+ GdkColor black;
+ GdkColor white;
+ GdkColor blue;
+ GdkColor nightcolor;
+ GdkColor lcd;
+ GdkColor lcd2;
+ GdkColor yellow;
+ GdkColor green;
+ GdkColor green2;
+ GdkColor mygray;
+ GdkColor textback;
+ GdkColor textbacknew;
+ GdkColor grey;
+ GdkColor orange;
+ GdkColor orange2;
+ GdkColor darkgrey;
+#endif
+}
+MapSettings;
+
+typedef struct
+{
+ GInt32 maps;
+ GDALDatasetH dataset[1024];
+ char *path[1024];
+}
+MapSet;
+
+typedef struct
+{
+ double req_lat;
+ double req_lon;
+ double req_scale;
+ double req_rotation;
+ double act_width;
+ double act_height;
+ double act_rotation;
+ double act_xZoom[9];
+ double act_yZoom[9];
+ GInt32 act_xPixel[9];
+ GInt32 act_yPixel[9];
+ char *path[9];
+ GDALDatasetH dataset[9];
+ double refScore;
+ GDALDatasetH altMaps[32];
+}
+MapState;
+
+typedef struct
+{
+#ifdef HAVE_CAIRO
+ cairo_t *cairo_cr;
+#endif
+#ifdef HAVE_GTK
+ GtkWidget *gtk_widget;
+ GdkDrawable *gtk_drawable;
+ GdkGC *gtk_gc;
+#endif
+#ifdef HAVE_QT
+ void *qt_painter;
+#endif
+#ifdef HAVE_QUARTZ
+ CGContextRef quartz_gc;
+#endif
+#ifdef WIN32
+ HDC win_dc;
+ HPEN win_pen;
+#endif
+}
+MapGC;
+
+// Map loading
+
+int mapinit(MapSettings *settings);
+
+int addmap(char *path, MapSet *mapset);
+
+int addmaps(char *path, MapSet *mapset);
+
+int freemaps(MapSet *mapset);
+
+int resetmap(MapState *mapstate);
+
+int findbestmap(MapSet *mapset, double lat, double lon,
+ double scale, int mode, double pixelsize);
+
+int selectbestmap(MapSet *mapset, MapState *mapstate,
+ int mode, double pixelsize);
+
+int coverifpossible(MapState *state, double width, double height);
+
+// Map info
+
+int metersperpixel(GDALDatasetH dataset, char *path, double lat,
+ double *xmpp, double *ympp);
+
+int scale2zoom(GDALDatasetH dataset, char *path,
+ double scale, double pixelsize, double lat,
+ double *xZoom, double *yZoom);
+
+int center2pixel(GDALDatasetH dataset,
+ GInt32 *xPixel, GInt32 *yPixel);
+
+double mapcontains(GDALDatasetH dataset, char *path, double lat, double lon);
+
+// Forward transforms
+
+int wgs2geo(GDALDatasetH dataset,
+ double lat, double lon,
+ double *xGeo, double *yGeo);
+
+int geo2pixel(GDALDatasetH dataset,
+ double xGeo, double yGeo,
+ GInt32 *xPixel, GInt32 *yPixel);
+
+int wgs2pixel(GDALDatasetH dataset, char *path,
+ double lat, double lon,
+ GInt32 *xPixel, GInt32 *yPixel);
+
+int wgs2state(double lat, double lon, MapState *state);
+
+int wgs2screen(MapState *state, double lat, double lon,
+ int *xPos, int *yPos);
+
+// Backward transforms
+
+int geo2wgs(GDALDatasetH dataset,
+ double xGeo, double yGeo,
+ double *lat, double *lon);
+
+int pixel2geo(GDALDatasetH dataset,
+ GInt32 xPixel, GInt32 yPixel,
+ double *xGeo, double *yGeo);
+
+int pixel2wgs(GDALDatasetH dataset, char* path,
+ GInt32 xPixel, GInt32 yPixel,
+ double *lat, double *lon);
+
+int screen2wgs(MapState *state, int xPos, int yPos,
+ double *lat, double *lon);
+
+// Rendering
+
+int drawmap(MapState *state, MapGC *mgc,
+ double viewWidth, double viewHeight, int mode);
+
+int drawmarkers(MapGC *mgc, int width, int height,
+ MapSettings *settings, MapState *state, double pixelsize,
+ double angle_to_destination, double direction);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/lib_map/map_draw.c b/src/lib_map/map_draw.c
new file mode 100644
index 0000000..635da8c
--- /dev/null
+++ b/src/lib_map/map_draw.c
@@ -0,0 +1,473 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+/*
+ * This file contains the refactored drawing functions from gpsdrive.c
+ */
+
+#include "map_priv.h"
+
+void
+draw_zoom_scale2 (MapGC *mgc, int width, int height,
+ MapSettings *settings,
+ GDALDatasetH dataset, char* path,
+ double zoom, double pixelsize)
+{
+ double milesconv = 1.0;
+
+ int pixels;
+ int m;
+ char txt[100];
+ pixels = 141 / milesconv;
+ //m = mapscale / (20 * zoom);
+
+ //m = scale2zoom(dataset, path, 1, pixelsize);
+ double xmpp, ympp;
+ metersperpixel(dataset, path, 0, &xmpp, &ympp);
+ m = pixels * (xmpp + ympp) / 2 / zoom;
+
+ if (m < 1000)
+ {
+ if (!settings->nauticflag)
+ snprintf (txt, sizeof (txt), "%d%s", m,
+ (settings->milesflag) ? "yrds" : "m");
+ else
+ snprintf (txt, sizeof (txt), "%.3f%s", m / 1000.0,
+ (settings->milesflag) ? "mi" : ((settings->metricflag) ? "km"
+ : "nmi"));
+
+ if (!settings->metricflag)
+ pixels = pixels * milesconv * 0.9144;
+ }
+ else
+ snprintf (txt, sizeof (txt), "%.1f%s", m / 1000.0,
+ (settings->milesflag) ? "mi" : ((settings->metricflag) ? "km" :
+ "nmi"));
+
+ //gdk_gc_set_foreground (mgc->gtk_gc, &settings->textback);
+ map_bkg_rectangle(mgc, settings,
+ (width - 20) - pixels - 5, height - 35,
+ pixels + 10, 30);
+
+ //gdk_gc_set_foreground (mgc->gtk_gc, &settings->black);
+
+ map_text(mgc, settings, width - 25, height - 33, txt, 0x100);
+
+ //gdk_gc_set_line_attributes (mgc->gtk_gc, 2, 0, 0, 0);
+ map_line(mgc, settings,
+ (width - 20) - pixels, height - 20 + 5,
+ (width - 20), height - 20 + 5, 0);
+ map_line(mgc, settings,
+ (width - 20) - pixels, height - 20,
+ (width - 20) - pixels, height - 20 + 10, 0);
+ map_line(mgc, settings,
+ (width - 20), height - 20,
+ (width - 20), height - 20 + 10, 0);
+
+ /* draw zoom factor */
+ snprintf (txt, sizeof (txt), "%lfx", zoom);
+
+ //gdk_gc_set_foreground (mgc->gtk_gc, &settings->mygray);
+ //map_bkg_rectangle(&mgc, settings, (width - 30), 0, 30, 30);
+
+ map_text(mgc, settings, width - 2, 2, txt, 0xd01);
+
+#ifdef MAP_DEBUG
+ /* draw file name */
+ {
+ char *filename = strrchr(path, '/');
+
+ if (filename)
+ filename++;
+ else
+ filename = path;
+
+ map_text(mgc, settings, 2, 2, filename, 0xc01);
+ }
+#endif
+}
+
+
+/* *****************************************************************************
+ */
+/*
+ * Draw a grid over the map
+ */
+void
+draw_grid2 (MapGC *mgc, int width, int height,
+ MapSettings *settings,
+ MapState *state, double pixelsize)
+{
+ int count;
+ double step;
+ double lat, lon;
+ double lat_ul, lon_ul;
+ double lat_ll, lon_ll;
+ double lat_ur, lon_ur;
+ double lat_lr, lon_lr;
+
+ double lat_min, lon_min;
+ double lat_max, lon_max;
+
+ // calculate the start and stop for lat/lon according to the displayed section
+ screen2wgs(state, 0, 0, &lat_ul, &lon_ul);
+ screen2wgs(state, 0, height, &lat_ll, &lon_ll);
+ screen2wgs(state, width, 0, &lat_ur, &lon_ur);
+ screen2wgs(state, width, height, &lat_lr, &lon_lr);
+ //calcxytopos2 (0, 0, &lat_ul, &lon_ul, current.zoom);
+ //calcxytopos2 (0, height, &lat_ll, &lon_ll, current.zoom);
+ //calcxytopos2 (width, 0, &lat_ur, &lon_ur, current.zoom);
+ //calcxytopos2 (width, height, &lat_lr, &lon_lr, current.zoom);
+
+ lat_min = MIN (lat_ll, lat_ul);
+ lat_max = MAX (lat_lr, lat_ur);
+ lon_min = MIN (lon_ll, lon_ul);
+ lon_max = MAX (lon_lr, lon_ur);
+
+ // Calculate distance between grid lines
+ {
+ double log10Step = floor(log10(lon_max - lon_min));
+ step = pow(10., log10Step);
+ double lines = (lon_max - lon_min) / step;
+
+ fprintf(stderr, "lines: %lf step: %lf\n", lines, step);
+
+ if (lines <= 1.5)
+ {
+ step *= 0.2;
+ }
+ else if (lines <= 3.5)
+ {
+ step *= 0.5;
+ }
+
+ fprintf(stderr, "step2: %lf\n", step);
+ }
+
+ lat_min = floor(lat_min / step) * step;
+ lon_min = floor(lon_min / step) * step;
+
+#ifdef MAP_DEBUG
+ printf ("Draw Grid: (%.2f,%.2f) - (%.2f,%.2f)\n", lat_min,
+ lon_min, lat_max, lon_max);
+#endif
+
+ // Set Drawing Colors
+ //gdk_gc_set_function (mgc->gtk_gc, GDK_AND);
+
+
+ // Loop over desired lat/lon
+ count = 0;
+ for (lon = lon_min; lon <= lon_max; lon = lon + step)
+ {
+ for (lat = lat_min; lat <= lat_max; lat = lat + step)
+ {
+ //gdouble posxdest11, posydest11;
+ //gdouble posxdest12, posydest12;
+ //gdouble posxdest21, posydest21;
+ //gdouble posxdest22, posydest22;
+ //gdouble posxdist, posydist;
+ GInt32 posxdest11, posydest11;
+ GInt32 posxdest12, posydest12;
+ GInt32 posxdest21, posydest21;
+ GInt32 posxdest22, posydest22;
+ GInt32 posxdist, posydist;
+ char str[200];
+
+ count++;
+
+ wgs2screen(state, lat, lon, &posxdest11, &posydest11);
+ wgs2screen(state, lat + step, lon, &posxdest12, &posydest12);
+ wgs2screen(state, lat, lon + step, &posxdest21, &posydest21);
+ wgs2screen(state, lat + step, lon + step, &posxdest22, &posydest22);
+ //calcxy2 (&posxdest11, &posydest11, lon, lat, current.zoom);
+ //calcxy2 (&posxdest12, &posydest12, lon, lat + step, current.zoom);
+ //calcxy2 (&posxdest21, &posydest21, lon + step, lat, current.zoom);
+ //calcxy2 (&posxdest22, &posydest22, lon + step, lat + step, current.zoom);
+
+ if (((posxdest11 >= 0) && (posxdest11 < width) &&
+ (posydest11 >= 0) && (posydest11 < height))
+ ||
+ ((posxdest22 >= 0) && (posxdest22 < width) &&
+ (posydest22 >= 0) && (posydest22 < height))
+ ||
+ ((posxdest21 >= 0) && (posxdest21 < width) &&
+ (posydest21 >= 0) && (posydest21 < height))
+ ||
+ ((posxdest12 >= 0) && (posxdest12 < width) &&
+ (posydest12 >= 0) && (posydest12 < height)))
+ {
+ // TODO: add linethikness 2 for Mayor Lines
+ map_line(mgc, settings,
+ posxdest11, posydest11,
+ posxdest21, posydest21, 1);
+ map_line(mgc, settings,
+ posxdest11, posydest11,
+ posxdest12, posydest12, 1);
+
+ // Text lon
+ if (step >= 1)
+ snprintf (str, sizeof (str), "%.0f",
+ lon);
+ else if (step >= .1)
+ snprintf (str, sizeof (str), "%.1f",
+ lon);
+ else if (step >= .01)
+ snprintf (str, sizeof (str), "%.2f",
+ lon);
+ else if (step >= .001)
+ snprintf (str, sizeof (str), "%.3f",
+ lon);
+ else
+ snprintf (str, sizeof (str), "%.4f",
+ lon);
+ posxdist = (posxdest12 - posxdest11) / 4;
+ posydist = (posydest12 - posydest11) / 4;
+ map_text (mgc, settings,
+ posxdest11 + posxdist,
+ posydest11 + posydist,
+ str, 0x300);
+
+ // Text lat
+ if (step >= 1)
+ snprintf (str, sizeof (str), "%.0f",
+ lat);
+ else if (step >= .1)
+ snprintf (str, sizeof (str), "%.1f",
+ lat);
+ else if (step >= .01)
+ snprintf (str, sizeof (str), "%.2f",
+ lat);
+ else if (step >= .001)
+ snprintf (str, sizeof (str), "%.3f",
+ lat);
+ else
+ snprintf (str, sizeof (str), "%.4f",
+ lat);
+ posxdist = (posxdest21 - posxdest11) / 4;
+ posydist = (posydest21 - posydest11) / 4;
+ map_text (mgc, settings,
+ posxdest11 + posxdist,
+ posydest11 + posydist,
+ str, 0x300);
+ }
+ }
+ }
+#ifdef MAP_DEBUG
+ printf ("draw_grid loops: %d\n", count);
+#endif
+}
+
+#ifdef yetToBeRefactored
+
+/* *****************************************************************************
+ * draw wlan Waypoints
+ */
+void
+drawwlan (gint posxdest, gint posydest, gint wlan)
+{
+ /* wlan=0: no wlan, 1:open wlan, 2:WEP crypted wlan */
+
+ if (wlan == 0)
+ return;
+
+ if ((posxdest >= 0) && (posxdest < SCREEN_X))
+ {
+ if ((posydest >= 0) && (posydest < SCREEN_Y))
+ {
+ if (wlan == 1)
+ gdk_draw_pixbuf (drawable, mgc->gtk_gc,
+ openwlanpixbuf, 0, 0,
+ posxdest - 14, posydest - 12,
+ 24, 24, GDK_RGB_DITHER_NONE,
+ 0, 0);
+ else
+ gdk_draw_pixbuf (drawable, mgc->gtk_gc,
+ closedwlanpixbuf, 0, 0,
+ posxdest - 14, posydest - 12,
+ 24, 24, GDK_RGB_DITHER_NONE,
+ 0, 0);
+ }
+ }
+}
+
+
+/* *****************************************************************************
+ * Draw waypoints on map
+ */
+// TODO: Put this in its own file
+void
+draw_waypoints ()
+{
+ gdouble posxdest, posydest;
+ gint k, k2, i, shownwp = 0;
+ gchar txt[200];
+
+ if (debug)
+ printf ("draw_waypoints()\n");
+
+ /* draw waypoints */
+ for (i = 0; i < maxwp; i++)
+ {
+ calcxy (&posxdest, &posydest,
+ (wayp + i)->lon, (wayp + i)->lat, current.zoom);
+
+ if ((posxdest >= 0) && (posxdest < SCREEN_X)
+ && (shownwp < MAXSHOWNWP)
+ && (posydest >= 0) && (posydest < SCREEN_Y))
+ {
+ gdk_gc_set_line_attributes (mgc->gtk_gc, 2, 0, 0, 0);
+ shownwp++;
+ g_strlcpy (txt, (wayp + i)->name, sizeof (txt));
+
+ // Draw Icon(typ) or + Sign
+ if ((wayp + i)->wlan > 0)
+ drawwlan (posxdest, posydest,
+ (wayp + i)->wlan);
+ else
+ drawicon (posxdest, posydest,
+ (wayp + i)->typ);
+
+ // Draw Proximity Circle
+ if ((wayp + i)->proximity > 0.0)
+ {
+ gint proximity_pixels;
+ if (mapscale)
+ proximity_pixels =
+ ((wayp + i)->proximity)
+ * current.zoom * PIXELFACT
+ / mapscale;
+ else
+ proximity_pixels = 2;
+
+ gdk_gc_set_foreground (mgc->gtk_gc, &blue);
+
+ gdk_draw_arc (drawable, mgc->gtk_gc, FALSE,
+ posxdest - proximity_pixels,
+ posydest - proximity_pixels,
+ proximity_pixels * 2,
+ proximity_pixels * 2, 0,
+ 64 * 360);
+ }
+
+
+ { /* draw shadow of text */
+ PangoFontDescription *pfd;
+ PangoLayout *wplabellayout;
+ gint width, height;
+ gchar *tn;
+
+ gdk_gc_set_foreground (mgc->gtk_gc, &darkgrey);
+ gdk_gc_set_function (mgc->gtk_gc, GDK_AND);
+ tn = g_strdelimit (txt, "_", ' ');
+
+ wplabellayout =
+ gtk_widget_create_pango_layout
+ (map_drawingarea, tn);
+ pfd = pango_font_description_from_string
+ (wplabelfont);
+ pango_layout_set_font_description
+ (wplabellayout, pfd);
+ pango_layout_get_pixel_size (wplabellayout,
+ &width, &height);
+ /* printf("j: %d\n",height); */
+ k = width + 4;
+ k2 = height;
+ if (shadow)
+ {
+ gdk_draw_layout_with_colors (drawable,
+ mgc->gtk_gc,
+ posxdest
+ + 15 +
+ SHADOWOFFSET,
+ posydest
+ -
+ k2 / 2 +
+ SHADOWOFFSET,
+ wplabellayout,
+ &darkgrey,
+ NULL);
+ }
+ if (wplabellayout != NULL)
+ g_object_unref (G_OBJECT
+ (wplabellayout));
+ /* freeing PangoFontDescription, cause it has been copied by prev. call */
+ pango_font_description_free (pfd);
+
+ }
+ gdk_gc_set_function (mgc->gtk_gc, GDK_COPY);
+
+
+ gdk_gc_set_function (mgc->gtk_gc, GDK_AND);
+
+ gdk_gc_set_foreground (mgc->gtk_gc, &textbacknew);
+ gdk_draw_rectangle (drawable, mgc->gtk_gc, 1,
+ posxdest + 13, posydest - k2 / 2,
+ k + 1, k2);
+ gdk_gc_set_function (mgc->gtk_gc, GDK_COPY);
+ gdk_gc_set_foreground (mgc->gtk_gc, &black);
+ gdk_gc_set_line_attributes (mgc->gtk_gc, 1, 0, 0, 0);
+ gdk_draw_rectangle (drawable, mgc->gtk_gc, 0,
+ posxdest + 12,
+ posydest - k2 / 2 - 1, k + 2, k2);
+
+ /* gdk_gc_set_foreground (mgc->gtk_gc, &yellow); */
+ {
+ /* prints in pango */
+ PangoFontDescription *pfd;
+ PangoLayout *wplabellayout;
+
+ wplabellayout =
+ gtk_widget_create_pango_layout
+ (map_drawingarea, txt);
+ pfd = pango_font_description_from_string
+ (wplabelfont);
+ pango_layout_set_font_description
+ (wplabellayout, pfd);
+
+ gdk_draw_layout_with_colors (drawable,
+ mgc->gtk_gc,
+ posxdest + 15,
+ posydest -
+ k2 / 2,
+ wplabellayout,
+ &white, NULL);
+ if (wplabellayout != NULL)
+ g_object_unref (G_OBJECT
+ (wplabellayout));
+ /* freeing PangoFontDescription, cause it has been copied by prev. call */
+ pango_font_description_free (pfd);
+
+ }
+
+ /* gdk_draw_text (drawable, smalltextfont, mgc->gtk_gc,
+ * posxdest + 13, posydest + 6, txt,
+ * strlen (txt));
+ */
+ }
+ }
+}
+
+#endif
+
diff --git a/src/lib_map/map_gpsmisc.c b/src/lib_map/map_gpsmisc.c
new file mode 100644
index 0000000..b01ceec
--- /dev/null
+++ b/src/lib_map/map_gpsmisc.c
@@ -0,0 +1,182 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ *********************************************************************/
+
+/*
+ * Everything but the necessary functionality for libgpsdrive stripped
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "map_priv.h"
+
+/* ******************************************************************
+ * calculate Earth radius for given lat
+ */
+double
+calcR2 (double lat)
+{
+ double a = 6378.137, r, sc, x, y, z;
+ double e2 = 0.08182 * 0.08182;
+ /* the radius of curvature of an ellipsoidal Earth in the plane of
+ * the meridian is given by
+ *
+ * R' = a * (1 - e^2) / (1 - e^2 * (sin(lat))^2)^(3/2)
+ *
+ * where a is the equatorial radius,
+ *
+ * b is the polar radius, and
+ * e is the eccentricity of the ellipsoid = sqrt(1 - b^2/a^2)
+ *
+ * a = 6378.137 km (3963 mi) Equatorial radius (surface to center distance)
+ * b = 6356.752 km (3950 mi) Polar radius (surface to center distance)
+ * e = 0.08182 Eccentricity
+ */
+
+ lat = lat * M_PI / 180.0;
+ sc = sin (lat);
+ x = a * (1.0 - e2);
+ z = 1.0 - e2 * sc * sc;
+ y = pow (z, 1.5);
+ r = x / y;
+
+ r = r * 1000.0;
+ /* g_print("\nR=%f",r); */
+ return r;
+}
+
+/* **********************************************************************
+ * Estimate the earth radius for given latitude
+ */
+double
+lat2radius2 (double lat)
+{
+ if (lat > 90.0)
+ {
+ lat = lat - 90;
+ }
+ if (lat < -90.0)
+ {
+ lat = lat + 90;
+ }
+ if (lat > 100)
+ {
+ fprintf (stderr, "ERROR: lat2radius(lat %lf) out of bound\n", lat);
+ lat = 100.0;
+ };
+ if (lat < -100)
+ {
+ fprintf (stderr, "ERROR: lat2radius(lat %lf) out of bound\n", lat);
+ lat = -100.0;
+ };
+ return calcR2((int) lat);
+}
+
+/* **********************************************************************
+ * calculates lat and lon for the given position on the screen
+ *
+ * modified version of calcxytopos
+ */
+void
+calcxytopos2 (int posx, int posy, double * mylat, double * mylon,
+ double zero_lat, double zero_long, double mapscale)
+{
+ int x, y, px, py;
+ double dif, lat, lon;
+ double current_lat = zero_lat; // ??????
+
+ double pixelfact = mapscale / PIXELFACT;
+
+ x = posx;
+ y = posy;
+ //px = (SCREEN_X_2 - x - xoff) * pixelfact / current.zoom;
+ //py = (-SCREEN_Y_2 + y + yoff) * pixelfact / current.zoom;
+ px = -posx * pixelfact;
+ py = posy * pixelfact;
+
+ lat = zero_lat - py / (lat2radius2 (current_lat) * M_PI / 180.0);
+ lat = zero_lat - py / (lat2radius2 (lat) * M_PI / 180.0);
+
+ if (lat > 360)
+ lat = lat - 360.0;
+ if (lat < -360)
+ lat = lat + 360.0;
+
+ lon = zero_long - px / ((lat2radius2 (lat) * M_PI / 180.0) *
+ cos (M_PI * lat / 180.0));
+
+ dif = lat * (1 -
+ (cos ((M_PI * fabs (lon - zero_long)) / 180.0)));
+ lat = lat - dif / 1.5;
+
+ if (lat > 360)
+ lat = 360.0;
+ if (lat < -360)
+ lat = -360.0;
+
+ lon = zero_long -
+ px / ((lat2radius2 (lat) * M_PI / 180.0) *
+ cos (M_PI * lat / 180.0));
+
+ if (lat > 360)
+ lat = 360.0;
+ if (lat < -360)
+ lat = -360.0;
+ if (lon > 180)
+ lon = 180.0;
+ if (lon < -180)
+ lon = -180.0;
+
+ *mylat = lat;
+ *mylon = lon;
+}
+
+/* ******************************************************************
+ * calculate xy pos of given lon/lat
+ *
+ * modified version of calcxy
+ */
+void
+calcxy2 (double * posx, double * posy, double lat, double lon,
+ double zero_lat, double zero_long, double mapscale)
+{
+ double dif;
+
+ double pixelfact = mapscale / PIXELFACT;
+
+ *posx = (lat2radius2 (lat) * M_PI / 180.0) * cos (M_PI * lat /
+ 180.0) *
+ (lon - zero_long);
+
+ *posx = *posx / pixelfact;
+
+ *posy = (lat2radius2 (lat) * M_PI / 180.0) * (lat - zero_lat);
+ dif = lat2radius2 (lat) * (1 -
+ (cos
+ ((M_PI * (lon - zero_long)) /
+ 180.0)));
+ *posy = *posy + dif / 1.85;
+
+ *posy = - *posy / pixelfact;
+}
diff --git a/src/lib_map/map_load.c b/src/lib_map/map_load.c
new file mode 100644
index 0000000..c193ec3
--- /dev/null
+++ b/src/lib_map/map_load.c
@@ -0,0 +1,574 @@
+//
+// Copyright (c) 2005 -- Daniel Wallner
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#include "map_priv.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <stdlib.h>
+
+int addmap(char *path, MapSet *mapset)
+{
+ GDALDatasetH dataset;
+#ifdef MAP_DEBUG
+ GDALDriverH driver;
+#endif
+
+ // Open file
+
+ dataset = GDALOpen(path, GA_ReadOnly);
+
+ if (!dataset)
+ {
+ return 0;
+ }
+
+#ifdef MAP_DEBUG
+ // Driver info
+
+ driver = GDALGetDatasetDriver(dataset);
+
+ fprintf(stderr,
+ "driver: %s/%s\n",
+ GDALGetDriverShortName(driver),
+ GDALGetDriverLongName(driver));
+
+ // File info
+
+ fprintf(stderr, "image size: %d x %d x %d\n",
+ GDALGetRasterXSize(dataset),
+ GDALGetRasterYSize(dataset),
+ GDALGetRasterCount(dataset));
+#endif
+
+ mapset->dataset[mapset->maps] = dataset;
+
+ mapset->path[mapset->maps] = (char *)malloc(strlen(path) + 1);
+ strcpy(mapset->path[mapset->maps], path);
+
+ return ++mapset->maps;
+}
+
+int addmaps(char *path, MapSet *mapset)
+{
+ DIR *dir;
+ struct dirent *direntry;
+ struct stat statbuf;
+
+ if (stat(path, &statbuf) == -1)
+ {
+ fprintf(stderr, "error opening map directory '%s': %s\n",
+ path,strerror(errno));
+
+ return 0;
+ }
+
+ if (!S_ISDIR(statbuf.st_mode))
+ {
+ addmap(path, mapset);
+ return mapset->maps;
+ }
+
+ dir = opendir(path);
+
+ if (!dir)
+ {
+ fprintf(stderr, "error opening map directory '%s': %s\n",
+ path,strerror(errno));
+
+ return 0;
+ }
+
+ while ((direntry = readdir(dir)))
+ {
+ char entrypath[1024];
+
+ if (!strcmp(direntry->d_name, ".") ||
+ !strcmp(direntry->d_name, "..") ||
+ strstr(direntry->d_name, ".wld") ||
+ strstr(direntry->d_name, ".txt"))
+ continue;
+
+ strcpy(entrypath, path);
+
+ if (entrypath[strlen(entrypath) - 1] != '/')
+ {
+ entrypath[strlen(entrypath) + 1] = 0;
+ entrypath[strlen(entrypath)] = '/';
+ }
+
+ strcat(entrypath, direntry->d_name);
+
+ addmap(entrypath, mapset);
+ }
+
+ closedir(dir);
+
+ return mapset->maps;
+}
+
+int freemaps(MapSet *mapset)
+{
+ GInt32 i;
+
+ for (i = 0; i < mapset->maps; i++)
+ {
+ GDALClose(mapset->dataset[i]);
+ free(mapset->path[i]);
+ }
+
+ return 1;
+}
+
+int resetmap(MapState *mapstate)
+{
+ int i;
+
+ mapstate->req_lat = 0;
+ mapstate->req_lon = 0;
+ mapstate->req_scale = 1;
+ mapstate->req_rotation = 0;
+ mapstate->act_width = 0;
+ mapstate->act_height = 0;
+ mapstate->act_rotation = 0;
+
+ for (i = 0; i < 9; i++)
+ {
+ mapstate->act_xZoom[i] = 1;
+ mapstate->act_yZoom[i] = 1;
+ mapstate->act_xPixel[i] = 0;
+ mapstate->act_yPixel[i] = 0;
+ mapstate->path[i] = NULL;
+ mapstate->dataset[i] = NULL;
+ }
+
+ mapstate->refScore = 10;
+
+ for (i = 0; i < 32; i++)
+ {
+ mapstate->altMaps[i] = NULL;
+ }
+
+ return 1;
+}
+
+double mapscore(GDALDatasetH dataset, char *path, double lat, double lon,
+ double scale, double pixelsize)
+{
+ double score = mapcontains(dataset, path, lat, lon);
+
+ double zoom;
+
+ if (score <= 0)
+ return score;
+
+ scale2zoom(dataset, path, scale, pixelsize, 0, &zoom, &zoom);
+
+ if (zoom < 1)
+ zoom = 1 / zoom / zoom;
+
+ return score / zoom;
+}
+
+int findbestmap(MapSet *mapset, double lat, double lon,
+ double scale, int mode, double pixelsize)
+{
+ int ret = 0;
+ double bestscore = -1e20;
+ int i;
+
+#ifdef MAP_DEBUG
+ fprintf(stderr, "find: %lf;%lf %lf\n", lat, lon, scale);
+#endif
+
+ for (i = 0; i < mapset->maps; i++)
+ {
+ if ((mode & 0x10) && strstr(mapset->path[i], "top_"))
+ continue;
+ if ((mode & 0x20) && strstr(mapset->path[i], "map_"))
+ continue;
+
+ double score = mapscore(mapset->dataset[i], mapset->path[i],
+ lat, lon, scale, pixelsize);
+
+ if (bestscore < score)
+ {
+ bestscore = score;
+ ret = i;
+ }
+
+#ifdef MAP_DEBUG
+ fprintf(stderr, "score: %lf best: %lf\n",
+ score, bestscore);
+#endif
+ }
+
+ return ret;
+}
+
+int setaltmaps(MapSet *mapset, MapState *mapstate, int mode, double pixelsize)
+{
+ int altIndex = 1;
+ int i;
+
+ #define ALT_ACCEPT 0.5
+
+ for (i = 0; i < mapset->maps && altIndex < 32; i++)
+ {
+ if (mapstate->altMaps[0] == mapset->dataset[i])
+ continue;
+
+ if ((mode & 0x10) && strstr(mapset->path[i], "top_"))
+ continue;
+ if ((mode & 0x20) && strstr(mapset->path[i], "map_"))
+ continue;
+
+ double score = mapscore(mapset->dataset[i], mapset->path[i],
+ mapstate->req_lat, mapstate->req_lon,
+ mapstate->req_scale, pixelsize);
+
+ if (score > mapstate->refScore * ALT_ACCEPT)
+ {
+ mapstate->altMaps[altIndex] = mapset->dataset[i];
+ altIndex++;
+ }
+ }
+
+ fprintf(stderr, "alt maps found: %d\n", altIndex - 1);
+
+ return altIndex;
+}
+
+int selectbestmap(MapSet *mapset, MapState *mapstate,
+ int mode, double pixelsize)
+{
+ double pseudoProj = (mode & 0x100) ? mapstate->req_lat : 0;
+ int map = -1;
+ int altIndex = -1;
+ int i;
+
+ #define NORMAL_DISCARD 0.8
+ #define ALT_DISCARD 0.4
+
+ if (mapstate->altMaps[1])
+ {
+ // Find current alt map index
+
+ for (i = 0; i < 32 && mapstate->altMaps[i]; i++)
+ {
+ if (mapstate->altMaps[i] == mapstate->dataset[0])
+ {
+ altIndex = i;
+ break;
+ }
+ }
+ }
+
+ if (mapstate->dataset[0])
+ {
+ // Check if old maps are good enough
+
+ if (altIndex != -1)
+ {
+ if (mode & 0x200)
+ {
+ altIndex++;
+ if (altIndex == 32 || !mapstate->altMaps[altIndex])
+ altIndex = 0;
+ }
+
+ for (i = 0; i < mapset->maps; i++)
+ {
+ if (mapset->dataset[i] == mapstate->altMaps[altIndex])
+ {
+ map = i;
+ break;
+ }
+ }
+
+ mapstate->dataset[0] = mapset->dataset[i];
+ mapstate->path[0] = mapset->path[i];
+
+ double score = mapscore(mapstate->dataset[0], mapstate->path[0],
+ mapstate->req_lat, mapstate->req_lon,
+ mapstate->req_scale, pixelsize);
+
+ if (score < mapstate->refScore * ALT_DISCARD)
+ map = -1;
+ }
+ else if (!(mode & 0x200))
+ {
+ double score = mapscore(mapstate->dataset[0], mapstate->path[0],
+ mapstate->req_lat, mapstate->req_lon,
+ mapstate->req_scale, pixelsize);
+
+ if (score > mapstate->refScore * NORMAL_DISCARD)
+ {
+#ifndef MAP_DEBUG
+ fprintf(stderr, "keeping old map: %s %lf %lf\n",
+ mapstate->path[0], score, mapstate->refScore);
+#endif
+ for (i = 0; i < mapset->maps; i++)
+ {
+ if (mapset->dataset[i] == mapstate->dataset[0])
+ {
+ map = i;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ fprintf(stderr, "map: %d alt: %d\n", map, altIndex);
+
+ if (map != -1)
+ {
+ wgs2pixel(mapstate->dataset[0], mapstate->path[0],
+ mapstate->req_lat, mapstate->req_lon,
+ &mapstate->act_xPixel[0], &mapstate->act_yPixel[0]);
+
+ scale2zoom(mapstate->dataset[0], mapstate->path[0],
+ mapstate->req_scale, pixelsize, pseudoProj,
+ &mapstate->act_xZoom[0], &mapstate->act_yZoom[0]);
+ }
+ else
+ {
+ map = findbestmap(mapset, mapstate->req_lat, mapstate->req_lon,
+ mapstate->req_scale, mode, pixelsize);
+
+ mapstate->dataset[0] = mapset->dataset[map];
+ mapstate->path[0] = mapset->path[map];
+
+ wgs2pixel(mapstate->dataset[0], mapstate->path[0],
+ mapstate->req_lat, mapstate->req_lon,
+ &mapstate->act_xPixel[0], &mapstate->act_yPixel[0]);
+
+ scale2zoom(mapstate->dataset[0], mapstate->path[0],
+ mapstate->req_scale, pixelsize, pseudoProj,
+ &mapstate->act_xZoom[0], &mapstate->act_yZoom[0]);
+
+ mapstate->refScore = mapscore(mapstate->dataset[0], mapstate->path[0],
+ mapstate->req_lat, mapstate->req_lon,
+ mapstate->req_scale, pixelsize);
+
+ mapstate->altMaps[0] = mapstate->dataset[0];
+
+ for (i = 1; i < 32; i++)
+ mapstate->altMaps[i] = NULL;
+
+ if (mode & 0x200)
+ setaltmaps(mapset, mapstate, mode, pixelsize);
+
+ if ((mode & 0xf) == 1)
+ {
+ // Add background map
+ int best = map;
+ double bestScale = 1e20;
+ double refScale;
+
+ scale2zoom(mapstate->dataset[0], mapstate->path[0],
+ 1, pixelsize, pseudoProj, &refScale, &refScale);
+
+ for (i = 0; i < mapset->maps; i++)
+ {
+ double scale;
+ scale2zoom(mapset->dataset[i], mapset->path[i],
+ 1, pixelsize, pseudoProj, &scale, &scale);
+
+ // We should check projection too!
+ if (scale > refScale && scale < bestScale &&
+ mapcontains(mapset->dataset[i], mapset->path[i],
+ mapstate->req_lat, mapstate->req_lon) > 0)
+ {
+ bestScale = scale;
+ best = i;
+ }
+ }
+
+ if (best != map)
+ {
+ mapstate->dataset[1] = mapset->dataset[best];
+ mapstate->path[1] = mapset->path[best];
+
+ wgs2pixel(mapstate->dataset[1], mapstate->path[1],
+ mapstate->req_lat, mapstate->req_lon,
+ &mapstate->act_xPixel[1], &mapstate->act_yPixel[1]);
+
+ scale2zoom(mapstate->dataset[1], mapstate->path[1],
+ mapstate->req_scale, pixelsize, pseudoProj,
+ &mapstate->act_xZoom[1], &mapstate->act_yZoom[1]);
+ }
+ else
+ {
+ mapstate->dataset[1] = NULL;
+ mapstate->path[1] = NULL;
+ }
+
+ mapstate->dataset[2] = NULL;
+ mapstate->path[2] = NULL;
+ }
+ else if ((mode & 0xf) == 2)
+ {
+ // Add map tiles
+ int maps = 1;
+ double refScale;
+
+ GInt32 width = GDALGetRasterXSize(mapstate->dataset[0]);
+ GInt32 height = GDALGetRasterYSize(mapstate->dataset[0]);
+
+ double minLat;
+ double maxLat;
+ double minLon;
+ double maxLon;
+
+ scale2zoom(mapstate->dataset[0], mapstate->path[0],
+ 1, pixelsize, pseudoProj, &refScale, &refScale);
+
+ pixel2wgs(mapstate->dataset[0], mapstate->path[0],
+ -10, -10, &maxLat, &minLon);
+ pixel2wgs(mapstate->dataset[0], mapstate->path[0],
+ width + 10, height + 10, &minLat, &maxLon);
+
+ for (i = 0; i < mapset->maps && maps < 8; i++)
+ {
+ double scale;
+
+ scale2zoom(mapset->dataset[i], mapset->path[i],
+ 1, pixelsize, pseudoProj, &scale, &scale);
+
+ // We should check projection too!
+ if (i != map && scale == refScale &&
+ (mapcontains(mapset->dataset[i], mapset->path[i],
+ minLat, minLon) > 0 ||
+ mapcontains(mapset->dataset[i], mapset->path[i],
+ maxLat, minLon) > 0 ||
+ mapcontains(mapset->dataset[i], mapset->path[i],
+ minLat, maxLon) > 0 ||
+ mapcontains(mapset->dataset[i], mapset->path[i],
+ maxLat, maxLon) > 0 ||
+ mapcontains(mapset->dataset[i], mapset->path[i],
+ (minLat + maxLat) / 2, minLon) > 0 ||
+ mapcontains(mapset->dataset[i], mapset->path[i],
+ minLat, (minLon + maxLon) / 2) > 0 ||
+ mapcontains(mapset->dataset[i], mapset->path[i],
+ (minLat + maxLat) / 2, maxLon) > 0 ||
+ mapcontains(mapset->dataset[i], mapset->path[i],
+ maxLat, (minLon + maxLon) / 2) > 0))
+ {
+ mapstate->dataset[maps] = mapset->dataset[i];
+ mapstate->path[maps] = mapset->path[i];
+
+ wgs2pixel(mapstate->dataset[maps], mapstate->path[1],
+ mapstate->req_lat, mapstate->req_lon,
+ &mapstate->act_xPixel[maps],
+ &mapstate->act_yPixel[1]);
+
+ scale2zoom(mapstate->dataset[maps], mapstate->path[maps],
+ mapstate->req_scale, pixelsize, pseudoProj,
+ &mapstate->act_xZoom[maps],
+ &mapstate->act_yZoom[maps]);
+
+ maps++;
+ }
+ }
+
+ mapstate->dataset[maps] = NULL;
+ mapstate->path[maps] = NULL;
+ }
+ else
+ {
+ // No secondary maps
+ mapstate->dataset[1] = NULL;
+ mapstate->path[1] = NULL;
+ }
+ }
+
+#ifdef MAP_DEBUG
+ if (mapstate->path[1])
+ fprintf(stderr, "selected: %s, %s\n",
+ mapstate->path[0], mapstate->path[1]);
+ else
+ fprintf(stderr, "selected: %s\n", mapstate->path[0]);
+#endif
+
+ return 1;
+}
+
+int coverifpossible(MapState *state, double width, double height)
+{
+ int i;
+
+ GInt32 westLeft = state->act_xPixel[0];
+ GInt32 northLeft = state->act_yPixel[0];
+ GInt32 eastLeft =
+ GDALGetRasterXSize(state->dataset[0]) - state->act_xPixel[0];
+ GInt32 southLeft =
+ GDALGetRasterYSize(state->dataset[0]) - state->act_yPixel[0];
+
+ double imageMinX = width / 2 / state->act_xZoom[0];
+ double imageMinY = height / 2 / state->act_yZoom[0];
+
+ if ((westLeft < -2 * imageMinX || eastLeft < -2 * imageMinX) ||
+ (northLeft < -2 * imageMinY || southLeft < -2 * imageMinY))
+ {
+ return 0;
+ }
+
+ if (westLeft < imageMinX && eastLeft > imageMinX)
+ {
+ state->act_xPixel[0] += MIN(eastLeft - imageMinX,
+ imageMinX - westLeft);
+ }
+ else if (westLeft > imageMinX && eastLeft < imageMinX)
+ {
+ state->act_xPixel[0] -= MIN(westLeft - imageMinX,
+ imageMinX - eastLeft);
+ }
+
+ if (northLeft < imageMinY && southLeft > imageMinY)
+ {
+ state->act_yPixel[0] += MIN(southLeft - imageMinY,
+ imageMinY - northLeft);
+ }
+ else if (northLeft > imageMinY && southLeft < imageMinY)
+ {
+ state->act_yPixel[0] -= MIN(northLeft - imageMinY,
+ imageMinY - southLeft);
+ }
+
+ double lat;
+ double lon;
+
+ if (state->dataset[1])
+ pixel2wgs(state->dataset[0], state->path[0],
+ state->act_xPixel[0], state->act_yPixel[0],
+ &lat, &lon);
+
+ for (i = 1; state->dataset[i]; i++)
+ {
+ wgs2pixel(state->dataset[i], state->path[i], lat, lon,
+ &state->act_xPixel[i], &state->act_yPixel[i]);
+ }
+
+ state->act_rotation = 0;
+
+ return 1;
+}
diff --git a/src/lib_map/map_port.c b/src/lib_map/map_port.c
new file mode 100644
index 0000000..d70df3c
--- /dev/null
+++ b/src/lib_map/map_port.c
@@ -0,0 +1,484 @@
+//
+// Copyright (c) 2005 -- Daniel Wallner
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#include "map_priv.h"
+
+#ifdef WIN32
+static void win32_setpen(MapGC *mgc, int width, COLORREF color)
+{
+ HPEN pen = mgc->win_pen;
+ mgc->win_pen = CreatePen(PS_SOLID, width, color);
+ SelectObject(mgc->win_dc, mgc->win_pen);
+ if (pen)
+ DeleteObject(pen);
+}
+#endif
+
+void map_line(MapGC *mgc, MapSettings *settings,
+ int x1, int y1, int x2, int y2, int style)
+{
+ if (FALSE);
+#ifdef HAVE_CAIRO
+ else if (mgc->cairo_cr)
+ {
+ if (style)
+ {
+ cairo_set_source_rgb(mgc->cairo_cr, .627, .627, .627);
+ cairo_set_line_width(mgc->cairo_cr, 1);
+ }
+ else
+ {
+ cairo_set_source_rgb(mgc->cairo_cr, 0, 0, 0);
+ cairo_set_line_width(mgc->cairo_cr, 2);
+ }
+ cairo_move_to(mgc->cairo_cr, x1, y1);
+ cairo_line_to(mgc->cairo_cr, x2, y2);
+ cairo_stroke(mgc->cairo_cr);
+ }
+#endif
+#ifdef HAVE_GTK
+ else if (mgc->gtk_drawable)
+ {
+ if (style)
+ {
+ gdk_gc_set_foreground (mgc->gtk_gc, &settings->darkgrey);
+ gdk_gc_set_line_attributes (mgc->gtk_gc, 1, 0, 0, 0);
+ }
+ else
+ {
+ gdk_gc_set_foreground(mgc->gtk_gc, &settings->black);
+ gdk_gc_set_line_attributes(mgc->gtk_gc, 2, 0, 0, 0);
+ }
+ gdk_draw_line(mgc->gtk_drawable, mgc->gtk_gc, x1, y1, x2, y2);
+ }
+#endif
+#ifdef HAVE_QT
+ else if (mgc->qt_painter)
+ {
+ qt_line(mgc->qt_painter, settings,
+ x1, y1, x2, y2, style);
+ }
+#endif
+#ifdef HAVE_QUARTZ
+ else if (mgc->quartz_gc)
+ {
+ if (style)
+ {
+ CGContextSetRGBStrokeColor(mgc->quartz_gc, .627, .627, .627, 1.0);
+ CGContextSetLineWidth(mgc->quartz_gc, 1.0);
+ }
+ else
+ {
+ CGContextSetRGBStrokeColor(mgc->quartz_gc, 0, 0, 0, 1);
+ CGContextSetLineWidth(mgc->quartz_gc, 2.0);
+ }
+ CGContextBeginPath(mgc->quartz_gc);
+ CGContextMoveToPoint(mgc->quartz_gc, x1, y1);
+ CGContextAddLineToPoint(mgc->quartz_gc, x2, y2);
+ CGContextStrokePath(mgc->quartz_gc);
+ }
+#endif
+#ifdef WIN32
+ else if (mgc->win_dc)
+ {
+ if (style)
+ {
+ win32_setpen(mgc, 1, RGB(0xa0, 0xa0, 0xa0));
+ }
+ else
+ {
+ win32_setpen(mgc, 2, RGB(0x0, 0x0, 0x0));
+ }
+ MoveToEx(mgc->win_dc, x1, y1, NULL);
+ LineTo(mgc->win_dc, x2, y2);
+ }
+#endif
+}
+
+void map_pos_rectangle(MapGC *mgc, MapSettings *settings,
+ int x, int y, int width, int height)
+{
+ if (FALSE);
+#ifdef HAVE_CAIRO
+ else if (mgc->cairo_cr)
+ {
+ cairo_set_source_rgb(mgc->cairo_cr, 0, 0, 1);
+ cairo_set_line_width(mgc->cairo_cr, 4);
+ cairo_rectangle(mgc->cairo_cr, x, y, width, height);
+ cairo_stroke(mgc->cairo_cr);
+ }
+#endif
+#ifdef HAVE_GTK
+ else if (mgc->gtk_drawable)
+ {
+ gdk_gc_set_foreground(mgc->gtk_gc, &settings->blue);
+ gdk_gc_set_line_attributes(mgc->gtk_gc, 4, 0, 0, 0);
+ gdk_draw_rectangle(mgc->gtk_drawable, mgc->gtk_gc, FALSE,
+ x, y, width, height);
+ }
+#endif
+#ifdef HAVE_QT
+ else if (mgc->qt_painter)
+ {
+ qt_pos_rectangle(mgc->qt_painter, settings,
+ x, y, width, height);
+ }
+#endif
+#ifdef HAVE_QUARTZ
+ else if (mgc->quartz_gc)
+ {
+ CGContextSetRGBStrokeColor(mgc->quartz_gc, 0, 0, 1.0, 1.0);
+ CGContextSetLineWidth(mgc->quartz_gc, 4.0);
+ //gdk_gc_set_line_attributes(mgc->gtk_gc, 4, 0, 0, 0);
+ //gdk_draw_rectangle(mgc->gtk_drawable, mgc->gtk_gc, FALSE,
+ // x, y, width, height);
+ }
+#endif
+#ifdef WIN32
+ else if (mgc->win_dc)
+ {
+ POINT p[5];
+
+ p[0].x = x;
+ p[0].y = y;
+ p[1].x = x + width;
+ p[1].y = y;
+ p[2].x = x + width;
+ p[2].y = y + height;
+ p[3].x = x;
+ p[3].y = y + height;
+ p[4].x = x;
+ p[4].y = y;
+
+ win32_setpen(mgc, 4, RGB(0x0, 0x0, 0xff));
+ Polyline(mgc->win_dc, p, 5);
+ }
+#endif
+}
+
+void map_bkg_rectangle(MapGC *mgc, MapSettings *settings,
+ int x, int y, int width, int height)
+{
+ if (FALSE);
+#ifdef HAVE_CAIRO
+ else if (mgc->cairo_cr)
+ {
+ cairo_set_operator(mgc->cairo_cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba(mgc->cairo_cr, .937, .937, .937, .8);
+ cairo_rectangle(mgc->cairo_cr, x, y, width, height);
+ cairo_fill(mgc->cairo_cr);
+ cairo_set_operator(mgc->cairo_cr, CAIRO_OPERATOR_SOURCE);
+ }
+#endif
+#ifdef HAVE_GTK
+ else if (mgc->gtk_drawable)
+ {
+ gdk_gc_set_function(mgc->gtk_gc, GDK_OR);
+ gdk_gc_set_foreground(mgc->gtk_gc, &settings->textback);
+ gdk_draw_rectangle(mgc->gtk_drawable, mgc->gtk_gc, TRUE,
+ x, y, width, height);
+ gdk_gc_set_function(mgc->gtk_gc, GDK_COPY);
+ }
+#endif
+#ifdef HAVE_QT
+ else if (mgc->qt_painter)
+ {
+ qt_bkg_rectangle(mgc->qt_painter, settings,
+ x, y, width, height);
+ }
+#endif
+#ifdef HAVE_QUARTZ
+ else if (mgc->quartz_gc)
+ {
+ CGContextSetRGBFillColor(mgc->quartz_gc, .937, .937, .937, 1.);
+ //gdk_gc_set_function(mgc->gtk_gc, GDK_OR);
+ //gdk_gc_set_foreground(mgc->gtk_gc, &settings->textback);
+ //gdk_draw_rectangle(mgc->gtk_drawable, mgc->gtk_gc, TRUE,
+ // x, y, width, height);
+ //gdk_gc_set_function(mgc->gtk_gc, GDK_COPY);
+ }
+#endif
+#ifdef WIN32
+ else if (mgc->win_dc)
+ {
+ COLORREF color = RGB(0xa5, 0xa6, 0xa5);
+ HBRUSH brush = CreateSolidBrush(color);
+ HBRUSH oldBrush = SelectObject(mgc->win_dc, brush);
+ SetROP2(mgc->win_dc, R2_MERGEPEN);
+ win32_setpen(mgc, 4, color);
+ Rectangle(mgc->win_dc, x, y, x + width, y + height);
+ SetROP2(mgc->win_dc, R2_COPYPEN);
+ SelectObject(mgc->win_dc, oldBrush);
+ DeleteObject(brush);
+ }
+#endif
+}
+
+void map_text(MapGC *mgc, MapSettings *settings,
+ int x, int y, const char *text, int style)
+{
+ if (FALSE);
+#ifdef HAVE_CAIRO
+ else if (mgc->cairo_cr)
+ {
+ int xpos = x;
+ int ypos = y;
+ cairo_text_extents_t extents;
+
+ cairo_select_font_face(mgc->cairo_cr, "Sans",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_NORMAL);
+
+ if (style & 0x800)
+ {
+ if (settings->pdamode)
+ cairo_set_font_size(mgc->cairo_cr, 9);
+ else
+ cairo_set_font_size(mgc->cairo_cr, 14);
+ }
+ else
+ {
+ if (settings->pdamode)
+ cairo_set_font_size(mgc->cairo_cr, 8);
+ else
+ cairo_set_font_size(mgc->cairo_cr, 11);
+ }
+
+ cairo_text_extents(mgc->cairo_cr, text, &extents);
+
+ if ((style & 0x300) == 0x100)
+ {
+ xpos -= extents.width;
+ }
+ else if ((style & 0x300) == 0x200)
+ {
+ xpos -= extents.width / 2;
+ }
+ else if ((style & 0x300) == 0x300)
+ {
+ xpos -= extents.width / 2;
+ ypos -= extents.height / 2;
+ }
+
+ if (style & 0x400)
+ map_bkg_rectangle(mgc, settings,
+ xpos, ypos, extents.width, extents.height);
+
+ if (style & 1)
+ cairo_set_source_rgb(mgc->cairo_cr, 0, 0, 1);
+ else
+ cairo_set_source_rgb(mgc->cairo_cr, 0, 0, 0);
+
+ cairo_move_to(mgc->cairo_cr, xpos, ypos + extents.height);
+ cairo_show_text(mgc->cairo_cr, text);
+ }
+#endif
+#ifdef HAVE_GTK
+ else if (mgc->gtk_drawable)
+ {
+ int xpos = x;
+ int ypos = y;
+ int width;
+ int height;
+
+ PangoFontDescription *fd;
+ PangoLayout *layout =
+ gtk_widget_create_pango_layout(mgc->gtk_widget, text);
+
+ if (style & 0x800)
+ {
+ if (settings->pdamode)
+ fd = pango_font_description_from_string("Sans 9");
+ else
+ fd = pango_font_description_from_string("Sans 14");
+ }
+ else
+ {
+ if (settings->pdamode)
+ fd = pango_font_description_from_string("Sans 8");
+ else
+ fd = pango_font_description_from_string("Sans 11");
+ }
+
+ pango_layout_set_font_description(layout, fd);
+
+ pango_layout_get_pixel_size(layout, &width, &height);
+
+ if ((style & 0x300) == 0x100)
+ {
+ xpos -= width;
+ }
+ else if ((style & 0x300) == 0x200)
+ {
+ xpos -= width / 2;
+ }
+ else if ((style & 0x300) == 0x300)
+ {
+ xpos -= width / 2;
+ ypos -= height / 2;
+ }
+
+ if (style & 0x400)
+ map_bkg_rectangle(mgc, settings,
+ xpos, ypos, width, height);
+
+ if (style & 1)
+ gdk_draw_layout_with_colors(mgc->gtk_drawable, mgc->gtk_gc, xpos, ypos,
+ layout, &settings->blue, NULL);
+ else
+ gdk_draw_layout_with_colors(mgc->gtk_drawable, mgc->gtk_gc, xpos, ypos,
+ layout, &settings->black, NULL);
+
+ if (layout != NULL)
+ g_object_unref(G_OBJECT(layout));
+
+ pango_font_description_free(fd);
+ }
+#endif
+#ifdef HAVE_QT
+ else if (mgc->qt_painter)
+ {
+ qt_text(mgc->qt_painter, settings,
+ x, y, text, style);
+ }
+#endif
+#ifdef HAVE_QUARTZ
+ else if (mgc->quartz_gc)
+ {
+ int xpos = x;
+ int ypos = y;
+ int width;
+ int height;
+
+ CGContextSelectFont(mgc->quartz_gc, "Verdana",
+ 8, kCGEncodingMacRoman);
+
+ if (style & 0x800)
+ {
+ if (settings->pdamode)
+ CGContextSetFontSize(mgc->quartz_gc, 9);
+ else
+ CGContextSetFontSize(mgc->quartz_gc, 14);
+ }
+ else
+ {
+ if (settings->pdamode)
+ CGContextSetFontSize(mgc->quartz_gc, 8);
+ else
+ CGContextSetFontSize(mgc->quartz_gc, 11);
+ }
+
+ {
+ CGPoint oldPos = CGContextGetTextPosition(mgc->quartz_gc);
+ CGContextSetTextDrawingMode(mgc->quartz_gc, kCGTextInvisible);
+ CGContextShowText(mgc->quartz_gc, text, strlen(text));
+ CGPoint newPos = CGContextGetTextPosition(mgc->quartz_gc);
+ CGContextSetTextDrawingMode(mgc->quartz_gc, kCGTextFill);
+ CGContextSetTextPosition(mgc->quartz_gc, oldPos.x, oldPos.y);
+ width = newPos.x - oldPos.x;
+ }
+
+ if ((style & 0x300) == 0x100)
+ {
+ xpos -= width;
+ }
+ else if ((style & 0x300) == 0x200)
+ {
+ xpos -= width / 2;
+ }
+ else if ((style & 0x300) == 0x300)
+ {
+ xpos -= width / 2;
+ ypos -= height / 2;
+ }
+
+ if (style & 0x400)
+ map_bkg_rectangle(mgc, settings,
+ xpos, ypos, width, height);
+
+ if (style & 1)
+ CGContextSetRGBStrokeColor(mgc->quartz_gc, 0, 0, 1, 1);
+ else
+ CGContextSetRGBStrokeColor(mgc->quartz_gc, 0, 0, 0, 1);
+
+ CGContextSetTextPosition(mgc->quartz_gc, xpos, ypos);
+ CGContextShowText(mgc->quartz_gc, text, strlen(text));
+ }
+#endif
+#ifdef WIN32
+ else if (mgc->win_dc)
+ {
+ int xpos = x;
+ int ypos = y;
+ int fontSize;
+ HFONT oldFont;
+ HFONT font;
+ SIZE textSize;
+
+ if (style & 0x800)
+ {
+ if (settings->pdamode)
+ fontSize = 9;
+ else
+ fontSize = 14;
+ }
+ else
+ {
+ if (settings->pdamode)
+ fontSize = 8;
+ else
+ fontSize = 11;
+ }
+
+ fontSize = fontSize * 3 / 2;
+
+ font = CreateFont(fontSize, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "MSSansSerif");
+ oldFont = SelectObject(mgc->win_dc, font);
+
+ GetTextExtentPoint32(mgc->win_dc, text, strlen(text), &textSize);
+
+ if ((style & 0x300) == 0x100)
+ {
+ xpos -= textSize.cx;
+ }
+ else if ((style & 0x300) == 0x200)
+ {
+ xpos -= textSize.cx / 2;
+ }
+ else if ((style & 0x300) == 0x300)
+ {
+ xpos -= textSize.cx / 2;
+ ypos -= textSize.cy / 2;
+ }
+
+ if (style & 0x400)
+ map_bkg_rectangle(mgc, settings,
+ xpos, ypos, textSize.cx, textSize.cy);
+
+ if (style & 1)
+ SetTextColor(mgc->win_dc, RGB(0x00, 0x00, 0xff));
+ else
+ SetTextColor(mgc->win_dc, RGB(0x00, 0x00, 0x00));
+
+ SetBkMode(mgc->win_dc, TRANSPARENT);
+ TextOut(mgc->win_dc, xpos, ypos, text, strlen(text));
+ SelectObject(mgc->win_dc, oldFont);
+ DeleteObject(font);
+ }
+#endif
+}
diff --git a/src/lib_map/map_port_cpp.cpp b/src/lib_map/map_port_cpp.cpp
new file mode 100644
index 0000000..561bab2
--- /dev/null
+++ b/src/lib_map/map_port_cpp.cpp
@@ -0,0 +1,123 @@
+//
+// Copyright (c) 2005 -- Daniel Wallner
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#include "map_priv.h"
+
+#ifdef HAVE_QT
+#include <qpainter.h>
+
+void qt_line(void *painter, MapSettings *settings,
+ int x1, int y1, int x2, int y2, int style)
+{
+ QPainter *qpainter = (QPainter *)painter;
+
+ if (style)
+ {
+ qpainter->setPen(QColor(0xa0, 0xa0, 0xa0));
+ //gdk_gc_set_line_attributes (mgc->gtk_gc, 1, 0, 0, 0);
+ }
+ else
+ {
+ qpainter->setPen(QColor(0, 0, 0));
+ //gdk_gc_set_line_attributes(mgc->gtk_gc, 2, 0, 0, 0);
+ }
+ qpainter->drawLine(x1, y1, x2, y2);
+}
+
+void qt_pos_rectangle(void *painter, MapSettings *settings,
+ int x, int y, int width, int height)
+{
+ QPainter *qpainter = (QPainter *)painter;
+
+ qpainter->setPen(QColor(0x00, 0x00, 0xff));
+ //gdk_gc_set_line_attributes(mgc->gtk_gc, 4, 0, 0, 0);
+ qpainter->drawRect(x, y, width, height);
+}
+
+void qt_bkg_rectangle(void *painter, MapSettings *settings,
+ int x, int y, int width, int height)
+{
+ QPainter *qpainter = (QPainter *)painter;
+
+ //qpainter->setCompositionMode(QPainter::CompositionMode_SourceAtop));
+ qpainter->fillRect(x, y, width, height,
+ QBrush(QColor(0xa5, 0xa6, 0xa5)));
+ //qpainter->setCompositionMode(QPainter::CompositionMode_SourceOver));
+}
+
+void qt_text(void *painter, MapSettings *settings,
+ int x, int y, const char *text, int style)
+{
+ QPainter *qpainter = (QPainter *)painter;
+
+ int xpos = x;
+ int ypos = y;
+ int width;
+ int height;
+
+ QFont font;
+
+ if (style & 0x800)
+ {
+ if (settings->pdamode)
+ font.setPointSize(9);
+ else
+ font.setPointSize(14);
+ }
+ else
+ {
+ if (settings->pdamode)
+ font.setPointSize(8);
+ else
+ font.setPointSize(11);
+ }
+
+ qpainter->setFont(font);
+
+ width = strlen(text) * 10;
+ height = 20;
+
+ if ((style & 0x300) == 0x100)
+ {
+ xpos -= width;
+ }
+ else if ((style & 0x300) == 0x200)
+ {
+ xpos -= width / 2;
+ }
+ else if ((style & 0x300) == 0x300)
+ {
+ xpos -= width / 2;
+ ypos -= height / 2;
+ }
+
+ if (style & 0x400)
+ qt_bkg_rectangle(painter, settings,
+ xpos, ypos, width, height);
+
+ ypos += 15;
+
+ if (style & 1)
+ qpainter->setPen(QColor(0x00, 0x00, 0xff));
+ else
+ qpainter->setPen(QColor(0x00, 0x00, 0x00));
+
+ qpainter->drawText(xpos, ypos, text);
+}
+
+#endif
diff --git a/src/lib_map/map_priv.h b/src/lib_map/map_priv.h
new file mode 100644
index 0000000..3e8a1d1
--- /dev/null
+++ b/src/lib_map/map_priv.h
@@ -0,0 +1,92 @@
+//
+// Copyright (c) 2005 -- Daniel Wallner
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#include "map.h"
+
+/* defines offset and color of the shadows */
+#define SHADOWOFFSET 7
+
+/* #define SHADOWGREY 0xD000 */
+#define SHADOWGREY 0xA000
+
+#define PIXELFACT 2817.947378
+
+/* WGS84 parameters */
+
+#define EQUATOR_CIRCUM 40075017.
+#define POLE_CIRCUM 40007863.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Private functions
+
+void calcxytopos2(int posx, int posy, double *mylat, double *mylon,
+ double zero_lat, double zero_long, double mapscale);
+void calcxy2(double *posx, double *posy, double lat, double lon,
+ double zero_lat, double zero_long, double mapscale);
+
+int mapcovers(GDALDatasetH dataset,
+ double xZoom, double yZoom,
+ double xPixel, double yPixel,
+ double width, double height);
+
+int gdal2argb(GDALDatasetH dataset, GUInt32 *imageData,
+ GInt32 imageWidth, GInt32 imageHeight,
+ GInt32 mapWest, GInt32 mapNorth,
+ GInt32 mapWidth, GInt32 mapHeight,
+ int alphaPos, int redPos, int greenPos, int bluePos, int mode);
+
+// Portable drawing functions
+
+void map_line(MapGC *mgc, MapSettings *settings,
+ int x1, int y1, int x2, int y2, int style);
+
+void map_pos_rectangle(MapGC *mgc, MapSettings *settings,
+ int x, int y, int width, int height);
+
+void map_bkg_rectangle(MapGC *mgc, MapSettings *settings,
+ int x, int y, int width, int height);
+
+void map_text(MapGC *mgc, MapSettings *settings,
+ int x, int y, const char *text, int style);
+
+#ifdef HAVE_QT
+void qt_line(void *painter, MapSettings *settings,
+ int x1, int y1, int x2, int y2, int style);
+
+void qt_pos_rectangle(void *painter, MapSettings *settings,
+ int x, int y, int width, int height);
+
+void qt_bkg_rectangle(void *painter, MapSettings *settings,
+ int x, int y, int width, int height);
+
+void qt_text(void *painter, MapSettings *settings,
+ int x, int y, const char *text, int style);
+
+int qt_drawmap(GDALDatasetH dataset, void *painter,
+ GInt32 imageWidth, GInt32 imageHeight,
+ GInt32 mapWest, GInt32 mapNorth,
+ GInt32 mapWidth, GInt32 mapHeight,
+ GInt32 xPos, GInt32 yPos, int mode);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/lib_map/map_render.c b/src/lib_map/map_render.c
new file mode 100644
index 0000000..31c3c24
--- /dev/null
+++ b/src/lib_map/map_render.c
@@ -0,0 +1,1208 @@
+//
+// Copyright (c) 2005 -- Daniel Wallner
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#include "map_priv.h"
+
+int mapinit(MapSettings *settings)
+{
+ GDALAllRegister();
+
+ settings->gblink = 0;
+ settings->blink = 0;
+ settings->milesflag = FALSE;
+ settings->metricflag = TRUE;
+ settings->nauticflag = FALSE;
+ settings->pdamode = FALSE;
+ settings->drawgrid = FALSE;
+ settings->zoomscale = TRUE;
+ settings->havepos = TRUE;
+ settings->posmode = FALSE;
+ settings->shadow = TRUE;
+ settings->markwaypoint = TRUE;
+
+#ifdef HAVE_GTK
+ GdkColormap *cmap;
+
+ gdk_color_parse("Red", &settings->red);
+ gdk_color_parse("Black", &settings->black);
+ gdk_color_parse("White", &settings->white);
+ gdk_color_parse("Blue", &settings->blue);
+ gdk_color_parse("#a00000", &settings->nightcolor);
+ gdk_color_parse("#8b958b", &settings->lcd);
+ gdk_color_parse("#737d6a", &settings->lcd2);
+ gdk_color_parse("Yellow", &settings->yellow);
+ gdk_color_parse("#00b000", &settings->green);
+ gdk_color_parse("Green", &settings->green2);
+ gdk_color_parse("#d5d6d5", &settings->mygray);
+ gdk_color_parse("#a5a6a5", &settings->textback);
+ gdk_color_parse("#4076cf", &settings->textbacknew);
+ gdk_color_parse("#c0c0c0", &settings->grey);
+ gdk_color_parse("#f06000", &settings->orange);
+ gdk_color_parse("#ff8000", &settings->orange2);
+ settings->darkgrey.pixel = 0;
+ settings->darkgrey.red = SHADOWGREY;
+ settings->darkgrey.green = SHADOWGREY;
+ settings->darkgrey.blue = SHADOWGREY;
+
+ cmap = gdk_colormap_get_system();
+ gdk_color_alloc(cmap, &settings->red);
+ gdk_color_alloc(cmap, &settings->black);
+ gdk_color_alloc(cmap, &settings->blue);
+ gdk_color_alloc(cmap, &settings->nightcolor);
+ gdk_color_alloc(cmap, &settings->lcd);
+ gdk_color_alloc(cmap, &settings->lcd2);
+ gdk_color_alloc(cmap, &settings->green);
+ gdk_color_alloc(cmap, &settings->green2);
+ gdk_color_alloc(cmap, &settings->white);
+ gdk_color_alloc(cmap, &settings->mygray);
+ gdk_color_alloc(cmap, &settings->yellow);
+ gdk_color_alloc(cmap, &settings->darkgrey);
+ gdk_color_alloc(cmap, &settings->grey);
+ gdk_color_alloc(cmap, &settings->textback);
+ gdk_color_alloc(cmap, &settings->textbacknew);
+ gdk_color_alloc(cmap, &settings->orange2);
+ gdk_color_alloc(cmap, &settings->orange);
+#endif
+
+ return 1;
+}
+
+int mapcovers(GDALDatasetH dataset,
+ double xZoom, double yZoom,
+ double xPixel, double yPixel,
+ double width, double height)
+{
+ GInt32 mapWidth = GDALGetRasterXSize(dataset);
+ GInt32 mapHeight = GDALGetRasterYSize(dataset);
+
+ if ((mapWidth - xPixel) * xZoom >= width / 2 &&
+ (mapHeight - yPixel) * yZoom >= height / 2 &&
+ xPixel * xZoom >= width / 2 &&
+ yPixel * yZoom >= height / 2)
+ {
+#ifdef MAP_DEBUG
+ fprintf(stderr, "Map covers screen\n");
+#endif
+ return 1;
+ }
+ else
+ {
+#ifdef MAP_DEBUG
+ fprintf(stderr, "Map doesn't cover screen\n");
+#endif
+ return 0;
+ }
+}
+
+int gdal2argb(GDALDatasetH dataset, GUInt32 *imageData,
+ GInt32 imageWidth, GInt32 imageHeight,
+ GInt32 mapWest, GInt32 mapNorth,
+ GInt32 mapWidth, GInt32 mapHeight,
+ int alphaPos, int redPos, int greenPos, int bluePos, int mode)
+{
+ if (GDALGetRasterCount(dataset) == 1)
+ {
+ // Single band image
+
+ GDALRasterBandH band = GDALGetRasterBand(dataset, 1);
+
+#ifdef MAP_DEBUG
+ int blockXSize, blockYSize;
+
+ GDALGetBlockSize(band, &blockXSize, &blockYSize);
+ fprintf(stderr, "blocksize: %d x %d type: %s, color interp: %s\n",
+ blockXSize, blockYSize,
+ GDALGetDataTypeName(GDALGetRasterDataType(band)),
+ GDALGetColorInterpretationName(
+ GDALGetRasterColorInterpretation(band)));
+#endif
+
+ switch (GDALGetRasterColorInterpretation(band))
+ {
+ case GCI_GrayIndex:
+ {
+ GUInt32 palette[256];
+
+ GInt32 i;
+ for (i = 0; i < 256; i++)
+ {
+ palette[i] =
+ (i << 24) |
+ (i << 16) |
+ (i << 8) |
+ i;
+ }
+
+ GByte *fileData = (GByte *)CPLMalloc(imageWidth * imageHeight);
+
+ GDALRasterIO(band, GF_Read,
+ mapWest, mapNorth, mapWidth, mapHeight,
+ fileData, imageWidth, imageHeight, GDT_Byte, 0, 0);
+
+ for (i = 0; i < imageWidth * imageHeight; i++)
+ {
+ imageData[i] = palette[fileData[i]];
+ }
+
+ CPLFree(fileData);
+ }
+ break;
+
+ case GCI_PaletteIndex:
+ {
+ GDALColorTableH hColorTable = GDALGetRasterColorTable(band);
+
+ GUInt32 *palette =
+ (GUInt32 *)CPLMalloc(GDALGetColorEntryCount(hColorTable) * 4);
+
+ GInt32 i;
+ for (i = 0; i < GDALGetColorEntryCount(hColorTable); i++)
+ {
+ GDALColorEntry entry;
+
+ GDALGetColorEntryAsRGB(hColorTable, i, &entry);
+ palette[i] =
+ (entry.c4 << (8 * alphaPos)) |
+ (entry.c3 << (8 * redPos)) |
+ (entry.c2 << (8 * greenPos)) |
+ (entry.c1 << (8 * bluePos));
+ }
+
+ GByte *fileData = (GByte *)CPLMalloc(imageWidth * imageHeight);
+
+ GDALRasterIO(band, GF_Read,
+ mapWest, mapNorth, mapWidth, mapHeight,
+ fileData, imageWidth, imageHeight, GDT_Byte, 0, 0);
+
+ for (i = 0; i < imageWidth * imageHeight ; i++)
+ {
+ imageData[i] = palette[fileData[i]];
+ }
+
+ CPLFree(palette);
+ CPLFree(fileData);
+ }
+ break;
+
+ default:
+ fprintf(stderr, "Unsupported single band type");
+ exit(1);
+ }
+ }
+ else
+ {
+ // Multi band image
+ GInt32 i;
+#ifdef SINGLE_RASTERIO
+ int bandMap[4];
+
+ for (i = 0; i < imageWidth * imageHeight; i++)
+ {
+ imageData[i] = 0xffffffff;
+ }
+
+ bandMap[3] = bandMap[2] = bandMap[1] = bandMap[0] = 0;
+
+ for (i = 1; i <= GDALGetRasterCount(dataset); i++)
+ {
+ GDALRasterBandH band = GDALGetRasterBand(dataset, i);
+
+#ifdef MAP_DEBUG
+ int blockXSize, blockYSize;
+
+ GDALGetBlockSize(band, &blockXSize, &blockYSize);
+ fprintf(stderr, "blocksize: %d x %d type: %s, color interp: %s\n",
+ blockXSize, blockYSize,
+ GDALGetDataTypeName(GDALGetRasterDataType(band)),
+ GDALGetColorInterpretationName(
+ GDALGetRasterColorInterpretation(band)));
+#endif
+
+ switch (GDALGetRasterColorInterpretation(band))
+ {
+ case GCI_AlphaBand:
+ {
+ bandMap[3] = i;
+ }
+ break;
+
+ case GCI_RedBand:
+ {
+ bandMap[0] = i;
+ }
+ break;
+
+ case GCI_GreenBand:
+ {
+ bandMap[1] = i;
+ }
+ break;
+
+ case GCI_BlueBand:
+ {
+ bandMap[2] = i;
+ }
+ break;
+
+ default:
+ fprintf(stderr, "Skipping unsupported multi band type: %s\n",
+ GDALGetColorInterpretationName(
+ GDALGetRasterColorInterpretation(band)));
+ }
+ }
+
+#ifdef MAP_DEBUG
+ fprintf(stderr, "bandmap: %d,%d,%d,%d\n",
+ bandMap[0], bandMap[1], bandMap[2], bandMap[3]);
+#endif
+
+ if (!bandMap[0] || !bandMap[1] || !bandMap[2])
+ {
+ fprintf(stderr, "Not an RGB image\n");
+ return 0;
+ }
+
+ if (bandMap[3])
+ {
+ // Image has alpha channel
+
+ GByte *fileData = (GByte *)CPLMalloc(imageWidth * imageHeight * 4);
+
+ GDALDatasetRasterIO(dataset, GF_Read,
+ mapWest, mapNorth, mapWidth, mapHeight,
+ fileData, imageWidth, imageHeight,
+ GDT_Byte, 4, bandMap, 0, 0, 0);
+
+ int bi = imageWidth * imageHeight;
+
+ for (i = 0; i < bi; i++)
+ {
+ ((GByte *)imageData)[i * 4 + redPos] = fileData[i];
+ ((GByte *)imageData)[i * 4 + greenPos] = fileData[i + bi];
+ ((GByte *)imageData)[i * 4 + bluePos] = fileData[i + 2 * bi];
+ ((GByte *)imageData)[i * 4 + alphaPos] = fileData[i + 3 * bi];
+ }
+ }
+ else
+ {
+ GByte *fileData = (GByte *)CPLMalloc(imageWidth * imageHeight * 3);
+
+ GDALDatasetRasterIO(dataset, GF_Read,
+ mapWest, mapNorth, mapWidth, mapHeight,
+ fileData, imageWidth, imageHeight,
+ GDT_Byte, 3, bandMap, 0, 0, 0);
+
+ int bi = imageWidth * imageHeight;
+
+ for (i = 0; i < bi; i++)
+ {
+ ((GByte *)imageData)[i * 3 + redPos] = fileData[i];
+ ((GByte *)imageData)[i * 3 + greenPos] = fileData[i + bi];
+ ((GByte *)imageData)[i * 3 + bluePos] = fileData[i + 2 * bi];
+ }
+
+ CPLFree(fileData);
+ }
+#else
+ for (i = 0; i < imageWidth * imageHeight; i++)
+ {
+ imageData[i] = 0xffffffff;
+ }
+
+ for (i = 1; i <= GDALGetRasterCount(dataset); i++)
+ {
+ GDALRasterBandH band;
+ band = GDALGetRasterBand(dataset, i);
+
+#ifdef MAP_DEBUG
+ int blockXSize, blockYSize;
+
+ GDALGetBlockSize(band, &blockXSize, &blockYSize);
+ fprintf(stderr, "blocksize: %d x %d type: %s, color interp: %s\n",
+ blockXSize, blockYSize,
+ GDALGetDataTypeName(GDALGetRasterDataType(band)),
+ GDALGetColorInterpretationName(
+ GDALGetRasterColorInterpretation(band)));
+#endif
+
+ switch (GDALGetRasterColorInterpretation(band))
+ {
+ case GCI_RedBand:
+ {
+ GByte *start = (GByte *)imageData;
+ start += 2 - redPos;
+ GDALRasterIO(band, GF_Read,
+ mapWest, mapNorth, mapWidth, mapHeight,
+ start, imageWidth, imageHeight, GDT_Byte, 4, 0);
+ }
+ break;
+
+ case GCI_GreenBand:
+ {
+ GByte *start = (GByte *)imageData;
+ start += 2 - greenPos;
+ GDALRasterIO(band, GF_Read,
+ mapWest, mapNorth, mapWidth, mapHeight,
+ start, imageWidth, imageHeight, GDT_Byte, 4, 0);
+ }
+ break;
+
+ case GCI_BlueBand:
+ {
+ GByte *start = (GByte *)imageData;
+ start += 2 - bluePos;
+ GDALRasterIO(band, GF_Read,
+ mapWest, mapNorth, mapWidth, mapHeight,
+ start, imageWidth, imageHeight, GDT_Byte, 4, 0);
+ }
+ break;
+
+ case GCI_AlphaBand:
+ {
+ GByte *start = (GByte *)imageData;
+ start += 3;
+ GDALRasterIO(band, GF_Read,
+ mapWest, mapNorth, mapWidth, mapHeight,
+ start, imageWidth, imageHeight, GDT_Byte, 4, 0);
+ }
+ break;
+
+ default:
+ fprintf(stderr, "Skipping unsupported multi band type: %s\n",
+ GDALGetColorInterpretationName(
+ GDALGetRasterColorInterpretation(band)));
+ }
+ }
+#endif
+ }
+
+ if (mode)
+ {
+ GInt32 i;
+
+ for (i = 0; i < imageWidth * imageHeight * 4; i++)
+ {
+ ((GByte *)imageData)[i] >>= 1;
+ }
+ }
+
+ return 1;
+}
+
+int drawmap(MapState *state, MapGC *mgc,
+ double viewWidth, double viewHeight, int mode)
+{
+ int i = 0;
+
+ while (state->dataset[i])
+ i++;
+
+ if (mapcovers(state->dataset[0],
+ state->act_xZoom[0], state->act_yZoom[0],
+ state->act_xPixel[0], state->act_yPixel[0],
+ viewWidth, viewHeight) && !mode)
+ i = 1;
+
+ for (i--; i >= 0; i--)
+ {
+ double xZoom = state->act_xZoom[i];
+ double yZoom = state->act_yZoom[i];
+
+ // Image width
+ GInt32 imageWidth = viewWidth;
+ GInt32 imageHeight = viewHeight;
+
+#ifdef HAVE_CAIRO
+ // Only cairo supports rotation at the moment
+ if (mgc->cairo_cr && state->req_rotation != 0.)
+ {
+ // This is not correct, should be calculated from rotation
+ imageWidth = viewWidth * 2.0;
+ imageHeight = viewHeight * 2.0;
+ }
+#endif
+
+ // Zoom
+ GInt32 zoomedWidth = imageWidth / xZoom + 2;
+ GInt32 zoomedHeight = imageHeight / yZoom + 2;
+
+ GInt32 actWest = state->act_xPixel[i] - zoomedWidth / 2;
+ GInt32 actEast = state->act_xPixel[i] + zoomedWidth / 2;
+ GInt32 actNorth = state->act_yPixel[i] - zoomedHeight / 2;
+ GInt32 actSouth = state->act_yPixel[i] + zoomedHeight / 2;
+
+ // Correct for image size
+ GInt32 limWest = MIN(MAX(actWest, 0),
+ GDALGetRasterXSize(state->dataset[i]));
+ GInt32 limNorth = MIN(MAX(actNorth, 0),
+ GDALGetRasterYSize(state->dataset[i]));
+ GInt32 limEast = MIN(MAX(actEast, 0),
+ GDALGetRasterXSize(state->dataset[i]));
+ GInt32 limSouth = MIN(MAX(actSouth, 0),
+ GDALGetRasterYSize(state->dataset[i]));
+
+ GInt32 fileWidth = limEast - limWest;
+ GInt32 fileHeight = limSouth - limNorth;
+
+ imageWidth = fileWidth * xZoom;
+ imageHeight = fileHeight * yZoom;
+
+ // Center
+ GInt32 xLimCenter =
+ - (actWest - limWest + (actEast - actWest) / 2) * xZoom;
+ GInt32 yLimCenter =
+ - (actNorth - limNorth + (actSouth - actNorth) / 2) * yZoom;
+
+ // Position
+ GInt32 xLimPos = -(actWest - limWest) * xZoom;
+ GInt32 yLimPos = -(actNorth - limNorth) * yZoom;
+
+#ifdef MAP_DEBUG
+ fprintf(stderr,
+ "cairo size: %d x %d\n"
+ "center: %d;%d\n"
+ "limCenter: %d;%d\n"
+ "limPos: %d;%d\n"
+ "zoomed: %d x %d\n"
+ "actWest: %d actEast: %d\n"
+ "actNorth: %d actSouth: %d\n"
+ "limWest: %d limEast: %d\n"
+ "limNorth: %d limSouth: %d\n"
+ "file size: %d x %d\n",
+ imageWidth, imageHeight,
+ state->act_xPixel[i], state->act_yPixel[i],
+ xLimCenter, yLimCenter,
+ xLimPos, yLimPos,
+ zoomedWidth, zoomedHeight,
+ actWest, actEast,
+ actNorth, actSouth,
+ limWest, limEast,
+ limNorth, limSouth,
+ fileWidth, fileHeight);
+#endif
+
+ if (!(imageWidth && imageHeight));
+#ifdef HAVE_CAIRO
+ else if (mgc->cairo_cr)
+ {
+ cairo_t *cr = mgc->cairo_cr;
+ cairo_surface_t *image;
+
+ GUInt32 *imageData = (GUInt32 *)
+ CPLMalloc(imageWidth * imageHeight * sizeof(GUInt32));
+
+ image =
+ cairo_image_surface_create_for_data((unsigned char*)imageData,
+ CAIRO_FORMAT_ARGB32,
+ imageWidth,
+ imageHeight,
+ imageWidth * sizeof(GUInt32));
+
+ // Fill image
+ gdal2argb(state->dataset[i], imageData, imageWidth, imageHeight,
+ limWest, limNorth, fileWidth, fileHeight, 3, 0, 1, 2, mode);
+
+ // Draw image
+ cairo_save(cr);
+
+ cairo_translate(cr, 0.5 * viewWidth, 0.5 * viewHeight);
+ cairo_rotate(cr, state->req_rotation * M_PI / 180);
+
+ cairo_translate(cr, xLimCenter, yLimCenter);
+
+ cairo_set_source_surface(cr, image, 0, 0);
+ cairo_paint(cr);
+ cairo_surface_destroy(image);
+
+ cairo_restore(cr);
+
+ // Clean up
+ CPLFree(imageData);
+ }
+#endif
+#ifdef HAVE_GTK
+ else if (mgc->gtk_drawable)
+ {
+ GUInt32 *imageData = (GUInt32 *) CPLMalloc(imageWidth *
+ imageHeight *
+ sizeof(GUInt32));
+
+ GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data((guchar*)imageData,
+ GDK_COLORSPACE_RGB,
+ TRUE, 8,
+ imageWidth, imageHeight,
+ imageWidth * 4,
+ NULL, NULL);
+
+ // Fill image
+ gdal2argb(state->dataset[i], imageData, imageWidth, imageHeight,
+ limWest, limNorth, fileWidth, fileHeight,
+ 3, 2, 1, 0, mode);
+
+ // Draw image
+ gdk_draw_pixbuf(mgc->gtk_drawable, NULL, pixbuf, 0, 0,
+ xLimPos, yLimPos, -1, -1,
+ GDK_RGB_DITHER_NORMAL, 0, 0);
+
+ // Clean up
+ g_object_unref(pixbuf);
+
+ CPLFree(imageData);
+ }
+#endif
+#ifdef HAVE_QT
+ else if (mgc->qt_painter)
+ {
+ qt_drawmap(state->dataset[i], mgc->qt_painter, imageWidth, imageHeight,
+ limWest, limNorth, fileWidth, fileHeight, xLimPos, yLimPos, mode);
+ }
+#endif
+#ifdef HAVE_QUARTZ
+ else if (mgc->quartz_gc)
+ {
+ GUInt32 *imageData = (GUInt32 *)
+ CPLMalloc(imageWidth * imageHeight * sizeof(GUInt32));
+
+ // Fill image
+ gdal2argb(state->dataset[i], imageData, imageWidth, imageHeight,
+ limWest, limNorth, fileWidth, fileHeight, 3, 0, 1, 2, mode);
+
+ CGContextSaveGState(mgc->quartz_gc);
+
+ // Draw image
+ {
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGDataProviderRef provider =
+ CGDataProviderCreateWithData(NULL, imageData,
+ imageWidth * imageHeight * 4, NULL);
+
+ CGImageRef image =
+ CGImageCreate(
+ imageWidth,
+ imageHeight,
+ 8,
+ 32,
+ imageWidth * 4,
+ colorSpace,
+ kCGImageAlphaPremultipliedFirst,
+ provider,
+ NULL,
+ 0,
+ kCGRenderingIntentDefault);
+
+ CGRect bounds = CGRectMake(xLimPos, yLimPos, imageWidth, imageHeight);
+
+ HIViewDrawCGImage(mgc->quartz_gc, &bounds, image);
+
+ CGImageRelease(image);
+
+ CGDataProviderRelease(provider);
+ CGColorSpaceRelease(colorSpace);
+ }
+
+ CGContextRestoreGState(mgc->quartz_gc);
+
+ // Clean up
+ CPLFree(imageData);
+ }
+#endif
+#ifdef WIN32
+ else if (mgc->win_dc)
+ {
+ GUInt32 *imageData;
+ BITMAPINFO bmi;
+ HBITMAP dib;
+ HDC dib_dc = CreateCompatibleDC(NULL);
+
+ memset(&bmi, 0, sizeof(BITMAPINFO));
+
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = imageWidth;
+ bmi.bmiHeader.biHeight = imageHeight;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biClrUsed = 0;
+
+ dib = CreateDIBSection(dib_dc, &bmi, DIB_RGB_COLORS,
+ (void **)&imageData, NULL, 0);
+ SelectObject(dib_dc, dib);
+
+ // Fill image
+ gdal2argb(state->dataset[i], imageData, imageWidth, imageHeight,
+ limWest, limNorth, fileWidth, fileHeight,
+ 3, 0, 1, 2, mode);
+
+ // Draw image
+ StretchBlt(mgc->win_dc, xLimPos, yLimPos, imageWidth, imageHeight,
+ dib_dc, 0, imageHeight, imageWidth, -imageHeight, SRCCOPY);
+
+ // Clean up
+ DeleteDC(dib_dc);
+ DeleteObject(dib);
+ }
+#endif
+ }
+
+ // Update state
+
+ state->act_rotation = 0;
+ state->act_width = viewWidth;
+ state->act_height = viewHeight;
+
+#ifdef HAVE_CAIRO
+ // Only cairo supports rotation at the moment
+ if (mgc->cairo_cr && state->req_rotation != 0.)
+ {
+ state->act_rotation = state->req_rotation;
+ }
+#endif
+
+ return 1;
+}
+
+
+
+
+
+#ifdef bajshora
+
+#ifdef HAVE_CAIRO
+int gdal2cairo(MapState *state, cairo_t *cr,
+ double crWidth, double crHeight, int mode)
+{
+ int i = 0;
+
+ while (state->dataset[i])
+ i++;
+
+ if (mapcovers(state->dataset[0],
+ state->act_xZoom[0], state->act_yZoom[0],
+ state->act_xPixel[0], state->act_yPixel[0],
+ crWidth, crHeight) && !mode)
+ i = 1;
+
+ for (i--; i >= 0; i--)
+ {
+ double xZoom = state->act_xZoom[i];
+ double yZoom = state->act_yZoom[i];
+
+ // Image width
+ GInt32 imageWidth = crWidth;
+ GInt32 imageHeight = crHeight;
+
+ if (state->req_rotation != 0.)
+ {
+ // This is not correct, should be calculated from rotation
+ imageWidth = crWidth * 2.0;
+ imageHeight = crHeight * 2.0;
+ }
+
+ // Zoom
+ GInt32 zoomedWidth = imageWidth / xZoom + 2;
+ GInt32 zoomedHeight = imageHeight / yZoom + 2;
+
+ GInt32 actWest = state->act_xPixel[i] - zoomedWidth / 2;
+ GInt32 actEast = state->act_xPixel[i] + zoomedWidth / 2;
+ GInt32 actNorth = state->act_yPixel[i] - zoomedHeight / 2;
+ GInt32 actSouth = state->act_yPixel[i] + zoomedHeight / 2;
+
+ // Correct for image size
+ GInt32 limWest = MIN(MAX(actWest, 0),
+ GDALGetRasterXSize(state->dataset[i]));
+ GInt32 limNorth = MIN(MAX(actNorth, 0),
+ GDALGetRasterYSize(state->dataset[i]));
+ GInt32 limEast = MIN(MAX(actEast, 0),
+ GDALGetRasterXSize(state->dataset[i]));
+ GInt32 limSouth = MIN(MAX(actSouth, 0),
+ GDALGetRasterYSize(state->dataset[i]));
+
+ GInt32 fileWidth = limEast - limWest;
+ GInt32 fileHeight = limSouth - limNorth;
+
+ imageWidth = fileWidth * xZoom;
+ imageHeight = fileHeight * yZoom;
+
+ // Center
+ GInt32 xLimCenter =
+ - (actWest - limWest + (actEast - actWest) / 2) * xZoom;
+ GInt32 yLimCenter =
+ - (actNorth - limNorth + (actSouth - actNorth) / 2) * yZoom;
+
+#ifdef MAP_DEBUG
+ fprintf(stderr,
+ "cairo size: %d x %d\n"
+ "center: %d;%d\n"
+ "limCenter: %d;%d\n"
+ "zoomed: %d x %d\n"
+ "actWest: %d actEast: %d\n"
+ "actNorth: %d actSouth: %d\n"
+ "limWest: %d limEast: %d\n"
+ "limNorth: %d limSouth: %d\n"
+ "file size: %d x %d\n",
+ imageWidth, imageHeight,
+ state->act_xPixel[i], state->act_yPixel[i],
+ xLimCenter, yLimCenter,
+ zoomedWidth, zoomedHeight,
+ actWest, actEast,
+ actNorth, actSouth,
+ limWest, limEast,
+ limNorth, limSouth,
+ fileWidth, fileHeight);
+#endif
+
+ cairo_surface_t *image;
+
+ GUInt32 *imageData = (GUInt32 *)
+ CPLMalloc(imageWidth * imageHeight * sizeof(GUInt32));
+
+ image =
+ cairo_image_surface_create_for_data((unsigned char*)imageData,
+ CAIRO_FORMAT_ARGB32,
+ imageWidth,
+ imageHeight,
+ imageWidth * sizeof(GUInt32));
+
+ // Fill image
+ gdal2argb(state->dataset[i], imageData, imageWidth, imageHeight,
+ limWest, limNorth, fileWidth, fileHeight, 3, 0, 1, 2, mode);
+
+ // Draw image
+ cairo_save(cr);
+
+ cairo_translate(cr, 0.5 * crWidth, 0.5 * crHeight);
+ cairo_rotate(cr, state->req_rotation * M_PI / 180);
+
+ cairo_translate(cr, xLimCenter, yLimCenter);
+
+ cairo_set_source_surface(cr, image, 0, 0);
+ cairo_paint(cr);
+ cairo_surface_destroy(image);
+
+ cairo_restore(cr);
+
+ // Clean up
+ CPLFree(imageData);
+ }
+
+ // Update state
+ state->act_rotation = state->req_rotation;
+ state->act_width = crWidth;
+ state->act_height = crHeight;
+
+ return 1;
+}
+#endif
+
+#ifdef HAVE_GTK
+int gdal2gtk(MapState *state, GdkDrawable *drawable,
+ gint gtkWidth, gint gtkHeight, int mode)
+{
+ int i = 0;
+
+ while (state->dataset[i])
+ i++;
+
+ if (mapcovers(state->dataset[0],
+ state->act_xZoom[0], state->act_yZoom[0],
+ state->act_xPixel[0], state->act_yPixel[0],
+ gtkWidth, gtkHeight) && !mode)
+ i = 1;
+
+ for (i--; i >= 0; i--)
+ {
+ double xZoom = state->act_xZoom[i];
+ double yZoom = state->act_yZoom[i];
+
+ // Image width
+ GInt32 imageWidth = gtkWidth;
+ GInt32 imageHeight = gtkHeight;
+
+#ifdef MAP_DEBUG
+ fprintf(stderr,"zoom: %lf;%lf x y %d;%d\n",
+ xZoom, yZoom, state->act_xPixel[i], state->act_yPixel[i]);
+#endif
+
+ // Zoom
+ GInt32 zoomedWidth = imageWidth / xZoom + 2;
+ GInt32 zoomedHeight = imageHeight / yZoom + 2;
+
+ GInt32 actWest = state->act_xPixel[i] - zoomedWidth / 2;
+ GInt32 actEast = state->act_xPixel[i] + zoomedWidth / 2;
+ GInt32 actNorth = state->act_yPixel[i] - zoomedHeight / 2;
+ GInt32 actSouth = state->act_yPixel[i] + zoomedHeight / 2;
+
+ // Correct for image size
+ GInt32 limWest = MIN(MAX(actWest, 0),
+ GDALGetRasterXSize(state->dataset[i]));
+ GInt32 limNorth = MIN(MAX(actNorth, 0),
+ GDALGetRasterYSize(state->dataset[i]));
+ GInt32 limEast = MIN(MAX(actEast, 0),
+ GDALGetRasterXSize(state->dataset[i]));
+ GInt32 limSouth = MIN(MAX(actSouth, 0),
+ GDALGetRasterYSize(state->dataset[i]));
+
+ GInt32 fileWidth = limEast - limWest;
+ GInt32 fileHeight = limSouth - limNorth;
+
+ imageWidth = fileWidth * xZoom;
+ imageHeight = fileHeight * yZoom;
+
+ // Position
+ GInt32 xLimPos = -(actWest - limWest) * xZoom;
+ GInt32 yLimPos = -(actNorth - limNorth) * yZoom;
+
+#ifdef MAP_DEBUG
+ fprintf(stderr,
+ "gtk size: %d x %d\n"
+ "center: %d;%d\n"
+ "limPos: %d;%d\n"
+ "zoomed: %d x %d\n"
+ "actWest: %d actEast: %d\n"
+ "actNorth: %d actSouth: %d\n"
+ "limWest: %d limEast: %d\n"
+ "limNorth: %d limSouth: %d\n"
+ "file size: %d x %d\n",
+ imageWidth, imageHeight,
+ state->act_xPixel[i], state->act_yPixel[i],
+ xLimPos, yLimPos,
+ zoomedWidth, zoomedHeight,
+ actWest, actEast,
+ actNorth, actSouth,
+ limWest, limEast,
+ limNorth, limSouth,
+ fileWidth, fileHeight);
+#endif
+
+ if (imageWidth && imageHeight)
+ {
+ GUInt32 *imageData = (GUInt32 *) CPLMalloc(imageWidth *
+ imageHeight *
+ sizeof(GUInt32));
+
+ GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data((guchar*)imageData,
+ GDK_COLORSPACE_RGB,
+ TRUE, 8,
+ imageWidth, imageHeight,
+ imageWidth * 4,
+ NULL, NULL);
+
+ // Fill image
+ gdal2argb(state->dataset[i], imageData, imageWidth, imageHeight,
+ limWest, limNorth, fileWidth, fileHeight,
+ 3, 2, 1, 0, mode);
+
+ // Draw image
+ gdk_draw_pixbuf(drawable, NULL, pixbuf, 0, 0,
+ xLimPos, yLimPos, -1, -1,
+ GDK_RGB_DITHER_NORMAL, 0, 0);
+
+ // Clean up
+ g_object_unref(pixbuf);
+
+ CPLFree(imageData);
+ }
+ }
+
+ // Update state
+ state->act_rotation = 0.;
+ state->act_width = gtkWidth;
+ state->act_height = gtkHeight;
+
+ return 1;
+}
+#endif
+
+#ifdef HAVE_QUARTZ
+int gdal2quartz(MapState *state, CGContextRef gc,
+ double qWidth, double qHeight, int mode)
+{
+ int i = 0;
+
+ while (state->dataset[i])
+ i++;
+
+ if (mapcovers(state->dataset[0],
+ state->act_xZoom[0], state->act_yZoom[0],
+ state->act_xPixel[0], state->act_yPixel[0],
+ qWidth, qHeight) && !mode)
+ i = 1;
+
+ for (i--; i >= 0; i--)
+ {
+ double xZoom = state->act_xZoom[i];
+ double yZoom = state->act_yZoom[i];
+
+ // Image width
+ GInt32 imageWidth = qWidth;
+ GInt32 imageHeight = qHeight;
+
+ if (state->req_rotation != 0.)
+ {
+ // This is not correct, should be calculated from rotation
+ imageWidth = qWidth * 2.0;
+ imageHeight = qHeight * 2.0;
+ }
+
+ // Zoom
+ GInt32 zoomedWidth = imageWidth / xZoom + 2;
+ GInt32 zoomedHeight = imageHeight / yZoom + 2;
+
+ GInt32 actWest = state->act_xPixel[i] - zoomedWidth / 2;
+ GInt32 actEast = state->act_xPixel[i] + zoomedWidth / 2;
+ GInt32 actNorth = state->act_yPixel[i] - zoomedHeight / 2;
+ GInt32 actSouth = state->act_yPixel[i] + zoomedHeight / 2;
+
+ // Correct for image size
+ GInt32 limWest = MIN(MAX(actWest, 0),
+ GDALGetRasterXSize(state->dataset[i]));
+ GInt32 limNorth = MIN(MAX(actNorth, 0),
+ GDALGetRasterYSize(state->dataset[i]));
+ GInt32 limEast = MIN(MAX(actEast, 0),
+ GDALGetRasterXSize(state->dataset[i]));
+ GInt32 limSouth = MIN(MAX(actSouth, 0),
+ GDALGetRasterYSize(state->dataset[i]));
+
+ GInt32 fileWidth = limEast - limWest;
+ GInt32 fileHeight = limSouth - limNorth;
+
+ imageWidth = fileWidth * xZoom;
+ imageHeight = fileHeight * yZoom;
+
+ // Center
+ GInt32 xLimCenter =
+ - (actWest - limWest + (actEast - actWest) / 2) * xZoom;
+ GInt32 yLimCenter =
+ - (actNorth - limNorth + (actSouth - actNorth) / 2) * yZoom;
+
+ // Position
+ GInt32 xLimPos = -(actWest - limWest) * xZoom;
+ GInt32 yLimPos = -(actNorth - limNorth) * yZoom;
+
+#ifdef MAP_DEBUG
+ fprintf(stderr,
+ "cairo size: %d x %d\n"
+ "center: %d;%d\n"
+ "limCenter: %d;%d\n"
+ "zoomed: %d x %d\n"
+ "actWest: %d actEast: %d\n"
+ "actNorth: %d actSouth: %d\n"
+ "limWest: %d limEast: %d\n"
+ "limNorth: %d limSouth: %d\n"
+ "file size: %d x %d\n",
+ imageWidth, imageHeight,
+ state->act_xPixel[i], state->act_yPixel[i],
+ xLimCenter, yLimCenter,
+ zoomedWidth, zoomedHeight,
+ actWest, actEast,
+ actNorth, actSouth,
+ limWest, limEast,
+ limNorth, limSouth,
+ fileWidth, fileHeight);
+#endif
+
+ GUInt32 *imageData = (GUInt32 *)
+ CPLMalloc(imageWidth * imageHeight * sizeof(GUInt32));
+
+ // Fill image
+ gdal2argb(state->dataset[i], imageData, imageWidth, imageHeight,
+ limWest, limNorth, fileWidth, fileHeight, 3, 0, 1, 2, mode);
+
+ CGContextSaveGState(gc);
+
+ //cairo_translate(cr, 0.5 * crWidth, 0.5 * crHeight);
+ //cairo_rotate(cr, state->req_rotation * M_PI / 180);
+
+ //cairo_translate(cr, xLimCenter, yLimCenter);
+
+ //cairo_set_source_surface(cr, image, 0, 0);
+ //cairo_paint(cr);
+
+ // Draw image
+{
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGDataProviderRef provider =
+ CGDataProviderCreateWithData(
+ NULL, imageData, imageWidth * imageHeight * 4, NULL);
+
+ CGImageRef image =
+ CGImageCreate(
+ imageWidth,
+ imageHeight,
+ 8,
+ 32,
+ imageWidth * 4,
+ colorSpace,
+ kCGImageAlphaPremultipliedFirst,
+ provider,
+ NULL,
+ 0,
+ kCGRenderingIntentDefault);
+
+ CGRect bounds = CGRectMake(xLimPos, yLimPos, imageWidth, imageHeight);
+
+ HIViewDrawCGImage(gc, &bounds, image);
+
+ CGImageRelease(image);
+
+ CGDataProviderRelease(provider);
+ CGColorSpaceRelease(colorSpace);
+}
+
+ CGContextRestoreGState(gc);
+
+ // Clean up
+ CPLFree(imageData);
+ }
+
+ // Update state
+ //state->act_rotation = state->req_rotation;
+ state->act_rotation = 0;
+ state->act_width = qWidth;
+ state->act_height = qHeight;
+
+ return 1;
+}
+#endif
+
+#ifdef WIN32
+int gdal2win32(MapState *state, HDC dc,
+ int gtkWidth, int gtkHeight, int mode)
+{
+ int i = 0;
+
+ while (state->dataset[i])
+ i++;
+
+ if (mapcovers(state->dataset[0],
+ state->act_xZoom[0], state->act_yZoom[0],
+ state->act_xPixel[0], state->act_yPixel[0],
+ gtkWidth, gtkHeight) && !mode)
+ i = 1;
+
+ for (i--; i >= 0; i--)
+ {
+ double xZoom = state->act_xZoom[i];
+ double yZoom = state->act_yZoom[i];
+
+ // Image width
+ GInt32 imageWidth = gtkWidth;
+ GInt32 imageHeight = gtkHeight;
+
+#ifdef MAP_DEBUG
+ fprintf(stderr,"zoom: %lf;%lf x y %d;%d\n",
+ xZoom, yZoom, state->act_xPixel[i], state->act_yPixel[i]);
+#endif
+
+ // Zoom
+ GInt32 zoomedWidth = imageWidth / xZoom + 2;
+ GInt32 zoomedHeight = imageHeight / yZoom + 2;
+
+ GInt32 actWest = state->act_xPixel[i] - zoomedWidth / 2;
+ GInt32 actEast = state->act_xPixel[i] + zoomedWidth / 2;
+ GInt32 actNorth = state->act_yPixel[i] - zoomedHeight / 2;
+ GInt32 actSouth = state->act_yPixel[i] + zoomedHeight / 2;
+
+ // Correct for image size
+ GInt32 limWest = MIN(MAX(actWest, 0),
+ GDALGetRasterXSize(state->dataset[i]));
+ GInt32 limNorth = MIN(MAX(actNorth, 0),
+ GDALGetRasterYSize(state->dataset[i]));
+ GInt32 limEast = MIN(MAX(actEast, 0),
+ GDALGetRasterXSize(state->dataset[i]));
+ GInt32 limSouth = MIN(MAX(actSouth, 0),
+ GDALGetRasterYSize(state->dataset[i]));
+
+ GInt32 fileWidth = limEast - limWest;
+ GInt32 fileHeight = limSouth - limNorth;
+
+ imageWidth = fileWidth * xZoom;
+ imageHeight = fileHeight * yZoom;
+
+ // Position
+ GInt32 xLimPos = -(actWest - limWest) * xZoom;
+ GInt32 yLimPos = -(actNorth - limNorth) * yZoom;
+
+#ifdef MAP_DEBUG
+ fprintf(stderr,
+ "gtk size: %d x %d\n"
+ "center: %d;%d\n"
+ "limPos: %d;%d\n"
+ "zoomed: %d x %d\n"
+ "actWest: %d actEast: %d\n"
+ "actNorth: %d actSouth: %d\n"
+ "limWest: %d limEast: %d\n"
+ "limNorth: %d limSouth: %d\n"
+ "file size: %d x %d\n",
+ imageWidth, imageHeight,
+ state->act_xPixel[i], state->act_yPixel[i],
+ xLimPos, yLimPos,
+ zoomedWidth, zoomedHeight,
+ actWest, actEast,
+ actNorth, actSouth,
+ limWest, limEast,
+ limNorth, limSouth,
+ fileWidth, fileHeight);
+#endif
+
+ if (imageWidth && imageHeight)
+ {
+ GUInt32 *imageData;
+ BITMAPINFO bmi;
+ HBITMAP dib;
+ HDC dib_dc = CreateCompatibleDC(NULL);
+
+ memset(&bmi, 0, sizeof(BITMAPINFO));
+
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = imageWidth;
+ bmi.bmiHeader.biHeight = imageHeight;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biClrUsed = 0;
+
+ dib = CreateDIBSection(dib_dc, &bmi, DIB_RGB_COLORS,
+ (void **)&imageData, NULL, 0);
+ SelectObject(dib_dc, dib);
+
+ // Fill image
+ gdal2argb(state->dataset[i], imageData, imageWidth, imageHeight,
+ limWest, limNorth, fileWidth, fileHeight,
+ 3, 0, 1, 2, mode);
+
+ // Draw image
+ StretchBlt(dc, xLimPos, yLimPos, imageWidth, imageHeight,
+ dib_dc, 0, imageHeight, imageWidth, -imageHeight, SRCCOPY);
+
+ // Clean up
+ DeleteDC(dib_dc);
+ DeleteObject(dib);
+ }
+ }
+
+ // Update state
+ state->act_rotation = 0.;
+ state->act_width = gtkWidth;
+ state->act_height = gtkHeight;
+
+ return 1;
+}
+#endif
+
+#endif
diff --git a/src/lib_map/map_render_cpp.cpp b/src/lib_map/map_render_cpp.cpp
new file mode 100644
index 0000000..150d0d7
--- /dev/null
+++ b/src/lib_map/map_render_cpp.cpp
@@ -0,0 +1,45 @@
+//
+// Copyright (c) 2005 -- Daniel Wallner
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#include "map_priv.h"
+
+#ifdef HAVE_QT
+#include <qpainter.h>
+#include <qimage.h>
+
+int qt_drawmap(GDALDatasetH dataset, void *painter,
+ GInt32 imageWidth, GInt32 imageHeight,
+ GInt32 mapWest, GInt32 mapNorth,
+ GInt32 mapWidth, GInt32 mapHeight,
+ GInt32 xPos, GInt32 yPos, int mode)
+{
+ QPainter *qpainter = (QPainter *)painter;
+ QImage qimage(imageWidth, imageHeight, 32);
+ GUInt32 *imageData = (GUInt32 *)qimage.bits();
+
+ // Fill image
+ gdal2argb(dataset, imageData, imageWidth, imageHeight,
+ mapWest, mapNorth, mapWidth, mapHeight,
+ 3, 0, 1, 2, mode);
+
+ // Draw image
+ qpainter->drawImage(xPos, yPos, qimage);
+
+ return 1;
+}
+#endif
diff --git a/src/lib_map/map_transform.c b/src/lib_map/map_transform.c
new file mode 100644
index 0000000..87ae1d2
--- /dev/null
+++ b/src/lib_map/map_transform.c
@@ -0,0 +1,591 @@
+//
+// Copyright (c) 2005 -- Daniel Wallner
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#include "map_priv.h"
+
+int metersperpixel(GDALDatasetH dataset, char *path, double lat,
+ double *xmpp, double *ympp)
+{
+ const char *wkt = GDALGetProjectionRef(dataset);
+
+ if (!wkt || !strlen(wkt))
+ {
+ if (strstr(path, "map_"))
+ {
+ double geoTransform[6];
+
+ if (GDALGetGeoTransform(dataset, geoTransform) != CE_None)
+ {
+ fprintf(stderr, "No valid geo transform\n");
+ }
+
+ *xmpp = fabs(geoTransform[1]) / PIXELFACT;
+ *ympp = fabs(geoTransform[5]) / PIXELFACT;
+ return 1;
+ }
+ else
+ {
+ double geoTransform[6];
+
+ if (GDALGetGeoTransform(dataset, geoTransform) == CE_None)
+ {
+#ifdef MAP_DEBUG
+ fprintf(stderr, "mpp: %lf;%lf\n",
+ fabs(geoTransform[1]) / PIXELFACT,
+ fabs(geoTransform[5]) / PIXELFACT);
+#endif
+ *xmpp = fabs(geoTransform[1]) / PIXELFACT;
+ *ympp = fabs(geoTransform[5]) / PIXELFACT;
+ if (lat != 0)
+ {
+ /* pseudo projection */
+ *xmpp *= fabs(cos(lat * M_PI / 180));
+ }
+ return 1;
+ }
+ else
+ {
+ // No valid geo transform
+ // Treat map as world topo map
+#ifdef MAP_DEBUG
+ fprintf(stderr, "Defaulting to world topo, mpp: %lf;%lf\n",
+ EQUATOR_CIRCUM / GDALGetRasterXSize(dataset),
+ POLE_CIRCUM / GDALGetRasterYSize(dataset) / 2);
+#endif
+ *xmpp = EQUATOR_CIRCUM / GDALGetRasterXSize(dataset);
+ *ympp = POLE_CIRCUM / GDALGetRasterXSize(dataset);
+
+ if (lat != 0)
+ {
+ /* pseudo projection */
+ *xmpp *= fabs(cos(lat * M_PI / 180));
+ }
+ return 1;
+ }
+ }
+ }
+
+ double geoTransform[6];
+ OGRSpatialReferenceH srDest = OSRNewSpatialReference(wkt);
+
+ if (GDALGetGeoTransform(dataset, geoTransform) != CE_None || !srDest)
+ {
+ fprintf(stderr, "No valid geo transform or spatial reference\n");
+ *xmpp = EQUATOR_CIRCUM / GDALGetRasterXSize(dataset);
+ *ympp = POLE_CIRCUM / GDALGetRasterYSize(dataset) / 2;
+ if (lat != 0)
+ {
+ /* pseudo projection */
+ *xmpp *= fabs(cos(lat * M_PI / 180));
+ }
+ return 0;
+ }
+
+ if (OSRIsProjected(srDest))
+ {
+ *xmpp = fabs(geoTransform[1]);
+ *ympp = fabs(geoTransform[5]);
+ }
+ else
+ {
+ *xmpp = EQUATOR_CIRCUM * fabs(geoTransform[1]) / 360;
+ *ympp = POLE_CIRCUM * fabs(geoTransform[5]) / 360;
+ if (lat != 0)
+ {
+ /* pseudo projection */
+ *xmpp *= fabs(cos(lat * M_PI / 180));
+ }
+ }
+
+ OSRDestroySpatialReference(srDest);
+ return 1;
+}
+
+int scale2zoom(GDALDatasetH dataset, char *path,
+ double scale, double pixelsize, double lat,
+ double *xZoom, double *yZoom)
+{
+ double xmpp;
+ double ympp;
+
+ int ret = metersperpixel(dataset, path, lat, &xmpp, &ympp);
+
+ *xZoom = xmpp / scale / pixelsize;
+ *yZoom = ympp / scale / pixelsize;
+
+ return ret;
+}
+
+int center2pixel(GDALDatasetH dataset,
+ GInt32 *xPixel, GInt32 *yPixel)
+{
+ *xPixel = GDALGetRasterXSize(dataset) / 2;
+ *yPixel = GDALGetRasterYSize(dataset) / 2;
+
+ return 1;
+}
+
+double mapcontains(GDALDatasetH dataset, char *path,
+ double lat, double lon)
+{
+ GInt32 width = GDALGetRasterXSize(dataset);
+ GInt32 height = GDALGetRasterYSize(dataset);
+
+ GInt32 xPixel;
+ GInt32 yPixel;
+
+ double xScore;
+ double yScore;
+
+ #define CHECK_MARGIN 400.
+ #define MARGIN_SCORE 0.9
+
+ wgs2pixel(dataset, path, lat, lon, &xPixel, &yPixel);
+
+ if (width <= 2 * CHECK_MARGIN)
+ xScore = 1. - fabs((2.0 * xPixel - width) / width);
+ else if (xPixel < CHECK_MARGIN)
+ xScore = xPixel / CHECK_MARGIN * MARGIN_SCORE;
+ else if (xPixel > width - CHECK_MARGIN)
+ xScore = (width - xPixel) / CHECK_MARGIN * MARGIN_SCORE;
+ else
+ xScore = 1. - (1. - MARGIN_SCORE) *
+ fabs((xPixel - width / 2.0) / (width / 2 - CHECK_MARGIN));
+
+ if (height <= 2 * CHECK_MARGIN)
+ yScore = 1. - fabs((2.0 * yPixel - height) / height);
+ else if (yPixel < CHECK_MARGIN)
+ yScore = yPixel / CHECK_MARGIN * MARGIN_SCORE;
+ else if (yPixel > height - CHECK_MARGIN)
+ yScore = (height - yPixel) / CHECK_MARGIN * MARGIN_SCORE;
+ else
+ yScore = 1. - (1. - MARGIN_SCORE) *
+ fabs((yPixel - height / 2.0) / (height / 2 - CHECK_MARGIN));
+
+ return MIN(xScore, yScore);
+}
+
+int wgs2geo(GDALDatasetH dataset,
+ double lat, double lon,
+ double *xGeo, double *yGeo)
+{
+ OGRSpatialReferenceH srWGS84;
+ OGRSpatialReferenceH srDest;
+ OGRCoordinateTransformationH trans;
+ double x = lon;
+ double y = lat;
+
+ *xGeo = 0;
+ *yGeo = 0;
+
+ const char *wkt = GDALGetProjectionRef(dataset);
+
+ if (!wkt || !strlen(wkt))
+ {
+ fprintf(stderr, "Unable to get projection\n");
+ return 0;
+ }
+
+ // Source
+
+ srWGS84 = OSRNewSpatialReference(NULL);
+ if (!srWGS84)
+ {
+ fprintf(stderr, "Unable to create source spatial reference\n");
+ return 0;
+ }
+
+ if (OSRSetWellKnownGeogCS(srWGS84, "WGS84") != OGRERR_NONE)
+ {
+ fprintf(stderr, "Unable to initialize source spatial reference\n");
+ return 0;
+ }
+
+ // Destination
+
+ srDest = OSRNewSpatialReference(wkt);
+ if (!srDest)
+ {
+ fprintf(stderr, "Unable to create target spatial reference\n");
+ return 0;
+ }
+
+#ifdef MAP_DEBUG
+ if (OSRIsProjected(srDest))
+ fprintf(stderr, "Projected SR\n");
+ else
+ fprintf(stderr, "Unprojected SR\n");
+ if (OSRIsGeographic(srDest))
+ fprintf(stderr, "Geographic SR\n");
+ else
+ fprintf(stderr, "Not geographic SR\n");
+ fprintf(stderr, "Linear units: %lf\n", OSRGetLinearUnits(srDest, NULL));
+#endif
+
+ // Transform
+
+ trans = OCTNewCoordinateTransformation(srWGS84, srDest);
+ if (!trans)
+ {
+ fprintf(stderr, "Unable to create transform\n");
+ return 0;
+ }
+
+ if (!OCTTransform(trans, 1, &x, &y, NULL))
+ {
+ fprintf(stderr, "Unable to transform\n");
+ return 0;
+ }
+
+ *xGeo = x;
+ *yGeo = y;
+
+ // Cleanup
+
+ OCTDestroyCoordinateTransformation(trans);
+ OSRDestroySpatialReference(srWGS84);
+ OSRDestroySpatialReference(srDest);
+
+ return 1;
+}
+
+int geo2pixel(GDALDatasetH hDataset,
+ double xGeo, double yGeo,
+ GInt32 *xPixel, GInt32 *yPixel)
+{
+ double geoTransform[6];
+ double pixelTransform[6];
+ double x, y;
+
+ if (GDALGetGeoTransform(hDataset, geoTransform) != CE_None)
+ {
+ fprintf(stderr, "No valid geo transform\n");
+
+ *xPixel = xGeo;
+ *yPixel = yGeo;
+
+ return 0;
+ }
+
+ GDALInvGeoTransform(geoTransform, pixelTransform);
+
+ GDALApplyGeoTransform(pixelTransform, xGeo, yGeo, &x, &y);
+
+ *xPixel = x;
+ *yPixel = y;
+
+ return 1;
+}
+
+int wgs2pixel(GDALDatasetH dataset, char *path,
+ double lat, double lon,
+ GInt32 *xPixel, GInt32 *yPixel)
+{
+ const char *wkt = GDALGetProjectionRef(dataset);
+
+ if (!wkt || !strlen(wkt))
+ {
+ if (strstr(path, "map_"))
+ {
+ double geoTransform[6];
+
+ if (GDALGetGeoTransform(dataset, geoTransform) != CE_None)
+ {
+ fprintf(stderr, "No valid geo transform\n");
+ return 0;
+ }
+
+ double map_lat = geoTransform[3] + 0.5 * geoTransform[5];
+ double map_lon = geoTransform[0] + 0.5 * geoTransform[1];
+ double map_scale = geoTransform[1];
+
+#ifdef MAP_DEBUG
+ printf("map lat lon scale %lf;%lf;%lf\n",
+ map_lat, map_lon, map_scale);
+#endif
+
+ double x, y;
+
+ calcxy2(&x, &y, lat, lon,
+ map_lat, map_lon, map_scale);
+
+ x += 0.5 * GDALGetRasterXSize(dataset);
+ y += 0.5 * GDALGetRasterYSize(dataset);
+
+ *xPixel = x;
+ *yPixel = y;
+
+#ifdef MAP_DEBUG
+ printf("map coord: %lf;%lf\n", x, y);
+#endif
+ }
+ else
+ {
+ double geoTransform[6];
+
+ if (GDALGetGeoTransform(dataset, geoTransform) == CE_None)
+ {
+ double map_lat = geoTransform[3] + 0.5 * geoTransform[5];
+ double map_lon = geoTransform[0] + 0.5 * geoTransform[1];
+ double map_scale = geoTransform[1];
+
+ *xPixel = 0.5 * GDALGetRasterXSize(dataset) +
+ (lon - map_lon) / map_scale * 313687320;
+ *yPixel = 0.5 * GDALGetRasterXSize(dataset) -
+ (lat - map_lat) / map_scale * 313687320;
+ }
+ else
+ {
+ // No valid geo transform
+ // Treat map as world topo map
+ *xPixel = 0.5 * GDALGetRasterXSize(dataset) +
+ (lon / 360) * GDALGetRasterXSize(dataset);
+ *yPixel = 0.5 * GDALGetRasterYSize(dataset) -
+ (lat / 360) * GDALGetRasterXSize(dataset);
+ }
+ }
+ }
+ else
+ {
+ double xGeo;
+ double yGeo;
+
+ wgs2geo(dataset, lat, lon, &xGeo, &yGeo);
+ geo2pixel(dataset, xGeo, yGeo, xPixel, yPixel);
+ }
+
+ return 1;
+}
+
+int wgs2state(double lat, double lon, MapState *state)
+{
+ int i;
+
+ for (i = 0; state->dataset[i]; i++)
+ wgs2pixel(state->dataset[i], state->path[i], lat, lon,
+ &state->act_xPixel[i], &state->act_yPixel[i]);
+
+ return 1;
+}
+
+int wgs2screen(MapState *state, double lat, double lon,
+ int *xPos, int *yPos)
+{
+ // This is incorrect for rotated maps
+
+ GInt32 xPixel;
+ GInt32 yPixel;
+
+ wgs2pixel(state->dataset[0], state->path[0], lat, lon, &xPixel, &yPixel);
+
+ double xDistance = state->act_xZoom[0] * (xPixel - state->act_xPixel[0]);
+ double yDistance = state->act_yZoom[0] * (yPixel - state->act_yPixel[0]);
+
+ *xPos = 0.5 * state->act_width + xDistance;
+ *yPos = 0.5 * state->act_height + yDistance;
+
+ return 1;
+}
+
+int geo2wgs(GDALDatasetH dataset,
+ double xGeo, double yGeo,
+ double *lat, double *lon)
+{
+ OGRSpatialReferenceH srSrc;
+ OGRSpatialReferenceH srWGS84;
+ OGRCoordinateTransformationH trans;
+ double x = xGeo;
+ double y = yGeo;
+
+ *lon = 0;
+ *lat = 0;
+
+ const char *wkt = GDALGetProjectionRef(dataset);
+
+ if (!wkt || !strlen(wkt))
+ {
+ fprintf(stderr, "Unable to get projection\n");
+ return 0;
+ }
+
+ // Source
+
+ srSrc = OSRNewSpatialReference(wkt);
+ if (!srSrc)
+ {
+ fprintf(stderr, "Unable to create target spatial reference\n");
+ return 0;
+ }
+
+ // Destination
+
+ srWGS84 = OSRNewSpatialReference(NULL);
+ if (!srWGS84)
+ {
+ fprintf(stderr, "Unable to create source spatial reference\n");
+ return 0;
+ }
+
+ if (OSRSetWellKnownGeogCS(srWGS84, "WGS84") != OGRERR_NONE)
+ {
+ fprintf(stderr, "Unable to initialize source spatial reference\n");
+ return 0;
+ }
+
+ // Transform
+
+ trans = OCTNewCoordinateTransformation(srSrc, srWGS84);
+ if (!trans)
+ {
+ fprintf(stderr, "Unable to create transform\n");
+ return 0;
+ }
+
+ if (!OCTTransform(trans, 1, &x, &y, NULL))
+ {
+ fprintf(stderr, "Unable to transform\n");
+ return 0;
+ }
+
+ *lon = x;
+ *lat = y;
+
+ // Cleanup
+
+ OCTDestroyCoordinateTransformation(trans);
+ OSRDestroySpatialReference(srSrc);
+ OSRDestroySpatialReference(srWGS84);
+
+ return 1;
+}
+
+int pixel2geo(GDALDatasetH dataset,
+ GInt32 xPixel, GInt32 yPixel,
+ double *xGeo, double *yGeo)
+{
+ double geoTransform[6];
+ double x, y;
+
+ if (GDALGetGeoTransform(dataset, geoTransform) != CE_None)
+ {
+ fprintf(stderr, "No valid geo transform\n");
+
+ *xGeo = xPixel;
+ *yGeo = yPixel;
+
+ return 0;
+ }
+
+ GDALApplyGeoTransform(geoTransform, xPixel, yPixel, &x, &y);
+
+ *xGeo = x;
+ *yGeo = y;
+
+ return 1;
+}
+
+int pixel2wgs(GDALDatasetH dataset, char *path,
+ GInt32 xPixel, GInt32 yPixel,
+ double *lat, double *lon)
+{
+ const char *wkt = GDALGetProjectionRef(dataset);
+
+ if (!wkt || !strlen(wkt))
+ {
+ if (strstr(path, "map_"))
+ {
+ double geoTransform[6];
+
+ if (GDALGetGeoTransform(dataset, geoTransform) != CE_None)
+ {
+ fprintf(stderr, "No valid geo transform\n");
+ return 0;
+ }
+
+ double map_lat = geoTransform[3] + 0.5 * geoTransform[5];
+ double map_lon = geoTransform[0] + 0.5 * geoTransform[1];
+ double map_scale = geoTransform[1];
+
+#ifdef MAP_DEBUG
+ printf("map lat lon scale w h %lf;%lf;%lf %d;%d\n",
+ map_lat, map_lon, map_scale,
+ GDALGetRasterXSize(dataset),
+ GDALGetRasterYSize(dataset));
+#endif
+
+ calcxytopos2(xPixel - GDALGetRasterXSize(dataset) / 2,
+ yPixel - GDALGetRasterYSize(dataset) / 2,
+ lat, lon, map_lat, map_lon, map_scale);
+
+#ifdef MAP_DEBUG
+ printf("res lat lon: %lf;%lf\n", *lat, *lon);
+#endif
+ }
+ else
+ {
+ double geoTransform[6];
+
+ if (GDALGetGeoTransform(dataset, geoTransform) == CE_None)
+ {
+ double map_lat = geoTransform[3] + 0.5 * geoTransform[5];
+ double map_lon = geoTransform[0] + 0.5 * geoTransform[1];
+ double map_scale = geoTransform[1];
+
+ *lon = (xPixel - 0.5 * GDALGetRasterXSize(dataset))
+ * map_scale / 313687320 + map_lon;
+ *lat = -(yPixel - 0.5 * GDALGetRasterXSize(dataset))
+ * map_scale / 313687320 + map_lon + map_lat;
+ }
+ else
+ {
+ // No valid geo transform
+ // Treat map as world topo map
+ *lon = (xPixel - 0.5 * GDALGetRasterXSize(dataset)) * 360.0
+ / GDALGetRasterXSize(dataset);
+ *lat = (yPixel - 0.5 * GDALGetRasterYSize(dataset)) * -360.0
+ / GDALGetRasterXSize(dataset);
+ }
+ }
+ }
+ else
+ {
+ double xGeo;
+ double yGeo;
+
+ pixel2geo(dataset, xPixel, yPixel, &xGeo, &yGeo);
+ geo2wgs(dataset, xGeo, yGeo, lat, lon);
+ }
+
+ return 1;
+}
+
+int screen2wgs(MapState *state, int xPos, int yPos,
+ double *lat, double *lon)
+{
+ // This is incorrect for rotated maps
+
+ double xDistance = xPos - 0.5 * state->act_width;
+ double yDistance = yPos - 0.5 * state->act_height;
+
+ GInt32 xPixel = state->act_xPixel[0] + xDistance / state->act_xZoom[0];
+ GInt32 yPixel = state->act_yPixel[0] + yDistance / state->act_yZoom[0];
+
+ pixel2wgs(state->dataset[0], state->path[0], xPixel, yPixel, lat, lon);
+
+ return 1;
+}
diff --git a/src/main_gui.c b/src/main_gui.c
new file mode 100644
index 0000000..dd01cd9
--- /dev/null
+++ b/src/main_gui.c
@@ -0,0 +1,1850 @@
+/*
+**********************************************************************
+
+Copyright (c) 2001-2007 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+**********************************************************************
+*/
+
+/*
+ * main_gui.c
+ *
+ * This module holds all the gui stuff for the main window
+ *
+ */
+
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <math.h>
+#include <gpsdrive.h>
+#include <icons.h>
+#include <config.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <gdk/gdktypes.h>
+#include "gtk/gtk.h"
+#include "gettext.h"
+#include <ctype.h>
+#include "gpsdrive.h"
+#include "gpsdrive_config.h"
+#include "gui.h"
+#include "poi_gui.h"
+#include "battery.h"
+#include "map_handler.h"
+#include "import_map.h"
+#include "download_map.h"
+#include "main_gui.h"
+#include "poi.h"
+#include "wlan.h"
+#include "routes.h"
+
+/* Defines for gettext I18n */
+#include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+extern currentstatus_struct current;
+extern coordinate_struct coords;
+extern color_struct colors;
+extern routestatus_struct route;
+extern int actualfriends, maxfriends;
+extern gchar loctime[20];
+extern gint mydebug;
+extern gint debug;
+extern gint iszoomed, xoff, yoff;
+extern gint sats_used, sats_in_view;
+
+extern gdouble wp_saved_target_lat;
+extern gdouble wp_saved_target_lon;
+extern gdouble wp_saved_posmode_lat;
+extern gdouble wp_saved_posmode_lon;
+extern gdouble pixelfact;
+
+extern gint usesql, havespeechout;
+extern gint slistsize, nlist[];
+extern gint PSIZE;
+extern GtkWidget *posbt;
+extern GtkWidget *bestmap_bt;
+extern GtkWidget *mapnik_bt;
+
+extern GtkWidget *main_window;
+
+
+/* Globally accessible widgets: */
+GtkWidget *map_drawingarea;
+GtkWidget *scaler_left_bt, *scaler_right_bt;
+GtkWidget *frame_statusbar, *frame_statusfriends;
+GtkWidget *main_table;
+GtkWidget *menuitem_sendmsg;
+
+// TODO: maybe these should be moved to local ones...
+GtkWidget *drawing_compass, *drawing_minimap, *drawing_gpsfix;
+GdkDrawable *drawable_compass, *drawable_minimap;
+GdkGC *kontext_compass, *kontext_gps, *kontext_minimap, *kontext_map;
+
+
+/* local widgets */
+static GtkWidget *mainbox_controls, *mainbox_status, *mainframe_map;
+static GtkTooltips *main_tooltips;
+static GtkWidget *frame_maptype;
+static GtkWidget *mapscaler_scaler;
+static GtkWidget *zoomin_bt, *zoomout_bt;
+static GtkWidget *statusprefscale_lb, *statusmapscale_lb;
+static GtkObject *mapscaler_adj;
+static GtkWidget *frame_dash_1, *frame_dash_2, *frame_dash_3, *frame_dash_4;
+static GtkWidget *statusfriends_lb, *statustime_lb;
+static GtkWidget *statuslat_lb, *statuslon_lb;
+static GtkWidget *statusheading_lb, *statusbearing_lb;
+static GtkWidget *hbox_zoom;
+
+/* Definitions for main menu */
+enum
+{
+ MENU_MAPIMPORT,
+ MENU_MAPDOWNLOAD,
+ MENU_LOADTRACK,
+ MENU_LOADROUTE,
+ MENU_SENDMSG,
+ MENU_SETTINGS,
+ MENU_HELPABOUT,
+ MENU_HELPCONTENT,
+};
+
+/* *****************************************************************************
+ * CALLBACKS
+ * *****************************************************************************/
+
+
+/* *****************************************************************************
+ * quit the program
+ */
+gint
+quit_program_cb (GtkWidget *widget, gpointer datum)
+{
+ gtk_main_quit ();
+ return TRUE;
+}
+
+
+/* ****************************************************************************
+ * toggle checkbox for mapnik mode
+ * datum == 2 also means switch off mapnik button
+ */
+gint
+toggle_mapnik_cb (GtkWidget *widget, guint datum)
+{
+ if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))
+ || (datum == 2))
+ {
+ local_config.MapnikStatusInt = 1;
+ gtk_widget_hide_all (frame_maptype);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (bestmap_bt), FALSE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
+ autobestmap_cb(bestmap_bt,0);
+ }
+ else
+ {
+ local_config.MapnikStatusInt = 0;
+ gtk_widget_show_all (GTK_WIDGET (frame_maptype));
+ }
+
+ // TODO: reload/update map display.....
+
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ * toggle coordinate format mode
+ */
+gint
+toggle_coords_cb (GtkWidget *widget)
+{
+ local_config.coordmode++;
+ if (local_config.coordmode >= LATLON_N_FORMATS)
+ local_config.coordmode = 0;
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ * evaluate choice from main menu
+ */
+gint
+main_menu_cb (GtkWidget *widget, gint choice)
+{
+ switch (choice)
+ {
+ case MENU_MAPIMPORT: import1_cb (NULL, 1); break;
+ case MENU_MAPDOWNLOAD: download_cb (NULL, 0); break;
+ case MENU_LOADTRACK: loadtrack_cb (NULL, 0); break;
+ case MENU_LOADROUTE: return TRUE; break;
+ case MENU_SENDMSG: sel_message_cb (NULL, 0); break;
+ case MENU_SETTINGS: settings_main_cb (NULL, 0); break;
+ case MENU_HELPABOUT: about_cb (NULL, 0); break;
+ case MENU_HELPCONTENT: help_cb (NULL, 0); break;
+ }
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ */
+gint
+autobestmap_cb (GtkWidget *widget, guint datum)
+{
+ gchar sc[15];
+
+ if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)) )
+ {
+ gtk_widget_set_sensitive (scaler_right_bt, FALSE);
+ gtk_widget_set_sensitive (scaler_left_bt, FALSE);
+ gtk_label_set_text (GTK_LABEL (statusprefscale_lb), _("Auto"));
+ if (mapscaler_scaler)
+ gtk_widget_set_sensitive (mapscaler_scaler, FALSE);
+ }
+ else
+ {
+ gtk_widget_set_sensitive (scaler_right_bt, TRUE);
+ gtk_widget_set_sensitive (scaler_left_bt, TRUE);
+ g_snprintf (sc, sizeof (sc), "1:%d", local_config.scale_wanted);
+ gtk_label_set_text (GTK_LABEL (statusprefscale_lb), sc);
+ if (mapscaler_scaler)
+ gtk_widget_set_sensitive (mapscaler_scaler, TRUE);
+ }
+
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ */
+gint
+minimapclick_cb (GtkWidget *widget, GdkEventMotion *event)
+{
+ gint x, y, px, py;
+ gdouble dif, lon, lat;
+ GdkModifierType state;
+
+ if (event->is_hint)
+ gdk_window_get_pointer (event->window, &x, &y, &state);
+ else
+ {
+ x = event->x;
+ y = event->y;
+ state = event->state;
+ }
+ if (state == 0)
+ return 0;
+#define MINISCREEN_X_2 64
+#define MINISCREEN_Y_2 51
+ px = (MINISCREEN_X_2 - x) * 10 * pixelfact;
+ py = (-MINISCREEN_Y_2 + y) * 10 * pixelfact;
+
+ minimap_xy2latlon(px, py, &lon, &lat, &dif);
+
+ /* g_print("\nstate: %x x:%d y:%d\n", state, x, y); */
+
+ /* Left mouse button */
+ if ((state & GDK_BUTTON1_MASK) == GDK_BUTTON1_MASK)
+ {
+ if (gui_status.posmode)
+ {
+ coords.posmode_lon = lon;
+ coords.posmode_lat = lat;
+ rebuildtracklist ();
+ }
+ }
+ /* Middle mouse button */
+ if ((state & GDK_BUTTON2_MASK) == GDK_BUTTON2_MASK)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (posbt),
+ FALSE);
+ rebuildtracklist ();
+ }
+
+ /* g_print("\nx: %d, y: %d\n", x, y); */
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ */
+gint
+zoom_cb (GtkWidget *widget, guint datum)
+{
+
+ if (iszoomed == FALSE) /* needed to be sure the old zoom is made */
+ return TRUE;
+ iszoomed = FALSE;
+
+ if (datum == 1)
+ { /* zoom in */
+ if (current.zoom >= ZOOM_MAX)
+ {
+ current.zoom = ZOOM_MAX;
+ iszoomed = TRUE;
+ }
+ else
+ {
+ current.zoom *= 2;
+ xoff *= 2;
+ yoff *= 2;
+ }
+ }
+ else if (datum == 2)
+ { /* zoom out */
+ if (current.zoom <= ZOOM_MIN)
+ {
+ current.zoom = ZOOM_MIN;
+ iszoomed = TRUE;
+ }
+ else
+ {
+ current.zoom /= 2;
+ xoff /= 2;
+ yoff /= 2;
+ }
+ }
+
+ if (current.zoom == ZOOM_MIN)
+ gtk_widget_set_sensitive (zoomout_bt, FALSE);
+ else
+ gtk_widget_set_sensitive (zoomout_bt, TRUE);
+ if (current.zoom == ZOOM_MAX)
+ gtk_widget_set_sensitive (zoomin_bt, FALSE);
+ else
+ gtk_widget_set_sensitive (zoomin_bt, TRUE);
+
+ if (current.importactive)
+ {
+ expose_cb (NULL, 0);
+ }
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ */
+gint
+scaler_cb (GtkAdjustment *adj, gdouble *datum)
+{
+ gchar sc[15];
+ local_config.scale_wanted = nlist[(gint) rint (adj->value)];
+ g_snprintf (sc, sizeof (sc), "1:%d", local_config.scale_wanted);
+ gtk_label_set_text (GTK_LABEL (statusprefscale_lb), sc);
+ if ( mydebug > 12 )
+ g_print ("Scaler: %d\n", local_config.scale_wanted);
+ current.needtosave = TRUE;
+
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ * Increase/decrease displayed map scale
+ * TODO: Improve finding of next apropriate map
+ * datum:
+ * 1 Zoom out
+ * 2 Zoom in
+ */
+gint
+scalerbt_cb (GtkWidget *widget, guint datum)
+{
+ if (datum == 1)
+ {
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (mapscaler_adj),
+ GTK_ADJUSTMENT (mapscaler_adj)->value +
+ GTK_ADJUSTMENT (mapscaler_adj)->step_increment);
+ }
+ else if (datum == 2)
+ {
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (mapscaler_adj),
+ GTK_ADJUSTMENT (mapscaler_adj)->value -
+ GTK_ADJUSTMENT (mapscaler_adj)->step_increment);
+ }
+
+ // TODO: check, if this is really necessary, and maybe remove...
+ expose_cb (NULL, 0);
+ expose_mini_cb (NULL, 0);
+
+ current.needtosave = TRUE;
+
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ * Update Contents of Dashboard fields
+ * the first parameter chooses one of the dashboard fields to update
+ * the second parameter chooses, which value should be dispayed there
+ */
+gint
+update_dashboard (GtkWidget *frame, gint source)
+{
+ // TODO: add "remaining time", "trip", "gps precision"
+ //gchar s2[100], s3[200], s2a[20];
+ gchar head[100], content[100], ctmp[10], unit[10], dirs = ' ';
+ //gchar font_unit[100];
+ gint font_size;
+
+ gdouble dir = 0.0;
+
+ font_size = 24;
+ //font_size = pango_font_description_get_size
+ // (local_config.color_dashboard);
+
+ switch (source)
+ {
+ case DASH_DIST:
+ {
+ g_strlcpy (head, _("Distance"), sizeof (head));
+ switch (local_config.distmode)
+ {
+ case DIST_MILES:
+ {
+ g_strlcpy (unit, "mi", sizeof (unit));
+ if (current.dist <= 1.0)
+ {
+ g_snprintf (ctmp, sizeof
+ (ctmp), "%.0f",
+ current.dist * 1760.0);
+ g_strlcpy (unit, "yrds",
+ sizeof (unit));
+ }
+ else if (current.dist <= 10.0)
+ {
+ g_snprintf (ctmp, sizeof
+ (ctmp), "%.2f",
+ current.dist);
+ }
+ else
+ {
+ g_snprintf (ctmp, sizeof
+ (ctmp), "%.1f",
+ current.dist);
+ }
+ break;
+ }
+ case DIST_NAUTIC:
+ {
+ g_strlcpy (unit, _("nmi"),
+ sizeof (unit));
+ if (current.dist <= 1.0)
+ {
+ g_snprintf (ctmp, sizeof
+ (ctmp), "%.3f",
+ current.dist);
+ }
+ else if (current.dist <= 10.0)
+ {
+ g_snprintf (ctmp, sizeof
+ (ctmp), "%.2f",
+ current.dist);
+ }
+ else
+ {
+ g_snprintf (ctmp, sizeof
+ (ctmp), "%.1f",
+ current.dist);
+ }
+ break;
+ }
+ default:
+ {
+ g_strlcpy (unit, _("km"),
+ sizeof (unit));
+ if (current.dist <= 1.0)
+ {
+ g_snprintf (ctmp, sizeof
+ (ctmp), "%.0f",
+ current.dist * 1000.0);
+ g_strlcpy (unit, "m",
+ sizeof (unit));
+ }
+ else if (current.dist <= 10.0)
+ {
+ g_snprintf (ctmp, sizeof
+ (ctmp), "%.2f",
+ current.dist);
+ }
+ else
+ {
+ g_snprintf (ctmp, sizeof
+ (ctmp), "%.1f",
+ current.dist);
+ }
+ }
+ }
+ g_snprintf (content, sizeof (content),
+ "<span color=\"%s\" font_desc=\"%s\">%s"
+ "<span font_desc=\"%.f\"> %s</span></span>",
+ local_config.color_dashboard,
+ local_config.font_dashboard, ctmp,
+ font_size*0.66, unit);
+ break;
+ }
+ case DASH_SPEED:
+ {
+ g_strlcpy (head, _("Speed"), sizeof (head));
+ switch (local_config.distmode)
+ {
+ case DIST_MILES:
+ g_strlcpy (unit, _("mi/h"),
+ sizeof (unit));
+ break;
+ case DIST_NAUTIC:
+ g_strlcpy (unit, _("knots"),
+ sizeof (unit));
+ break;
+ default:
+ g_strlcpy (unit, _("km/h"),
+ sizeof (unit));
+ }
+ g_snprintf (content, sizeof (content),
+ "<span color=\"%s\" font_desc=\"%s\">"
+ "% 3.1f<span font_desc=\"%.f\"> %s</span></span>",
+ local_config.color_dashboard,
+ local_config.font_dashboard,
+ current.groundspeed,
+ font_size*0.66, unit);
+ break;
+ }
+ case DASH_BEARING:
+ {
+ g_strlcpy (head, _("Bearing"), sizeof (head));
+ g_snprintf (content, sizeof (content),
+ "<span color=\"%s\" font_desc=\"%s\">%03.f"
+ "%s</span>",
+ local_config.color_dashboard,
+ local_config.font_dashboard,
+ RAD2DEG (current.bearing), DEGREE);
+ break;
+ }
+ case DASH_HEADING:
+ {
+ g_strlcpy (head, _("Heading"), sizeof (head));
+ g_snprintf (content, sizeof (content),
+ "<span color=\"%s\" font_desc=\"%s\">%03.f"
+ "%s</span>",
+ local_config.color_dashboard,
+ local_config.font_dashboard,
+ RAD2DEG (current.heading), DEGREE);
+ break;
+ }
+ case DASH_TURN:
+ {
+ g_strlcpy (head, _("Turn"), sizeof (head));
+ dir = RAD2DEG (current.bearing)
+ - RAD2DEG (current.heading);
+ if (dir > 180)
+ dir = dir - 360;
+ else if (dir < -180)
+ dir = 360 + dir;
+ if (dir < 0.0)
+ dirs = 'L';
+ else if (dir > 0.0)
+ dirs = 'R';
+ g_snprintf (content, sizeof (content),
+ "<span color=\"%s\" font_desc=\"%s\">%c %03d"
+ "%s</span>",
+ local_config.color_dashboard,
+ local_config.font_dashboard,
+ dirs, abs (dir), DEGREE);
+ break;
+ }
+ case DASH_TIMEREMAIN:
+ {
+ g_strlcpy (head, _("Time remaining"), sizeof (head));
+
+ g_snprintf (content, sizeof (content),
+ "<span color=\"%s\" font_desc=\"%s\">%s"
+ "%s</span>",
+ local_config.color_dashboard,
+ local_config.font_dashboard, "---", "min");
+ break;
+ }
+ case DASH_ALT:
+ {
+ g_strlcpy (head, _("Altitude"), sizeof (head));
+ if (current.gpsfix == 3)
+ {
+ switch (local_config.altmode)
+ {
+ case ALT_FEET:
+ {
+ g_snprintf (ctmp, sizeof (ctmp),
+ "%.0f", current.altitude
+ * 3.2808399 +
+ local_config.normalnull);
+ g_strlcpy (unit, "ft", sizeof (unit));
+ break;
+ }
+ case ALT_YARDS:
+ {
+ g_snprintf (ctmp, sizeof (ctmp),
+ "%.0f", current.altitude
+ * 1.093613 +
+ local_config.normalnull);
+ g_strlcpy (unit, "yd", sizeof (unit));
+ break;
+ }
+ default:
+ {
+ g_snprintf (ctmp, sizeof (ctmp),
+ "%.0f", current.altitude
+ + local_config.normalnull);
+ g_strlcpy (unit, "m", sizeof (unit));
+ }
+ }
+ g_snprintf (content, sizeof (content),
+ "<span color=\"%s\" font_desc=\"%s\">"
+ "%s<span font_desc=\"%.f\"> %s</span></span>",
+ local_config.color_dashboard,
+ local_config.font_dashboard,
+ ctmp, font_size*0.66, unit);
+ }
+ else
+ {
+ g_snprintf (content, sizeof (content),
+ "<span color=\"%s\" font_desc=\"%s\" "
+ "size=\"small\"> %s</span>",
+ local_config.color_dashboard,
+ local_config.font_dashboard, _("n/a"));
+ }
+ break;
+ }
+ case DASH_TRIP:
+ {
+ g_strlcpy (head, _("Trip"), sizeof (head));
+
+ g_snprintf (content, sizeof (content),
+ "<span color=\"%s\" font_desc=\"%s\">%s"
+ "%s</span>",
+ local_config.color_dashboard,
+ local_config.font_dashboard, "---", "km");
+ break;
+ }
+ case DASH_GPSPRECISION:
+ {
+ g_strlcpy (head, _("GPS Precision"), sizeof (head));
+
+ g_snprintf (content, sizeof (content),
+ "<span color=\"%s\" font_desc=\"%s\">%s"
+ "%s</span>",
+ local_config.color_dashboard,
+ local_config.font_dashboard, "---", "m");
+ break;
+ }
+ case DASH_TIME:
+ {
+ g_strlcpy (head, _("Current Time"), sizeof (head));
+ if (current.gpsfix > 1)
+ {
+ g_snprintf (content, sizeof (content),
+ "<span color=\"%s\" font_desc=\"%s\">"
+ "%s</span>",
+ local_config.color_dashboard,
+ local_config.font_dashboard, loctime);
+ }
+ else
+ {
+ g_snprintf (content, sizeof (content),
+ "<span color=\"%s\" font_desc=\"%s\" "
+ "size=\"16000\">%s</span>",
+ local_config.color_dashboard,
+ local_config.font_dashboard, _("n/a"));
+ }
+ break;
+ }
+ }
+
+ g_object_set (frame, "label", head, NULL);
+ gtk_label_set_markup (GTK_LABEL (GTK_BIN (frame)->child), content);
+
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ * Update Status Displays
+ TODO: move functionality from gpsdrive.c to here
+ */
+gint
+update_statusdisplay ()
+{
+ gchar stmp[20];
+ gdouble t_lat, t_lon;
+
+ /* update gps time */
+ gtk_label_set_text (GTK_LABEL (statustime_lb), loctime);
+
+ /* update friends */
+ if (local_config.showfriends)
+ {
+ g_snprintf (stmp, sizeof (stmp), "%d/%d", actualfriends,
+ maxfriends);
+ gtk_label_set_text (GTK_LABEL (statusfriends_lb), stmp);
+ }
+
+ /* update lat/lon display */
+ if (gui_status.posmode)
+ {
+ GdkModifierType state;
+ gint x, y;
+
+ gdk_window_get_pointer (map_drawingarea->window, &x, &y,&state);
+ calcxytopos (x, y, &t_lat, &t_lon, current.zoom);
+ if ( mydebug > 20 )
+ printf ("Actual mouse position: lat:%f,lon:%f"
+ "(x:%d,y:%d)\n", t_lat, t_lon, x, y);
+ /* display position of Mouse in lat/lon Fields */
+ }
+ else
+ {
+ t_lat = coords.current_lat;
+ t_lon = coords.current_lon;
+ }
+ coordinate2gchar(stmp, sizeof(stmp), t_lat, TRUE,
+ local_config.coordmode);
+ gtk_label_set_text (GTK_LABEL (statuslat_lb), stmp);
+ coordinate2gchar(stmp, sizeof(stmp), t_lon, FALSE,
+ local_config.coordmode);
+ gtk_label_set_text (GTK_LABEL (statuslon_lb), stmp);
+
+ /*update mapscale */
+ g_snprintf (stmp, sizeof (stmp), "1:%ld", current.mapscale);
+ gtk_label_set_text (GTK_LABEL (statusmapscale_lb), stmp);
+
+ /* update heading */
+ g_snprintf (stmp, sizeof (stmp), "%3.0f%s",
+ RAD2DEG (current.heading), DEGREE);
+ gtk_label_set_text (GTK_LABEL (statusheading_lb), stmp);
+
+ /* update bearing */
+ g_snprintf (stmp, sizeof (stmp), "%3.0f%s",
+ RAD2DEG (current.bearing), DEGREE);
+ gtk_label_set_text (GTK_LABEL (statusbearing_lb), stmp);
+
+ /* update dashboard */
+ update_dashboard (frame_dash_1, local_config.dashboard_1);
+ update_dashboard (frame_dash_2, local_config.dashboard_2);
+ update_dashboard (frame_dash_3, local_config.dashboard_3);
+ update_dashboard (frame_dash_4, local_config.dashboard_4);
+
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ * Update Display of GPS Status
+ */
+gint
+expose_gpsfix (GtkWidget *widget, guint *datum)
+{
+ GdkDrawable *drawable_gpsfix;
+ GdkGC *kontext_gpsfix;
+ PangoFontDescription *pfd_gpsfix;
+ PangoLayout *layout_gpsfix;
+ gint t_x, t_y, t_tx, t_ty, t_wx, i;
+
+ if (mydebug >50)
+ fprintf (stderr, "expose_gpsfix()\n");
+
+ drawable_gpsfix = drawing_gpsfix->window;
+ if (!drawable_gpsfix) {
+ return 0;
+ }
+ kontext_gpsfix = gdk_gc_new (drawable_gpsfix);
+ pfd_gpsfix = pango_font_description_from_string ("Sans 8");
+ gdk_drawable_get_size (drawable_gpsfix, &t_x, &t_y);
+
+ layout_gpsfix = gtk_widget_create_pango_layout
+ (drawing_gpsfix, _("No GPS"));
+ pango_layout_set_font_description (layout_gpsfix, pfd_gpsfix);
+ pango_layout_get_pixel_size (layout_gpsfix, &t_tx, &t_ty);
+
+ if (current.simmode)
+ {
+ gdk_gc_set_foreground (kontext_gpsfix, &colors.blue);
+ pango_layout_set_text (layout_gpsfix, _("Simulation Mode"), -1);
+ gdk_draw_rectangle (drawable_gpsfix, kontext_gpsfix,
+ TRUE, 0,0, t_x, t_y);
+ gdk_draw_layout_with_colors (drawable_gpsfix, kontext_gpsfix,
+ 5, (t_y-t_ty)/2, layout_gpsfix,
+ &colors.white, NULL);
+ }
+ else
+ {
+ switch (current.gpsfix)
+ {
+ case 0:
+ {
+ gdk_gc_set_foreground (kontext_gpsfix, &colors.red);
+ break;
+ }
+ case 1:
+ {
+ gdk_gc_set_foreground (kontext_gpsfix, &colors.red);
+ pango_layout_set_text (layout_gpsfix, "No Fix", -1);
+ break;
+ }
+ case 2:
+ {
+ // TODO: have a look at the nmea parsing
+ // to avoid "jumping" between 2D and 3D
+ gdk_gc_set_foreground (kontext_gpsfix, &colors.green);
+ pango_layout_set_text (layout_gpsfix, "2D Fix", -1);
+ break;
+ }
+ case 3:
+ {
+ gdk_gc_set_foreground (kontext_gpsfix, &colors.green);
+ pango_layout_set_text (layout_gpsfix, "3D Fix", -1);
+ break;
+ }
+ }
+
+ gdk_draw_rectangle (drawable_gpsfix, kontext_gpsfix,
+ TRUE, 0,0, t_x, t_y);
+ gdk_draw_layout_with_colors (drawable_gpsfix, kontext_gpsfix,
+ t_x-t_tx-5, (t_y-t_ty)/2, layout_gpsfix,
+ &colors.black, NULL);
+
+ gdk_gc_set_foreground (kontext_gpsfix, &colors.black);
+ t_wx = (t_x-t_tx-26)/12;
+ if (t_wx < 1)
+ t_wx =1;
+ gdk_gc_set_line_attributes (kontext_gpsfix, t_wx, 0, 0, 0);
+ for (i=1; i<13; i++)
+ {
+ if (i > sats_in_view)
+ gdk_gc_set_foreground
+ (kontext_gpsfix, &colors.grey);
+ else if (i > sats_used)
+ gdk_gc_set_foreground
+ (kontext_gpsfix, &colors.darkgrey);
+ gdk_draw_line (drawable_gpsfix, kontext_gpsfix,
+ i*(t_wx+1)+5, 5, i*(t_wx+1)+5, t_y-5);
+ }
+ }
+
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ * Reactions to pressed key
+ TODO: check if everything is fine and not obsolete
+ */
+gint
+key_pressed_cb (GtkWidget * widget, GdkEventKey * event)
+{
+ gdouble lat, lon;
+ gint x, y;
+ GdkModifierType state;
+
+ if ( mydebug > 0 )
+ g_print ("event:%x key:%c\n", event->keyval, event->keyval);
+
+ // Toggle Grid Display
+ if ((toupper (event->keyval)) == 'G')
+ {
+ local_config.showgrid = !local_config.showgrid;
+ current.needtosave = TRUE;
+ }
+
+ // Toggle Friends Server activities
+ if ((toupper (event->keyval)) == 'F')
+ {
+ local_config.showfriends = !local_config.showfriends;
+ current.needtosave = TRUE;
+ }
+
+ // Add Waypoint at current gps location
+ if ((toupper (event->keyval)) == 'X')
+ {
+ coords.wp_lat = coords.current_lat;
+ coords.wp_lon = coords.current_lon;
+ addwaypoint_cb (NULL, NULL);
+ }
+
+ // Add Waypoint at current gps location without asking
+ if ((toupper (event->keyval)) == 'W')
+ {
+ gchar wp_name[100], wp_type[100], wp_comment[100];
+ time_t t;
+ struct tm *ts;
+ time (&t);
+ ts = localtime (&t);
+ g_snprintf (wp_name, sizeof (wp_name), "%s", asctime (ts));
+ g_snprintf (wp_type, sizeof (wp_type),
+ "waypoint.wpttemp.wpttemp-green");
+ g_snprintf (wp_comment, sizeof (wp_comment),
+ _("Quicksaved Waypoint"));
+ if (usesql)
+ addwaypoint (wp_name, wp_type, wp_comment,
+ coords.current_lat, coords.current_lon, TRUE);
+ else
+ addwaypoint (wp_name, wp_type, wp_comment,
+ coords.current_lat, coords.current_lon, FALSE);
+ }
+
+ // Add waypoint at current mouse location
+ if ((toupper (event->keyval)) == 'Y')
+ {
+ gdk_window_get_pointer (map_drawingarea->window, &x, &y, &state);
+ calcxytopos (x, y, &lat, &lon, current.zoom);
+ if ( mydebug > 0 )
+ printf ("Actual Position: lat:%f,lon:%f (x:%d,y:%d)\n",
+ lat, lon, x, y);
+ /* Add mouse position as waypoint */
+ coords.wp_lat = lat;
+ coords.wp_lon = lon;
+ addwaypoint_cb (NULL, 0);
+ }
+
+ // Add instant waypoint a current mouse location
+ if ((toupper (event->keyval)) == 'P')
+ {
+ gchar wp_name[100], wp_type[100], wp_comment[100];
+ time_t t;
+ struct tm *ts;
+ time (&t);
+ ts = localtime (&t);
+ g_snprintf (wp_name, sizeof (wp_name), "%s", asctime (ts));
+ g_snprintf (wp_type, sizeof (wp_type),
+ "waypoint.wpttemp.wpttemp-yellow");
+ g_snprintf (wp_comment, sizeof (wp_comment),
+ _("Temporary Waypoint"));
+ gdk_window_get_pointer (map_drawingarea->window, &x, &y, &state);
+ calcxytopos (x, y, &lat, &lon, current.zoom);
+ if ( mydebug > 0 )
+ printf ("Add Waypoint: %s lat:%f,lon:%f (x:%d,y:%d)\n",
+ wp_name, lat, lon, x, y);
+ if (usesql)
+ addwaypoint (wp_name, wp_type, wp_comment, lat, lon, TRUE);
+ else
+ addwaypoint (wp_name, wp_type, wp_comment, lat, lon, FALSE);
+ }
+
+ // Add instant routepoint at current mouse location
+ if ((toupper (event->keyval)) == 'R')
+ {
+ quickadd_routepoint ();
+ }
+
+ // In Route mode Force next Route Point
+ if (((toupper (event->keyval)) == 'J') && route.active)
+ {
+ route.forcenext = TRUE;
+ }
+
+
+ // Zoom in/out
+
+ // if (local_config.guimode == GUI_PDA)
+ // {
+ // if (event->keyval == 0xFF52)
+ // scalerbt_cb (NULL, 1); /* RNM */
+ // if (event->keyval == 0xFF54)
+ // scalerbt_cb (NULL, 2); /* RNM */
+ // }
+ if ((toupper (event->keyval)) == '-' || (event->keyval == 0xFFad))
+ {
+ /* Zoom out */
+ scalerbt_cb (NULL, 1);
+ }
+ if ((toupper (event->keyval)) == '+' || (event->keyval == 0xFFab))
+ {
+ /* Zoom in */
+ scalerbt_cb (NULL, 2);
+ }
+
+ // Switch Night Mode
+ if ((toupper (event->keyval)) == 'N')
+ {
+ // TODO: enable functionality once nightmode
+ // is available again
+ }
+
+ // Query Info for next points and streets
+ if ( ( (toupper (event->keyval)) == '?' )
+ || ( (toupper (event->keyval)) == 'Q') )
+ {
+ gdk_window_get_pointer (map_drawingarea->window, &x, &y, &state);
+ gdouble lat1,lon1,lat2,lon2;
+ gint delta = 10;
+ calcxytopos (x-delta, y-delta, &lat1, &lon1, current.zoom);
+ calcxytopos (x+delta, y+delta, &lat2, &lon2, current.zoom);
+ printf ("---------------------------------------------\n");
+ if ( local_config.showpoi )
+ poi_query_area (min(lat1,lat2), min(lon1,lon2),
+ max(lat1,lat2), max(lon1,lon2) );
+
+ if ( local_config.showwlan )
+ wlan_query_area (min(lat1,lat2),
+ min(lon1,lon2), max(lat1,lat2), max(lon1,lon2) );
+
+ gdouble lat,lon;
+ calcxytopos (x, y, &lat, &lon, current.zoom);
+ gdouble dist=lat2-lat1;
+ dist = dist>0?dist:-dist;
+// if ( streets_draw )
+// streets_query_point ( lat,lon, dist );
+ }
+
+
+ if ( mydebug>10 )
+ fprintf(stderr,"Key pressed: %0x\n",event->keyval);
+
+
+ if (gui_status.posmode)
+ {
+ gdouble x, y;
+
+ if ( (event->keyval == 0xff52)) // Up
+ {
+ calcxy (&x, &y, coords.current_lon,
+ coords.current_lat, current.zoom);
+ calcxytopos (x, 0, &coords.current_lat,
+ &coords.current_lon, current.zoom);
+ }
+
+ if ( (event->keyval == 0xff54 )) // Down
+ {
+ calcxy (&x, &y, coords.current_lon,
+ coords.current_lat, current.zoom);
+ calcxytopos (x, SCREEN_Y, &coords.current_lat,
+ &coords.current_lon, current.zoom);
+ }
+ if ( (event->keyval == 0xff51 )) // Left
+ {
+ calcxy (&x, &y, coords.current_lon,
+ coords.current_lat, current.zoom);
+ calcxytopos (0, y, &coords.current_lat,
+ &coords.current_lon, current.zoom);
+ }
+ if ( (event->keyval == 0xff53 )) // Right
+
+ {
+ calcxy (&x, &y, coords.current_lon, coords.current_lat, current.zoom);
+ calcxytopos (SCREEN_X, y, &coords.current_lat, &coords.current_lon, current.zoom);
+ }
+ coords.posmode_lon = coords.current_lon;
+ coords.posmode_lat = coords.current_lat;
+ }
+ return 0;
+}
+
+
+/* *****************************************************************************
+ * Window: Main -> Controls
+ */
+void create_controls_mainbox (void)
+{
+ GtkWidget *vbox_buttons, *frame_poi, *frame_track;
+ GtkWidget *frame_mapcontrol;
+ GtkWidget *zoomin_img, *zoomout_img;
+ GtkWidget *hbox_scaler, *mute_bt;
+ GtkWidget *pda_box_left, *pda_box_right;
+
+ GtkWidget *menuitem_maps, *menuitem_mapimport, *menuitem_mapdownload;
+ GtkWidget *menuitem_load, *menuitem_settings;
+ GtkWidget *menuitem_help, *menuitem_helpabout, *menuitem_helpcontent;
+ GtkWidget *menuitem_loadtrack, *menuitem_loadroute;
+ GtkWidget *menuitem_quit, *main_menu, *menuitem_menu;
+ GtkWidget *menu_menu, *menu_help, *menu_maps, *menu_load;
+ GtkWidget *menuitem_sep, *sendmsg_img;
+
+ GtkWidget *vbox_poi, *poi_draw_bt, *wlan_draw_bt, *wp_draw_bt;
+ GtkWidget *vbox_track, *showtrack_bt, *savetrack_bt;
+
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_controls_mainbox\n");
+
+ /* MENU AND BUTTONS */
+ {
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_controls_mainbox(MENU AND BUTTONS)\n");
+ vbox_buttons = gtk_vbox_new (TRUE, 3 * PADDING);
+
+ /* Main Menu */
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_controls_mainbox(Main Menu)\n");
+ main_menu = gtk_menu_bar_new ();
+ menu_menu = gtk_menu_new ();
+ menuitem_menu = gtk_menu_item_new_with_label (_("Options"));
+ gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), menuitem_menu);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem_menu), menu_menu);
+
+ menu_maps = gtk_menu_new ();
+ menuitem_maps = gtk_menu_item_new_with_label (_("Maps"));
+ menuitem_mapimport = gtk_menu_item_new_with_label (_("Import"));
+ menuitem_mapdownload = gtk_menu_item_new_with_label (_("Download"));
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu_menu), menuitem_maps);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem_maps), menu_maps);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu_maps), menuitem_mapimport);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu_maps),
+ menuitem_mapdownload);
+ g_signal_connect (menuitem_mapimport, "activate",
+ GTK_SIGNAL_FUNC (main_menu_cb), (gpointer) MENU_MAPIMPORT);
+ g_signal_connect (menuitem_mapdownload, "activate",
+ GTK_SIGNAL_FUNC (main_menu_cb), (gpointer) MENU_MAPDOWNLOAD);
+
+ menu_load = gtk_menu_new ();
+ menuitem_load = gtk_image_menu_item_new_from_stock ("gtk-open", NULL);
+ menuitem_loadtrack = gtk_menu_item_new_with_label (_("Track File"));
+ menuitem_loadroute = gtk_menu_item_new_with_label (_("Route File"));
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu_menu), menuitem_load);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem_load), menu_load);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu_load), menuitem_loadtrack);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu_load), menuitem_loadroute);
+ g_signal_connect (menuitem_loadtrack, "activate",
+ GTK_SIGNAL_FUNC (main_menu_cb), (gpointer) MENU_LOADTRACK);
+ g_signal_connect (menuitem_loadroute, "activate",
+ GTK_SIGNAL_FUNC (main_menu_cb), (gpointer) MENU_LOADROUTE);
+
+ // TODO: add load route functionality, until then the item is disabled
+ gtk_widget_set_sensitive (menuitem_loadroute, FALSE);
+
+ menuitem_sendmsg =
+ gtk_image_menu_item_new_with_label (_("Send Message"));
+ sendmsg_img =
+ gtk_image_new_from_stock ("gtk-network", GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image
+ (GTK_IMAGE_MENU_ITEM (menuitem_sendmsg), sendmsg_img);
+ if (!local_config.showfriends)
+ gtk_widget_set_sensitive (menuitem_sendmsg, FALSE);
+ menuitem_settings =
+ gtk_image_menu_item_new_from_stock ("gtk-preferences", NULL);
+ menuitem_sep = gtk_separator_menu_item_new ();
+ menuitem_quit =
+ gtk_image_menu_item_new_from_stock ("gtk-quit", NULL);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu_menu), menuitem_sendmsg);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu_menu), menuitem_settings);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu_menu), menuitem_sep);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu_menu), menuitem_quit);
+ g_signal_connect (menuitem_sendmsg, "activate",
+ GTK_SIGNAL_FUNC (main_menu_cb), (gpointer) MENU_SENDMSG);
+ g_signal_connect (menuitem_settings, "activate",
+ GTK_SIGNAL_FUNC (main_menu_cb), (gpointer) MENU_SETTINGS);
+ g_signal_connect (menuitem_quit, "activate",
+ GTK_SIGNAL_FUNC (quit_program_cb), NULL);
+
+ /* Help Menu */
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_controls_mainbox(Help Menu)\n");
+ menu_help = gtk_menu_new ();
+ menuitem_help = gtk_menu_item_new_with_label (_("Help"));
+ menuitem_helpabout =
+ gtk_image_menu_item_new_from_stock ("gtk-about", NULL);
+ menuitem_helpcontent =
+ gtk_image_menu_item_new_from_stock ("gtk-help", NULL);
+ gtk_menu_shell_append (GTK_MENU_SHELL (main_menu), menuitem_help);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem_help), menu_help);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu_help),
+ menuitem_helpabout);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu_help),
+ menuitem_helpcontent);
+ g_signal_connect (menuitem_helpabout, "activate",
+ GTK_SIGNAL_FUNC (main_menu_cb), (gpointer) MENU_HELPABOUT);
+ g_signal_connect (menuitem_helpcontent, "activate",
+ GTK_SIGNAL_FUNC (main_menu_cb), (gpointer) MENU_HELPCONTENT);
+
+ gtk_box_pack_start (GTK_BOX (vbox_buttons),
+ main_menu, FALSE, FALSE, 1 * PADDING);
+
+ /* Buttons: Zoom */
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_controls_mainbox(Bottons: Zoom)\n");
+ hbox_zoom = gtk_hbox_new (FALSE, 1 * PADDING);
+ zoomin_bt = gtk_button_new ();
+ zoomin_img = gtk_image_new_from_stock
+ ("gtk-zoom-in", GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (zoomin_bt), zoomin_img);
+ g_signal_connect (GTK_OBJECT (zoomin_bt), "clicked",
+ GTK_SIGNAL_FUNC (zoom_cb), (gpointer) 1);
+ zoomout_bt = gtk_button_new ();
+ zoomout_img = gtk_image_new_from_stock
+ ("gtk-zoom-out", GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (zoomout_bt), zoomout_img);
+ g_signal_connect (GTK_OBJECT (zoomout_bt), "clicked",
+ GTK_SIGNAL_FUNC (zoom_cb), (gpointer) 2);
+ if (current.zoom <= ZOOM_MIN)
+ gtk_widget_set_sensitive (zoomout_bt, FALSE);
+ if (current.zoom >= ZOOM_MAX)
+ gtk_widget_set_sensitive (zoomin_bt, FALSE);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (main_tooltips), zoomin_bt,
+ _("Zoom into the current map"), NULL);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (main_tooltips), zoomout_bt,
+ _("Zooms out off the current map"), NULL);
+ gtk_box_pack_start (GTK_BOX (hbox_zoom),
+ zoomout_bt, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (hbox_zoom),
+ zoomin_bt, TRUE, TRUE, 1 * PADDING);
+ if (local_config.guimode != GUI_CAR) {
+ gtk_box_pack_start (GTK_BOX (vbox_buttons),
+ hbox_zoom, FALSE, FALSE, 1 * PADDING);
+ }
+
+ /* Buttons: Scaler */
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_controls_mainbox(Bottons: Scaler)\n");
+ hbox_scaler = gtk_hbox_new (FALSE, 1 * PADDING);
+ scaler_right_bt = gtk_button_new_with_label (">>");
+ g_signal_connect (GTK_OBJECT (scaler_right_bt), "clicked",
+ GTK_SIGNAL_FUNC (scalerbt_cb), (gpointer) 1);
+ scaler_left_bt = gtk_button_new_with_label ("<<");
+ g_signal_connect (GTK_OBJECT (scaler_left_bt), "clicked",
+ GTK_SIGNAL_FUNC (scalerbt_cb), (gpointer) 2);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (main_tooltips), scaler_left_bt,
+ _("Select the next more detailed map"), NULL);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (main_tooltips), scaler_right_bt,
+ _("Select the next less detailed map"), NULL);
+ gtk_box_pack_start (GTK_BOX (hbox_scaler),
+ scaler_left_bt, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (hbox_scaler),
+ scaler_right_bt, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (vbox_buttons),
+ hbox_scaler, FALSE, FALSE, 1 * PADDING);
+
+
+ /* Button: Mute Speech */
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_controls_mainbox(Bottons: Mute Speech)\n");
+ if (havespeechout)
+ {
+ mute_bt = gtk_check_button_new_with_label (_("Mute Speech"));
+ gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (mute_bt), FALSE);
+ if (local_config.mute)
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (mute_bt), TRUE);
+ }
+ g_signal_connect (GTK_OBJECT (mute_bt), "clicked",
+ GTK_SIGNAL_FUNC (toggle_button_cb),
+ &local_config.mute);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (main_tooltips), mute_bt,
+ _("Disable output of speech"), NULL);
+ gtk_box_pack_start (GTK_BOX (vbox_buttons),
+ mute_bt, FALSE, FALSE, 1 * PADDING);
+ }
+
+ /* Button: Search POIs */
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_controls_mainbox(Bottons: Search POI)\n");
+ find_poi_bt = gtk_button_new_from_stock (GTK_STOCK_FIND);
+ if (!usesql)
+ {
+ g_signal_connect (GTK_OBJECT (find_poi_bt), "clicked",
+ GTK_SIGNAL_FUNC (sel_target_cb), (gpointer) 2);
+ }
+ else
+ {
+ g_signal_connect (GTK_OBJECT (find_poi_bt), "clicked",
+ GTK_SIGNAL_FUNC (show_poi_lookup_cb), (gpointer) 2);
+ }
+ gtk_box_pack_start (GTK_BOX (vbox_buttons),
+ find_poi_bt, FALSE, FALSE, 1 * PADDING);
+
+ } /* END MENU AND BUTTONS */
+
+ /* WAYPOINTS AND POIs */
+ {
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_controls_mainbox(Bottons: WAYPOINTS AND POIs)\n");
+
+ frame_poi = gtk_frame_new (_("Points"));
+ vbox_poi = gtk_vbox_new (TRUE, 1 * PADDING);
+ gtk_container_add (GTK_CONTAINER (frame_poi), vbox_poi);
+
+ /* Checkbox: POI Draw */
+ if (usesql)
+ {
+ poi_draw_bt = gtk_check_button_new_with_label (_("POI"));
+ if (local_config.showpoi)
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (poi_draw_bt), TRUE);
+ }
+ gtk_box_pack_start (GTK_BOX (vbox_poi),
+ poi_draw_bt, FALSE, FALSE, 0 * PADDING);
+ g_signal_connect (GTK_OBJECT (poi_draw_bt), "clicked",
+ GTK_SIGNAL_FUNC (toggle_button_cb),
+ &local_config.showpoi);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (main_tooltips), poi_draw_bt,
+ _("Show Points Of Interest found in Database"), NULL);
+ }
+
+ /* Checkbox: WLAN Draw */
+ wlan_draw_bt = gtk_check_button_new_with_label (_("WLAN"));
+ if (local_config.showwlan)
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (wlan_draw_bt), TRUE);
+ }
+ if (usesql)
+ {
+ gtk_box_pack_start (GTK_BOX (vbox_poi),
+ wlan_draw_bt, FALSE, FALSE, 0 * PADDING);
+ }
+ g_signal_connect (GTK_OBJECT (wlan_draw_bt), "clicked",
+ GTK_SIGNAL_FUNC (toggle_button_cb),
+ &local_config.showwlan);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (main_tooltips), wlan_draw_bt,
+ _("Show Data found in Kismet Database"), NULL);
+
+ /* Checkbox: Draw Waypoints from file */
+ wp_draw_bt = gtk_check_button_new_with_label (_("WP"));
+ if (local_config.showwaypoints)
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (wp_draw_bt), TRUE);
+ g_signal_connect (GTK_OBJECT (wp_draw_bt), "clicked",
+ GTK_SIGNAL_FUNC (toggle_button_cb),
+ &local_config.showwaypoints);
+ gtk_box_pack_start (GTK_BOX (vbox_poi), wp_draw_bt,
+ FALSE, FALSE, 0 * PADDING);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (main_tooltips), wlan_draw_bt,
+ _("Show Waypoints found in way.txt file"), NULL);
+
+ } /* END WAYPOINTS AND POIs */
+
+ /* TRACKS */
+ {
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_controls_mainbox(Bottons: TRACKS)\n");
+ frame_track = gtk_frame_new (_("Track"));
+ vbox_track = gtk_vbox_new (TRUE, 1 * PADDING);
+ gtk_container_add (GTK_CONTAINER (frame_track), vbox_track);
+
+ /* Checkbox: Show Track */
+ showtrack_bt = gtk_check_button_new_with_label (_("Show"));
+ if (local_config.showtrack)
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (showtrack_bt), TRUE);
+ }
+ g_signal_connect (GTK_OBJECT (showtrack_bt), "clicked",
+ GTK_SIGNAL_FUNC (toggle_button_cb), &local_config.showtrack);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (main_tooltips), showtrack_bt,
+ _("Show tracking on the map"), NULL);
+ gtk_box_pack_start (GTK_BOX (vbox_track), showtrack_bt,
+ FALSE, FALSE, 0 * PADDING);
+
+ /* Checkbox: Save Track */
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_controls_mainbox(Bottons: Save Track)\n");
+ savetrack_bt = gtk_check_button_new_with_label (_("Save"));
+ if (local_config.savetrack)
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (savetrack_bt), TRUE);
+ g_signal_connect (GTK_OBJECT (savetrack_bt), "clicked",
+ GTK_SIGNAL_FUNC (toggle_button_cb), &local_config.savetrack);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (main_tooltips), savetrack_bt,
+ _("Save the track to given filename at program exit"),
+ NULL);
+ gtk_box_pack_start (GTK_BOX (vbox_track), savetrack_bt,
+ FALSE, FALSE,0 * PADDING);
+ } /* END TRACKS */
+
+ /* MAP CONTROL */
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_controls_mainbox(Bottons: MAP CONTROL)\n");
+ {
+ frame_mapcontrol = make_display_map_controls ();
+ } /* END MAP CONTROL */
+
+ /* MAP TYPE */
+ {
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_controls_mainbox(Bottons: MAP TYPE)\n");
+ frame_maptype = make_display_map_checkboxes();
+ } /* END MAP TYPE */
+
+
+ if (local_config.guimode == GUI_PDA)
+ {
+ mainbox_controls = gtk_hbox_new (TRUE, 0 * PADDING);
+
+ pda_box_left = gtk_vbox_new (FALSE, 1 * PADDING);
+ pda_box_right = gtk_vbox_new (FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_controls), pda_box_left, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (mainbox_controls), pda_box_right, TRUE, TRUE, 0);
+
+ gtk_box_pack_start (GTK_BOX (pda_box_left), vbox_buttons, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (pda_box_left), frame_poi, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (pda_box_left), frame_track, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (pda_box_right),frame_mapcontrol, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (pda_box_right),frame_maptype, TRUE, TRUE, 1 * PADDING);
+ }
+ else
+ if (local_config.guimode == GUI_CAR)
+ {
+ mainbox_controls = gtk_vbox_new (FALSE, 0 * PADDING);
+
+ gtk_box_pack_start (GTK_BOX (mainbox_controls),vbox_buttons, FALSE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_controls),frame_poi, FALSE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_controls),frame_track, FALSE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_controls),frame_mapcontrol, FALSE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_controls),frame_maptype, TRUE, TRUE, 1 * PADDING);
+ }
+ else
+ {
+ mainbox_controls = gtk_vbox_new (FALSE, 0 * PADDING);
+
+ gtk_box_pack_start (GTK_BOX (mainbox_controls), vbox_buttons, FALSE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_controls), frame_poi, FALSE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_controls), frame_track, FALSE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_controls), frame_mapcontrol, FALSE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_controls), frame_maptype, TRUE, TRUE, 1 * PADDING);
+ }
+
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_controls_mainbox: END\n");
+}
+
+
+/* *****************************************************************************
+ * Window: Main -> Status
+ */
+void create_status_mainbox (void)
+{
+
+ GtkWidget *statusdashboard_box;
+ GtkWidget *statusdashsub1_box, *statusdashsub2_box;
+ GtkWidget *statussmall_box, *frame_statustime;
+ GtkWidget *frame_statusbearing, *frame_statusheading;
+ GtkWidget *frame_statuslat, *frame_statuslon;
+ GtkWidget *eventbox_statuslat, *eventbox_statuslon;
+ GtkWidget *frame_statusmapscale, *frame_statusprefscale;
+ GtkWidget *statusbar_box, *frame_statusgpsfix;
+ GtkWidget *dashboard_1_lb, *dashboard_2_lb;
+ GtkWidget *dashboard_3_lb, *dashboard_4_lb;
+ GtkWidget *frame_compass, *frame_minimap;
+
+ gchar sc[15];
+ gint scaler_pos= 0;
+ gint scale = 0;
+
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_status_mainbox\n");
+
+ mainbox_status = gtk_vbox_new (FALSE, 0 * PADDING);
+
+
+ /* DASHBOARD */
+ {
+ /* Frame Mini Map */
+ frame_minimap = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type
+ (GTK_FRAME (frame_minimap), GTK_SHADOW_NONE);
+ drawing_minimap = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (drawing_minimap, 128, 103);
+ g_signal_connect (drawing_minimap, "expose_event",
+ GTK_SIGNAL_FUNC (expose_mini_cb), NULL);
+ gtk_widget_add_events (GTK_WIDGET (drawing_minimap),
+ GDK_BUTTON_PRESS_MASK);
+ g_signal_connect_swapped (drawing_minimap,
+ "button-press-event",
+ GTK_SIGNAL_FUNC (minimapclick_cb),
+ GTK_OBJECT (drawing_minimap));
+ gtk_container_add (GTK_CONTAINER (frame_minimap),
+ drawing_minimap);
+ drawable_minimap = drawing_minimap->window;
+
+ /* Frame Compass */
+ frame_compass = gtk_frame_new (NULL);
+ drawing_compass = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (drawing_compass, 100, 100);
+ gtk_container_add (GTK_CONTAINER (frame_compass),
+ drawing_compass);
+ g_signal_connect (GTK_OBJECT (drawing_compass),
+ "expose_event", GTK_SIGNAL_FUNC (expose_compass),
+ NULL);
+
+ /* Frame Dashboard 1 */
+ frame_dash_1 = gtk_frame_new (" = 1 = ");
+ dashboard_1_lb = gtk_label_new ("---");
+ gtk_container_add (GTK_CONTAINER (frame_dash_1),
+ dashboard_1_lb);
+
+ /* Frame Dashboard 2 */
+ frame_dash_2 = gtk_frame_new (" = 2 = ");
+ dashboard_2_lb = gtk_label_new ("---");
+ gtk_container_add (GTK_CONTAINER (frame_dash_2),
+ dashboard_2_lb);
+
+ /* Frame_Dashboard 3 */
+ frame_dash_3 = gtk_frame_new (" = 3 = ");
+ dashboard_3_lb = gtk_label_new ("---");
+ gtk_container_add (GTK_CONTAINER (frame_dash_3),
+ dashboard_3_lb);
+
+ /* Frame_Dashboard 4 */
+ frame_dash_4 = gtk_frame_new (" = 4 = ");
+ dashboard_4_lb = gtk_label_new ("---");
+ gtk_container_add (GTK_CONTAINER (frame_dash_4),
+ dashboard_4_lb);
+
+ } /* END DASHBOARD */
+
+
+ /* SMALL STATUS TEXT */
+ {
+ /* Time */
+ frame_statustime = gtk_frame_new (_("GPS-Time"));
+ statustime_lb = gtk_label_new ("00:00");
+ gtk_container_add (GTK_CONTAINER (frame_statustime),
+ statustime_lb);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (main_tooltips),
+ frame_statustime,
+ _("This shows the time from your GPS receiver"), NULL);
+
+ /* Friends */
+ frame_statusfriends = gtk_frame_new (_("Friends"));
+ statusfriends_lb = gtk_label_new ("0/0");
+ gtk_container_add (GTK_CONTAINER (frame_statusfriends),
+ statusfriends_lb);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (main_tooltips),
+ frame_statusfriends,
+ _("Number of mobile targets within timeframe/total"
+ " received from friendsserver"), NULL);
+
+ /* Bearing */
+ frame_statusbearing = gtk_frame_new (_("Bearing"));
+ statusbearing_lb = gtk_label_new ("0000");
+ gtk_container_add (GTK_CONTAINER (frame_statusbearing),
+ statusbearing_lb);
+
+ /* Heading */
+ frame_statusheading = gtk_frame_new (_("Heading"));
+ statusheading_lb = gtk_label_new ("0000");
+ gtk_container_add (GTK_CONTAINER (frame_statusheading),
+ statusheading_lb);
+
+ /* Latitude */
+ frame_statuslat = gtk_frame_new (_("Latitude"));
+ statuslat_lb = gtk_label_new ("00,00000N");
+ eventbox_statuslat = gtk_event_box_new ();
+ gtk_widget_add_events (eventbox_statuslat,
+ GDK_BUTTON_PRESS_MASK);
+ g_signal_connect (eventbox_statuslat, "button_press_event",
+ GTK_SIGNAL_FUNC (toggle_coords_cb), NULL);
+ gtk_container_add (GTK_CONTAINER (eventbox_statuslat),
+ statuslat_lb);
+ gtk_container_add (GTK_CONTAINER (frame_statuslat),
+ eventbox_statuslat);
+
+ /* Longitude */
+ frame_statuslon = gtk_frame_new (_("Longitude"));
+ statuslon_lb = gtk_label_new ("000,00000E");
+ eventbox_statuslon = gtk_event_box_new ();
+ gtk_widget_add_events (eventbox_statuslon,
+ GDK_BUTTON_PRESS_MASK);
+ g_signal_connect (eventbox_statuslon, "button_press_event",
+ GTK_SIGNAL_FUNC (toggle_coords_cb), NULL);
+ gtk_container_add (GTK_CONTAINER (eventbox_statuslon),
+ statuslon_lb);
+ gtk_container_add (GTK_CONTAINER (frame_statuslon),
+ eventbox_statuslon);
+
+ /* Map Scale */
+ frame_statusmapscale = gtk_frame_new (_("Map scale"));
+ statusmapscale_lb = gtk_label_new ("---");
+ gtk_container_add (GTK_CONTAINER (frame_statusmapscale),
+ statusmapscale_lb);
+
+ /* Preferred Scale */
+ frame_statusprefscale = gtk_frame_new (_("Pref. scale"));
+ g_snprintf (sc, sizeof (sc), "1:%d", local_config.scale_wanted);
+ statusprefscale_lb = gtk_label_new (sc);
+ gtk_container_add (GTK_CONTAINER (frame_statusprefscale),
+ statusprefscale_lb);
+
+ /* GPS Fix Status */
+ frame_statusgpsfix = gtk_frame_new (_("GPS Status"));
+ drawing_gpsfix = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (drawing_gpsfix,
+ 100, -1);
+ gtk_container_add (GTK_CONTAINER (frame_statusgpsfix),
+ drawing_gpsfix);
+ g_signal_connect (GTK_OBJECT (drawing_gpsfix),
+ "expose_event", GTK_SIGNAL_FUNC (expose_gpsfix),
+ NULL);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (main_tooltips),
+ frame_statusgpsfix,
+ _("This shows the GPS Status and Number of satellites"
+ " in use."), NULL);
+ } /* SMALL STATUS TEXT */
+
+
+ /* STATUS BAR AND SCALE SLIDER */
+ {
+ /* Status Bar */
+ frame_statusbar = gtk_statusbar_new ();
+ gtk_statusbar_set_has_resize_grip
+ (GTK_STATUSBAR (frame_statusbar), FALSE);
+ current.statusbar_id = gtk_statusbar_get_context_id
+ (GTK_STATUSBAR (frame_statusbar), "main");
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar),
+ current.statusbar_id,
+ _("GpsDrive (c)2001-2007 F. Ganter"));
+
+ /* Map Scale Slider */
+ /* search which scaler_pos is fitting scale_wanted */
+ while ( (local_config.scale_wanted > scale )
+ && (scaler_pos <= slistsize ) )
+ {
+ scaler_pos++;
+ scale = nlist[(gint) rint (scaler_pos)];
+ }
+ mapscaler_adj = gtk_adjustment_new
+ (scaler_pos, 0, slistsize - 1, 1,
+ slistsize / 4, 1 / slistsize );
+ mapscaler_scaler = gtk_hscale_new
+ (GTK_ADJUSTMENT (mapscaler_adj));
+ g_signal_connect (GTK_OBJECT (mapscaler_adj), "value_changed",
+ GTK_SIGNAL_FUNC (scaler_cb), NULL);
+ gtk_scale_set_draw_value (GTK_SCALE (mapscaler_scaler), FALSE);
+ } /* END STATUS BAR AND SCALE SLIDER */
+
+ /* Pack all the widgets together according to GUI-Mode */
+ if (local_config.guimode == GUI_PDA)
+ {
+ statusdashboard_box = gtk_table_new (2, 2, TRUE);
+ gtk_table_attach_defaults (GTK_TABLE (statusdashboard_box), frame_dash_1, 0, 1, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (statusdashboard_box), frame_dash_2, 1, 2, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (statusdashboard_box), frame_dash_3, 0, 1, 1, 2);
+ gtk_table_attach_defaults (GTK_TABLE (statusdashboard_box), frame_dash_4, 1, 2, 1, 2);
+
+ statussmall_box = gtk_vbox_new (FALSE, PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statuslat, FALSE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statuslon, FALSE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statusgpsfix, TRUE, TRUE, 1 * PADDING);
+
+ statusbar_box = gtk_hbox_new (TRUE, PADDING);
+ gtk_box_pack_start (GTK_BOX (statusbar_box), frame_compass, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statusbar_box), statussmall_box, TRUE, TRUE, 1 * PADDING);
+
+ gtk_box_pack_start (GTK_BOX (mainbox_status), statusdashboard_box, TRUE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_status), statusbar_box, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_status), frame_statusbar, TRUE, FALSE, 1* PADDING);
+ }
+ else
+ if (local_config.guimode == GUI_CAR)
+ {
+ statusdashboard_box = gtk_hbox_new (FALSE, PADDING);
+ statusdashsub1_box = gtk_hbox_new (FALSE, PADDING);
+ statusdashsub2_box = gtk_hbox_new (TRUE, PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_controls), frame_compass, FALSE, FALSE, 1 * PADDING);
+ // gtk_box_pack_start (GTK_BOX (mainbox_controls), frame_minimap, FALSE, FALSE, 1 * PADDING);
+
+ gtk_box_pack_start (GTK_BOX (statusdashsub2_box), frame_dash_1, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statusdashsub2_box), frame_dash_2, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statusdashsub2_box), frame_dash_3, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statusdashboard_box), statusdashsub1_box, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (statusdashboard_box), statusdashsub2_box, TRUE, TRUE, 0);
+
+ // --- ACPI / Temperature / Battery
+ create_temperature_widget(statusdashboard_box);
+ create_battery_widget(statusdashboard_box);
+
+ statussmall_box = gtk_hbox_new (FALSE, PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statustime, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statusfriends, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statusbearing, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statusheading, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statuslat, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statuslon, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statusmapscale, TRUE, TRUE, 1 * PADDING);
+ //gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statusprefscale, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statusgpsfix, TRUE, TRUE, 1 * PADDING);
+
+ statusbar_box = gtk_hbox_new (FALSE, PADDING);
+ gtk_box_pack_start (GTK_BOX (statusbar_box), frame_statusbar, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statusbar_box), mapscaler_scaler, TRUE, TRUE, 1 * PADDING);
+
+ gtk_box_pack_start (GTK_BOX (mainbox_status), statusdashboard_box, TRUE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_status), statussmall_box, TRUE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_status), statusbar_box, TRUE, FALSE, 1 * PADDING);
+ } else
+ {
+ statusdashboard_box = gtk_hbox_new (FALSE, PADDING);
+ statusdashsub1_box = gtk_hbox_new (FALSE, PADDING);
+ statusdashsub2_box = gtk_hbox_new (TRUE, PADDING);
+ gtk_box_pack_start (GTK_BOX (statusdashsub1_box),frame_minimap, FALSE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statusdashsub1_box),frame_compass, FALSE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statusdashsub2_box),frame_dash_1, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statusdashsub2_box),frame_dash_2, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statusdashsub2_box),frame_dash_3, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statusdashboard_box),statusdashsub1_box, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (statusdashboard_box),statusdashsub2_box, TRUE, TRUE, 0);
+
+
+ // --- ACPI / Temperature / Battery
+ create_temperature_widget(statusdashboard_box);
+ create_battery_widget(statusdashboard_box);
+
+ statussmall_box = gtk_hbox_new (FALSE, PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statustime, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statusfriends, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statusbearing, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statusheading, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statuslat, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statuslon, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statusmapscale, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statusprefscale, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statussmall_box), frame_statusgpsfix, TRUE, TRUE, 1 * PADDING);
+
+ statusbar_box = gtk_hbox_new (FALSE, PADDING);
+ gtk_box_pack_start (GTK_BOX (statusbar_box), frame_statusbar, TRUE, TRUE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (statusbar_box), mapscaler_scaler, TRUE, TRUE, 1 * PADDING);
+
+ gtk_box_pack_start (GTK_BOX (mainbox_status),statusdashboard_box, TRUE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_status),statussmall_box, TRUE, FALSE, 1 * PADDING);
+ gtk_box_pack_start (GTK_BOX (mainbox_status),statusbar_box, TRUE, FALSE, 1 * PADDING);
+ }
+}
+
+
+/* *****************************************************************************
+ * Window: Main -> Map
+ */
+void create_map_mainbox (void)
+{
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_map_mainbox\n");
+
+ mainframe_map = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (mainframe_map), GTK_SHADOW_IN);
+ map_drawingarea = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (map_drawingarea, SCREEN_X, SCREEN_Y);
+ gtk_container_add (GTK_CONTAINER (mainframe_map), map_drawingarea);
+
+ gtk_widget_add_events (GTK_WIDGET (map_drawingarea),
+ GDK_BUTTON_PRESS_MASK);
+ g_signal_connect_swapped (GTK_OBJECT (map_drawingarea),
+ "button-press-event", GTK_SIGNAL_FUNC (mapclick_cb),
+ GTK_OBJECT (map_drawingarea));
+ g_signal_connect_swapped (GTK_OBJECT (map_drawingarea),
+ "scroll_event", GTK_SIGNAL_FUNC (mapscroll_cb),
+ GTK_OBJECT (map_drawingarea));
+}
+
+
+/* *****************************************************************************
+ * Window: Main
+ */
+gint create_main_window (gchar *geom, gint *usegeom)
+{
+ gchar main_title[100];
+ GdkPixbuf *mainwindow_icon_pixbuf;
+
+ if ( mydebug > 11 )
+ fprintf(stderr,"create_main_window\n");
+
+ main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+ g_snprintf (main_title, sizeof (main_title),
+ "%s v%s", "GpsDrive", VERSION);
+
+ gtk_window_set_title (GTK_WINDOW (main_window), main_title);
+ gtk_container_set_border_width (GTK_CONTAINER (main_window), 0);
+ gtk_window_set_position (GTK_WINDOW (main_window),
+ GTK_WIN_POS_CENTER);
+ g_signal_connect (GTK_OBJECT (main_window), "delete_event",
+ GTK_SIGNAL_FUNC (quit_program_cb), NULL);
+ g_signal_connect (GTK_OBJECT (main_window), "key_press_event",
+ GTK_SIGNAL_FUNC (key_pressed_cb), NULL);
+
+ mainwindow_icon_pixbuf = read_icon ("gpsicon.png",1);
+ if (mainwindow_icon_pixbuf)
+ {
+ gtk_window_set_icon (GTK_WINDOW (main_window),
+ mainwindow_icon_pixbuf);
+ gdk_pixbuf_unref (mainwindow_icon_pixbuf);
+ }
+
+ main_tooltips = gtk_tooltips_new();
+
+ /* Create the three parts of the main window */
+ create_controls_mainbox ();
+ create_status_mainbox ();
+ create_map_mainbox ();
+
+ if (local_config.guimode == GUI_PDA)
+ { /* PDA Mode */
+ GtkWidget *map_lb, *controls_lb, *status_lb;
+
+ main_table = gtk_notebook_new ();
+
+ map_lb = gtk_label_new (_("Map"));
+ gtk_notebook_append_page (GTK_NOTEBOOK (main_table),
+ mainframe_map, map_lb);
+ controls_lb = gtk_label_new (_("Controls"));
+ gtk_notebook_append_page (GTK_NOTEBOOK (main_table),
+ mainbox_controls, controls_lb);
+ status_lb = gtk_label_new (_("Status"));
+ gtk_notebook_append_page (GTK_NOTEBOOK (main_table),
+ mainbox_status, status_lb);
+ gtk_container_add (GTK_CONTAINER (main_window), main_table);
+ }
+ else if (local_config.guimode == GUI_XWIN)
+ { /* X-Win Mode (separate windows) */
+ // TODO: ...
+ }
+ else
+ { /* Classic Mode (Standard) */
+ main_table = gtk_table_new (4, 2, FALSE);
+ gtk_table_attach_defaults (GTK_TABLE (main_table),
+ mainbox_controls, 0, 1, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (main_table),
+ mainframe_map, 1, 2, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (main_table),
+ mainbox_status, 0, 2, 2, 3);
+ gtk_container_add (GTK_CONTAINER (main_window), main_table);
+
+ }
+
+ gtk_widget_show_all (main_window);
+
+ //if ( ( local_config.guimode == GUI_DESKTOP )
+ if( (local_config.MapnikStatusInt ) ){
+ toggle_mapnik_cb( mapnik_bt, 2 );
+ }
+
+ if ( !local_config.showfriends)
+ gtk_widget_hide_all (frame_statusfriends);
+
+ return 0;
+}
+
diff --git a/src/main_gui.h b/src/main_gui.h
new file mode 100644
index 0000000..2740074
--- /dev/null
+++ b/src/main_gui.h
@@ -0,0 +1,50 @@
+/***********************************************************************
+
+Copyright (c) 2001-2006 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ *********************************************************************
+
+***********************************************************************/
+
+#ifndef GPSDRIVE_MAIN_GUI_H
+#define GPSDRIVE_MAIN_GUI_H
+
+/* Definitions for the dashboard */
+enum
+{
+ DASH_DIST,
+ DASH_TIMEREMAIN,
+ DASH_BEARING,
+ DASH_TURN,
+ DASH_SPEED,
+ DASH_HEADING,
+ DASH_ALT,
+ DASH_TRIP,
+ DASH_GPSPRECISION,
+ DASH_TIME,
+};
+
+gint create_main_window (gchar *geom, gint *usegeom);
+gint autobestmap_cb (GtkWidget *widget, guint datum);
+gint update_statusdisplay (void);
+gint expose_gpsfix (GtkWidget *widget, guint *datum);
+
+#endif /* GPSDRIVE_MAIN_GUI_H */
diff --git a/src/map_handler.c b/src/map_handler.c
new file mode 100644
index 0000000..5129c6f
--- /dev/null
+++ b/src/map_handler.c
@@ -0,0 +1,1052 @@
+/***********************************************************************
+ *
+ * Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+ *
+ * Website: www.gpsdrive.de
+ *
+ * Disclaimer: Please do not use for navigation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ **********************************************************************
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <math.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gpsdrive.h>
+#include <config.h>
+#include <math.h>
+#include "gpsdrive.h"
+#include "speech_out.h"
+#include "speech_strings.h"
+#include "gui.h"
+#include "gpsdrive_config.h"
+#include "routes.h"
+#include "mapnik.h"
+#include "main_gui.h"
+
+/* variables */
+extern gint ignorechecksum, mydebug, debug;
+extern gint real_screen_x, real_screen_y;
+extern gint real_psize, real_smallmenu;
+extern gint SCREEN_X_2, SCREEN_Y_2;
+extern gdouble pixelfact, posx, posy;
+extern gint havepos, haveposcount, blink, gblink, xoff, yoff;
+extern gdouble trip_lat, trip_lon;
+extern gdouble milesconv;
+extern gint nrmaps;
+extern gint maploaded;
+extern gint debug, mydebug;
+extern gint usesql;
+extern gint selected_wp_mode;
+extern gint iszoomed;
+extern gchar oldangle[100];
+extern gdouble new_dl_lat,new_dl_lon;
+extern gint new_dl_scale;
+extern color_struct colors;
+extern coordinate_struct coords;
+extern routestatus_struct route;
+wpstruct *routelist;
+extern gint thisrouteline;
+extern gint gcount, milesflag, downloadwindowactive;
+extern GtkWidget *drawing_minimap;
+extern GtkWidget *bestmap_bt, *poi_draw_bt;
+extern GtkWidget *posbt, *mapnik_bt;
+extern currentstatus_struct current;
+
+extern gchar oldfilename[2048];
+
+extern gint borderlimit;
+
+gchar mapfilename[2048];
+extern gint saytarget;
+
+extern int havedefaultmap;
+
+extern GdkPixbuf *image, *tempimage, *pixbuf_minimap;
+extern GtkWidget *mapscaler_scaler;
+extern GtkWidget *scaler_left_bt, *scaler_right_bt;
+extern GtkObject *mapscaler_adj;
+extern GdkGC *kontext_map;
+
+#include "gettext.h"
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+
+enum map_projections map_projection (char *filename);
+
+
+mapsstruct *maps = NULL;
+gint message_wrong_maps_shown = FALSE;
+time_t maptxtstamp = 0;
+gint needreloadmapconfig = FALSE;
+int havenasa = -1;
+
+GtkWidget *maptogglebt, *topotogglebt;
+
+
+gint max_display_map = 0;
+map_dir_struct *display_map;
+gint displaymap_top = TRUE;
+gint displaymap_map = TRUE;
+
+
+/* *****************************************************************************
+ */
+gint
+maptoggle_cb (GtkWidget * widget, guint datum)
+{
+ displaymap_map = !displaymap_map;
+ if (displaymap_map)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (maptogglebt), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (maptogglebt), FALSE);
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* *****************************************************************************
+ */
+gint
+topotoggle_cb (GtkWidget * widget, guint datum)
+{
+ displaymap_top = !displaymap_top;
+ if (displaymap_top)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (topotogglebt), TRUE);
+ else
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (topotogglebt), FALSE);
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* *****************************************************************************
+ */
+gint
+display_maps_cb (GtkWidget * widget, guint datum)
+{
+ if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON (display_map[datum].checkbox)))
+ display_map[datum].to_be_displayed = TRUE;
+ else
+ display_map[datum].to_be_displayed = FALSE;
+
+ int i;
+ for (i = 0; i < max_display_map; i++)
+ {
+ char tbd = display_map[i].to_be_displayed ? 'D' : '_';
+ printf ("Found %s,%c\n", display_map[i].name, tbd);
+ }
+
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* ******************************************************************
+ */
+GtkWidget *
+make_display_map_controls ()
+{
+ if ( mydebug > 11 )
+ fprintf(stderr,"make_display_map_controls()\n");
+ GtkWidget *frame_maptype;
+ GtkWidget *vbox_map_controls;
+ GtkTooltips *tooltips;
+ tooltips = gtk_tooltips_new ();
+
+ // Frame
+ frame_maptype = gtk_frame_new (_("Map Controls"));
+ vbox_map_controls = gtk_vbox_new (TRUE, 1 * PADDING);
+ gtk_container_add (GTK_CONTAINER (frame_maptype), vbox_map_controls);
+
+ // Checkbox ---- Best Map
+ bestmap_bt = gtk_check_button_new_with_label (_("Auto _best map"));
+ gtk_button_set_use_underline (GTK_BUTTON (bestmap_bt), TRUE);
+ gtk_box_pack_start (GTK_BOX (vbox_map_controls),
+ bestmap_bt, FALSE, FALSE,0 * PADDING);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (tooltips), bestmap_bt,
+ _("Always select the most detailed map available"), NULL);
+
+ if (local_config.autobestmap)
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (bestmap_bt), TRUE);
+ }
+ gtk_signal_connect (GTK_OBJECT (bestmap_bt), "clicked",
+ GTK_SIGNAL_FUNC (autobestmap_cb), (gpointer) 1);
+
+ // Checkbox ---- Pos Mode
+ posbt = gtk_check_button_new_with_label (_("Pos. _mode"));
+ gtk_button_set_use_underline (GTK_BUTTON (posbt), TRUE);
+ gtk_signal_connect (GTK_OBJECT (posbt),
+ "clicked", GTK_SIGNAL_FUNC (pos_cb), (gpointer) 1);
+ gtk_box_pack_start
+ (GTK_BOX (vbox_map_controls), posbt, FALSE, FALSE,0 * PADDING);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (tooltips), posbt,
+ _("Turn position mode on. You can move on the map with the "
+ "left mouse button click. Clicking near the border switches "
+ "to the proximate map."), NULL);
+
+#ifdef MAPNIK
+ if (active_mapnik_ysn()) {
+ // Checkbox ---- Mapnik Mode
+ if ( mydebug > 11 )
+ fprintf(stderr,"make_display_map_controls(Checkbox ---- Mapnik Mode)\n");
+
+ mapnik_bt = gtk_check_button_new_with_label (_("Mapnik Mode"));
+ gtk_button_set_use_underline (GTK_BUTTON (mapnik_bt), TRUE);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (tooltips), mapnik_bt,
+ _("Turn mapnik mode on. In this mode vector maps rendered by "
+ "mapnik (e.g. OpenStreetMap Data) are used instead of the "
+ "other maps."), NULL);
+ g_signal_connect (GTK_OBJECT (mapnik_bt), "clicked",
+ GTK_SIGNAL_FUNC (toggle_mapnik_cb), (gpointer) 1);
+ gtk_box_pack_start(GTK_BOX (vbox_map_controls), mapnik_bt, FALSE, FALSE,0 * PADDING);
+ }
+#endif
+
+ if ( mydebug > 11 )
+ fprintf(stderr,"make_display_map_controls(DONE)\n");
+ return frame_maptype;
+}
+
+/* ******************************************************************
+ */
+GtkWidget *
+make_display_map_checkboxes()
+{
+ GtkWidget *frame_maptype;
+ GtkWidget *vbox3;
+ GtkTooltips *tooltips;
+
+ // Frame
+ frame_maptype = gtk_frame_new (_("Shown map type"));
+ vbox3 = gtk_vbox_new (FALSE, 1 * PADDING);
+ gtk_container_add (GTK_CONTAINER (frame_maptype), vbox3);
+
+ if (0)
+ {
+ // Checkbox ---- Show Map: map_
+ maptogglebt = gtk_check_button_new_with_label (_("Street map"));
+ if (displaymap_map)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (maptogglebt), TRUE);
+ gtk_signal_connect (GTK_OBJECT (maptogglebt),
+ "clicked", GTK_SIGNAL_FUNC (maptoggle_cb),
+ (gpointer) 1);
+ gtk_box_pack_start (GTK_BOX (vbox3), maptogglebt, FALSE, FALSE,
+ 0 * PADDING);
+
+ // Checkbox ---- Show Map: top_
+ topotogglebt = gtk_check_button_new_with_label (_("Topo map"));
+ if (displaymap_top)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (topotogglebt), TRUE);
+
+ gtk_signal_connect (GTK_OBJECT (topotogglebt),
+ "clicked", GTK_SIGNAL_FUNC (topotoggle_cb),
+ (gpointer) 1);
+
+ gtk_box_pack_start (GTK_BOX (vbox3), topotogglebt, FALSE, FALSE,
+ 0 * PADDING);
+
+ }
+
+ tooltips = gtk_tooltips_new ();
+ glong i;
+ for (i = 0; i < max_display_map; i++)
+ {
+ // Checkbox ---- Show Map: name xy
+ gchar display_name[100];
+
+
+ if (mydebug > 1)
+ g_snprintf (display_name, sizeof (display_name), "%s (%d)",
+ _(display_map[i].name), display_map[i].count);
+ else
+ g_snprintf (display_name, sizeof (display_name), "%s",
+ _(display_map[i].name));
+
+
+ display_map[i].count++;
+
+ display_map[i].checkbox
+ = gtk_check_button_new_with_label (display_name);
+
+ if (display_map[i].to_be_displayed)
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
+ (display_map[i].checkbox), TRUE);
+
+ gtk_signal_connect (GTK_OBJECT (display_map[i].checkbox),
+ "clicked", GTK_SIGNAL_FUNC (display_maps_cb),
+ (gpointer) i);
+
+ gtk_box_pack_start (GTK_BOX (vbox3), display_map[i].checkbox, FALSE,
+ FALSE, 0 * PADDING);
+ }
+
+ return frame_maptype;
+}
+
+/* ******************************************************************
+ * extract the directory part of the File and then
+ * add it to the display_map[] structure
+ * returns the index of the display_map[] structure
+ */
+int
+add_map_dir (gchar * filename)
+{
+
+ gint i;
+
+ /* memorize map dir names */
+ if (mydebug > 99)
+ fprintf (stderr, "add_map_dir(%s)\n", filename);
+
+ gchar map_dir[200];
+
+ g_strlcpy (map_dir, filename, sizeof (map_dir));
+ char *slash_pos = strstr (map_dir, "/");
+ if (slash_pos)
+ slash_pos[0] = '\0';
+ else
+ g_strlcpy (map_dir, "no_dir", sizeof (map_dir));
+
+ for (i = 0; i < max_display_map; i++)
+ {
+ if (!strcmp (display_map[i].name, map_dir))
+ {
+ display_map[i].count++;
+ //printf("Found %s,%s\n",display_map[i].name,map_dir);
+ return i;
+ }
+ }
+ if (i >= max_display_map)
+ {
+ max_display_map += 1;
+ display_map = g_renew (map_dir_struct, display_map, max_display_map);
+ }
+ g_strlcpy (display_map[i].name, map_dir, sizeof (display_map[i].name));
+ display_map[i].to_be_displayed = TRUE;
+ display_map[i].count++;
+ return i;
+}
+
+/* *****************************************************************************
+ * map_koord.txt is in mappath!
+ */
+void
+test_loaded_map_names ()
+{
+ gint i;
+ for (i = 0; i < nrmaps; i++)
+ {
+ if (proj_undef == map_projection ((maps + i)->filename))
+ {
+ GString *error;
+ error = g_string_new (NULL);
+ g_string_printf (error, "%s%d\n%s\n",
+ _("Error in line "), i + 1,
+ _
+ ("I have found filenames in map_koord.txt which are\n"
+ "not map_* or top_* files. Please rename them and change the entries in\n"
+ "map_koord.txt. Use map_* for street maps and top_* for topographical\n"
+ "maps. Otherwise, the maps will not be displayed!"));
+ popup_warning (NULL, error->str);
+ g_string_free (error, TRUE);
+ message_wrong_maps_shown = TRUE;
+ }
+ }
+}
+
+/* ******************************************************************
+ * Check if map_koord.txt needs to be reloaded an do if so
+ */
+void
+map_koord_check_and_reload ()
+{
+ gchar mappath[2048];
+ struct stat buf;
+
+ if (mydebug > 50)
+ fprintf (stderr, "map_koord_check_and_reload()\n");
+
+ /* Check for changed map_koord.txt and reload if changed */
+ g_strlcpy (mappath, local_config.dir_maps, sizeof (mappath));
+ g_strlcat (mappath, "map_koord.txt", sizeof (mappath));
+
+ stat (mappath, &buf);
+ if (buf.st_mtime != maptxtstamp)
+ {
+ needreloadmapconfig = TRUE;
+ }
+
+ if (needreloadmapconfig)
+ {
+ loadmapconfig ();
+ g_print ("%s reloaded\n", "map_koord.txt");
+ maptxtstamp = buf.st_mtime;
+ };
+}
+
+
+
+/* *****************************************************************************
+ * write the definitions of the map files
+ * Attention! program writes decimal point as set in locale
+ * i.eg 4.678 is in Germany 4,678 !!!
+ */
+void
+savemapconfig ()
+{
+ gchar mappath[2048];
+ FILE *st;
+ gint i;
+
+ if (local_config.dir_maps[strlen (local_config.dir_maps) - 1] != '/')
+ g_strlcat (local_config.dir_maps, "/", sizeof (local_config.dir_maps));
+
+ g_strlcpy (mappath, local_config.dir_maps, sizeof (mappath));
+ g_strlcat (mappath, "map_koord.txt", sizeof (mappath));
+ st = fopen (mappath, "w");
+ if (st == NULL)
+ {
+ perror (mappath);
+ exit (2);
+ }
+
+ for (i = 0; i < nrmaps; i++)
+ {
+ fprintf (st, "%s %.5f %.5f %ld\n", (maps + i)->filename,
+ (maps + i)->lat, (maps + i)->lon, (maps + i)->scale);
+ }
+
+ fclose (st);
+}
+
+/* *****************************************************************************
+ * load the definitions of the map files
+ */
+gint
+loadmapconfig ()
+{
+ gchar mappath[2048];
+ FILE *st;
+ gint i;
+ gint max_nrmaps = 1000;
+ gchar buf[1512], s1[40], s2[40], s3[40], filename[100], minlat[40], minlon[40], maxlat[40], maxlon[40];
+ gint p, e;
+
+ if (mydebug > 50)
+ fprintf (stderr, "loadmapconfig()\n");
+
+ init_nasa_mapfile ();
+ if (local_config.dir_maps[strlen (local_config.dir_maps) - 1] != '/')
+ g_strlcat (local_config.dir_maps, "/", sizeof (local_config.dir_maps));
+
+ g_strlcpy (mappath, local_config.dir_maps, sizeof (mappath));
+ g_strlcat (mappath, "map_koord.txt", sizeof (mappath));
+ st = fopen (mappath, "r");
+ if (st == NULL)
+ {
+ mkdir (local_config.dir_home, 0777);
+ st = fopen (mappath, "w+");
+ if (st == NULL)
+ {
+ perror (mappath);
+ return FALSE;
+ }
+ st = freopen (mappath, "r", st);
+ if (st == NULL)
+ {
+ perror (mappath);
+ return FALSE;
+ }
+
+ }
+ if (nrmaps > 0)
+ g_free (maps);
+
+ // Here I should reserve a little bit more than 1 map
+ maps = g_new (mapsstruct, max_nrmaps);
+ i = nrmaps = 0;
+ havenasa = -1;
+ while ((p = fgets (buf, 1512, st) != 0))
+ {
+ e = sscanf (buf, "%s %s %s %s %s %s %s %s", filename, s1, s2, s3, minlat, minlon, maxlat, maxlon);
+ if ((mydebug > 50) && !(nrmaps % 1000))
+ {
+ fprintf (stderr, "loadmapconfig(%d)\r", nrmaps);
+ }
+
+
+ if (e == 4 || e == 8)
+ {
+ /* already done in coordinate_string2 double
+ g_strdelimit (s1, ",", '.');
+ g_strdelimit (s2, ",", '.');
+ g_strdelimit (s3, ",", '.');
+ g_strdelimit (minlat, ",", ".")
+ g_strdelimit (minlon, ",", ".")
+ g_strdelimit (maxlat, ",", ".")
+ g_strdelimit (maxlon, ",", ".")
+ */
+
+ g_strlcpy ((maps + i)->filename, filename, 200);
+ (maps + i)->map_dir = add_map_dir (filename);
+ coordinate_string2gdouble (s1, &((maps + i)->lat));
+ coordinate_string2gdouble (s2, &((maps + i)->lon));
+
+ if (e == 8) {
+ (maps + i)->hasbbox = TRUE;
+ coordinate_string2gdouble(minlat, &((maps + i)->minlat));
+ coordinate_string2gdouble(minlon, &((maps + i)->minlon));
+ coordinate_string2gdouble(maxlat, &((maps + i)->maxlat));
+ coordinate_string2gdouble(maxlon, &((maps + i)->maxlon));
+ } else
+ (maps + i)->hasbbox = FALSE;
+
+ (maps + i)->scale = strtol (s3, NULL, 0);
+ i++;
+ nrmaps = i;
+ havenasa = -1;
+ if (nrmaps >= max_nrmaps)
+ {
+ max_nrmaps += 1000;
+ maps = g_renew (mapsstruct, maps, max_nrmaps);
+ }
+
+ }
+ else
+ {
+ fprintf (stderr, "Line not recognized\n");
+ }
+ }
+ fclose (st);
+
+ needreloadmapconfig = FALSE;
+ return FALSE;
+}
+
+
+/* ******************************************************************
+ *
+ */
+int
+create_nasa ()
+{
+ gint i, j;
+ gchar nasaname[255];
+ int nasaisvalid = FALSE;
+
+ if ((havenasa < 0) || (!nasaisvalid))
+ {
+ /* delete nasamaps entries from maps list */
+ for (i = 0; i < nrmaps; i++)
+ {
+ if ((strcmp ((maps + i)->filename, "top_NASA_IMAGE.ppm")) == 0)
+ {
+ for (j = i; j < (nrmaps - 1); j++)
+ *(maps + j) = *(maps + j + 1);
+ nrmaps--;
+ continue;
+ }
+ }
+
+ /* Try creating a nasamap and add it to the map list */
+ havenasa =
+ create_nasa_mapfile (coords.current_lat, coords.current_lon,
+ TRUE, nasaname);
+ if (havenasa > 0)
+ {
+ i = nrmaps;
+ nrmaps++;
+ maps = g_renew (mapsstruct, maps, (nrmaps + 2));
+ havenasa =
+ create_nasa_mapfile (coords.current_lat, coords.current_lon,
+ FALSE, nasaname);
+ (maps + i)->lat = coords.current_lat;
+ (maps + i)->lon = coords.current_lon;
+ (maps + i)->scale = havenasa;
+ g_strlcpy ((maps + i)->filename, nasaname, 200);
+ if ((strcmp (oldfilename, "top_NASA_IMAGE.ppm")) == 0)
+ g_strlcpy (oldfilename, "XXXOLDMAPXXX.ppm", sizeof (oldfilename));
+ }
+ }
+ return nasaisvalid;
+}
+
+/* ******************************************************************
+ * load the map with number bestmap
+ */
+
+void
+load_best_map (long long bestmap)
+{
+ if (bestmap != 9999999999LL)
+ {
+ g_strlcpy (mapfilename, (maps + bestmap)->filename,
+ sizeof (mapfilename));
+ if ((strcmp (oldfilename, mapfilename)) != 0)
+ {
+ g_strlcpy (oldfilename, mapfilename, sizeof (oldfilename));
+ if (debug)
+ g_print ("New map: %s\n", mapfilename);
+ pixelfact = (maps + bestmap)->scale / PIXELFACT;
+ coords.zero_lon = (maps + bestmap)->lon;
+ coords.zero_lat = (maps + bestmap)->lat;
+ current.mapscale = (maps + bestmap)->scale;
+ xoff = yoff = 0;
+ if (nrmaps > 0)
+ loadmap (mapfilename);
+ }
+ }
+ else
+ { // No apropriate map found take worldmap
+ if (((strcmp (oldfilename, mapfilename)) != 0) && (havedefaultmap))
+ {
+ g_strlcpy (oldfilename, mapfilename, sizeof (oldfilename));
+ g_strlcpy (mapfilename, "top_GPSWORLD.jpg", sizeof (mapfilename));
+ pixelfact = 88067900.43 / PIXELFACT;
+ coords.zero_lon = 0;
+ coords.zero_lat = 0;
+ current.mapscale = 88067900.43;
+ xoff = yoff = 0;
+ loadmap (mapfilename);
+ }
+ }
+
+}
+
+/* *****************************************************************************
+ * We load the map
+ * return TRUE on success
+ */
+int
+loadmap (char *filename)
+{
+ gchar mappath[2048];
+ GdkPixbuf *limage;
+ guchar *lpixels, *pixels;
+ int i, j, k;
+ static int print_loadmap_error = FALSE;
+
+ if (mydebug > 10)
+ fprintf (stderr, "loadmap(%s)\n", filename);
+
+ if (maploaded)
+ gdk_pixbuf_unref (image);
+
+ if ( !strcmp (filename,"mapnik") ) {
+ limage = gdk_pixbuf_new_from_data(get_mapnik_imagedata(), GDK_COLORSPACE_RGB, FALSE, 8, 1280, 1024, 1280 * 3, NULL, NULL);
+ } else {
+ limage = gdk_pixbuf_new_from_file (filename, NULL);
+ if (limage == NULL)
+ {
+ g_snprintf (mappath, sizeof (mappath), "data/maps/%s", filename);
+ limage = gdk_pixbuf_new_from_file (mappath, NULL);
+ }
+ if (limage == NULL)
+ {
+ g_snprintf (mappath, sizeof (mappath), "%s%s", local_config.dir_maps, filename);
+ limage = gdk_pixbuf_new_from_file (mappath, NULL);
+ }
+ if (limage == NULL)
+ {
+ g_snprintf (mappath, sizeof (mappath), "%s/gpsdrive/maps/%s", DATADIR,
+ filename);
+ limage = gdk_pixbuf_new_from_file (mappath, NULL);
+ }
+ if (limage == NULL)
+ {
+ g_snprintf (mappath, sizeof (mappath), "/usr/share/gpsdrive/maps/%s", filename);
+ limage = gdk_pixbuf_new_from_file (mappath, NULL);
+ }
+ }
+
+ map_proj = map_projection (filename);
+
+ if (limage == NULL)
+ havedefaultmap = FALSE;
+
+ if (limage == NULL) {
+ if (!print_loadmap_error) {
+ GString *error;
+ error = g_string_new (NULL);
+ g_string_sprintf (error, "%s\n%s\n",
+ _(" Mapfile could not be loaded:"), filename);
+ popup_warning (NULL, error->str);
+ g_string_free (error, TRUE);
+ maploaded = FALSE;
+ print_loadmap_error = TRUE;
+ }
+ return FALSE;
+ } else {
+ print_loadmap_error = FALSE;
+ }
+
+
+ if (!gdk_pixbuf_get_has_alpha (limage))
+ image = limage;
+ else
+ {
+ image = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 0, 8, 1280, 1024);
+ if (image == NULL)
+ {
+ fprintf (stderr,
+ "can't get image gdk_pixbuf_new (GDK_COLORSPACE_RGB, 0, 8, 1280, 1024)\n");
+ exit (1);
+ }
+ lpixels = gdk_pixbuf_get_pixels (limage);
+ pixels = gdk_pixbuf_get_pixels (image);
+ if (pixels == NULL)
+ {
+ fprintf (stderr,
+ "can't get pixels pixels = gdk_pixbuf_get_pixels (image);\n");
+ exit (1);
+ }
+ j = k = 0;
+ for (i = 0; i < (1280 * 1024); i++)
+ {
+ memcpy ((pixels + j), (lpixels + k), 3);
+ j += 3;
+ k += 4;
+ }
+ gdk_pixbuf_unref (limage);
+
+ }
+
+ expose_cb (NULL, NULL);
+ iszoomed = FALSE;
+ /* current.zoom = 1; */
+ xoff = yoff = 0;
+
+ rebuildtracklist ();
+
+ if (!maploaded)
+ display_status (_("Map found!"));
+
+ maploaded = TRUE;
+
+ /* draw minimap */
+ if (pixbuf_minimap)
+ gdk_pixbuf_unref (pixbuf_minimap);
+
+ pixbuf_minimap = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 0, 8, 128, 103);
+
+ gdk_pixbuf_scale (image, pixbuf_minimap, 0, 0, 128, 103,
+ 0, 0, 0.1, 0.10, GDK_INTERP_TILES);
+ expose_mini_cb (NULL, 0);
+
+ return TRUE;
+}
+
+
+/* ******************************************************************
+ * test if any of the "Display_backgroud_map"-Checkboxes are on
+ */
+int
+display_background_map ()
+{
+ gint i;
+ gint show__background_map = FALSE;
+
+ for (i = 0; i < max_display_map; i++)
+ {
+ if (display_map[i].to_be_displayed)
+ show__background_map = TRUE;
+ }
+ return show__background_map;
+}
+
+
+/* ******************************************************************
+ * test if we need to load another map
+ */
+void
+test_and_load_newmap ()
+{
+ long long best = 1000000000LL;
+ gdouble posx = 0, posy =0;
+ long long bestmap = 9999999999LL;
+ gdouble pixelfactloc;
+ gdouble bestscale = 1000000000.0;
+ gdouble fact;
+ gint i, ncount = 0;
+ gdouble dif;
+ static int nasaisvalid = FALSE;
+ int takemap = FALSE;
+
+ if (current.importactive)
+ return;
+
+ // TODO: this doesn't belong here, move it somewhere else...
+ if (gui_status.posmode) {
+ trip_lat = coords.current_lon = coords.posmode_lon;
+ trip_lon = coords.current_lat = coords.posmode_lat;
+ } else update_route ();
+
+
+ // Test if we want Background image as Map
+ if (!display_background_map ()) {
+ current.mapscale = (glong) local_config.scale_wanted;
+ pixelfact = current.mapscale / PIXELFACT;
+ coords.zero_lat = coords.current_lat;
+ coords.zero_lon = coords.current_lon;
+ xoff = yoff = 0;
+ map_proj = proj_map;
+
+ // extra variable; so we can later make it configurable
+ gchar bg_mapfilename[2048];
+ g_strlcpy (bg_mapfilename, "map_LightYellow.png", sizeof (bg_mapfilename));
+
+ g_strlcpy (oldfilename, mapfilename, sizeof (oldfilename));
+ g_strlcpy (mapfilename, bg_mapfilename, sizeof (mapfilename));
+ loadmap (mapfilename);
+ return;
+ }
+
+#ifdef MAPNIK
+ if ( local_config.MapnikStatusInt > 0 && active_mapnik_ysn()){
+ if (mydebug > 0)
+ fprintf (stderr, "rendering mapnik map ....\n");
+ g_strlcpy (oldfilename, mapfilename, sizeof (oldfilename));
+ g_strlcpy (mapfilename, "Mapnik direct Render", sizeof (mapfilename));
+ //gint LevelInt = 18 - GTK_ADJUSTMENT (mapscaler_adj)->value;
+ //set_mapnik_map(current_lat, current_lon, LevelInt);
+ int ForceMapCenterYsn = 0;
+ if (local_config.MapnikStatusInt == 1) {
+ ForceMapCenterYsn = 1;
+ local_config.MapnikStatusInt = 2; /* set active */
+ }
+ /* render map, but only if it is needed */
+ if (set_mapnik_map_ysn(coords.current_lat, coords.current_lon, ForceMapCenterYsn, local_config.scale_wanted)) {;
+ // local_config.MapnikStatusInt = 2;
+ set_cursor_style(CURSOR_WATCH);
+ render_mapnik();
+ /* only load map if there is a new one. */
+ if (get_mapnik_newmapysn()) {
+ current.mapscale = get_mapnik_mapscale();// 68247.3466832;;
+ pixelfact = get_mapnik_pixelfactor();
+ get_mapnik_center(&coords.zero_lat, &coords.zero_lon);
+ xoff = yoff = 0;
+ //loadmap("/tmp/mapnik.png");
+ loadmap("mapnik");
+ }
+ set_cursor_style(CURSOR_DEFAULT);
+ }
+ return;
+ }
+#endif
+
+ /* search for suitable maps */
+ if (displaymap_top) nasaisvalid = create_nasa ();
+ nasaisvalid = FALSE;
+
+ /* have a look through all the maps and decide which map
+ * is the best/apropriate
+ * RESULT: bestmap [index in (maps + i) for the choosen map]
+ */
+ for (i = 0; i < nrmaps; i++) {
+ if (!display_map[(maps + i)->map_dir].to_be_displayed) {
+ continue;
+ }
+
+ takemap = FALSE;
+ if ((maps + i)->hasbbox) {
+ /* new system with boundarybox */
+ if ((maps + i)->minlat < coords.current_lat &&
+ (maps + i)->minlon < coords.current_lon &&
+ (maps + i)->maxlat > coords.current_lat &&
+ (maps + i)->maxlon > coords.current_lon) {
+ takemap = TRUE;
+ }
+ } else {
+ /* old system */
+
+ enum map_projections proj = map_projection ((maps + i)->filename);
+
+ /* Longitude */
+ if (proj_map == proj)
+ posx = (lat2radius ((maps + i)->lat) * M_PI / 180)
+ * cos (DEG2RAD( (maps + i)->lat))
+ * (coords.current_lon - (maps + i)->lon);
+ else if (proj_top == proj)
+ posx = (lat2radius (0) * M_PI / 180) * (coords.current_lon - (maps + i)->lon);
+ else if (proj_googlesat == proj)
+ posx = (lat2radius (0) * M_PI / 180) * (coords.current_lon - (maps + i)->lon);
+ else
+ printf("Error: unknown Projection\n");
+
+ /* latitude */
+ if (proj_map == proj) {
+ posy = (lat2radius ((maps + i)->lat) * M_PI / 180)
+ * (coords.current_lat - (maps + i)->lat);
+ dif = lat2radius ((maps + i)->lat)
+ * (1 - (cos (DEG2RAD((coords.current_lon - (maps + i)->lon)) )));
+ posy = posy + dif / 2.0;
+ } else if (proj_top == proj) {
+ posy = (lat2radius (0) * M_PI / 180) * (coords.current_lat - (maps + i)->lat);
+ } else if (proj_googlesat == proj) {
+ posy = 1.5* (lat2radius (0) * M_PI / 180) * (coords.current_lat - (maps + i)->lat);
+ } else
+ printf("Error: unknown Projection\n");
+
+ pixelfactloc = (maps + i)->scale / PIXELFACT;
+ posx = posx / pixelfactloc;
+ posy = posy / pixelfactloc;
+ /* */
+ if (strcmp ("top_NASA_IMAGE.ppm", (maps + i)->filename) == 0) {
+ ncount++;
+ }
+ /* takemap? */
+ if (((gint) posx > -(640 - borderlimit)) &&
+ ((gint) posx < (640 - borderlimit)) &&
+ ((gint) posy > -(512 - borderlimit)) &&
+ ((gint) posy < (512 - borderlimit))) {
+ takemap = TRUE;
+ }
+ }
+ if (takemap) {
+ if (displaymap_top)
+ if (strcmp ("top_NASA_IMAGE.ppm", (maps + i)->filename) == 0) {
+ /* nasa map is in range */
+ nasaisvalid = TRUE;
+ }
+
+ if (!local_config.autobestmap) {
+ if (local_config.scale_wanted > (maps + i)->scale)
+ fact = (gdouble) local_config.scale_wanted / (maps + i)->scale;
+ else
+ fact = (maps + i)->scale / (gdouble) local_config.scale_wanted;
+ if (fact < bestscale) {
+ bestscale = fact;
+ bestmap = i;
+ /* bestcentereddist = centereddist; */
+ }
+ } else { /* autobestmap */
+ if ((maps + i)->scale < best) {
+ bestmap = i;
+ best = (maps + i)->scale;
+ }
+ }
+ } /* End of if posy> ... posx> ... */
+ } /* End of for ... i < nrmaps */
+ // RESULT: bestmap [index in (maps + i) for the choosen map]
+
+ load_best_map (bestmap);
+}
+
+/* *****************************************************************************
+ * Robins hacking
+ * Show (in yellow) any downloaded maps with in +/-20% of the currently
+ * requested map download also show bounds of map with a black border
+ * This is currently hooked in to the drawdownloadrectangle() function
+ * but may be better else where as a seperate function that can be
+ * turned on and off as requried.
+ * Due to RGB bit masks the map to be downloaded will now be green
+ * so that the new download area will be visible over the top of the
+ * previous downloaded maps.
+ */
+void
+drawloadedmaps ()
+{
+ int i;
+ gdouble x, y, la, lo;
+ gint scale, xo, yo;
+ if (mydebug > 50)
+ fprintf (stderr, "drawloadedmaps()\n");
+ for (i = 0; i < nrmaps; i++)
+ {
+ scale = new_dl_scale;
+ if (maps[i].scale <= scale * 1.2 && maps[i].scale >= scale * 0.8)
+ {
+ //printf("Selected map at lon %lf lat %lf\n",maps[i].lat,maps[i].lon);
+ la = maps[i].lat;
+ lo = maps[i].lon;
+ // scale=maps[i].scale;
+ calcxy (&x, &y, lo, la, current.zoom);
+ xo = 1280.0 * current.zoom * scale / current.mapscale;
+ yo = 1024.0 * current.zoom * scale / current.mapscale;
+ // yellow background
+ gdk_gc_set_foreground (kontext_map, &colors.yellow);
+ gdk_gc_set_function (kontext_map, GDK_AND);
+ gdk_gc_set_line_attributes (kontext_map, 2, 0, 0, 0);
+ gdk_draw_rectangle (drawable, kontext_map, 1, x - xo / 2,
+ y - yo / 2, xo, yo);
+ // solid border
+ gdk_gc_set_foreground (kontext_map, &colors.black);
+ gdk_gc_set_function (kontext_map, GDK_SOLID);
+ gdk_gc_set_line_attributes (kontext_map, 2, 0, 0, 0);
+ gdk_draw_rectangle (drawable, kontext_map, 0, x - xo / 2,
+ y - yo / 2, xo, yo);
+ }
+ }
+}
+
+
+/* *****************************************************************************
+ * draw downloadrectangle
+ */
+void
+drawdownloadrectangle (gint big)
+{
+
+ if (mydebug > 50)
+ fprintf (stderr, "drawdownloadrectangle()\n");
+ drawloadedmaps ();
+ if (downloadwindowactive)
+ {
+ gdouble x, y, la, lo;
+ gint scale, xo, yo;
+ la = new_dl_lat;
+ lo = new_dl_lon;
+ scale = new_dl_scale;
+ gdk_gc_set_foreground (kontext_map, &colors.green2);
+ gdk_gc_set_function (kontext_map, GDK_AND);
+ gdk_gc_set_line_attributes (kontext_map, 2, 0, 0, 0);
+ if (big)
+ {
+ calcxy (&x, &y, lo, la, current.zoom);
+ xo = 1280.0 * current.zoom * scale / current.mapscale;
+ yo = 1024.0 * current.zoom * scale / current.mapscale;
+ gdk_draw_rectangle (drawable, kontext_map, 1, x - xo / 2,
+ y - yo / 2, xo, yo);
+ }
+ else
+ if (local_config.guimode != GUI_CAR
+ && ! local_config.MapnikStatusInt ) {
+ calcxymini (&x, &y, lo, la, 1);
+ xo = 128.0 * scale / current.mapscale;
+ yo = 102.0 * scale / current.mapscale;
+ gdk_draw_rectangle (drawing_minimap->window,
+ kontext_map, 1, x - xo / 2, y - yo / 2, xo, yo);
+ }
+
+ gdk_gc_set_function (kontext_map, GDK_COPY);
+ }
+
+}
diff --git a/src/map_handler.h b/src/map_handler.h
new file mode 100644
index 0000000..6d13504
--- /dev/null
+++ b/src/map_handler.h
@@ -0,0 +1,6 @@
+#ifndef MAP_HANDLER_H_
+#define MAP_HANDLER_H_
+int add_map_dir (gchar *);
+GtkWidget *make_display_map_checkboxes();
+GtkWidget *make_display_map_controls();
+#endif /*MAP_HANDLER_H_*/
diff --git a/src/map_projection.c b/src/map_projection.c
new file mode 100644
index 0000000..f237318
--- /dev/null
+++ b/src/map_projection.c
@@ -0,0 +1,345 @@
+/***********************************************************************
+ *
+ * Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+ *
+ * Website: www.gpsdrive.de
+ *
+ * Disclaimer: Please do not use for navigation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ **********************************************************************
+ */
+
+#include <libintl.h>
+#include <locale.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <math.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gpsdrive.h>
+#include <config.h>
+#include "gpsdrive.h"
+#include "speech_out.h"
+#include "speech_strings.h"
+#include "mapnik.h"
+
+/* variables */
+extern gint ignorechecksum, mydebug, debug;
+extern gint real_screen_x, real_screen_y;
+extern gint real_psize, real_smallmenu;
+extern gint SCREEN_X_2, SCREEN_Y_2;
+extern gdouble pixelfact, posx, posy;
+extern gdouble bearing;
+extern gint haveposcount, blink, gblink, xoff, yoff;
+extern gdouble trip_lat, trip_lon;
+extern gdouble milesconv;
+extern gint nrmaps;
+extern gint maploaded;
+extern gint debug, mydebug;
+extern gint usesql;
+extern glong mapscale;
+extern gchar newmaplat[100], newmaplon[100], newmapsc[100], oldangle[100];
+
+extern gint thisrouteline;
+extern gint gcount, downloadwindowactive;
+extern GtkWidget *bestmap_bt, *poi_draw_bt, *streets_draw_bt;
+extern coordinate_struct coords;
+extern gchar oldfilename[2048];
+
+extern gint borderlimit;
+
+extern gint saytarget;
+
+extern int havedefaultmap;
+
+extern GdkPixbuf *image, *tempimage;
+
+#include "gettext.h"
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+
+enum map_projections map_proj = proj_top;
+
+/* ******************************************************************
+ * Find the maptype for a given Filename
+ */
+enum map_projections
+map_projection (char *filename)
+{
+ enum map_projections proj = proj_undef;
+
+ if (strstr (filename, "expedia/"))
+ proj = proj_map;
+ else if (strstr (filename, "landsat/"))
+ proj = proj_map;
+ else if (strstr (filename, "geoscience/"))
+ proj = proj_map;
+ else if (strstr (filename, "incrementp/"))
+ proj = proj_map;
+ else if (strstr (filename, "gov_au/"))
+ proj = proj_map;
+ else if (strstr (filename, "_map/"))
+ proj = proj_map;
+ else if (!strncmp(filename, "map_", 4)) /* For Compatibility */
+ proj = proj_map;
+ else if (strstr(filename, "/map_")) /* For Compatibility */
+ proj = proj_map;
+ else if (strstr (filename, "googlesat/"))
+ proj = proj_googlesat;
+#ifdef MAPNIK
+ else if (strstr (filename, "mapnik/"))
+ proj = proj_map;
+#endif
+ else if (strstr (filename, "NASAMAPS/"))
+ proj = proj_top;
+ else if (strstr (filename, "eniro/"))
+ proj = proj_top;
+ else if (strstr (filename, "_top/"))
+ proj = proj_top;
+ else if (!strncmp(filename, "top_", 4)) /* For Compatibility */
+ proj = proj_top;
+ else if (strstr(filename, "/top_")) /* For Compatibility */
+ proj = proj_top;
+#ifdef MAPNIK
+ else if (strstr(filename, "mapnik"))
+ proj = proj_mapnik;
+#endif
+ else
+ {
+ proj = proj_undef;
+ }
+ return proj;
+}
+
+
+/* **********************************************************************
+ * calculates lat and lon for the given position on the screen
+ */
+void
+calcxytopos (int posx, int posy, gdouble * mylat, gdouble * mylon, gint zoom)
+{
+ int px, py;
+ gdouble dif, lat, lon;
+
+ // hack to avoid some strange errors caused by commas that shouldn't be there
+ setlocale(LC_NUMERIC,"C");
+
+ if (mydebug > 99)
+ fprintf (stderr, "calcxytopos(%d,%d,__,%d)\n", posx, posy, zoom);
+
+ // Screen xy --> pixmap xy
+ px = (SCREEN_X_2 - posx - xoff) * pixelfact / zoom;
+ py = (-SCREEN_Y_2 + posy + yoff) * pixelfact / zoom;
+
+ if (proj_map == map_proj)
+ {
+ lat = coords.zero_lat - py / lat2radius_pi_180 (coords.current_lat);
+ lat = coords.zero_lat - py / lat2radius_pi_180 (lat);
+ lon = coords.zero_lon - px / (lat2radius_pi_180 (lat) * cos (DEG2RAD(lat)));
+
+ dif = lat * (1 - (cos (DEG2RAD(fabs (lon - coords.zero_lon)))));
+ lat = lat - dif / 1.5;
+
+ lon = coords.zero_lon - px / (lat2radius_pi_180 (lat) * cos (DEG2RAD(lat)));
+ }
+ else if (proj_top == map_proj)
+ {
+ lat = coords.zero_lat - py / lat2radius_pi_180 (0);
+ lon = coords.zero_lon - px / lat2radius_pi_180 (0);
+ }
+ else if (proj_googlesat == map_proj)
+ {
+ lat = coords.zero_lat - (py/1.5) / lat2radius_pi_180 (0);
+ lon = coords.zero_lon - (px*1.0) / lat2radius_pi_180 (0);
+ }
+#ifdef MAPNIK
+ else if (proj_mapnik == map_proj)
+ {
+ // only use the offset
+ get_mapnik_clacxytopos(&lat, &lon, posx, posy, xoff, yoff, zoom);
+ }
+#endif
+ else
+ {
+ fprintf (stderr, "ERROR: calcxytopos: unknown map Projection\n");
+ lat = 0.0; /* dummy value */
+ lon = 0.0;
+ }
+
+ // Error check
+ if (mydebug > 20)
+ {
+ if (lat > 360)
+ fprintf (stderr, "ERROR: calcxytopos(lat %f) out of bound\n", lat);
+ if (lat < -360)
+ fprintf (stderr, "ERROR: calcxytopos(lat %f) out of bound\n", lat);
+ if (lon > 180)
+ fprintf (stderr, "ERROR: calcxytopos(lon %f) out of bound\n", lon);
+ if (lon < -180)
+ fprintf (stderr, "ERROR: calcxytopos(lon %f) out of bound\n", lon);
+ };
+
+ *mylat = lat;
+ *mylon = lon;
+
+ if (mydebug > 90)
+ fprintf (stderr, "calcxytopos(%d,%d,_,_,%d) ---> %g,%g\n", posx, posy, zoom, lat, lon);
+}
+
+
+
+/* ******************************************************************
+ * calculate xy pos of given lon/lat
+ */
+void calcxy (gdouble * posx, gdouble * posy, gdouble lon, gdouble lat, gint zoom)
+{
+ gdouble dif;
+ if (mydebug > 99)
+ fprintf (stderr, "calcxy(_,_,%g,%g,%d)\n", *posx, *posy, zoom);
+ // Error check
+ if (mydebug > 20)
+ {
+ if (lat > 360)
+ fprintf (stderr, "WARNING: calcxy(lat %f) out of bound\n", lat);
+ if (lat < -360)
+ fprintf (stderr, "WARNING: calcxy(lat %f) out of bound\n", lat);
+ if (lon > 180)
+ fprintf (stderr, "WARNING: calcxy(lon %f) out of bound\n", lon);
+ if (lon < -180)
+ fprintf (stderr, "WARNING: calcxy(lon %f) out of bound\n", lon);
+ };
+
+ if (proj_map == map_proj)
+ {
+ *posx = lat2radius_pi_180 (lat) * cos (DEG2RAD(lat)) * (lon - coords.zero_lon);
+ *posy = lat2radius_pi_180 (lat) * (lat - coords.zero_lat);
+ dif = lat2radius (lat) * (1 - (cos (DEG2RAD((lon - coords.zero_lon)))));
+ *posy = *posy + dif / 1.85;
+ }
+ else if (proj_top == map_proj)
+ {
+ *posx = lat2radius_pi_180 (0.0) * (lon - coords.zero_lon);
+ *posy = lat2radius_pi_180 (lat) * (lat - coords.zero_lat);
+ }
+ else if (proj_googlesat == map_proj)
+ {
+ *posx = 1.0 * lat2radius_pi_180 (0.0) * (lon - coords.zero_lon);
+ *posy = 1.5 * lat2radius_pi_180 (lat) * (lat - coords.zero_lat);
+ }
+#ifdef MAPNIK
+ else if (proj_mapnik == map_proj)
+ {
+ // only use the offset
+ get_mapnik_clacxy(posx, posy, lat, lon, xoff, yoff, zoom);
+ }
+#endif
+ else
+ fprintf (stderr, "ERROR: calcxy: unknown map Projection\n");
+
+ if (proj_mapnik != map_proj) {
+ // pixmap xy --> Screen xy
+ *posx = (SCREEN_X_2 + *posx * zoom / pixelfact) - xoff;
+ *posy = (SCREEN_Y_2 - *posy * zoom / pixelfact) - yoff;
+ }
+ if (mydebug > 90)
+ fprintf (stderr, "calcxy(_,_,%g,%g,%d) ---> %g,%g\n", *posx, *posy, zoom, lat, lon);
+}
+
+/* ******************************************************************
+ */
+void
+minimap_xy2latlon (gint px, gint py, gdouble * lon, gdouble * lat, gdouble * dif)
+{
+ *lat = coords.zero_lat - py / lat2radius_pi_180 (coords.current_lat);
+ *lat = coords.zero_lat - py / lat2radius_pi_180 (*lat);
+ *lon = coords.zero_lon - px / (lat2radius (*lat) * cos (DEG2RAD(*lat)));
+
+ if (proj_top == map_proj)
+ {
+ *dif = (*lat) * (1 - (cos (DEG2RAD(fabs (*lon - coords.zero_lon)))));
+ *lat = (*lat) - (*dif) / 1.5;
+ }
+ else if (proj_map == map_proj)
+ *dif = 0;
+ else if (proj_googlesat == map_proj)
+ {
+ *dif = (*lat) * (1 - (cos (DEG2RAD(fabs (*lon - coords.zero_lon)))));
+ *lat = (*lat) - (*dif) / 1.5;
+ }
+#ifdef MAPNIK
+ else if (proj_mapnik == map_proj) {
+ *dif = 0;
+ get_mapnik_minixy2latlon(px, py, lat, lon);
+ }
+#endif
+ else {
+ printf ("ERROR: minimap_xy2latlon: unknown map Projection\n");
+ *lon = coords.zero_lon - px / (lat2radius_pi_180 (*lat) * cos (DEG2RAD(*lat)));
+ }
+}
+
+/* ******************************************************************
+ * calculate xy position in mini map window from given lat/lon
+ */
+void calcxymini (gdouble * posx, gdouble * posy, gdouble lon, gdouble lat, gint zoom)
+{
+
+#ifdef MAPNIK
+ if (proj_mapnik == map_proj) {
+ get_mapnik_miniclacxy(posx, posy, lat, lon, zoom);
+ return;
+ }
+#endif
+ gdouble dif;
+ if (proj_map == map_proj)
+ *posx = lat2radius_pi_180 (lat) * cos (DEG2RAD(lat)) * (lon - coords.zero_lon);
+ else if (proj_top == map_proj)
+ *posx = lat2radius_pi_180 (0) * (lon - coords.zero_lon);
+ else if (proj_googlesat == map_proj)
+ *posx = lat2radius_pi_180 (0) * (lon - coords.zero_lon);
+ else
+ printf ("Eroor: calcxymini: unknown Projection\n");
+
+ *posx = 64 + *posx * zoom / (10 * pixelfact);
+ *posx = *posx;
+ if (proj_map == map_proj)
+ {
+ dif = lat2radius (lat) * (1 - (cos (DEG2RAD(lon - coords.zero_lon))));
+ *posy = lat2radius_pi_180 (lat) * (lat - coords.zero_lat);
+ *posy = *posy + dif / 1.85;
+ }
+ else if (proj_top == map_proj)
+ *posy = lat2radius_pi_180 (lat) * (lat - coords.zero_lat);
+ else if (proj_googlesat == map_proj)
+ *posy = lat2radius_pi_180 (lat) * (lat - coords.zero_lat);
+ else
+ printf ("Eroor: calcxymini: unknown Projection\n");
+
+ *posy = 51 - *posy * zoom / (10 * pixelfact);
+ *posy = *posy;
+}
diff --git a/src/mapnik.cpp b/src/mapnik.cpp
new file mode 100644
index 0000000..965fda6
--- /dev/null
+++ b/src/mapnik.cpp
@@ -0,0 +1,462 @@
+#ifdef MAPNIK
+
+/*
+#include <QWidget>
+#include <QImage>
+#include <QPixmap>
+#include <QPen>
+*/
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <mapnik/map.hpp>
+#include <mapnik/load_map.hpp>
+#include <mapnik/agg_renderer.hpp>
+#include <mapnik/layer.hpp>
+#include <mapnik/projection.hpp>
+#include <mapnik/ctrans.hpp>
+#include <mapnik/memory_datasource.hpp>
+#include <mapnik/datasource_cache.hpp>
+#include <mapnik/font_engine_freetype.hpp>
+#include <string>
+#include <fstream>
+
+#include "mapnik.h"
+#include "config.h"
+
+using mapnik::Image32;
+using mapnik::Map;
+using mapnik::Layer;
+using mapnik::Envelope;
+using mapnik::coord2d;
+using mapnik::feature_ptr;
+using mapnik::geometry_ptr;
+using mapnik::CoordTransform;
+
+extern int mydebug;
+extern int borderlimit;
+extern int SCREEN_X_2;
+extern int SCREEN_Y_2;
+
+mapnik::projection Proj("+proj=merc +datum=WGS84");
+
+typedef struct {
+ int WidthInt;
+ int HeightInt;
+ int BorderlimitInt;
+ double CenterLatDbl;
+ double CenterLonDbl;
+ mapnik::coord2d CenterPt;
+ int RenderMapYsn;
+ double ScaleInt;
+ unsigned char *ImageRawDataPtr;
+ mapnik::Map *MapPtr;
+ int NewMapYsn;
+} MapnikMapStruct;
+
+MapnikMapStruct MapnikMap;
+int MapnikInitYsn = 0;
+
+namespace mapnik {
+
+using namespace std;
+using namespace mapnik;
+
+/*
+double scales [] = {279541132.014,
+ 139770566.007,
+ 69885283.0036,
+ 34942641.5018,
+ 17471320.7509,
+ 8735660.37545,
+ 4367830.18772,
+ 2183915.09386,
+ 1091957.54693,
+ 545978.773466,
+ 272989.386733,
+ 136494.693366,
+ 68247.3466832,
+ 34123.6733416,
+ 17061.8366708,
+ 8530.9183354,
+ 4265.4591677,
+ 2132.72958385,
+ 1066.36479192,
+ 533.182395962};
+const int MIN_LEVEL = 0;
+const int MAX_LEVEL = 18;
+*/
+
+/*
+ * little replace function for strings
+ */
+string ReplaceString(const string &SearchString, const string &ReplaceString, string StringToReplace)
+{
+ string::size_type pos = StringToReplace.find(SearchString, 0);
+ int LengthSearch = SearchString.length();
+
+ while(string::npos != pos )
+ {
+ StringToReplace.replace(pos, LengthSearch, ReplaceString);
+ pos = StringToReplace.find(SearchString, 0);
+ }
+ return StringToReplace;
+}
+
+/*
+ * initialize mapnik
+ */
+extern "C"
+void init_mapnik (char *ConfigXML) {
+
+ // register datasources (plug-ins) and a font
+ // Both datasorce_cache and font_engine are 'singletons'.
+
+ datasource_cache::instance()->register_datasources("/usr/lib/mapnik/input/");
+ freetype_engine::instance()->register_font("/usr/lib/mapnik/fonts/DejaVuSans.ttf");
+
+ MapnikMap.WidthInt = 1280;
+ MapnikMap.HeightInt = 1024;
+ MapnikMap.BorderlimitInt = borderlimit;
+ MapnikMap.ScaleInt = -1; // <-- force creation of map if a map is set
+ MapnikMap.MapPtr = new mapnik::Map(MapnikMap.WidthInt, MapnikMap.HeightInt);
+
+ //load map
+ std::string mapnik_config_file (ConfigXML);
+ mapnik::load_map(*MapnikMap.MapPtr, mapnik_config_file);
+ MapnikInitYsn = -1;
+}
+
+/*
+ * mapnik initialized?
+ */
+extern "C"
+int active_mapnik_ysn() {
+ if (MapnikInitYsn)
+ return -1;
+ else
+ return 0;
+
+}
+
+/*
+ * Generate the local mapnik config xml
+ */
+extern "C"
+int gen_mapnik_config_xml_ysn(char *Dest, char *Username) {
+
+ // This location has to be adapted in the future
+ // for now it should work if gpsdrive is installed in the standard location
+ string mapnik_config_file("./scripts/mapnik/osm.xml");
+ if ( ! boost:: filesystem::exists(mapnik_config_file) )
+ mapnik_config_file.assign("../scripts/mapnik/osm.xml");
+ if ( ! boost:: filesystem::exists(mapnik_config_file) )
+ mapnik_config_file.assign(DATADIR).append("/mapnik/osm.xml");
+ cout << "Using Mapnik config-file: " << mapnik_config_file << endl;
+
+ if ( ! boost:: filesystem::exists(mapnik_config_file) ) {
+ // file not found return
+ return 0;
+ }
+
+ // load files
+
+ ifstream InputXML (mapnik_config_file.c_str());
+ ofstream DestXML (Dest);
+
+ if (InputXML && DestXML) {
+ if (InputXML.is_open()) {
+ string s ;
+ while (getline(InputXML, s)) {
+ DestXML << ReplaceString("@USER@", Username, s) << endl;
+ }
+ }
+ }
+ InputXML.close();
+ DestXML.close();
+
+ return -1;
+}
+
+/*
+ * set new map values
+ * center lat/lon
+ * pForceNewCenterYsn = force maprendering with new center
+ * pScaleInt = gpsdrive scale wanted
+ * returing yes/no if a new map should be rendered
+ */
+extern "C"
+int set_mapnik_map_ysn(const double pPosLatDbl, const double pPosLonDbl, int pForceNewCenterYsn, const int pScaleInt) {
+ int PanCntInt = 0;
+ int OnMapYsn = 0;
+ double scale_denom = MapnikMap.ScaleInt;
+ double res = scale_denom * 0.00028;
+ /* first we disable the map rendering
+ * and test if we need to render a new map */
+ MapnikMap.RenderMapYsn = 0;
+
+
+ if (pScaleInt != MapnikMap.ScaleInt) {
+ /* new scale */
+ MapnikMap.ScaleInt = pScaleInt;
+ pForceNewCenterYsn = 1; /* we always force the center */
+ }
+
+ /* force new center */
+ if (pForceNewCenterYsn) {
+ MapnikMap.CenterLatDbl = pPosLatDbl;
+ MapnikMap.CenterLonDbl = pPosLonDbl;
+ MapnikMap.RenderMapYsn = 1;
+ }
+ /* if a new map should be rendered,
+ * then caculate new center pix coord
+ * else out of allowed map aerea? pan!*/
+ if (MapnikMap.RenderMapYsn) {
+ /* calc new center pix */
+ MapnikMap.CenterPt.x = MapnikMap.CenterLonDbl;
+ MapnikMap.CenterPt.y = MapnikMap.CenterLatDbl;
+ Proj.forward(MapnikMap.CenterPt.x, MapnikMap.CenterPt.y);
+ } else {
+ /* out of allowed map area? pan! if more then 10 times to pan center to map*/
+ while (!OnMapYsn && PanCntInt < 10) {
+ OnMapYsn = 1;
+ mapnik::coord2d Pt = mapnik::coord2d(pPosLonDbl, pPosLatDbl);
+ Proj.forward(Pt.x, Pt.y);
+ /* pan right or left? */
+ if ((MapnikMap.CenterPt.x + (0.5 * MapnikMap.WidthInt - MapnikMap.BorderlimitInt) * res) < Pt.x) {
+ cout << "pan right\n";
+ /* pan right */
+ MapnikMap.CenterPt.x = MapnikMap.CenterPt.x + (MapnikMap.WidthInt - MapnikMap.BorderlimitInt * 2) * res;
+ PanCntInt += 1;
+ OnMapYsn = 0;
+ } else if ((MapnikMap.CenterPt.x - (0.5 * MapnikMap.WidthInt - MapnikMap.BorderlimitInt) * res) > Pt.x) {
+ /* pan left */
+ cout << "pan left\n";
+ MapnikMap.CenterPt.x = MapnikMap.CenterPt.x - (MapnikMap.WidthInt - MapnikMap.BorderlimitInt * 2) * res;
+ PanCntInt += 1;
+ OnMapYsn = 0;
+ }
+ /* pan up or down? */
+ if ((MapnikMap.CenterPt.y + (0.5 * MapnikMap.HeightInt - MapnikMap.BorderlimitInt) * res) < Pt.y) {
+ cout << "pan up\n";
+ /* pan up */
+ MapnikMap.CenterPt.y = MapnikMap.CenterPt.y + (MapnikMap.HeightInt - MapnikMap.BorderlimitInt * 2) * res;
+ PanCntInt += 1;
+ OnMapYsn = 0;
+ } else if ((MapnikMap.CenterPt.y - (0.5 * MapnikMap.HeightInt - MapnikMap.BorderlimitInt) * res) > Pt.y) {
+ /* pan down */
+ cout << "pan down\n";
+ MapnikMap.CenterPt.y = MapnikMap.CenterPt.y - (MapnikMap.HeightInt - MapnikMap.BorderlimitInt * 2) * res;
+ PanCntInt += 1;
+ OnMapYsn = 0;
+ }
+ }
+
+ if (PanCntInt > 0 && OnMapYsn) {
+ /* render map */
+ MapnikMap.RenderMapYsn = 1;
+ /* calc new lat/lon */
+ MapnikMap.CenterLonDbl = MapnikMap.CenterPt.x;
+ MapnikMap.CenterLatDbl = MapnikMap.CenterPt.y;
+ Proj.inverse(MapnikMap.CenterLonDbl, MapnikMap.CenterLatDbl);
+ } else if (PanCntInt) {
+ MapnikMap.CenterLatDbl = pPosLatDbl;
+ MapnikMap.CenterLonDbl = pPosLonDbl;
+ MapnikMap.RenderMapYsn = 1;
+ MapnikMap.CenterPt.x = MapnikMap.CenterLonDbl;
+ MapnikMap.CenterPt.y = MapnikMap.CenterLatDbl;
+ Proj.forward(MapnikMap.CenterPt.x, MapnikMap.CenterPt.y);
+ }
+ }
+
+
+ //Check level
+ /*if (MapnikMap.ScaleInt < MIN_LEVEL) MapnikMap.ScaleInt = MIN_LEVEL;
+ if (MapnikMap.ScaleInt > MAX_LEVEL) MapnikMap.ScaleInt = MAX_LEVEL;
+*/
+}
+
+/*
+ * convert the color channel
+ */
+inline unsigned char
+convert_color_channel (unsigned char Source, unsigned char Alpha) {
+ return Alpha ? ((Source << 8) - Source) / Alpha : 0;
+}
+
+/*
+ * converting argb32 to gdkpixbuf
+ */
+void
+convert_argb32_to_gdkpixbuf_data (unsigned char const *Source, unsigned char *Dest) {
+ unsigned char const *SourcePixel = Source;
+ unsigned char *DestPixel = Dest;
+ for (int y = 0; y < MapnikMap.HeightInt; y++) {
+ for (int x = 0; x < MapnikMap.WidthInt; x++) {
+ DestPixel[0] = convert_color_channel(SourcePixel[0], SourcePixel[3]);
+ DestPixel[1] = convert_color_channel(SourcePixel[1], SourcePixel[3]);
+ DestPixel[2] = convert_color_channel(SourcePixel[2], SourcePixel[3]);
+ DestPixel += 3;
+ SourcePixel += 4;
+ }
+ }
+}
+
+/*
+ * is there a new map to render?
+ */
+extern "C"
+void render_mapnik () {
+
+ MapnikMap.NewMapYsn = false;
+ if (!MapnikMap.RenderMapYsn) return;
+
+
+
+ //double scale_denom = scales[MapnikMap.ScaleInt];
+ double scale_denom = MapnikMap.ScaleInt;
+ double res = scale_denom * 0.00028;
+
+ /* render image */
+ Envelope<double> box = Envelope<double>(MapnikMap.CenterPt.x - 0.5 * MapnikMap.WidthInt * res,
+ MapnikMap.CenterPt.y - 0.5 * MapnikMap.HeightInt * res,
+ MapnikMap.CenterPt.x + 0.5 * MapnikMap.WidthInt * res,
+ MapnikMap.CenterPt.y + 0.5 * MapnikMap.HeightInt * res);
+
+ MapnikMap.MapPtr->zoomToBox(box);
+
+ Image32 buf(MapnikMap.WidthInt, MapnikMap.HeightInt);
+ mapnik::agg_renderer<Image32> ren(*MapnikMap.MapPtr,buf);
+ ren.apply();
+
+ if (mydebug > 0) std::cout << MapnikMap.MapPtr->getCurrentExtent() << "\n";
+
+ /* get raw data for gpsdrives pixbuf */
+ if (!MapnikMap.ImageRawDataPtr) {
+ MapnikMap.ImageRawDataPtr = (unsigned char *) malloc(MapnikMap.WidthInt * 3 * MapnikMap.HeightInt);
+ }
+ convert_argb32_to_gdkpixbuf_data(buf.raw_data(), MapnikMap.ImageRawDataPtr);
+
+ /* ok we have a map set default values */
+ MapnikMap.NewMapYsn = true;
+ mapnik::Envelope<double> ext = MapnikMap.MapPtr->getCurrentExtent();
+ mapnik::coord2d pt = ext.center();
+ MapnikMap.CenterPt.x = pt.x;
+ MapnikMap.CenterPt.y = pt.y;
+ Proj.inverse(pt.x, pt.y);
+ MapnikMap.CenterLonDbl = pt.x;
+ MapnikMap.CenterLatDbl = pt.y;
+
+}
+
+/*
+ * return pointer to imagedata for gpsdrive
+ */
+extern "C"
+unsigned char *get_mapnik_imagedata() {
+ return MapnikMap.ImageRawDataPtr;
+}
+
+/*
+ * return selected mapscale
+ */
+extern "C"
+double get_mapnik_mapscale() {
+ return MapnikMap.ScaleInt;
+}
+
+/*
+ * return pixelfactor
+ */
+extern "C"
+double get_mapnik_pixelfactor() {
+ return MapnikMap.ScaleInt * 0.00028;
+}
+
+/*
+ * return if a new map was rendered
+ */
+extern "C"
+int get_mapnik_newmapysn() {
+ return MapnikMap.NewMapYsn;
+}
+
+/*
+ * return mapcenter of actual rendered map
+ */
+extern "C"
+void get_mapnik_center(double *pLatDbl, double *pLonDbl) {
+ *pLatDbl = MapnikMap.CenterLatDbl;
+ *pLonDbl = MapnikMap.CenterLonDbl;
+}
+
+/*
+ * wraper function for gpsdrive
+ */
+extern "C"
+void get_mapnik_clacxytopos(double *pLatDbl, double *pLonDbl, int pXInt, int pYInt, int pXOffInt, int pYOffInt, int pZoom) {
+ double XDbl = (SCREEN_X_2 - pXInt - pXOffInt) * MapnikMap.ScaleInt * 0.00028 / pZoom;
+ double YDbl = (SCREEN_Y_2 - pYInt - pYOffInt) * MapnikMap.ScaleInt * 0.00028 / pZoom;
+ double LonDbl = MapnikMap.CenterPt.x - XDbl;
+ double LatDbl = MapnikMap.CenterPt.y + YDbl;
+ Proj.inverse(LonDbl, LatDbl);
+ *pLonDbl = LonDbl;
+ *pLatDbl = LatDbl;
+}
+
+/*
+ * wraper function for gpsdrive
+ */
+extern "C"
+void get_mapnik_clacxy(double *pXDbl, double *pYDbl, double pLatDbl, double pLonDbl, int pXOffInt, int pYOffInt, int pZoom) {
+
+ double X = pLonDbl;
+ double Y = pLatDbl;
+ Proj.forward(X, Y);
+ X = X - MapnikMap.CenterPt.x;
+ Y = Y - MapnikMap.CenterPt.y;
+
+ *pXDbl = (SCREEN_X_2 + X * pZoom / (MapnikMap.ScaleInt * 0.00028)) - pXOffInt;
+ *pYDbl = (SCREEN_Y_2 - Y * pZoom / (MapnikMap.ScaleInt * 0.00028)) - pYOffInt;
+
+}
+
+/*
+ * wraper function for gpsdrive
+ */
+extern "C"
+void get_mapnik_minixy2latlon(int pXInt, int pYInt, double *pLatDbl, double *pLonDbl) {
+ double XDbl = pXInt;
+ double YDbl = pYInt;
+ double LonDbl = MapnikMap.CenterPt.x - XDbl;
+ double LatDbl = MapnikMap.CenterPt.y - YDbl;
+ Proj.inverse(LonDbl, LatDbl);
+ *pLonDbl = LonDbl;
+ *pLatDbl = LatDbl;
+}
+
+/*
+ * wraper function for gpsdrive
+ */
+extern "C"
+void get_mapnik_miniclacxy(double *pXDbl, double *pYDbl, double pLatDbl, double pLonDbl, int pZoom) {
+ double X = pLonDbl;
+ double Y = pLatDbl;
+ Proj.forward(X, Y);
+ X = X - MapnikMap.CenterPt.x;
+ Y = Y - MapnikMap.CenterPt.y;
+
+ *pXDbl = (64 + X * pZoom / (MapnikMap.ScaleInt * 0.00028 * 10));
+ *pYDbl = (51 - Y * pZoom / (MapnikMap.ScaleInt * 0.00028 * 10));
+
+}
+
+
+} //end namespace mapnik
+
+#endif
diff --git a/src/mapnik.h b/src/mapnik.h
new file mode 100644
index 0000000..0f48ebf
--- /dev/null
+++ b/src/mapnik.h
@@ -0,0 +1,34 @@
+// $Id: mapnik.h 185 1994-06-08 08:37:25Z commiter $
+// mapnik.h
+//
+// 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.
+
+#ifdef MAPNIK
+#ifndef _MAPNIK_DEF_H
+#define _MAPNIK_DEF_H
+
+void init_mapnik(char *ConfigXML);
+int active_mapnik_ysn();
+int gen_mapnik_config_xml_ysn(char *Dest, char *Username);
+int set_mapnik_map_ysn(const double pPosLatDbl, const double pPosLonDbl, int pForceNewCenterYsn, const int pScaleLevelInt);
+void render_mapnik ( );
+unsigned char *get_mapnik_imagedata ( );
+double get_mapnik_mapscale();
+double get_mapnik_pixelfactor();
+int get_mapnik_newmapysn();
+void get_mapnik_center(double *pLatDbl, double *pLonDbl);
+void get_mapnik_clacxytopos(double *pLatDbl, double *pLonDbl, int pX, int pY, int pXOffInt, int pYOffInt, int zoom);
+void get_mapnik_clacxy(double *pXDbl, double *pYDbl, double pLatDbl, double pLonDbl, int pXOffInt, int pYOffInt, int pZoom);
+void get_mapnik_minixy2latlon(int pXInt, int pYInt, double *pLatDbl, double *pLonDbl);
+void get_mapnik_miniclacxy(double *pXDbl, double *pYDbl, double pLatDbl, double pLonDbl, int pZoom);
+
+#endif // _MAPNIK_DEF_H
+#endif // MAPNIK
diff --git a/src/navigation.c b/src/navigation.c
new file mode 100644
index 0000000..5390cae
--- /dev/null
+++ b/src/navigation.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ *********************************************************************
+
+*/
+
+
+/* navigation was never really available, and there are enough reasons not to
+ * include commercial map data for this, so I removed all the teleatlas stuff.
+ *
+ * maybe we will have navigation with data from the openstreetmap.org project some day.
+ *
+ * d.s.e
+ *
+*/
+
diff --git a/src/navigation_gui.c b/src/navigation_gui.c
new file mode 100644
index 0000000..83b7c96
--- /dev/null
+++ b/src/navigation_gui.c
@@ -0,0 +1,32 @@
+/*
+**********************************************************************
+
+Copyright (c) 2001-2007 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+**********************************************************************
+*/
+
+/*
+ * navigation_gui.c
+ *
+ * This module will hold all the gui stuff for the navigation mode
+ */
+
diff --git a/src/nmea_handler.c b/src/nmea_handler.c
new file mode 100644
index 0000000..bf7dba8
--- /dev/null
+++ b/src/nmea_handler.c
@@ -0,0 +1,875 @@
+/***********************************************************************
+ *
+ * Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+ *
+ * Website: www.gpsdrive.de
+ *
+ * Disclaimer: Please do not use for navigation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ **********************************************************************
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <math.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gpsdrive.h>
+#include <time.h>
+#include <config.h>
+#include <math.h>
+#include <termios.h>
+#include "gps_handler.h"
+#include "gpsdrive_config.h"
+#include "gui.h"
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+
+extern gint maploaded;
+extern gint isnight, disableisnight;
+
+extern gint mydebug;
+gint nmea_handler_debug = 0;
+
+extern gchar utctime[20], loctime[20];
+extern gint forcehavepos;
+extern gint haveposcount;
+extern gint blink, gblink, xoff, yoff;
+extern gint zone;
+extern gdouble milesconv;
+extern gint oldsatfix, oldsatsanz;
+extern gdouble precision, gsaprecision;
+extern gchar localedecimal;
+extern gdouble gbreit, glang, milesconv, olddist;
+extern gchar mapfilename[1024];
+extern gdouble posx, posy;
+extern gint satlist[MAXSATS][4], satlistdisp[MAXSATS][4], satbit;
+extern gint newsatslevel;
+extern gint satfix, usedgps;
+extern gint sats_used, sats_in_view;
+extern gchar *buffer, *big;
+extern fd_set readmask;
+extern struct timeval timeout;
+extern gdouble earthr;
+extern GTimer *timer, *disttimer;
+extern int newdata;
+extern pthread_mutex_t mutex;
+extern GtkWidget *startgpsbt;
+extern int didrootcheck;
+extern gint messagestatusbarid, timeoutcount;
+extern gint simpos_timeout;
+extern int timerto;
+extern GtkTooltips *temptooltips;
+extern GtkWidget *satslabel1, *satslabel2, *satslabel3;
+extern GdkPixbuf *satsimage;
+extern gchar dgpsserver[80], dgpsport[10];
+extern gchar gpsdservername[200];
+extern GtkWidget *status;
+extern GtkWidget *pixmapwidget, *gotowindow;
+extern gint statuslock, gpson;
+extern gint earthmate;
+static gchar gradsym[] = "\xc2\xb0";
+extern coordinate_struct coords;
+extern currentstatus_struct current;
+
+/* variables */
+extern gint ignorechecksum;
+//, mapistopo;
+extern gint real_screen_x, real_screen_y, real_psize, real_smallmenu;
+extern gint SCREEN_X_2, SCREEN_Y_2;
+extern gdouble posx, posy;
+extern gint haveposcount;
+extern FILE *nmeaout;
+// ---------------------- NMEA
+gint haveRMCsentence = FALSE;
+gchar nmeamodeandport[50];
+gdouble NMEAsecs = 0.0;
+gint NMEAoldsecs = 0;
+FILE *nmeaout = NULL;
+/* if we get data from gpsd in NMEA format haveNMEA is TRUE */
+gint haveNMEA;
+extern gint sock;
+
+
+/* ******************************************************************
+ * check NMEA checksum
+ * ARGS: NMEA String
+ * RETURNS: TRUE if Checksumm is ok
+ */
+gint
+checksum (gchar * text)
+{
+ gchar t[120], t2[10];
+ gint i = 1, checksum = 0, j, orig;
+
+ if (ignorechecksum)
+ return TRUE;
+
+ strncpy (t, text, 100);
+ t[100] = 0;
+ j = strlen (t) - 3;
+ while (('\0' != t[i]) && (i < j))
+ checksum = checksum ^ t[i++];
+ g_strlcpy (t2, (t + j + 1), sizeof (t2));
+ sscanf (t2, "%X", &orig);
+ if (mydebug + nmea_handler_debug > 50)
+ {
+ g_print ("nmea_handler: gpsd: %s\n", t);
+ g_print ("nmea_handler: gpsd: origchecksum: %X, my:%X\n", orig, checksum);
+ }
+
+ if (orig == checksum)
+ {
+ g_strlcpy (text, t, 1000);
+ return TRUE;
+ }
+ else
+ {
+ g_print
+ ("\n"
+ "*** nmea_handler: NMEA checksum error!\n"
+ "*** nmea_handler: NMEA: %s\n"
+ "*** nmea_handler: Checksum is: %X, should be: %X\n", t,
+ orig, checksum);
+ return FALSE;
+ }
+}
+
+
+/* *****************************************************************************
+ * open serial port or pty master or file for NMEA output
+ */
+FILE *
+opennmea (const char *name)
+{
+ struct termios tios;
+
+ if (mydebug + nmea_handler_debug >50)
+ printf ("nmea_handler: opennmea()\n");
+
+ FILE *const out = fopen (name, "w");
+ if (out == NULL)
+ {
+ perror (_("can't open NMEA output file"));
+ exit (1);
+ }
+
+ if (tcgetattr (fileno (out), &tios))
+ return out; /* not a terminal, oh well */
+
+ tios.c_iflag = 0;
+ tios.c_oflag = 0;
+ tios.c_cflag = CS8 | CLOCAL;
+ tios.c_lflag = 0;
+ tios.c_cc[VMIN] = 1;
+ tios.c_cc[VTIME] = 0;
+ cfsetospeed (&tios, B4800);
+ tcsetattr (fileno (out), TCSAFLUSH, &tios);
+ return out;
+}
+
+/* *****************************************************************************
+ */
+void
+write_nmea_line (const char *line)
+{
+ int checksum = 0;
+ fprintf (nmeaout, "$%s*", line);
+ while ('\0' != *line)
+ checksum = checksum ^ *line++;
+ fprintf (nmeaout, "%02X\r\n", checksum);
+ fflush (nmeaout);
+}
+
+/* *****************************************************************************
+ */
+void
+gen_nmea_coord (char *out)
+{
+ gdouble lat = fabs (coords.current_lat), lon = fabs (coords.current_lon);
+ g_snprintf (out, sizeof (out), ",%02d%07.5f,%c,%03d%07.5f,%c",
+ (int) floor (lat), 60 * (lat - floor (lat)),
+ (coords.current_lat < 0 ? 'S' : 'N'),
+ (int) floor (lon), 60 * (lon - floor (lon)),
+ (coords.current_lon < 0 ? 'W' : 'E'));
+}
+
+/* *****************************************************************************
+ */
+gint
+write_nmea_cb (GtkWidget * widget, guint * datum)
+{
+ char buffer[180];
+ time_t now = time (NULL);
+ struct tm *st = gmtime (&now);
+
+ strftime (buffer, sizeof (buffer), "GPGGA,%H%M%S.000", st);
+ gen_nmea_coord (buffer + strlen (buffer));
+ g_strlcpy (buffer + strlen (buffer), ",1,00,0.0,,M,,,,0000",
+ sizeof (buffer) - strlen (buffer));
+ write_nmea_line (buffer);
+
+ g_strlcpy (buffer, "GPGLL", sizeof (buffer));
+ gen_nmea_coord (buffer + strlen (buffer));
+ strftime (buffer + strlen (buffer), 80, ",%H%M%S.000,A", st);
+ write_nmea_line (buffer);
+
+ strftime (buffer, sizeof (buffer), "GPRMC,%H%M%S.000,A", st);
+ gen_nmea_coord (buffer + strlen (buffer));
+ g_snprintf (buffer + strlen (buffer), sizeof (buffer), ",%.2f,%.2f",
+ current.groundspeed / milesconv / 1.852,
+ current.heading * 180.0 / M_PI);
+ strftime (buffer + strlen (buffer), 80, ",%d%m%y,,", st);
+ write_nmea_line (buffer);
+
+ g_snprintf (buffer, sizeof (buffer), "GPVTG,%.2f,T,,M,%.2f,N,%.2f,K",
+ current.heading * 180.0 / M_PI,
+ current.groundspeed / milesconv / 1.852, current.groundspeed / milesconv);
+ write_nmea_line (buffer);
+
+ return TRUE;
+}
+
+
+/* ******************************************************************
+ * show HDOP in meters
+ */
+void
+convertGSA (char *f)
+{
+ gchar field[50][100], b[500];
+ gint i, l, j = 0, start = 0;
+
+ memset (b, 0, 100);
+ l = strlen (f);
+ for (i = 0; i < l; i++)
+ {
+ if ((f[i] == ',') || (f[i] == '*'))
+ {
+ g_strlcpy (field[j], (f + start), 100);
+ field[j][i - start] = 0;
+ start = i + 1;
+ j++;
+ }
+ }
+ if ( mydebug + nmea_handler_debug > 80 )
+ {
+ g_print ("nmea_handler: gpsd: GSA Fields: ");
+ for (i = 0; i < j; i++)
+ {
+ g_print ("%d:%s$", i, field[i]);
+ }
+ g_print ("\n");
+ }
+
+ current.gpsfix = g_strtod (field[2], 0);
+
+ if (current.gpsfix > 1)
+ {
+
+ gsaprecision = g_strtod (field[15], 0);
+ if ( mydebug + nmea_handler_debug > 80 )
+ g_print ("nmea_handler: gpsd: GSA PDOP: %.1f\n", gsaprecision);
+ }
+}
+
+
+/* *****************************************************************************
+ */
+void
+convertRMC (char *f)
+{
+ gchar field[50][100], b[100];
+ gint start = 0;
+ gint longdegree, latdegree;
+ gchar langri, breitri;
+ size_t i, j = 0;
+ memset (b, 0, 100);
+
+ /* if simulation mode we display status and return */
+ if (current.simmode && maploaded && !gui_status.posmode)
+ {
+ display_status (_("Simulation mode"));
+ return;
+ }
+
+ /* get fields delimited with ',' */
+ for (i = 0; i < strlen (f); i++)
+ {
+ if (f[i] == ',')
+ {
+ g_strlcpy (field[j], (f + start), 100);
+ field[j][i - start] = 0;
+ start = i + 1;
+ j++;
+ }
+ }
+ if ((j != 11) && (j != 12))
+ {
+ g_print ("gpsd: GPRMC: wrong number of fields (%d)\n", (int) j);
+ return;
+ }
+ if (!haveRMCsentence)
+ {
+ if ( mydebug + nmea_handler_debug > 80 )
+ g_print ("nmea_handler: gpsd: got RMC data, using it\n");
+ haveRMCsentence = TRUE;
+ }
+
+ if ( mydebug + nmea_handler_debug > 80 )
+ {
+ g_print ("nmea_handler: gpsd: RMC Fields: \n");
+ for (i = 0; i < j; i++)
+ g_print ("nmea_handler: gpsd: RMC Field %d:%s\n", (int) i, field[i]);
+ g_print ("\n");
+ }
+ g_snprintf (b, sizeof (b), "%c%c:%c%c.%c%c ", field[1][0],
+ field[1][1], field[1][2], field[1][3], field[1][4],
+ field[1][5]);
+ g_strlcpy (utctime, b, sizeof (utctime));
+ if ( mydebug + nmea_handler_debug > 80 )
+ g_print ("nmea_handler: gpsd: utctime: %s\n", utctime);
+ if ((field[2][0] != 'A') && !forcehavepos)
+ {
+ current.gpsfix = 1;
+ haveposcount = 0;
+ return;
+ }
+ else
+ {
+ current.gpsfix = 2;
+ haveposcount++;
+ if (haveposcount == 3)
+ {
+ rebuildtracklist ();
+ }
+
+ }
+ /* Latitude North / South */
+ /* if field[3] is shorter than 9 characters, add zeroes in the beginning */
+ if (strlen (field[3]) < 8)
+ {
+ if ( mydebug + nmea_handler_debug > 0 )
+ {
+ g_print ("nmea_handler: Latitude field %s is shorter than 9 characters. (%Zu)\n",
+ field[3], strlen (field[3]));
+ }
+ for (i = 0; i < 9; i++)
+ {
+ b[i] = '0';
+ }
+ b[9] = 0;
+ g_strlcpy (b + (9 - strlen (field[3])), field[3], sizeof (b));
+ g_strlcpy (field[3], b, sizeof (field[3]));
+ }
+
+ b[0] = field[3][0];
+ b[1] = field[3][1];
+ b[2] = 0;
+ latdegree = atoi (b);
+ if ( mydebug + nmea_handler_debug > 80 )
+ g_print ("nmea_handler: gpsd: lat part1: %s\n", b);
+
+
+ b[0] = field[3][2];
+ b[1] = field[3][3];
+ b[2] = '.';
+ b[3] = field[3][5];
+ b[4] = field[3][6];
+ b[5] = field[3][7];
+ b[6] = field[3][8];
+ b[7] = 0;
+ if ( mydebug + nmea_handler_debug > 80 )
+ g_print ("nmea_handler: gpsd: lat part2: %s\n", b);
+ if (!gui_status.posmode)
+ {
+ gdouble cl;
+ if ( mydebug + nmea_handler_debug > 80 )
+ g_print ("nmea_handler: gpsd: lat atof(%s):%f \n", b,atof(b));
+ cl = latdegree + atof (b) / 60.0;
+ if ( mydebug + nmea_handler_debug > 80 )
+ g_print ("nmea_handler: gpsd: cl: %f\n", cl);
+
+ if (field[4][0] == 'S')
+ cl = cl * -1;
+ if ((cl >= -90.0) && (cl <= 90.0))
+ coords.current_lat = cl;
+ breitri = field[4][0];
+ g_snprintf (b, sizeof (b), " %8.5f%s%c", coords.current_lat, gradsym, breitri);
+ if ( mydebug + nmea_handler_debug > 60 )
+ {
+ g_print ("nmea_handler: RMC lat: %8.5f\n", coords.current_lat);
+ }
+ }
+
+ /* Longitude East / West */
+
+ /* if field[5] is shorter than 10 characters, add zeroes in the beginning */
+ if (strlen (field[5]) < 9)
+ {
+ if ( mydebug + nmea_handler_debug > 0 )
+ {
+ g_print ("nmea_handler: Longitude field %s is shorter than 10 characters. (%Zu)\n",
+ field[5], strlen (field[5]));
+ }
+ for (i = 0; i < 10; i++)
+ {
+ b[i] = '0';
+ }
+ b[10] = 0;
+ g_strlcpy (b + (10 - strlen (field[5])), field[5], sizeof (b));
+ g_strlcpy (field[5], b, sizeof (field[5]));
+ }
+
+ b[0] = field[5][0];
+ b[1] = field[5][1];
+ b[2] = field[5][2];
+ b[3] = 0;
+ longdegree = atoi (b);
+
+ b[0] = field[5][3];
+ b[1] = field[5][4];
+ b[2] = '.';
+ b[3] = field[5][6];
+ b[4] = field[5][7];
+ b[5] = field[5][8];
+ b[6] = field[5][9];
+ b[7] = 0;
+ if (!gui_status.posmode)
+ {
+ gdouble cl;
+ cl = longdegree + atof (b) / 60.0;
+ if ( mydebug + nmea_handler_debug > 60 )
+ g_print ("nmea_handler: RMC dir: %c\n", field[6][0]);
+ if (field[6][0] == 'W')
+ cl = cl * -1;
+ if ((cl >= -180.0) && (cl <= 180.0))
+ coords.current_lon = cl;
+ langri = field[6][0];
+ g_snprintf (b, sizeof (b), " %8.5f%s%c", coords.current_lon, gradsym, langri);
+ if ( mydebug + nmea_handler_debug > 60 )
+ {
+ g_print ("nmea_handler: RMC lon: %8.5f\n", coords.current_lon);
+ }
+ }
+
+ /* speed */
+ b[0] = field[7][0];
+ b[1] = field[7][1];
+ b[2] = field[7][2];
+ b[3] = '.';
+ b[4] = field[7][4];
+ b[5] = 0;
+ current.groundspeed = atof (b) * 1.852 * milesconv;
+
+ // What hapens here with b or mapfilename?
+ g_snprintf (b, sizeof (b), " %s: %s", _("Map"), mapfilename);
+
+ /* g_print("Field %s\n",field[8]); */
+ b[0] = field[8][0];
+ b[1] = field[8][1];
+ b[2] = field[8][2];
+ b[3] = '.';
+ b[4] = field[8][4];
+ b[5] = 0;
+ /* heading is the course we are driving */
+ current.heading = atof (b);
+ current.heading = current.heading * M_PI / 180;
+
+ {
+ int h, m, s;
+ h = m = s = 0;
+ if (strcmp (utctime, "n/a") != 0)
+ {
+ sscanf (utctime, "%d:%d.%d", &h, &m, &s);
+ h += zone;
+ if (h > 23)
+ h -= 24;
+ if (h < 0)
+ h += 24;
+ g_snprintf (loctime, sizeof (loctime), "%d:%02d", h, m);
+ }
+ else
+ g_strlcpy (loctime, "n/a", sizeof (loctime));
+ }
+
+}
+
+/* *****************************************************************************
+ * show satellites signal level
+ */
+gint
+convertGSV (char *f)
+{
+ gchar field[50][100], b[500];
+ gint i, l, i2, j = 0, start = 0, n, db, anz, az, el;
+
+ memset (b, 0, 100);
+ l = strlen (f);
+ for (i = 0; i < l; i++)
+ {
+ if ((f[i] == ',') || (f[i] == '*'))
+ {
+ g_strlcpy (field[j], (f + start), 100);
+ field[j][i - start] = 0;
+ start = i + 1;
+ j++;
+ }
+ }
+ if ( mydebug + nmea_handler_debug > 80 )
+ {
+ g_print ("nmea_handler: gpsd: GSV Fields:\n");
+ g_print ("nmea_handler: gpsd: ");
+ for (i = 0; i < j; i++)
+ {
+ g_print ("%d:%s$", i, field[i]);
+ }
+ g_print ("\n");
+ }
+ if (j > 40)
+ {
+ g_print ("nmea_handler: gpsd: GPGSV: wrong number of fields (%d)\n", j);
+ return FALSE;
+ }
+
+ if (field[2][0] == '1')
+ satbit = satbit | 1;
+ if (field[2][0] == '2')
+ satbit = satbit | 2;
+ if (field[2][0] == '3')
+ satbit = satbit | 4;
+
+ anz = atoi (field[3]);
+ b[0] = field[1][0];
+ b[1] = 0;
+ i2 = atof (b);
+ if (mydebug + nmea_handler_debug && ( i2 != satbit))
+ g_print ("nmea_handler: gpsd: convertGSV(): bits should be: %d is: %d\n", i2, satbit);
+ g_snprintf (b, sizeof (b), "Satellites: %d\n", anz);
+ if (anz != oldsatsanz)
+ newsatslevel = TRUE;
+ oldsatsanz = anz;
+
+ for (i = 4; i < j; i += 4)
+ {
+ n = atoi (field[i]);
+ if (n > MAXSATS)
+ {
+ fprintf (stderr,
+ "gpsd: illegal satellite number: %d, ignoring\n", n);
+ continue;
+ }
+ db = atoi (field[i + 3]);
+ el = atoi (field[i + 1]);
+ az = atoi (field[i + 2]);
+ if ( mydebug + nmea_handler_debug > 80 )
+ fprintf (stderr,
+ "nmea_handler: gpsd: satnumber: %2d elev: %3d azimut: %3d signal %3ddb\n",
+ n, el, az, db);
+
+ satlist[n][0] = n;
+ satlist[n][1] = db;
+ satlist[n][2] = el;
+ satlist[n][3] = az;
+ }
+
+ if (((pow (2, i2)) - 1) == satbit)
+ {
+ sats_in_view = 0;
+ for (i = 0; i < MAXSATS; i++)
+ if (satlist[i][0] != 0)
+ {
+ g_snprintf (b, sizeof (b), "% 2d: % 2ddb ",
+ satlist[i][0], satlist[i][1]);
+ sats_in_view++;
+ }
+ satbit = 0;
+
+ memcpy (satlistdisp, satlist, sizeof (satlist));
+ memset (satlist, 0, sizeof (satlist));
+ newsatslevel = TRUE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/* ******************************************************************
+ * show altitude and satfix
+ */
+void
+convertGGA (char *f)
+{
+ gchar field[50][100], b[500];
+ gint i, l, j = 0, start = 0;
+ gint longdegree, latdegree;
+ gchar langri, breitri;
+
+ memset (b, 0, 100);
+ l = strlen (f);
+ for (i = 0; i < l; i++)
+ {
+ if ((f[i] == ',') || (f[i] == '*'))
+ {
+ g_strlcpy (field[j], (f + start), 100);
+ field[j][i - start] = 0;
+ start = i + 1;
+ j++;
+ }
+ }
+ if ( mydebug + nmea_handler_debug > 80 )
+ {
+ g_print ("nmea_handler: gpsd: GGA Fields: ");
+ for (i = 0; i < j; i++)
+ {
+ g_print ("%d:%s$", i, field[i]);
+ }
+ g_print ("\n");
+ }
+
+ if ((j != 15) && (j != 16))
+ {
+ g_print ("GPGGA: wrong number of fields (%d)\n", j);
+ return;
+ }
+
+ /* the receiver sends no GPRMC, so we get the data from here */
+ if (!haveRMCsentence)
+ {
+ gint mysecs;
+
+ if ( mydebug + nmea_handler_debug > 80 )
+ g_print ("nmea_handler: gpsd: got no RMC data, using GGA data\n");
+ g_snprintf (b, sizeof (b), "%c%c", field[1][4], field[1][5]);
+ sscanf (b, "%d", &mysecs);
+ if (mysecs != NMEAoldsecs)
+ {
+ NMEAsecs = mysecs - NMEAoldsecs;
+ if (NMEAsecs < 0)
+ NMEAsecs += 60;
+ NMEAoldsecs = mysecs;
+ }
+ /* g_print("nmeasecs: %.2f mysecs: %d, nmeaoldsecs: %d\n", NMEAsecs, */
+ /* mysecs, NMEAoldsecs); */
+ g_snprintf (b, sizeof (b), "%c%c:%c%c.%c%c ", field[1][0],
+ field[1][1], field[1][2], field[1][3],
+ field[1][4], field[1][5]);
+ g_strlcpy (utctime, b, sizeof (utctime));
+
+ if (field[6][0] == '0')
+ {
+ current.gpsfix = 1;
+ haveposcount = 0;
+ return;
+ }
+ else
+ {
+ current.gpsfix = 2;
+ haveposcount++;
+ if (haveposcount == 3)
+ {
+ rebuildtracklist ();
+ }
+ }
+
+ /* Latitude North / South */
+ /* if field[2] is shorter than 9 characters, add zeroes in beginning */
+ if (strlen (field[2]) < 9)
+ {
+ if ( mydebug + nmea_handler_debug > 0 )
+ {
+ g_print
+ ("nmea_handler: Latitude field %s is shorter than 9 characters. (%Zu)\n",
+ field[2], strlen (field[2]));
+ }
+ for (i = 0; i < 9; i++)
+ {
+ b[i] = '0';
+ }
+ b[9] = 0;
+ g_strlcpy (b + (9 - strlen (field[2])), field[2], sizeof (b));
+ g_strlcpy (field[2], b, sizeof (field[2]));
+ }
+
+ b[0] = field[2][0];
+ b[1] = field[2][1];
+ b[2] = 0;
+ latdegree = atoi (b);
+
+
+ b[0] = field[2][2];
+ b[1] = field[2][3];
+ b[2] = '.';
+ b[3] = field[2][5];
+ b[4] = field[2][6];
+ b[5] = field[2][7];
+ b[6] = field[2][8];
+ b[7] = 0;
+ if ( mydebug + nmea_handler_debug > 80 )
+ fprintf (stderr, "nmea_handler: gpsd: posmode: %d\n",
+ gui_status.posmode);
+ if (!gui_status.posmode)
+ {
+ gdouble cl;
+ cl = latdegree + atof (b) / 60.0;
+ if (field[3][0] == 'S')
+ cl = cl * -1;
+ if ((cl >= -90.0) && (cl <= 90.0))
+ coords.current_lat = cl;
+
+ breitri = field[3][0];
+ /* fprintf (stderr, "%8.5f%s%c cl:%f\n", current_lat, gradsym, breitri,cl); */
+ if ( mydebug + nmea_handler_debug > 10 )
+ {
+ g_print ("nmea_handler: lat: %8.5f\n", coords.current_lat);
+ }
+ }
+
+ /* Longitude East / West */
+ /* if field[4] is shorter than 10 chars, add zeroes in the beginning */
+ if (strlen (field[4]) < 10)
+ {
+ if ( mydebug + nmea_handler_debug > 10 )
+ {
+ g_print
+ ("nmea_handler: Longitude field %s is shorter than 10 characters. (%Zu)\n",
+ field[4], strlen (field[4]));
+ }
+ for (i = 0; i < 10; i++)
+ {
+ b[i] = '0';
+ }
+ b[10] = 0;
+ g_strlcpy (b + (10 - strlen (field[4])), field[4], sizeof (b));
+ g_strlcpy (field[4], b, sizeof (field[4]));
+ }
+
+ b[0] = field[4][0];
+ b[1] = field[4][1];
+ b[2] = field[4][2];
+ b[3] = 0;
+ longdegree = atoi (b);
+
+ b[0] = field[4][3];
+ b[1] = field[4][4];
+ b[2] = '.';
+ b[3] = field[4][6];
+ b[4] = field[4][7];
+ b[5] = field[4][8];
+ b[6] = field[4][9];
+ b[7] = 0;
+
+ if (!gui_status.posmode && !current.simmode)
+ {
+ gdouble cl;
+ cl = longdegree + atof (b) / 60.0;
+ if (field[5][0] == 'W')
+ cl = cl * -1;
+ if ((cl >= -180.0) && (cl <= 180.0))
+ coords.current_lon = cl;
+
+ langri = field[5][0];
+ /* fprintf (stderr, "%8.5f%s%c cl:%f\n", coords.current_lon, gradsym, langri,cl); */
+ if ( mydebug + nmea_handler_debug > 0 )
+ {
+ g_print ("nmea_handler: lon: %8.5f\n", coords.current_lon);
+ }
+ }
+
+ if ( mydebug + nmea_handler_debug > 80 )
+ g_print ("nmea_handler: gpsd: GGA pos: %f %f\n", coords.current_lat, coords.current_lon);
+ }
+
+ satfix = g_strtod (field[6], 0);
+ sats_used = g_strtod (field[7], 0);
+ if (current.gpsfix > 1)
+ {
+ current.altitude = g_strtod (field[9], 0);
+ if ( mydebug + nmea_handler_debug > 80 )
+ g_print ("nmea_handler: gpsd: Altitude: %.1f, Fix: %d\n",
+ current.altitude, satfix);
+ }
+ else
+ {
+ current.groundspeed = 0;
+ sats_used = 0;
+ }
+ {
+ int h, m, s;
+ h = m = s = 0;
+ if (strcmp (utctime, "n/a") != 0)
+ {
+ sscanf (utctime, "%d:%d.%d", &h, &m, &s);
+ h += zone;
+ if (h > 23)
+ h -= 24;
+ if (h < 0)
+ h += 24;
+ g_snprintf (loctime, sizeof (loctime), "%d:%02d", h, m);
+ }
+ else
+ g_strlcpy (loctime, "n/a", sizeof (loctime));
+ }
+}
+
+
+/* ******************************************************************
+ * show estimated position error $PGRME (Garmin only)
+ */
+void
+convertRME (char *f)
+{
+ gchar field[50][100], b[500];
+ gint i, l, j = 0, start = 0;
+
+ memset (b, 0, 100);
+ l = strlen (f);
+ for (i = 0; i < l; i++)
+ {
+ if ((f[i] == ',') || (f[i] == '*'))
+ {
+ g_strlcpy (field[j], (f + start), 100);
+ field[j][i - start] = 0;
+ start = i + 1;
+ j++;
+ }
+ }
+ if ( mydebug + nmea_handler_debug > 80 )
+ {
+ g_print ("nmea_handler: gpsd: RME Fields: ");
+ for (i = 0; i < j; i++)
+ g_print ("%d:%s$", i, field[i]);
+ g_print ("\n");
+ }
+ if (current.gpsfix > 1)
+ {
+ precision = g_strtod (field[1], 0);
+ if ( mydebug + nmea_handler_debug > 80 )
+ g_print ("nmea_handler: gpsd: RME precision: %.1f\n", precision);
+ }
+}
diff --git a/src/nmea_handler.h b/src/nmea_handler.h
new file mode 100644
index 0000000..d271416
--- /dev/null
+++ b/src/nmea_handler.h
@@ -0,0 +1,50 @@
+/***********************************************************************
+
+Copyright (c) 2001,2002 Fritz Ganter <ganter@ganter.at>
+
+Website: www.kraftvoll.at/software
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+/*
+$Log$
+Revision 1.1 1994/06/10 02:11:00 tweety
+move nmea handling to it's own file Part 1
+
+
+
+*/
+
+
+#ifndef NMEA_HANDLER_H
+#define NMEA_HANDLER_H
+gint get_position_data_cb (GtkWidget * widget, guint * datum);
+void convertRMC (char *f);
+void convertGGA (char *f);
+void convertRME (char *f);
+void convertGSA (char *f);
+
+gint checksum (gchar * text);
+FILE *opennmea (const char *name);
+void write_nmea_line (const char *line);
+void gen_nmea_coord (char *out);
+gint write_nmea_cb (GtkWidget * widget, guint * datum);
+
+
+
+#endif /* NMEA_HANDLER_H */
diff --git a/src/poi.c b/src/poi.c
new file mode 100644
index 0000000..b59a5a0
--- /dev/null
+++ b/src/poi.c
@@ -0,0 +1,1392 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+
+/*
+ * poi_ support module: display
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <sys/time.h>
+#include <math.h>
+#include <gmodule.h>
+#include <gdk/gdktypes.h>
+#include "gtk/gtk.h"
+
+#include "gpsdrive.h"
+#include "poi.h"
+#include "config.h"
+#include "gettext.h"
+#include "icons.h"
+#include <gpsdrive_config.h>
+#include "gui.h"
+
+#include "gettext.h"
+#include <libxml/xmlreader.h>
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+
+extern gchar language[];
+extern gint do_unit_test;
+extern gint maploaded;
+extern gint isnight, disableisnight;
+extern color_struct colors;
+extern gdouble wp_saved_target_lat, wp_saved_target_lon;
+extern gdouble wp_saved_posmode_lat, wp_saved_posmode_lon;
+extern gint debug, mydebug;
+extern GtkWidget *map_drawingarea;
+extern gint usesql;
+extern glong mapscale;
+extern gdouble dbdistance;
+extern gint friends_poi_id[TRAVEL_N_MODES];
+extern coordinate_struct coords;
+extern currentstatus_struct current;
+extern GdkGC *kontext_map;
+
+extern GdkPixbuf *posmarker_img;
+extern GdkGC *kontext;
+
+char txt[5000];
+PangoLayout *poi_label_layout;
+#include "mysql/mysql.h"
+
+extern MYSQL mysql;
+extern MYSQL_RES *res;
+extern MYSQL_ROW row;
+#define MAXDBNAME 30
+extern char poitypetable[MAXDBNAME];
+
+// keep actual visible POIs in Memory
+poi_struct *poi_list;
+
+// keep POI info from last search result in Memory
+poi_struct *poi_result;
+GtkListStore *poi_result_tree;
+
+glong poi_nr; // current number of poi to count
+glong poi_list_count; // max index of POIs actually in memory
+guint poi_result_count; // max index of POIs found in POI search
+glong poi_limit = -1; // max allowed index (if you need more you have to alloc memory)
+
+gchar poi_label_font[100];
+GdkColor poi_colorv;
+PangoFontDescription *pfd;
+PangoLayout *poi_label_layout;
+
+poi_type_struct poi_type_list[poi_type_list_max];
+int poi_type_list_count = 0;
+GtkTreeStore *poi_types_tree;
+
+gdouble poi_lat_lr = 0, poi_lon_lr = 0;
+gdouble poi_lat_ul = 0, poi_lon_ul = 0;
+
+
+/* ****************************************************************** */
+
+void poi_rebuild_list (void);
+void get_poitype_tree (void);
+
+
+/* *******************************************************
+ * check, which poi_types should be shown in the map.
+ * filtering is only done on the base category level.
+ */
+void
+update_poi_type_filter ()
+{
+ GtkTreeIter t_iter;
+ gboolean t_selected;
+ gchar *t_name;
+ gchar t_string[200];
+ gchar t_config[2000];
+
+ if (mydebug > 21)
+ fprintf (stderr, "update_poi_type_filter:\n");
+
+ g_strlcpy (current.poifilter, "AND (", sizeof (current.poifilter));
+ g_strlcpy (local_config.poi_filter, "", sizeof (local_config.poi_filter));
+
+ gtk_tree_model_get_iter_first
+ (GTK_TREE_MODEL (poi_types_tree), &t_iter);
+
+ do
+ {
+ gtk_tree_model_get (GTK_TREE_MODEL (poi_types_tree), &t_iter,
+ POITYPE_NAME, &t_name,
+ POITYPE_SELECT, &t_selected, -1);
+ if (!t_selected)
+ {
+ /* build SQL string for filter */
+ g_snprintf (t_string, sizeof (t_string),
+ "poi_type.name NOT LIKE \"%s%%\" AND ",
+ t_name);
+ g_strlcat (current.poifilter,
+ t_string, sizeof (current.poifilter));
+
+ /* build settings string for config file */
+ g_snprintf (t_config, sizeof (t_config),
+ "%s|", t_name);
+ g_strlcat (local_config.poi_filter,
+ t_config, sizeof (local_config.poi_filter));
+ }
+ }
+ while (gtk_tree_model_iter_next
+ (GTK_TREE_MODEL (poi_types_tree), &t_iter));
+
+ g_strlcat (current.poifilter, "TRUE)", sizeof (current.poifilter));
+
+ g_free (t_name);
+
+ current.needtosave = TRUE;
+ poi_draw_list (TRUE);
+}
+
+
+/* *******************************************************
+ * search database for POIs filtered by data entered
+ * into the POI-Lookup window
+ */
+guint
+poi_get_results (const gchar *text, const gchar *pdist, const gint posflag, const gint typeflag, const gchar *type)
+{
+ gdouble lat, lon, dist;
+ gdouble lat_min, lon_min;
+ gdouble lat_max, lon_max;
+ gdouble dist_lat, dist_lon;
+ gdouble temp_lon, temp_lat;
+ gdouble temp_dist_num;
+
+ char sql_query[5000];
+ char type_filter[3000];
+ gchar *temp_text;
+ char temp_dist[15];
+ int r, rges;
+ int temp_id;
+
+ GtkTreeIter iter;
+
+ // clear results from last search
+ gtk_list_store_clear (poi_result_tree);
+
+ dist = g_strtod (pdist, NULL);
+ if (dist <= 0)
+ dist = dbdistance;
+
+ if (posflag)
+ {
+ lat = wp_saved_target_lat;
+ lon = wp_saved_target_lon;
+ }
+ else
+ {
+ if (gui_status.posmode)
+ {
+ lat = wp_saved_posmode_lat;
+ lon = wp_saved_posmode_lon;
+ }
+ else
+ {
+ lat = coords.current_lat;
+ lon = coords.current_lon;
+ }
+ }
+
+ // calculate bbox around starting point derived from specified distance
+ // latitude: 1 degree = 111,13 km
+ // longitude: 1 degree = 111,13 km * cos(latitude)
+ // (this is not very accurate, but should be suitable for filtering pois)
+ dist_lat = fabs (dist/111.13);
+ if (lat==90.0 || lat ==-90.0)
+ dist_lon = 180;
+ else
+ dist_lon = fabs (dist/(111.13*cos(lat)));
+
+ lat_min = lat-dist_lat;
+ lon_min = lon-dist_lon;
+ lat_max = lat+dist_lat;
+ lon_max = lon+dist_lon;
+
+ if (mydebug > 25)
+ {
+ fprintf (stderr, " --- lat: %f lon: %f dist: %f\n", lat, lon, dist);
+ fprintf (stderr, " --- lat_min: %f lat_max: %f dist_lat: %f\n", lat_min, lat_max, dist_lat);
+ fprintf (stderr, " --- lon_min: %f lon_max: %f dist_lon: %f\n", lon_min, lon_max, dist_lon);
+ }
+
+ if (lon_min < -180.0) lon_min = -180.0;
+ if (lon_max > 180.0) lon_max = 180.0;
+ if (lat_min < -90.0) lat_min = -90.0;
+ if (lat_max > 90.0) lat_max = 90.0;
+
+ /* choose poi_type_ids to search */
+ if (typeflag)
+ {
+ g_snprintf (type_filter, sizeof (type_filter),
+ "AND (poi_type.name LIKE \'%s%%\')",type);
+ }
+ else
+ {
+ g_snprintf (type_filter, sizeof (type_filter), " ");
+ }
+
+ /* prepare search text for database query */
+ temp_text = escape_sql_string (text);
+ g_strdelimit (temp_text, "*", '%');
+
+ g_snprintf (sql_query, sizeof (sql_query),
+ "SELECT poi.poi_id,poi.name,poi.comment,poi.poi_type_id,"
+ "poi.lon,poi.lat FROM poi INNER JOIN poi_type ON"
+ " poi.poi_type_id=poi_type.poi_type_id "
+ " WHERE ( lat BETWEEN %.6f AND %.6f ) AND ( lon BETWEEN %.6f"
+ " AND %.6f ) AND (poi.name LIKE '%%%s%%' OR comment LIKE '%%%s%%')"
+ " %s LIMIT %d;",
+ lat_min, lat_max, lon_min, lon_max, temp_text, temp_text,
+ type_filter, local_config.poi_results_max);
+
+ if (mydebug > 20)
+ printf ("poi_get_results: POI mysql query: %s\n", sql_query);
+
+ if (dl_mysql_query (&mysql, sql_query))
+ {
+ printf ("poi_get_results: Error in query: \n");
+ fprintf (stderr, "poi_get_results: Error in query: %s\n",
+ dl_mysql_error (&mysql));
+ return 0;
+ }
+
+ if (!(res = dl_mysql_store_result (&mysql)))
+ {
+ fprintf (stderr, "Error in store results: %s\n",
+ dl_mysql_error (&mysql));
+ dl_mysql_free_result (res);
+ res = NULL;
+ return 0;
+ }
+
+ g_free (temp_text);
+
+ rges = r = 0;
+ poi_nr = 0;
+ while ((row = dl_mysql_fetch_row (res)))
+ {
+ rges++;
+
+ if (mydebug > 20)
+ fprintf (stderr, "Query Result: %s\t%s\t%s\t%s\n",
+ row[0], row[1], row[2], row[3]);
+ // get next free mem for point
+ poi_nr++;
+ if (poi_nr > poi_limit)
+ {
+ poi_limit = poi_nr + 10000;
+ if (mydebug > 20)
+ g_print ("Try to allocate Memory for %ld poi\n", poi_limit);
+ poi_result = g_renew (poi_struct, poi_result, poi_limit);
+ if (NULL == poi_result)
+ {
+ g_print ("Error: Cannot allocate Memory for %ld poi\n", poi_limit);
+ poi_limit = -1;
+ return 0;
+ }
+ }
+
+ // Save retrieved poi information into structure
+ (poi_result + poi_nr)->poi_id = (gint) g_strtod (row[0], NULL);
+ g_strlcpy ((poi_result + poi_nr)->name, row[1], sizeof ((poi_result + poi_nr)->name));
+ if (row[2] == NULL)
+ g_strlcpy ((poi_result + poi_nr)->comment, "n/a", sizeof ((poi_result + poi_nr)->comment));
+ else
+ g_strlcpy ((poi_result + poi_nr)->comment, row[2], sizeof ((poi_result + poi_nr)->comment));
+ (poi_result + poi_nr)->poi_type_id = (gint) g_strtod (row[3], NULL);
+ temp_id = (gint) g_strtod (row[3], NULL);
+ (poi_result + poi_nr)->lon = g_strtod (row[4], NULL);
+ temp_lon = g_strtod (row[4], NULL);
+ (poi_result + poi_nr)->lat = g_strtod (row[5], NULL);
+ temp_lat = g_strtod (row[5], NULL);
+ temp_dist_num = calcdist (temp_lon, temp_lat);
+ g_snprintf (temp_dist, sizeof (temp_dist), "%9.3f", temp_dist_num);
+
+ gtk_list_store_append (poi_result_tree, &iter);
+ gtk_list_store_set (poi_result_tree, &iter,
+ RESULT_ID, (poi_result + poi_nr)->poi_id,
+ RESULT_NAME, (poi_result + poi_nr)->name,
+ RESULT_COMMENT, (poi_result + poi_nr)->comment,
+ RESULT_TYPE_TITLE, poi_type_list[temp_id].title,
+ RESULT_TYPE_NAME, poi_type_list[temp_id].name,
+ RESULT_TYPE_ICON, poi_type_list [temp_id].icon,
+ RESULT_DISTANCE, temp_dist,
+ RESULT_DIST_NUM, temp_dist_num,
+ RESULT_LAT, temp_lat,
+ RESULT_LON, temp_lon,
+ -1);
+
+ /* check for friendsd entry */
+ if (g_str_has_prefix(poi_type_list[temp_id].name, "people.friendsd"))
+ g_print ("\nfriend\n");
+
+ }
+
+ poi_result_count = poi_nr;
+
+ if (mydebug > 20)
+ printf (_("%ld(%d) rows read\n"), poi_list_count, rges);
+
+ if (!dl_mysql_eof (res))
+ {
+ fprintf (stderr, "poi_get_results: Error in dl_mysql_eof: %s\n",
+ dl_mysql_error (&mysql));
+ dl_mysql_free_result (res);
+ res = NULL;
+ return 0;
+ }
+
+ dl_mysql_free_result (res);
+ res = NULL;
+
+ return poi_result_count;
+
+}
+
+
+/* *******************************************************
+ * draw standard poi label
+ */
+void
+draw_label (char *txt, gdouble posx, gdouble posy)
+{
+ gint width, height;
+ gint k, k2;
+
+ if (!local_config.showpoilabel)
+ {
+ if (mydebug > 20)
+ printf ("draw_label: drawing of label is disabled\n");
+ return;
+ }
+
+ if (mydebug > 30)
+ fprintf (stderr, "draw_label(%s,%g,%g)\n", txt, posx, posy);
+
+ gdk_gc_set_foreground (kontext_map, &colors.textback);
+
+ poi_label_layout = gtk_widget_create_pango_layout (map_drawingarea, txt);
+ pfd = pango_font_description_from_string ("Sans 8");
+ if (poi_list_count > 200)
+ pfd = pango_font_description_from_string ("Sans 6");
+
+ pango_layout_set_font_description (poi_label_layout, pfd);
+ pango_layout_get_pixel_size (poi_label_layout, &width, &height);
+ k = width + 4;
+ k2 = height;
+
+ gdk_gc_set_function (kontext_map, GDK_COPY);
+
+ gdk_gc_set_function (kontext_map, GDK_AND);
+
+ { // Draw rectangle arround Text
+ // gdk_gc_set_foreground (kontext, &textbacknew);
+ gdk_gc_set_foreground (kontext_map, &colors.darkgrey);
+ gdk_draw_rectangle (drawable, kontext_map, 1,
+ posx + 13, posy - k2 / 2, k + 1, k2);
+
+ }
+
+ poi_label_layout = gtk_widget_create_pango_layout (map_drawingarea, txt);
+ pango_layout_set_font_description (poi_label_layout, pfd);
+
+ gdk_draw_layout_with_colors (drawable, kontext_map,
+ posx + 15, posy - k2 / 2,
+ poi_label_layout, &colors.lightgrey, NULL);
+ if (poi_label_layout != NULL)
+ g_object_unref (G_OBJECT (poi_label_layout));
+ /* freeing PangoFontDescription, cause it has been copied by prev. call */
+ pango_font_description_free (pfd);
+}
+
+
+/* *******************************************************
+ * draw friends label
+ */
+void
+draw_label_friend (char *txt, gdouble posx, gdouble posy)
+{
+ gint width, height;
+ gint k, k2;
+
+ if (mydebug > 30)
+ fprintf (stderr, "draw_label(%s,%g,%g)\n", txt, posx, posy);
+
+ poi_label_layout = gtk_widget_create_pango_layout (map_drawingarea, txt);
+
+ pfd = pango_font_description_from_string (local_config.font_friends);
+ gdk_gc_set_foreground (kontext_map, &colors.textbacknew);
+
+ pango_layout_set_font_description (poi_label_layout, pfd);
+ pango_layout_get_pixel_size (poi_label_layout, &width, &height);
+ k = width + 4;
+ k2 = height;
+
+ gdk_gc_set_function (kontext_map, GDK_COPY);
+ gdk_gc_set_function (kontext_map, GDK_AND);
+
+ gdk_draw_layout_with_colors (drawable, kontext_map,
+ posx + 16, posy - k2 / 2 + 1,
+ poi_label_layout, &colors.black, NULL);
+
+ gdk_draw_layout_with_colors (drawable, kontext_map,
+ posx + 15, posy - k2 / 2,
+ poi_label_layout, &colors.friends, NULL);
+ if (poi_label_layout != NULL)
+ g_object_unref (G_OBJECT (poi_label_layout));
+ /* freeing PangoFontDescription, cause it
+ * has been copied by prev. call */
+ pango_font_description_free (pfd);
+}
+
+
+int
+poi_check_if_moved (void)
+{
+ gdouble lat_lr, lon_lr;
+ gdouble lat_ul, lon_ul;
+
+ if (poi_lat_lr == 0 && poi_lon_lr == 0 &&
+ poi_lat_ul == 0 && poi_lon_ul == 0)
+ return 1;
+
+ calcxytopos (SCREEN_X, SCREEN_Y, &lat_lr, &lon_lr, current.zoom);
+ calcxytopos (0, 0, &lat_ul, &lon_ul, current.zoom);
+
+ if (poi_lat_lr == lat_lr && poi_lon_lr == lon_lr &&
+ poi_lat_ul == lat_ul && poi_lon_ul == lon_ul)
+ return 0;
+ return 1;
+}
+
+
+/* ******************************************************************
+ * get poi_type_id from given poi_type name
+*/
+gint
+poi_type_id_from_name (gchar name[POI_TYPE_LIST_STRING_LENGTH])
+{
+ int i;
+ for (i = 0; i < poi_type_list_max; i++)
+ {
+ if (strcmp (poi_type_list[i].name,name) == 0)
+ return poi_type_list[i].poi_type_id;
+ }
+ return 1; // return poi_type 1 = 'unknown' if not in table
+}
+
+
+/* ******************************************************************
+ * check if poi is friend
+*/
+gboolean
+poi_is_friend (gint type)
+{
+ gint i;
+
+ for (i = 0; i < TRAVEL_N_MODES; i++)
+ {
+ if (friends_poi_id[i] == type)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* ******************************************************************
+ * add new row to poitype tree
+*/
+static gboolean
+poitypetree_addrow (guint i, GtkTreeIter *parent)
+{
+ GtkTreeIter iter;
+
+ gtk_tree_store_append (poi_types_tree, &iter, parent);
+
+ gtk_tree_store_set (poi_types_tree, &iter,
+ POITYPE_ID, poi_type_list[i].poi_type_id,
+ POITYPE_NAME, poi_type_list[i].name,
+ POITYPE_ICON, poi_type_list[i].icon,
+ POITYPE_SCALE_MIN, poi_type_list[i].scale_min,
+ POITYPE_SCALE_MAX, poi_type_list[i].scale_max,
+ POITYPE_DESCRIPTION, poi_type_list[i].description,
+ POITYPE_TITLE, poi_type_list[i].title,
+ POITYPE_SELECT, FALSE,
+ -1);
+
+ if (mydebug > 30)
+ {
+ fprintf (stderr,
+ "poitypetree_addrow:added %d - %s\n",
+ poi_type_list[i].poi_type_id,
+ poi_type_list[i].name);
+ }
+
+ return TRUE;
+}
+
+
+/* ******************************************************************
+ * find parent for given poitype and add new entry if found
+ */
+static gboolean poitypetree_find_parent (
+ GtkTreeModel *model, GtkTreePath *path,
+ GtkTreeIter *iter, guint i)
+{
+ gchar *value;
+
+ gchar *parent_name;
+ gint k;
+ guint l = 0;
+
+ for (k = poi_type_list[i].level; k>0; k--)
+ {
+ l += strcspn (
+ (poi_type_list[i].name + poi_type_list[i].level
+ - k + l), ".");
+ }
+
+ parent_name = g_strndup (poi_type_list[i].name,
+ poi_type_list[i].level + l -1);
+
+ gtk_tree_model_get (model, iter, POITYPE_NAME, &value, -1);
+
+ if (g_ascii_strcasecmp (parent_name, (gchar *) value) == 0)
+ {
+
+ if (mydebug > 40)
+ {
+ fprintf (stderr,
+ "poitypetree_find_parent: %d+%d : %s => %s\n",
+ l, poi_type_list[i].level - 1,
+ poi_type_list[i].name, parent_name);
+ }
+ poitypetree_addrow (i, iter);
+ g_free (value);
+ g_free (parent_name);
+ return TRUE;
+ }
+ else
+ {
+ g_free (value);
+ g_free (parent_name);
+ return FALSE;
+ }
+}
+
+/* ******************************************************************
+ * sort poitype data from flat struct into a gtk-tree
+ */
+gboolean
+create_poitype_tree (guint max_level)
+{
+ guint i = 0;
+ guint j = 0;
+
+ if (mydebug > 20)
+ fprintf (stderr, "create_poitype_tree:\n");
+
+ /* insert base categories into tree */
+ for (i = 0; i < poi_type_list_max; i++)
+ {
+ if (strlen (poi_type_list[i].name) > 0)
+ {
+ if (poi_type_list[i].level == 0)
+ {
+ poitypetree_addrow (i, (GtkTreeIter *) NULL);
+ if (mydebug > 30)
+ {
+ fprintf (stderr,
+ "create_poitype_tree:"
+ " adding base type %s\n",
+ poi_type_list[i].name);
+ }
+ }
+ }
+ else
+ {
+ poi_type_list[i].level = 99;
+ }
+ }
+
+ /* insert subcategories into tree */
+ for (j = 1; j <= max_level; j++)
+ {
+ for (i = 0; i < poi_type_list_max; i++)
+ {
+ if (poi_type_list[i].level == j)
+ {
+ gtk_tree_model_foreach
+ (GTK_TREE_MODEL (poi_types_tree),
+ *(GtkTreeModelForeachFunc)
+ poitypetree_find_parent, (gpointer) i);
+ }
+ }
+ }
+
+ return gtk_tree_model_get_iter_first
+ (GTK_TREE_MODEL (poi_types_tree), &current.poitype_iter);
+}
+
+
+/* ******************************************************************
+ * get a list of all possible poi_types and load their icons
+*/
+void
+get_poitype_tree (void)
+{
+ if (mydebug > 25)
+ printf ("get_poitype_tree ()\n");
+
+ // Clear poi_type_tree
+ gtk_tree_store_clear (poi_types_tree);
+
+ guint counter = 0;
+ guint max_level = 0;
+
+ // get poi_type info from icons.xml
+ {
+ xmlTextReaderPtr xml_reader;
+ gchar iconsxml_file[200];
+ gint valid_poi_type = 0;
+ gint xml_status = 0; // 0 = empty, 1 = node, -1 = error
+ gint tag_type = 0; // 1 = start, 3 = #text, 15 = end
+ xmlChar *tag_name;
+ gchar t_scale_max[POI_TYPE_LIST_STRING_LENGTH];
+ gchar t_scale_min[POI_TYPE_LIST_STRING_LENGTH];
+ gchar t_title[POI_TYPE_LIST_STRING_LENGTH];
+ gchar t_title_en[POI_TYPE_LIST_STRING_LENGTH];
+ gchar t_title_lang[POI_TYPE_LIST_STRING_LENGTH];
+ gchar t_description[POI_TYPE_LIST_STRING_LENGTH];
+ gchar t_desc_en[POI_TYPE_LIST_STRING_LENGTH];
+ gchar t_desc_lang[POI_TYPE_LIST_STRING_LENGTH];
+ gchar t_name[POI_TYPE_LIST_STRING_LENGTH];
+ gchar t_poi_type_id[POI_TYPE_LIST_STRING_LENGTH];
+ guint i,j;
+
+ g_snprintf (iconsxml_file, sizeof (iconsxml_file),
+ "./data/map-icons/icons.xml" );
+ xml_reader = xmlNewTextReaderFilename(iconsxml_file);
+
+ if (xml_reader == NULL)
+ {
+ g_snprintf (iconsxml_file, sizeof (iconsxml_file),
+ "%s/icons.xml", local_config.dir_home);
+ xml_reader = xmlNewTextReaderFilename(iconsxml_file);
+ }
+ if (xml_reader == NULL)
+ {
+ g_snprintf (iconsxml_file, sizeof (iconsxml_file),
+ "%s/map-icons/icons.xml", DATADIR);
+ xml_reader = xmlNewTextReaderFilename(iconsxml_file);
+ }
+ if (xml_reader == NULL)
+ {
+ fprintf (stderr, "get_poitype_tree: File %s not found!\n",
+ iconsxml_file);
+ return;
+ }
+ if (mydebug > 10)
+ {
+ fprintf (stderr, "get_poitype_tree: Trying to parse file:"
+ "%s\n", iconsxml_file);
+ }
+ xml_status = xmlTextReaderRead(xml_reader);
+ while (xml_status == 1) /* parse complete file */
+ {
+ g_strlcpy (t_title, "n/a", sizeof(t_title));
+ g_strlcpy (t_title_en, "n/a", sizeof(t_title));
+ g_strlcpy (t_description, "n/a", sizeof(t_description));
+ g_strlcpy (t_desc_en, "n/a", sizeof(t_description));
+ g_strlcpy (t_name, "n/a", sizeof(t_name));
+ g_strlcpy (t_scale_min, "1", sizeof(t_scale_min));
+ g_strlcpy (t_scale_max, "50000", sizeof(t_scale_max));
+ valid_poi_type = 0;
+ tag_type = xmlTextReaderNodeType(xml_reader);
+ tag_name = xmlTextReaderName(xml_reader);
+ if (tag_type == 1 && xmlStrEqual(tag_name, BAD_CAST "rule"))
+ /* START element rule */
+ {
+ if (mydebug > 50) fprintf (stderr, "----------\n");
+ while ( tag_type != 15 || !xmlStrEqual(tag_name,
+ BAD_CAST "rule")) /* inside element rule */
+ {
+ xml_status = xmlTextReaderRead(xml_reader);
+ tag_type = xmlTextReaderNodeType(xml_reader);
+ tag_name = xmlTextReaderName(xml_reader);
+ if (tag_type == 1)
+ {
+ if (xmlStrEqual(tag_name, BAD_CAST "condition") && xmlStrEqual (xmlTextReaderGetAttribute(xml_reader, BAD_CAST "k"), BAD_CAST "poi"))
+ {
+ if (mydebug > 4)
+ fprintf(stderr, "*** poi = %s\n", xmlTextReaderGetAttribute(xml_reader, BAD_CAST "v"));
+ valid_poi_type = 1;
+ counter++;
+ continue;
+ }
+ if (xmlStrEqual(tag_name, BAD_CAST "scale_min")) /* scale_min */
+ {
+ do
+ {
+ xml_status = xmlTextReaderRead(xml_reader);
+ tag_type = xmlTextReaderNodeType(xml_reader);
+ tag_name = xmlTextReaderName(xml_reader);
+ if (tag_type == 3)
+ {
+ g_snprintf(t_scale_min, sizeof(t_scale_min), "%s", xmlTextReaderConstValue(xml_reader));
+ continue;
+ }
+ } while (tag_type != 15);
+ continue;
+ }
+ if (xmlStrEqual(tag_name, BAD_CAST "scale_max")) /* scale_max */
+ {
+ do
+ {
+ xml_status = xmlTextReaderRead(xml_reader);
+ tag_type = xmlTextReaderNodeType(xml_reader);
+ tag_name = xmlTextReaderName(xml_reader);
+ if (tag_type == 3)
+ {
+ g_snprintf(t_scale_max, sizeof(t_scale_max), "%s", xmlTextReaderConstValue(xml_reader));
+ continue;
+ }
+ } while (tag_type != 15);
+ continue;
+ }
+ if (xmlStrEqual(tag_name, BAD_CAST "title")) /* title */
+ {
+ g_snprintf(t_title_lang, sizeof(t_title_lang), "%s", xmlTextReaderGetAttribute(xml_reader, BAD_CAST "lang"));
+ do
+ {
+ xml_status = xmlTextReaderRead(xml_reader);
+ tag_type = xmlTextReaderNodeType(xml_reader);
+ tag_name = xmlTextReaderName(xml_reader);
+ if (tag_type == 3)
+ {
+ if (strcmp(t_title_lang, "en")==0)
+ {
+ g_snprintf(t_title_en, sizeof(t_title_en), "%s", xmlTextReaderConstValue (xml_reader));
+ continue;
+ }
+ if (strcmp(t_title_lang, language)==0)
+ {
+ g_snprintf(t_title, sizeof(t_title), "%s", xmlTextReaderConstValue(xml_reader));
+ continue;
+ }
+ }
+ } while (tag_type != 15);
+ continue;
+ }
+ if (xmlStrEqual(tag_name, BAD_CAST "description")) /* description */
+ {
+ g_snprintf(t_desc_lang, sizeof(t_desc_lang), "%s", xmlTextReaderGetAttribute(xml_reader, BAD_CAST "lang"));
+ do
+ {
+ xml_status = xmlTextReaderRead(xml_reader);
+ tag_type = xmlTextReaderNodeType(xml_reader);
+ tag_name = xmlTextReaderName(xml_reader);
+ if (tag_type == 3)
+ {
+ if (strcmp(t_desc_lang, "en")==0)
+ {
+ g_snprintf(t_desc_en, sizeof(t_desc_en), "%s", xmlTextReaderConstValue(xml_reader));
+ continue;
+ }
+ if (strcmp(t_desc_lang, language)==0)
+ {
+ g_snprintf(t_description, sizeof(t_description), "%s", xmlTextReaderConstValue(xml_reader));
+ continue;
+ }
+ }
+ } while (tag_type != 15);
+ continue;
+ }
+ if (xmlStrEqual(tag_name, BAD_CAST "geoinfo")) /* geoinfo */
+ {
+ while ( tag_type != 15 || !xmlStrEqual(tag_name, BAD_CAST "geoinfo")) /* inside element geoinfo */
+ {
+ xml_status = xmlTextReaderRead(xml_reader);
+ tag_type = xmlTextReaderNodeType(xml_reader);
+ tag_name = xmlTextReaderName(xml_reader);
+ if (tag_type == 1)
+ {
+ if (xmlStrEqual(tag_name, BAD_CAST "name")) /* name */
+ {
+ do
+ {
+ xml_status = xmlTextReaderRead(xml_reader);
+ tag_type = xmlTextReaderNodeType(xml_reader);
+ tag_name = xmlTextReaderName(xml_reader);
+ if (tag_type == 3)
+ {
+ g_snprintf(t_name, sizeof(t_name), "%s", xmlTextReaderConstValue(xml_reader));
+ continue;
+ }
+ } while (tag_type != 15);
+ continue;
+ }
+ if (xmlStrEqual(tag_name, BAD_CAST "poi_type_id")) /* poi_type_id */
+ {
+ do
+ {
+ xml_status = xmlTextReaderRead(xml_reader);
+ tag_type = xmlTextReaderNodeType(xml_reader);
+ tag_name = xmlTextReaderName(xml_reader);
+ if (tag_type == 3)
+ {
+ g_snprintf(t_poi_type_id, sizeof(t_poi_type_id), "%s", xmlTextReaderConstValue(xml_reader));
+ continue;
+ }
+ } while (tag_type != 15);
+ continue;
+ }
+ }
+ }
+ continue;
+ } /* END element geoinfo */
+ }
+ }
+ if (valid_poi_type)
+ {
+ int index = (gint) g_strtod (t_poi_type_id, NULL);
+ if (index >= poi_type_list_max)
+ {
+ fprintf (stderr, "get_poitype_tree: "
+ "index(%d) > poi_type_list_max(%d)\n",
+ index, poi_type_list_max);
+ continue;
+ }
+ if (poi_type_list_count < index)
+ {
+ poi_type_list_count = index;
+ }
+ poi_type_list[index].poi_type_id = index;
+ poi_type_list[index].scale_min = (gint) g_strtod (t_scale_min, NULL);
+ poi_type_list[index].scale_max = (gint) g_strtod (t_scale_max, NULL);
+
+ /* use english title/description,
+ * if no localized info is available */
+ if (strcmp(t_description, "n/a")==0)
+ g_strlcpy(t_description, t_desc_en, sizeof(t_description));
+ if (strcmp(t_title, "n/a")==0)
+ g_strlcpy(t_title, t_title_en, sizeof(t_title));
+
+
+ g_strlcpy (poi_type_list[index].description,
+ t_description, sizeof
+ (poi_type_list[index].description));
+ g_strlcpy (poi_type_list[index].title, t_title,
+ sizeof (poi_type_list[index].title));
+ g_strlcpy (poi_type_list[index].name, t_name,
+ sizeof(poi_type_list[index].name));
+ g_strlcpy (poi_type_list[index].icon_name, t_name,
+ sizeof(poi_type_list[index].icon_name));
+ poi_type_list[index].icon = read_themed_icon
+ (poi_type_list[index].icon_name);
+
+ j = 0;
+ for (i=0; i < strlen (poi_type_list[index].name); i++)
+ {
+ if (g_str_has_prefix
+ ((poi_type_list[index].name + i) , "."))
+ {
+ j++;
+ }
+ }
+ poi_type_list[index].level = j;
+ if (max_level < j)
+ {
+ max_level = j;
+ }
+
+ if (poi_type_list[index].icon == NULL)
+ {
+ if (mydebug > 40)
+ printf ("get_poitype_tree: %3d:Icon '%s' for '%s'\tnot found\n",
+ index, poi_type_list[index].icon_name, poi_type_list[index].name);
+ if (do_unit_test)
+ exit (-1);
+ }
+ }
+ } /* END element rule */
+ xml_status = xmlTextReaderRead(xml_reader);
+ }
+ xmlFreeTextReader(xml_reader);
+ if (xml_status != 0)
+ fprintf(stderr,
+ "get_poitype_tree: Failed to parse file: %s\n",
+ iconsxml_file);
+ else
+ fprintf (stdout, "Read %d POI-Types from %s\n",
+ counter, iconsxml_file);
+
+ }
+
+ if (mydebug > 20)
+ fprintf (stderr,
+ "get_poitype_tree: Loaded %d Icons for poi_types 1 - %d\n",
+ counter, poi_type_list_count);
+
+ create_poitype_tree (max_level);
+}
+
+
+/* *******************************************************
+ * if zoom, xoff, yoff or map are changed
+ * TODO: use the real datatype for reading from database
+ * (don't convert string to double)
+ * TODO: call this only if the above mentioned events occur!
+ */
+void
+poi_rebuild_list (void)
+{
+ char sql_query[5000];
+ struct timeval t;
+ int r, rges;
+ time_t ti;
+
+ gdouble lat_ul, lon_ul;
+ gdouble lat_ll, lon_ll;
+ gdouble lat_ur, lon_ur;
+ gdouble lat_lr, lon_lr;
+ gdouble lat_min, lon_min;
+ gdouble lat_max, lon_max;
+ gdouble lat_mid, lon_mid;
+
+
+ if (!usesql)
+ return;
+
+ if (!local_config.showpoi)
+ {
+ if (mydebug > 20)
+ printf ("poi_rebuild_list: POI_draw is off\n");
+ return;
+ }
+
+ if (mydebug > 20)
+ {
+ printf
+ ("poi_rebuild_list: Start\t\t\t\t\t\tvvvvvvvvvvvvvvvvvvvvvvvvvv\n");
+ }
+
+
+ if (!maploaded)
+ return;
+
+ if (current.importactive)
+ return;
+
+
+ // calculate the start and stop for lat/lon according to the displayed section
+ calcxytopos (0, 0, &lat_ul, &lon_ul, current.zoom);
+ calcxytopos (0, SCREEN_Y, &lat_ll, &lon_ll, current.zoom);
+ calcxytopos (SCREEN_X, 0, &lat_ur, &lon_ur, current.zoom);
+ calcxytopos (SCREEN_X, SCREEN_Y, &lat_lr, &lon_lr, current.zoom);
+
+ lat_min = min (lat_ll, lat_ul);
+ lat_max = max (lat_lr, lat_ur);
+ lon_min = min (lon_ll, lon_ul);
+ lon_max = max (lon_lr, lon_ur);
+
+ lat_mid = (lat_min + lat_max) / 2;
+ lon_mid = (lon_min + lon_max) / 2;
+
+ gdouble poi_posx, poi_posy;
+ gettimeofday (&t, NULL);
+ ti = t.tv_sec + t.tv_usec / 1000000.0;
+
+ g_snprintf (sql_query, sizeof (sql_query),
+ "SELECT poi.lat,poi.lon,poi.name,poi.poi_type_id,poi.source_id FROM poi "
+ "INNER JOIN poi_type ON poi.poi_type_id=poi_type.poi_type_id "
+ "WHERE ( lat BETWEEN %.6f AND %.6f ) AND ( lon BETWEEN %.6f AND %.6f ) "
+ "AND ( %ld BETWEEN scale_min AND scale_max ) %s LIMIT 40000;",
+ lat_min, lat_max, lon_min, lon_max, current.mapscale, current.poifilter);
+
+ if (mydebug > 20)
+ {
+ printf ("poi_rebuild_list: POI mysql query: %s\n", sql_query);
+ }
+
+ if (dl_mysql_query (&mysql, sql_query))
+ {
+ printf ("poi_rebuild_list: Error in query: \n");
+ fprintf (stderr, "poi_rebuild_list: Error in query: %s\n",
+ dl_mysql_error (&mysql));
+ return;
+ }
+
+ if (!(res = dl_mysql_store_result (&mysql)))
+ {
+ fprintf (stderr, "Error in store results: %s\n",
+ dl_mysql_error (&mysql));
+ dl_mysql_free_result (res);
+ res = NULL;
+ return;
+ }
+
+ rges = r = 0;
+ poi_nr = 0;
+ while ((row = dl_mysql_fetch_row (res)))
+ {
+ rges++;
+ gdouble lat, lon;
+
+ if (mydebug > 20)
+ fprintf (stderr, "Query Result: %s\t%s\t%s\t%s\n",
+ row[0], row[1], row[2], row[3]);
+
+ lat = g_strtod (row[0], NULL);
+ lon = g_strtod (row[1], NULL);
+ calcxy (&poi_posx, &poi_posy, lon, lat, current.zoom);
+
+ if ((poi_posx > -50) && (poi_posx < (SCREEN_X + 50)) &&
+ (poi_posy > -50) && (poi_posy < (SCREEN_Y + 50)))
+ {
+ // get next free mem for point
+ poi_nr++;
+ if (poi_nr > poi_limit)
+ {
+ poi_limit = poi_nr + 10000;
+ if (mydebug > 20)
+ g_print ("Try to allocate Memory for %ld poi\n", poi_limit);
+
+ poi_list = g_renew (poi_struct, poi_list, poi_limit);
+ if (NULL == poi_list)
+ {
+ g_print ("Error: Cannot allocate Memory for %ld poi\n",
+ poi_limit);
+ poi_limit = -1;
+ return;
+ }
+ }
+
+ // Save retrieved poi information into structure
+ (poi_list + poi_nr)->lat = lat;
+ (poi_list + poi_nr)->lon = lon;
+ (poi_list + poi_nr)->x = poi_posx;
+ (poi_list + poi_nr)->y = poi_posy;
+ g_strlcpy ((poi_list + poi_nr)->name, row[2],
+ sizeof ((poi_list + poi_nr)->name));
+ (poi_list + poi_nr)->poi_type_id = (gint) g_strtod (row[3], NULL);
+ if (mydebug > 20)
+ {
+ g_snprintf ((poi_list + poi_nr)->name,
+ sizeof ((poi_list + poi_nr)->name), "%s %s"
+ //"\n(%.4f ,%.4f)",
+ // (poi_list + poi_nr)->poi_type_id,
+ , row[2], row[4]
+ // , lat, lon
+ );
+ /*
+ * `type_id` int(11) NOT NULL default \'0\',
+ * `alt` double default \'0\',
+ * `proximity` float default \'0\',
+ * `comment` varchar(255) default NULL,
+ * `scale_min` smallint(6) NOT NULL default \'0\',
+ * `scale_max` smallint(6) NOT NULL default \'0\',
+ * `last_modified` date NOT NULL default \'0000-00-00\',
+ * `url` varchar(160) NULL ,
+ * `address_id` int(11) default \'0\',
+ * `source_id` int(11) NOT NULL default \'0\',
+ */
+ }
+
+ /*
+ * if ( mydebug > 20 )
+ * printf ("DB: %f %f \t( x:%f, y:%f )\t%s\n",
+ * (poi_list + poi_nr)->lat, (poi_list + poi_nr)->lon,
+ * (poi_list + poi_nr)->x, (poi_list + poi_nr)->y,
+ * (poi_list + poi_nr)->name
+ * );
+ */
+ }
+ }
+
+
+ poi_list_count = poi_nr;
+
+ // print time for getting Data
+ gettimeofday (&t, NULL);
+ ti = (t.tv_sec + t.tv_usec / 1000000.0) - ti;
+ if (mydebug > 20)
+ printf (_("%ld(%d) rows read in %.2f seconds\n"), poi_list_count,
+ rges, (gdouble) ti);
+
+
+ /* remember where the data belongs to */
+ poi_lat_lr = lat_lr;
+ poi_lon_lr = lon_lr;
+ poi_lat_ul = lat_ul;
+ poi_lon_ul = lon_ul;
+
+ if (!dl_mysql_eof (res))
+ {
+ fprintf (stderr, "poi_rebuild_list: Error in dl_mysql_eof: %s\n",
+ dl_mysql_error (&mysql));
+ dl_mysql_free_result (res);
+ res = NULL;
+ return;
+ }
+
+ dl_mysql_free_result (res);
+ res = NULL;
+
+ if (mydebug > 20)
+ {
+ printf ("poi_rebuild_list: End \t\t\t\t\t\t");
+ printf ("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
+ }
+}
+
+
+/* *******************************************************
+ * draw poi_ on image
+ TODO: find free space on drawing area. So the Text doesn't overlap
+*/
+void
+poi_draw_list (gboolean draw_now)
+{
+ gint i;
+
+ if (!usesql)
+ return;
+
+ if (current.importactive)
+ return;
+
+ if (!maploaded)
+ return;
+
+ if (!local_config.showpoi)
+ {
+ if (mydebug > 20)
+ printf ("poi_draw_list: POI_draw is off\n");
+ return;
+ }
+
+
+ if (mydebug > 20)
+ printf
+ ("poi_draw_list: Start\t\t\tvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n");
+
+ if (poi_check_if_moved () || draw_now)
+ poi_rebuild_list ();
+
+ /* ------------------------------------------------------------------ */
+ /* draw poi_list points */
+ if (mydebug > 20)
+ printf ("poi_draw_list: drawing %ld points\n", poi_list_count);
+
+ for (i = 1; i <= poi_list_count; i++)
+ {
+ gdouble posx, posy;
+
+ posx = (poi_list + i)->x;
+ posy = (poi_list + i)->y;
+
+ if ((posx >= 0) && (posx < SCREEN_X) &&
+ (posy >= 0) && (posy < SCREEN_Y))
+ {
+
+
+ gdk_gc_set_line_attributes (kontext_map, 2, 0, 0, 0);
+
+ g_strlcpy (txt, (poi_list + i)->name, sizeof (txt));
+
+ GdkPixbuf *icon;
+ int icon_index = (poi_list + i)->poi_type_id;
+ icon = poi_type_list[icon_index].icon;
+
+ if (icon != NULL && icon_index > 0)
+ {
+ if (poi_list_count < 2000)
+ {
+ int wx = gdk_pixbuf_get_width (icon);
+ int wy = gdk_pixbuf_get_height (icon);
+
+ gdk_draw_pixbuf (drawable, kontext_map, icon,
+ 0, 0,
+ posx - wx / 2,
+ posy - wy / 2,
+ wx, wy, GDK_RGB_DITHER_NONE, 0, 0);
+ }
+ }
+ else
+ {
+ gdk_gc_set_foreground (kontext_map, &colors.red);
+ if (poi_list_count < 20000)
+ { // Only draw small + if more than ... Points
+ draw_plus_sign (posx, posy);
+ }
+ else
+ {
+ draw_small_plus_sign (posx, posy);
+ }
+ }
+
+ /* draw friends label in configured color */
+ if (local_config.showfriends && poi_is_friend (icon_index))
+ {
+ draw_label_friend (txt, posx, posy);
+ //draw_posmarker (posx, posy, 45,
+ // &colors.blue, 1, FALSE, FALSE);
+ }
+ /* draw label only if we display less than 1000 POIs */
+ else if (poi_list_count < 1000)
+ {
+ draw_label (txt, posx, posy);
+ }
+ }
+ }
+ if (mydebug > 20)
+ printf
+ ("poi_draw_list: End\t\t\t^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
+}
+
+
+/* *******************************************************
+ * query all Info for Points in area around lat/lon
+*/
+void
+poi_query_area (gdouble lat1, gdouble lon1, gdouble lat2, gdouble lon2)
+{
+ gint i;
+ printf ("Query: %f ... %f , %f ... %f\n", lat1, lat2, lon1, lon2);
+
+ for (i = 0; i < poi_list_count; i++)
+ {
+ //printf ("check POI: %ld: %f %f :%s\n",i,(poi_list + i)->lat, (poi_list + i)->lon,(poi_list + i)->name);
+ if ((lat1 <= (poi_list + i)->lat) &&
+ ((poi_list + i)->lat <= lat2) &&
+ (lon1 <= (poi_list + i)->lon) && ((poi_list + i)->lon <= lon2))
+ {
+ printf ("Query POI: %d: %f %f :%s\n",
+ i, (poi_list + i)->lat, (poi_list + i)->lon,
+ (poi_list + i)->name);
+ }
+ }
+}
+
+/* *******************************************************
+ * initialize POI filter from config settings
+*/
+void init_poi_type_filter ()
+{
+ GtkTreeIter t_iter;
+ gchar *t_name;
+
+ gtk_tree_model_get_iter_first
+ (GTK_TREE_MODEL (poi_types_tree), &t_iter);
+ do
+ {
+ gtk_tree_model_get (GTK_TREE_MODEL (poi_types_tree), &t_iter,
+ POITYPE_NAME, &t_name, -1);
+
+ if (g_strstr_len (local_config.poi_filter,
+ sizeof (local_config.poi_filter), t_name))
+ {
+ gtk_tree_store_set
+ (poi_types_tree, &t_iter,
+ POITYPE_SELECT, 0, -1);
+ }
+ else
+ {
+ gtk_tree_store_set
+ (poi_types_tree, &t_iter,
+ POITYPE_SELECT, 1, -1);
+ }
+ }
+ while (gtk_tree_model_iter_next
+ (GTK_TREE_MODEL (poi_types_tree), &t_iter));
+
+ g_free (t_name);
+}
+
+
+/* *******************************************************
+ */
+void
+poi_init (void)
+{
+ poi_limit = 40000;
+ poi_list = g_new (poi_struct, poi_limit);
+ poi_result = g_new (poi_struct, poi_limit);
+ if (poi_list == NULL || poi_result == NULL)
+ {
+ g_print ("Error: Cannot allocate Memory for %ld poi\n",
+ poi_limit);
+ poi_limit = -1;
+ return;
+ }
+
+ /* init gtk-list for storage of results of poi-search */
+ poi_result_tree = gtk_list_store_new (RES_COLUMS,
+ G_TYPE_INT, /* poi.poi_id */
+ G_TYPE_STRING, /* poi.name */
+ G_TYPE_STRING, /* poi.comment */
+ G_TYPE_STRING, /* poi_type.title */
+ G_TYPE_STRING, /* poi_type.name */
+ GDK_TYPE_PIXBUF, /* poi_type.icon */
+ G_TYPE_STRING, /* formatted distance */
+ G_TYPE_DOUBLE, /* numerical distance */
+ G_TYPE_DOUBLE, /* numerical latitude */
+ G_TYPE_DOUBLE /* numerical longitude */
+ );
+
+ /* init gtk-tree for storage of poi-type data */
+ poi_types_tree = gtk_tree_store_new (POITYPE_COLUMS,
+ G_TYPE_INT, /* id */
+ G_TYPE_STRING, /* name */
+ GDK_TYPE_PIXBUF, /* icon */
+ G_TYPE_INT, /* scale_min */
+ G_TYPE_INT, /* scale_max */
+ G_TYPE_STRING, /* description */
+ G_TYPE_STRING, /* title */
+ G_TYPE_BOOLEAN /* select */
+ );
+
+ /* read poi-type data and icons from icons.xml */
+ get_poitype_tree ();
+
+ /* set poi filter according to config file */
+ init_poi_type_filter ();
+ update_poi_type_filter ();
+}
diff --git a/src/poi.h b/src/poi.h
new file mode 100644
index 0000000..48ed65e
--- /dev/null
+++ b/src/poi.h
@@ -0,0 +1,113 @@
+/***********************************************************************
+
+Copyright (c) 2001,2002 Fritz Ganter <ganter@ganter.at>
+
+Website: www.kraftvoll.at/software
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+
+#ifndef GPSDRIVE_POI_H
+#define GPSDRIVE_POI_H
+
+/*
+ * See poi.c for details.
+ */
+
+#include <gtk/gtk.h>
+
+typedef struct
+{
+ gint poi_id;
+ gdouble lon;
+ gdouble lat;
+ gdouble alt;
+ gchar name[80];
+ gint poi_type_id;
+ gdouble proximity;
+ gchar comment[255];
+ gint scale_min;
+ gint scale_max;
+ //date last_modified
+ gchar url[160];
+ gint address_id;
+ gint source_id;
+ gdouble x; // x position on screen
+ gdouble y; // y position on screen
+}
+poi_struct;
+
+#define POI_TYPE_LIST_STRING_LENGTH 80
+
+/* poi related functions */
+void draw_label (char *txt, gdouble posx, gdouble posy);
+void draw_label_friend (char *txt, gdouble posx, gdouble posy);
+void poi_init (void);
+void poi_rebuild_list (void);
+gint poi_type_id_from_name (gchar name[POI_TYPE_LIST_STRING_LENGTH]);
+void poi_draw_list (gboolean draw_now);
+gint poi_draw_cb (GtkWidget * widget, guint datum);
+void poi_query_area ( gdouble lat1, gdouble lon1 ,gdouble lat2, gdouble lon2 );
+GdkPixbuf * read_poi_icon (gchar * icon_name);
+void get_poitype_tree (void);
+guint poi_get_results (const gchar *text, const gchar *dist, const gint posflag, const gint typeflag, const gchar *type);
+void update_poi_type_filter (void);
+void init_poi_type_filter(void);
+
+typedef struct
+{
+ guint poi_type_id;
+ gchar name[POI_TYPE_LIST_STRING_LENGTH];
+ gchar icon_name[POI_TYPE_LIST_STRING_LENGTH];
+ GdkPixbuf *icon;
+ gint scale_min;
+ gint scale_max;
+ gint level;
+ gchar description[POI_TYPE_LIST_STRING_LENGTH];
+ gchar title[POI_TYPE_LIST_STRING_LENGTH];
+} poi_type_struct;
+#define poi_type_list_max 1000
+
+enum {
+ RESULT_ID,
+ RESULT_NAME,
+ RESULT_COMMENT,
+ RESULT_TYPE_TITLE,
+ RESULT_TYPE_NAME,
+ RESULT_TYPE_ICON,
+ RESULT_DISTANCE,
+ RESULT_DIST_NUM,
+ RESULT_LAT,
+ RESULT_LON,
+ RES_COLUMS
+};
+
+enum {
+ POITYPE_ID,
+ POITYPE_NAME,
+ POITYPE_ICON,
+ POITYPE_SCALE_MIN,
+ POITYPE_SCALE_MAX,
+ POITYPE_DESCRIPTION,
+ POITYPE_TITLE,
+ POITYPE_SELECT,
+ POITYPE_COLUMS
+};
+
+#endif /* GPSDRIVE_POI_H */
diff --git a/src/poi_gui.c b/src/poi_gui.c
new file mode 100644
index 0000000..36abdef
--- /dev/null
+++ b/src/poi_gui.c
@@ -0,0 +1,1346 @@
+/*
+**********************************************************************
+
+Copyright (c) 2001-2007 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+**********************************************************************
+*/
+
+/*
+ * poi_gui.c
+ *
+ * This module holds all the gui stuff for the poi-related windows
+ */
+
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <gpsdrive.h>
+#include <icons.h>
+#include <config.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <gdk/gdktypes.h>
+#include "gtk/gtk.h"
+#include "gettext.h"
+#include "gpsdrive.h"
+#include "gpsdrive_config.h"
+#include "gui.h"
+#include "poi.h"
+#include "poi_gui.h"
+#include "routes.h"
+
+/* Defines for gettext I18n */
+#include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+
+struct pattern
+{
+ GtkEntry *text, *distance;
+ gint poitype_id;
+ gchar *poitype_name;
+ gint typeflag; /* 0: search all types, 1: search only selected */
+ gint posflag; /* 0: search at current position, 1: search at destination */
+ guint result_count;
+} criteria;
+
+static GtkWidget *statusbar_poilist;
+static gint statusbar_id;
+
+
+extern routestatus_struct route;
+extern coordinate_struct coords;
+
+extern gint mydebug;
+extern gint debug;
+
+extern GtkTreeStore *poi_types_tree;
+extern GtkListStore *poi_result_tree;
+extern GtkListStore *route_list_tree;
+
+extern gdouble wp_saved_target_lat;
+extern gdouble wp_saved_target_lon;
+extern gdouble wp_saved_posmode_lat;
+extern gdouble wp_saved_posmode_lon;
+
+extern color_struct colors;
+extern currentstatus_struct current;
+
+extern GtkWidget *find_poi_bt;
+extern GtkWidget *posbt;
+extern GtkWidget *settings_window;
+
+extern GdkPixbuf *targetmarker_img;
+
+GtkWidget *poi_types_window;
+
+/* poi lookup window */
+GtkWidget *poi_lookup_window;
+GtkWidget *button_delete;
+GtkWidget *button_target;
+GtkWidget *button_addtoroute;
+
+/* route window */
+GtkWidget *route_window;
+GtkWidget *button_startroute;
+GtkWidget *button_remove, *button_routesave;
+
+
+
+/* *****************************************************************************
+ * CALLBACKS
+ */
+gint
+show_poi_lookup_cb (GtkWidget *button, gpointer data)
+{
+ gtk_widget_set_sensitive (find_poi_bt, FALSE);
+ gtk_widget_set_sensitive (posbt, FALSE);
+
+ /* save old target/posmode for cancel event */
+ wp_saved_target_lat = coords.target_lat;
+ wp_saved_target_lon = coords.target_lon;
+ if (gui_status.posmode)
+ {
+ wp_saved_posmode_lat = coords.posmode_lat;
+ wp_saved_posmode_lon = coords.posmode_lon;
+ }
+
+ gtk_widget_show_all (poi_lookup_window);
+ return TRUE;
+}
+
+static void
+evaluate_poi_search_cb (GtkWidget *button, struct pattern *entries)
+{
+ gchar search_status[80];
+
+ if (mydebug>5)
+ {
+ fprintf (stdout, "\npoi search criteria:\n text: %s\n distance: %s\t posflag: %d\n",
+ gtk_entry_get_text (entries->text) ,
+ gtk_entry_get_text (entries->distance),
+ entries->posflag);
+ }
+
+ entries->result_count = poi_get_results
+ (gtk_entry_get_text (entries->text),
+ gtk_entry_get_text (entries->distance),
+ entries->posflag, entries->typeflag, entries->poitype_name);
+
+ gtk_statusbar_pop (GTK_STATUSBAR (statusbar_poilist), statusbar_id);
+ if (entries->result_count == local_config.poi_results_max)
+ {
+ g_snprintf (search_status, sizeof (search_status),
+ _(" Found %d matching entries (Limit reached)."),
+ entries->result_count);
+ }
+ else
+ {
+ g_snprintf (search_status, sizeof (search_status),
+ _(" Found %d matching entries."),
+ entries->result_count);
+ }
+ gtk_statusbar_push (GTK_STATUSBAR (statusbar_poilist), statusbar_id, search_status);
+}
+
+void
+toggle_window_poi_info_cb (GtkToggleButton *togglebutton, gpointer user_data)
+{
+
+}
+
+static void
+searchpoitypemode_cb (GtkToggleButton *button)
+{
+ if (gtk_toggle_button_get_active(button))
+ {
+ /* switch to selection from selected poi-type */
+ criteria.typeflag = TRUE;
+ }
+ else
+ {
+ /* switch to selection from all poi-types */
+ criteria.typeflag = FALSE;
+ }
+}
+
+static void
+searchdistancemode_cb (GtkToggleButton *button, gpointer user_data)
+{
+ if (gtk_toggle_button_get_active(button))
+ {
+ criteria.posflag = 0; /* search near current position */
+ }
+ else
+ {
+ criteria.posflag = 1; /* search near destination */
+ }
+}
+
+
+static void
+close_poi_lookup_window_cb (GtkWidget *window)
+{
+ /* restore saved values */
+ if (!route.active)
+ {
+ coords.target_lat = wp_saved_target_lat;
+ coords.target_lon = wp_saved_target_lon;
+ }
+ if (gui_status.posmode)
+ {
+ coords.posmode_lat = wp_saved_posmode_lat;
+ coords.posmode_lon = wp_saved_posmode_lon;
+ }
+
+ gtk_widget_hide_all (poi_lookup_window);
+ gtk_widget_set_sensitive (find_poi_bt, TRUE);
+ gtk_widget_set_sensitive (posbt, TRUE);
+}
+
+
+static void
+select_jump_poi_cb (GtkWidget *window)
+{
+ gtk_widget_hide_all (poi_lookup_window);
+
+ coords.current_lat = coords.target_lat;
+ coords.current_lon = coords.target_lon;
+
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (posbt), TRUE);
+
+ gtk_widget_set_sensitive (find_poi_bt, TRUE);
+ gtk_widget_set_sensitive (posbt, TRUE);
+}
+
+
+static void
+select_target_poi_cb (GtkWidget *window)
+{
+ gtk_widget_hide_all (poi_lookup_window);
+
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (posbt), FALSE);
+
+ gtk_widget_set_sensitive (find_poi_bt, TRUE);
+ gtk_widget_set_sensitive (posbt, TRUE);
+}
+
+
+static void
+delete_poi_cb (GtkTreeSelection *selection, gpointer data)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ gint selected_poi_id = 0;
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ if (popup_yes_no(GTK_WINDOW (poi_lookup_window), NULL) == GTK_RESPONSE_YES)
+ {
+ gtk_tree_model_get (model, &iter,
+ RESULT_ID, &selected_poi_id,
+ -1);
+ if (mydebug>20)
+ fprintf (stderr, "deleting poi with id: %d\n", selected_poi_id);
+ deletesqldata (selected_poi_id);
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+ }
+ }
+}
+
+
+static void
+select_poi_cb (GtkTreeSelection *selection, gpointer data)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ if (route.edit)
+ {
+ add_poi_to_route (model, iter);
+ if (route.items)
+ {
+ gtk_widget_set_sensitive
+ (button_startroute, TRUE);
+ gtk_widget_set_sensitive
+ (button_routesave, TRUE);
+ }
+ }
+ else
+ {
+ if (!route.active)
+ {
+ gtk_tree_model_get (model, &iter,
+ RESULT_LAT, &coords.target_lat,
+ RESULT_LON, &coords.target_lon,
+ -1);
+ if (mydebug>50)
+ fprintf (stdout,
+ " new target -> %f / %f\n",
+ coords.target_lat,
+ coords.target_lon);
+ }
+ }
+
+ gtk_widget_set_sensitive (button_delete, TRUE);
+
+ /* if posmode enabled set posmode_lat/lon */
+ if (gui_status.posmode)
+ {
+ gtk_tree_model_get (model, &iter,
+ RESULT_LAT, &coords.posmode_lat,
+ RESULT_LON, &coords.posmode_lon,
+ -1);
+ }
+ }
+}
+
+
+static gint
+select_poitype_cb (GtkComboBox *combo_box, gpointer data)
+{
+ GtkTreeIter iter;
+
+ if (gtk_combo_box_get_active_iter (combo_box, &iter))
+ {
+ gtk_tree_model_get (GTK_TREE_MODEL (poi_types_tree), &iter,
+ POITYPE_ID, &criteria.poitype_id,
+ POITYPE_NAME, &criteria.poitype_name,
+ -1);
+ }
+
+ if (mydebug>50)
+ {
+ fprintf (stderr, " selected poi-type -> %d / %s\n",
+ criteria.poitype_id, criteria.poitype_name);
+ }
+ return FALSE;
+}
+
+
+static void
+close_route_window_cb ()
+{
+ gtk_widget_destroy (route_window);
+ route.edit = FALSE;
+
+ if (GTK_IS_WIDGET (button_addtoroute))
+ gtk_widget_set_sensitive (button_addtoroute, TRUE);
+}
+
+
+static void
+route_startstop_cb ()
+{
+ route.active = !route.active;
+
+ if (route.active)
+ {
+ route.edit = FALSE;
+ route_settarget (-1);
+ }
+ else
+ {
+ // TODO: stop routing
+ }
+ close_route_window_cb ();
+}
+
+
+static void
+route_cancel_cb ()
+{
+ gtk_list_store_clear (route_list_tree);
+ close_route_window_cb ();
+ route.items = 0;
+ route.distance = 0.0;
+}
+
+
+static void
+select_routepoint_cb ()
+{
+ gtk_widget_set_sensitive (button_remove, TRUE);
+}
+
+
+static void
+remove_routepoint_cb (GtkTreeSelection *selection, gpointer data)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+ }
+
+ /* cancel route, if no elements are left */
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL
+ (route_list_tree), &iter) == FALSE)
+ {
+ route_cancel_cb ();
+ }
+}
+
+
+static void
+poilist_highlight_cb
+ (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell,
+ GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data)
+{
+ gchar *value;
+
+ gtk_tree_model_get (tree_model, iter, RESULT_TYPE_NAME, &value, -1);
+
+ /* show friendsd entries in red color */
+ if (g_str_has_prefix (value, "people.friendsd"))
+ {
+ g_object_set (G_OBJECT (cell),
+ "foreground-gdk", &colors.red, NULL);
+ }
+ else
+ {
+ g_object_set (G_OBJECT (cell),
+ "foreground-gdk", NULL, NULL);
+ }
+
+ g_free (value);
+}
+
+
+/* *****************************************************************************
+ * Window: POI-Info
+ */
+void create_poi_info_window (void)
+{
+ GtkWidget *poi_info_window;
+ GtkWidget *vbox_poidata;
+ GtkWidget *frame_poi_basicdata;
+ GtkWidget *alignment_basic;
+ GtkWidget *table_basic;
+ GtkWidget *label_name;
+ GtkWidget *label_comment;
+ GtkWidget *checkbutton_private;
+ GtkWidget *entry_name;
+ GtkWidget *entry_comment;
+ GtkWidget *entry_lat;
+ GtkWidget *entry_lon;
+ GtkWidget *entry_alt;
+ GtkWidget *label_alt;
+ GtkWidget *label_lon;
+ GtkWidget *label_lat;
+ GtkWidget *hseparator_basic;
+ GtkWidget *label_type;
+ GtkWidget *combobox_type;
+ GtkWidget *entry_poitypeid;
+ GtkWidget *label_basic;
+ GtkWidget *expander_extra;
+ GtkWidget *frame_extra;
+ GtkWidget *alignment_extra;
+ GtkWidget *scrolledwindow_extra;
+ GtkWidget *treeview_extra;
+ GtkWidget *label_extradata;
+ GtkWidget *hbox_status;
+ GtkWidget *statusbar_poiinfo;
+ GtkWidget *button_save;
+ GtkWidget *button_close;
+
+ poi_info_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (poi_info_window), _("POI-Info"));
+ gtk_window_set_icon_name (GTK_WINDOW (poi_info_window), "gtk-info");
+ //gtk_window_set_decorated (GTK_WINDOW (poi_info_window), FALSE);
+ gtk_window_set_focus_on_map (GTK_WINDOW (poi_info_window), FALSE);
+
+ vbox_poidata = gtk_vbox_new (FALSE, 0);
+ gtk_widget_show (vbox_poidata);
+ gtk_container_add (GTK_CONTAINER (poi_info_window), vbox_poidata);
+
+ frame_poi_basicdata = gtk_frame_new (NULL);
+ gtk_widget_show (frame_poi_basicdata);
+ gtk_box_pack_start (GTK_BOX (vbox_poidata), frame_poi_basicdata, FALSE, FALSE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (frame_poi_basicdata), 5);
+
+ alignment_basic = gtk_alignment_new (0.5, 0.5, 1, 1);
+ gtk_widget_show (alignment_basic);
+ gtk_container_add (GTK_CONTAINER (frame_poi_basicdata), alignment_basic);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment_basic), 5, 5, 5, 5);
+
+ table_basic = gtk_table_new (6, 6, FALSE);
+ gtk_widget_show (table_basic);
+ gtk_container_add (GTK_CONTAINER (alignment_basic), table_basic);
+
+ label_name = gtk_label_new (_("Name"));
+ gtk_widget_show (label_name);
+ gtk_table_attach (GTK_TABLE (table_basic), label_name, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label_name), 0, 0.5);
+
+ label_comment = gtk_label_new (_("Comment"));
+ gtk_widget_show (label_comment);
+ gtk_table_attach (GTK_TABLE (table_basic), label_comment, 0, 1, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label_comment), 0, 0.5);
+
+ checkbutton_private = gtk_check_button_new_with_mnemonic (_("private"));
+ gtk_widget_show (checkbutton_private);
+ gtk_table_attach (GTK_TABLE (table_basic), checkbutton_private, 5, 6, 0, 1,
+ (GtkAttachOptions) (0),
+ (GtkAttachOptions) (0), 0, 0);
+
+ entry_name = gtk_entry_new ();
+ gtk_widget_show (entry_name);
+ gtk_table_attach (GTK_TABLE (table_basic), entry_name, 1, 5, 0, 1,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_entry_set_max_length (GTK_ENTRY (entry_name), 80);
+
+ entry_comment = gtk_entry_new ();
+ gtk_widget_show (entry_comment);
+ gtk_table_attach (GTK_TABLE (table_basic), entry_comment, 1, 6, 1, 2,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_entry_set_max_length (GTK_ENTRY (entry_comment), 255);
+
+ entry_lat = gtk_entry_new ();
+ gtk_widget_show (entry_lat);
+ gtk_table_attach (GTK_TABLE (table_basic), entry_lat, 0, 2, 5, 6,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_entry_set_width_chars (GTK_ENTRY (entry_lat), 12);
+
+ entry_lon = gtk_entry_new ();
+ gtk_widget_show (entry_lon);
+ gtk_table_attach (GTK_TABLE (table_basic), entry_lon, 2, 4, 5, 6,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_entry_set_width_chars (GTK_ENTRY (entry_lon), 12);
+
+ entry_alt = gtk_entry_new ();
+ gtk_widget_show (entry_alt);
+ gtk_table_attach (GTK_TABLE (table_basic), entry_alt, 4, 6, 5, 6,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_entry_set_width_chars (GTK_ENTRY (entry_alt), 10);
+
+ label_alt = gtk_label_new (_("Altitude"));
+ gtk_widget_show (label_alt);
+ gtk_table_attach (GTK_TABLE (table_basic), label_alt, 4, 5, 4, 5,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label_alt), 0, 0.5);
+
+ label_lon = gtk_label_new (_("Longitude"));
+ gtk_widget_show (label_lon);
+ gtk_table_attach (GTK_TABLE (table_basic), label_lon, 2, 3, 4, 5,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label_lon), 0, 0.5);
+
+ label_lat = gtk_label_new (_("Latitude"));
+ gtk_widget_show (label_lat);
+ gtk_table_attach (GTK_TABLE (table_basic), label_lat, 0, 1, 4, 5,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label_lat), 0, 0.5);
+
+ hseparator_basic = gtk_hseparator_new ();
+ gtk_widget_show (hseparator_basic);
+ gtk_table_attach (GTK_TABLE (table_basic), hseparator_basic, 0, 6, 3, 4,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 5);
+
+ label_type = gtk_label_new (_("Type"));
+ gtk_widget_show (label_type);
+ gtk_table_attach (GTK_TABLE (table_basic), label_type, 0, 1, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (label_type), 0, 0.5);
+
+ combobox_type = gtk_combo_box_new_text ();
+ gtk_widget_show (combobox_type);
+ gtk_table_attach (GTK_TABLE (table_basic), combobox_type, 1, 5, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+
+ entry_poitypeid = gtk_entry_new ();
+ gtk_widget_show (entry_poitypeid);
+ gtk_table_attach (GTK_TABLE (table_basic), entry_poitypeid, 5, 6, 2, 3,
+ (GtkAttachOptions) (0),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_entry_set_max_length (GTK_ENTRY (entry_poitypeid), 5);
+ gtk_editable_set_editable (GTK_EDITABLE (entry_poitypeid), FALSE);
+ gtk_entry_set_has_frame (GTK_ENTRY (entry_poitypeid), FALSE);
+ gtk_entry_set_width_chars (GTK_ENTRY (entry_poitypeid), 5);
+
+ label_basic = gtk_label_new (_("Basic Data"));
+ gtk_widget_show (label_basic);
+ gtk_frame_set_label_widget (GTK_FRAME (frame_poi_basicdata), label_basic);
+
+ expander_extra = gtk_expander_new (NULL);
+ gtk_widget_show (expander_extra);
+ gtk_box_pack_start (GTK_BOX (vbox_poidata), expander_extra, TRUE, TRUE, 0);
+ gtk_expander_set_expanded (GTK_EXPANDER (expander_extra), TRUE);
+
+ frame_extra = gtk_frame_new (NULL);
+ gtk_widget_show (frame_extra);
+ gtk_container_add (GTK_CONTAINER (expander_extra), frame_extra);
+ gtk_container_set_border_width (GTK_CONTAINER (frame_extra), 5);
+ gtk_frame_set_label_align (GTK_FRAME (frame_extra), 0, 0);
+
+ alignment_extra = gtk_alignment_new (0.5, 0.5, 1, 1);
+ gtk_widget_show (alignment_extra);
+ gtk_container_add (GTK_CONTAINER (frame_extra), alignment_extra);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment_extra), 0, 0, 12, 0);
+
+ scrolledwindow_extra = gtk_scrolled_window_new (NULL, NULL);
+ gtk_widget_show (scrolledwindow_extra);
+ gtk_container_add (GTK_CONTAINER (alignment_extra), scrolledwindow_extra);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow_extra), GTK_SHADOW_IN);
+
+ treeview_extra = gtk_tree_view_new ();
+ gtk_widget_show (treeview_extra);
+ gtk_container_add (GTK_CONTAINER (scrolledwindow_extra), treeview_extra);
+
+ label_extradata = gtk_label_new (_("Extra Data"));
+ gtk_widget_show (label_extradata);
+ gtk_expander_set_label_widget (GTK_EXPANDER (expander_extra), label_extradata);
+
+ hbox_status = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show (hbox_status);
+ gtk_box_pack_start (GTK_BOX (vbox_poidata), hbox_status, FALSE, TRUE, 0);
+
+ statusbar_poiinfo = gtk_statusbar_new ();
+ gtk_widget_show (statusbar_poiinfo);
+ gtk_box_pack_start (GTK_BOX (hbox_status), statusbar_poiinfo, TRUE, TRUE, 0);
+ gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (statusbar_poiinfo), FALSE);
+
+ button_save = gtk_button_new_from_stock ("gtk-save");
+ gtk_widget_show (button_save);
+ gtk_box_pack_start (GTK_BOX (hbox_status), button_save, FALSE, FALSE, 0);
+
+ button_close = gtk_button_new_from_stock ("gtk-close");
+ gtk_widget_show (button_close);
+ gtk_box_pack_start (GTK_BOX (hbox_status), button_close, FALSE, FALSE, 0);
+
+ gtk_widget_show_all (poi_info_window);
+}
+
+
+/* *****************************************************************************
+ * Window: POI-Lookup
+ */
+void create_window_poi_lookup (void)
+{
+ GtkWidget *dialog_vbox_poisearch;
+ GtkWidget *vbox_searchbox, *expander_poisearch;
+ GtkWidget *frame_search_criteria, *alignment_criteria;
+ GtkWidget *vbox_criteria, *hbox_text;
+ GtkWidget *label_text, *entry_text;
+ GtkWidget *button_search, *hbox_distance;
+ GtkWidget *label_distance, *entry_distance;
+ GtkWidget *label_distfrom, *radiobutton_distcurrent;
+ GSList *radiobutton_distance_group = NULL;
+ GtkWidget *radiobutton_distcursor;
+ GtkWidget *hbox_type, *label_type, *radiobutton_typeall;
+ GSList *radiobutton_type_group = NULL;
+ GtkWidget *radiobutton_typesel;
+ GtkWidget *label_criteria, *frame_poiresults;
+ GtkWidget *alignment_poiresults, *vbox_poiresults;
+ GtkWidget *scrolledwindow_poilist, *treeview_poilist;
+ GtkCellRenderer *renderer_poilist;
+ GtkTreeViewColumn *column_poilist;
+ GtkTreeSelection *poilist_select;
+ GtkWidget *hbox_poistatus;
+ GtkWidget *togglebutton_poiinfo, *alignment_poiinfo, *hbox11;
+ GtkWidget *image_poiinfo, *label_poiinfo, *label_results;
+ GtkWidget *dialog_action_area_poisearch, *alignment_addtoroute;
+ GtkWidget *hbox_addtoroute, *image_addtoroute, *label_addtoroute;
+ GtkWidget *alignment_target, *hbox_target, *image_target;
+ GtkWidget *label_target, *button_close, *button_jumpto;
+ GtkWidget *alignment_jumpto, *hbox_jumpto, *image_jumpto;
+ GtkWidget *label_jumpto, *combobox_typetree;
+ GtkCellRenderer *renderer_type_name;
+ GtkCellRenderer *renderer_type_icon;
+ GtkTooltips *tooltips_poilookup;
+ gchar text[50];
+
+ criteria.posflag = 0;
+ criteria.result_count = 0;
+
+ tooltips_poilookup = gtk_tooltips_new();
+ gtk_tooltips_set_delay (tooltips_poilookup, TOOLTIP_DELAY);
+ if (local_config.showtooltips)
+ gtk_tooltips_enable (tooltips_poilookup);
+ else
+ gtk_tooltips_disable (tooltips_poilookup);
+
+ poi_lookup_window = gtk_dialog_new ();
+ gtk_container_set_border_width (GTK_CONTAINER (poi_lookup_window), 2);
+ gtk_window_set_title (GTK_WINDOW (poi_lookup_window),
+ _("Lookup Point of Interest"));
+ gtk_window_set_position (GTK_WINDOW (poi_lookup_window),
+ GTK_WIN_POS_CENTER);
+ gtk_window_set_type_hint (GTK_WINDOW (poi_lookup_window),
+ GDK_WINDOW_TYPE_HINT_DIALOG);
+ if (local_config.guimode == GUI_PDA)
+ gtk_window_set_default_size (GTK_WINDOW (poi_lookup_window),
+ real_screen_x, real_screen_y);
+ else
+ gtk_window_set_default_size (GTK_WINDOW (poi_lookup_window),
+ -1, 400);
+
+ dialog_vbox_poisearch = GTK_DIALOG (poi_lookup_window)->vbox;
+
+ vbox_searchbox = gtk_vbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox_poisearch),
+ vbox_searchbox, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox_searchbox), 2);
+
+ expander_poisearch = gtk_expander_new (NULL);
+ gtk_box_pack_start (GTK_BOX (vbox_searchbox),
+ expander_poisearch, FALSE, TRUE, 0);
+ gtk_expander_set_expanded (GTK_EXPANDER (expander_poisearch), TRUE);
+
+ /* Frame: POI Search Criteria */
+ {
+ frame_search_criteria = gtk_frame_new (NULL);
+ gtk_container_add (GTK_CONTAINER (expander_poisearch),
+ frame_search_criteria);
+ gtk_frame_set_label_align (GTK_FRAME (frame_search_criteria), 0, 0);
+
+ alignment_criteria = gtk_alignment_new (0.5, 0.5, 1, 1);
+ gtk_container_add (GTK_CONTAINER (frame_search_criteria),
+ alignment_criteria);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment_criteria),
+ 5, 5, 12, 5);
+
+ vbox_criteria = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (alignment_criteria), vbox_criteria);
+
+ hbox_text = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox_criteria), hbox_text, TRUE, TRUE, 0);
+
+ label_text = gtk_label_new (_("<i>Search Text:</i>"));
+ gtk_box_pack_start (GTK_BOX (hbox_text), label_text, FALSE, FALSE, 0);
+ gtk_label_set_use_markup (GTK_LABEL (label_text), TRUE);
+
+ entry_text = gtk_entry_new ();
+ criteria.text = GTK_ENTRY (entry_text);
+ gtk_box_pack_start (GTK_BOX (hbox_text), entry_text, TRUE, TRUE, 5);
+ gtk_entry_set_max_length (GTK_ENTRY (entry_text), 255);
+ g_signal_connect (entry_text, "activate",
+ GTK_SIGNAL_FUNC (evaluate_poi_search_cb), &criteria);
+
+ /* Button to activate POI search */
+ button_search = gtk_button_new_from_stock ("gtk-find");
+ gtk_box_pack_start (GTK_BOX (hbox_text), button_search,
+ FALSE, FALSE, 5);
+ g_signal_connect (button_search, "clicked",
+ GTK_SIGNAL_FUNC (evaluate_poi_search_cb), &criteria);
+
+ /* Distance selection */
+ hbox_distance = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox_criteria),
+ hbox_distance, TRUE, TRUE, 0);
+
+ label_distance = gtk_label_new (_("<i>max. Distance:</i>"));
+ gtk_box_pack_start (GTK_BOX (hbox_distance),
+ label_distance, FALSE, FALSE, 10);
+ gtk_label_set_use_markup (GTK_LABEL (label_distance), TRUE);
+ gtk_label_set_single_line_mode (GTK_LABEL (label_distance), TRUE);
+
+ entry_distance = gtk_entry_new ();
+ criteria.distance = GTK_ENTRY (entry_distance);
+ gtk_box_pack_start (GTK_BOX (hbox_distance),
+ entry_distance, FALSE, TRUE, 0);
+ gtk_entry_set_max_length (GTK_ENTRY (entry_distance), 5);
+ g_snprintf (text, sizeof (text), "%0.1f",
+ local_config.poi_searchradius);
+ gtk_entry_set_text (GTK_ENTRY (entry_distance), text);
+ gtk_entry_set_width_chars (GTK_ENTRY (entry_distance), 5);
+ g_signal_connect (entry_distance, "activate",
+ GTK_SIGNAL_FUNC (evaluate_poi_search_cb), &criteria);
+
+ label_distfrom = gtk_label_new (_("km from"));
+ gtk_box_pack_start (GTK_BOX (hbox_distance),
+ label_distfrom, FALSE, FALSE, 0);
+
+ radiobutton_distcurrent = gtk_radio_button_new_with_mnemonic
+ (NULL, _("current position"));
+ gtk_box_pack_start (GTK_BOX (hbox_distance),
+ radiobutton_distcurrent, FALSE, FALSE, 15);
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON
+ (radiobutton_distcurrent), radiobutton_distance_group);
+ radiobutton_distance_group = gtk_radio_button_get_group
+ (GTK_RADIO_BUTTON (radiobutton_distcurrent));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
+ (radiobutton_distcurrent), TRUE);
+ gtk_tooltips_set_tip ( tooltips_poilookup, radiobutton_distcurrent,
+ _("Search near current Position"), NULL);
+ g_signal_connect (radiobutton_distcurrent, "toggled",
+ GTK_SIGNAL_FUNC (searchdistancemode_cb), NULL);
+
+ radiobutton_distcursor = gtk_radio_button_new_with_mnemonic
+ (NULL, _("Destination/Cursor"));
+ gtk_box_pack_start (GTK_BOX (hbox_distance),
+ radiobutton_distcursor, FALSE, FALSE, 10);
+ gtk_container_set_border_width (GTK_CONTAINER
+ (radiobutton_distcursor), 5);
+ gtk_button_set_focus_on_click (GTK_BUTTON
+ (radiobutton_distcursor), FALSE);
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON
+ (radiobutton_distcursor), radiobutton_distance_group);
+ radiobutton_distance_group = gtk_radio_button_get_group
+ (GTK_RADIO_BUTTON (radiobutton_distcursor));
+ gtk_tooltips_set_tip ( tooltips_poilookup, radiobutton_distcursor,
+ _("Search near selected Destination"), NULL);
+
+ /* POI-Type Selection */
+ hbox_type = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox_criteria), hbox_type, TRUE, TRUE, 0);
+
+ label_type = gtk_label_new (_("<i>POI-Types:</i>"));
+ gtk_box_pack_start (GTK_BOX (hbox_type), label_type, FALSE, FALSE, 10);
+ gtk_label_set_use_markup (GTK_LABEL (label_type), TRUE);
+ gtk_label_set_single_line_mode (GTK_LABEL (label_type), TRUE);
+
+ combobox_typetree = gtk_combo_box_new_with_model
+ (GTK_TREE_MODEL (poi_types_tree));
+ renderer_type_icon = gtk_cell_renderer_pixbuf_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox_typetree),
+ renderer_type_icon, FALSE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox_typetree),
+ renderer_type_icon, "pixbuf", POITYPE_ICON, NULL);
+ renderer_type_name = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox_typetree),
+ renderer_type_name, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox_typetree),
+ renderer_type_name, "text", POITYPE_TITLE, NULL);
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX(combobox_typetree),
+ &current.poitype_iter);
+ select_poitype_cb (GTK_COMBO_BOX (combobox_typetree), NULL);
+ g_signal_connect (G_OBJECT (combobox_typetree), "changed",
+ G_CALLBACK (select_poitype_cb), NULL);
+ gtk_box_pack_end (GTK_BOX (hbox_type),
+ combobox_typetree, TRUE, TRUE, 5);
+
+ radiobutton_typeall =
+ gtk_radio_button_new_with_mnemonic (NULL, _("all"));
+ gtk_box_pack_start (GTK_BOX (hbox_type),
+ radiobutton_typeall, FALSE, FALSE, 10);
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON
+ (radiobutton_typeall), radiobutton_type_group);
+ radiobutton_type_group = gtk_radio_button_get_group
+ (GTK_RADIO_BUTTON (radiobutton_typeall));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
+ (radiobutton_typeall), TRUE);
+ gtk_tooltips_set_tip ( tooltips_poilookup, radiobutton_typeall,
+ _("Search all POI-Categories"), NULL);
+
+ radiobutton_typesel = gtk_radio_button_new_with_mnemonic
+ (NULL, _("selected:"));
+ gtk_box_pack_start (GTK_BOX (hbox_type),
+ radiobutton_typesel, FALSE, FALSE, 10);
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON
+ (radiobutton_typesel), radiobutton_type_group);
+ gtk_tooltips_set_tip ( tooltips_poilookup, radiobutton_typesel,
+ _("Search only in selected POI-Categories"), NULL);
+
+ g_signal_connect (radiobutton_typesel, "toggled",
+ GTK_SIGNAL_FUNC (searchpoitypemode_cb), NULL);
+
+ label_criteria = gtk_label_new (_("Search Criteria"));
+ gtk_widget_show (label_criteria);
+ gtk_expander_set_label_widget (GTK_EXPANDER (expander_poisearch),
+ label_criteria);
+ }
+
+ /* Frame: POI-Results */
+ {
+ frame_poiresults = gtk_frame_new (NULL);
+ gtk_box_pack_start (GTK_BOX (vbox_searchbox),
+ frame_poiresults, TRUE, TRUE, 5);
+ gtk_frame_set_label_align (GTK_FRAME (frame_poiresults), 0.02, 0.5);
+
+ alignment_poiresults = gtk_alignment_new (0.5, 0.5, 1, 1);
+ gtk_container_add (GTK_CONTAINER (frame_poiresults),
+ alignment_poiresults);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment_poiresults),
+ 2, 2, 2, 2);
+
+ vbox_poiresults = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (alignment_poiresults),
+ vbox_poiresults);
+
+ scrolledwindow_poilist = gtk_scrolled_window_new (NULL, NULL);
+ gtk_box_pack_start (GTK_BOX (vbox_poiresults),
+ scrolledwindow_poilist, TRUE, TRUE, 0);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW
+ (scrolledwindow_poilist),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW
+ (scrolledwindow_poilist), GTK_SHADOW_IN);
+
+ treeview_poilist = gtk_tree_view_new_with_model
+ (GTK_TREE_MODEL (poi_result_tree));
+
+ renderer_poilist = gtk_cell_renderer_pixbuf_new ();
+ column_poilist = gtk_tree_view_column_new_with_attributes ("_",
+ renderer_poilist, "pixbuf", RESULT_TYPE_ICON, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_poilist),
+ column_poilist);
+
+ renderer_poilist = gtk_cell_renderer_text_new ();
+ column_poilist = gtk_tree_view_column_new_with_attributes (
+ _("Name"), renderer_poilist,
+ "text", RESULT_NAME, NULL);
+ gtk_tree_view_column_set_sort_column_id (column_poilist, RESULT_NAME);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_poilist),
+ column_poilist);
+ gtk_tree_view_column_set_cell_data_func
+ (column_poilist, renderer_poilist, poilist_highlight_cb,
+ NULL, NULL);
+
+ renderer_poilist = gtk_cell_renderer_text_new ();
+ column_poilist = gtk_tree_view_column_new_with_attributes (
+ _("Distance"), renderer_poilist,
+ "text", RESULT_DISTANCE, NULL);
+ gtk_tree_view_column_set_sort_column_id (column_poilist,
+ RESULT_DIST_NUM);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_poilist),
+ column_poilist);
+
+ renderer_poilist = gtk_cell_renderer_text_new ();
+ column_poilist = gtk_tree_view_column_new_with_attributes (
+ _("Type"), renderer_poilist,
+ "text", RESULT_TYPE_TITLE, NULL);
+ g_object_set (G_OBJECT (renderer_poilist),
+ "foreground-gdk", &colors.textback, NULL);
+ gtk_tree_view_column_set_sort_column_id (column_poilist,
+ RESULT_TYPE_TITLE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_poilist),
+ column_poilist);
+
+ renderer_poilist = gtk_cell_renderer_text_new ();
+ column_poilist = gtk_tree_view_column_new_with_attributes (
+ _("Comment"), renderer_poilist,
+ "text", RESULT_COMMENT, NULL);
+ gtk_tree_view_column_set_sort_column_id (column_poilist,
+ RESULT_COMMENT);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_poilist),
+ column_poilist);
+
+ gtk_container_add (GTK_CONTAINER (scrolledwindow_poilist),
+ treeview_poilist);
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview_poilist), TRUE);
+
+
+ poilist_select = gtk_tree_view_get_selection (GTK_TREE_VIEW
+ (treeview_poilist));
+ gtk_tree_selection_set_mode (poilist_select, GTK_SELECTION_SINGLE);
+ g_signal_connect (G_OBJECT (poilist_select), "changed",
+ G_CALLBACK (select_poi_cb), NULL);
+
+ hbox_poistatus = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox_poiresults),
+ hbox_poistatus, FALSE, TRUE, 0);
+
+ statusbar_poilist = gtk_statusbar_new ();
+ gtk_box_pack_start (GTK_BOX (hbox_poistatus),
+ statusbar_poilist, TRUE, TRUE, 0);
+ gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR
+ (statusbar_poilist), FALSE);
+ statusbar_id = gtk_statusbar_get_context_id (GTK_STATUSBAR
+ (statusbar_poilist), "poilist");
+ gtk_statusbar_push (GTK_STATUSBAR (statusbar_poilist), statusbar_id,
+ _(" Please enter your search criteria!"));
+
+ /* button "POI-Info" */
+ togglebutton_poiinfo = gtk_toggle_button_new ();
+ gtk_box_pack_start (GTK_BOX (hbox_poistatus),
+ togglebutton_poiinfo, FALSE, FALSE, 0);
+ alignment_poiinfo = gtk_alignment_new (0.5, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (togglebutton_poiinfo),
+ alignment_poiinfo);
+ hbox11 = gtk_hbox_new (FALSE, 2);
+ gtk_container_add (GTK_CONTAINER (alignment_poiinfo), hbox11);
+ image_poiinfo = gtk_image_new_from_stock ("gtk-info",
+ GTK_ICON_SIZE_BUTTON);
+ gtk_box_pack_start (GTK_BOX (hbox11), image_poiinfo, FALSE, FALSE, 0);
+ label_poiinfo = gtk_label_new_with_mnemonic (_("POI-Info"));
+ gtk_box_pack_start (GTK_BOX (hbox11), label_poiinfo, FALSE, FALSE, 0);
+ gtk_tooltips_set_tip ( tooltips_poilookup, togglebutton_poiinfo,
+ _("Show detailed Information for selected Point of Interest"),
+ NULL);
+
+ // TODO: complete POI-Info functionality, until then button is disabled:
+ gtk_widget_set_sensitive (togglebutton_poiinfo, FALSE);
+
+ label_results = gtk_label_new (_("Results"));
+ gtk_frame_set_label_widget (GTK_FRAME (frame_poiresults),
+ label_results);
+ gtk_label_set_use_markup (GTK_LABEL (label_results), TRUE);
+ }
+
+ dialog_action_area_poisearch = GTK_DIALOG
+ (poi_lookup_window)->action_area;
+
+ /* button "edit route" */
+ button_addtoroute = gtk_button_new ();
+ gtk_dialog_add_action_widget (GTK_DIALOG (poi_lookup_window),
+ button_addtoroute, 0);
+ GTK_WIDGET_SET_FLAGS (button_addtoroute, GTK_CAN_DEFAULT);
+ alignment_addtoroute = gtk_alignment_new (0.5, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (button_addtoroute),
+ alignment_addtoroute);
+ hbox_addtoroute = gtk_hbox_new (FALSE, 2);
+ gtk_container_add (GTK_CONTAINER (alignment_addtoroute),
+ hbox_addtoroute);
+ image_addtoroute = gtk_image_new_from_stock ("gtk-add",
+ GTK_ICON_SIZE_BUTTON);
+ gtk_box_pack_start (GTK_BOX (hbox_addtoroute),
+ image_addtoroute, FALSE, FALSE, 0);
+ label_addtoroute = gtk_label_new_with_mnemonic (_("Edit _Route"));
+ gtk_box_pack_start (GTK_BOX (hbox_addtoroute),
+ label_addtoroute, FALSE, FALSE, 0);
+ gtk_tooltips_set_tip ( tooltips_poilookup, button_addtoroute,
+ _("Switch to Add selected entry to Route"), NULL);
+ g_signal_connect (button_addtoroute, "clicked",
+ GTK_SIGNAL_FUNC (route_window_cb), NULL);
+
+ /* button "delete POI" */
+ button_delete = gtk_button_new_from_stock ("gtk-delete");
+ gtk_dialog_add_action_widget (GTK_DIALOG (poi_lookup_window),
+ button_delete, 0);
+ GTK_WIDGET_SET_FLAGS (button_delete, GTK_CAN_DEFAULT);
+ gtk_tooltips_set_tip ( tooltips_poilookup, button_delete,
+ _("Delete selected entry"), NULL);
+ g_signal_connect_swapped (button_delete, "clicked",
+ GTK_SIGNAL_FUNC (delete_poi_cb), poilist_select);
+
+ /* button "Jump to POI" */
+ button_jumpto = gtk_button_new ();
+ gtk_dialog_add_action_widget (GTK_DIALOG (poi_lookup_window),
+ button_jumpto, 0);
+ GTK_WIDGET_SET_FLAGS (button_jumpto, GTK_CAN_DEFAULT);
+ alignment_jumpto = gtk_alignment_new (0.5, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (button_jumpto), alignment_jumpto);
+ hbox_jumpto = gtk_hbox_new (FALSE, 2);
+ gtk_container_add (GTK_CONTAINER (alignment_jumpto), hbox_jumpto);
+ image_jumpto = gtk_image_new_from_stock ("gtk-jump-to",
+ GTK_ICON_SIZE_BUTTON);
+ gtk_box_pack_start (GTK_BOX (hbox_jumpto),
+ image_jumpto, FALSE, FALSE, 0);
+ label_jumpto = gtk_label_new (_("Jump to POI"));
+ gtk_tooltips_set_tip ( tooltips_poilookup, button_jumpto,
+ _("Jump to selected entry (and switch to Pos. Mode if not already active)"), NULL);
+ gtk_box_pack_start (GTK_BOX (hbox_jumpto),
+ label_jumpto, FALSE, FALSE, 0);
+ g_signal_connect_swapped (button_jumpto, "clicked",
+ GTK_SIGNAL_FUNC (select_jump_poi_cb), NULL);
+
+ /* button "Select as Destination" */
+ button_target = gtk_button_new ();
+ gtk_dialog_add_action_widget (GTK_DIALOG (poi_lookup_window),
+ button_target, 0);
+ GTK_WIDGET_SET_FLAGS (button_target, GTK_CAN_DEFAULT);
+ alignment_target = gtk_alignment_new (0.5, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (button_target), alignment_target);
+ hbox_target = gtk_hbox_new (FALSE, 2);
+ gtk_container_add (GTK_CONTAINER (alignment_target), hbox_target);
+ image_target = gtk_image_new_from_pixbuf (targetmarker_img);
+ gtk_box_pack_start (GTK_BOX (hbox_target),
+ image_target, FALSE, FALSE, 0);
+ label_target = gtk_label_new (_("Select Target"));
+ gtk_tooltips_set_tip ( tooltips_poilookup, button_target,
+ _("Use selected entry as target destination (and leave Pos. Mode if active)"), NULL);
+ gtk_box_pack_start (GTK_BOX (hbox_target),
+ label_target, FALSE, FALSE, 0);
+ g_signal_connect_swapped (button_target, "clicked",
+ GTK_SIGNAL_FUNC (select_target_poi_cb), NULL);
+
+ /* button "close" */
+ button_close = gtk_button_new_from_stock ("gtk-close");
+ gtk_dialog_add_action_widget (GTK_DIALOG (poi_lookup_window),
+ button_close, GTK_RESPONSE_CLOSE);
+ GTK_WIDGET_SET_FLAGS (button_close, GTK_CAN_DEFAULT);
+ gtk_tooltips_set_tip ( tooltips_poilookup, button_close,
+ _("Close this window"), NULL);
+ g_signal_connect_swapped (button_close, "clicked",
+ GTK_SIGNAL_FUNC (close_poi_lookup_window_cb),
+ poi_lookup_window);
+ g_signal_connect (GTK_OBJECT (poi_lookup_window), "delete_event",
+ GTK_SIGNAL_FUNC (close_poi_lookup_window_cb), NULL);
+
+ /* disable delete button until POI is selected from list */
+ gtk_widget_set_sensitive (button_delete, FALSE);
+
+ /* disable target selection in active routemode */
+ if (route.active)
+ gtk_widget_set_sensitive (button_target, FALSE);
+
+ gtk_widget_grab_focus (entry_text);
+}
+
+
+/* *****************************************************************************
+ * Window: Edit Route
+ */
+void route_window_cb (GtkWidget *calling_button)
+{
+ GtkWidget *dialog_vbox_route;
+ GtkWidget *vbox_routedetails;
+ GtkWidget *frame_routedetails;
+ GtkWidget *scrolledwindow_routedetails;
+ GtkWidget *alignment_startroute;
+ GtkWidget *hbox_startroute;
+ GtkWidget *image_startroute;
+ GtkWidget *label_startroute;
+ GtkWidget *label_routedetails;
+ GtkWidget *treeview_routelist;
+ GtkCellRenderer *renderer_routelist;
+ GtkTreeViewColumn *column_routelist;
+ GtkTreeSelection *routelist_select;
+ GtkWidget *dialog_action_area_routedetails;
+ GtkWidget *button_close;
+ GtkWidget *button_cancel;
+ GtkWidget *alignment_cancel;
+ GtkWidget *hbox_cancel;
+ GtkWidget *image_cancel;
+ GtkWidget *label_cancel;
+ GtkTooltips *tooltips_routewindow;
+
+ gtk_widget_set_sensitive (button_addtoroute, FALSE);
+
+ route.edit = TRUE;
+
+ if (!route.items)
+ {
+ route.distance = 0.0;
+ route.pointer = 0;
+ }
+
+ tooltips_routewindow = gtk_tooltips_new();
+ gtk_tooltips_set_delay (tooltips_routewindow, TOOLTIP_DELAY);
+ if (local_config.showtooltips)
+ gtk_tooltips_enable (tooltips_routewindow);
+ else
+ gtk_tooltips_disable (tooltips_routewindow);
+
+ route_window = gtk_dialog_new ();
+ gtk_container_set_border_width (GTK_CONTAINER (route_window), 2);
+ gtk_window_set_title (GTK_WINDOW (route_window), _("Edit Route"));
+ gtk_window_set_position (GTK_WINDOW (route_window),
+ GTK_WIN_POS_NONE);
+ gtk_window_set_type_hint (GTK_WINDOW (route_window),
+ GDK_WINDOW_TYPE_HINT_DIALOG);
+ if (local_config.guimode == GUI_PDA)
+ {
+ gtk_window_set_default_size (GTK_WINDOW (route_window),
+ real_screen_x, real_screen_y);
+ }
+ else
+ gtk_window_set_default_size (GTK_WINDOW (route_window), -1, 250);
+
+ dialog_vbox_route = GTK_DIALOG (route_window)->vbox;
+
+ vbox_routedetails = gtk_vbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox_route),
+ vbox_routedetails, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox_routedetails), 2);
+
+ /* Frame: Route-Details */
+ {
+ frame_routedetails = gtk_frame_new (NULL);
+ gtk_box_pack_start (GTK_BOX (vbox_routedetails),
+ frame_routedetails, TRUE, TRUE, 5);
+ gtk_frame_set_label_align (GTK_FRAME (frame_routedetails), 0.02, 0.5);
+
+ scrolledwindow_routedetails = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW
+ (scrolledwindow_routedetails), GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW
+ (scrolledwindow_routedetails), GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (frame_routedetails),
+ scrolledwindow_routedetails);
+
+ treeview_routelist = gtk_tree_view_new_with_model
+ (GTK_TREE_MODEL (route_list_tree));
+
+ // ### show number of point in route list...
+ renderer_routelist = gtk_cell_renderer_text_new ();
+ column_routelist = gtk_tree_view_column_new_with_attributes (
+ "#", renderer_routelist,
+ "text", ROUTE_NUMBER, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_routelist),
+ column_routelist);
+
+ renderer_routelist = gtk_cell_renderer_pixbuf_new ();
+ column_routelist = gtk_tree_view_column_new_with_attributes ("_",
+ renderer_routelist, "pixbuf", ROUTE_ICON, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_routelist),
+ column_routelist);
+
+ renderer_routelist = gtk_cell_renderer_text_new ();
+ column_routelist = gtk_tree_view_column_new_with_attributes (
+ _("Name"), renderer_routelist,
+ "text", ROUTE_NAME, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_routelist),
+ column_routelist);
+
+ renderer_routelist = gtk_cell_renderer_text_new ();
+ column_routelist = gtk_tree_view_column_new_with_attributes (
+ _("Distance"), renderer_routelist,
+ "text", ROUTE_DISTANCE, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_routelist),
+ column_routelist);
+
+ renderer_routelist = gtk_cell_renderer_text_new ();
+ column_routelist = gtk_tree_view_column_new_with_attributes (
+ _("Trip"), renderer_routelist,
+ "text", ROUTE_TRIP, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_routelist),
+ column_routelist);
+
+ gtk_container_add (GTK_CONTAINER (scrolledwindow_routedetails),
+ treeview_routelist);
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview_routelist), TRUE);
+
+ routelist_select = gtk_tree_view_get_selection
+ (GTK_TREE_VIEW (treeview_routelist));
+ gtk_tree_selection_set_mode (routelist_select, GTK_SELECTION_SINGLE);
+ g_signal_connect (G_OBJECT (routelist_select), "changed",
+ G_CALLBACK (select_routepoint_cb), NULL);
+
+ label_routedetails = gtk_label_new (_("Route List"));
+ gtk_frame_set_label_widget (GTK_FRAME (frame_routedetails),
+ label_routedetails);
+ gtk_label_set_use_markup (GTK_LABEL (label_routedetails), TRUE);
+ }
+
+ dialog_action_area_routedetails = GTK_DIALOG (route_window)->action_area;
+
+ /* button "start route" */
+ button_startroute = gtk_button_new ();
+ gtk_dialog_add_action_widget (GTK_DIALOG (route_window), button_startroute, 0);
+ GTK_WIDGET_SET_FLAGS (button_startroute, GTK_CAN_DEFAULT);
+ alignment_startroute = gtk_alignment_new (0.5, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (button_startroute), alignment_startroute);
+ hbox_startroute = gtk_hbox_new (FALSE, 2);
+ gtk_container_add (GTK_CONTAINER (alignment_startroute), hbox_startroute);
+ if (route.active)
+ {
+ image_startroute = gtk_image_new_from_stock
+ ("gtk-media-stop", GTK_ICON_SIZE_BUTTON);
+ label_startroute = gtk_label_new_with_mnemonic (_("Stop Route"));
+ gtk_tooltips_set_tip ( tooltips_routewindow, button_startroute,
+ _("Stop the Route Mode"), NULL);
+ }
+ else
+ {
+ image_startroute = gtk_image_new_from_stock
+ ("gtk-media-play", GTK_ICON_SIZE_BUTTON);
+ label_startroute = gtk_label_new_with_mnemonic (_("Start Route"));
+ gtk_tooltips_set_tip ( tooltips_routewindow,
+ button_startroute, _("Start the Route Mode"), NULL);
+ }
+ if (!route.items)
+ gtk_widget_set_sensitive (button_startroute, FALSE);
+
+ gtk_box_pack_start (GTK_BOX (hbox_startroute),
+ image_startroute, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox_startroute),
+ label_startroute, FALSE, FALSE, 0);
+ g_signal_connect (button_startroute, "clicked",
+ GTK_SIGNAL_FUNC (route_startstop_cb), NULL);
+
+ /* button "remove point from route" */
+ button_remove = gtk_button_new_from_stock ("gtk-remove");
+ gtk_dialog_add_action_widget (GTK_DIALOG (route_window), button_remove, 0);
+ GTK_WIDGET_SET_FLAGS (button_remove, GTK_CAN_DEFAULT);
+ gtk_tooltips_set_tip ( tooltips_routewindow, button_remove,
+ _("Remove selected Entry from Route"), NULL);
+ gtk_widget_set_sensitive (button_remove, FALSE);
+ g_signal_connect_swapped (button_remove, "clicked",
+ GTK_SIGNAL_FUNC (remove_routepoint_cb), routelist_select);
+
+ /* button "cancel route" */
+ button_cancel = gtk_button_new ();
+ gtk_dialog_add_action_widget (GTK_DIALOG (route_window), button_cancel, 0);
+ GTK_WIDGET_SET_FLAGS (button_cancel, GTK_CAN_DEFAULT);
+ alignment_cancel = gtk_alignment_new (0.5, 0.5, 0, 0);
+ gtk_container_add (GTK_CONTAINER (button_cancel), alignment_cancel);
+ hbox_cancel = gtk_hbox_new (FALSE, 2);
+ gtk_container_add (GTK_CONTAINER (alignment_cancel), hbox_cancel);
+ image_cancel = gtk_image_new_from_stock ("gtk-cancel", GTK_ICON_SIZE_BUTTON);
+ gtk_box_pack_start (GTK_BOX (hbox_cancel), image_cancel, FALSE, FALSE, 0);
+ label_cancel = gtk_label_new (_("Cancel Route"));
+ gtk_tooltips_set_tip ( tooltips_routewindow, button_cancel,
+ _("Discard Route"), NULL);
+ gtk_box_pack_start (GTK_BOX (hbox_cancel), label_cancel, FALSE, FALSE, 0);
+ g_signal_connect (button_cancel, "clicked",
+ GTK_SIGNAL_FUNC (route_cancel_cb), NULL);
+
+ /* button "save route" */
+ button_routesave = gtk_button_new_from_stock ("gtk-save");
+ gtk_dialog_add_action_widget (GTK_DIALOG (route_window), button_routesave, 0);
+ GTK_WIDGET_SET_FLAGS (button_routesave, GTK_CAN_DEFAULT);
+ gtk_tooltips_set_tip ( tooltips_routewindow, button_routesave,
+ _("Export current route to a GPX File"), NULL);
+ gtk_widget_set_sensitive (button_routesave, FALSE);
+ g_signal_connect (button_routesave, "clicked",
+ GTK_SIGNAL_FUNC (route_export_cb), (gpointer) TRUE);
+
+ /* button "close" */
+ button_close = gtk_button_new_from_stock ("gtk-close");
+ gtk_dialog_add_action_widget (GTK_DIALOG (route_window),
+ button_close, GTK_RESPONSE_CLOSE);
+ GTK_WIDGET_SET_FLAGS (button_close, GTK_CAN_DEFAULT);
+ gtk_tooltips_set_tip (tooltips_routewindow, button_close,
+ _("Close this window"), NULL);
+ g_signal_connect_swapped (button_close, "clicked",
+ GTK_SIGNAL_FUNC (close_route_window_cb), route_window);
+ g_signal_connect (GTK_OBJECT (route_window), "delete_event",
+ GTK_SIGNAL_FUNC (close_route_window_cb), NULL);
+
+ gtk_widget_show_all (route_window);
+}
+
+
+
diff --git a/src/poi_gui.h b/src/poi_gui.h
new file mode 100644
index 0000000..5b3adac
--- /dev/null
+++ b/src/poi_gui.h
@@ -0,0 +1,37 @@
+/***********************************************************************
+
+Copyright (c) 2001-2006 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ *********************************************************************
+
+***********************************************************************/
+
+#ifndef GPSDRIVE_POI_GUI_H
+#define GPSDRIVE_POI_GUI_H
+
+void create_window_poi_lookup (void);
+void poi_info_cb (void);
+void route_window_cb (GtkWidget *calling_button);
+gint show_poi_lookup_cb (GtkWidget *button, gpointer data);
+GtkWidget * create_poi_types_window (void);
+gint toggle_window_poitypes_cb (GtkWidget *trigger, gboolean multi);
+
+#endif /* GPSDRIVE_POI_GUI_H */
diff --git a/src/routes.c b/src/routes.c
new file mode 100644
index 0000000..3b9d1fe
--- /dev/null
+++ b/src/routes.c
@@ -0,0 +1,1135 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <sys/time.h>
+#include <stdlib.h>
+
+#include "gpsdrive.h"
+#include "gpsdrive_config.h"
+#include "poi.h"
+#include "config.h"
+#include "gettext.h"
+#include "icons.h"
+#include "routes.h"
+#include "gui.h"
+#include "main_gui.h"
+#include <speech_out.h>
+#include <speech_strings.h>
+
+#include "gettext.h"
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+extern gint debug, mydebug;
+extern GtkWidget *destframe;
+extern gint havespeechout, speechcount;
+extern gchar oldangle[100];
+extern gint saytarget;
+extern wpstruct *wayp;
+extern gint maxwp, maxfriends;
+extern friendsstruct *friends, *fserver;
+extern int sortcolumn, sortflag;
+extern gint selected_wp_list_line;
+extern GtkWidget *mylist;
+extern gint onemousebutton;
+extern gint dontsetwp;
+extern gint usesql;
+extern poi_struct *poi_list;
+extern glong poi_list_count;
+extern gdouble milesconv;
+extern color_struct colors;
+extern coordinate_struct coords;
+extern currentstatus_struct current;
+extern GdkGC *kontext_map;
+extern GtkWidget *map_drawingarea;
+extern GtkWidget *frame_statusbar;
+extern poi_type_struct poi_type_list[poi_type_list_max];
+
+GtkWidget *routewindow;
+wpstruct *routelist;
+GtkListStore *route_list_tree;
+GtkWidget *myroutelist;
+gint thisrouteline = 0;
+GtkWidget *create_route_button, *create_route2_button, *select_route_button, *gotobt;
+routestatus_struct route;
+extern GtkWidget *route_window;
+
+/* ******************************************************************
+ */
+void
+init_route_list ()
+{
+ routelist = g_new0 (wpstruct, 100);
+}
+
+/* ******************************************************************
+ */
+void
+free_route_list ()
+{
+ g_free (routelist);
+}
+
+/* *****************************************************************************
+ * set the target in routemode
+ */
+
+void
+setroutetarget (GtkWidget * widget, gint datum)
+{
+ //gchar str[200];
+ gchar buf[1000], buf2[1000], *tn;
+
+
+ if ( mydebug >50 ) fprintf(stderr , "setroutetarget()\n");
+
+ if (datum != -1)
+ route.pointer = datum;
+
+ g_strlcpy (current.target, (routelist + route.pointer)->name,
+ sizeof (current.target));
+ coords.target_lat = (routelist + route.pointer)->lat;
+ coords.target_lon = (routelist + route.pointer)->lon;
+// g_snprintf (str, sizeof (str), "%s: %s[%d/%d]", _("To"), current.target,
+// route.pointer + 1, route.items);
+// gtk_frame_set_label (GTK_FRAME (destframe), str);
+ tn = g_strdelimit (current.target, "_", ' ');
+ g_strlcpy (buf2, "", sizeof (buf2));
+ if (tn[0] == '*')
+ {
+ g_strlcpy (buf2, "das mobile Ziel ", sizeof (buf2));
+ g_strlcat (buf2, (tn + 1), sizeof (buf2));
+ }
+ else
+ g_strlcat (buf2, tn, sizeof (buf2));
+
+ g_snprintf( buf, sizeof(buf), speech_new_target[voicelang], buf2 );
+ speech_out_speek (buf);
+
+ speechcount = 0;
+ g_strlcpy (oldangle, "XXX", sizeof (oldangle));
+ saytarget = TRUE;
+}
+
+/* *****************************************************************************
+ * cancel sel_route window
+ */
+gint
+sel_routecancel_cb (GtkWidget * widget, guint datum)
+{
+ //gchar str[200];
+
+ gtk_widget_destroy (GTK_WIDGET (routewindow));
+
+// g_snprintf (str, sizeof (str), "%s: %s", _("To"), current.target);
+// gtk_frame_set_label (GTK_FRAME (destframe), str);
+ route.edit = FALSE;
+ route.active = FALSE;
+ route.pointer = route.items = 0;
+ gtk_widget_set_sensitive (create_route_button, TRUE);
+ /* enable jump button */
+ gtk_widget_set_sensitive (gotobt, TRUE);
+ return FALSE;
+}
+
+/* *****************************************************************************
+ * destroy sel_route window but continue routing
+ */
+gint
+sel_routeclose_cb (GtkWidget * widget, guint datum)
+{
+ route.edit = FALSE;
+ gtk_widget_destroy (GTK_WIDGET (routewindow));
+ gtk_widget_set_sensitive (create_route_button, TRUE);
+ return FALSE;
+}
+
+/* *****************************************************************************
+ */
+gint
+do_route_cb (GtkWidget * widget, guint datum)
+{
+ gtk_widget_destroy (GTK_WIDGET (routewindow));
+ gtk_widget_set_sensitive (create_route_button, TRUE);
+ /* disable waypoint jump button */
+ gtk_widget_set_sensitive (gotobt, FALSE);
+ route.edit = FALSE;
+ route.active = TRUE;
+ setroutetarget (NULL, -1);
+ return FALSE;
+}
+
+
+/* *****************************************************************************
+ */
+void
+insertroutepoints ()
+{
+ gint i, j;
+ gchar *text[5], text0[20], text1[20], text2[20], text3[20];
+
+ i = thisrouteline;
+ (wayp + i)->dist = calcdist ((wayp + i)->lon, (wayp + i)->lat);
+ text[1] = (wayp + i)->name;
+ g_snprintf (text0, sizeof (text0), "%d", i + 1);
+
+ coordinate2gchar(text1, sizeof(text1), (wayp+i)->lat, TRUE,
+ local_config.coordmode);
+ coordinate2gchar(text2, sizeof(text2), (wayp+i)->lon, FALSE,
+ local_config.coordmode);
+ g_snprintf (text3, sizeof (text3), "%9.3f", (wayp + i)->dist);
+ text[0] = text0;
+ text[2] = text1;
+ text[3] = text2;
+ text[4] = text3;
+ j = gtk_clist_append (GTK_CLIST (myroutelist), (gchar **) text);
+ gtk_clist_set_foreground (GTK_CLIST (myroutelist), j, &colors.black);
+ g_strlcpy ((routelist + route.items)->name, (wayp + i)->name, 40);
+ (routelist + route.items)->lat = (wayp + i)->lat;
+ (routelist + route.items)->lon = (wayp + i)->lon;
+ route.items++;
+ gtk_widget_set_sensitive (select_route_button, TRUE);
+
+}
+
+/* *****************************************************************************
+ */
+void
+insertallroutepoints ()
+{
+ gint i, j;
+ gchar *text[5], text0[20], text1[20], text2[20], text3[20];
+
+ for (i = 0; i < maxwp; i++)
+ {
+ (wayp + i)->dist =
+ calcdist ((wayp + i)->lon, (wayp + i)->lat);
+ text[1] = (wayp + i)->name;
+ g_snprintf (text0, sizeof (text0), "%d", i + 1);
+
+ coordinate2gchar(text1, sizeof(text1), (wayp+i)->lat, TRUE,
+ local_config.coordmode);
+ coordinate2gchar(text2, sizeof(text2), (wayp+i)->lon, FALSE,
+ local_config.coordmode);
+ g_snprintf (text3, sizeof (text3), "%9.3f", (wayp + i)->dist);
+ text[0] = text0;
+ text[2] = text1;
+ text[3] = text2;
+ text[4] = text3;
+ j = gtk_clist_append (GTK_CLIST (myroutelist),
+ (gchar **) text);
+ gtk_clist_set_foreground (GTK_CLIST (myroutelist), j, &colors.black);
+ g_strlcpy ((routelist + route.items)->name, (wayp + i)->name,
+ 40);
+ (routelist + route.items)->lat = (wayp + i)->lat;
+ (routelist + route.items)->lon = (wayp + i)->lon;
+ route.items++;
+ }
+ gtk_widget_set_sensitive (select_route_button, TRUE);
+
+}
+
+/* *****************************************************************************
+ */
+void
+insertwaypoints (gint mobile)
+{
+ gint i, j;
+ gchar *text[6], text0[20], text1[20], text2[20], text3[20], name[40];
+ gdouble la, lo, dist;
+ time_t ti, tif;
+
+ /* insert waypoint into the clist */
+
+ if (!mobile)
+ {
+ if (usesql)
+ {
+ return;
+ }
+ else
+ {
+ for (i = 0; i < maxwp; i++)
+ {
+ (wayp + i)->dist =
+ calcdist ((wayp + i)->lon, (wayp + i)->lat);
+
+ text[1] = (wayp + i)->name;
+ text[2] = (wayp + i)->typ;
+
+ g_snprintf (text0, sizeof (text0), "%02d", i + 1);
+ coordinate2gchar(text1, sizeof(text1),
+ (wayp+i)->lat, TRUE,
+ local_config.coordmode);
+ coordinate2gchar(text2, sizeof(text2),
+ (wayp+i)->lon, FALSE,
+ local_config.coordmode);
+ g_snprintf (text3, sizeof (text3), "%9.3f",
+ (wayp + i)->dist);
+ text[0] = text0;
+ text[3] = text1;
+ text[4] = text2;
+ text[5] = text3;
+ j = gtk_clist_append (GTK_CLIST (mylist),
+ (gchar **) text);
+ gtk_clist_set_foreground (GTK_CLIST (mylist), j,
+ &colors.black);
+ }
+ }
+ }
+
+ for (i = 0; i < maxfriends; i++)
+ {
+ ti = time (NULL);
+ tif = atol ((friends + i)->timesec);
+ if ((ti - local_config.friends_maxsecs) > tif)
+ continue;
+
+ if (mobile)
+ g_strlcpy (name, "", sizeof (name));
+ else
+ g_strlcpy (name, "*", sizeof (name));
+ g_strlcat (name, (friends + i)->name, sizeof (name));
+ g_snprintf (text0, sizeof (text0), "%d", i + maxwp + 1);
+ coordinate_string2gdouble((friends + i)->lat, &la);
+ coordinate_string2gdouble((friends + i)->lon, &lo);
+ coordinate2gchar(text1, sizeof(text1), la, TRUE,
+ local_config.coordmode);
+ coordinate2gchar(text2, sizeof(text2), lo, FALSE,
+ local_config.coordmode);
+
+ if (!mobile)
+ {
+ text[0] = text0;
+ text[1] = name;
+ text[2] = (friends + i)->type;
+ text[3] = text1;
+ text[4] = text2;
+ dist = calcdist (lo, la);
+ g_snprintf (text3, sizeof (text3), "%9.3f", dist);
+ text[5] = text3;
+ }
+ else
+ {
+ text[0] = name;
+ text[1] = text1;
+ text[2] = text2;
+ dist = calcdist (lo, la);
+ g_snprintf (text3, sizeof (text3), "%9.3f", dist);
+ text[3] = text3;
+ }
+
+ j = gtk_clist_append (GTK_CLIST (mylist), (gchar **) text);
+ if (mobile)
+ gtk_clist_set_foreground (GTK_CLIST (mylist), j,
+ &colors.black);
+ else
+ gtk_clist_set_foreground (GTK_CLIST (mylist), j,
+ &colors.red);
+ }
+
+ /* we want te columns sorted by distance from current position */
+ gtk_clist_set_sort_column (GTK_CLIST (mylist), (gint) sortcolumn);
+ gtk_clist_sort (GTK_CLIST (mylist));
+}
+
+/* *****************************************************************************
+ */
+gint
+reinsertwp_cb (GtkWidget * widget, guint datum)
+{
+ gint i, j, k, val;
+ gchar *p;
+ GtkAdjustment *ad;
+
+ /* update routine for select target window */
+ k = 0;
+ ad = gtk_clist_get_vadjustment (GTK_CLIST (mylist));
+ val = (GTK_ADJUSTMENT (ad)->value);
+
+ gtk_clist_freeze (GTK_CLIST (mylist));
+ gtk_clist_clear (GTK_CLIST (mylist));
+ insertwaypoints (FALSE);
+ for (i = 0; i < maxwp; i++)
+ {
+ gtk_clist_get_text (GTK_CLIST (mylist), i, 0, &p);
+ j = atol (p);
+ if (selected_wp_list_line == j)
+ {
+ k = i;
+ break;
+ }
+ }
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (ad), val);
+ dontsetwp = TRUE;
+ gtk_clist_select_row (GTK_CLIST (mylist), k, 0);
+ dontsetwp = FALSE;
+ gtk_clist_thaw (GTK_CLIST (mylist));
+ return TRUE;
+}
+
+/* ******************************************************************
+ *
+ */
+gint
+create_route_cb (GtkWidget * widget, guint datum)
+{
+ GtkWidget *window;
+ gchar *tabeltitel1[] = { "#",
+ _("Waypoint"), _("Latitude"), _("Longitude"), _("Distance"),
+ NULL
+ };
+ GtkWidget *scrwindow, *vbox, *button, *button3, *hbox, *hbox_displays, *l1;
+ gint i, j;
+ gchar *text[5], text0[20], text1[20], text2[20], text3[20];
+ GtkTooltips *tooltips;
+
+ route.edit = TRUE;
+ window = gtk_dialog_new ();
+ routewindow = window;
+ /* gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, TRUE); */
+
+ gtk_window_set_title (GTK_WINDOW (window), _("Define route"));
+ gtk_window_set_default_size (GTK_WINDOW (window), 320, 320);
+ myroutelist = gtk_clist_new_with_titles (5, tabeltitel1);
+ gtk_signal_connect (GTK_OBJECT (GTK_CLIST (myroutelist)),
+ "select-row",
+ GTK_SIGNAL_FUNC (setroutetarget),
+ GTK_OBJECT (myroutelist));
+
+ select_route_button = gtk_button_new_with_label (_("Start route"));
+ gtk_widget_set_sensitive (select_route_button, FALSE);
+
+ GTK_WIDGET_SET_FLAGS (select_route_button, GTK_CAN_DEFAULT);
+ gtk_signal_connect (GTK_OBJECT (select_route_button), "clicked",
+ GTK_SIGNAL_FUNC (do_route_cb), 0);
+ gtk_window_set_default (GTK_WINDOW (window), select_route_button);
+
+ create_route2_button =
+ gtk_button_new_with_label (_("Take all WP as route"));
+ GTK_WIDGET_SET_FLAGS (create_route2_button, GTK_CAN_DEFAULT);
+ gtk_signal_connect (GTK_OBJECT (create_route2_button), "clicked",
+ GTK_SIGNAL_FUNC (insertallroutepoints), 0);
+
+ button = gtk_button_new_with_label (_("Abort route"));
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+ gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC
+ (sel_routecancel_cb), GTK_OBJECT (window));
+ gtk_signal_connect_object (GTK_OBJECT (window),
+ "delete_event",
+ GTK_SIGNAL_FUNC
+ (sel_routeclose_cb), GTK_OBJECT (window));
+
+ /* button3 = gtk_button_new_with_label (_("Close")); */
+ button3 = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
+ GTK_WIDGET_SET_FLAGS (button3, GTK_CAN_DEFAULT);
+ gtk_signal_connect_object (GTK_OBJECT (button3), "clicked",
+ GTK_SIGNAL_FUNC
+ (sel_routeclose_cb), GTK_OBJECT (window));
+
+ /* Font �ndern falls PDA-Mode und Touchscreen */
+ if (local_config.guimode == GUI_PDA)
+ {
+ if (onemousebutton)
+ {
+
+ /* Change default font throughout the widget */
+ PangoFontDescription *font_desc;
+ font_desc =
+ pango_font_description_from_string
+ ("Sans 10");
+ gtk_widget_modify_font (myroutelist, font_desc);
+ pango_font_description_free (font_desc);
+ }
+ }
+
+ gtk_clist_set_column_justification (GTK_CLIST (myroutelist), 4,
+ GTK_JUSTIFY_RIGHT);
+ gtk_clist_set_column_justification (GTK_CLIST (myroutelist), 0,
+ GTK_JUSTIFY_RIGHT);
+ gtk_clist_set_column_auto_resize (GTK_CLIST (myroutelist), 0, TRUE);
+ gtk_clist_set_column_auto_resize (GTK_CLIST (myroutelist), 1, TRUE);
+ gtk_clist_set_column_auto_resize (GTK_CLIST (myroutelist), 2, TRUE);
+ gtk_clist_set_column_auto_resize (GTK_CLIST (myroutelist), 3, TRUE);
+ gtk_clist_set_column_auto_resize (GTK_CLIST (myroutelist), 4, TRUE);
+
+ scrwindow = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (scrwindow), myroutelist);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW
+ (scrwindow),
+ (GtkPolicyType)
+ GTK_POLICY_AUTOMATIC,
+ (GtkPolicyType) GTK_POLICY_AUTOMATIC);
+ vbox = gtk_vbox_new (FALSE, 2);
+ /* gtk_container_add (GTK_CONTAINER (window), vbox); */
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (window)->vbox), vbox, TRUE, TRUE, 2);
+
+ gtk_box_pack_start (GTK_BOX (vbox), scrwindow, TRUE, TRUE, 2);
+ hbox = gtk_hbox_new (TRUE, 2);
+ hbox_displays = gtk_hbox_new (TRUE, 2);
+ if (!route.active)
+ l1 = gtk_label_new (_
+ ("Click on waypoints list\nto add waypoints"));
+ else
+ l1 = gtk_label_new (_
+ ("Click on list item\nto select next waypoint"));
+ gtk_box_pack_start (GTK_BOX (vbox), l1, FALSE, FALSE, 2);
+ /* gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 2); */
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (window)->action_area),
+ hbox, TRUE, TRUE, 2);
+
+ gtk_box_pack_start (GTK_BOX (hbox), select_route_button, TRUE, TRUE,
+ 2);
+ gtk_box_pack_start (GTK_BOX (hbox), create_route2_button, TRUE, TRUE,
+ 2);
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 2);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox_displays, FALSE, FALSE, 2);
+ gtk_box_pack_start (GTK_BOX (hbox), button3, TRUE, TRUE, 2);
+ gtk_widget_set_sensitive (create_route_button, FALSE);
+
+ if (route.active)
+ {
+ gtk_widget_set_sensitive (select_route_button, FALSE);
+ gtk_clist_clear (GTK_CLIST (myroutelist));
+ for (i = 0; i < route.items; i++)
+ {
+ (routelist + i)->dist =
+ calcdist ((routelist + i)->lon,
+ (routelist + i)->lat);
+ text[1] = (routelist + i)->name;
+ g_snprintf (text0, sizeof (text0), "%d", i + 1);
+ g_snprintf (text1, sizeof (text1), "%8.5f",
+ (routelist + i)->lat);
+ g_snprintf (text2, sizeof (text2), "%8.5f",
+ (routelist + i)->lon);
+ g_snprintf (text3, sizeof (text3), "%9.3f",
+ (routelist + i)->dist);
+ text[0] = text0;
+ text[2] = text1;
+ text[3] = text2;
+ text[4] = text3;
+ j = gtk_clist_append (GTK_CLIST (myroutelist),
+ (gchar **) text);
+ gtk_clist_set_foreground (GTK_CLIST (myroutelist), j,
+ &colors.black);
+ }
+ }
+ else
+ route.items = 0;
+ tooltips = gtk_tooltips_new ();
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (tooltips), create_route2_button,
+ _
+ ("Create a route from all waypoints. Sorted with order in file, not distance."),
+ NULL);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (tooltips), select_route_button,
+ _
+ ("Click here to start your journey. GpsDrive guides you through the waypoints in this list."),
+ NULL);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (tooltips), button,
+ _("Abort your journey"), NULL);
+
+ gtk_widget_show_all (window);
+
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ */
+void
+route_next_target ()
+{
+ //gchar str[100];
+ gchar buf[200];
+ gdouble d;
+ /* test for new route point */
+ if (strcmp (current.target, " "))
+ {
+ if (route.active)
+ d = calcdist ((routelist + route.pointer)->lon,
+ (routelist + route.pointer)->lat);
+ else
+ d = calcdist (coords.target_lon, coords.target_lat);
+
+ if (d <= ROUTEREACH || route.forcenext)
+ {
+ route.forcenext = FALSE;
+ if ((route.pointer != (route.items - 1)) && (route.active))
+ {
+ route.pointer++;
+
+ /* let's say the waypoint description */
+ saytargettext (local_config.wp_file, current.target);
+
+ setroutetarget (NULL, -1);
+ }
+ else
+ {
+ /* route endpoint reached */
+ if (saytarget)
+ {
+ g_snprintf (buf, sizeof (buf),
+ speech_target_reached[voicelang], current.target);
+ speech_out_speek (buf);
+
+ /* let's say the waypoint description */
+ saytargettext (local_config.wp_file, current.target);
+ }
+// g_snprintf (str, sizeof (str),
+// "%s: %s", _("To"), current.target);
+// gtk_frame_set_label (GTK_FRAME (destframe), str);
+ route.edit = FALSE;
+ route.active = FALSE;
+ saytarget = FALSE;
+ route.pointer = route.items = 0;
+ }
+ }
+ }
+}
+
+
+// ***********************************************************************
+// ***********************************************************************
+// ***********************************************************************
+// Here follows the new, POI-related route stuff...
+
+
+/* *****************************************************************************
+ * create a new POI of type "waypoint.routepoint"
+ * and append it to the current route
+ */
+void quickadd_routepoint ()
+{
+
+ gchar t_name[100], t_cmt[100], t_nr[5], t_trip[15];;
+ gchar t_dist[15], t_type[POI_TYPE_LIST_STRING_LENGTH];
+ gdouble t_lat, t_lon, last_lat, last_lon, t_dist_num;
+ glong t_id;
+ gint t_x, t_y, t_ptid;
+ GdkPixbuf *t_icon;
+ GdkModifierType state;
+ GtkTreeIter iter_route;
+ GtkTreePath *path_route;
+
+ time_t t;
+ struct tm *ts;
+ time (&t);
+
+ ts = localtime (&t);
+ g_snprintf (t_name, sizeof (t_name), _("Routepoint"));
+ g_snprintf (t_cmt, sizeof (t_cmt), _("Quicksaved Routepoint"));
+ gdk_window_get_pointer (map_drawingarea->window, &t_x, &t_y, &state);
+ calcxytopos (t_x, t_y, &t_lat, &t_lon, current.zoom);
+ if ( mydebug > 0 )
+ printf ("Add Routepoint: %s lat:%f,lon:%f (x:%d,y:%d)\n",
+ t_name, t_lat, t_lon, t_x, t_y);
+
+ t_id = addwaypoint (t_name,
+ "waypoint.routepoint", t_cmt, t_lat, t_lon, TRUE);
+
+ t_ptid = poi_type_id_from_name ("waypoint.routepoint");
+ t_icon = poi_type_list[t_ptid].icon;
+
+ gtk_list_store_append (route_list_tree, &iter_route);
+
+ route.items +=1;
+
+ /* calculate trip distance */
+ if (route.items > 1)
+ {
+ path_route = gtk_tree_model_get_path (GTK_TREE_MODEL
+ (route_list_tree), &iter_route);
+ gtk_tree_path_prev (path_route);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (route_list_tree),
+ &iter_route, path_route);
+ gtk_tree_model_get (GTK_TREE_MODEL (route_list_tree),
+ &iter_route,
+ ROUTE_LON, &last_lon, ROUTE_LAT, &last_lat, -1);
+ route.distance += calc_wpdist (last_lon, last_lat,
+ t_lon, t_lat, FALSE);
+ gtk_tree_path_next (path_route);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (route_list_tree),
+ &iter_route, path_route);
+
+ if (mydebug>25)
+ {
+ fprintf (stderr, "quickadd_routepoint: Path: %s\n",
+ gtk_tree_path_to_string (path_route));
+ }
+ }
+ else if (route.items == 1)
+ {
+ route.distance =+ calcdist (t_lon, t_lat);
+ }
+ g_snprintf (t_trip, sizeof (t_trip), "%9.3f", route.distance);
+ g_snprintf (t_nr, sizeof (t_nr), " %d", route.items);
+ g_strlcat (t_name, t_nr, sizeof (t_name));
+ t_dist_num = calcdist (t_lon, t_lat);
+ g_snprintf (t_dist, sizeof (t_dist), "%9.3f", t_dist_num);
+ g_snprintf (t_type, sizeof (t_type), "waypoint.routepoint");
+
+ if (mydebug>25)
+ {
+ fprintf (stderr, "add_point_to_route: (%d) ID: %ld |"
+ " NAME: %s | LON: %f | LAT: %f | ICON: %p\n",
+ route.items, t_id, t_name, t_lon, t_lat, t_icon);
+ }
+
+ gtk_list_store_set (route_list_tree, &iter_route,
+ ROUTE_ID, t_id,
+ ROUTE_NUMBER, route.items,
+ ROUTE_ICON, t_icon,
+ ROUTE_NAME, t_name,
+ ROUTE_DISTANCE, t_dist,
+ ROUTE_TRIP, t_trip,
+ ROUTE_LON, t_lon,
+ ROUTE_LAT, t_lat,
+ ROUTE_CMT, t_cmt,
+ ROUTE_TYPE, t_type,
+ -1);
+
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar),
+ current.statusbar_id,
+ _("Routepoint added."));
+}
+
+
+/* *****************************************************************************
+ * save current route to gpx file
+ */
+gboolean route_export_cb (gboolean defaultfile)
+{
+ const gchar gpx_head[] =
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<gpx\n xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n"
+ " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
+ " xmlns=\"http://www.topografix.com/GPX/1/0\"\n"
+ " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0"
+ " http://www.topografix.com/GPX/1/0/gpx.xsd\"\n"
+ " version=\"1.0\"\n"
+ " creator=\"GPSDrive %s - http://www.gpsdrive.de\">\n"
+ "<name>exported GPSDrive Route</name>\n"
+ "<time>%s</time>\n"
+ "\n<rte>\n";
+ const gchar gpx_foot[] = "</rte>\n\n</gpx>\n";
+
+ FILE *routefile;
+ gchar filepath[1024];
+ GTimeVal current_time;
+ GtkTreeIter iter;
+ gchar *t_name, *t_cmt, *t_type;
+ gdouble t_lat, t_lon;
+
+ if (!defaultfile)
+ {
+ // TODO: add dialog to enter filename and other route data
+ }
+ else
+ {
+ g_snprintf (filepath, sizeof (filepath), "%sroutesaved.gpx",
+ local_config.dir_home);
+ }
+
+ routefile = fopen(filepath, "w+t");
+ if(routefile == NULL)
+ {
+ perror (filepath);
+ return FALSE;
+ }
+ g_get_current_time (&current_time);
+ fprintf (routefile, gpx_head,
+ PACKAGE_VERSION, g_time_val_to_iso8601 (&current_time));
+
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (route_list_tree), &iter);
+ do
+ {
+ gtk_tree_model_get
+ (GTK_TREE_MODEL (route_list_tree), &iter,
+ ROUTE_NAME, &t_name,
+ ROUTE_LON, &t_lon,
+ ROUTE_LAT, &t_lat,
+ ROUTE_CMT, &t_cmt,
+ ROUTE_TYPE, &t_type,
+ -1);
+ fprintf (routefile, " <rtept lat=\"%.6f\" lon=\"%.6f\">\n",
+ t_lat, t_lon);
+ if (strlen (t_name))
+ fprintf (routefile, " <name>%s</name>\n", t_name);
+ if (strncmp (t_cmt, "n/a", 3) != 0)
+ fprintf (routefile, " <cmt>%s</cmt>\n", t_cmt);
+ fprintf (routefile, " <type>%s</type>\n", t_type);
+ fprintf (routefile, " </rtept>\n");
+ }
+ while (gtk_tree_model_iter_next (GTK_TREE_MODEL
+ (route_list_tree), &iter));
+
+ fprintf (routefile, gpx_foot);
+
+ fclose (routefile);
+ g_free (t_name);
+ g_free (t_cmt);
+ g_free (t_type);
+
+ gtk_statusbar_push (GTK_STATUSBAR (frame_statusbar),
+ current.statusbar_id,
+ _("Route saved"));
+
+ return TRUE;
+}
+
+
+/* ****************************************************************************
+ * set target to the given route item
+ */
+void
+route_settarget (gint rt_ptr)
+{
+ gchar t_rt_ptr[5];
+ gchar *t_name;
+ GtkTreeIter iter_route;
+
+ if ( mydebug >50 )
+ fprintf (stderr , "route_settarget: ");
+
+ if (rt_ptr == -1)
+ {
+ g_snprintf (t_rt_ptr, sizeof (t_rt_ptr),
+ "%d", (route.pointer));
+ }
+ else
+ {
+ g_snprintf (t_rt_ptr, sizeof (t_rt_ptr),
+ "%d", (rt_ptr));
+ }
+ gtk_tree_model_get_iter_from_string
+ (GTK_TREE_MODEL (route_list_tree), &iter_route, t_rt_ptr);
+ gtk_tree_model_get
+ (GTK_TREE_MODEL (route_list_tree), &iter_route,
+ ROUTE_NAME, &t_name,
+ ROUTE_LON, &(coords.target_lon),
+ ROUTE_LAT, &(coords.target_lat),
+ -1);
+ g_snprintf (current.target, sizeof (current.target), t_name);
+
+ if ( mydebug >50 )
+ fprintf (stderr , "(%d/%d) %.6f / %.6f - %s\n",
+ route.pointer, route.items, coords.target_lat,
+ coords.target_lon, current.target);
+
+ //TODO: do speech output, if enabled
+/*
+ g_snprintf (str, sizeof (str), "%s: %s[%d/%d]", _("To"), targetname,
+ route.pointer + 1, route.items);
+ gtk_frame_set_label (GTK_FRAME (destframe), str);
+ tn = g_strdelimit (targetname, "_", ' ');
+ g_strlcpy (buf2, "", sizeof (buf2));
+ if (tn[0] == '*')
+ {
+ g_strlcpy (buf2, "das mobile Ziel ", sizeof (buf2));
+ g_strlcat (buf2, (tn + 1), sizeof (buf2));
+ }
+ else
+ g_strlcat (buf2, tn, sizeof (buf2));
+
+ g_snprintf( buf, sizeof(buf), speech_new_target[voicelang], buf2 );
+ speech_out_speek (buf);
+
+ speechcount = 0;
+ g_strlcpy (oldangle, "XXX", sizeof (oldangle));
+ saytarget = TRUE;
+*/
+
+
+ g_free (t_name);
+}
+
+
+/* ****************************************************************************
+ * draw lines showing the route
+ */
+void
+draw_route (void)
+{
+ GdkSegment *route_seg;
+
+ gdouble destpos_x, destpos_y, curpos_x, curpos_y;
+ gint i, j;
+ gint t = 0;
+ gchar t_routept[5];
+ GtkTreeIter iter_route;
+ gdouble t_lon, t_lat;
+
+ if (route.items < 1)
+ return;
+
+ i = (route.items + 5);
+ route_seg = g_new0 (GdkSegment, i);
+
+ if (usesql)
+ {
+ /* poi mode */
+ g_snprintf (t_routept, sizeof (t_routept), "%d",
+ (route.pointer));
+ gtk_tree_model_get_iter_from_string
+ (GTK_TREE_MODEL (route_list_tree),
+ &iter_route, t_routept);
+
+ calcxy (&curpos_x, &curpos_y,
+ coords.current_lon, coords.current_lat, current.zoom);
+ (route_seg)->x1 = curpos_x;
+ (route_seg)->y1 = curpos_y;
+
+ do
+ {
+ gtk_tree_model_get
+ (GTK_TREE_MODEL (route_list_tree), &iter_route,
+ ROUTE_LON, &t_lon, ROUTE_LAT, &t_lat, -1);
+ if (t != 0)
+ {
+ (route_seg + t)->x1 = (route_seg + t - 1)->x2;
+ (route_seg + t)->y1 = (route_seg + t - 1)->y2;
+ }
+ calcxy (&destpos_x, &destpos_y, t_lon, t_lat,
+ current.zoom);
+ (route_seg + t)->x2 = destpos_x;
+ (route_seg + t)->y2 = destpos_y;
+ t++;
+ }
+ while (gtk_tree_model_iter_next (GTK_TREE_MODEL
+ (route_list_tree), &iter_route));
+ }
+ else
+ {
+ /* waypoints mode */
+ /* start beginning with actual route.pointer */
+ for (j = route.pointer; j < route.items; j++)
+ {
+ /* start drawing with current_pos */
+ if (j == route.pointer)
+ {
+ calcxy (&curpos_x, &curpos_y,
+ coords.current_lon,
+ coords.current_lat, current.zoom);
+ (route_seg + t)->x1 = curpos_x;
+ (route_seg + t)->y1 = curpos_y;
+ }
+ else
+ {
+ (route_seg + t)->x1 = (route_seg + t - 1)->x2;
+ (route_seg + t)->y1 = (route_seg + t - 1)->y2;
+ }
+ calcxy (&destpos_x, &destpos_y, (routelist +
+ j)->lon, (routelist + j)->lat, current.zoom);
+ (route_seg + t)->x2 = destpos_x;
+ (route_seg + t)->y2 = destpos_y;
+ t++;
+ }
+ }
+
+ gdk_gc_set_line_attributes (kontext_map, 4, GDK_LINE_ON_OFF_DASH, 0, 0);
+ gdk_gc_set_foreground (kontext_map, &colors.route);
+ gdk_draw_segments (drawable, kontext_map, (GdkSegment *) route_seg, t);
+ g_free (route_seg);
+}
+
+
+/* *******************************************************
+ * append selected poi to the end of the route
+ */
+void
+add_poi_to_route (GtkTreeModel *model, GtkTreeIter iter)
+{
+ GtkTreeIter iter_route;
+ GtkTreePath *path_route;
+
+ GdkPixbuf *t_icon;
+ gchar *t_name, *t_dist, *t_cmt, *t_type;
+ gchar t_trip[15];
+ gint t_id;
+ gdouble t_lon, t_lat, t_distnum, last_lon, last_lat;
+
+ route.items +=1;
+
+ /* get data from selected POI */
+ gtk_tree_model_get (model, &iter,
+ RESULT_ID, &t_id,
+ RESULT_TYPE_ICON, &t_icon,
+ RESULT_NAME, &t_name,
+ RESULT_LON, &t_lon,
+ RESULT_LAT, &t_lat,
+ RESULT_DISTANCE, &t_dist,
+ RESULT_DIST_NUM, &t_distnum,
+ RESULT_COMMENT, &t_cmt,
+ RESULT_TYPE_NAME, &t_type,
+ -1);
+
+ gtk_list_store_append (route_list_tree, &iter_route);
+
+ /* calculate trip distance */
+ if (route.items > 1)
+ {
+ path_route = gtk_tree_model_get_path (GTK_TREE_MODEL
+ (route_list_tree), &iter_route);
+ gtk_tree_path_prev (path_route);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (route_list_tree),
+ &iter_route, path_route);
+ gtk_tree_model_get (GTK_TREE_MODEL (route_list_tree),
+ &iter_route,
+ ROUTE_LON, &last_lon, ROUTE_LAT, &last_lat, -1);
+ route.distance += calc_wpdist (last_lon, last_lat,
+ t_lon, t_lat, FALSE);
+ gtk_tree_path_next (path_route);
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (route_list_tree),
+ &iter_route, path_route);
+
+ if (mydebug>25)
+ {
+ fprintf (stderr, "add_poi_to_route: Path: %s\n",
+ gtk_tree_path_to_string (path_route));
+ }
+ }
+ else if (route.items == 1)
+ {
+ route.distance =+ calcdist (t_lon, t_lat);
+ }
+ g_snprintf (t_trip, sizeof (t_trip), "%9.3f", route.distance);
+
+ if (mydebug>25)
+ {
+ fprintf (stderr, "add_poi_to_route: (%d) ID: %d |"
+ " NAME: %s | LON: %f | LAT: %f | ICON: %p\n",
+ route.items, t_id, t_name, t_lon, t_lat, t_icon);
+ }
+
+ gtk_list_store_set (route_list_tree, &iter_route,
+ ROUTE_ID, t_id,
+ ROUTE_NUMBER, route.items,
+ ROUTE_ICON, t_icon,
+ ROUTE_NAME, t_name,
+ ROUTE_DISTANCE, t_dist,
+ ROUTE_TRIP, t_trip,
+ ROUTE_LON, t_lon,
+ ROUTE_LAT, t_lat,
+ ROUTE_CMT, t_cmt,
+ ROUTE_TYPE, t_type,
+ -1);
+
+ g_object_unref (t_icon);
+ g_free (t_name);
+ g_free (t_dist);
+ g_free (t_cmt);
+ g_free (t_type);
+}
+
+
+/* *******************************************************
+ * update route, if the current position has changed:
+ */
+void
+update_route (void)
+{
+ gdouble d;
+
+ /* in waypoint mode call the old function */
+ if (!usesql)
+ {
+ route_next_target ();
+ return;
+ }
+
+ /* check if current target is reached, and select next */
+ if (route.active)
+ {
+ d = calcdist (coords.target_lon, coords.target_lat);
+
+ if (d <= ROUTEREACH || route.forcenext)
+ {
+ route.forcenext = FALSE;
+ if (route.pointer != (route.items - 1))
+ {
+ /* set target to next route item */
+ route.pointer++;
+ route_settarget (-1);
+ }
+ else
+ {
+ /* endpoint reached, stop routing */
+ route.active = FALSE;
+ route.pointer = route.items = 0;
+ }
+ }
+ }
+
+ /* recalculate trip /distance data if values are displayed */
+ if (route.items && GTK_IS_WIDGET (route_window))
+ {
+ // TODO: add functionality...
+ }
+}
+
+
+/* *******************************************************
+ * basic init for routing support
+ */
+void
+route_init (void)
+{
+
+ /* init gtk-list for storage of route data */
+ route_list_tree = gtk_list_store_new (ROUTE_COLUMS,
+ G_TYPE_INT, /* ROUTE_ID */
+ G_TYPE_INT, /* ROUTE_NUMBER */
+ GDK_TYPE_PIXBUF, /* ROUTE_ICON */
+ G_TYPE_STRING, /* ROUTE_NAME */
+ G_TYPE_STRING, /* ROUTE_DISTANCE */
+ G_TYPE_STRING, /* ROUTE_TRIP */
+ G_TYPE_DOUBLE, /* ROUTE_LON */
+ G_TYPE_DOUBLE, /* ROUTE_LAT */
+ G_TYPE_STRING, /* ROUTE_CMT */
+ G_TYPE_STRING /* ROUTE_TYPE */
+ );
+
+ /* init route status data */
+ route.active = FALSE; /* routemode off */
+ route.edit = FALSE; /* route editmode off */
+ route.items = 0; /* route is empty/not available */
+ route.distance = 0.0; /* route length is 0 */
+ route.pointer = 0; /* reset next route target */
+ route.show = TRUE; /* default route display is on */
+ route.forcenext = FALSE;
+}
diff --git a/src/routes.h b/src/routes.h
new file mode 100644
index 0000000..e5ee277
--- /dev/null
+++ b/src/routes.h
@@ -0,0 +1,65 @@
+/***********************************************************************
+
+Copyright (c) 2001,2002 Fritz Ganter <ganter@ganter.at>
+
+Website: www.kraftvoll.at/software
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+#ifndef GPSDRIVE_ROUTE_H
+#define GPSDRIVE_ROUTE_H
+
+#include <gtk/gtk.h>
+
+extern gint thisrouteline;
+extern GtkWidget *create_route_button;
+extern GtkWidget *create_route2_button;
+extern GtkWidget *select_route_button;
+extern GtkWidget *gotobt;
+
+void init_route_list ();
+void free_route_list ();
+void insertwaypoints (gint mobile);
+
+void quickadd_routepoint ();
+
+void route_init (void);
+gboolean route_export_cb (gboolean defaultfile);
+
+void add_poi_to_route (GtkTreeModel *model, GtkTreeIter iter);
+
+void draw_route ();
+void route_settarget (gint rt_ptr);
+void update_route (void);
+
+enum {
+ ROUTE_ID,
+ ROUTE_NUMBER,
+ ROUTE_ICON,
+ ROUTE_NAME,
+ ROUTE_DISTANCE,
+ ROUTE_TRIP,
+ ROUTE_LON,
+ ROUTE_LAT,
+ ROUTE_CMT,
+ ROUTE_TYPE,
+ ROUTE_COLUMS
+};
+
+#endif /* GPSDRIVE_ROUTE_H */
diff --git a/src/settings.c b/src/settings.c
new file mode 100644
index 0000000..1d77dcf
--- /dev/null
+++ b/src/settings.c
@@ -0,0 +1,2223 @@
+/*
+ Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+ Website: www.gpsdrive.de
+
+ Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* Include Dateien */
+#include "config.h"
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <math.h>
+#include "poi.h"
+#include "poi_gui.h"
+
+#include <sys/time.h>
+#include <gpsdrive.h>
+#include "gui.h"
+
+#include "gettext.h"
+
+#include <time.h>
+#include <dirent.h>
+#include <arpa/inet.h>
+#include "gpsdrive_config.h"
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+
+extern gint mydebug, havespeechout;
+
+typedef struct
+{
+ gchar n[200];
+}
+namesstruct;
+
+extern namesstruct *names;
+extern GtkWidget *addwaypointwindow;
+extern gchar gpsdservername[200];
+extern gint needreloadmapconfig;
+extern GtkWidget *mapdirbt, *addwaypoint1, *addwaypoint2,
+ *frame_speed, *frame_sats;
+extern gint isnight, disableisnight;
+extern gint nighttimer, iszoomed;
+extern gint newsatslevel;
+extern gint wpsize, satfix, usedgps, earthmate;
+extern GtkWidget *miles;
+extern gint gcount, downloadwindowactive;
+extern GtkWidget *status, *pixmapwidget, *gotowindow;
+extern GtkWidget *routewindow, *setupentry[50], *setupentrylabel[50];
+extern GtkWidget *poi_types_window;
+extern GtkWidget *frame_statusfriends;
+static gdouble hour, sunrise, sunset;
+extern gchar utctime[20], loctime[20];
+extern gint real_screen_x, real_screen_y, real_psize, real_smallmenu;
+extern gdouble tripodometer, tripavspeed, triptime, tripmaxspeed, triptmp,
+ milesconv;
+extern gint tripavspeedcount;
+extern gint lastnotebook;
+extern GtkWidget *settingsnotebook, *slowcpubt;
+GtkWidget *ge12;
+gint zone;
+
+#define MAXDBNAME 30
+extern char dbhost[MAXDBNAME], dbuser[MAXDBNAME], dbpass[MAXDBNAME];
+extern char dbtable[MAXDBNAME], dbname[MAXDBNAME];
+extern poi_type_struct poi_type_list[poi_type_list_max];
+extern int poi_type_list_count;
+extern double dbdistance;
+extern int dbusedist;
+GtkWidget *sqlfn[100], *ipbt;
+gint sqlselects[MAXPOITYPES], sqlandmode = TRUE;
+extern GdkColormap *cmap;
+
+extern gint usesql;
+extern gint storetz;
+static gboolean friendsiplock = FALSE;
+static gboolean friendsnamelock = FALSE;
+extern gchar *font_wplabel;
+extern char friendserverip[20];
+GtkWidget *entryavspeed, *entrymaxspeed, *entrytripodometer, *entrytriptime,
+ *tripunitlabel;
+extern color_struct colors;
+extern currentstatus_struct current;
+extern GtkTreeStore *poi_types_tree;
+int showsid = TRUE;
+extern int expedia_de;
+GtkWidget *menuitem_sendmsg;
+
+GtkWidget *settings_window = NULL;
+
+/* ****************************************************************************
+ * CALLBACKS
+ */
+
+/* ************************************************************************* */
+static gint
+setdistmode_cb (GtkWidget *widget)
+{
+ gint selection;
+
+ selection = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
+
+ switch (selection)
+ {
+ case DIST_MILES:
+ milesconv = KM2MILES;
+ local_config.distmode = DIST_MILES;
+ break;
+ case DIST_METRIC:
+ milesconv = 1.0;
+ local_config.distmode = DIST_METRIC;
+ break;
+ case DIST_NAUTIC:
+ milesconv = KM2NAUTIC;
+ local_config.distmode = DIST_NAUTIC;
+ break;
+ }
+
+ current.needtosave = TRUE;
+
+ if (mydebug >10)
+ fprintf (stderr, "Setting distance format to %d %%.\n",
+ local_config.distmode);
+
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setaltmode_cb (GtkWidget *widget)
+{
+ gint selection;
+
+ selection = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
+
+ if (selection != -1)
+ local_config.altmode = selection;
+
+ if (mydebug >10)
+ fprintf (stderr, "Setting altitude display format to %d.\n",
+ local_config.altmode);
+
+ current.needtosave = TRUE;
+
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setcolor_cb (GtkWidget *widget, GdkColor *targetcolor)
+{
+ gchar *tcol;
+
+ gtk_color_button_get_color
+ (GTK_COLOR_BUTTON (widget), targetcolor);
+
+ tcol = get_colorstring (&colors.track);
+ g_strlcpy (local_config.color_track, tcol,
+ sizeof (local_config.color_track));
+ g_free (tcol);
+ tcol = get_colorstring (&colors.route);
+ g_strlcpy (local_config.color_route, tcol,
+ sizeof (local_config.color_route));
+ g_free (tcol);
+ tcol = get_colorstring (&colors.friends);
+ g_strlcpy (local_config.color_friends, tcol,
+ sizeof (local_config.color_friends));
+ g_free (tcol);
+ tcol = get_colorstring (&colors.wplabel);
+ g_strlcpy (local_config.color_wplabel, tcol,
+ sizeof (local_config.color_wplabel));
+ g_free (tcol);
+ tcol = get_colorstring (&colors.dashboard);
+ g_strlcpy (local_config.color_dashboard, tcol,
+ sizeof (local_config.color_dashboard));
+ g_free (tcol);
+
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setcoordmode_cb (GtkWidget *widget)
+{
+ gint selection;
+
+ selection = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
+
+ if (selection != -1)
+ {
+ local_config.coordmode = selection;
+ if (mydebug >10)
+ fprintf (stderr, "Setting coordinate format to %d.\n",
+ selection);
+ }
+
+ current.needtosave = TRUE;
+
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setfont_cb (GtkWidget *widget, gchar *font)
+{
+ gchar *tfont;
+
+ tfont = (gchar *) gtk_font_button_get_font_name
+ (GTK_FONT_BUTTON (widget));
+ g_strlcpy (font, tfont, 100);
+
+ if (mydebug > 10 )
+ fprintf (stderr, "setfont_cb: Setting font to: %s\n", font);
+
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setfriendmaxsec_cb (GtkWidget *spin, GtkWidget *combobox)
+{
+ gdouble value;
+ gint unit;
+
+ value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (spin));
+ unit = gtk_combo_box_get_active (GTK_COMBO_BOX (combobox));
+
+ switch (unit)
+ {
+ case 0: /* days */
+ local_config.friends_maxsecs = value * 86400;
+ break;
+ case 1: /* hours */
+ local_config.friends_maxsecs = value * 3600;
+ break;
+ case 2: /* minutes */
+ local_config.friends_maxsecs = value * 60;
+ break;
+ }
+
+ if (mydebug > 10)
+ fprintf (stderr,
+ "Setting max. age for friends data to %ld seconds.\n",
+ local_config.friends_maxsecs);
+
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setfriendmaxsecunit_cb (GtkWidget *combobox, GtkWidget *spin)
+{
+ return setfriendmaxsec_cb (spin, combobox);
+}
+
+/* ************************************************************************* */
+static gint
+setfriendname_cb (GtkWidget *widget)
+{
+ gchar *name;
+
+ if (friendsnamelock)
+ {
+ return TRUE;
+ }
+
+ name = (gchar *) gtk_entry_get_text (GTK_ENTRY (widget));
+ g_strlcpy (local_config.friends_name, name,
+ sizeof (local_config.friends_name));
+
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setfriendsrv_cb (GtkWidget *widget)
+{
+ gchar *srv;
+
+ srv = (gchar *) gtk_entry_get_text (GTK_ENTRY (widget));
+ g_strlcpy (local_config.friends_serverfqn, srv,
+ sizeof (local_config.friends_serverfqn));
+
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setfriendsrvip_cb (GtkWidget *widget)
+{
+ gchar *srvip;
+
+ if (friendsiplock)
+ {
+ return TRUE;
+ }
+
+ srvip = (gchar *) gtk_entry_get_text (GTK_ENTRY (widget));
+ g_strlcpy (local_config.friends_serverip, srvip,
+ sizeof (local_config.friends_serverip));
+
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setfriendsrvip_lookup_cb (GtkWidget *entry)
+{
+ struct hostent *hent = NULL;
+
+ char *quad;
+ struct in_addr adr;
+
+ hent = gethostbyname (local_config.friends_serverfqn);
+ if ((NULL != hent) && (AF_INET == hent->h_addrtype))
+ {
+ bcopy (hent->h_addr, &adr.s_addr, hent->h_length);
+ quad = inet_ntoa (adr);
+ g_strlcpy (local_config.friends_serverip, quad,
+ sizeof (local_config.friends_serverip));
+ }
+ else
+ {
+ g_strlcpy (local_config.friends_serverip, "0.0.0.0",
+ sizeof (local_config.friends_serverip));
+ }
+
+ friendsiplock = TRUE;
+ gtk_entry_set_text (GTK_ENTRY (entry), local_config.friends_serverip);
+ friendsiplock = FALSE;
+
+ if (mydebug > 10)
+ {
+ fprintf (stderr, "\nSetting friends server ip to %s\n",
+ local_config.friends_serverip);
+ }
+
+ return FALSE;
+}
+
+/* ************************************************************************* */
+static gint
+setpoisearch_cb (GtkWidget *widget, gint value)
+{
+ switch (value)
+ {
+ case 1: /* set radius preference */
+ local_config.poi_searchradius = g_strtod (
+ gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
+ break;
+ case 2: /* set results limit */
+ local_config.poi_results_max =
+ atoi (gtk_entry_get_text (GTK_ENTRY (widget)));
+ if (local_config.poi_results_max < 1)
+ local_config.poi_results_max = 1;
+ break;
+ default:
+ return FALSE;
+ }
+
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setshowfriends_cb (GtkWidget *entry)
+{
+ if (strlen (local_config.friends_name) == 0)
+ {
+ g_strlcpy (local_config.friends_name, _("EnterYourName"),
+ sizeof (local_config.friends_name));
+ friendsnamelock = TRUE;
+ gtk_entry_set_text (GTK_ENTRY (entry),
+ local_config.friends_name);
+ friendsnamelock = FALSE;
+ }
+
+ if (0 == strcmp (local_config.friends_name, _("EnterYourName")))
+ {
+ popup_warning (GTK_WINDOW (settings_window),
+ _("You should change your name in the first field!"));
+ return TRUE;
+ }
+
+ local_config.showfriends = !local_config.showfriends;
+
+ if (local_config.showfriends)
+ {
+ gtk_widget_show_all (frame_statusfriends);
+ gtk_widget_set_sensitive (menuitem_sendmsg, TRUE);
+ }
+ else
+ {
+ gtk_widget_hide_all (frame_statusfriends);
+ gtk_widget_set_sensitive (menuitem_sendmsg, FALSE);
+ }
+
+ if (mydebug >10)
+ {
+ fprintf (stderr, "Setting friend display to %d.\n",
+ local_config.showfriends);
+ }
+
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+settogglevalue_cb (GtkWidget *widget, gint *item)
+{
+ *item = !*item;
+
+ if (mydebug >10)
+ {
+ fprintf (stderr, "Setting config value to %d.\n",
+ *item);
+ }
+
+ current.needtosave = TRUE;
+
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setmapdir_cb (GtkWidget *widget)
+{
+ gchar *tdir;
+
+ tdir = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
+
+ if (tdir && strcmp (local_config.dir_maps, tdir) != 0)
+ {
+ g_strlcpy (local_config.dir_maps, tdir,
+ sizeof (local_config.dir_maps));
+ //if (mydebug >3)
+ fprintf (stderr, "setting maps dir to: %s\n", tdir);
+ needreloadmapconfig = TRUE;
+ current.needtosave = TRUE;
+ gtk_timeout_add (2000, (GtkFunction) loadmapconfig, 0);
+ }
+ g_free (tdir);
+
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setmaxcpuload_cb (GtkWidget *widget)
+{
+ local_config.maxcpuload =
+ gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
+
+ if (local_config.maxcpuload == 0)
+ local_config.maxcpuload = 40;
+
+ if (mydebug >10)
+ fprintf (stderr, "Setting max. CPU-Load to %d %%.\n",
+ local_config.maxcpuload);
+
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setnightmode_cb (GtkWidget *widget, guint value)
+{
+ switch (value)
+ {
+ case NIGHT_OFF:
+ switch_nightmode (FALSE);
+ break;
+ case NIGHT_ON:
+ switch_nightmode (TRUE);
+ break;
+ case NIGHT_AUTO:
+ if (isnight)
+ switch_nightmode (TRUE);
+ else
+ switch_nightmode (FALSE);
+ break;
+ default:
+ return FALSE;
+ }
+
+ local_config.nightmode = value;
+
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setpoitheme_cb (GtkWidget *combo)
+{
+ gchar *theme;
+
+ theme = gtk_combo_box_get_active_text(GTK_COMBO_BOX(combo));
+ g_strlcpy (local_config.icon_theme, theme,
+ sizeof (local_config.icon_theme));
+
+ get_poitype_tree ();
+ init_poi_type_filter();
+
+ if ( mydebug > 1 )
+ {
+ fprintf (stderr, "POI Theme changed to: %s\n", theme);
+ }
+
+ g_free (theme);
+
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setposmarker_cb (GtkWidget *widget)
+{
+ gint selection;
+
+ selection = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
+
+ if (selection != -1)
+ local_config.posmarker = selection;
+
+ if (mydebug >10)
+ fprintf (stderr, "Setting posmarker style to %d.\n",
+ local_config.posmarker);
+
+ current.needtosave = TRUE;
+
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setsimmode_cb (GtkWidget *widget, guint value)
+{
+ local_config.simmode = value;
+ if (value == SIM_AUTO)
+ {
+ if (current.gpsfix < 2)
+ current.simmode = TRUE;
+ else
+ current.simmode = FALSE;
+ }
+ else
+ {
+ current.simmode = value;
+ }
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+settravelmode_cb (GtkWidget *widget)
+{
+ gint selection;
+
+ selection = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
+
+ if (selection != -1)
+ local_config.travelmode = selection;
+
+ if (mydebug >10)
+ fprintf (stderr, "Setting travelmode to %d.\n",
+ local_config.travelmode);
+
+ current.needtosave = TRUE;
+
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setwpfile_cb (GtkWidget *widget)
+{
+ gchar *tfile;
+
+ tfile = gtk_file_chooser_get_filename
+ (GTK_FILE_CHOOSER (widget));
+ if (tfile && strcmp (local_config.wp_file, tfile) != 0)
+ {
+ g_strlcpy (local_config.wp_file, tfile,
+ sizeof (local_config.wp_file));
+ if (mydebug >3)
+ fprintf (stderr, "setting wp_file to: %s\n",
+ tfile);
+ loadwaypoints ();
+ }
+ g_free (tfile);
+
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+/* ************************************************************************* */
+static gint
+setwpfilequick_cb (GtkWidget *widget, guint datum)
+{
+ gchar *selected;
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
+ {
+ selected = g_strconcat (local_config.dir_home,
+ (names + datum)->n, NULL);
+ if (strcmp (local_config.wp_file, selected))
+ {
+ g_strlcpy (local_config.wp_file, selected,
+ sizeof (local_config.wp_file));
+ if (mydebug > 3)
+ fprintf (stderr, "active wp_file: %s\n",
+ local_config.wp_file);
+ loadwaypoints ();
+ iszoomed = FALSE;
+ }
+ g_free (selected);
+ }
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
+
+/* ************************************************************************* */
+static void
+settings_close_cb (GtkWidget *window)
+{
+ gtk_widget_destroy (window);
+}
+
+
+/* ************************************************************************* */
+static void
+toggle_poitype
+ (GtkCellRendererToggle *renderer, gchar *path_str, gpointer data)
+{
+ GtkTreeIter iter;
+ GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
+ gboolean value;
+
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (poi_types_tree), &iter, path);
+ gtk_tree_model_get (GTK_TREE_MODEL (poi_types_tree), &iter,
+ POITYPE_SELECT, &value, -1);
+
+ value = !value;
+
+ gtk_tree_store_set (poi_types_tree, &iter,
+ POITYPE_SELECT, value, -1);
+
+ update_poi_type_filter ();
+
+ gtk_tree_path_free (path);
+}
+
+
+/* *************************************************************************
+ * SETTINGS WINDOW
+ * ************************************************************************* */
+
+/* ************************************************************************* */
+static void
+settings_general (GtkWidget *notebook)
+{
+ GtkWidget *dist_label, *dist_combo;
+ GtkWidget *alt_label, *alt_combo;
+ GtkWidget *coord_label, *coord_combo;
+ GtkWidget *simulation_lb;
+ GtkWidget *simmode_auto_rb, *simmode_on_rb, *simmode_off_rb;
+ GtkWidget *simmode_table;
+ GtkWidget *maxcpu_label, *maxcpu_spin;
+ GtkTooltips *general_tooltips;
+ GtkWidget *general_vbox;
+ GtkWidget *general_label;
+ GtkWidget *units_table, *misc_table;
+ GtkWidget *units_frame, *misc_frame;
+ GtkWidget *units_fr_lb, *misc_fr_lb;
+ GtkWidget *mapdir_label, *mapdir_bt;
+ GtkWidget *map_table, *map_frame, *map_fr_lb;
+
+ general_tooltips = gtk_tooltips_new ();
+
+ /* distance format */
+ {
+ dist_label = gtk_label_new (_("Distance"));
+ dist_combo = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (dist_combo), "stat. miles");
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (dist_combo), "kilometers");
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (dist_combo), "naut. miles");
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX (dist_combo), local_config.distmode);
+ gtk_tooltips_set_tip (general_tooltips, dist_label,
+ _("Choose here the unit for the display of distances."), NULL);
+ g_signal_connect (dist_combo, "changed",
+ GTK_SIGNAL_FUNC (setdistmode_cb), 0);
+ }
+
+ /* altitude format */
+ {
+ alt_label = gtk_label_new (_("Altitude"));
+ alt_combo = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (alt_combo), "feet");
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (alt_combo), "meters");
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (alt_combo), "yards");
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX (alt_combo), local_config.altmode);
+ gtk_tooltips_set_tip (general_tooltips, alt_label,
+ _("Choose here the unit for the display of altitudes."), NULL);
+ g_signal_connect (alt_combo, "changed",
+ GTK_SIGNAL_FUNC (setaltmode_cb), 0);
+ }
+
+ /* coordinate format */
+ {
+ coord_label = gtk_label_new (_("Coordinates"));
+ coord_combo = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (coord_combo), "DD.ddddd");
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (coord_combo), "DD MM SS.ss");
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (coord_combo), "DD MM.mmm");
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX (coord_combo), local_config.coordmode);
+ gtk_tooltips_set_tip (general_tooltips, coord_label,
+ _("Choose here the format for the coordinates display."), NULL);
+ g_signal_connect (coord_combo, "changed",
+ GTK_SIGNAL_FUNC (setcoordmode_cb), 0);
+ }
+
+ /* units table */
+ {
+ units_table = gtk_table_new (3, 2, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (units_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (units_table), 5);
+ gtk_table_attach (GTK_TABLE (units_table),
+ coord_label, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (units_table),
+ coord_combo, 1, 2, 0, 1);
+ gtk_table_attach (GTK_TABLE (units_table),
+ dist_label, 0, 1, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (units_table),
+ dist_combo, 1, 2, 1, 2);
+ gtk_table_attach (GTK_TABLE (units_table),
+ alt_label, 0, 1, 2, 3, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (units_table),
+ alt_combo, 1, 2, 2, 3);
+ }
+
+ /* misc settings */
+ {
+ simulation_lb = gtk_label_new (_("Simulation mode"));
+ simmode_auto_rb = gtk_radio_button_new_with_label
+ (NULL, _("Automatic"));
+ g_signal_connect (simmode_auto_rb, "toggled",
+ GTK_SIGNAL_FUNC (setsimmode_cb), (gpointer) SIM_AUTO);
+ simmode_on_rb = gtk_radio_button_new_with_label_from_widget
+ (GTK_RADIO_BUTTON (simmode_auto_rb), _("On"));
+ g_signal_connect (simmode_on_rb, "toggled",
+ GTK_SIGNAL_FUNC (setsimmode_cb), (gpointer) SIM_ON);
+ simmode_off_rb = gtk_radio_button_new_with_label_from_widget
+ (GTK_RADIO_BUTTON (simmode_auto_rb), _("Off"));
+ g_signal_connect (simmode_off_rb, "toggled",
+ GTK_SIGNAL_FUNC (setsimmode_cb), (gpointer) SIM_OFF);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (general_tooltips), simmode_auto_rb,
+ _("If activated, the position pointer moves towards "
+ "the selected target simulating a moving vehicle, when no "
+ "GPS is available."), NULL);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (general_tooltips), simmode_on_rb,
+ _("If activated, the position pointer moves towards "
+ "the selected target simulating a moving vehicle always."),
+ NULL);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (general_tooltips), simmode_off_rb,
+ _("Switches simulation mode off"), NULL);
+ switch (local_config.simmode)
+ {
+ case SIM_OFF:
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (simmode_off_rb), TRUE);
+ break;
+ case SIM_ON:
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (simmode_on_rb), TRUE);
+ break;
+ case SIM_AUTO:
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (simmode_auto_rb), TRUE);
+ break;
+ }
+
+ simmode_table = gtk_table_new (1, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (simmode_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (simmode_table), 5);
+ gtk_table_attach_defaults (GTK_TABLE (simmode_table),
+ simmode_on_rb, 0, 1, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (simmode_table),
+ simmode_off_rb, 1, 2, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (simmode_table),
+ simmode_auto_rb, 2, 3, 0, 1);
+
+ maxcpu_label = gtk_label_new (_("Maximum CPU load (in %)"));
+ maxcpu_spin = gtk_spin_button_new_with_range (0, 95, 5);
+ gtk_spin_button_set_value
+ (GTK_SPIN_BUTTON (maxcpu_spin),
+ (gdouble) local_config.maxcpuload);
+ gtk_tooltips_set_tip (general_tooltips, maxcpu_spin,
+ _("Select the approx. maximum CPU load.\nUse 20-30% on "
+ "notebooks while on battery to save power. "
+ "This effects the refresh rate of the map screen."), NULL);
+ gtk_signal_connect (GTK_OBJECT (maxcpu_spin), "changed",
+ GTK_SIGNAL_FUNC (setmaxcpuload_cb), NULL);
+ }
+
+ /* misc table */
+ {
+ misc_table = gtk_table_new (4, 2, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (misc_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (misc_table), 5);
+ gtk_table_attach (GTK_TABLE (misc_table),
+ simulation_lb, 0, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (misc_table),
+ simmode_table, 0, 2, 1, 2);
+ gtk_table_attach (GTK_TABLE (misc_table),
+ maxcpu_label, 0, 1, 2, 3, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (misc_table),
+ maxcpu_spin, 1, 2, 2, 3);
+ }
+
+ /* map settings */
+ {
+ mapdir_label = gtk_label_new (_("Maps directory"));
+ mapdir_bt = gtk_file_chooser_button_new (_("Select Maps Directory"),
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
+ gtk_file_chooser_set_current_folder
+ (GTK_FILE_CHOOSER (mapdir_bt), local_config.dir_maps);
+ gtk_file_chooser_set_show_hidden (GTK_FILE_CHOOSER (mapdir_bt), TRUE);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (general_tooltips), mapdir_bt,
+ _("Path to your map files. In the specified directory "
+ "also the index file map_koord.txt must be present."), NULL);
+ g_signal_connect (mapdir_bt, "selection-changed",
+ GTK_SIGNAL_FUNC (setmapdir_cb), NULL);
+ }
+
+ /* map table */
+ {
+ map_table = gtk_table_new (2, 2, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (map_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (map_table), 5);
+ gtk_table_attach (GTK_TABLE (map_table),
+ mapdir_label, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (map_table),
+ mapdir_bt, 1, 2, 0, 1);
+ }
+
+ general_vbox = gtk_vbox_new (FALSE, 2);
+
+ units_frame = gtk_frame_new (NULL);
+ units_fr_lb = gtk_label_new (NULL);
+ gtk_label_set_markup (GTK_LABEL (units_fr_lb), _("<b>Units</b>"));
+ gtk_frame_set_label_widget (GTK_FRAME (units_frame), units_fr_lb);
+ gtk_frame_set_shadow_type (GTK_FRAME (units_frame), GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (units_frame), units_table);
+
+ misc_frame = gtk_frame_new (NULL);
+ misc_fr_lb = gtk_label_new (NULL);
+ gtk_label_set_markup
+ (GTK_LABEL (misc_fr_lb), _("<b>Miscellaneous</b>"));
+ gtk_frame_set_label_widget (GTK_FRAME (misc_frame), misc_fr_lb);
+ gtk_frame_set_shadow_type (GTK_FRAME (misc_frame), GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (misc_frame), misc_table);
+
+ map_frame = gtk_frame_new (NULL);
+ map_fr_lb = gtk_label_new (NULL);
+ gtk_label_set_markup
+ (GTK_LABEL (map_fr_lb), _("<b>Map Settings</b>"));
+ gtk_frame_set_label_widget (GTK_FRAME (map_frame), map_fr_lb);
+ gtk_frame_set_shadow_type (GTK_FRAME (map_frame), GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (map_frame), map_table);
+
+ gtk_box_pack_start (GTK_BOX (general_vbox),
+ units_frame, FALSE, FALSE, 2);
+ gtk_box_pack_start (GTK_BOX (general_vbox),
+ map_frame, FALSE, FALSE, 2);
+ gtk_box_pack_start (GTK_BOX (general_vbox),
+ misc_frame, FALSE, FALSE, 2);
+
+ general_label = gtk_label_new (_("General"));
+ gtk_notebook_append_page
+ (GTK_NOTEBOOK (notebook), general_vbox, general_label);
+}
+
+/* ************************************************************************* */
+static void
+settings_gui (GtkWidget *notebook)
+{
+ GtkWidget *gui_vbox, *gui_label;
+ GtkWidget *gui_map_frame, *gui_map_fr_lb;
+ GtkWidget *gui_misc_frame, *gui_misc_fr_lb;
+ GtkWidget *gui_night_frame, *gui_night_fr_lb;
+ GtkWidget *gui_map_table, *gui_misc_table;
+ GtkWidget *gui_trackcol_bt, *gui_routecol_bt;
+ GtkWidget *gui_friendscol_bt, *gui_friendscol_lb;
+ GtkWidget *gui_wpcol_bt, *gui_wpcol_lb;
+ GtkWidget *gui_trackcol_lb, *gui_routecol_lb;
+
+ GtkWidget *gui_bigcol_lb, *gui_bigcol_bt;
+ GtkWidget *gui_bigfont_bt, *gui_friendsfont_bt;
+ GtkWidget *gui_shadow_bt, *gui_nightauto_rb;
+ GtkWidget *gui_scaleshow_bt, *gui_zoomshow_bt;
+ GtkWidget *gui_nighton_rb, *gui_nightoff_rb;
+ GtkWidget *gui_night_table, *gui_wpfont_bt;
+ GtkWidget *gui_trackstyle_combo, *gui_routestyle_combo;
+ GtkWidget *gui_marker_lb, *gui_marker_bt;
+
+ GtkWidget *gui_gridshow_bt;
+ GtkTooltips *gui_tooltips;
+
+ gui_vbox = gtk_vbox_new (FALSE, 2);
+ gui_tooltips = gtk_tooltips_new ();
+
+ /* gui features settings */
+ {
+ gui_gridshow_bt = gtk_check_button_new_with_label (_("Show grid"));
+ gtk_tooltips_set_tip (gui_tooltips, gui_gridshow_bt,
+ _("This will show a grid over the map"), NULL);
+ if (local_config.showgrid)
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (gui_gridshow_bt), TRUE);
+ }
+ else
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (gui_gridshow_bt), FALSE);
+ }
+ g_signal_connect (GTK_OBJECT (gui_gridshow_bt), "clicked",
+ GTK_SIGNAL_FUNC (settogglevalue_cb),
+ &local_config.showgrid);
+
+ gui_shadow_bt = gtk_check_button_new_with_label (_("Show Shadows"));
+ gtk_tooltips_set_tip (gui_tooltips, gui_shadow_bt,
+ _("Switches shadows on map on or off"), NULL);
+ if (local_config.showshadow)
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (gui_shadow_bt), TRUE);
+ }
+ else
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (gui_shadow_bt), FALSE);
+ }
+ g_signal_connect (GTK_OBJECT (gui_shadow_bt), "clicked",
+ GTK_SIGNAL_FUNC (settogglevalue_cb),
+ &local_config.showshadow);
+
+ gui_zoomshow_bt = gtk_check_button_new_with_label (_("Show zoom level"));
+ gtk_tooltips_set_tip (gui_tooltips, gui_zoomshow_bt,
+ _("This will show the current zoom level of the map"), NULL);
+ if (local_config.showzoom)
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (gui_zoomshow_bt), TRUE);
+ }
+ else
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (gui_zoomshow_bt), FALSE);
+ }
+ g_signal_connect (GTK_OBJECT (gui_zoomshow_bt), "clicked",
+ GTK_SIGNAL_FUNC (settogglevalue_cb),
+ &local_config.showzoom);
+
+ gui_scaleshow_bt = gtk_check_button_new_with_label (_("Show scalebar"));
+ gtk_tooltips_set_tip (gui_tooltips, gui_scaleshow_bt,
+ _("This will show the scalebar in the map"), NULL);
+ if (local_config.showscalebar)
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (gui_scaleshow_bt), TRUE);
+ }
+ else
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (gui_scaleshow_bt), FALSE);
+ }
+ g_signal_connect (GTK_OBJECT (gui_scaleshow_bt), "clicked",
+ GTK_SIGNAL_FUNC (settogglevalue_cb),
+ &local_config.showscalebar);
+
+ gui_marker_lb = gtk_label_new (_("Position Marker"));
+ gui_marker_bt = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (gui_marker_bt), "Blob");
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (gui_marker_bt), "Arrow");
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (gui_marker_bt), "T-Style");
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX (gui_marker_bt), local_config.posmarker);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (gui_tooltips), gui_marker_bt,
+ _("Choose the apperance of your position marker."), NULL);
+ g_signal_connect (gui_marker_bt, "changed",
+ GTK_SIGNAL_FUNC (setposmarker_cb), NULL);
+
+ gui_misc_table = gtk_table_new (3, 4, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (gui_misc_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (gui_misc_table), 5);
+ gtk_table_attach_defaults (GTK_TABLE (gui_misc_table),
+ gui_gridshow_bt, 0, 1, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (gui_misc_table),
+ gui_shadow_bt, 2, 3, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (gui_misc_table),
+ gui_zoomshow_bt, 0, 1, 1, 2);
+ gtk_table_attach_defaults (GTK_TABLE (gui_misc_table),
+ gui_scaleshow_bt, 2, 3, 1, 2);
+ gtk_table_attach_defaults (GTK_TABLE (gui_misc_table),
+ gui_marker_lb, 0, 1, 2, 3);
+ gtk_table_attach_defaults (GTK_TABLE (gui_misc_table),
+ gui_marker_bt, 2, 3, 2, 3);
+ }
+
+ /* gui nightmode settings */
+ {
+ gui_nightauto_rb = gtk_radio_button_new_with_label
+ (NULL, _("Automatic"));
+ g_signal_connect (gui_nightauto_rb, "toggled",
+ GTK_SIGNAL_FUNC (setnightmode_cb), (gpointer) NIGHT_AUTO);
+ gui_nighton_rb = gtk_radio_button_new_with_label_from_widget
+ (GTK_RADIO_BUTTON (gui_nightauto_rb), _("On"));
+ g_signal_connect (gui_nighton_rb, "toggled",
+ GTK_SIGNAL_FUNC (setnightmode_cb), (gpointer) NIGHT_ON);
+ gui_nightoff_rb = gtk_radio_button_new_with_label_from_widget
+ (GTK_RADIO_BUTTON (gui_nightauto_rb), _("Off"));
+ g_signal_connect (gui_nightoff_rb, "toggled",
+ GTK_SIGNAL_FUNC (setnightmode_cb), (gpointer) NIGHT_OFF);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (gui_tooltips), gui_nightauto_rb,
+ _("Switches automagically to night mode if it is dark "
+ "outside. Press 'N' key to turn off nightmode."), NULL);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (gui_tooltips), gui_nighton_rb,
+ _("Switches night mode on. Press 'N' key to turn off "
+ "nightmode."), NULL);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (gui_tooltips), gui_nightoff_rb,
+ _("Switches night mode off"), NULL);
+ switch (local_config.nightmode)
+ {
+ case NIGHT_OFF:
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (gui_nightoff_rb), TRUE);
+ break;
+ case NIGHT_ON:
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (gui_nighton_rb), TRUE);
+ break;
+ case NIGHT_AUTO:
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (gui_nightauto_rb), TRUE);
+ break;
+ }
+
+ gui_night_table = gtk_table_new (1, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (gui_night_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (gui_night_table), 5);
+ gtk_table_attach_defaults (GTK_TABLE (gui_night_table),
+ gui_nighton_rb, 0, 1, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (gui_night_table),
+ gui_nightoff_rb, 1, 2, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (gui_night_table),
+ gui_nightauto_rb, 2, 3, 0, 1);
+ }
+
+ /* gui fonts/colors settings */
+ {
+ gui_trackcol_lb = gtk_label_new (_("Track"));
+ gui_trackcol_bt = gtk_color_button_new_with_color
+ (&colors.track);
+ gtk_color_button_set_title
+ (GTK_COLOR_BUTTON (gui_trackcol_bt),
+ _("Choose Track color"));
+ g_signal_connect (gui_trackcol_bt, "color-set",
+ GTK_SIGNAL_FUNC (setcolor_cb), &colors.track);
+ gtk_tooltips_set_tip (gui_tooltips, gui_trackcol_bt,
+ _("Set here the color of the drawn track"), NULL);
+ gui_trackstyle_combo = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (gui_trackstyle_combo), "line style");
+ gtk_tooltips_set_tip (gui_tooltips, gui_trackstyle_combo,
+ _("Set here the line style of the drawn track"), NULL);
+ // TODO: add 'change linestyle' functionality
+ // combobox is disabled until that is done
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX (gui_trackstyle_combo), 0);
+ gtk_widget_set_sensitive (gui_trackstyle_combo, FALSE);
+
+ /* Route line color & style */
+ gui_routecol_lb = gtk_label_new (_("Route"));
+ gui_routecol_bt = gtk_color_button_new_with_color
+ (&colors.route);
+ gtk_color_button_set_title
+ (GTK_COLOR_BUTTON (gui_routecol_bt),
+ _("Choose Route color"));
+ g_signal_connect (gui_routecol_bt, "color-set",
+ GTK_SIGNAL_FUNC (setcolor_cb), &colors.route);
+ gtk_tooltips_set_tip (gui_tooltips, gui_routecol_bt,
+ _("Set here the color of the drawn route"), NULL);
+ gui_routestyle_combo = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (gui_routestyle_combo), "line style");
+ gtk_tooltips_set_tip (gui_tooltips, gui_routestyle_combo,
+ _("Set here the line style of the drawn route"), NULL);
+ // TODO: add 'change linestyle' functionality
+ // combobox is disabled until that is done
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX (gui_routestyle_combo), 0);
+ gtk_widget_set_sensitive (gui_routestyle_combo, FALSE);
+
+ /* Friends label color & font */
+ gui_friendscol_lb = gtk_label_new (_("Friends"));
+ gui_friendscol_bt = gtk_color_button_new_with_color
+ (&colors.friends);
+ gtk_color_button_set_title
+ (GTK_COLOR_BUTTON (gui_friendscol_bt),
+ _("Choose Friends color"));
+ g_signal_connect (gui_friendscol_bt, "color-set",
+ GTK_SIGNAL_FUNC (setcolor_cb), &colors.friends);
+ gtk_tooltips_set_tip (gui_tooltips, gui_friendscol_bt,
+ _("Set here the text color of the drawn friends"), NULL);
+ gui_friendsfont_bt = gtk_font_button_new_with_font
+ (local_config.font_friends);
+ gtk_font_button_set_title
+ (GTK_FONT_BUTTON (gui_friendsfont_bt),
+ _("Choose font for friends"));
+ gtk_font_button_set_use_font
+ (GTK_FONT_BUTTON (gui_friendsfont_bt), TRUE);
+ g_signal_connect (gui_friendsfont_bt, "font-set",
+ GTK_SIGNAL_FUNC (setfont_cb), local_config.font_friends);
+ gtk_tooltips_set_tip (gui_tooltips, gui_friendsfont_bt,
+ _("Set here the font of the drawn friends"), NULL);
+
+ /* Waypoints label color & font */
+ gui_wpcol_lb = gtk_label_new (_("Waypoints"));
+ gui_wpcol_bt = gtk_color_button_new_with_color
+ (&colors.wplabel);
+ gtk_color_button_set_title
+ (GTK_COLOR_BUTTON (gui_wpcol_bt),
+ _("Choose Waypoints label color"));
+ g_signal_connect (gui_wpcol_bt, "color-set",
+ GTK_SIGNAL_FUNC (setcolor_cb), &colors.wplabel);
+ gtk_tooltips_set_tip (gui_tooltips, gui_wpcol_bt,
+ _("Set here the text color of the waypoint labels"), NULL);
+ gui_wpfont_bt = gtk_font_button_new_with_font
+ (local_config.font_wplabel);
+ gtk_font_button_set_title
+ (GTK_FONT_BUTTON (gui_wpfont_bt),
+ _("Choose font for waypoint labels"));
+ gtk_font_button_set_use_font
+ (GTK_FONT_BUTTON (gui_wpfont_bt), TRUE);
+ g_signal_connect (gui_wpfont_bt, "font-set",
+ GTK_SIGNAL_FUNC (setfont_cb), local_config.font_wplabel);
+ gtk_tooltips_set_tip (gui_tooltips, gui_wpfont_bt,
+ _("Set here the font of waypoint labels"), NULL);
+
+ /* Big Display color & font */
+ gui_bigcol_lb = gtk_label_new (_("Dashboard"));
+ gui_bigcol_bt = gtk_color_button_new_with_color
+ (&colors.dashboard);
+ gtk_color_button_set_title
+ (GTK_COLOR_BUTTON (gui_bigcol_bt),
+ _("Choose color for dashboard"));
+ g_signal_connect (gui_bigcol_bt, "color-set",
+ GTK_SIGNAL_FUNC (setcolor_cb), &colors.dashboard);
+ gtk_tooltips_set_tip (gui_tooltips, gui_bigcol_bt,
+ _("Set here the color of the dashboard"), NULL);
+ gui_bigfont_bt = gtk_font_button_new_with_font
+ (local_config.font_dashboard);
+ gtk_font_button_set_title
+ (GTK_FONT_BUTTON (gui_bigfont_bt),
+ _("Choose font for dashboard"));
+ gtk_font_button_set_use_font
+ (GTK_FONT_BUTTON (gui_bigfont_bt), TRUE);
+ g_signal_connect (gui_bigfont_bt, "font-set",
+ GTK_SIGNAL_FUNC (setfont_cb), local_config.font_dashboard);
+ gtk_tooltips_set_tip (gui_tooltips, gui_bigfont_bt,
+ _("Set here the font of the dashboard"), NULL);
+
+ gui_map_table = gtk_table_new (5, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (gui_map_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (gui_map_table), 5);
+ gtk_table_attach (GTK_TABLE (gui_map_table),
+ gui_trackcol_lb, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach (GTK_TABLE (gui_map_table),
+ gui_trackcol_bt, 1, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (gui_map_table),
+ gui_trackstyle_combo, 2, 3, 0, 1);
+ gtk_table_attach (GTK_TABLE (gui_map_table),
+ gui_routecol_lb, 0, 1, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach (GTK_TABLE (gui_map_table),
+ gui_routecol_bt, 1, 2, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (gui_map_table),
+ gui_routestyle_combo, 2, 3, 1, 2);
+ gtk_table_attach (GTK_TABLE (gui_map_table),
+ gui_friendscol_lb, 0, 1, 2, 3, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach (GTK_TABLE (gui_map_table),
+ gui_friendscol_bt, 1, 2, 2, 3, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (gui_map_table),
+ gui_friendsfont_bt, 2, 3, 2, 3);
+ gtk_table_attach (GTK_TABLE (gui_map_table),
+ gui_wpcol_lb, 0, 1, 3, 4, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach (GTK_TABLE (gui_map_table),
+ gui_wpcol_bt, 1, 2, 3, 4, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (gui_map_table),
+ gui_wpfont_bt, 2, 3, 3, 4);
+ gtk_table_attach (GTK_TABLE (gui_map_table),
+ gui_bigcol_lb, 0, 1, 4, 5, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach (GTK_TABLE (gui_map_table),
+ gui_bigcol_bt, 1, 2, 4, 5, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (gui_map_table),
+ gui_bigfont_bt, 2, 3, 4, 5);
+ }
+
+ /* gui fonts/colors/styles frame */
+ gui_map_frame = gtk_frame_new (NULL);
+ gui_map_fr_lb = gtk_label_new (NULL);
+ gtk_label_set_markup
+ (GTK_LABEL (gui_map_fr_lb), _("<b>Fonts, Colors, Styles</b>"));
+ gtk_frame_set_label_widget
+ (GTK_FRAME (gui_map_frame), gui_map_fr_lb);
+ gtk_frame_set_shadow_type
+ (GTK_FRAME (gui_map_frame), GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (gui_map_frame), gui_map_table);
+
+ /* gui nightmode frame */
+ gui_night_frame = gtk_frame_new (NULL);
+ gui_night_fr_lb = gtk_label_new (NULL);
+ gtk_label_set_markup
+ (GTK_LABEL (gui_night_fr_lb), _("<b>Nightmode</b>"));
+ gtk_frame_set_label_widget
+ (GTK_FRAME (gui_night_frame), gui_night_fr_lb);
+ gtk_frame_set_shadow_type
+ (GTK_FRAME (gui_night_frame), GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (gui_night_frame), gui_night_table);
+
+ /* gui features frame */
+ gui_misc_frame = gtk_frame_new (NULL);
+ gui_misc_fr_lb = gtk_label_new (NULL);
+ gtk_label_set_markup
+ (GTK_LABEL (gui_misc_fr_lb), _("<b>Map Features</b>"));
+ gtk_frame_set_label_widget
+ (GTK_FRAME (gui_misc_frame), gui_misc_fr_lb);
+ gtk_frame_set_shadow_type
+ (GTK_FRAME (gui_misc_frame), GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (gui_misc_frame), gui_misc_table);
+
+ gtk_box_pack_start
+ (GTK_BOX (gui_vbox), gui_misc_frame, FALSE, FALSE, 2);
+ gtk_box_pack_start
+ (GTK_BOX (gui_vbox), gui_night_frame, FALSE, FALSE, 2);
+ gtk_box_pack_start
+ (GTK_BOX (gui_vbox), gui_map_frame, FALSE, FALSE, 2);
+
+ gui_label = gtk_label_new (_("GUI"));
+ gtk_notebook_append_page
+ (GTK_NOTEBOOK (notebook), gui_vbox, gui_label);
+}
+
+/* ************************************************************************* */
+static void
+settings_nav (GtkWidget *notebook)
+{
+ GtkWidget *nav_vbox, *nav_label;
+ GtkWidget *travel_label, *travel_combo;
+ GtkWidget *nav_table, *speech_table;
+ GtkWidget *nav_frame, *speech_frame;
+ GtkWidget *nav_fr_lb, *speech_fr_lb;
+ GtkWidget *sounddir_bt, *sounddist_bt;
+ GtkWidget *soundspeed_bt, *soundgps_bt;
+ GtkTooltips *nav_tooltips;
+
+ gchar travelmodes[TRAVEL_N_MODES][20];
+ gint i;
+
+ nav_tooltips = gtk_tooltips_new ();
+ nav_vbox = gtk_vbox_new (FALSE, 2);
+
+ /* travelmode */
+ {
+ travel_label = gtk_label_new (_("Travel Mode"));
+ travel_combo = gtk_combo_box_new_text ();
+ g_strlcpy (travelmodes[TRAVEL_CAR], _("Car"),
+ sizeof(travelmodes[TRAVEL_CAR]));
+ g_strlcpy (travelmodes[TRAVEL_BIKE], _("Bike"),
+ sizeof(travelmodes[TRAVEL_BIKE]));
+ g_strlcpy (travelmodes[TRAVEL_WALK], _("Walk"),
+ sizeof(travelmodes[TRAVEL_WALK]));
+ g_strlcpy (travelmodes[TRAVEL_BOAT], _("Boat"),
+ sizeof(travelmodes[TRAVEL_BOAT]));
+ g_strlcpy (travelmodes[TRAVEL_AIRPLANE], _("Airplane"),
+ sizeof(travelmodes[TRAVEL_AIRPLANE]));
+ for (i=0; i<TRAVEL_N_MODES; i++)
+ {
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (travel_combo), travelmodes[i]);
+ }
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX (travel_combo), local_config.travelmode);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (nav_tooltips), travel_combo,
+ _("Choose your travel mode. This is used to determine "
+ "which icon should be used to display your position."), NULL);
+ g_signal_connect (travel_combo, "changed",
+ GTK_SIGNAL_FUNC (settravelmode_cb), NULL);
+ }
+
+ nav_table = gtk_table_new (3, 2, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (nav_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (nav_table), 5);
+ gtk_table_attach (GTK_TABLE (nav_table),
+ travel_label, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (nav_table),
+ travel_combo, 1, 2, 0, 1);
+
+ speech_table = gtk_table_new (2, 2, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (speech_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (speech_table), 5);
+
+ /* speech output settings
+ * set following sounds
+ * sound_direction ... say direction to target
+ * sound_distance ... say distance to target
+ * sound_speed ... say your current speed
+ * sound_gps ... say GPS status
+ */
+ {
+ sounddir_bt = gtk_check_button_new_with_label (_("Direction"));
+ sounddist_bt = gtk_check_button_new_with_label (_("Distance"));
+ soundspeed_bt = gtk_check_button_new_with_label (_("Speed"));
+ soundgps_bt = gtk_check_button_new_with_label (_("GPS Status"));
+ if (local_config.sound_direction)
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (sounddir_bt), TRUE);
+ }
+ if (local_config.sound_distance)
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (sounddist_bt), TRUE);
+ }
+ if (local_config.sound_speed)
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (soundspeed_bt), TRUE);
+ }
+ if (local_config.sound_gps)
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (soundgps_bt), TRUE);
+ }
+ g_signal_connect (sounddir_bt, "clicked",
+ GTK_SIGNAL_FUNC (settogglevalue_cb),
+ &local_config.sound_direction);
+ g_signal_connect (GTK_OBJECT (sounddist_bt), "clicked",
+ GTK_SIGNAL_FUNC (settogglevalue_cb),
+ &local_config.sound_distance);
+ g_signal_connect (GTK_OBJECT (soundspeed_bt), "clicked",
+ GTK_SIGNAL_FUNC (settogglevalue_cb),
+ &local_config.sound_speed);
+ g_signal_connect (GTK_OBJECT (soundgps_bt), "clicked",
+ GTK_SIGNAL_FUNC (settogglevalue_cb),
+ &local_config.sound_gps);
+ gtk_table_attach_defaults
+ (GTK_TABLE (speech_table), sounddir_bt, 0, 1, 0, 1);
+ gtk_table_attach_defaults
+ (GTK_TABLE (speech_table), sounddist_bt, 0, 1, 1, 2);
+ gtk_table_attach_defaults
+ (GTK_TABLE (speech_table), soundspeed_bt, 1, 2, 0, 1);
+ gtk_table_attach_defaults
+ (GTK_TABLE (speech_table), soundgps_bt, 1, 2, 1, 2);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (nav_tooltips), sounddir_bt,
+ _("Switch on for speech output of the direction to the "
+ "target"), NULL);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (nav_tooltips), sounddist_bt,
+ _("Switch on for speech output of the distance to the "
+ "target"), NULL);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (nav_tooltips), soundspeed_bt,
+ _("Switch on for speech output of your current speed"), NULL);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (nav_tooltips), soundgps_bt,
+ _("Switch on for speech output of the status of your "
+ "GPS signal"), NULL);
+ }
+
+ nav_frame = gtk_frame_new (NULL);
+ nav_fr_lb = gtk_label_new (NULL);
+ gtk_label_set_markup
+ (GTK_LABEL (nav_fr_lb), _("<b>Navigation Settings</b>"));
+ gtk_frame_set_label_widget (GTK_FRAME (nav_frame), nav_fr_lb);
+ gtk_frame_set_shadow_type (GTK_FRAME (nav_frame), GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (nav_frame), nav_table);
+
+ speech_frame = gtk_frame_new (NULL);
+ speech_fr_lb = gtk_label_new (NULL);
+ gtk_label_set_markup
+ (GTK_LABEL (speech_fr_lb), _("<b>Speech Output</b>"));
+ gtk_frame_set_label_widget (GTK_FRAME (speech_frame), speech_fr_lb);
+ gtk_frame_set_shadow_type (GTK_FRAME (speech_frame), GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (speech_frame), speech_table);
+
+ gtk_box_pack_start (GTK_BOX (nav_vbox), nav_frame, FALSE, FALSE, 2);
+ gtk_box_pack_start (GTK_BOX (nav_vbox), speech_frame, FALSE, FALSE, 2);
+
+ nav_label = gtk_label_new (_("Navigation"));
+ gtk_notebook_append_page
+ (GTK_NOTEBOOK (notebook), nav_vbox, nav_label);
+}
+
+/* ************************************************************************* */
+static void
+settings_poi (GtkWidget *notebook)
+{
+ GtkWidget *poi_vbox, *poi_label;
+ GtkTooltips * poi_tooltips;
+ GtkWidget *wp_frame, *wp_fr_lb, *wp_table;
+ GtkWidget *poisearch_frame, *poisearch_fr_lb, *poisearch_table;
+ GtkWidget *poidisplay_frame, *poidisplay_fr_lb, *poidisplay_table;
+ GtkWidget *wpfile_label, *wpfile_bt;
+ GtkWidget *poitheme_label, *poitheme_combo;
+ GtkWidget *poi_dist_label, *poi_dist_entry;
+ GtkWidget *poi_max_label, *poi_max_entry;
+ GtkWidget *poi_max2_label, *poi_dist2_label;
+ GtkWidget *poifilter_label;
+ GtkWidget *poi_labelshow_bt;
+ GtkWidget *scrolledwindow_poitypes;
+ GtkWidget *poitypes_treeview;
+ GtkCellRenderer *renderer_poitypes;
+ GtkTreeViewColumn *column_poitypes;
+ GtkTreeSelection *poitypes_select;
+
+ gchar text[50];
+
+ poi_tooltips = gtk_tooltips_new ();
+ poi_vbox = gtk_vbox_new (FALSE, 2);
+
+ /* Waypoints */
+ {
+ wpfile_label = gtk_label_new (_("Waypoints File"));
+ wpfile_bt = gtk_file_chooser_button_new
+ (_("Select Waypoints File"), GTK_FILE_CHOOSER_ACTION_OPEN);
+ if (!gtk_file_chooser_set_filename
+ (GTK_FILE_CHOOSER (wpfile_bt), local_config.wp_file))
+ {
+ gtk_file_chooser_set_current_folder
+ (GTK_FILE_CHOOSER (wpfile_bt), local_config.dir_home);
+ }
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (poi_tooltips), wpfile_bt,
+ _("Choose the waypoints file to use!\nCurrently only files in "
+ "GpsDrive's way.txt format are supported."), NULL);
+ g_signal_connect (wpfile_bt, "selection-changed",
+ GTK_SIGNAL_FUNC (setwpfile_cb), NULL);
+
+ wp_table = gtk_table_new (1, 2, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (wp_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (wp_table), 5);
+ gtk_table_attach (GTK_TABLE (wp_table),
+ wpfile_label, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (wp_table),
+ wpfile_bt, 1, 2, 0, 1);
+ }
+
+ /* POI Search settings */
+ {
+ poi_dist_label = gtk_label_new (_("Default search radius"));
+ poi_dist_entry = gtk_entry_new ();
+ gtk_entry_set_max_length (GTK_ENTRY (poi_dist_entry), 5);
+ g_snprintf (text, sizeof (text), "%0.1f",
+ local_config.poi_searchradius);
+ gtk_entry_set_text
+ (GTK_ENTRY (poi_dist_entry), text);
+ g_signal_connect (poi_dist_entry, "changed",
+ GTK_SIGNAL_FUNC (setpoisearch_cb), (gpointer) 1);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (poi_tooltips), poi_dist_entry,
+ _("Choose the default search range (in km) for the POI-Lookup"
+ " Window."), NULL);
+ poi_dist2_label = gtk_label_new (_("km"));
+
+ poi_max_label = gtk_label_new (_("Limit results to"));
+ poi_max_entry = gtk_entry_new ();
+ gtk_entry_set_max_length (GTK_ENTRY (poi_max_entry), 5);
+ g_snprintf (text, sizeof (text), "%0d", local_config.poi_results_max);
+ gtk_entry_set_text
+ (GTK_ENTRY (poi_max_entry), text);
+ g_signal_connect (poi_max_entry, "changed",
+ GTK_SIGNAL_FUNC (setpoisearch_cb), (gpointer) 2);
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (poi_tooltips), poi_max_entry,
+ _("Choose the limit for the amount of found entries displayed "
+ "in the POI-Lookup Window. Depending on your system a value "
+ "set too high may slow down your system."), NULL);
+ poi_max2_label = gtk_label_new (_("entries"));
+
+ poisearch_table = gtk_table_new (2, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (poisearch_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (poisearch_table), 5);
+ gtk_table_attach (GTK_TABLE (poisearch_table),
+ poi_dist_label, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach (GTK_TABLE (poisearch_table),
+ poi_dist_entry, 1, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach (GTK_TABLE (poisearch_table),
+ poi_dist2_label, 2, 3, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach (GTK_TABLE (poisearch_table),
+ poi_max_label, 0, 1, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach (GTK_TABLE (poisearch_table),
+ poi_max_entry, 1, 2, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach (GTK_TABLE (poisearch_table),
+ poi_max2_label, 2, 3, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ }
+
+ /* POI Display settings */
+ {
+ poi_labelshow_bt = gtk_check_button_new_with_label (_("Show POI Label"));
+ gtk_tooltips_set_tip (poi_tooltips, poi_labelshow_bt,
+ _("This will print the name next to the POI-Icon"), NULL);
+ if (local_config.showpoilabel)
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (poi_labelshow_bt), TRUE);
+ }
+ else
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (poi_labelshow_bt), FALSE);
+ }
+ g_signal_connect (GTK_OBJECT (poi_labelshow_bt), "clicked",
+ GTK_SIGNAL_FUNC (settogglevalue_cb),
+ &local_config.showpoilabel);
+
+ poitheme_label = gtk_label_new (_("POI-Theme"));
+ poitheme_combo = gtk_combo_box_new_text();
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX(poitheme_combo), "square.big");
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX(poitheme_combo), "square.small");
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX(poitheme_combo), "classic.big");
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX(poitheme_combo), "classic.small");
+ if (!strcmp (local_config.icon_theme, "square.big"))
+ {
+ gtk_combo_box_set_active( GTK_COMBO_BOX (poitheme_combo), 0 );
+ }
+ else if (!strcmp (local_config.icon_theme, "square.small"))
+ {
+ gtk_combo_box_set_active( GTK_COMBO_BOX (poitheme_combo), 1 );
+ }
+ else if (!strcmp (local_config.icon_theme, "classic.big"))
+ {
+ gtk_combo_box_set_active( GTK_COMBO_BOX (poitheme_combo), 2 );
+ }
+ else if (!strcmp (local_config.icon_theme, "classic.small"))
+ {
+ gtk_combo_box_set_active( GTK_COMBO_BOX (poitheme_combo), 3 );
+ }
+ g_signal_connect (poitheme_combo, "changed",
+ GTK_SIGNAL_FUNC (setpoitheme_cb), NULL);
+
+ poifilter_label = gtk_label_new (_("POI-Filter"));
+ scrolledwindow_poitypes = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW
+ (scrolledwindow_poitypes), GTK_SHADOW_IN);
+
+ poitypes_treeview = gtk_tree_view_new_with_model
+ (GTK_TREE_MODEL (poi_types_tree));
+ gtk_container_add (GTK_CONTAINER (scrolledwindow_poitypes),
+ poitypes_treeview);
+
+ renderer_poitypes = gtk_cell_renderer_toggle_new ();
+ column_poitypes = gtk_tree_view_column_new_with_attributes (NULL,
+ renderer_poitypes, "active", POITYPE_SELECT, NULL);
+ g_signal_connect (renderer_poitypes, "toggled",
+ G_CALLBACK (toggle_poitype), NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (poitypes_treeview),
+ column_poitypes);
+
+ renderer_poitypes = gtk_cell_renderer_pixbuf_new ();
+ column_poitypes = gtk_tree_view_column_new_with_attributes (NULL,
+ renderer_poitypes, "pixbuf", POITYPE_ICON, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (poitypes_treeview),
+ column_poitypes);
+
+ renderer_poitypes = gtk_cell_renderer_text_new ();
+ column_poitypes = gtk_tree_view_column_new_with_attributes (
+ NULL, renderer_poitypes,
+ "text", POITYPE_TITLE, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (poitypes_treeview),
+ column_poitypes);
+
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (poitypes_treeview),
+ FALSE);
+ gtk_tree_view_collapse_all (GTK_TREE_VIEW (poitypes_treeview));
+
+ /* disable drawing of tree expanders */
+ column_poitypes = gtk_tree_view_column_new ();
+ gtk_tree_view_append_column (GTK_TREE_VIEW (poitypes_treeview),
+ column_poitypes);
+ gtk_tree_view_set_expander_column
+ (GTK_TREE_VIEW (poitypes_treeview), column_poitypes);
+ gtk_tree_view_column_set_visible (column_poitypes, FALSE);
+
+ poitypes_select = gtk_tree_view_get_selection
+ (GTK_TREE_VIEW (poitypes_treeview));
+ gtk_tree_selection_set_mode (poitypes_select, GTK_SELECTION_SINGLE);
+
+ poidisplay_table = gtk_table_new (3, 2, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (poidisplay_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (poidisplay_table), 5);
+ gtk_table_attach (GTK_TABLE (poidisplay_table),
+ poi_labelshow_bt, 0, 2, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0 ,0);
+ gtk_table_attach (GTK_TABLE (poidisplay_table),
+ poitheme_label, 0, 1, 1, 2,
+ GTK_SHRINK, GTK_SHRINK, 0 ,0);
+ gtk_table_attach (GTK_TABLE (poidisplay_table),
+ poitheme_combo, 1, 2, 1, 2,
+ GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0 ,0);
+ gtk_table_attach (GTK_TABLE (poidisplay_table),
+ poifilter_label, 0, 1, 2, 3,
+ GTK_SHRINK, GTK_SHRINK, 0 ,0);
+ gtk_table_attach_defaults (GTK_TABLE (poidisplay_table),
+ scrolledwindow_poitypes, 1, 2, 2, 3); }
+
+
+ wp_frame = gtk_frame_new (NULL);
+ wp_fr_lb = gtk_label_new (NULL);
+ gtk_label_set_markup
+ (GTK_LABEL (wp_fr_lb), _("<b>Waypoints</b>"));
+ gtk_frame_set_label_widget (GTK_FRAME (wp_frame), wp_fr_lb);
+ gtk_frame_set_shadow_type (GTK_FRAME (wp_frame), GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (wp_frame), wp_table);
+
+ poisearch_frame = gtk_frame_new (NULL);
+ poisearch_fr_lb = gtk_label_new (NULL);
+ gtk_label_set_markup
+ (GTK_LABEL (poisearch_fr_lb), _("<b>POI Search Settings</b>"));
+ gtk_frame_set_label_widget (GTK_FRAME (poisearch_frame),
+ poisearch_fr_lb);
+ gtk_frame_set_shadow_type (GTK_FRAME (poisearch_frame),
+ GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (poisearch_frame), poisearch_table);
+
+ poidisplay_frame = gtk_frame_new (NULL);
+ poidisplay_fr_lb = gtk_label_new (NULL);
+ gtk_label_set_markup
+ (GTK_LABEL (poidisplay_fr_lb), _("<b>POI Display</b>"));
+ gtk_frame_set_label_widget (GTK_FRAME (poidisplay_frame),
+ poidisplay_fr_lb);
+ gtk_frame_set_shadow_type (GTK_FRAME (poidisplay_frame),
+ GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (poidisplay_frame), poidisplay_table);
+
+
+ gtk_box_pack_start
+ (GTK_BOX (poi_vbox), poidisplay_frame, TRUE, TRUE, 2);
+ gtk_box_pack_start
+ (GTK_BOX (poi_vbox), poisearch_frame, FALSE, FALSE, 2);
+ gtk_box_pack_start (GTK_BOX (poi_vbox), wp_frame, FALSE, FALSE, 2);
+
+ poi_label = gtk_label_new (_("POI"));
+ gtk_notebook_append_page
+ (GTK_NOTEBOOK (notebook), poi_vbox, poi_label);
+}
+
+/* ************************************************************************* */
+static void
+settings_wp (GtkWidget *notebook)
+{
+ GtkWidget *wp_vbox, *wp_label;
+ GtkWidget *wpfile_label, *wpfile_bt;
+ GtkWidget *wp_table, *wp_frame, *wp_fr_lb;
+ GtkWidget *wpqs_table, *wpqs_frame, *wpqs_fr_lb;
+ GtkTooltips *wp_tooltips;
+
+ GtkWidget *wpfile_rb[30];
+ DIR *d;
+ gchar path[400];
+ gchar *current_wpfile;
+ struct dirent *dat;
+ gint dircount = 0;
+ gint i;
+
+ wp_vbox = gtk_vbox_new (FALSE, 2);
+ wp_tooltips = gtk_tooltips_new ();
+
+ /* waypoints file dialog */
+ {
+ wpfile_label = gtk_label_new (_("Waypoints File"));
+ wpfile_bt = gtk_file_chooser_button_new
+ (_("Select Waypoints File"), GTK_FILE_CHOOSER_ACTION_OPEN);
+ if (!gtk_file_chooser_set_filename
+ (GTK_FILE_CHOOSER (wpfile_bt), local_config.wp_file))
+ {
+ gtk_file_chooser_set_current_folder
+ (GTK_FILE_CHOOSER (wpfile_bt), local_config.dir_home);
+ }
+ gtk_tooltips_set_tip (GTK_TOOLTIPS (wp_tooltips), wpfile_bt,
+ _("Choose the waypoints file to use!\nCurrently only files in "
+ "GpsDrive's way.txt format are supported."), NULL);
+ g_signal_connect (wpfile_bt, "selection-changed",
+ GTK_SIGNAL_FUNC (setwpfile_cb), NULL);
+
+ wp_table = gtk_table_new (1, 2, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (wp_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (wp_table), 5);
+ gtk_table_attach_defaults (GTK_TABLE (wp_table),
+ wpfile_label, 0, 1, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (wp_table),
+ wpfile_bt, 1, 2, 0, 1);
+ }
+
+ /* waypoints quick select */
+ {
+ g_strlcpy (path, local_config.dir_home, sizeof (path));
+ current_wpfile = g_strrstr (local_config.wp_file, "/") + 1;
+ names = g_new (namesstruct, 102);
+ d = opendir (path);
+ if (NULL != d)
+ {
+ do
+ {
+ dat = readdir (d);
+ if (NULL != dat)
+ {
+ if ( 0 == strncmp (dat->d_name, "way", 3)
+ && 0 == strncmp ((dat->d_name +
+ (strlen (dat->d_name) - 4)),".txt", 4)
+ )
+ {
+ g_strlcpy ((names + dircount)->n,
+ dat->d_name, 200);
+ dircount++;
+ if (dircount >= 100)
+ {
+ popup_warning (NULL,
+ _("Don't use more than\n100"
+ "waypoint(way*.txt) files!"));
+ g_free (names);
+ }
+ }
+ }
+ }
+ while (NULL != dat);
+ }
+ free (d);
+
+ wpqs_table = gtk_table_new (1 + (dircount - 1) / 2, 2, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (wpqs_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (wpqs_table), 5);
+
+ for (i = 0; i < dircount; i++)
+ {
+ if (0 == i)
+ {
+ wpfile_rb[i] = gtk_radio_button_new_with_label
+ (NULL, (names + i)->n);
+ }
+ else
+ {
+ wpfile_rb[i] = gtk_radio_button_new_with_label (
+ gtk_radio_button_group (
+ GTK_RADIO_BUTTON (wpfile_rb[0])),
+ (names + i)->n);
+ }
+ g_signal_connect (wpfile_rb[i], "clicked",
+ GTK_SIGNAL_FUNC (setwpfilequick_cb), (gpointer) i);
+ gtk_table_attach_defaults (GTK_TABLE (wpqs_table),
+ wpfile_rb[i], i % 2, i % 2 + 1, i / 2, i / 2 + 1);
+
+ if (!(strcmp (current_wpfile, (names + i)->n)))
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (wpfile_rb[i]), TRUE);
+ }
+ }
+
+ }
+
+ wp_frame = gtk_frame_new (NULL);
+ wp_fr_lb = gtk_label_new (NULL);
+ gtk_label_set_markup
+ (GTK_LABEL (wp_fr_lb), _("<b>File Dialog Selection</b>"));
+ gtk_frame_set_label_widget (GTK_FRAME (wp_frame), wp_fr_lb);
+ gtk_frame_set_shadow_type (GTK_FRAME (wp_frame), GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (wp_frame), wp_table);
+
+ wpqs_frame = gtk_frame_new (NULL);
+ wpqs_fr_lb = gtk_label_new (NULL);
+ gtk_label_set_markup
+ (GTK_LABEL (wpqs_fr_lb), _("<b>Quick Select File</b>"));
+ gtk_frame_set_label_widget (GTK_FRAME (wpqs_frame), wpqs_fr_lb);
+ gtk_frame_set_shadow_type (GTK_FRAME (wpqs_frame), GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (wpqs_frame), wpqs_table);
+
+ gtk_box_pack_start (GTK_BOX (wp_vbox), wpqs_frame, FALSE, FALSE, 2);
+ //gtk_box_pack_start (GTK_BOX (wp_vbox), wp_frame, TRUE, FALSE, 2);
+
+ wp_label = gtk_label_new (_("Waypoints"));
+ gtk_notebook_append_page
+ (GTK_NOTEBOOK (notebook), wp_vbox, wp_label);
+}
+
+/* ************************************************************************* */
+static void
+settings_friends (GtkWidget *notebook)
+{
+ GtkWidget *friends_vbox, *friends_label;
+ GtkWidget *friendgen_table, *friendsrv_table;
+ GtkWidget *friendgen_frame, *friendsrv_frame;
+ GtkWidget *friendgen_fr_lb, *friendsrv_fr_lb;
+ GtkTooltips *friends_tooltips;
+ GtkWidget *friendenable_bt, *friendwarning_lb;
+ GtkWidget *friendname_label, *friendname_entry;
+ GtkWidget *friendmaxsec_label, *friendmaxsec_spin;
+ GtkWidget *friendmaxsec_combo;
+ GtkWidget *friendsrv_label, *friendsrv_entry;
+ GtkWidget *friendsrvip_label, *friendsrvip_entry;
+ GtkWidget *friendsrvip_bt;
+
+ friends_tooltips = gtk_tooltips_new ();
+ friends_vbox = gtk_vbox_new (FALSE, 2);
+
+ /* friends general settings */
+ {
+ friendgen_table = gtk_table_new (4, 4, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (friendgen_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (friendgen_table), 5);
+
+ friendwarning_lb = gtk_label_new (_("If you enable this "
+ "service, <span color=\"red\">everyone</span> using\n"
+ "the same server can see your position!"));
+ gtk_label_set_use_markup (GTK_LABEL (friendwarning_lb), TRUE);
+
+ friendname_label = gtk_label_new (_("Your name"));
+ friendname_entry = gtk_entry_new ();
+ gtk_entry_set_max_length (GTK_ENTRY (friendname_entry), 40);
+ gtk_entry_set_text
+ (GTK_ENTRY (friendname_entry), local_config.friends_name);
+ g_signal_connect (friendname_entry, "changed",
+ GTK_SIGNAL_FUNC (setfriendname_cb), NULL);
+
+ friendenable_bt = gtk_check_button_new_with_label
+ (_("Enable friends service"));
+ if (local_config.showfriends)
+ {
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (friendenable_bt), TRUE);
+ }
+ g_signal_connect_swapped (friendenable_bt, "clicked",
+ GTK_SIGNAL_FUNC (setshowfriends_cb), friendname_entry);
+
+ friendmaxsec_label = gtk_label_new
+ (_("Show only positions newer than"));
+ friendmaxsec_spin = gtk_spin_button_new_with_range (0, 120, 0.5);
+ friendmaxsec_combo = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (friendmaxsec_combo), _("Days"));
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (friendmaxsec_combo), _("Hours"));
+ gtk_combo_box_append_text
+ (GTK_COMBO_BOX (friendmaxsec_combo), _("Minutes"));
+ if (local_config.friends_maxsecs > 120 * 3600)
+ {
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX (friendmaxsec_combo), 0);
+ gtk_spin_button_set_value
+ (GTK_SPIN_BUTTON (friendmaxsec_spin),
+ local_config.friends_maxsecs / 86400);
+ }
+ else if (local_config.friends_maxsecs > 120 * 60)
+ {
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX (friendmaxsec_combo), 1);
+ gtk_spin_button_set_value
+ (GTK_SPIN_BUTTON (friendmaxsec_spin),
+ local_config.friends_maxsecs / 3600);
+ }
+ else
+ {
+ gtk_combo_box_set_active
+ (GTK_COMBO_BOX (friendmaxsec_combo), 2);
+ gtk_spin_button_set_value
+ (GTK_SPIN_BUTTON (friendmaxsec_spin),
+ local_config.friends_maxsecs / 60);
+ }
+ g_signal_connect (friendmaxsec_spin, "changed",
+ GTK_SIGNAL_FUNC (setfriendmaxsec_cb), friendmaxsec_combo);
+ g_signal_connect (friendmaxsec_combo, "changed",
+ GTK_SIGNAL_FUNC (setfriendmaxsecunit_cb), friendmaxsec_spin);
+
+ gtk_table_attach_defaults (GTK_TABLE (friendgen_table),
+ friendenable_bt, 0, 4, 0, 1);
+ gtk_table_attach (GTK_TABLE (friendgen_table),
+ friendname_label, 0, 1, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (friendgen_table),
+ friendname_entry, 1, 4, 1, 2);
+ gtk_table_attach (GTK_TABLE (friendgen_table),
+ friendmaxsec_label, 0, 2, 2, 3, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (friendgen_table),
+ friendmaxsec_spin, 2, 3, 2, 3);
+ gtk_table_attach_defaults (GTK_TABLE (friendgen_table),
+ friendmaxsec_combo, 3, 4, 2, 3);
+ gtk_table_attach_defaults (GTK_TABLE (friendgen_table),
+ friendwarning_lb, 0, 4, 3, 4);
+
+ gtk_tooltips_set_tip (friends_tooltips, friendenable_bt,
+ _("Enable/disable use of friends service. You have to "
+ "enter a username, don't use the default name!"),
+ NULL);
+ gtk_tooltips_set_tip (friends_tooltips, friendname_entry,
+ _("Set here the name which will be shown near your position."),
+ NULL);
+ gtk_tooltips_set_tip (friends_tooltips, friendmaxsec_spin,
+ _("Set here the max. age of friends positions that are "
+ "displayed. Older positions are not shown."),
+ NULL);
+ }
+
+ /* friends server settings */
+ {
+ friendsrv_table = gtk_table_new (2, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (friendsrv_table), 5);
+ gtk_table_set_col_spacings (GTK_TABLE (friendsrv_table), 5);
+
+ friendsrv_label = gtk_label_new (_("Name"));
+ friendsrv_entry = gtk_entry_new ();
+ gtk_entry_set_max_length (GTK_ENTRY (friendsrv_entry), 255);
+ gtk_entry_set_text
+ (GTK_ENTRY (friendsrv_entry), local_config.friends_serverfqn);
+ g_signal_connect (friendsrv_entry, "changed",
+ GTK_SIGNAL_FUNC (setfriendsrv_cb), NULL);
+
+ friendsrvip_label = gtk_label_new (_("IP"));
+ friendsrvip_entry = gtk_entry_new ();
+ gtk_entry_set_max_length (GTK_ENTRY (friendsrvip_entry), 20);
+ gtk_entry_set_text
+ (GTK_ENTRY (friendsrvip_entry), local_config.friends_serverip);
+ g_signal_connect (friendsrvip_entry, "changed",
+ GTK_SIGNAL_FUNC (setfriendsrvip_cb), NULL);
+
+ friendsrvip_bt = gtk_button_new_with_label (_("Lookup"));
+ g_signal_connect_swapped (friendsrvip_bt, "clicked",
+ GTK_SIGNAL_FUNC (setfriendsrvip_lookup_cb), friendsrvip_entry);
+
+ gtk_table_attach (GTK_TABLE (friendsrv_table),
+ friendsrv_label, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (friendsrv_table),
+ friendsrv_entry, 1, 3, 0, 1);
+ gtk_table_attach (GTK_TABLE (friendsrv_table),
+ friendsrvip_label, 0, 1, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_table_attach_defaults (GTK_TABLE (friendsrv_table),
+ friendsrvip_entry, 1, 2, 1, 2);
+ gtk_table_attach_defaults (GTK_TABLE (friendsrv_table),
+ friendsrvip_bt, 2, 3, 1, 2);
+
+ gtk_tooltips_set_tip (friends_tooltips, friendsrv_entry,
+ _("Set here the fully qualified host name (i.e. friends."
+ "gpsdrive.de) of the friends server to use, then press "
+ "the \"Lookup\" button."), NULL);
+ gtk_tooltips_set_tip (friends_tooltips, friendsrvip_bt,
+ _("Press this button to resolve the friends server name."),
+ NULL);
+ gtk_tooltips_set_tip (friends_tooltips, friendsrvip_entry,
+ _("Set here the IP adress (i.e. 127.0.0.1) if you don't set "
+ "the hostname above"), NULL);
+ }
+
+ /* friends general frame */
+ friendgen_frame = gtk_frame_new (NULL);
+ friendgen_fr_lb = gtk_label_new (NULL);
+ gtk_label_set_markup
+ (GTK_LABEL (friendgen_fr_lb), _("<b>General</b>"));
+ gtk_frame_set_label_widget
+ (GTK_FRAME (friendgen_frame), friendgen_fr_lb);
+ gtk_frame_set_shadow_type
+ (GTK_FRAME (friendgen_frame), GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (friendgen_frame), friendgen_table);
+
+ /* friends server frame */
+ friendsrv_frame = gtk_frame_new (NULL);
+ friendsrv_fr_lb = gtk_label_new (NULL);
+ gtk_label_set_markup
+ (GTK_LABEL (friendsrv_fr_lb), _("<b>Server</b>"));
+ gtk_frame_set_label_widget
+ (GTK_FRAME (friendsrv_frame), friendsrv_fr_lb);
+ gtk_frame_set_shadow_type
+ (GTK_FRAME (friendsrv_frame), GTK_SHADOW_NONE);
+ gtk_container_add (GTK_CONTAINER (friendsrv_frame), friendsrv_table);
+
+ gtk_box_pack_start
+ (GTK_BOX (friends_vbox), friendgen_frame, FALSE, FALSE, 2);
+ gtk_box_pack_start
+ (GTK_BOX (friends_vbox), friendsrv_frame, FALSE, FALSE, 2);
+
+ friends_label = gtk_label_new (_("Friends"));
+ gtk_notebook_append_page
+ (GTK_NOTEBOOK (notebook), friends_vbox, friends_label);
+}
+
+/* ************************************************************************* */
+/* TODO: fill with content
+static void
+settings_fly (GtkWidget *notebook)
+{
+ GtkWidget *fly_vbox, *fly_label;
+
+
+ fly_vbox = gtk_vbox_new (FALSE, 2);
+
+ fly_label = gtk_label_new (_("Fly"));
+ gtk_notebook_append_page
+ (GTK_NOTEBOOK (notebook), fly_vbox, fly_label);
+
+}
+*/
+
+/* ************************************************************************* */
+/* TODO: fill with content
+static void
+settings_gps (GtkWidget *notebook)
+{
+ GtkWidget *gps_vbox, *gps_label;
+
+
+ gps_vbox = gtk_vbox_new (FALSE, 2);
+
+ gps_label = gtk_label_new (_("GPS"));
+ gtk_notebook_append_page
+ (GTK_NOTEBOOK (notebook), gps_vbox, gps_label);
+
+}
+*/
+
+/* ************************************************************************* */
+/* TODO: fill with content
+static void
+settings_nautic (GtkWidget *notebook)
+{
+ GtkWidget *nautic_vbox, *nautic_label;
+
+
+ nautic_vbox = gtk_vbox_new (FALSE, 2);
+
+ nautic_label = gtk_label_new (_("Nautic"));
+ gtk_notebook_append_page
+ (GTK_NOTEBOOK (notebook), nautic_vbox, nautic_label);
+
+}
+*/
+
+/* *************************************************************************
+ * main setup:
+ * creates the settings window and calls all the other setup functions
+ */
+gint
+settings_main_cb (GtkWidget *widget, guint datum)
+{
+ GtkWidget *settings_nb, *close_bt;
+
+ settings_window = gtk_dialog_new ();
+ gtk_window_set_title
+ (GTK_WINDOW (settings_window), _("GpsDrive Settings"));
+ gtk_window_set_position
+ (GTK_WINDOW (settings_window), GTK_WIN_POS_CENTER);
+ gtk_window_set_modal
+ (GTK_WINDOW (settings_window), TRUE);
+
+ /* settings close button */
+ close_bt = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
+ GTK_WIDGET_SET_FLAGS (close_bt, GTK_CAN_DEFAULT);
+ gtk_window_set_default (GTK_WINDOW (settings_window), close_bt);
+ g_signal_connect_swapped (close_bt, "clicked",
+ GTK_SIGNAL_FUNC (settings_close_cb), settings_window);
+ g_signal_connect (GTK_OBJECT (settings_window), "delete_event",
+ GTK_SIGNAL_FUNC (settings_close_cb), NULL);
+
+ gtk_container_set_border_width
+ (GTK_CONTAINER (settings_window), 2 * PADDING);
+
+ /* Create a new notebook, place the position of the tabs */
+ settings_nb = gtk_notebook_new ();
+ gtk_notebook_set_scrollable (GTK_NOTEBOOK (settings_nb), TRUE);
+ gtk_notebook_set_tab_pos (GTK_NOTEBOOK (settings_nb), GTK_POS_TOP);
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (settings_nb), TRUE);
+ gtk_notebook_popup_enable (GTK_NOTEBOOK (settings_nb));
+
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (settings_window)->vbox),
+ settings_nb, TRUE, TRUE, 2 * PADDING);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (settings_window)->action_area),
+ close_bt, TRUE, TRUE, 2);
+
+ /* fill the tabs with the necessary dialogs */
+ settings_general (settings_nb);
+ if (usesql)
+ settings_poi (settings_nb);
+ else
+ settings_wp (settings_nb);
+ settings_friends (settings_nb);
+ settings_nav (settings_nb);
+ settings_gui (settings_nb);
+ //settings_gps (settings_nb);
+ //settings_fly (settings_nb);
+ //settings_nautic (settings_nb);
+
+ gtk_widget_show_all (settings_window);
+ gtk_notebook_set_current_page
+ (GTK_NOTEBOOK (settings_nb), lastnotebook);
+
+ return TRUE;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* *****************************************************************************
+ */
+void
+testifnight (void)
+{
+// daylights ();
+
+ if ((hour > sunset) || (hour < sunrise))
+ {
+ isnight = TRUE;
+ }
+ else
+ {
+ isnight = FALSE;
+ }
+
+ if (mydebug > 20)
+ {
+ if (isnight)
+ {
+ g_print ("\nIt is night\n");
+ }
+ else
+ {
+ g_print ("\nIt is day\n");
+ }
+ }
+}
+
+/* *****************************************************************************
+ */
+gint
+infosettz (GtkWidget * widget, guint datum)
+{
+ gchar *sc;
+
+ sc = (char *) gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (ge12)->entry));
+ sscanf (sc, "GMT%d", &zone);
+
+ if ( mydebug > 20 )
+ {
+ g_print ("\nTimezone: %d", zone);
+ }
+
+ current.needtosave = TRUE;
+ return TRUE;
+}
+
diff --git a/src/settings_gui.c b/src/settings_gui.c
new file mode 100644
index 0000000..a3a6845
--- /dev/null
+++ b/src/settings_gui.c
@@ -0,0 +1,32 @@
+/*
+**********************************************************************
+
+Copyright (c) 2001-2007 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+**********************************************************************
+*/
+
+/*
+ * settings_gui.c
+ *
+ * This module will hold all the gui stuff for the settings menus
+ */
+
diff --git a/src/speech_out.c b/src/speech_out.c
new file mode 100644
index 0000000..44fc8ce
--- /dev/null
+++ b/src/speech_out.c
@@ -0,0 +1,662 @@
+/*************************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+/*
+ $Log$
+ Revision 1.13 2006/08/20 12:41:55 tweety
+ ifox rectangle position behind scaler display in map
+ rename font variables to meaningfull names
+ this also renames the config parameters of font strings in config file
+ they now are :font_s_text, font_s_verysmalltext, font_s_smalltext, font_s_bigtext, font_s_wplabel
+ move ta_displaystreetname to main loop
+ start centralizing font selection. More has to be done here
+ add simple insertsqldata test to unit tests
+
+ Revision 1.12 2006/02/05 16:38:06 tweety
+ reading floats with scanf looks at the locale LANG=
+ so if you have a locale de_DE set reading way.txt results in clearing the
+ digits after the '.'
+ For now I set the LC_NUMERIC always to en_US, since there we have . defined for numbers
+
+ Revision 1.11 2006/01/03 14:24:10 tweety
+ eliminate compiler Warnings
+ try to change all occurences of longi -->lon, lati-->lat, ...i
+ use drawicon(posxdest,posydest,"w-lan.open") instead of using a seperate variable
+ rename drawgrid --> do_draw_grid
+ give the display frames usefull names frame_lat, ...
+ change handling of WP-types to lowercase
+ change order for directories reading icons
+ always read inconfile
+
+ Revision 1.10 1994/06/08 13:02:31 tweety
+ adjust debug levels
+
+ Revision 1.9 2005/10/10 22:01:26 robstewart
+ Updated to attempt fix on bug reported by Andreas.
+
+ Revision 1.8 2005/05/15 06:51:27 tweety
+ all speech strings are now represented as arrays of strings
+ author: Rob Stewart <rob@groupboard.com>
+
+ Revision 1.7 2005/04/29 17:41:57 tweety
+ Moved the speech string to a seperate File
+
+ Revision 1.6 2005/04/20 23:33:49 tweety
+ reformatted source code with anjuta
+ So now we have new indentations
+
+ Revision 1.5 2005/04/13 19:58:31 tweety
+ renew indentation to 4 spaces + tabstop=8
+
+ Revision 1.4 2005/04/10 21:50:50 tweety
+ reformatting c-sources
+
+ Revision 1.3 2005/04/10 20:47:49 tweety
+ added src/speech_out.h
+ update configure and po Files
+
+ Revision 1.2 2005/03/25 14:38:46 tweety
+ change flite usage so no file is generated inbetween. This also fixes problem with flite having
+ problems speaking a file without a trailing \n
+
+ Revision 1.1.1.1 2004/12/23 16:03:24 commiter
+ Initial import, straight from 2.10pre2 tar.gz archive
+
+ Revision 1.37 2004/03/02 00:53:35 ganter
+ v2.09pre1
+ added new gpsfetchmap.pl (works again with Expedia)
+ added sound settings in settings menu
+ max serial device string is now 40 char
+
+ Revision 1.36 2004/02/08 17:16:25 ganter
+ replacing all strcat with g_strlcat to avoid buffer overflows
+
+ Revision 1.35 2004/02/08 16:35:10 ganter
+ replacing all sprintf with g_snprintf to avoid buffer overflows
+
+ Revision 1.34 2004/02/06 22:29:24 ganter
+ updated README and man page
+
+ Revision 1.33 2004/02/02 03:38:32 ganter
+ code cleanup
+
+ Revision 1.32 2004/01/29 04:42:17 ganter
+ after valgrind
+
+ Revision 1.31 2004/01/17 17:41:48 ganter
+ replaced all gdk_pixbuf_render_to_drawable (obsolet) with gdk_draw_pixbuf
+
+ Revision 1.30 2004/01/16 13:19:59 ganter
+ update targetlist if goto button pressed
+
+ Revision 1.29 2004/01/11 10:01:57 ganter
+ gray border for .dsc file text
+
+ Revision 1.28 2004/01/05 05:52:58 ganter
+ changed all frames to respect setting
+
+ Revision 1.27 2004/01/01 09:07:33 ganter
+ v2.06
+ trip info is now live updated
+ added cpu temperature display for acpi
+ added tooltips for battery and temperature
+
+ Revision 1.26 2003/12/17 02:17:56 ganter
+ added donation window
+ waypoint describtion (.dsc files) works again
+ added dist_alarm ...
+
+ Revision 1.25 2003/10/04 17:43:58 ganter
+ translations dont need to be utf-8, but the .po files must specify the
+ correct coding (ie, UTF-8, iso8859-15)
+
+ Revision 1.24 2003/05/11 21:15:46 ganter
+ v2.0pre7
+ added script convgiftopng
+ This script converts .gif into .png files, which reduces CPU load
+ run this script in your maps directory, you need "convert" from ImageMagick
+
+ Friends mode runs fine now
+ Added parameter -H to correct the alitude
+
+ Revision 1.23 2003/05/07 10:52:23 ganter
+ ...
+
+ Revision 1.22 2003/01/15 15:30:28 ganter
+ before dynamically loading mysql
+
+ Revision 1.21 2002/11/02 12:38:55 ganter
+ changed website to www.gpsdrive.de
+
+ Revision 1.20 2002/07/30 20:49:55 ganter
+ 1.26pre3
+ added support for festival lite (flite)
+ changed http request to HTTP1.1 and added correct servername
+
+ Revision 1.19 2002/06/23 17:09:35 ganter
+ v1.23pre9
+ now PDA mode looks good.
+
+ Revision 1.18 2002/06/02 20:54:10 ganter
+ added navigation.c and copyrights
+
+ Revision 1.17 2002/05/11 15:45:31 ganter
+ v1.21pre1
+ degree,minutes,seconds should work now
+
+ Revision 1.16 2002/05/04 10:48:24 ganter
+ v1.20pre2
+
+ Revision 1.15 2002/05/04 09:17:37 ganter
+ added new intl subdir
+
+ Revision 1.14 2002/05/02 01:34:11 ganter
+ added speech output of waypoint description
+
+ Revision 1.13 2002/04/14 23:06:26 ganter
+ v1.17
+
+ Revision 1.12 2001/11/01 20:17:59 ganter
+ v1.0 added spanish voice output
+
+ Revision 1.11 2001/09/30 18:45:27 ganter
+ v0.29
+ added choice of map type
+
+ Revision 1.10 2001/09/30 12:09:43 ganter
+ added help menu
+
+ Revision 1.9 2001/09/28 15:43:56 ganter
+ v0.28 changed layout, some bugfixes
+
+ Revision 1.8 2001/09/25 23:49:44 ganter
+ v 0.27
+
+ Revision 1.7 2001/09/23 22:31:14 ganter
+ v0.26
+
+ Revision 1.6 2001/09/18 05:33:06 ganter
+ ..
+
+ Revision 1.5 2001/09/17 00:29:38 ganter
+ added speech output of bearing
+
+ Revision 1.4 2001/09/16 21:36:05 ganter
+ speech output is working
+
+ Revision 1.3 2001/09/16 19:12:35 ganter
+ ...
+
+*/
+
+
+/* There must be the software "festival" running in server mode */
+/* http://www.speech.cs.cmu.edu/festival */
+
+
+/* Include Dateien */
+#include "config.h"
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <math.h>
+#include <sys/time.h>
+#include <gpsdrive.h>
+#include <speech_strings.h>
+
+#include "gettext.h"
+
+#include <time.h>
+#include "gui.h"
+#include "gpsdrive_config.h"
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+enum allowed_languages { english, german, spanish };
+enum allowed_languages voicelang;
+
+extern currentstatus_struct current;
+extern gint havespeechout;
+extern int mydebug;
+gint speechsock = -1;
+gchar *displaytext = NULL;
+extern color_struct colors;
+extern GdkDrawable *drawable;
+extern gint real_screen_y, real_screen_x;
+gint do_display_dsc = FALSE, textcount;
+extern gint useflite, foundradar, speechcount;
+extern gchar oldangle[100];
+extern GtkWidget *map_drawingarea;
+
+
+#define SPEECHOUTSERVER "127.0.0.1"
+
+/* *****************************************************************************
+ */
+gint
+speech_out_init ()
+{
+ struct sockaddr_in server;
+ struct hostent *server_data;
+
+ /* open socket to port 1314 */
+ if ((speechsock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ return (FALSE);
+ }
+ server.sin_family = AF_INET;
+ /* We retrieve the IP address of the server from its name: */
+ if ((server_data = gethostbyname (SPEECHOUTSERVER)) == NULL)
+ {
+ return (FALSE);
+ }
+ memcpy (&server.sin_addr, server_data->h_addr, server_data->h_length);
+ server.sin_port = htons (1314);
+ /* We initiate the connection */
+ if (connect (speechsock, (struct sockaddr *) &server, sizeof server) <
+ 0)
+ {
+ return (FALSE);
+ }
+
+
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ */
+void
+speech_out_speek (char *text)
+{
+ gchar out[2000];
+
+ if (!havespeechout)
+ return;
+ if (gui_status.posmode)
+ return;
+
+ if ( mydebug > 0 )
+ g_print (text);
+ if (!useflite)
+ {
+ g_snprintf (out, sizeof (out), "(SayText \"%s\")\n", text);
+ write (speechsock, out, strlen (out));
+ }
+ else
+ {
+ g_strlcat (text, ".\n", sizeof (text));
+ g_snprintf (out, sizeof (out), "flite -t '%s'&", text);
+ if ( mydebug > 0 )
+ printf ("speech with flite: %s\n", out);
+ system (out);
+ }
+}
+
+/* *****************************************************************************
+ */
+void
+speech_out_speek_raw (char *text)
+{
+ if (!havespeechout)
+ return;
+ if (gui_status.posmode)
+ return;
+
+ if ( mydebug > 0 )
+ g_print (text);
+
+ write (speechsock, text, strlen (text));
+}
+
+/* *****************************************************************************
+ * if second parameter is TRUE, then also greeting is spoken
+ */
+gint
+speech_saytime_cb (GtkWidget * widget, guint datum)
+{
+ time_t t;
+ struct tm *ts;
+ gchar buf[200];
+
+ if (local_config.mute)
+ return TRUE;
+
+ time (&t);
+ ts = localtime (&t);
+
+ if( havespeechout )
+ {
+ if( 1 == datum )
+ {
+ if( (ts->tm_hour >= 0) && (ts->tm_hour < 12) )
+ {
+ g_snprintf( buf, sizeof(buf), speech_morning[voicelang] );
+ }
+ if( (ts->tm_hour >= 12) && (ts->tm_hour < 18) )
+ {
+ g_snprintf( buf, sizeof(buf), speech_afternoon[voicelang] );
+ }
+ if( ts->tm_hour >= 18 )
+ {
+ g_snprintf( buf, sizeof(buf), speech_evening[voicelang] );
+ }
+
+ speech_out_speek( buf );
+ }
+
+ if( 1 == ts->tm_hour )
+ {
+ g_snprintf( buf, sizeof(buf), speech_time_mins[voicelang], ts->tm_min );
+ }
+ else
+ {
+ g_snprintf(
+ buf, sizeof(buf), speech_time_hrs_mins[voicelang], ts->tm_hour,
+ ts->tm_min );
+ }
+
+ speech_out_speek( buf );
+ }
+
+ return TRUE;
+}
+
+/* *****************************************************************************
+ */
+void
+saytargettext (gchar * filename, gchar * tg)
+{
+ gchar file[500];
+ gint fd, e;
+ gchar *start, *end;
+ struct stat buf;
+ gchar *data, *b, *tg2, target[100];
+
+ /* build .dsc filename */
+ g_strlcpy (file, filename, sizeof (file));
+ file[strlen (file) - 3] = 0;
+ g_strlcat (file, "dsc", sizeof (file));
+ /* get size */
+ e = stat (file, &buf);
+ if (e != 0)
+ return;
+
+ fd = open (file, O_RDONLY);
+ /* map +2000 bytes to get 0 at the end */
+ data = mmap (0, buf.st_size + 2000, PROT_READ, MAP_SHARED, fd, 0);
+ g_strlcpy (target, "$", sizeof (target));
+ tg2 = g_strdelimit (tg, " ", '_');
+ g_strlcat (target, tg2, sizeof (target));
+ start = strstr (data, target);
+ if (start != NULL)
+ {
+ start = strstr (start, "\n");
+ end = strstr (start, "$");
+ if (end == NULL)
+ end = start + strlen (start);
+ b = calloc (end - start + 50, 1);
+ if (displaytext != NULL)
+ free (displaytext);
+ displaytext = calloc (end - start + 50, 1);
+ strncpy (displaytext, start, end - start);
+ displaytext[end - start + 1] = 0;
+ g_strlcpy (b, displaytext, end - start + 50);
+ displaytext = g_strdelimit (displaytext, "\n", ' ');
+ do_display_dsc = TRUE;
+ textcount = 0;
+ speech_out_speek (b);
+ free (b);
+ }
+ munmap (data, buf.st_size + 2000);
+}
+
+/* *****************************************************************************
+ */
+void
+display_dsc (void)
+{
+ GdkGC *kontext;
+ gint len;
+ gchar *text;
+ PangoFontDescription *pfd;
+ PangoLayout *wplabellayout;
+
+
+ if (!do_display_dsc)
+ return;
+ if ((textcount >= (int) strlen (displaytext)))
+ {
+ do_display_dsc = FALSE;
+ free (displaytext);
+ displaytext = NULL;
+ return;
+ }
+ if (textcount > 20)
+ text = displaytext + textcount;
+ else
+ text = displaytext;
+ kontext = gdk_gc_new (drawable);
+ len = strlen (text);
+ /* if (len>10) */
+ /* len=10; */
+
+
+ /* gdk_gc_set_function (kontext, GDK_OR); */
+
+ gdk_gc_set_foreground (kontext, &colors.mygray);
+ gdk_draw_rectangle (drawable, kontext, 1, 0, SCREEN_Y - 40, SCREEN_X,
+ 40);
+ gdk_gc_set_function (kontext, GDK_COPY);
+ /* gdk_gc_set_foreground (kontext, &blue); */
+
+ /* prints in pango */
+
+ wplabellayout = gtk_widget_create_pango_layout (map_drawingarea, text);
+ //KCFX
+ if (local_config.guimode == GUI_PDA)
+ pfd = pango_font_description_from_string ("Sans 8");
+ else
+ pfd = pango_font_description_from_string ("Sans bold 14");
+ pango_layout_set_font_description (wplabellayout, pfd);
+ /* pango_layout_get_pixel_size (wplabellayout, &width, &height); */
+ gdk_draw_layout_with_colors (drawable, kontext, 11, SCREEN_Y - 30,
+ wplabellayout, &colors.blue, NULL);
+
+ if (wplabellayout != NULL)
+ g_object_unref (G_OBJECT (wplabellayout));
+ /* freeing PangoFontDescription, cause it has been copied by prev. call */
+ pango_font_description_free (pfd);
+
+
+
+ textcount += 2;
+
+}
+
+/* *****************************************************************************
+ */
+void
+speech_out_close (void)
+{
+ if (speechsock != -1)
+ close (speechsock);
+}
+
+
+/* *****************************************************************************
+ */
+gint
+speech_out_cb (GtkWidget * widget, guint * datum)
+{
+ gchar buf[500], s2[100];
+ gint angle;
+
+ if (strcmp (oldangle, "XXX"))
+ {
+ if (local_config.mute)
+ return TRUE;
+ if (foundradar)
+ return TRUE;
+ if (current.importactive)
+ return TRUE;
+ }
+
+ speechcount++;
+ angle = RAD2DEG (current.bearing);
+
+ if (!current.simmode && !current.gpsfix)
+ {
+ if( (1 == speechcount) && local_config.sound_gps )
+ {
+ g_snprintf( buf, sizeof(buf), speech_too_few_satellites[voicelang] );
+ speech_out_speek (buf);
+ }
+
+ return TRUE;
+ }
+
+ if( (angle >= 338) || (angle < 22) )
+ {
+ g_strlcpy( s2, speech_front[voicelang], sizeof(s2) );
+ }
+ else if( (angle >= 22) && (angle < 68) )
+ {
+ g_strlcpy( s2, speech_front_right[voicelang], sizeof(s2) );
+ }
+ else if( (angle >= 68) && (angle < 112) )
+ {
+ g_strlcpy( s2, speech_right[voicelang], sizeof(s2) );
+ }
+ else if( (angle >= 112) && (angle < 158) )
+ {
+ g_strlcpy( s2, speech_behind_right[voicelang], sizeof(s2) );
+ }
+ else if( (angle >= 158) && (angle < 202) )
+ {
+ g_strlcpy( s2, speech_behind[voicelang], sizeof(s2) );
+ }
+ else if( (angle >= 202) && (angle < 248) )
+ {
+ g_strlcpy( s2, speech_behind_left[voicelang], sizeof(s2) );
+ }
+ else if( (angle >= 248) && (angle < 292) )
+ {
+ g_strlcpy( s2, speech_left[voicelang], sizeof(s2) );
+ }
+ else if( (angle >= 292) && (angle < 338) )
+ {
+ g_strlcpy( s2, speech_front_left[voicelang], sizeof(s2) );
+ }
+
+ if( (1 == speechcount) || (strcmp (s2, oldangle)) )
+ {
+ if (local_config.sound_direction)
+ {
+ g_snprintf( buf, sizeof(buf), speech_destination_is[voicelang], s2 );
+ speech_out_speek (buf);
+ }
+
+ g_strlcpy (oldangle, s2, sizeof (oldangle));
+ }
+ if( (3 == speechcount) && (current.groundspeed >= 20) )
+ {
+ if (local_config.sound_speed)
+ {
+ if (local_config.distmode == DIST_MILES)
+ {
+ g_snprintf(
+ buf, sizeof(buf), speech_speed_mph[voicelang], (int) current.groundspeed );
+ }
+ else
+ {
+ g_snprintf(
+ buf, sizeof(buf), speech_speed_kph[voicelang], (int) current.groundspeed );
+ }
+
+ speech_out_speek( buf );
+ }
+ }
+
+ if (speechcount > 10)
+ speechcount = 0;
+
+ if( (2 == speechcount) || ((current.dist < 1.2) && (7 == speechcount)) )
+ {
+ if (local_config.sound_distance)
+ {
+ if (local_config.distmode == DIST_MILES)
+ {
+ if( current.dist <= 1.2 )
+ {
+ g_snprintf( s2, sizeof(s2), speech_yards[voicelang], current.dist * 1760.0 );
+ }
+ else
+ {
+ g_snprintf( s2, sizeof(s2), speech_miles[voicelang], current.dist );
+ }
+ }
+ else
+ {
+ if( current.dist <= 1.2 )
+ {
+ g_snprintf( s2, sizeof(s2), speech_meters[voicelang],
+ (int) (current.dist * 1000) );
+ }
+ else if( 1 == (int) current.dist )
+ {
+ g_snprintf( s2, sizeof(s2), speech_one_kilometer[voicelang] );
+ }
+ else
+ {
+ g_snprintf(
+ s2, sizeof(s2), speech_kilometers[voicelang], (int) current.dist );
+ }
+ }
+
+ g_snprintf(
+ buf, sizeof(buf), speech_distance_to[voicelang], current.target, s2 );
+
+ speech_out_speek( buf );
+ }
+ }
+
+ return TRUE;
+}
diff --git a/src/speech_out.h b/src/speech_out.h
new file mode 100644
index 0000000..e690742
--- /dev/null
+++ b/src/speech_out.h
@@ -0,0 +1,45 @@
+/*******************************************************************************
+
+Copyright (c) 2001-2005 Fritz Ganter <ganter@ganter.at>
+
+Website: www.kraftvoll.at/software
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*******************************************************************************/
+/*
+$Log$
+Revision 1.3 2005/04/29 17:41:57 tweety
+Moved the speech string to a seperate File
+
+Revision 1.2 2005/04/22 06:13:16 tweety
+added speechout text to .h File
+Author: Rob Stewart <rob@groupboard.com>
+
+Revision 1.1 2005/04/10 20:47:49 tweety
+added src/speech_out.h
+update configure and po Files
+
+
+*******************************************************************************/
+
+#ifndef GPSDRIVE_SPEECH_OUT_H
+#define GPSDRIVE_SPEECH_OUT_H
+
+extern enum { english, german, spanish } voicelang;
+
+#endif // GPSDRIVE_SPEECH_OUT_H
diff --git a/src/speech_strings.c b/src/speech_strings.c
new file mode 100644
index 0000000..635f616
--- /dev/null
+++ b/src/speech_strings.c
@@ -0,0 +1,368 @@
+/*******************************************************************************
+
+Copyright (c) 2001-2005 Fritz Ganter <ganter@ganter.at>
+
+Website: www.kraftvoll.at/software
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*******************************************************************************/
+
+/*
+$Log$
+Revision 1.4 2006/06/16 20:16:10 tweety
+correct speech strings
+
+Revision 1.3 2005/10/10 22:00:41 robstewart
+Updated to attempt fix on bug reported by Andreas.
+
+Revision 1.2 2005/05/15 06:51:27 tweety
+all speech strings are now represented as arrays of strings
+author: Rob Stewart <rob@groupboard.com>
+
+Revision 1.1 2005/04/29 17:41:57 tweety
+Moved the speech string to a seperate File
+
+
+
+*******************************************************************************/
+
+// ************************************************************************** //
+// This file is used to contain all the spoken phrases in the given languages.
+// **** NOTE **** Remember to include punctuation to make the phrases proper
+// sentences, festival will adjust the sound to make it more natural if you do.
+//
+// **** TODO ****
+// Perhaps move these to the international strings system.
+
+// ************************************************************************** //
+// This enumeration is used to define all the currently supported languages.
+// Add new languages to the end, you *MUST* then add new strings to *ALL*
+// of the following arrays.
+
+#include <gtk/gtk.h>
+
+// ************************************************************************** //
+// The actual phrases used to inform the user. NOTE the order of the items
+// within each array is VERY important and must match the above enumeration.
+
+gchar* speech_target_reached[] =
+{
+ "You reached the target %s.",
+ "Sie haben das Ziel %s erreicht.",
+ "usted ha llegado a %s."
+};
+
+gchar* speech_new_target[] =
+{
+ "New target is %s.",
+ "Neues Ziel ist %s.",
+ "Destinación definida: %s."
+};
+
+
+gchar* speech_danger_radar[] =
+{
+ "Danger, Danger, Radar in %d meters, Your speed is %d.",
+ "Achtung, Achtung, Radar in %d metern, Ihre Geschwindigkeit ist %d.",
+ "Atención Atención, control de velocidad en %d metros, Su velocidad es %d."
+};
+
+// **** TODO ****
+// German string needs corrected
+gchar* speech_info_radar[] =
+{
+ "Information, Radar in %d meters.",
+ "Information, Radarfalle in %d metern.",
+ "Información, control de velocidad en %d metros."
+};
+
+gchar* speech_arrival_hours_mins[] =
+{
+ "Arrival in approximatly %d hours and %d minutes.",
+ "Ankunft in circa %d Stunden und %d minuten.",
+ "Llegada en %d horas y %d minutos."
+};
+
+gchar* speech_arrival_mins[] =
+{
+ "Arrival in approximatly %d minutes.",
+ "Ankunft in zirca %d minuten.",
+ "Llegada en %d minutos."
+};
+
+// **** TODO ****
+// Spanish string needs corrected
+gchar* speech_arrival_one_hour_mins[] =
+{
+ "Arrival in approximatly one hour and %d minutes.",
+ "Ankunft in circa einer Stunde und %d minuten.",
+ "Arrival in approximatly one hour and %d minutes."
+};
+
+// **** TODO ****
+// Spanish string needs corrected
+gchar* speech_diff_gps_found[] =
+{
+ "Differential GPS signal found.",
+ "Ein differenzielles GPS Signal wurde gefunden.",
+ "Differential GPS signal found."
+};
+
+// **** TODO ****
+// Spanish string needs corrected
+gchar* speech_diff_gps_lost[] =
+{
+ "No differential GPS signal detected.",
+ "Kein differenzielles GPS Signal vorhanden.",
+ "No differential GPS signal detected."
+};
+
+// **** TODO ****
+// Spanish string needs corrected
+gchar* speech_gps_lost[] =
+{
+ "No GPS signal dectected.",
+ "Kein ausreichendes GPS Signal vorhanden.",
+ "No GPS signal dectected.",
+};
+
+gchar* speech_gps_good[] =
+{
+ "GPS signal good.",
+ "Gutes GPS Signal vorhanden.",
+ "GPS signal bueno."
+};
+
+// **** TODO ****
+// Spanish string needs corrected
+gchar* speech_kismet_found[] =
+{
+ "Found kismet. Happy wardriving.",
+ "Kismet gefunden. Viel Spass beim woardreifing.",
+ "Found kismet. Happy wardriving."
+};
+
+// **** TODO ****
+// Spanish string needs corrected
+gchar* speech_message_received[] =
+{
+ "You received a message from %s.",
+ "Sie haben eine Nachricht von %s erhalten.",
+ "You received a message from %s."
+};
+
+gchar* speech_morning[] =
+{
+ "Good Morning,",
+ "Guten Morgen.",
+ "Buenos días."
+};
+
+gchar* speech_afternoon[] =
+{
+ "Good afternoon,",
+ "Guten Tag.",
+ "Buenos tardes."
+};
+
+gchar* speech_evening[] =
+{
+ "Good evening,",
+ "Guten Abend.",
+ "Buenas noches."
+};
+
+gchar* speech_time_mins[] =
+{
+ "It is one %d.",
+ "Es ist ein Uhr %d",
+ "Es la una y %d minutos."
+};
+
+gchar* speech_time_hrs_mins[] =
+{
+ "It is %d %d.",
+ "Es ist %d Uhr %d",
+ "Son las %d horas y %d minutos."
+};
+
+gchar* speech_too_few_satellites[] =
+{
+ "Not enough satellites in view.",
+ "Zuwenig Satelliten in Sicht.",
+ "El GPS Fix no está disponible."
+};
+
+// This is part of a sentence, so punctuation is given elsewhere.
+gchar* speech_destination_is[] =
+{
+ "Destination is %s",
+ "Das Ziel ist %s",
+ "Su destinación está %s"
+};
+
+gchar* speech_front[] =
+{
+ "in front of you.",
+ "vor ihnen.",
+ "delante de usted."
+};
+
+gchar* speech_front_right[] =
+{
+ "ahead of you to the right.",
+ "rechts vor ihnen.",
+ "delante de usted a la derecha."
+};
+
+gchar* speech_right[] =
+{
+ "to your right.",
+ "rechts.",
+ "a la derecha."
+};
+
+gchar* speech_behind_right[] =
+{
+ "behind you to the right.",
+ "rechts hinter ihnen.",
+ "de tras de usted a la derecha."
+};
+
+gchar* speech_behind[] =
+{
+ "behind you.",
+ "hinter ihnen.",
+ "de tras de usted."
+};
+
+gchar* speech_behind_left[] =
+{
+ "behind you to the left.",
+ "links hinter ihnen.",
+ "de tras de usted a la izquierda."
+};
+
+gchar* speech_left[] =
+{
+ "to your left.",
+ "links.",
+ "a la izquierda."
+};
+
+gchar* speech_front_left[] =
+{
+ "ahead of you to the left.",
+ "links vor ihnen.",
+ "delante de usted a la izquierda."
+};
+
+gchar* speech_speed_mph[] =
+{
+ "The current speed is %d miles per hour.",
+ "Die momentane Geschwindigkeit ist %d Meilen pro Stunde.",
+ "La velocidad actual es %d milla por hora."
+};
+
+gchar* speech_speed_kph[] =
+{
+ "The current speed is %d kilometers per hour.",
+ "Die momentane Geschwindigkeit ist %d kmh",
+ "La velocidad actual es %d kilometros por hora."
+};
+
+// This is part of a sentence, so punctuation is given elsewhere.
+gchar* speech_distance_to[] =
+{
+ "Distance to %s is %s",
+ "Die Entfernung bis %s ist %s",
+ "La distancia a la %s es %s"
+};
+
+gchar* speech_yards[] =
+{
+ "%.0f yards.",
+ "%.0f yard.",
+ "%.0f yards."
+};
+
+gchar* speech_miles[] =
+{
+ "%.0f miles.",
+ "%.0f Meilen.",
+ "%.0f millas."
+};
+
+gchar* speech_meters[] =
+{
+ "%d meters.",
+ "%d meter.",
+ "%d metros."
+};
+
+gchar* speech_kilometers[] =
+{
+ "%d kilometers.",
+ "%d kilometer.",
+ "%d kilometros."
+};
+
+// **** TODO ****
+// Spanish string needs corrected
+gchar* speech_one_kilometer[] =
+{
+ "one kilometer.",
+ "ein kilometer.",
+ "one kilometer."
+};
+
+gchar* speech_remaining_battery[] =
+{
+ "Remaining battery: %d%%",
+ "Batterieladung: %d%%",
+ "BaterÃa restante: %d%%"
+};
+
+// **** TODO ****
+// Spanish string needs corrected
+gchar* speech_found_access_point[] =
+{
+ "Found new %s access point: %s",
+ "Es wurde ein neuer %s ei pi gefunden. name ,.,., %s ,.,., tschännel %d",
+ "Found new %s access point: %s"
+};
+
+// **** TODO ****
+// Spanish string needs corrected
+gchar* speech_access_closed[] =
+{
+ "closed",
+ "verschlüsselter",
+ "closed"
+};
+
+// **** TODO ****
+// Spanish string needs corrected
+gchar* speech_access_open[] =
+{
+ "open",
+ "offener",
+ "open"
+};
+
+// ************************************************************************** //
diff --git a/src/speech_strings.h b/src/speech_strings.h
new file mode 100644
index 0000000..44bb1a7
--- /dev/null
+++ b/src/speech_strings.h
@@ -0,0 +1,83 @@
+/*******************************************************************************
+
+Copyright (c) 2001-2005 Fritz Ganter <ganter@ganter.at>
+
+Website: www.kraftvoll.at/software
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*******************************************************************************/
+/*
+$Log$
+Revision 1.2 2005/05/15 06:51:27 tweety
+all speech strings are now represented as arrays of strings
+author: Rob Stewart <rob@groupboard.com>
+
+Revision 1.1 2005/04/29 17:41:57 tweety
+Moved the speech string to a seperate File
+
+
+
+*******************************************************************************/
+
+#ifndef GPSDRIVE_SPEECH_STRINGS_H
+#define GPSDRIVE_SPEECH_STRINGS_H
+
+
+extern gchar* speech_target_reached[];
+extern gchar* speech_new_target[];
+extern gchar* speech_danger_radar[];
+extern gchar* speech_info_radar[];
+extern gchar* speech_arrival_hours_mins[];
+extern gchar* speech_arrival_mins[];
+extern gchar* speech_arrival_one_hour_mins[];
+extern gchar* speech_diff_gps_found[];
+extern gchar* speech_diff_gps_lost[];
+extern gchar* speech_gps_lost[];
+extern gchar* speech_gps_good[];
+extern gchar* speech_kismet_found[];
+extern gchar* speech_message_received[];
+extern gchar* speech_morning[];
+extern gchar* speech_afternoon[];
+extern gchar* speech_evening[];
+extern gchar* speech_time_mins[];
+extern gchar* speech_time_hrs_mins[];
+extern gchar* speech_too_few_satellites[];
+extern gchar* speech_destination_is[];
+extern gchar* speech_front[];
+extern gchar* speech_front_right[];
+extern gchar* speech_right[];
+extern gchar* speech_behind_right[];
+extern gchar* speech_behind[];
+extern gchar* speech_behind_left[];
+extern gchar* speech_left[];
+extern gchar* speech_front_left[];
+extern gchar* speech_speed_mph[];
+extern gchar* speech_speed_kph[];
+extern gchar* speech_distance_to[];
+extern gchar* speech_yards[];
+extern gchar* speech_miles[];
+extern gchar* speech_meters[];
+extern gchar* speech_kilometers[];
+extern gchar* speech_one_kilometer[];
+extern gchar* speech_remaining_battery[];
+extern gchar* speech_found_access_point[];
+extern gchar* speech_access_closed[];
+extern gchar* speech_access_open[];
+
+
+#endif // GPSDRIVE_SPEECH_STRINGS_H
diff --git a/src/splash.c b/src/splash.c
new file mode 100644
index 0000000..8d4e35e
--- /dev/null
+++ b/src/splash.c
@@ -0,0 +1,654 @@
+/*******************************************************************
+
+Copyright (c) 2001-2006 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <config.h>
+#include "gpsdrive_config.h"
+#include <gpsdrive.h>
+#include <poi.h>
+#include <time.h>
+#include <speech_out.h>
+#include <icons.h>
+#include <splash.h>
+#include <speech_strings.h>
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+
+
+
+
+
+extern gint max_display_map;
+extern map_dir_struct *display_map;
+
+GtkWidget *splash_window;
+extern gint wpflag, displaymap_top, displaymap_map;
+extern gint scaleprefered;
+extern gint mydebug, defaultserver;
+extern gint setdefaultpos;
+extern gint usedgps;
+extern gdouble milesconv;
+extern gint satposmode, printoutsats;
+extern gint real_screen_x, real_screen_y, real_psize, real_smallmenu, lastnotebook;
+#define MAXDBNAME 30
+extern char dbhost[MAXDBNAME], dbuser[MAXDBNAME], dbpass[MAXDBNAME];
+extern char dbtable[MAXDBNAME], dbname[MAXDBNAME];
+extern double dbdistance;
+extern int dbusedist;
+extern gint earthmate, zone;
+extern int sockfd, showsid, storetz;
+
+extern coordinate_struct coords;
+#define KM2MILES 0.62137119
+
+
+gint
+remove_splash_cb (GtkWidget * widget, gpointer datum)
+{
+ gtk_widget_destroy (splash_window);
+ return (FALSE);
+}
+
+
+static void
+create_tags (GtkTextBuffer * buffer)
+{
+ gtk_text_buffer_create_tag (buffer, "heading",
+ "weight", PANGO_WEIGHT_BOLD,
+ "size", 12 * PANGO_SCALE, NULL);
+
+ gtk_text_buffer_create_tag (buffer, "italic",
+ "style", PANGO_STYLE_ITALIC, NULL);
+
+ gtk_text_buffer_create_tag (buffer, "bold",
+ "weight", PANGO_WEIGHT_BOLD, NULL);
+
+ gtk_text_buffer_create_tag (buffer, "big",
+ /* points times the PANGO_SCALE factor */
+ "size", 20 * PANGO_SCALE, NULL);
+
+
+ gtk_text_buffer_create_tag (buffer, "blue_foreground",
+ "foreground", "blue", NULL);
+
+ gtk_text_buffer_create_tag (buffer, "red_foreground",
+ "foreground", "red", NULL);
+
+ gtk_text_buffer_create_tag (buffer, "not_editable",
+ "editable", FALSE, NULL);
+
+ gtk_text_buffer_create_tag (buffer, "word_wrap",
+ "wrap_mode", GTK_WRAP_WORD, NULL);
+
+ gtk_text_buffer_create_tag (buffer, "center",
+ "justification", GTK_JUSTIFY_CENTER,
+ NULL);
+
+ gtk_text_buffer_create_tag (buffer, "underline",
+ "underline", PANGO_UNDERLINE_SINGLE,
+ NULL);
+
+}
+
+static void
+insert_text (GtkTextBuffer * buffer)
+{
+ GtkTextIter iter;
+ GtkTextIter start, end;
+ gchar *t1 =
+ _
+ ("Left mouse button : Set position (usefull in simulation mode)\n"
+ "Right mouse button : Set target directly on the map\n"
+ "Middle mouse button : Display position again\n"
+ "Shift left mouse button : smaller map\n"
+ "Shift right mouse button : larger map\n"
+ "Control left mouse button : Set a waypoint (mouse position) on the map\n"
+ "Control right mouse button: Set a waypoint at current position on the map\n\n");
+
+ gchar *t2 = _("j : switch to next waypoint in route mode\n"
+ "x : add waypoint at current position\n"
+ "y : add waypoint at mouse cursor position\n"
+ "n : switch on light for 60sec in nightmode\n"
+ "g : Toggle grid\n"
+ "f : Toggle friends display\n"
+ "w : Set Waypoint at current location without asking\n"
+ "p : Set Waypoint at current cursor position without asking\n"
+ "r : Add current cursor position to end of route\n"
+ "+ : Zoom in \n" "- : Zoom out\n");
+ gchar *t3 =
+ _("Press the underlined key together with the ALT-key.\n\n"
+ "You can move on the map by selecting the Position-Mode"
+ " in the menu. A blue rectangle shows this mode, you can set this cursor by clicking on the map."
+ " If you click on the border of the map (the outer 20%) then the map switches to the next area.\n\n"
+ "Suggestions welcome.\n\n");
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
+
+
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
+ _("GpsDrive v"), -1,
+ "heading", NULL);
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, VERSION, -1,
+ "heading", NULL);
+ gtk_text_buffer_insert (buffer, &iter,
+ _
+ ("\n\nYou find new versions on http://www.gpsdrive.de\n"),
+ -1);
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
+ _
+ ("Disclaimer: Please do not use for navigation. \n\n"),
+ -1, "red_foreground", NULL);
+
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
+ _
+ ("Please have a look into the manpage (man gpsdrive) for program details!"),
+ -1, "italic", NULL);
+ gtk_text_buffer_insert (buffer, &iter, "\n\n", -1);
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
+ _
+ ("Mouse control (clicking on the map):\n"),
+ -1, "blue_foreground",
+ NULL);
+
+ gtk_text_buffer_insert (buffer, &iter, "\n", -1);
+ gtk_text_buffer_insert (buffer, &iter, t1, -1);
+
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
+ _("Short cuts:\n"), -1,
+ "blue_foreground", NULL);
+ gtk_text_buffer_insert (buffer, &iter, "\n", -1);
+ gtk_text_buffer_insert (buffer, &iter, t2, -1);
+ gtk_text_buffer_insert (buffer, &iter, "\n", -1);
+
+ gtk_text_buffer_insert (buffer, &iter,
+ _("The other key shortcuts are marked as "),
+ -1);
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
+ _("underlined"), -1,
+ "underline", NULL);
+ gtk_text_buffer_insert (buffer, &iter,
+ _(" letters in the button text.\n"), -1);
+ gtk_text_buffer_insert (buffer, &iter, t3, -1);
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
+ _("Have a lot of fun!"), -1,
+ "big", NULL);
+ gtk_text_buffer_insert (buffer, &iter, "\n", -1);
+
+
+ /* Apply word_wrap tag to whole buffer */
+ gtk_text_buffer_get_bounds (buffer, &start, &end);
+ gtk_text_buffer_apply_tag_by_name (buffer, "not_editable", &start,
+ &end);
+ gtk_text_buffer_apply_tag_by_name (buffer, "word_wrap", &start, &end);
+
+
+}
+
+
+gint
+help_cb (GtkWidget * widget, guint datum)
+{
+ static GtkWidget *window = NULL;
+ GtkWidget *vpaned, *knopf;
+ GtkWidget *view1;
+ GtkWidget *sw, *vbox;
+ /* GtkTextBuffer *buffer; */
+ GtkTextBuffer *buffer;
+
+
+
+ window = gtk_dialog_new ();
+ gtk_window_set_default_size (GTK_WINDOW (window), 580, 570);
+
+ g_signal_connect (window, "destroy",
+ G_CALLBACK (gtk_widget_destroyed), &window);
+
+ gtk_window_set_title (GTK_WINDOW (window), "GpsDrive Help");
+ gtk_container_set_border_width (GTK_CONTAINER (window), 5);
+
+ vpaned = gtk_vpaned_new ();
+ gtk_container_set_border_width (GTK_CONTAINER (vpaned), 5);
+
+ vbox = gtk_vbox_new (FALSE, 3);
+ /* gtk_container_add (GTK_CONTAINER (window), vbox); */
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (window)->vbox), vbox, TRUE, TRUE, 2);
+
+ gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 3);
+
+ /* For convenience, we just use the autocreated buffer from
+ * the first text view; you could also create the buffer
+ * by itself with gtk_text_buffer_new(), then later create
+ * a view widget.
+ */
+ view1 = gtk_text_view_new ();
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view1));
+ /* view2 = gtk_text_view_new_with_buffer (buffer); */
+
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ gtk_paned_add1 (GTK_PANED (vpaned), sw);
+
+ gtk_container_add (GTK_CONTAINER (sw), view1);
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ /* gtk_paned_add2 (GTK_PANED (vpaned), sw); */
+
+ /* gtk_container_add (GTK_CONTAINER (sw), view2); */
+
+
+ create_tags (buffer);
+ insert_text (buffer);
+
+
+
+ knopf = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
+ gtk_signal_connect_object (GTK_OBJECT (knopf), "clicked",
+ GTK_SIGNAL_FUNC
+ (gtk_widget_destroy), GTK_OBJECT (window));
+ /* gtk_box_pack_start (GTK_BOX (vbox), knopf, FALSE, FALSE, 5); */
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (window)->action_area),
+ knopf, TRUE, TRUE, 2);
+
+
+ gtk_widget_show_all (vpaned);
+
+ gtk_widget_show_all (window);
+
+ return TRUE;
+
+}
+
+
+gint
+message_cb (char *msgid, char *name, char *text, int fs)
+{
+ static GtkWidget *window = NULL;
+ GtkWidget *vpaned, *knopf2;
+ GtkWidget *view1;
+ GtkWidget *sw, *knopf, *vbox;
+ /* GtkTextBuffer *buffer; */
+ GtkTextBuffer *buffer;
+ GtkTextIter iter;
+ GtkTextIter start, end;
+ gchar titlestr[60];
+ gchar buf[MAXMESG];
+
+ window = gtk_dialog_new ();
+ gtk_window_set_default_size (GTK_WINDOW (window), 320, 240);
+
+ g_signal_connect (window, "destroy",
+ G_CALLBACK (gtk_widget_destroyed), &window);
+
+ g_snprintf (titlestr, sizeof (titlestr), "%s %s", _("From:"), name);
+ gtk_window_set_title (GTK_WINDOW (window), titlestr);
+ gtk_container_set_border_width (GTK_CONTAINER (window), 0);
+
+ vpaned = gtk_vpaned_new ();
+ gtk_container_set_border_width (GTK_CONTAINER (vpaned), 5);
+
+ vbox = gtk_vbox_new (FALSE, 3);
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (window)->vbox), vbox, TRUE, TRUE, 2);
+
+
+ gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 3);
+
+
+ knopf = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
+ gtk_signal_connect_object (GTK_OBJECT (knopf), "clicked",
+ GTK_SIGNAL_FUNC
+ (gtk_widget_destroy), GTK_OBJECT (window));
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (window)->action_area),
+ knopf, TRUE, TRUE, 2);
+
+
+ /* For convenience, we just use the autocreated buffer from
+ * the first text view; you could also create the buffer
+ * by itself with gtk_text_buffer_new(), then later create
+ * a view widget.
+ */
+ view1 = gtk_text_view_new ();
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view1));
+ /* view2 = gtk_text_view_new_with_buffer (buffer); */
+
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ gtk_paned_add1 (GTK_PANED (vpaned), sw);
+
+ gtk_container_add (GTK_CONTAINER (sw), view1);
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ /* reminder_create_tags (buffer); */
+ /* reminder_insert_text (buffer); */
+ /* attach_widgets (GTK_TEXT_VIEW (view1)); */
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
+ gtk_text_buffer_create_tag (buffer, "word_wrap",
+ "wrap_mode", GTK_WRAP_WORD, NULL);
+ gtk_text_buffer_create_tag (buffer, "heading",
+ "weight", PANGO_WEIGHT_BOLD,
+ "size", 10 * PANGO_SCALE, NULL);
+
+ gtk_text_buffer_create_tag (buffer, "blue_foreground",
+ "foreground", "blue", "weight",
+ PANGO_WEIGHT_BOLD, "size",
+ 10 * PANGO_SCALE, NULL);
+ gtk_text_buffer_create_tag (buffer, "red_foreground", "foreground",
+ "red", "weight", PANGO_WEIGHT_BOLD,
+ "size", 10 * PANGO_SCALE, NULL);
+ gtk_text_buffer_create_tag (buffer, "center", "justification",
+ GTK_JUSTIFY_CENTER, NULL);
+ if (fs)
+ {
+ g_snprintf (buf, sizeof (buf),
+ _
+ ("You received a message from\nthe friends server (%s)\n"),
+ name);
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, buf,
+ -1, "heading",
+ "center",
+ "red_foreground",
+ NULL);
+ }
+ else
+ {
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
+ _
+ ("You received a message through the friends server from:\n"),
+ -1, "heading",
+ "center", NULL);
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, name,
+ -1,
+ "blue_foreground",
+ "center", NULL);
+ }
+ gtk_text_buffer_insert (buffer, &iter, "\n\n", -1);
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
+ _
+ ("Message text:\n"),
+ -1, "heading", NULL);
+ gtk_text_buffer_insert (buffer, &iter, text, -1);
+ gtk_text_buffer_get_bounds (buffer, &start, &end);
+ gtk_text_buffer_apply_tag_by_name (buffer, "word_wrap", &start, &end);
+ /* gtk_text_iter_can_insert (&iter, FALSE); */
+
+ knopf2 = gtk_button_new_from_stock (GTK_STOCK_OK);
+
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw),
+ knopf2);
+
+
+ gtk_widget_show_all (vpaned);
+
+ gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
+
+ gtk_widget_show_all (window);
+ g_snprintf (buf, sizeof (buf), "ACK: %s", msgid);
+ if ( mydebug > 10 )
+ fprintf (stderr, "\nsending to %s:\n%s\n", local_config.friends_serverip,
+ buf);
+ sockfd = -1;
+ friends_sendmsg (local_config.friends_serverip, buf);
+ gdk_beep ();
+
+ g_snprintf( buf, sizeof(buf), speech_message_received[voicelang], name );
+ speech_out_speek (buf);
+
+ return TRUE;
+}
+
+
+
+GtkWidget *
+getPixmapFromFile (GtkWidget * widget, const gchar * filename)
+{
+ GtkWidget *pixmap;
+ GdkColormap *colormap;
+ GdkPixmap *gdkpixmap;
+ GdkBitmap *mask;
+
+ if (!filename || !filename[0])
+ return NULL;
+
+ colormap = gtk_widget_get_colormap (widget);
+ gdkpixmap =
+ gdk_pixmap_colormap_create_from_xpm (NULL, colormap, &mask,
+ NULL, filename);
+ if (gdkpixmap == NULL)
+ {
+ printf ("**** couldn't create pixmap from file: '%s'\n",
+ filename);
+ return NULL;
+ }
+
+ pixmap = gtk_pixmap_new (gdkpixmap, mask);
+ gdk_pixmap_unref (gdkpixmap);
+ gdk_bitmap_unref (mask);
+ return pixmap;
+}
+
+
+GtkWidget *
+getPixmapFromXpm (GtkWidget * widget, gchar ** xpmname)
+{
+ GtkWidget *pixmap;
+ GdkColormap *colormap;
+ GdkPixmap *gdkpixmap;
+ GdkBitmap *mask;
+
+ if (!xpmname || !xpmname[0])
+ return NULL;
+
+ colormap = gtk_widget_get_colormap (widget);
+ gdkpixmap =
+ gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask,
+ NULL, xpmname);
+ if (gdkpixmap == NULL)
+ {
+ printf ("**** couldn't create pixmap from xpm: '%s'\n",
+ *xpmname);
+ return NULL;
+ }
+
+ pixmap = gtk_pixmap_new (gdkpixmap, mask);
+ gdk_pixmap_unref (gdkpixmap);
+ gdk_bitmap_unref (mask);
+ return pixmap;
+}
+
+void
+show_splash (void)
+{
+ gchar xpmfile[400];
+ GtkWidget *pixmap = NULL;
+
+ gtk_window_set_auto_startup_notification (FALSE);
+
+ g_snprintf (xpmfile, sizeof (xpmfile), "%s/gpsdrive/%s", DATADIR,
+ "pixmaps/gpsdrivesplash.png");
+
+ splash_window = gtk_window_new (GTK_WINDOW_POPUP);
+
+ gtk_window_set_type_hint (GTK_WINDOW (splash_window),
+ GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);
+ gtk_window_set_title (GTK_WINDOW (splash_window),
+ _("Starting GPS Drive"));
+ gtk_window_set_position (GTK_WINDOW (splash_window),
+ GTK_WIN_POS_CENTER);
+
+ gtk_widget_realize (splash_window);
+ gdk_window_set_decorations (GTK_WIDGET (splash_window)->window, 0);
+
+ /* get image */
+ pixmap = getPixmapFromFile (splash_window, xpmfile);
+
+ if (pixmap != NULL)
+ {
+ gtk_pixmap_set (GTK_PIXMAP (pixmap),
+ GTK_PIXMAP (pixmap)->pixmap,
+ GTK_PIXMAP (pixmap)->mask);
+ }
+ else
+ {
+ fprintf (stderr,
+ _
+ ("\nWarning: unable to open splash picture\nPlease "
+ "install the program as root with:\nmake install\n\n"));
+ return;
+ }
+ /* gtk_widget_show (splash_window); */
+
+ gtk_container_add (GTK_CONTAINER (splash_window), pixmap);
+ gtk_widget_shape_combine_mask (splash_window,
+ GTK_PIXMAP (pixmap)->mask, 0, 0);
+
+ gtk_widget_show (pixmap);
+ gtk_widget_show (splash_window);
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+
+ gtk_timeout_add (3000, (GtkFunction) remove_splash_cb, NULL);
+}
+
+
+gint
+about_cb (GtkWidget * widget, guint datum)
+{
+ GtkAboutDialog *about_window;
+ gchar xpmfile[400];
+ GdkPixbuf *pixmap = NULL;
+
+ const gchar *authors[] =
+ {
+ "Aart Koelewijn <aart@mtack.xs4all.nl>",
+ "Belgabor <belgabor@gmx.de>",
+ "Blake Swadling <blake@swadling.com>",
+ "Christoph Metz <loom@mopper.de>",
+ "Chuck Gantz <chuck.gantz@globalstar.com>",
+ "Dan Egnor <egnor@ofb.net>",
+ "Daniel Hiepler <rigid@akatash.de>",
+ "Darazs Attila <zumi@freestart.hu>",
+ "Fritz Ganter <ganter@ganter.at>",
+ "Guenther Meyer <d.s.e@sordidmusic.com>",
+ "J.D. Schmidt <jdsmobile@gmail.com>",
+ "Joerg Ostertag <gpsdrive@ostertag.name>" ,
+ "Jan-Benedict Glaw <jbglaw@lug-owl.de>",
+ "John Hay <jhay@icomtek.csir.co.za>",
+ "Johnny Cache <johnycsh@hick.org>",
+ "Miguel Angelo Rozsas <miguel@rozsas.xx.nom.br>",
+ "Mike Auty",
+ "Oddgeir Kvien <oddgeir@oddgeirkvien.com>",
+ "Oliver Kuehlert <Oliver.Kuehlert@mpi-hd.mpg.de>",
+ "Olli Salonen <olli@cabbala.net>",
+ "Philippe De Swert",
+ "Richard Scheffenegger <rscheff@chello.at>",
+ "Rob Stewart <rob@groupboard.com>",
+ "Russell Harding <hardingr@billingside.com>",
+ "Russell Mirov <russell.mirov@sun.com>",
+ "Wilfried Hemp <Wilfried.Hemp@t-online.de>",
+ "<molter@gufi.org>",
+ "<pdana@mail.utexas.edu>",
+ "<timecop@japan.co.jp>",
+ "<wulf@netbsd.org>",
+ NULL
+ };
+
+ about_window = GTK_ABOUT_DIALOG (gtk_about_dialog_new ());
+ gtk_window_set_position (GTK_WINDOW (about_window), GTK_WIN_POS_CENTER);
+
+ gtk_about_dialog_set_version (about_window, VERSION);
+ gtk_about_dialog_set_copyright (about_window, "Copyright (c) 2001-2006 Fritz Ganter <ganter@ganter.at>");
+ gtk_about_dialog_set_website (about_window, "http://www.gpsdrive.de/");
+ gtk_about_dialog_set_authors (about_window, authors);
+ gtk_about_dialog_set_translator_credits (about_window, _("translator-credits"));
+ gtk_about_dialog_set_comments (about_window,
+ _("GpsDrive is a car (bike, ship, plane) navigation system, that displays your position provided from a GPS receiver on a zoomable map and much more..."));
+
+ gtk_about_dialog_set_license (about_window,
+ _("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.\n\nGpsDrive uses data from the OpenStreetMap Project (http://www.openstreetmap.org), which is freely available under the terms of the Creative Commons Attribution-ShareAlike 2.0 license."));
+ gtk_about_dialog_set_wrap_license (about_window, TRUE);
+
+ g_snprintf (xpmfile, sizeof (xpmfile), "%s/gpsdrive/%s", DATADIR, "pixmaps/gpsdrivelogo.png");
+ pixmap = gdk_pixbuf_new_from_file (xpmfile, NULL);
+ if (pixmap == NULL)
+ {
+ fprintf (stderr, _("\nWarning: unable to open logo picture\nPlease install the program as root with:\nmake install\n\n"));
+ return TRUE;
+ }
+ gtk_about_dialog_set_logo (about_window, pixmap);
+
+ gtk_widget_show_all (GTK_WIDGET (about_window));
+ g_signal_connect (GTK_WIDGET (about_window), "response", G_CALLBACK
+ (gtk_widget_destroy), NULL);
+ return TRUE;
+}
+
+
+/* writes time and position to /tmp/gpsdrivepos */
+void
+signalposreq ()
+{
+ FILE *f;
+ time_t t;
+ struct tm *ts;
+
+ f = fopen ("/tmp/gpsdrivepos", "w");
+ if (f == NULL)
+ {
+ perror ("/tmp/gpsdrivepos");
+ return;
+ }
+ time (&t);
+ ts = localtime (&t);
+ fprintf (f, asctime (ts));
+ fprintf (f, "POS %f %f\n", coords.current_lat, coords.current_lon);
+ fclose (f);
+}
diff --git a/src/splash.h b/src/splash.h
new file mode 100644
index 0000000..646e04d
--- /dev/null
+++ b/src/splash.h
@@ -0,0 +1,40 @@
+/*******************************************************************
+
+Copyright (c) 2001-2006 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+#ifndef GPSDRIVE_SPLASH_H
+#define GPSDRIVE_SPLASH_H
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <config.h>
+#include <gmodule.h>
+#include <gdk/gdktypes.h>
+#include "gtk/gtk.h"
+#include "gpsproto.h"
+
+gint remove_splash_cb (GtkWidget *widget, gpointer datum);
+
+#endif /* GPSDRIVE_SPLASH_H */
diff --git a/src/track.c b/src/track.c
new file mode 100644
index 0000000..fdbbb00
--- /dev/null
+++ b/src/track.c
@@ -0,0 +1,357 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+/*
+ * Track support module: display, disk loading/saving.
+ * Based in Files track0001.sav
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include "gpsdrive.h"
+#include "gpsdrive_config.h"
+#include "track.h"
+#include "config.h"
+#include "gui.h"
+#include "main_gui.h"
+
+extern gint mydebug;
+extern gint maploaded;
+extern glong tracknr, tracklimit, trackcoordlimit;
+glong trackcoordnr, tracklimit, trackcoordlimit,old_trackcoordnr;
+extern trackcoordstruct *trackcoord;
+extern GdkSegment *track;
+extern GdkSegment *trackshadow;
+
+extern wpstruct *routelist;
+extern GdkColor blue;
+extern gint isnight, disableisnight;
+extern color_struct colors;
+extern currentstatus_struct current;
+
+extern GdkGC *kontext_map;
+
+/* ----------------------------------------------------------------------------- */
+/* if zoom, xoff, yoff or map are changed */
+void
+rebuildtracklist (void)
+{
+ gdouble posxdest, posydest;
+ gdouble posxsource, posysource;
+ posxsource = -1000;
+ posysource = -1000;
+ gint i, so;
+
+ if (!maploaded)
+ return;
+
+ if (!local_config.showtrack)
+ return;
+ if (current.importactive)
+ return;
+
+ tracknr = 0;
+ for (i = 0; i < trackcoordnr; i++)
+ {
+ calcxy (&posxdest, &posydest, (trackcoord + i)->lon,
+ (trackcoord + i)->lat, current.zoom);
+
+ if ((trackcoord + i)->lon > 1000.0) /* Track Break ? */
+ {
+ posxsource = posysource = -1000;
+ }
+ else
+ {
+ if (((posxdest > -50) && (posxdest < (SCREEN_X + 50))
+ && (posydest > -50)
+ && (posydest < (SCREEN_Y + 50))
+ && (posxsource > -50)
+ && (posxsource < (SCREEN_X + 50))
+ && (posysource > -50) && (posysource < (SCREEN_Y + 50))))
+ {
+ if ((posxdest != posxsource) || (posydest != posysource))
+ {
+ /* so=(int)(((trackcoord + i)->alt))>>5; */
+ so = SHADOWOFFSET;
+ /*
+ * printf("x: %8f %8f Y:%.6f %.6f \t",
+ * posxsource,posxdest,
+ * posysource,posydest);
+ * printf("%.6f, %.6f (%.6f)\n",
+ * (trackcoord + i)->lon,
+ * (trackcoord + i)->lat, current.zoom);
+ */
+ (track + tracknr)->x1 = posxsource;
+ (track + tracknr)->x2 = posxdest;
+ (track + tracknr)->y1 = posysource;
+ (track + tracknr)->y2 = posydest;
+ (trackshadow + tracknr)->x1 = posxsource + so;
+ (trackshadow + tracknr)->x2 = posxdest + so;
+ (trackshadow + tracknr)->y1 = posysource + so;
+ (trackshadow + tracknr)->y2 = posydest + so;
+
+ tracknr += 1;
+ }
+ }
+ posxsource = posxdest;
+ posysource = posydest;
+ }
+ }
+}
+
+
+
+/* ------------------------------------------------------------------------- *
+ * draw track on image
+ */
+void
+drawtracks (void)
+{
+ gint t=0;
+
+ // if (!maploaded)
+ // return;
+ if (!local_config.showtrack)
+ return;
+ if (current.importactive)
+ return;
+
+ t = 2 * (tracknr >> 1) - 1;
+ /* t=tracknr; */
+ if (t < 1)
+ return;
+
+ gdk_gc_set_line_attributes (kontext_map, 4, 0, 0, 0);
+ if (local_config.showshadow) {
+ gdk_gc_set_foreground (kontext_map, &colors.shadow);
+ gdk_gc_set_function (kontext_map, GDK_AND);
+ gdk_draw_segments (drawable, kontext_map, (GdkSegment *) trackshadow, t);
+ gdk_gc_set_function (kontext_map, GDK_COPY);
+ }
+ if ((!disableisnight) &&
+ ((local_config.nightmode == NIGHT_ON) ||
+ ((local_config.nightmode == NIGHT_AUTO) && isnight)))
+ gdk_gc_set_foreground (kontext_map, &colors.red);
+ else
+ gdk_gc_set_foreground (kontext_map, &colors.track);
+
+ gdk_draw_segments (drawable, kontext_map, (GdkSegment *) track, t);
+
+ return;
+}
+
+
+/* ----------------------------------------------------------------------------- */
+/* stores the track into a file, if argument testname is true, no saving is
+ done, only savetrackfn is set
+ mode=0: test Filename
+ mode=1: write actual track
+ mode=2: write actual track and append to all_track.sav
+*/
+void
+savetrackfile (gint mode)
+{
+ struct stat sbuf;
+ gchar buff[1024];
+ gint e, i;
+ gchar mappath[400], lat[30], alt[30], lon[30];
+ FILE *st;
+
+ if ( mydebug > 11 )
+ g_print ("savetrack(%d)\n", mode);
+
+ if (mode == 0)
+ {
+ i = 0;
+ do
+ {
+ g_snprintf (buff, sizeof (buff), "%strack%04d.sav",
+ local_config.dir_home, i++);
+ e = stat (buff, &sbuf);
+ }
+ while (e == 0);
+ g_strlcpy (savetrackfn, g_basename (buff), sizeof (savetrackfn));
+ return;
+ }
+
+ /* save in new file */
+ g_strlcpy (mappath, local_config.dir_home, sizeof (mappath));
+ g_strlcat (mappath, savetrackfn, sizeof (mappath));
+ st = fopen (mappath, "w");
+ if (st == NULL)
+ {
+ perror (mappath);
+ return;
+ }
+
+ for (i = 0; i < trackcoordnr; i++)
+ {
+ g_snprintf (lat, sizeof (lat), "%10.6f", (trackcoord + i)->lat);
+ g_strdelimit (lat, ",", '.');
+ g_snprintf (lon, sizeof (lon), "%10.6f", (trackcoord + i)->lon);
+ g_strdelimit (lon, ",", '.');
+ g_snprintf (alt, sizeof (alt), "%10.0f", (trackcoord + i)->alt);
+
+ fprintf (st, "%s %s %s %s\n", lat, lon, alt,
+ (trackcoord + i)->postime);
+ }
+ fclose (st);
+
+ if (mode == 1)
+ return;
+
+ /* append to existing backup file */
+ g_strlcpy (mappath, local_config.dir_home, sizeof (mappath));
+ g_strlcat (mappath, "track-ALL.sav", sizeof (mappath));
+ st = fopen (mappath, "a");
+ if (st == NULL)
+ {
+ perror (mappath);
+ return;
+ }
+
+ for (i = 0; i < trackcoordnr; i++)
+ {
+ g_snprintf (lat, sizeof (lat), "%10.6f", (trackcoord + i)->lat);
+ g_strdelimit (lat, ",", '.');
+ g_snprintf (lon, sizeof (lon), "%10.6f", (trackcoord + i)->lon);
+ g_strdelimit (lon, ",", '.');
+ g_snprintf (alt, sizeof (alt), "%10.0f", (trackcoord + i)->alt);
+
+ fprintf (st, "%s %s %s %s\n", lat, lon, alt,
+ (trackcoord + i)->postime);
+ }
+ fclose (st);
+
+}
+
+/* *****************************************************************************
+ * this routine is called whenever a new position is processed. Every
+ * 30 seconds it writes the accumulated positions to a file "incremental.sav"
+ * so that a pretty recent track is available even if the application or
+ * system crashes. It is expected that the user will manually delete the
+ * file prior to a trip/hike. It will only write to the file if the
+ * "save_track" option is selected. If gpsdrive has been running for
+ * quite a while without "save_track" selected, this routine will capture
+ * the entire track up to that point.
+*/
+
+void do_incremental_save() {
+ gint i;
+ gchar mappath[400], lat[30], alt[30], lon[30];
+ FILE *st;
+
+ if ((trackcoordnr % 30) == 29) { /* RNM: append to existing incremental file every 30 seconds */
+ g_strlcpy (mappath, local_config.dir_home, sizeof (mappath));
+ g_strlcat (mappath, "incremental.sav", sizeof(mappath));
+ st = fopen (mappath, "a");
+ if (st == NULL) {
+ st = fopen (mappath, "w");
+ if (st == NULL) {
+ perror (mappath);
+ printf("Can't open or create incremental.sav\n");
+ return;
+ }
+ else printf("Creating incremental.sav\n");
+ }
+
+ for (i = old_trackcoordnr; i < trackcoordnr; i++) {
+ g_snprintf (lat, sizeof (lat), "%10.6f", (trackcoord + i)->lat);
+ g_strdelimit (lat, ",", '.');
+ g_snprintf (lon, sizeof (lon), "%10.6f", (trackcoord + i)->lon);
+ g_strdelimit (lon, ",", '.');
+ g_snprintf (alt, sizeof (alt), "%10.0f", (trackcoord + i)->alt);
+
+ fprintf (st, "%s %s %s %s\n", lat, lon, alt, (trackcoord + i)->postime);
+ }
+ fclose (st);
+ old_trackcoordnr = trackcoordnr ;
+ }
+}
+
+
+/* *****************************************************************************
+ */
+gint
+gettrackfile (GtkWidget * widget, gpointer datum)
+{
+ G_CONST_RETURN gchar *fn;
+ gchar buf[520], lat[30], lon[30], alt[30], str[30];
+ FILE *st;
+ gint i;
+
+ fn = gtk_file_chooser_get_filename (datum);
+ st = fopen (fn, "r");
+ if (st == NULL)
+ {
+ perror (fn);
+ return TRUE;
+ }
+ g_free (trackcoord);
+ g_free (track);
+ g_free (trackshadow);
+ track = g_new (GdkSegment, 100000);
+ trackshadow = g_new (GdkSegment, 100000);
+ tracknr = 0;
+ tracklimit = 100000;
+ trackcoord = g_new (trackcoordstruct, 100000);
+ trackcoordnr = 0;
+ trackcoordlimit = 100000;
+ i = 0;
+ while (fgets (buf, 512, st))
+ {
+ sscanf (buf, "%s %s %s %[^\n]", lat, lon, alt, str);
+ g_strlcpy ((trackcoord + i)->postime, str, 30);
+ (trackcoord + i)->lat = g_strtod (lat, NULL);
+ (trackcoord + i)->lon = g_strtod (lon, NULL);
+ (trackcoord + i)->alt = g_strtod (alt, NULL);
+ i++;
+ trackcoordnr++;
+
+ if ((trackcoordnr * 2) > (trackcoordlimit - 1000))
+ {
+ trackcoord =
+ g_renew (trackcoordstruct, trackcoord, trackcoordlimit + 100000);
+ trackcoordlimit += 100000;
+ track = g_renew (GdkSegment, track, tracklimit + 100000);
+ trackshadow =
+ g_renew (GdkSegment, trackshadow, tracklimit + 100000);
+ tracklimit += 100000;
+ }
+
+
+ }
+ (trackcoord + i)->lat = 1001.0;
+ (trackcoord + i)->lon = 1001.0;
+
+ trackcoordnr++;
+
+ rebuildtracklist ();
+ fclose (st);
+ gtk_widget_destroy (datum);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (track_bt), TRUE);
+
+ return TRUE;
+}
diff --git a/src/track.h b/src/track.h
new file mode 100644
index 0000000..f91f5bb
--- /dev/null
+++ b/src/track.h
@@ -0,0 +1,51 @@
+/***********************************************************************
+
+Copyright (c) 2001,2002 Fritz Ganter <ganter@ganter.at>
+
+Website: www.kraftvoll.at/software
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+#ifndef GPSDRIVE_TRACK_H
+#define GPSDRIVE_TRACK_H
+
+/*
+ * See track.c for details.
+ */
+
+#include <gtk/gtk.h>
+
+
+
+typedef struct
+{
+ gdouble lon;
+ gdouble lat;
+ gdouble alt;
+ gchar postime[30];
+}
+trackcoordstruct;
+
+void savetrackfile (gint testname);
+void rebuildtracklist (void);
+void drawtracks (void);
+gint gettrackfile (GtkWidget *widget, gpointer datum);
+
+
+#endif /* GPSDRIVE_TRACK_H */
diff --git a/src/unit_test.c b/src/unit_test.c
new file mode 100644
index 0000000..4dff1c1
--- /dev/null
+++ b/src/unit_test.c
@@ -0,0 +1,887 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ *********************************************************************
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <math.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gpsdrive.h>
+#include <config.h>
+#include <math.h>
+#include "speech_out.h"
+#include "speech_strings.h"
+#include "battery.h"
+#include "nmea_handler.h"
+#include "gui.h"
+
+gint errors = 0;
+
+extern gint mydebug;
+extern coordinate_struct coords;
+//extern gint mapistopo;
+extern glong mapscale;
+extern gdouble pixelfact;
+extern int usesql;
+extern gchar dir_proc[200];
+extern gchar cputempstring[20], batstring[20];
+extern int didrootcheck;
+extern int newdata;
+extern char serialdata[4096];
+extern gint haveRMCsentence;
+extern currentstatus_struct current;
+
+/* ******************************************************************
+ * This Function tests internal routines of gpsdrive
+ */
+
+void set_unittest_timer (void);
+
+/* ******************************************************************
+ * write a file with content in one function call
+ */
+void
+write_file (gchar * filename, gchar * content)
+{
+ FILE *fp;
+ fp = fopen (filename, "w");
+ if (fp == NULL)
+ {
+ fprintf (stderr, "!!! ERROR: Error opening %s\n", filename);
+ perror ("ERROR");
+ errors++;
+ }
+
+ fprintf (fp, "%s", content);
+ fclose (fp);
+}
+
+
+/* ******************************************************************
+ * Test the nmea parser, simply check if the right position is set after parsing
+ */
+gint unit_test_nmea()
+{
+ gint errors = 0;
+ if (mydebug > 0)
+ printf ("\n");
+ printf ("Testing nmea handler\n");
+
+ typedef struct
+ {
+ gdouble should_lat, should_lon;
+ char *nmea_string;
+ } test_struct;
+ test_struct test_array[] = {
+ /* nothing happens (lat/lon) with these nmea sentences
+ {55.6403, 12.6378, "$GPGSV,3,1,10,29,66,286,43,28,57,126,35,26,57,290,45,08,51,073,29*7E" },
+ {55.6403, 12.6378, "$GPGSV,3,2,10,10,34,201,40,27,25,076,00,19,14,033,00,21,12,305,27*75" },
+ {55.6403, 12.6378, "$GPGSV,3,3,10,15,11,329,00,18,11,325,00*79" },
+ {55.6403, 12.6378, "$GPGSA,A,3,10,28,26,29,08,21,,,,,,,2.5,1.4,2.0*3D" },
+ {55.6403, 12.6378, "$GPGSA,A,3,10,28,26,29,08,21,,,,,,,2.5,1.4,2.0*3D" },
+ */
+ /* unsuported sentence for nmea reading
+ {55.64039333333, 12.63781833333, "$GPGLL,5538.4236,N,01238.2691,E,122041.481,A*31" },
+ {-55.640395, 12.63783, "$GPGLL,5538.4237,S,01238.2698,E,122040.481,A*38" },
+ */
+
+ { 55.640393333, 12.637818333, "$GPRMC,122041.481,A,5538.4236,N,01238.2691,E,0.000000,214.43,010806,,*09" },
+ { 55.640395, -12.63783, "$GPRMC,122040.481,A,5538.4237,N,01238.2698,W,0.000000,214.43,010806,,*12" },
+ { 55.640395, 12.63783, "$GPRMC,122040.481,A,5538.4237,N,01238.2698,E,0.000000,214.43,010806,,*00" },
+ {-55.640395, -12.63783, "$GPRMC,122040.481,A,5538.4237,S,01238.2698,W,0.000000,214.43,010806,,*0F" },
+ {-55.640395, 12.63783, "$GPRMC,122040.481,A,5538.4237,S,01238.2698,E,0.000000,214.43,010806,,*1D" },
+
+ { 52.299051666, 9.638140, "$GPRMC,165318.993,A,5217.9431,N,00938.2884,E,000.0,000.0,010806,001.1,E*66"},
+
+ { 55.640393333, 12.637818333, "$GPGGA,122041.481,5538.4236,N,01238.2691,E,2,06,1.4,40.4,M,41.4,M,1.1,0000*46" },
+ { 55.640395, 12.63783, "$GPGGA,122040.481,5538.4237,N,01238.2698,E,2,06,1.4,39.8,M,41.4,M,1.1,0000*4D" },
+ { 48.117500,11.595000, "$GPGGA,125500.481,4807.0500,N,01135.7000,E,2,06,1.4,39.8,M,41.4,M,1.1,0000*40" },
+ {-99,-99,""},
+ };
+ gint i;
+ gdouble diff;
+ for (i = 0; test_array[i].should_lat != -99; i++)
+ {
+ haveRMCsentence=FALSE;
+ newdata=TRUE;
+ gui_status.posmode=FALSE;
+ //strncpy ( serialdata, test_array[i].nmea_string,sizeof (serialdata));
+ get_position_data_cb(NULL,NULL);
+
+ int ok=TRUE;
+
+ diff = fabs(coords.current_lat - test_array[i].should_lat);
+ if ( diff > 0.000001 )
+ {
+ printf ("!!!! ERROR wrong lat diff: %f\n",diff);
+ ok=FALSE;
+ }
+ diff = fabs(coords.current_lon - test_array[i].should_lon);
+ if ( diff >0.000001 )
+ {
+ printf ("!!!! ERROR wrong lon diff: %f\n",diff);
+ ok=FALSE;
+ }
+ if ( ! ok ) {
+ printf ("!!!! ERROR is %f,%f\n"
+ " should %f,%f\n"
+ " nmea: %s\n",
+ coords.current_lat,coords.current_lon,
+ test_array[i].should_lat,test_array[i].should_lon,
+ test_array[i].nmea_string
+ );
+ errors++;
+ } else {
+ if ( mydebug>1 )
+ printf ("parsing OK; values: %f,%f\t"
+ " nmea: %s\n",
+ coords.current_lat,coords.current_lon,
+ test_array[i].nmea_string
+ );
+
+ }
+ }
+
+ return errors;
+}
+
+/* ******************************************************************
+ * Unit Tests
+ * in this function some of the internal functions of gpsdrive are called
+ * with known parameters. The results then are checked to what is expected.
+ * If a non expected/wrong result is detected we exit with -1
+ *
+ * This way I hope we can reduce the number of errors comming back after
+ * already having been fixed.
+ */
+void
+unit_test (void)
+{
+
+ printf ("\n");
+ printf ("#############################################################################\n");
+ printf ("#############################################################################\n");
+ printf ("#############################################################################\n");
+ printf ("\n");
+ printf ("GpsDrive Started to do UNIT Tests\n");
+ printf ("\n");
+ printf ("#############################################################################\n");
+ printf ("#############################################################################\n");
+ printf ("#############################################################################\n");
+ printf ("\n");
+
+
+ // ------------------------------------------------------------------
+ {
+ if (mydebug > 0)
+ printf ("\n");
+ printf ("Testing line_crosses_rectangle(lx/y,lx/y, rx/y,rx/y)\n");
+
+ typedef struct
+ {
+ gint result;
+ gdouble x1, y1, x2, y2;
+ gdouble xr1, ry1, rx2, ry2;
+ } test_struct;
+ test_struct test_array[] = {
+ {1, 2, 2, 15, 6, 4, 3, 10, 5},
+ {1, 2, 2, 15, 6, 4, 3, 10, 5},
+ {1, 6, 4, 5, 6, 4, 3, 10, 5},
+ {1, 8, 2, 12, 6, 4, 3, 10, 5},
+ {1, 6, 2, 7, 7, 4, 3, 10, 5},
+ {0, 8, 6, 12, 8, 4, 3, 10, 5},
+ {0, 12, 4, 15, 4, 4, 3, 10, 5},
+ {0, 5, 6, 5, 8, 4, 3, 10, 5},
+
+ {-99, 0, 0, 0, 0, 0, 0, 0, 0}
+ };
+
+ gint i;
+ for (i = 0; test_array[i].result != -99; i++)
+ {
+ gint erg = line_crosses_rectangle (test_array[i].x1, test_array[i].y1,
+ test_array[i].x2, test_array[i].y2,
+ test_array[i].xr1,
+ test_array[i].ry1,
+ test_array[i].rx2,
+ test_array[i].ry2);
+ if (erg == test_array[i].result)
+ {
+ if (mydebug > 0)
+ fprintf (stderr,
+ " %d: line_crosses_rectangle(%g,%g %g,%g, %g,%g %g,%g) ==> %d\n",
+ i,
+ test_array[i].x1, test_array[i].y1,
+ test_array[i].x2, test_array[i].y2,
+ test_array[i].xr1, test_array[i].ry1,
+ test_array[i].rx2, test_array[i].ry2, erg);
+ }
+ else
+ {
+ printf ("!!!! ERROR\n");
+ fprintf (stderr,
+ " %d: line_crosses_rectangle(%g,%g %g,%g, %g,%g %g,%g)"
+ " ==> %d "
+ "should be %d\n",
+ i,
+ test_array[i].x1, test_array[i].y1,
+ test_array[i].x2, test_array[i].y2,
+ test_array[i].xr1, test_array[i].ry1,
+ test_array[i].rx2, test_array[i].ry2,
+ erg, test_array[i].result);
+ errors++;
+ }
+ }
+
+ }
+
+ // ------------------------------------------------------------------
+ {
+ if (mydebug > 0)
+ printf ("\n");
+ printf ("Testing distance_line_point()\n");
+
+ typedef struct
+ {
+ gdouble dist, x1, y1, x2, y2, xp, yp;
+ } test_struct;
+ test_struct test_array[] = {
+ // dist, line Point
+ {0.0, 0.0, 0.0, 2.0, 0.0, 1.0, 0.0},
+ {1.0, 0.0, 0.0, 2.0, 0.0, 1.0, 1.0},
+ {1.0, 0.0, 0.0, 2.0, 0.0, 1.0, -1.0},
+ {1.0, 2.0, 0.0, 0.0, 0.0, 1.0, 1.0},
+ {1.0, 2.0, 0.0, 0.0, 0.0, 1.0, -1.0},
+
+ {sqrt (2 * 2 + 1 * 1), 2.0, 2.0, 6.0, 4.0, 8.0, 5.0},
+ {sqrt (2 * 2 + 1 * 1), 2.0, 2.0, 6.0, 4.0, 0.0, 1.0},
+
+ {sqrt (2 * 2 + 1 * 1), 6.0, 4.0, 2.0, 2.0, 8.0, 5.0},
+ {sqrt (2 * 2 + 1 * 1), 6.0, 4.0, 2.0, 2.0, 0.0, 1.0},
+
+ {sqrt (2 * 2 + 1 * 1), 2.0, 2.0, 6.0, 4.0, 3.0, 5.0},
+ {sqrt (2 * 2 + 1 * 1), 6.0, 4.0, 2.0, 2.0, 3.0, 5.0},
+
+ {sqrt (2 * 2 + 1 * 1), 2.0, 2.0, 6.0, 4.0, 5.0, 1.0},
+ {sqrt (2 * 2 + 1 * 1), 6.0, 4.0, 2.0, 2.0, 5.0, 1.0},
+
+ {sqrt (2 * 2 + 1 * 1), 6.0, 4.0, 2.0, 2.0, 7.0, 6.0},
+ {sqrt (2 * 2 + 1 * 1), 6.0, 4.0, 2.0, 2.0, 7.0, 2.0},
+ {sqrt (2 * 2 + 1 * 1), 6.0, 4.0, 2.0, 2.0, 5.0, 6.0},
+ {2, 6.0, 4.0, 2.0, 2.0, 6.0, 6.0},
+
+ {2, 6.0, 4.0, 2.0, 2.0, 2.0, 0.0},
+ {sqrt (2 * 2 + 1 * 1), 6.0, 4.0, 2.0, 2.0, 3.0, 0.0},
+ {sqrt (2 * 2 + 1 * 1), 6.0, 4.0, 2.0, 2.0, 1.0, 0.0},
+
+ {-99.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
+ };
+
+ gint i;
+ for (i = 0; test_array[i].dist != -99; i++)
+ {
+ gdouble d;
+ d = distance_line_point (test_array[i].x1, test_array[i].y1,
+ test_array[i].x2, test_array[i].y2,
+ test_array[i].xp, test_array[i].yp);
+ if ((d - test_array[i].dist) < 0.00000001)
+ {
+ if (mydebug > 0)
+ fprintf (stderr,
+ " %d: distance_line_point(%g,%g, %g,%g, %g,%g) ==> %g\n",
+ i, test_array[i].x1, test_array[i].y1,
+ test_array[i].x2, test_array[i].y2,
+ test_array[i].xp, test_array[i].yp, d);
+ }
+ else
+ {
+ printf ("!!!! ERROR\n");
+ printf
+ ("distance_line_point(%g,%g, %g,%g, %g,%g) = %g should be %g\n",
+ test_array[i].x1, test_array[i].y1, test_array[i].x2,
+ test_array[i].y2, test_array[i].xp, test_array[i].yp, d,
+ test_array[i].dist);
+ errors++;
+ }
+ }
+ }
+
+ // ------------------------------------------------------------------
+ {
+ if (mydebug > 0)
+ printf ("\n");
+ printf ("Testing coordinate_string2gdouble()\n");
+
+ gchar test_string1[100];
+ gchar test_string2[100];
+ gdouble coordinate;
+ gdouble delta;
+
+ typedef struct
+ {
+ gdouble number;
+ gchar string[100];
+ } test_struct;
+ test_struct test_array[] = {
+ {0.0, "0"},
+ {0.0, "0.0"},
+ {0.0, "0,0"},
+
+ {1.0, "1"},
+ {1.0, "1.0"},
+ {1.0, "1,0"},
+
+ {12.0, "12"},
+ {12.0, "12.0"},
+ {12.0, "12,0"},
+
+ {-12.0, "-12"},
+ {-12.0, "-12.0"},
+ {-12.0, "-12,0"},
+
+ {-12.0, "12W"},
+ {-12.0, "12.0W"},
+ {-12.0, "12,0W"},
+
+ {121.7654789, "121.7654789"},
+ {121.7654789, "121,7654789"},
+ {121.7654789, " 121.7654789 "},
+ {121.7654789, " 121,7654789 "},
+ {121.7654789, "\t121,7654789 "},
+ {121.7654789, " 121,7654789\t"},
+ {121.7654789, "\n121,7654789\t"},
+ {121.7654789, " 121,7654789\t"},
+
+ {-121.7654789, "-121.7654789"},
+ {-121.7654789, "-121,7654789"},
+ {-121.7654789, " -121.7654789 "},
+ {-121.7654789, " -121,7654789 "},
+ {-121.7654789, "\t-121,7654789 "},
+ {-121.7654789, " -121,7654789\t"},
+ {-121.7654789, "\n-121,7654789\t"},
+ {-121.7654789, " -121,7654789\t"},
+
+ {-121.7654789, "121.7654789E"},
+ {-121.7654789, "121,7654789E"},
+ {-121.7654789, " 121.7654789E "},
+ {-121.7654789, " 121,7654789E "},
+ {-121.7654789, "\t121,7654789E "},
+ {-121.7654789, " 121,7654789E\t"},
+ {-121.7654789, "\n121,7654789E\t"},
+ {-121.7654789, " 121,7654789E\t"},
+
+ {12.35, "12" "\xc2" "\xb0" "21'E"},
+ {-12.35, "12" "\xc2" "\xb0" "21'W"},
+ {12.35, "12" "\xc2" "\xb0" "21'N"},
+ {-12.35, "12" "\xc2" "\xb0" "21'S"},
+
+ {12.35194444444444, "12" "\xc2" "\xb0" "21'7''E"},
+
+
+ {0.0, "END"}
+ };
+
+ gint i;
+ for (i = 0;
+ strncmp (test_array[i].string, "END", sizeof (test_array[i].string));
+ i++)
+ {
+
+ coordinate = -9999;
+ g_strlcpy (test_string1, test_array[i].string, sizeof (test_string1));
+ g_strlcpy (test_string2, test_string1, sizeof (test_string1));
+ coordinate_string2gdouble (test_string1, &coordinate);
+ if (mydebug > 0)
+ fprintf (stderr,
+ " %d: coordinate_string2gdouble('%s') --> %g\n", i,
+ test_string1, coordinate);
+ delta = test_array[i].number - coordinate;
+ if (delta > 1e-10)
+ {
+ printf ("!!!! ERROR\n");
+ printf (" coordinate_string2gdouble('%s') --> %g\n",
+ test_string1, coordinate);
+ errors++;
+ }
+ // Will the input string be modified ?
+ if (strcmp (test_string1, test_string2))
+ {
+ printf ("!!!! ERROR: Input String changed\n");
+ errors++;
+ printf (" coordinate_string2gdouble('%s')\n", test_string1);
+ printf (" --> ('%s')\n", test_string2);
+ }
+
+ }
+
+
+
+ if (mydebug > 0)
+ printf ("\n");
+ printf ("Testing coordinate_string2gdouble()\n");
+
+
+ }
+
+ // ------------------------------------------------------------------
+ {
+ if (mydebug > 0)
+ printf ("\n");
+ printf ("Testing coordinate2gchar()\n");
+
+ gchar test_string1[100];
+ gdouble coordinate;
+
+ // coordinate2gchar (gchar * buff, gint buff_size, gdouble pos, gint islat, gint mode)
+
+ coordinate = 12.1;
+ coordinate2gchar (test_string1, sizeof (test_string1), coordinate, FALSE,
+ 1);
+ if (mydebug > 1)
+ printf (" %g --> '%s'\n", coordinate, test_string1);
+ if (strcmp ("12" "\xc2" "\xb0" "05'60.00''E", test_string1))
+ {
+ printf ("!!!! ERROR\n");
+ errors++;
+ }
+
+ coordinate = -12.1;
+ coordinate2gchar (test_string1, sizeof (test_string1), coordinate, FALSE,
+ 1);
+ if (mydebug > 1)
+ printf (" %g --> '%s'\n", coordinate, test_string1);
+ if (strcmp ("12" "\xc2" "\xb0" "05'60.00''W", test_string1))
+ {
+ printf ("!!!! ERROR\n");
+ errors++;
+ }
+
+ coordinate = 12.1;
+ coordinate2gchar (test_string1, sizeof (test_string1), coordinate, TRUE,
+ 1);
+ if (mydebug > 1)
+ printf (" %g --> '%s'\n", coordinate, test_string1);
+ if (strcmp ("12" "\xc2" "\xb0" "05'60.00''N", test_string1))
+ {
+ printf ("!!!! ERROR\n");
+ errors++;
+ }
+
+ coordinate = -12.1;
+ coordinate2gchar (test_string1, sizeof (test_string1), coordinate, TRUE,
+ 1);
+ if (mydebug > 1)
+ printf (" %g --> '%s'\n", coordinate, test_string1);
+ if (strcmp ("12" "\xc2" "\xb0" "05'60.00''S", test_string1))
+ {
+ printf ("!!!! ERROR\n");
+ errors++;
+ }
+ }
+
+ // ------------------------------------------------------------------
+ {
+ if (mydebug > 0)
+ printf ("\n");
+ printf ("Testing calcxytopos() and calcxy()\n");
+
+ // void calcxytopos (int posx, int posy, gdouble *mylat, gdouble *mylon, gint zoom);
+ // void calcxy (gdouble *posx, gdouble *posy, gdouble lon, gdouble lat, gint zoom);
+
+ map_proj = proj_map;
+ current.zoom = 1;
+ current.mapscale = 10000;
+ pixelfact = current.mapscale / PIXELFACT;
+
+ if (mydebug > 1)
+ {
+ printf (" pixelfact: %g\n", pixelfact);
+ printf (" mapscale: %ld\n", current.mapscale);
+ printf (" SCREEN X/Y: %d/%d\n", SCREEN_X, SCREEN_Y);
+ printf ("\n");
+ }
+
+ typedef struct
+ {
+ gdouble cur_lat, cur_lon;
+ gdouble x, y;
+ gdouble lat, lon;
+ } test_struct;
+ test_struct test_array[] = {
+ {12, 48, SCREEN_X / 2, SCREEN_Y / 2, 12, 48},
+ {12, 48, SCREEN_X, SCREEN_Y, 11.9848, 48.021},
+ {12, 48, 0, SCREEN_Y, 11.9848, 47.979},
+ {12, 48, SCREEN_X, 0, 12.0152, 48.021},
+ {12, 48, 0, 0, 12.0152, 47.979},
+
+ {-12, 48, SCREEN_X / 2, SCREEN_Y / 2, -12, 48},
+ {-12, 48, SCREEN_X, SCREEN_Y, -11.9848, 48.021},
+ {-12, 48, 0, SCREEN_Y, -11.9848, 47.979},
+ {-12, 48, SCREEN_X, 0, -12.0152, 48.021},
+ {-12, 48, 0, 0, -12.0152, 47.979},
+
+ {12, -48, SCREEN_X / 2, SCREEN_Y / 2, 12, -48},
+ {12, -48, SCREEN_X, SCREEN_Y, 11.9848, -48.021},
+ {12, -48, 0, SCREEN_Y, 11.9848, -47.979},
+ {12, -48, SCREEN_X, 0, 12.0152, -48.021},
+ {12, -48, 0, 0, 12.0152, -47.979},
+
+ {-12, -48, SCREEN_X / 2, SCREEN_Y / 2, -12, -48},
+ {-12, -48, SCREEN_X, SCREEN_Y, -11.9848, -48.021},
+ {-12, -48, 0, SCREEN_Y, -11.9848, -47.979},
+ {-12, -48, SCREEN_X, 0, -12.0152, -48.021},
+ {-12, -48, 0, 0, -12.0152, -47.979},
+
+ {0, 0, -99.0, 0.0, 0.0, 0.0},
+ };
+
+ gint i;
+ for (i = 0; test_array[i].x != -99; i++)
+ {
+ gdouble lat, lon;
+ gint x, y;
+ gdouble gx, gy;
+
+ coords.current_lat = coords.zero_lat = test_array[i].cur_lat;
+ coords.current_lon = coords.zero_lon = test_array[i].cur_lon;
+
+ x = test_array[i].x;
+ y = test_array[i].y;
+ calcxytopos (x, y, &lat, &lon, current.zoom);
+ if (mydebug > 0)
+ {
+ printf (" %d: current_pos: %g,%g\n", i, coords.current_lat,
+ coords.current_lon);
+ fprintf (stderr,
+ " %d: calcxytopos(%-7d,%-7d) --> (%g,%g)\n",
+ i, x, y, lat, lon);
+ }
+
+ gdouble delta_lat = test_array[i].lat - lat;
+ if (abs (delta_lat) > 1e-10)
+ {
+ printf ("!!!! ERROR: Delta-lat(%g)\n", delta_lat);
+ errors++;
+ fprintf (stderr,
+ "!!ERROR: calcxytopos(%-7.4d,%-7.4d) --> (%g,%g) should be (%g,%g)\n",
+ x, y, lat, lon, test_array[i].lat, test_array[i].lon);
+ }
+
+ // Backward transformation
+ calcxy (&gx, &gy, lon, lat, current.zoom);
+ if (mydebug > 0)
+ fprintf (stderr,
+ " %d: (%-7.4g,%-7.4g) <-- calcxy(%g,%g)\n",
+ i, gx, gy, lat, lon);
+ gint delta_x = gx - x;
+ if (abs (delta_x) >= 1)
+ {
+ printf ("!!!! ERROR: Delta-x(%d)>1\n", delta_x);
+ errors++;
+ }
+ gint delta_y = gy - y;
+ if (abs (delta_y) >= 1)
+ {
+ printf ("!!!! ERROR: Delta-y(%d)>1\n", delta_y);
+ errors++;
+ }
+ if (mydebug > 0)
+ printf ("\n");
+ }
+ }
+
+ // ------------------------------------------------------------------
+ {
+ int res;
+
+ if (mydebug > 0)
+ printf ("\n");
+ printf ("Testing if SQL Support is on\n");
+
+ if (!usesql)
+ {
+ printf ("ERROR !!!!!!!!\n");
+ printf ("Problem with SQL Support\n");
+ errors++;
+ }
+
+ res = insertsqldata(999.9,999.9,"Testpoint","test","Test Description", 1);
+ if (1>res)
+ {
+ printf ("ERROR !!!!!!!!\n");
+ printf ("Problem inserting waypoint into mySQL Table waypoints\n");
+ errors++;
+ }
+
+ }
+
+ // ------------------------------------------------------------------
+ {
+ if (mydebug > 0)
+ printf ("\n");
+ printf ("Testing if acpi/apm is parsing correct\n");
+
+ gchar fn[500];
+ gint response;
+
+
+ g_snprintf (dir_proc, sizeof (dir_proc), "/tmp/gpsdrive-unit-test");
+ mkdir (dir_proc, 0777);
+ g_snprintf (dir_proc, sizeof (dir_proc), "/tmp/gpsdrive-unit-test/proc");
+ mkdir (dir_proc, 0777);
+
+ if (mydebug > 0)
+ printf (" --------> remove maybe old Files\n");
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/BAT1/state", dir_proc);
+ unlink (fn);
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/BAT2/state", dir_proc);
+ unlink (fn);
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/BAT1/info", dir_proc);
+ unlink (fn);
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/BAT2/info", dir_proc);
+ unlink (fn);
+ g_snprintf (fn, sizeof (fn), "%s/apm", dir_proc);
+ unlink (fn);
+ g_snprintf (fn, sizeof (fn), "%s/acpi/thermal_zone/ATF00/temperature",
+ dir_proc);
+ unlink (fn);
+
+
+ if (mydebug > 0)
+ printf
+ (" -------> Check if we get positive answers even if no files should be there\n");
+ if (battery_get_values ())
+ {
+ printf ("battery reporting Problem: battery status without file\n");
+ errors++;
+ }
+
+ if (temperature_get_values ())
+ {
+ printf
+ ("temperature reporting Problemtem: temperature without file\n");
+ errors++;
+ }
+
+ if (mydebug > 0)
+ printf (" -------> Create Dummy Files/dirs for ACPI\n");
+ g_snprintf (fn, sizeof (fn), dir_proc);
+ g_strlcat (fn, "/acpi", sizeof (fn));
+ mkdir (fn, 0777);
+ g_strlcat (fn, "/battery", sizeof (fn));
+ mkdir (fn, 0777);
+
+ if (mydebug > 0)
+ printf (" -------> one Battery\n");
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/BAT1", dir_proc);
+ mkdir (fn, 0777);
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/BAT1/state", dir_proc);
+ write_file (fn, "present: yes\n"
+ "capacity state: ok\n"
+ "charging state: charging\n"
+ "present rate: 5000 mW\n"
+ "remaining capacity: 20000 mWh\n"
+ "present voltage: 16764 mV\n");
+
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/BAT1/info", dir_proc);
+ write_file (fn, "present: yes\n"
+ "design capacity: 59200 mWh\n"
+ "last full capacity: 40000 mWh\n"
+ "battery technology: non-rechargeable\n"
+ "design voltage: 14800 mV\n"
+ "design capacity warning: 0 mWh\n"
+ "design capacity low: 120 mWh\n"
+ "capacity granularity 1: 0 mWh\n"
+ "capacity granularity 2: 10 mWh\n"
+ "model number: \n");
+ if (!battery_get_values ())
+ {
+ printf ("battery reporting Problem: no battery status for 1 Bat\n");
+ errors++;
+ }
+ if (mydebug > 1)
+ printf ("batstring: %s\n", batstring);
+ if (strcmp (batstring, "Batt 50%, 240 min"))
+ {
+ printf ("!!!! ERROR\n");
+ errors++;
+ }
+
+
+ if (mydebug > 0)
+ printf (" -------> and another Battery\n");
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/BAT2", dir_proc);
+ mkdir (fn, 0777);
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/BAT2/state", dir_proc);
+ write_file (fn, "present: yes\n"
+ "capacity state: ok\n"
+ "charging state: charging\n"
+ "present rate: 500 mW\n"
+ "remaining capacity: 1000 mWh\n"
+ "present voltage: 16764 mV\n");
+
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/BAT2/info", dir_proc);
+ write_file (fn, "present: yes\n"
+ "design capacity: 59200 mWh\n"
+ "last full capacity: 10000 mWh\n"
+ "battery technology: non-rechargeable\n"
+ "design voltage: 14800 mV\n"
+ "design capacity warning: 0 mWh\n"
+ "design capacity low: 120 mWh\n"
+ "capacity granularity 1: 0 mWh\n"
+ "capacity granularity 2: 10 mWh\n"
+ "model number: \n");
+ response = battery_get_values ();
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/BAT1/state", dir_proc);
+ unlink (fn);
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/BAT1/info", dir_proc);
+ unlink (fn);
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/BAT2/state", dir_proc);
+ unlink (fn);
+ g_snprintf (fn, sizeof (fn), "%s/acpi/battery/BAT2/info", dir_proc);
+ unlink (fn);
+ if (!response)
+ {
+ printf ("battery reporting Problem: no battery status for 1 Bat\n");
+ errors++;
+ }
+ if (mydebug > 1)
+ printf ("batstring: %s\n", batstring);
+ if (strcmp (batstring, "Batt 42%, 229 min"))
+ {
+ printf ("!!!! ERROR\n");
+ errors++;
+ }
+
+ if (mydebug > 0)
+ printf (" -------> Check with apm\n");
+ g_snprintf (fn, sizeof (fn), "%s/apm", dir_proc);
+ // write_file(fn,"test test test 0x03 test 0x01 99% test test\n");
+
+ gchar battery_string[200];
+ sprintf (battery_string, "%s %s %s %x %s %x %d%% %s %s\ntest1\n",
+ "test1", "test2", "test3", 3, "test4", 3, 99, "test5", "test6");
+ write_file (fn, battery_string);
+ write_file (fn, "1 2 3 04 4 06 71% 7 8\n");
+ response = battery_get_values ();
+ if (mydebug > 1)
+ printf ("batstring: %s\n", batstring);
+ unlink (fn);
+ if (!response)
+ {
+ printf ("battery reporting Problem: no bat reported\n");
+ errors++;
+ }
+ if (!strcmp (batstring, "Batt 71%"))
+ {
+ printf ("!!!! ERROR\n");
+ errors++;
+ }
+
+
+
+
+ if (mydebug > 0)
+ printf (" -------> Check acpi thermal zone\n");
+ g_snprintf (fn, sizeof (fn), "%s/acpi/thermal_zone", dir_proc);
+ mkdir (fn, 0777);
+ g_snprintf (fn, sizeof (fn), "%s/acpi/thermal_zone/ATF00", dir_proc);
+ mkdir (fn, 0777);
+ g_snprintf (fn, sizeof (fn), "%s/acpi/thermal_zone/ATF00/temperature",
+ dir_proc);
+ write_file (fn, "temperature: 59 C\n");
+
+ response = temperature_get_values ();
+ if (mydebug > 1)
+ printf ("tempstring: %s\n", cputempstring);
+ // unlink(fn);
+ if (!response)
+ {
+ printf ("ERROR: temperature reporting Problem: no temp reported\n");
+ errors++;
+ }
+
+ }
+
+
+ // ------------------------------------------------------------------
+ //errors += unit_test_nmea();
+
+ set_unittest_timer();
+ if (errors > 0)
+ {
+ printf ("\n\n");
+ printf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+ printf ("!!! !!!\n");
+ printf ("!!! FOUND %2d ERRORS !!!\n",
+ errors);
+ printf ("!!! !!!\n");
+ printf
+ ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n");
+ exit (-1);
+ }
+
+ // ------------------------------------------------------------------
+ printf ("\n\nUnit Tests ( Part 1 ) successfull\n\n");
+}
+
+
+
+
+/* *****************************************************************************
+ */
+gint
+unittest_settings_open (GtkWidget * widget, guint * datum)
+{
+
+ if (mydebug > 0)
+ printf (" -------> Open Settings\n");
+
+ settings_main_cb(0,1);
+
+ return FALSE; // Only once
+}
+gint
+unittest_settings_close (GtkWidget * widget, guint * datum)
+{
+
+ if (mydebug > 0)
+ printf (" -------> Close Settings\n");
+
+ return FALSE; // Only once
+}
+
+/* *****************************************************************************
+ */
+void
+set_unittest_timer (void)
+{
+ printf ("Testing Open and Close Settings\n");
+ gtk_timeout_add (1000, (GtkFunction) unittest_settings_open,NULL );
+ gtk_timeout_add (2000, (GtkFunction) quit_program_cb,NULL);
+}
diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt
new file mode 100644
index 0000000..1cbabfa
--- /dev/null
+++ b/src/util/CMakeLists.txt
@@ -0,0 +1,44 @@
+project(util)
+
+find_package(GDAL REQUIRED)
+
+set(UTIL_INCLUDE_DIRS
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${GTK2_INCLUDE_DIRS}
+ ${GDAL_INCLUDE_DIRS}
+)
+
+#includes
+set(util_INCLUDE_DIR
+ ${util_SOURCE_DIR}/
+ CACHE INTERNAL ""
+)
+
+add_definitions(-DHAVE_GTK -DHAVE_CAIRO)
+
+include_directories(${UTIL_INCLUDE_DIRS})
+
+set(worldgen_SRCS
+ worldgen.c
+)
+
+set(gmapview_SRCS
+ gmapview.c
+)
+
+if (GDAL_FOUND)
+ add_executable(worldgen ${worldgen_SRCS})
+ target_link_libraries(worldgen ${GDAL_LIBRARIES})
+ install(TARGETS worldgen DESTINATION ${BIN_INSTALL_DIR})
+endif (GDAL_FOUND)
+
+if (GDAL_FOUND AND GTK2_FOUND)
+ add_executable(gmapview ${gmapview_SRCS})
+ target_link_libraries(gmapview
+ map
+ ${GDAL_LIBRARIES}
+ ${GTK2_LIBRARIES}
+ )
+ install(TARGETS gmapview DESTINATION ${BIN_INSTALL_DIR})
+endif (GDAL_FOUND AND GTK2_FOUND)
+
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
new file mode 100644
index 0000000..31e4698
--- /dev/null
+++ b/src/util/Makefile.am
@@ -0,0 +1,51 @@
+LIB_MAP=../lib_map/map_gpsdrive.c ../lib_map/map_load.c \
+ ../lib_map/map_transform.c ../lib_map/map_gpsmisc.c \
+ ../lib_map/map_render.c \
+ ../lib_map/map.h ../lib_map/map_priv.h
+
+
+LIB_MAP_O=../lib_map/map_gpsdrive.o ../lib_map/map_load.o \
+ ../lib_map/map_transform.o ../lib_map/map_gpsmisc.o \
+ ../lib_map/map_render.o
+
+LIB_MAP_L= map_gpsdrive.c map_load.c \
+ map_transform.c map_gpsmisc.c \
+ map_render.c
+
+if HAVE_GDAL
+worldgendir=$(bindir)
+worldgen_PROGRAMS = worldgen
+worldgen_SOURCES= worldgen.c
+# ../lib_map/lib_map.a
+worldgen_LDFLAGS = $(GDAL_LIBS)
+
+if HAVE_GTK
+#CFLAGS += -DHAVE_CAIRO
+#CFLAGS += -DHAVE_GTK
+
+# the $(GDAL_LIBS) part is a quick hack. So please could
+# someone knowing autoconf reconsidder if there is a better solution
+lib_map_lflags = \
+ $(GDAL_LIBS) \
+ `pkg-config cairo --libs` \
+ `pkg-config gtk+-2.0 --libs`\
+ `gdal-config --libs`
+
+
+gmapviewdir=$(bindir)
+gmapview_PROGRAMS = gmapview
+gmapview_SOURCES= gmapview.c
+gmapview_LDFLAGS = \
+ ../lib_map/lib_map.a \
+ $(lib_map_lflags) \
+ $(LDADD) $(GDAL_LDADD) $(LFLAGS) -lm
+gmapview_CXXFLAGS = $(CFLAGS) $(PREFIX) $(PLUGINPATH) \
+ $(PKGDATAPATH) $(GDAL_CFLAGS) $(CXXFLAGS) $(EXTRA_CXXFLAGS) \
+ -DHAVE_CAIRO -DHAVE_GTK
+endif
+
+endif
+
+EXTRA_DIST = $(gmapview_SOURCES) $(worldgen_SOURCES) \
+ gps.c mmapview.c qmapview.cpp wmapview.c CMakeLists.txt
+
diff --git a/src/util/Makefile.in b/src/util/Makefile.in
new file mode 100644
index 0000000..45dd458
--- /dev/null
+++ b/src/util/Makefile.in
@@ -0,0 +1,599 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_GDAL_TRUE@worldgen_PROGRAMS = worldgen$(EXEEXT)
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@gmapview_PROGRAMS = gmapview$(EXEEXT)
+subdir = src/util
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_perl_modules.m4 \
+ $(top_srcdir)/m4/ac_check_socketlen_t.m4 \
+ $(top_srcdir)/m4/aq_check_gdal.m4 $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(gmapviewdir)" \
+ "$(DESTDIR)$(worldgendir)"
+gmapviewPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+worldgenPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(gmapview_PROGRAMS) $(worldgen_PROGRAMS)
+am__gmapview_SOURCES_DIST = gmapview.c
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@am_gmapview_OBJECTS = \
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@ gmapview.$(OBJEXT)
+gmapview_OBJECTS = $(am_gmapview_OBJECTS)
+gmapview_LDADD = $(LDADD)
+am__worldgen_SOURCES_DIST = worldgen.c
+@HAVE_GDAL_TRUE@am_worldgen_OBJECTS = worldgen.$(OBJEXT)
+worldgen_OBJECTS = $(am_worldgen_OBJECTS)
+worldgen_LDADD = $(LDADD)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(gmapview_SOURCES) $(worldgen_SOURCES)
+DIST_SOURCES = $(am__gmapview_SOURCES_DIST) \
+ $(am__worldgen_SOURCES_DIST)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkgdatadir = @pkgdatadir@
+ACLOCAL = @ACLOCAL@
+AMAPNIK = @AMAPNIK@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_GLIB_LIBS = @DBUS_GLIB_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISABLEGARMIN_FALSE = @DISABLEGARMIN_FALSE@
+DISABLEGARMIN_TRUE = @DISABLEGARMIN_TRUE@
+DISABLEPLUGINS_FALSE = @DISABLEPLUGINS_FALSE@
+DISABLEPLUGINS_TRUE = @DISABLEPLUGINS_TRUE@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRIENDSSERVERVERSION = @FRIENDSSERVERVERSION@
+GDAL_CFLAGS = @GDAL_CFLAGS@
+GDAL_CONFIG = @GDAL_CONFIG@
+GDAL_LDADD = @GDAL_LDADD@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GLIB_MKENUMS = @GLIB_MKENUMS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GOBJECT_QUERY = @GOBJECT_QUERY@
+GREP = @GREP@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+HAVE_DBUS_FALSE = @HAVE_DBUS_FALSE@
+HAVE_DBUS_TRUE = @HAVE_DBUS_TRUE@
+HAVE_GDAL_FALSE = @HAVE_GDAL_FALSE@
+HAVE_GDAL_TRUE = @HAVE_GDAL_TRUE@
+HAVE_GTK_FALSE = @HAVE_GTK_FALSE@
+HAVE_GTK_TRUE = @HAVE_GTK_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBADD_DL = @LIBADD_DL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NOGARMIN = @NOGARMIN@
+NOPLUGINS = @NOPLUGINS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PCRE_CONFIG = @PCRE_CONFIG@
+PERL = @PERL@
+PERL_PACKAGE_DIR = @PERL_PACKAGE_DIR@
+PKGCONFIG_CFLAGS = @PKGCONFIG_CFLAGS@
+PKGCONFIG_LIBS = @PKGCONFIG_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+POSUB = @POSUB@
+POW_LIB = @POW_LIB@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WITH_MAPNIK_FALSE = @WITH_MAPNIK_FALSE@
+WITH_MAPNIK_TRUE = @WITH_MAPNIK_TRUE@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XML_CFLAGS = @XML_CFLAGS@
+XML_LIBS = @XML_LIBS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+LIB_MAP = ../lib_map/map_gpsdrive.c ../lib_map/map_load.c \
+ ../lib_map/map_transform.c ../lib_map/map_gpsmisc.c \
+ ../lib_map/map_render.c \
+ ../lib_map/map.h ../lib_map/map_priv.h
+
+LIB_MAP_O = ../lib_map/map_gpsdrive.o ../lib_map/map_load.o \
+ ../lib_map/map_transform.o ../lib_map/map_gpsmisc.o \
+ ../lib_map/map_render.o
+
+LIB_MAP_L = map_gpsdrive.c map_load.c \
+ map_transform.c map_gpsmisc.c \
+ map_render.c
+
+@HAVE_GDAL_TRUE@worldgendir = $(bindir)
+@HAVE_GDAL_TRUE@worldgen_SOURCES = worldgen.c
+# ../lib_map/lib_map.a
+@HAVE_GDAL_TRUE@worldgen_LDFLAGS = $(GDAL_LIBS)
+
+#CFLAGS += -DHAVE_CAIRO
+#CFLAGS += -DHAVE_GTK
+
+# the $(GDAL_LIBS) part is a quick hack. So please could
+# someone knowing autoconf reconsidder if there is a better solution
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@lib_map_lflags = \
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@ $(GDAL_LIBS) \
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@ `pkg-config cairo --libs` \
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@ `pkg-config gtk+-2.0 --libs`\
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@ `gdal-config --libs`
+
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@gmapviewdir = $(bindir)
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@gmapview_SOURCES = gmapview.c
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@gmapview_LDFLAGS = \
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@ ../lib_map/lib_map.a \
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@ $(lib_map_lflags) \
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@ $(LDADD) $(GDAL_LDADD) $(LFLAGS) -lm
+
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@gmapview_CXXFLAGS = $(CFLAGS) $(PREFIX) $(PLUGINPATH) \
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@ $(PKGDATAPATH) $(GDAL_CFLAGS) $(CXXFLAGS) $(EXTRA_CXXFLAGS) \
+@HAVE_GDAL_TRUE@@HAVE_GTK_TRUE@ -DHAVE_CAIRO -DHAVE_GTK
+
+EXTRA_DIST = $(gmapview_SOURCES) $(worldgen_SOURCES) \
+ gps.c mmapview.c qmapview.cpp wmapview.c CMakeLists.txt
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/util/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/util/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-gmapviewPROGRAMS: $(gmapview_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(gmapviewdir)" || $(mkdir_p) "$(DESTDIR)$(gmapviewdir)"
+ @list='$(gmapview_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(gmapviewPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(gmapviewdir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(gmapviewPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(gmapviewdir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-gmapviewPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(gmapview_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(gmapviewdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(gmapviewdir)/$$f"; \
+ done
+
+clean-gmapviewPROGRAMS:
+ @list='$(gmapview_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+install-worldgenPROGRAMS: $(worldgen_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(worldgendir)" || $(mkdir_p) "$(DESTDIR)$(worldgendir)"
+ @list='$(worldgen_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(worldgenPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(worldgendir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(worldgenPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(worldgendir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-worldgenPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(worldgen_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(worldgendir)/$$f'"; \
+ rm -f "$(DESTDIR)$(worldgendir)/$$f"; \
+ done
+
+clean-worldgenPROGRAMS:
+ @list='$(worldgen_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+gmapview$(EXEEXT): $(gmapview_OBJECTS) $(gmapview_DEPENDENCIES)
+ @rm -f gmapview$(EXEEXT)
+ $(LINK) $(gmapview_LDFLAGS) $(gmapview_OBJECTS) $(gmapview_LDADD) $(LIBS)
+worldgen$(EXEEXT): $(worldgen_OBJECTS) $(worldgen_DEPENDENCIES)
+ @rm -f worldgen$(EXEEXT)
+ $(LINK) $(worldgen_LDFLAGS) $(worldgen_OBJECTS) $(worldgen_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmapview.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/worldgen.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(gmapviewdir)" "$(DESTDIR)$(worldgendir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-gmapviewPROGRAMS clean-libtool \
+ clean-worldgenPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-gmapviewPROGRAMS install-worldgenPROGRAMS
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-gmapviewPROGRAMS uninstall-info-am \
+ uninstall-worldgenPROGRAMS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-gmapviewPROGRAMS clean-libtool clean-worldgenPROGRAMS \
+ ctags distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-exec install-exec-am \
+ install-gmapviewPROGRAMS install-info install-info-am \
+ install-man install-strip install-worldgenPROGRAMS \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-gmapviewPROGRAMS \
+ uninstall-info-am uninstall-worldgenPROGRAMS
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/util/gmapview.c b/src/util/gmapview.c
new file mode 100644
index 0000000..bb0979f
--- /dev/null
+++ b/src/util/gmapview.c
@@ -0,0 +1,601 @@
+//
+// Copyright (c) 2005 -- Daniel Wallner
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#include "../lib_map/map.h"
+
+#include <gtk/gtk.h>
+#include <stdio.h>
+#ifdef USE_CAIRO
+#include <cairo.h>
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+
+void init_gps();
+void free_gps();
+
+#define PIXEL_SIZE 0.22E-3
+#define SCALE_RATIO 10
+
+MapSettings mapsettings;
+MapSet mapset;
+MapState mapstates[16];
+GtkWidget *canvases[16];
+int views = 1;
+int render_mode = 0x100;
+int cover = 0;
+int transparent = 0;
+double pixel_size = PIXEL_SIZE;
+int noZoom = FALSE;
+
+static void expose(GtkWidget *widget, GdkEventExpose *event,
+ MapState *mapstate)
+{
+ gint width = widget->allocation.width;
+ gint height = widget->allocation.height;
+
+#ifdef USE_CAIRO
+ MapGC mgc;
+
+ memset((void*)&mgc, 0, sizeof(mgc));
+
+ mgc.cairo_cr = gdk_cairo_create(widget->window);
+
+ if (cover)
+ coverifpossible(mapstate, width, height);
+
+ drawmap(mapstate, &mgc, width, height, transparent);
+
+ drawmarkers(&mgc, width, height,
+ &mapsettings, mapstate, pixel_size,
+ 0, 0);
+
+ cairo_destroy(mgc.cairo_cr);
+#else
+ MapGC mgc;
+
+ memset((void*)&mgc, 0, sizeof(mgc));
+
+ mgc.gtk_widget = widget;
+ mgc.gtk_drawable = widget->window;
+ mgc.gtk_gc = gdk_gc_new(widget->window);
+
+ if (cover)
+ coverifpossible(mapstate, width, height);
+
+ drawmap(mapstate, &mgc, width, height, transparent);
+
+ drawmarkers(&mgc, width, height,
+ &mapsettings, mapstate, pixel_size,
+ 0, 0);
+
+ gdk_gc_unref(mgc.gtk_gc);
+#endif
+}
+
+static gboolean button_press(GtkWidget *widget, GdkEventButton *event,
+ MapState *mapstate)
+{
+ int i;
+
+ mapsettings.posmode = TRUE;
+
+ screen2wgs(mapstate, event->x, event->y,
+ &mapstate->req_lat, &mapstate->req_lon);
+
+ fprintf(stderr, "new center: %lf;%lf\n",
+ mapstate->req_lat, mapstate->req_lon);
+
+ for (i = 0; i < views; i++)
+ {
+ mapstates[i].req_lat = mapstate->req_lat;
+ mapstates[i].req_lon = mapstate->req_lon;
+
+ if (views != mapset.maps)
+ {
+ selectbestmap(&mapset, &mapstates[i], render_mode, pixel_size);
+ }
+ else
+ {
+ double pseudo_lat = (render_mode & 0x100) ? mapstate->req_lat : 0;
+
+ wgs2pixel(mapstates[i].dataset[0], mapstates[i].path[0],
+ mapstate->req_lat, mapstate->req_lon,
+ &mapstates[i].act_xPixel[0], &mapstates[i].act_yPixel[0]);
+
+ scale2zoom(mapstates[i].dataset[0], mapstates[i].path[0],
+ mapstates[i].req_scale, pixel_size, pseudo_lat,
+ &mapstates[i].act_xZoom[0], &mapstates[i].act_yZoom[0]);
+ }
+
+ if (noZoom)
+ {
+ mapstates[i].act_xZoom[0] = 1;
+ mapstates[i].act_yZoom[0] = 1;
+ }
+
+ gtk_widget_queue_draw(canvases[i]);
+ }
+
+ return TRUE;
+}
+
+static gint key_press(GtkWidget *widget, GdkEventKey *event,
+ MapState *mapstate)
+{
+ int i;
+
+ int redraw = 0;
+
+ double factor = 1;
+
+ if (!event->length)
+ return FALSE;
+
+ switch (event->string[0])
+ {
+ case '+':
+ factor = 1 / 1.5;
+ redraw = 1;
+ break;
+
+ case '-':
+ factor = 1.5;
+ redraw = 1;
+ break;
+
+ case 'm':
+ render_mode = (render_mode & 0xfff0) + (((render_mode & 0x0f) + 1) % 3);
+ redraw = 1;
+ break;
+
+ case 'f':
+ render_mode = (render_mode & 0xff0f) +
+ (((((render_mode & 0xf0) >> 4) + 1) % 3) << 4);
+ redraw = 1;
+ break;
+
+ case 'a':
+ render_mode = render_mode | 0x200;
+ redraw = 1;
+ break;
+
+ case 'c':
+ cover = !cover;
+ redraw = 1;
+ break;
+
+ case 'p':
+ mapsettings.havepos = !mapsettings.havepos;
+ redraw = 1;
+ break;
+
+ case 's':
+ render_mode ^= 0x100;
+ redraw = 1;
+ break;
+
+ case 'g':
+ mapsettings.drawgrid = !mapsettings.drawgrid;
+ redraw = 1;
+ break;
+
+ case 't':
+ transparent = !transparent;
+ redraw = 1;
+ break;
+
+ case 'r':
+ mapstate->req_rotation += 45;
+ if (mapstate->req_rotation >= 360)
+ mapstate->req_rotation -= 360;
+ redraw = 1;
+ break;
+ }
+
+ fprintf(stderr, "mode: %X\n", render_mode);
+
+ if (redraw)
+ for (i = 0; i < views; i++)
+ {
+ mapstates[i].req_scale *= factor;
+
+ if (views != mapset.maps)
+ {
+ selectbestmap(&mapset, &mapstates[i], render_mode, pixel_size);
+ }
+ else
+ {
+ double pseudo_lat = (render_mode & 0x100) ? mapstate->req_lat : 0;
+
+ wgs2pixel(mapstates[i].dataset[0], mapstates[i].path[0],
+ mapstate->req_lat, mapstate->req_lon,
+ &mapstates[i].act_xPixel[0],
+ &mapstates[i].act_yPixel[0]);
+
+ scale2zoom(mapstates[i].dataset[0], mapstates[i].path[0],
+ mapstates[i].req_scale, pixel_size, pseudo_lat,
+ &mapstates[i].act_xZoom[0], &mapstates[i].act_yZoom[0]);
+ }
+
+ if (noZoom)
+ {
+ mapstates[i].act_xZoom[0] = 1;
+ mapstates[i].act_yZoom[0] = 1;
+ }
+
+ gtk_widget_queue_draw(canvases[i]);
+ }
+
+ render_mode &= ~0x200;
+
+ return TRUE;
+}
+
+void usage()
+{
+ fprintf(stderr, "libmap test and sample application\n\n");
+ fprintf(stderr, " usage: gmapview [input map files or directories] [options and arguments]\n\n");
+ fprintf(stderr, " -h print this message\n");
+ fprintf(stderr, " -a latitude initial latitude\n");
+ fprintf(stderr, " -o longitude initial longitude\n");
+ fprintf(stderr, " -s scale initial scale\n");
+ fprintf(stderr, " -r rotation initial rotation\n");
+ fprintf(stderr, " -p pixel size (mm) pixel size\n");
+ fprintf(stderr, " -d dpi (1/inch) pixel size\n");
+ fprintf(stderr, " -z no zoom\n");
+ fprintf(stderr, " -v n number of views\n");
+ fprintf(stderr, " -w windowed views\n");
+ fprintf(stderr, " -l linear view scale\n");
+ fprintf(stderr, " -m ratio view scale ratio\n\n");
+ fprintf(stderr, " If no input is given, gmapview uses the current directory.\n");
+ fprintf(stderr, " When the number of views equals the number of maps,\n");
+ fprintf(stderr, " each map is fixed to each view.\n");
+ fprintf(stderr, " You can combine short flags, so `-w -z' means the same as -wz or -zw.\n");
+ fprintf(stderr, "\n When gmapview is running it can be controlled with the following keys:\n");
+ fprintf(stderr, "\n + Zoom in\n");
+ fprintf(stderr, " - Zoom out\n");
+ fprintf(stderr, " m Drawing mode (Single, overview, tiled)\n");
+ fprintf(stderr, " f Filter maps (Street, topo, all)\n");
+ fprintf(stderr, " a Show alternate map\n");
+ fprintf(stderr, " c Cover if possible\n");
+ fprintf(stderr, " p Show current position\n");
+ fprintf(stderr, " s Pseudo projection\n");
+ fprintf(stderr, " g Grid\n");
+ fprintf(stderr, " t Transparent\n");
+ fprintf(stderr, " r Rotate\n");
+ fprintf(stderr, "\n Left mouse click selects a new center point.\n");
+}
+
+int main(int argc, char **argv)
+{
+ extern char *optarg;
+ extern int optind;
+ extern int optopt;
+
+ int i;
+
+ GtkWidget *windows[16];
+ GtkWidget *paned;
+ GtkWidget *box1 = NULL;
+ GtkWidget *box2 = NULL;
+
+ gboolean windowed = FALSE;
+ gboolean latSet = FALSE;
+ gboolean lonSet = FALSE;
+ gboolean scaleSet = FALSE;
+ gboolean linear = FALSE;
+ double ratio = SCALE_RATIO;
+
+ gtk_init(&argc, &argv);
+
+ mapinit(&mapsettings);
+
+ resetmap(&mapstates[0]);
+
+ while (optind < argc)
+ {
+ if (argv[optind][0] != '-' || strlen(argv[optind]) <= 1)
+ {
+ // Load maps
+ if (!addmaps(argv[optind], &mapset))
+ {
+ fprintf(stderr,
+ "Unable to open input file: %s\n",
+ argv[optind]);
+ return 1;
+ }
+
+ optind++;
+ }
+ else
+ {
+ // Option
+ int opt = getopt(argc, argv, ":ha:o:s:r:p:d:zv:wlm:");
+ if (opt != -1)
+ {
+ switch (opt)
+ {
+ case 'h':
+ usage();
+ return 1;
+
+ case 'a':
+ mapstates[0].req_lat = atof(optarg);
+ latSet = TRUE;
+ break;
+
+ case 'o':
+ mapstates[0].req_lon = atof(optarg);
+ lonSet = TRUE;
+ break;
+
+ case 's':
+ mapstates[0].req_scale = atof(optarg);
+ scaleSet = TRUE;
+ break;
+
+ case 'r':
+ mapstates[0].req_rotation = atof(optarg) * M_PI / 180;
+ break;
+
+ case 'p':
+ pixel_size = atof(optarg) / 1000;
+ break;
+
+ case 'd':
+ pixel_size = 0.0254 / atof(optarg);
+ break;
+
+ case 'z':
+ noZoom = TRUE;
+ break;
+
+ case 'v':
+ views = atoi(optarg);
+ break;
+
+ case 'w':
+ windowed = TRUE;
+ break;
+
+ case 'l':
+ linear = TRUE;
+ break;
+
+ case 'm':
+ ratio = atof(optarg);
+ break;
+
+ case ':': // No argument
+ fprintf(stderr,
+ "Option -%c is missing an argument\n",
+ (char)optopt);
+ return 1;
+
+ case '?':
+ default:
+ fprintf(stderr,
+ "Unknown option -%c\n",
+ (char)optopt);
+ return 1;
+ }
+ }
+ }
+ }
+
+ if (!mapset.maps && !addmaps(".", &mapset))
+ {
+ fprintf(stderr, "No maps in current directory\n");
+ return 1;
+ }
+
+ if (views < 0 || views > 16)
+ {
+ fprintf(stderr, "Unsupported number of views\n");
+ return 1;
+ }
+
+ {
+ GInt32 xPixel;
+ GInt32 yPixel;
+
+ double lat;
+ double lon;
+
+ int smallest = -1;
+ double smallestScale = 0;
+
+ // Find smallest map
+ for (i = 0; i < mapset.maps; i++)
+ {
+ double scale;
+
+ scale2zoom(mapset.dataset[i], mapset.path[i],
+ 1, pixel_size, 0, &scale, &scale);
+
+ if (smallest == -1 || scale < smallestScale)
+ {
+ smallest = i;
+ smallestScale = scale;
+ }
+ }
+
+ // Center on smallest map
+ center2pixel(mapset.dataset[smallest], &xPixel, &yPixel);
+ pixel2wgs(mapset.dataset[smallest], mapset.path[smallest],
+ xPixel, yPixel, &lat, &lon);
+
+ if (latSet)
+ {
+ lat = mapstates[0].req_lat;
+ }
+ if (lonSet)
+ {
+ lon = mapstates[0].req_lon;
+ }
+
+ // Init mapstates
+ for (i = 0; i < views; i++)
+ {
+ if (i)
+ resetmap(&mapstates[i]);
+
+ mapstates[i].req_lat = lat;
+ mapstates[i].req_lon = lon;
+
+ mapstates[i].req_rotation = mapstates[0].req_rotation;
+
+ if (views == mapset.maps)
+ {
+ mapstates[i].dataset[0] = mapset.dataset[i];
+ mapstates[i].path[0] = mapset.path[i];
+ mapstates[i].dataset[1] = NULL;
+ mapstates[i].path[1] = NULL;
+
+ scale2zoom(mapstates[i].dataset[0], mapstates[i].path[0],
+ 1, pixel_size, 0,
+ &mapstates[i].req_scale, &mapstates[i].req_scale);
+
+ mapstates[i].act_xZoom[0] = 1.0;
+ mapstates[i].act_yZoom[0] = 1.0;
+ }
+ else
+ {
+ if (i == 0 && !scaleSet)
+ {
+ mapstates[i].dataset[0] = mapset.dataset[smallest];
+ mapstates[i].path[0] = mapset.path[smallest];
+
+ scale2zoom(mapset.dataset[smallest], mapset.path[smallest],
+ 1, pixel_size, 0,
+ &mapstates[0].req_scale, &mapstates[0].req_scale);
+ }
+
+ // Set scales relative to smallest map
+ if (i)
+ {
+ if (linear)
+ mapstates[i].req_scale = ratio * i * mapstates[0].req_scale;
+ else
+ mapstates[i].req_scale = ratio * mapstates[i - 1].req_scale;
+ }
+
+ selectbestmap(&mapset, &mapstates[i], render_mode, pixel_size);
+ }
+
+ if (noZoom)
+ {
+ mapstates[i].act_xZoom[0] = 1;
+ mapstates[i].act_yZoom[0] = 1;
+ }
+
+ wgs2pixel(mapstates[i].dataset[0], mapstates[i].path[0], lat, lon,
+ &mapstates[i].act_xPixel[0], &mapstates[i].act_yPixel[0]);
+ }
+ }
+
+ if (views == 1)
+ windowed = TRUE;
+
+ if (windowed)
+ {
+ for (i = 0; i < views; i++)
+ {
+ windows[i] = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+ g_signal_connect(G_OBJECT(windows[i]), "delete-event",
+ G_CALLBACK(gtk_main_quit), NULL);
+
+ g_signal_connect(G_OBJECT(windows[i]), "key_press_event",
+ G_CALLBACK(key_press), mapstates);
+ }
+ }
+ else
+ {
+ windows[0] = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+ g_signal_connect(G_OBJECT(windows[0]), "delete-event",
+ G_CALLBACK(gtk_main_quit), NULL);
+
+ g_signal_connect(G_OBJECT(windows[0]), "key_press_event",
+ G_CALLBACK(key_press), mapstates);
+
+ paned = gtk_hpaned_new();
+
+ gtk_container_add(GTK_CONTAINER(windows[0]), paned);
+
+ box1 = gtk_vbox_new(TRUE, 4);
+ box2 = gtk_vbox_new(TRUE, 4);
+
+ gtk_paned_pack1(GTK_PANED(paned), box1, FALSE, FALSE);
+ gtk_paned_pack2(GTK_PANED(paned), box2, FALSE, FALSE);
+ }
+
+ for (i = 0; i < views; i++)
+ {
+ canvases[i] = gtk_drawing_area_new();
+
+ gtk_widget_set_size_request(canvases[i], 100, 100);
+
+ gtk_widget_add_events(canvases[i], GDK_BUTTON_PRESS_MASK);
+
+ g_signal_connect(G_OBJECT(canvases[i]), "expose-event",
+ G_CALLBACK(expose), &mapstates[i]);
+
+ g_signal_connect(G_OBJECT(canvases[i]), "button_press_event",
+ G_CALLBACK(button_press), &mapstates[i]);
+
+ if (windowed)
+ {
+ gtk_container_add(GTK_CONTAINER(windows[i]), canvases[i]);
+
+ gtk_widget_show_all(windows[i]);
+ }
+ else
+ {
+ if ((i & 1 && (!(views & 1) || i < 2)) ||
+ (!(i & 1) && (views & 1) && (i > 1)))
+ {
+ gtk_box_pack_start_defaults(GTK_BOX(box2), canvases[i]);
+ }
+ else
+ {
+ gtk_box_pack_start_defaults(GTK_BOX(box1), canvases[i]);
+ }
+ }
+ }
+
+ if (!windowed)
+ gtk_widget_show_all(windows[0]);
+
+#ifdef HAVE_GPS
+ init_gps();
+#endif
+
+ gtk_main();
+
+#ifdef HAVE_GPS
+ free_gps();
+#endif
+
+ freemaps(&mapset);
+
+ return 0;
+}
diff --git a/src/util/gps.c b/src/util/gps.c
new file mode 100644
index 0000000..0340b15
--- /dev/null
+++ b/src/util/gps.c
@@ -0,0 +1,60 @@
+//
+// Copyright (c) 2005 -- Daniel Wallner
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#ifdef HAVE_GPS
+
+#include <../lib_map/gps.h>
+
+#include <stdio.h>
+
+struct gps_data_t *gpsdata;
+pthread_t handler;
+
+void gps_callback(struct gps_data_t *sentence,
+ char *buf, size_t len, int level)
+{
+ printf("gps\n");
+}
+
+void init_gps()
+{
+ gpsdata = gps_open("localhost", DEFAULT_GPSD_PORT);
+
+ if (!gpsdata)
+ {
+ fprintf(stderr, "Unable to open gps\n");
+ return;
+ }
+
+ if (!gps_set_callback(gpsdata, gps_callback, &handler))
+ {
+ fprintf(stderr, "Unable to create gps thread\n");
+ return;
+ }
+}
+
+void free_gps()
+{
+ if (gpsdata)
+ {
+ gps_del_callback(gpsdata, &handler);
+ gps_close(gpsdata);
+ }
+}
+
+#endif
diff --git a/src/util/mmapview.c b/src/util/mmapview.c
new file mode 100644
index 0000000..5988abb
--- /dev/null
+++ b/src/util/mmapview.c
@@ -0,0 +1,762 @@
+//
+// Copyright (c) 2005 -- Daniel Wallner
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#include "../lib_map/map.h"
+
+#include <stdio.h>
+#ifdef USE_CAIRO
+#include <cairo.h>
+#endif
+#include <Carbon/Carbon.h>
+
+#include <unistd.h>
+#include <stdlib.h>
+
+void init_gps();
+void free_gps();
+
+#define PIXEL_SIZE 0.22E-3
+#define SCALE_RATIO 10
+
+typedef struct
+{
+ HIViewRef view;
+ MapState *mapstate;
+}
+ViewData;
+
+MapSettings mapsettings;
+MapSet mapset;
+MapState mapstates[16];
+ViewData canvases[16];
+int views = 1;
+int render_mode = 0x100;
+int cover = 0;
+int draw_transparent = 0;
+double pixel_size = PIXEL_SIZE;
+int noZoom = FALSE;
+
+static void expose(CGContextRef gc, int width, int height, MapState *mapstate)
+{
+#ifdef USE_CAIRO
+#else
+ MapGC mgc;
+
+ memset((void*)&mgc, 0, sizeof(mgc));
+
+ mgc.quartz_gc = gc;
+
+ if (cover)
+ coverifpossible(mapstate, width, height);
+
+ drawmap(mapstate, &mgc, width, height, draw_transparent);
+
+ drawmarkers(&mgc, width, height,
+ &mapsettings, mapstate, pixel_size,
+ 0, 0);
+#endif
+}
+
+static void button_press(int x, int y, MapState *mapstate)
+{
+ int i;
+
+ mapsettings.posmode = TRUE;
+
+ screen2wgs(mapstate, x, y,
+ &mapstate->req_lat, &mapstate->req_lon);
+
+ fprintf(stderr, "new center: %lf;%lf\n",
+ mapstate->req_lat, mapstate->req_lon);
+
+ for (i = 0; i < views; i++)
+ {
+ mapstates[i].req_lat = mapstate->req_lat;
+ mapstates[i].req_lon = mapstate->req_lon;
+
+ if (views != mapset.maps)
+ {
+ selectbestmap(&mapset, &mapstates[i], render_mode, pixel_size);
+ }
+ else
+ {
+ double pseudo_lat = (render_mode & 0x100) ? mapstate->req_lat : 0;
+
+ wgs2pixel(mapstates[i].dataset[0], mapstates[i].path[0],
+ mapstate->req_lat, mapstate->req_lon,
+ &mapstates[i].act_xPixel[0], &mapstates[i].act_yPixel[0]);
+
+ scale2zoom(mapstates[i].dataset[0], mapstates[i].path[0],
+ mapstates[i].req_scale, pixel_size, pseudo_lat,
+ &mapstates[i].act_xZoom[0], &mapstates[i].act_yZoom[0]);
+ }
+
+ if (noZoom)
+ {
+ mapstates[i].act_xZoom[0] = 1;
+ mapstates[i].act_yZoom[0] = 1;
+ }
+
+ HIViewSetNeedsDisplay(canvases[i].view, TRUE);
+ }
+}
+
+static void key_press(char key, MapState *mapstate)
+{
+ int i;
+
+ int redraw = 0;
+
+ double factor = 1;
+
+ switch (key)
+ {
+ case '+':
+ factor = 1 / 1.5;
+ redraw = 1;
+ break;
+
+ case '-':
+ factor = 1.5;
+ redraw = 1;
+ break;
+
+ case 'm':
+ render_mode = (render_mode & 0xfff0) + (((render_mode & 0x0f) + 1) % 3);
+ redraw = 1;
+ break;
+
+ case 'f':
+ render_mode = (render_mode & 0xff0f) +
+ (((((render_mode & 0xf0) >> 4) + 1) % 3) << 4);
+ redraw = 1;
+ break;
+
+ case 'a':
+ render_mode = render_mode | 0x200;
+ redraw = 1;
+ break;
+
+ case 'c':
+ cover = !cover;
+ redraw = 1;
+ break;
+
+ case 'p':
+ mapsettings.havepos = !mapsettings.havepos;
+ redraw = 1;
+ break;
+
+ case 's':
+ render_mode ^= 0x100;
+ redraw = 1;
+ break;
+
+ case 'g':
+ mapsettings.drawgrid = !mapsettings.drawgrid;
+ redraw = 1;
+ break;
+
+ case 't':
+ draw_transparent = !draw_transparent;
+ redraw = 1;
+ break;
+
+ case 'r':
+ mapstate->req_rotation += 45;
+ if (mapstate->req_rotation >= 360)
+ mapstate->req_rotation -= 360;
+ redraw = 1;
+ break;
+ }
+
+ fprintf(stderr, "mode: %X\n", render_mode);
+
+ if (redraw)
+ for (i = 0; i < views; i++)
+ {
+ mapstates[i].req_scale *= factor;
+
+ if (views != mapset.maps)
+ {
+ selectbestmap(&mapset, &mapstates[i], render_mode, pixel_size);
+ }
+ else
+ {
+ double pseudo_lat = (render_mode & 0x100) ? mapstate->req_lat : 0;
+
+ wgs2pixel(mapstates[i].dataset[0], mapstates[i].path[0],
+ mapstate->req_lat, mapstate->req_lon,
+ &mapstates[i].act_xPixel[0],
+ &mapstates[i].act_yPixel[0]);
+
+ scale2zoom(mapstates[i].dataset[0], mapstates[i].path[0],
+ mapstates[i].req_scale, pixel_size, pseudo_lat,
+ &mapstates[i].act_xZoom[0], &mapstates[i].act_yZoom[0]);
+ }
+
+ if (noZoom)
+ {
+ mapstates[i].act_xZoom[0] = 1;
+ mapstates[i].act_yZoom[0] = 1;
+ }
+
+ HIViewSetNeedsDisplay(canvases[i].view, TRUE);
+ }
+
+ render_mode &= ~0x200;
+}
+
+static pascal OSStatus OnViewEvent(EventHandlerCallRef handler,
+ EventRef event, ViewData *data)
+{
+ OSStatus err = CallNextEventHandler(handler, event);
+ UInt32 kind = GetEventKind(event);
+
+ if (err)
+ return err;
+
+ switch (kind)
+ {
+ case kEventControlBoundsChanged:
+ // Force redraw
+ HIViewSetNeedsDisplay(data->view, TRUE);
+ return noErr;
+
+ case kEventControlClick:
+ {
+ HIPoint where;
+ err = GetEventParameter(event, kEventParamMouseLocation, typeHIPoint,
+ NULL, sizeof( HIPoint ), NULL, &where);
+ Point local;
+ local.h = where.x;
+ local.v = where.y;
+ QDGlobalToLocalPoint(GetWindowPort(GetControlOwner(data->view)),
+ &local);
+ button_press(local.h, local.v, data->mapstate);
+ }
+ return noErr;
+
+ case kEventControlDraw:
+ {
+ // Get CGContextRef
+ CGContextRef gc;
+ err = GetEventParameter(event,
+ kEventParamCGContextRef,
+ typeCGContextRef,
+ NULL,
+ sizeof(CGContextRef),
+ NULL,
+ &gc);
+ if (err)
+ return err;
+
+ CGRect r;
+
+ HIViewGetBounds(data->view, &r);
+
+ expose(gc, r.size.width, r.size.height, data->mapstate);
+ }
+ return noErr;
+ }
+
+ return err;
+}
+
+static pascal OSStatus OnWindowEvent(EventHandlerCallRef handler,
+ EventRef event, MapState *mapstate)
+{
+ UInt32 kind = GetEventKind(event);
+
+ switch (kind)
+ {
+ case kEventRawKeyDown:
+ {
+ char charCode;
+ GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar,
+ NULL, sizeof(char), NULL, &charCode);
+ key_press(charCode, mapstate);
+ }
+ break;
+
+ case kEventWindowClose:
+ QuitApplicationEventLoop();
+ break;
+
+ default:
+ return eventNotHandledErr;
+ }
+
+ return noErr;
+}
+
+WindowRef CreateWindow(int width, int height, MapState *mapstate)
+{
+ WindowRef window;
+
+ Rect rect;
+ SetRect(&rect, 0, 0, width, height);
+
+ OSStatus err = CreateNewWindow(kDocumentWindowClass,
+ kWindowStandardDocumentAttributes |
+ kWindowStandardHandlerAttribute |
+ kWindowCompositingAttribute |
+ kWindowInWindowMenuAttribute,
+ &rect,
+ &window);
+
+ // Setup window
+ Str255 title = "\pmmapview";
+ SetWTitle(window, title);
+ RepositionWindow(window, NULL, kWindowCascadeOnMainScreen);
+
+ // Change size box to transparent
+ HIViewRef growThumb = NULL;
+ HIViewFindByID(HIViewGetRoot(window), kHIViewWindowGrowBoxID, &growThumb);
+ if (growThumb != NULL)
+ {
+ err = HIGrowBoxViewSetTransparent(growThumb, TRUE);
+ }
+
+ // Setup window events
+ InstallStandardEventHandler(GetWindowEventTarget(window));
+
+ EventTypeSpec eventList[] = {
+ {kEventClassKeyboard, kEventRawKeyDown},
+ {kEventClassWindow, kEventWindowClickContentRgn},
+ {kEventClassWindow, kEventWindowClose}};
+
+ InstallWindowEventHandler(window, NewEventHandlerUPP
+ ((EventHandlerProcPtr)OnWindowEvent),
+ GetEventTypeCount(eventList),
+ eventList, (void*)mapstate, NULL);
+
+ return window;
+}
+
+HIViewRef CreateMapView(HIViewRef parent, int left, int top,
+ int right, int bottom, ViewData *data)
+{
+ HIViewRef view;
+
+ HIRect bounds = CGRectMake(left, top, right, bottom);
+
+ OSStatus err = HIObjectCreate(kHIViewClassID, nil, (HIObjectRef *)&view);
+ data->view = view;
+
+ err = HIViewChangeAttributes(view, kHIViewAllowsSubviews, 0);
+ err = HIViewAddSubview(parent, view);
+ err = HIViewSetFrame(view, &bounds);
+ err = HIViewSetVisible(view, true);
+
+ // Setup view events
+ static EventTypeSpec viewEvents[] = {
+ {kEventClassControl, kEventControlClick},
+ {kEventClassControl, kEventControlBoundsChanged},
+ {kEventClassControl, kEventControlDraw}};
+
+ InstallControlEventHandler(view,
+ NewEventHandlerUPP((EventHandlerProcPtr)OnViewEvent),
+ GetEventTypeCount(viewEvents),
+ viewEvents,
+ (void*)data,
+ NULL);
+
+ return view;
+}
+
+void usage()
+{
+ fprintf(stderr, "libmap test and sample application\n\n");
+ fprintf(stderr, " usage: gmapview [input map files or directories] [options and arguments]\n\n");
+ fprintf(stderr, " -h print this message\n");
+ fprintf(stderr, " -a latitude initial latitude\n");
+ fprintf(stderr, " -o longitude initial longitude\n");
+ fprintf(stderr, " -s scale initial scale\n");
+ fprintf(stderr, " -r rotation initial rotation\n");
+ fprintf(stderr, " -p pixel size (mm) pixel size\n");
+ fprintf(stderr, " -d dpi (1/inch) pixel size\n");
+ fprintf(stderr, " -z no zoom\n");
+ fprintf(stderr, " -v n number of views\n");
+ fprintf(stderr, " -w windowed views\n");
+ fprintf(stderr, " -l linear view scale\n");
+ fprintf(stderr, " -m ratio view scale ratio\n\n");
+ fprintf(stderr, " If no input is given, gmapview uses the current directory.\n");
+ fprintf(stderr, " When the number of views equals the number of maps,\n");
+ fprintf(stderr, " each map is fixed to each view.\n");
+ fprintf(stderr, " You can combine short flags, so `-w -z' means the same as -wz or -zw.\n");
+ fprintf(stderr, "\n When gmapview is running it can be controlled with the following keys:\n");
+ fprintf(stderr, "\n + Zoom in\n");
+ fprintf(stderr, " - Zoom out\n");
+ fprintf(stderr, " m Drawing mode (Single, overview, tiled)\n");
+ fprintf(stderr, " f Filter maps (Street, topo, all)\n");
+ fprintf(stderr, " a Show alternate map\n");
+ fprintf(stderr, " c Cover if possible\n");
+ fprintf(stderr, " p Show current position\n");
+ fprintf(stderr, " s Pseudo projection\n");
+ fprintf(stderr, " g Grid\n");
+ fprintf(stderr, " t Transparent\n");
+ fprintf(stderr, " r Rotate\n");
+ fprintf(stderr, "\n Left mouse click selects a new center point.\n");
+}
+
+int main(int argc, char **argv)
+{
+ extern char *optarg;
+ extern int optind;
+ extern int optopt;
+
+ int i;
+
+ WindowRef windows[16];
+ //GtkWidget *paned;
+ //GtkWidget *box1;
+ //GtkWidget *box2;
+
+ int windowed = FALSE;
+ int latSet = FALSE;
+ int lonSet = FALSE;
+ int scaleSet = FALSE;
+ int linear = FALSE;
+ double ratio = SCALE_RATIO;
+
+ mapinit(&mapsettings);
+
+ resetmap(&mapstates[0]);
+
+ while (optind < argc)
+ {
+ if (argv[optind][0] != '-' || strlen(argv[optind]) <= 1)
+ {
+ // Load maps
+ if (!addmaps(argv[optind], &mapset))
+ {
+ fprintf(stderr,
+ "Unable to open input file: %s\n",
+ argv[optind]);
+ return 1;
+ }
+
+ optind++;
+ }
+ else
+ {
+ // Option
+ int opt = getopt(argc, argv, ":ha:o:s:r:p:d:zv:wlm:");
+ if (opt != -1)
+ {
+ switch (opt)
+ {
+ case 'h':
+ usage();
+ return 1;
+
+ case 'a':
+ mapstates[0].req_lat = atof(optarg);
+ latSet = TRUE;
+ break;
+
+ case 'o':
+ mapstates[0].req_lon = atof(optarg);
+ lonSet = TRUE;
+ break;
+
+ case 's':
+ mapstates[0].req_scale = atof(optarg);
+ scaleSet = TRUE;
+ break;
+
+ case 'r':
+ mapstates[0].req_rotation = atof(optarg) * M_PI / 180;
+ break;
+
+ case 'p':
+ pixel_size = atof(optarg) / 1000;
+ break;
+
+ case 'd':
+ pixel_size = 0.0254 / atof(optarg);
+ break;
+
+ case 'z':
+ noZoom = TRUE;
+ break;
+
+ case 'v':
+ views = atoi(optarg);
+ break;
+
+ case 'w':
+ windowed = TRUE;
+ break;
+
+ case 'l':
+ linear = TRUE;
+ break;
+
+ case 'm':
+ ratio = atof(optarg);
+ break;
+
+ case ':': // No argument
+ fprintf(stderr,
+ "Option -%c is missing an argument\n",
+ (char)optopt);
+ return 1;
+
+ case '?':
+ default:
+ fprintf(stderr,
+ "Unknown option -%c\n",
+ (char)optopt);
+ return 1;
+ }
+ }
+ }
+ }
+
+ if (!mapset.maps && !addmaps(".", &mapset))
+ {
+ fprintf(stderr, "No maps in current directory\n");
+ return 1;
+ }
+
+ if (views < 0 || views > 16)
+ {
+ fprintf(stderr, "Unsupported number of views\n");
+ return 1;
+ }
+
+ {
+ GInt32 xPixel;
+ GInt32 yPixel;
+
+ double lat;
+ double lon;
+
+ int smallest = -1;
+ double smallestScale = 0;
+
+ // Find smallest map
+ for (i = 0; i < mapset.maps; i++)
+ {
+ double scale;
+
+ scale2zoom(mapset.dataset[i], mapset.path[i],
+ 1, pixel_size, 0, &scale, &scale);
+
+ if (smallest == -1 || scale < smallestScale)
+ {
+ smallest = i;
+ smallestScale = scale;
+ }
+ }
+
+ // Center on smallest map
+ center2pixel(mapset.dataset[smallest], &xPixel, &yPixel);
+ pixel2wgs(mapset.dataset[smallest], mapset.path[smallest],
+ xPixel, yPixel, &lat, &lon);
+
+ if (latSet)
+ {
+ lat = mapstates[0].req_lat;
+ }
+ if (lonSet)
+ {
+ lon = mapstates[0].req_lon;
+ }
+
+ // Init mapstates
+ for (i = 0; i < views; i++)
+ {
+ if (i)
+ resetmap(&mapstates[i]);
+
+ mapstates[i].req_lat = lat;
+ mapstates[i].req_lon = lon;
+
+ mapstates[i].req_rotation = mapstates[0].req_rotation;
+
+ if (views == mapset.maps)
+ {
+ mapstates[i].dataset[0] = mapset.dataset[i];
+ mapstates[i].path[0] = mapset.path[i];
+ mapstates[i].dataset[1] = NULL;
+ mapstates[i].path[1] = NULL;
+
+ scale2zoom(mapstates[i].dataset[0], mapstates[i].path[0],
+ 1, pixel_size, 0,
+ &mapstates[i].req_scale, &mapstates[i].req_scale);
+
+ mapstates[i].act_xZoom[0] = 1.0;
+ mapstates[i].act_yZoom[0] = 1.0;
+ }
+ else
+ {
+ if (i == 0 && !scaleSet)
+ {
+ mapstates[i].dataset[0] = mapset.dataset[smallest];
+ mapstates[i].path[0] = mapset.path[smallest];
+
+ scale2zoom(mapset.dataset[smallest], mapset.path[smallest],
+ 1, pixel_size, 0,
+ &mapstates[0].req_scale, &mapstates[0].req_scale);
+ }
+
+ // Set scales relative to smallest map
+ if (i)
+ {
+ if (linear)
+ mapstates[i].req_scale = ratio * i * mapstates[0].req_scale;
+ else
+ mapstates[i].req_scale = ratio * mapstates[i - 1].req_scale;
+ }
+
+ selectbestmap(&mapset, &mapstates[i], render_mode, pixel_size);
+ }
+
+ if (noZoom)
+ {
+ mapstates[i].act_xZoom[0] = 1;
+ mapstates[i].act_yZoom[0] = 1;
+ }
+
+ wgs2pixel(mapstates[i].dataset[0], mapstates[i].path[0], lat, lon,
+ &mapstates[i].act_xPixel[0], &mapstates[i].act_yPixel[0]);
+ }
+ }
+
+ if (views == 1)
+ windowed = TRUE;
+
+ CGRect screenRect = CGDisplayBounds(kCGDirectMainDisplay);
+
+ int width = screenRect.size.width;
+ int height = screenRect.size.height;
+
+ width = width * 3 / 4;
+ height = height * 5 / 8;
+
+ if (windowed)
+ {
+ width /= 2;
+ height /= 2;
+ }
+
+ if (windowed)
+ {
+ for (i = 0; i < views; i++)
+ {
+ windows[i] = CreateWindow(width, height, &mapstates[i]);
+ }
+ }
+ else
+ {
+ windows[0] = CreateWindow(width, height, &mapstates[0]);
+
+ //HIViewRef rootView = HIViewGetRoot(windows[0]);
+ Rect rect;
+
+ HIViewRef separator;
+
+ SetRect(&rect, width / 2 - 2, 0, width / 2 + 2, height);
+ CreateSeparatorControl(windows[0], &rect, &separator);
+ //HIViewAddSubview(rootView, separator);
+
+ //err = HIViewChangeAttributes(view, kHIViewAllowsSubviews, 0);
+ //err = HIViewAddSubview(parent, view);
+ //err = HIViewSetFrame(view, &bounds);
+ //err = HIViewSetVisible(view, true);
+
+/*
+ paned = gtk_hpaned_new();
+
+ gtk_container_add(GTK_CONTAINER(windows[0]), paned);
+
+ box1 = gtk_vbox_new(TRUE, 4);
+ box2 = gtk_vbox_new(TRUE, 4);
+
+ gtk_paned_pack1(GTK_PANED(paned), box1, FALSE, FALSE);
+ gtk_paned_pack2(GTK_PANED(paned), box2, FALSE, FALSE);*/
+ }
+
+ for (i = 0; i < views; i++)
+ {
+ canvases[i].mapstate = &mapstates[i];
+
+ if (windowed)
+ {
+ HIViewRef root = NULL;
+ OSStatus err = HIViewFindByID(HIViewGetRoot(windows[i]), kHIViewWindowContentID, &root);
+
+ HIViewRef view = CreateMapView(root, 0, 0, width, height, &canvases[i]);
+
+ HILayoutInfo li;
+ li.version = kHILayoutInfoVersionZero;
+ err = HIViewGetLayoutInfo(view, &li);
+ li.binding.top.toView = root;
+ li.binding.top.kind = kHILayoutBindTop;
+ li.binding.bottom.toView = root;
+ li.binding.bottom.kind = kHILayoutBindBottom;
+ li.binding.left.toView = root;
+ li.binding.left.kind = kHILayoutBindLeft;
+ li.binding.right.toView = root;
+ li.binding.right.kind = kHILayoutBindRight;
+ err = HIViewSetLayoutInfo(view, &li);
+
+ ShowWindow(windows[i]);
+ }
+ else
+ {
+ HIViewRef root = NULL;
+ OSStatus err = HIViewFindByID(HIViewGetRoot(windows[0]),
+ kHIViewWindowContentID, &root);
+
+ int viewTop = height * (i / 2) / ((views + 1) / 2);
+ int viewBot = height * (i / 2 + 1) / ((views + 1) / 2);
+ if ((i & 1 && (!(views & 1) || i < 2)) ||
+ (!(i & 1) && (views & 1) && (i > 1)))
+ {
+ HIViewRef view = CreateMapView(root, 0, viewTop,
+ width / 2 - 2, viewBot, &canvases[i]);
+ }
+ else
+ {
+ HIViewRef view = CreateMapView(root, width / 2 + 2, viewTop,
+ width / 2, viewBot, &canvases[i]);
+ }
+ }
+ }
+
+ if (!windowed)
+ ShowWindow(windows[0]);
+
+#ifdef HAVE_GPS
+ init_gps();
+#endif
+
+ RunApplicationEventLoop();
+
+#ifdef HAVE_GPS
+ free_gps();
+#endif
+
+ freemaps(&mapset);
+
+ return 0;
+}
diff --git a/src/util/qmapview.cpp b/src/util/qmapview.cpp
new file mode 100644
index 0000000..38eef1a
--- /dev/null
+++ b/src/util/qmapview.cpp
@@ -0,0 +1,633 @@
+//
+// Copyright (c) 2005 -- Daniel Wallner
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+// Qt API reference:
+// http://doc.trolltech.com/
+
+#include "../lib_map/map.h"
+
+#include <qapplication.h>
+#include <qmainwindow.h>
+#include <qwidget.h>
+#include <qsplitter.h>
+#include <qlayout.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <stdio.h>
+#ifdef USE_CAIRO
+#include <cairo.h>
+#include <cairo-xlib.h>
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+
+extern "C" {
+ void init_gps();
+ void free_gps();
+}
+
+#define PIXEL_SIZE 0.22E-3
+#define SCALE_RATIO 10
+
+class MapWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ MapWidget(QWidget *parent, MapState *mapstate);
+ ~MapWidget();
+
+protected:
+ void paintEvent(QPaintEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+
+private:
+#ifdef USE_CAIRO
+ cairo_t *m_cr;
+ cairo_surface_t *m_surf;
+#endif
+ MapState *m_mapstate;
+};
+
+MapSettings mapsettings;
+MapSet mapset;
+MapState mapstates[16];
+MapWidget *canvases[16];
+int views = 1;
+int render_mode = 0x100;
+int cover = 0;
+int transparent = 0;
+double pixel_size = PIXEL_SIZE;
+int noZoom = 0;
+
+
+MapWidget::MapWidget(QWidget *parent, MapState *mapstate):
+ QWidget(parent, "MapWidget"),
+ m_mapstate(mapstate)
+{
+#ifdef USE_CAIRO
+ m_surf = cairo_xlib_surface_create((Display *)x11AppDisplay(),
+ (Drawable)handle(),
+ (Visual *)x11Visual(),
+ width(), height());
+ m_cr = cairo_create(m_surf);
+ cairo_surface_destroy(m_surf);
+#endif
+
+ setFocus();
+ setFocusPolicy(QWidget::StrongFocus);
+ setBackgroundMode(Qt::NoBackground);
+}
+
+MapWidget::~MapWidget()
+{
+#ifdef USE_CAIRO
+ cairo_destroy(m_cr);
+ m_cr = 0;
+#endif
+}
+
+void MapWidget::paintEvent(QPaintEvent *)
+{
+#ifdef USE_CAIRO
+ MapGC mgc;
+
+ memset((void*)&mgc, 0, sizeof(mgc));
+
+ m_surf = cairo_get_target(m_cr);
+ cairo_xlib_surface_set_drawable(m_surf, handle(), width(), height());
+ mgc.cairo_cr = m_cr;
+
+ if (cover)
+ coverifpossible(m_mapstate, width(), height());
+
+ cairo_save(m_cr);
+
+ drawmap(m_mapstate, &mgc, width(), height(), transparent);
+
+ drawmarkers(&mgc, width(), height(),
+ &mapsettings, m_mapstate, pixel_size,
+ 0, 0);
+
+ cairo_restore(m_cr);
+#else
+ QPainter painter(this);
+
+ MapGC mgc;
+
+ memset((void*)&mgc, 0, sizeof(mgc));
+
+ mgc.qt_painter = &painter;
+
+ if (cover)
+ coverifpossible(m_mapstate, width(), height());
+
+ drawmap(m_mapstate, &mgc, width(), height(), transparent);
+
+ drawmarkers(&mgc, width(), height(),
+ &mapsettings, m_mapstate, pixel_size,
+ 0, 0);
+#endif
+}
+
+void MapWidget::mousePressEvent(QMouseEvent *event)
+{
+ int i;
+
+ mapsettings.posmode = TRUE;
+
+ screen2wgs(m_mapstate, event->x(), event->y(),
+ &m_mapstate->req_lat, &m_mapstate->req_lon);
+
+ fprintf(stderr, "new center: %lf;%lf\n",
+ m_mapstate->req_lat, m_mapstate->req_lon);
+
+ for (i = 0; i < views; i++)
+ {
+ mapstates[i].req_lat = m_mapstate->req_lat;
+ mapstates[i].req_lon = m_mapstate->req_lon;
+
+ if (views != mapset.maps)
+ {
+ selectbestmap(&mapset, &mapstates[i], render_mode, pixel_size);
+ }
+ else
+ {
+ double pseudo_lat = (render_mode & 0x100) ? m_mapstate->req_lat : 0;
+
+ wgs2pixel(mapstates[i].dataset[0], mapstates[i].path[0],
+ m_mapstate->req_lat, m_mapstate->req_lon,
+ &mapstates[i].act_xPixel[0], &mapstates[i].act_yPixel[0]);
+
+ scale2zoom(mapstates[i].dataset[0], mapstates[i].path[0],
+ mapstates[i].req_scale, pixel_size, pseudo_lat,
+ &mapstates[i].act_xZoom[0], &mapstates[i].act_yZoom[0]);
+ }
+
+ if (noZoom)
+ {
+ mapstates[i].act_xZoom[0] = 1;
+ mapstates[i].act_yZoom[0] = 1;
+ }
+
+ canvases[i]->update();
+ }
+}
+
+void MapWidget::keyPressEvent(QKeyEvent *event)
+{
+ int i;
+
+ int redraw = 0;
+
+ double factor = 1;
+
+ switch (event->ascii())
+ {
+ case '+':
+ factor = 1 / 1.5;
+ redraw = 1;
+ break;
+
+ case '-':
+ factor = 1.5;
+ redraw = 1;
+ break;
+
+ case 'm':
+ render_mode = (render_mode & 0xfff0) + (((render_mode & 0x0f) + 1) % 3);
+ redraw = 1;
+ break;
+
+ case 'f':
+ render_mode = (render_mode & 0xff0f) +
+ (((((render_mode & 0xf0) >> 4) + 1) % 3) << 4);
+ redraw = 1;
+ break;
+
+ case 'a':
+ render_mode = render_mode | 0x200;
+ redraw = 1;
+ break;
+
+ case 'c':
+ cover = !cover;
+ redraw = 1;
+ break;
+
+ case 'p':
+ mapsettings.havepos = !mapsettings.havepos;
+ redraw = 1;
+ break;
+
+ case 's':
+ render_mode ^= 0x100;
+ redraw = 1;
+ break;
+
+ case 'g':
+ mapsettings.drawgrid = !mapsettings.drawgrid;
+ redraw = 1;
+ break;
+
+ case 't':
+ transparent = !transparent;
+ redraw = 1;
+ break;
+
+ case 'r':
+ m_mapstate->req_rotation += 45;
+ if (m_mapstate->req_rotation >= 360)
+ m_mapstate->req_rotation -= 360;
+ redraw = 1;
+ break;
+ }
+
+ fprintf(stderr, "mode: %X\n", render_mode);
+
+ if (redraw)
+ for (i = 0; i < views; i++)
+ {
+ mapstates[i].req_scale *= factor;
+
+ if (views != mapset.maps)
+ {
+ selectbestmap(&mapset, &mapstates[i], render_mode, pixel_size);
+ }
+ else
+ {
+ double pseudo_lat = (render_mode & 0x100) ?
+ m_mapstate->req_lat : 0;
+
+ wgs2pixel(mapstates[i].dataset[0], mapstates[i].path[0],
+ m_mapstate->req_lat, m_mapstate->req_lon,
+ &mapstates[i].act_xPixel[0],
+ &mapstates[i].act_yPixel[0]);
+
+ scale2zoom(mapstates[i].dataset[0], mapstates[i].path[0],
+ mapstates[i].req_scale, pixel_size, pseudo_lat,
+ &mapstates[i].act_xZoom[0], &mapstates[i].act_yZoom[0]);
+ }
+
+ if (noZoom)
+ {
+ mapstates[i].act_xZoom[0] = 1;
+ mapstates[i].act_yZoom[0] = 1;
+ }
+
+ canvases[i]->update();
+ }
+
+ render_mode &= ~0x200;
+}
+
+void usage()
+{
+ fprintf(stderr, "libmap test and sample application\n\n");
+ fprintf(stderr, " usage: qmapview [input map files or directories] [options and arguments]\n\n");
+ fprintf(stderr, " -h print this message\n");
+ fprintf(stderr, " -a latitude initial latitude\n");
+ fprintf(stderr, " -o longitude initial longitude\n");
+ fprintf(stderr, " -s scale initial scale\n");
+ fprintf(stderr, " -r rotation initial rotation\n");
+ fprintf(stderr, " -p pixel size (mm) pixel size\n");
+ fprintf(stderr, " -d dpi (1/inch) pixel size\n");
+ fprintf(stderr, " -z no zoom\n");
+ fprintf(stderr, " -v n number of views\n");
+ fprintf(stderr, " -w windowed views\n");
+ fprintf(stderr, " -l linear view scale\n");
+ fprintf(stderr, " -m ratio view scale ratio\n\n");
+ fprintf(stderr, " If no input is given, gmapview uses the current directory.\n");
+ fprintf(stderr, " When the number of views equals the number of maps,\n");
+ fprintf(stderr, " each map is fixed to each view.\n");
+ fprintf(stderr, " You can combine short flags, so `-w -z' means the same as -wz or -zw.\n");
+ fprintf(stderr, "\n When qmapview is running it can be controlled with the following keys:\n");
+ fprintf(stderr, "\n + Zoom in\n");
+ fprintf(stderr, " - Zoom out\n");
+ fprintf(stderr, " m Drawing mode (Single, overview, tiled)\n");
+ fprintf(stderr, " f Filter maps (Street, topo, all)\n");
+ fprintf(stderr, " a Show alternate map\n");
+ fprintf(stderr, " c Cover if possible\n");
+ fprintf(stderr, " p Show current position\n");
+ fprintf(stderr, " s Pseudo projection\n");
+ fprintf(stderr, " g Grid\n");
+ fprintf(stderr, " t Transparent\n");
+ fprintf(stderr, " r Rotate\n");
+ fprintf(stderr, "\n Left mouse click selects a new center point.\n");
+}
+
+int main(int argc, char **argv)
+{
+ extern char *optarg;
+ extern int optind;
+ extern int optopt;
+
+ int i;
+
+ int latSet = FALSE;
+ int lonSet = FALSE;
+ int scaleSet = FALSE;
+ int linear = FALSE;
+ int windowed = FALSE;
+ double ratio = SCALE_RATIO;
+
+ QApplication theApp(argc, argv);
+
+ mapinit(&mapsettings);
+
+ resetmap(&mapstates[0]);
+
+ while (optind < argc)
+ {
+ if (argv[optind][0] != '-' || strlen(argv[optind]) <= 1)
+ {
+ // Load maps
+ if (!addmaps(argv[optind], &mapset))
+ {
+ fprintf(stderr,
+ "Unable to open input file: %s\n",
+ argv[optind]);
+ return 1;
+ }
+
+ optind++;
+ }
+ else
+ {
+ // Option
+ int opt = getopt(argc, argv, ":ha:o:s:r:p:d:zv:wlm:");
+ if (opt != -1)
+ {
+ switch (opt)
+ {
+ case 'h':
+ usage();
+ return 1;
+
+ case 'a':
+ mapstates[0].req_lat = atof(optarg);
+ latSet = TRUE;
+ break;
+
+ case 'o':
+ mapstates[0].req_lon = atof(optarg);
+ lonSet = TRUE;
+ break;
+
+ case 's':
+ mapstates[0].req_scale = atof(optarg);
+ scaleSet = TRUE;
+ break;
+
+ case 'r':
+ mapstates[0].req_rotation = atof(optarg) * M_PI / 180;
+ break;
+
+ case 'p':
+ pixel_size = atof(optarg) / 1000;
+ break;
+
+ case 'd':
+ pixel_size = 0.0254 / atof(optarg);
+ break;
+
+ case 'z':
+ noZoom = TRUE;
+ break;
+
+ case 'v':
+ views = atoi(optarg);
+ break;
+
+ case 'w':
+ windowed = TRUE;
+ break;
+
+ case 'l':
+ linear = TRUE;
+ break;
+
+ case 'm':
+ ratio = atof(optarg);
+ break;
+
+ case ':': // No argument
+ fprintf(stderr,
+ "Option -%c is missing an argument\n",
+ (char)optopt);
+ return 1;
+
+ case '?':
+ default:
+ fprintf(stderr,
+ "Unknown option -%c\n",
+ (char)optopt);
+ return 1;
+ }
+ }
+ }
+ }
+
+ if (!mapset.maps && !addmaps(".", &mapset))
+ {
+ fprintf(stderr, "No maps in current directory\n");
+ return 1;
+ }
+
+ if (views < 0 || views > 16)
+ {
+ fprintf(stderr, "Unsupported number of views\n");
+ return 1;
+ }
+
+ {
+ GInt32 xPixel;
+ GInt32 yPixel;
+
+ double lat;
+ double lon;
+
+ int smallest = -1;
+ double smallestScale = 0;
+
+ // Find smallest map
+ for (i = 0; i < mapset.maps; i++)
+ {
+ double scale;
+
+ scale2zoom(mapset.dataset[i], mapset.path[i],
+ 1, pixel_size, 0, &scale, &scale);
+
+ if (smallest == -1 || scale < smallestScale)
+ {
+ smallest = i;
+ smallestScale = scale;
+ }
+ }
+
+ // Center on smallest map
+ center2pixel(mapset.dataset[smallest], &xPixel, &yPixel);
+ pixel2wgs(mapset.dataset[smallest], mapset.path[smallest],
+ xPixel, yPixel, &lat, &lon);
+
+ if (latSet)
+ {
+ lat = mapstates[0].req_lat;
+ }
+ if (lonSet)
+ {
+ lon = mapstates[0].req_lon;
+ }
+
+ // Init mapstates
+ for (i = 0; i < views; i++)
+ {
+ if (i)
+ resetmap(&mapstates[i]);
+
+ mapstates[i].req_lat = lat;
+ mapstates[i].req_lon = lon;
+
+ mapstates[i].req_rotation = mapstates[0].req_rotation;
+
+ if (views == mapset.maps)
+ {
+ mapstates[i].dataset[0] = mapset.dataset[i];
+ mapstates[i].path[0] = mapset.path[i];
+ mapstates[i].dataset[1] = NULL;
+ mapstates[i].path[1] = NULL;
+
+ scale2zoom(mapstates[i].dataset[0], mapstates[i].path[0],
+ 1, pixel_size, 0,
+ &mapstates[i].req_scale, &mapstates[i].req_scale);
+
+ mapstates[i].act_xZoom[0] = 1.0;
+ mapstates[i].act_yZoom[0] = 1.0;
+ }
+ else
+ {
+ if (i == 0 && !scaleSet)
+ {
+ mapstates[i].dataset[0] = mapset.dataset[smallest];
+ mapstates[i].path[0] = mapset.path[smallest];
+
+ scale2zoom(mapset.dataset[smallest], mapset.path[smallest],
+ 1, pixel_size, 0,
+ &mapstates[0].req_scale, &mapstates[0].req_scale);
+ }
+
+ // Set scales relative to smallest map
+ if (i)
+ {
+ if (linear)
+ mapstates[i].req_scale = ratio * i * mapstates[0].req_scale;
+ else
+ mapstates[i].req_scale = ratio * mapstates[i - 1].req_scale;
+ }
+
+ selectbestmap(&mapset, &mapstates[i], render_mode, pixel_size);
+ }
+
+ if (noZoom)
+ {
+ mapstates[i].act_xZoom[0] = 1;
+ mapstates[i].act_yZoom[0] = 1;
+ }
+
+ wgs2pixel(mapstates[i].dataset[0], mapstates[i].path[0], lat, lon,
+ &mapstates[i].act_xPixel[0], &mapstates[i].act_yPixel[0]);
+ }
+ }
+
+ // Create windows and views
+
+ QMainWindow *windows[16];
+ QSplitter *box1 = 0;
+ QSplitter *box2 = 0;
+
+ if (views == 1)
+ windowed = TRUE;
+
+ if (windowed)
+ {
+ for (i = 0; i < views; i++)
+ {
+ windows[i] = new QMainWindow();
+ }
+ }
+ else
+ {
+ windows[0] = new QMainWindow();
+
+ QSplitter *split = new QSplitter(windows[0]);
+ windows[0]->setCentralWidget(split);
+
+ box1 = new QSplitter(split);
+ box1->setOrientation(QSplitter::Vertical);
+ box2 = new QSplitter(split);
+ box2->setOrientation(QSplitter::Vertical);
+ }
+
+ for (i = 0; i < views; i++)
+ {
+ if (windowed)
+ {
+ canvases[i] = new MapWidget(windows[i], &mapstates[i]);
+
+ windows[i]->setCentralWidget(canvases[i]);
+
+ windows[i]->show();
+ }
+ else
+ {
+ if ((i & 1 && (!(views & 1) || i < 2)) ||
+ (!(i & 1) && (views & 1) && (i > 1)))
+ {
+ canvases[i] = new MapWidget(box2, &mapstates[i]);
+ }
+ else
+ {
+ canvases[i] = new MapWidget(box1, &mapstates[i]);
+ }
+ }
+ }
+
+ theApp.setMainWidget(windows[0]);
+
+ if (!windowed)
+ windows[0]->show();
+
+#ifdef HAVE_GPS
+ init_gps();
+#endif
+
+ int ret = theApp.exec();
+
+#ifdef HAVE_GPS
+ free_gps();
+#endif
+
+ freemaps(&mapset);
+
+ return ret;
+}
+
+// This line is necessary when there are no separate header files:
+// http://doc.trolltech.com/3.1/moc.html
+#include "qmapview.moc"
diff --git a/src/util/wmapview.c b/src/util/wmapview.c
new file mode 100644
index 0000000..992d9ff
--- /dev/null
+++ b/src/util/wmapview.c
@@ -0,0 +1,653 @@
+//
+// Copyright (c) 2005 -- Daniel Wallner
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#include "../lib_map/map.h"
+
+#include <windows.h>
+#include <windowsx.h>
+#include <stdio.h>
+#ifdef USE_CAIRO
+#include <cairo.h>
+#endif
+#include <unistd.h>
+#include <stdlib.h>
+
+#define PIXEL_SIZE 0.22E-3
+#define SCALE_RATIO 10
+
+typedef struct
+{
+ HWND view;
+ MapState *mapstate;
+}
+ViewData;
+
+MapSettings mapsettings;
+MapSet mapset;
+MapState mapstates[16];
+ViewData canvases[16];
+int views = 1;
+int render_mode = 0x100;
+int cover = 0;
+int transparent = 0;
+double pixel_size = PIXEL_SIZE;
+int noZoom = FALSE;
+
+static void expose(HDC dc, int width, int height, MapState *mapstate)
+{
+ MapGC mgc;
+
+ memset((void*)&mgc, 0, sizeof(mgc));
+
+ mgc.win_dc = dc;
+
+ if (cover)
+ coverifpossible(mapstate, width, height);
+
+ drawmap(mapstate, &mgc, width, height, transparent);
+
+ drawmarkers(&mgc, width, height,
+ &mapsettings, mapstate, pixel_size,
+ 0, 0);
+
+ if (mgc.win_pen)
+ DeleteObject(SelectObject(mgc.win_dc, mgc.win_pen));
+}
+
+static void button_press(int x, int y, MapState *mapstate)
+{
+ int i;
+
+ mapsettings.posmode = TRUE;
+
+ screen2wgs(mapstate, x, y,
+ &mapstate->req_lat, &mapstate->req_lon);
+
+ fprintf(stderr, "new center: %lf;%lf\n",
+ mapstate->req_lat, mapstate->req_lon);
+
+ for (i = 0; i < views; i++)
+ {
+ mapstates[i].req_lat = mapstate->req_lat;
+ mapstates[i].req_lon = mapstate->req_lon;
+
+ if (views != mapset.maps)
+ {
+ selectbestmap(&mapset, &mapstates[i], render_mode, pixel_size);
+ }
+ else
+ {
+ double pseudo_lat = (render_mode & 0x100) ? mapstate->req_lat : 0;
+
+ wgs2pixel(mapstates[i].dataset[0], mapstates[i].path[0],
+ mapstate->req_lat, mapstate->req_lon,
+ &mapstates[i].act_xPixel[0], &mapstates[i].act_yPixel[0]);
+
+ scale2zoom(mapstates[i].dataset[0], mapstates[i].path[0],
+ mapstates[i].req_scale, pixel_size, pseudo_lat,
+ &mapstates[i].act_xZoom[0], &mapstates[i].act_yZoom[0]);
+ }
+
+ if (noZoom)
+ {
+ mapstates[i].act_xZoom[0] = 1;
+ mapstates[i].act_yZoom[0] = 1;
+ }
+
+ InvalidateRect(canvases[i].view, NULL, FALSE);
+ }
+}
+
+static void key_press(char key, MapState *mapstate)
+{
+ int i;
+
+ int redraw = 0;
+
+ double factor = 1;
+
+ switch (key)
+ {
+ case '+':
+ factor = 1 / 1.5;
+ redraw = 1;
+ break;
+
+ case '-':
+ factor = 1.5;
+ redraw = 1;
+ break;
+
+ case 'm':
+ render_mode = (render_mode & 0xfff0) + (((render_mode & 0x0f) + 1) % 3);
+ redraw = 1;
+ break;
+
+ case 'f':
+ render_mode = (render_mode & 0xff0f) +
+ (((((render_mode & 0xf0) >> 4) + 1) % 3) << 4);
+ redraw = 1;
+ break;
+
+ case 'a':
+ render_mode = render_mode | 0x200;
+ redraw = 1;
+ break;
+
+ case 'c':
+ cover = !cover;
+ redraw = 1;
+ break;
+
+ case 'p':
+ mapsettings.havepos = !mapsettings.havepos;
+ redraw = 1;
+ break;
+
+ case 's':
+ render_mode ^= 0x100;
+ redraw = 1;
+ break;
+
+ case 'g':
+ mapsettings.drawgrid = !mapsettings.drawgrid;
+ redraw = 1;
+ break;
+
+ case 't':
+ transparent = !transparent;
+ redraw = 1;
+ break;
+
+ case 'r':
+ mapstate->req_rotation += 45;
+ if (mapstate->req_rotation >= 360)
+ mapstate->req_rotation -= 360;
+ redraw = 1;
+ break;
+ }
+
+ fprintf(stderr, "mode: %X\n", render_mode);
+
+ if (redraw)
+ for (i = 0; i < views; i++)
+ {
+ mapstates[i].req_scale *= factor;
+
+ if (views != mapset.maps)
+ {
+ selectbestmap(&mapset, &mapstates[i], render_mode, pixel_size);
+ }
+ else
+ {
+ double pseudo_lat = (render_mode & 0x100) ? mapstate->req_lat : 0;
+
+ wgs2pixel(mapstates[i].dataset[0], mapstates[i].path[0],
+ mapstate->req_lat, mapstate->req_lon,
+ &mapstates[i].act_xPixel[0],
+ &mapstates[i].act_yPixel[0]);
+
+ scale2zoom(mapstates[i].dataset[0], mapstates[i].path[0],
+ mapstates[i].req_scale, pixel_size, pseudo_lat,
+ &mapstates[i].act_xZoom[0], &mapstates[i].act_yZoom[0]);
+ }
+
+ if (noZoom)
+ {
+ mapstates[i].act_xZoom[0] = 1;
+ mapstates[i].act_yZoom[0] = 1;
+ }
+
+ InvalidateRect(canvases[i].view, NULL, FALSE);
+ }
+
+ render_mode &= ~0x200;
+}
+
+static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg,
+ WPARAM wParam, LPARAM lParam)
+{
+ MapState *mapstate = (MapState *)GetWindowLong(hWnd, GWL_USERDATA);
+
+ switch (msg)
+ {
+ case WM_CHAR:
+ key_press(wParam, mapstate);
+ break;
+
+ case WM_LBUTTONDOWN:
+ button_press(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), mapstate);
+ break;
+
+ case WM_ERASEBKGND:
+ return TRUE;
+
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+ HDC dc;
+ RECT rect;
+ GetClientRect(hWnd, &rect);
+ dc = BeginPaint(hWnd, &ps);
+ expose(dc, rect.right, rect.bottom, mapstate);
+ EndPaint(hWnd, &ps);
+ }
+ break;
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+
+ default:
+ return DefWindowProc(hWnd, msg, wParam, lParam);
+ }
+
+ return FALSE;
+}
+
+#define CLASSNAME "wmapview"
+#define TITLE CLASSNAME
+
+void WinInit()
+{
+ WNDCLASSEX wc = {0};
+
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = (WNDPROC)WndProc;
+ wc.hInstance = GetModuleHandle(NULL);
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+ wc.lpszClassName = CLASSNAME;
+
+ if (!RegisterClassEx(&wc))
+ {
+ fprintf(stderr, "Failed to register window class");
+ exit(1);
+ }
+}
+
+HWND CreateFrameWindow(MapState *mapstate)
+{
+ HWND window = CreateWindow(CLASSNAME, TITLE,
+ WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,
+ CW_USEDEFAULT, 0, NULL, NULL,
+ GetModuleHandle(NULL), NULL);
+
+ if (!window)
+ {
+ fprintf(stderr, "Failed to create window");
+ return 0;
+ }
+
+ SetWindowLong(window, GWL_USERDATA, (LONG)mapstate);
+
+ return window;
+}
+
+void usage()
+{
+ fprintf(stderr, "libmap test and sample application\n\n");
+ fprintf(stderr, " usage: wmapview [input map files or directories] [options and arguments]\n\n");
+ fprintf(stderr, " -h print this message\n");
+ fprintf(stderr, " -a latitude initial latitude\n");
+ fprintf(stderr, " -o longitude initial longitude\n");
+ fprintf(stderr, " -s scale initial scale\n");
+ fprintf(stderr, " -r rotation initial rotation\n");
+ fprintf(stderr, " -p pixel size (mm) pixel size\n");
+ fprintf(stderr, " -d dpi (1/inch) pixel size\n");
+ fprintf(stderr, " -z no zoom\n");
+ fprintf(stderr, " -v n number of views\n");
+ fprintf(stderr, " -w windowed views\n");
+ fprintf(stderr, " -l linear view scale\n");
+ fprintf(stderr, " -m ratio view scale ratio\n\n");
+ fprintf(stderr, " If no input is given, gmapview uses the current directory.\n");
+ fprintf(stderr, " When the number of views equals the number of maps,\n");
+ fprintf(stderr, " each map is fixed to each view.\n");
+ fprintf(stderr, " You can combine short flags, so `-w -z' means the same as -wz or -zw.\n");
+ fprintf(stderr, "\n When wmapview is running it can be controlled with the following keys:\n");
+ fprintf(stderr, "\n + Zoom in\n");
+ fprintf(stderr, " - Zoom out\n");
+ fprintf(stderr, " m Drawing mode (Single, overview, tiled)\n");
+ fprintf(stderr, " f Filter maps (Street, topo, all)\n");
+ fprintf(stderr, " a Show alternate map\n");
+ fprintf(stderr, " c Cover if possible\n");
+ fprintf(stderr, " p Show current position\n");
+ fprintf(stderr, " s Pseudo projection\n");
+ fprintf(stderr, " g Grid\n");
+ fprintf(stderr, " t Transparent\n");
+ fprintf(stderr, " r Rotate\n");
+ fprintf(stderr, "\n Left mouse click selects a new center point.\n");
+}
+
+int main(int argc, char **argv)
+{
+ extern char *optarg;
+ extern int optind;
+ extern int optopt;
+
+ int i;
+
+ HWND windows[16];
+ //GtkWidget *paned;
+ //GtkWidget *box1;
+ //GtkWidget *box2;
+ MSG msg;
+
+ int windowed = FALSE;
+ int latSet = FALSE;
+ int lonSet = FALSE;
+ int scaleSet = FALSE;
+ int linear = FALSE;
+ double ratio = SCALE_RATIO;
+
+ WinInit();
+
+ mapinit(&mapsettings);
+
+ resetmap(&mapstates[0]);
+
+ while (optind < argc)
+ {
+ if (argv[optind][0] != '-' || strlen(argv[optind]) <= 1)
+ {
+ // Load maps
+ if (!addmaps(argv[optind], &mapset))
+ {
+ fprintf(stderr,
+ "Unable to open input file: %s\n",
+ argv[optind]);
+ return 1;
+ }
+
+ optind++;
+ }
+ else
+ {
+ // Option
+ int opt = getopt(argc, argv, ":ha:o:s:r:p:d:zv:wlm:");
+ if (opt != -1)
+ {
+ switch (opt)
+ {
+ case 'h':
+ usage();
+ return 1;
+
+ case 'a':
+ mapstates[0].req_lat = atof(optarg);
+ latSet = TRUE;
+ break;
+
+ case 'o':
+ mapstates[0].req_lon = atof(optarg);
+ lonSet = TRUE;
+ break;
+
+ case 's':
+ mapstates[0].req_scale = atof(optarg);
+ scaleSet = TRUE;
+ break;
+
+ case 'r':
+ mapstates[0].req_rotation = atof(optarg) * M_PI / 180;
+ break;
+
+ case 'p':
+ pixel_size = atof(optarg) / 1000;
+ break;
+
+ case 'd':
+ pixel_size = 0.0254 / atof(optarg);
+ break;
+
+ case 'z':
+ noZoom = TRUE;
+ break;
+
+ case 'v':
+ views = atoi(optarg);
+ break;
+
+ case 'w':
+ windowed = TRUE;
+ break;
+
+ case 'l':
+ linear = TRUE;
+ break;
+
+ case 'm':
+ ratio = atof(optarg);
+ break;
+
+ case ':': // No argument
+ fprintf(stderr,
+ "Option -%c is missing an argument\n",
+ (char)optopt);
+ return 1;
+
+ case '?':
+ default:
+ fprintf(stderr,
+ "Unknown option -%c\n",
+ (char)optopt);
+ return 1;
+ }
+ }
+ }
+ }
+
+ if (!mapset.maps && !addmaps(".", &mapset))
+ {
+ fprintf(stderr, "No maps in current directory\n");
+ return 1;
+ }
+
+ if (views < 0 || views > 16)
+ {
+ fprintf(stderr, "Unsupported number of views\n");
+ return 1;
+ }
+
+ {
+ GInt32 xPixel;
+ GInt32 yPixel;
+
+ double lat;
+ double lon;
+
+ int smallest = -1;
+ double smallestScale = 0;
+
+ // Find smallest map
+ for (i = 0; i < mapset.maps; i++)
+ {
+ double scale;
+
+ scale2zoom(mapset.dataset[i], mapset.path[i],
+ 1, pixel_size, 0, &scale, &scale);
+
+ if (smallest == -1 || scale < smallestScale)
+ {
+ smallest = i;
+ smallestScale = scale;
+ }
+ }
+
+ // Center on smallest map
+ center2pixel(mapset.dataset[smallest], &xPixel, &yPixel);
+ pixel2wgs(mapset.dataset[smallest], mapset.path[smallest],
+ xPixel, yPixel, &lat, &lon);
+
+ if (latSet)
+ {
+ lat = mapstates[0].req_lat;
+ }
+ if (lonSet)
+ {
+ lon = mapstates[0].req_lon;
+ }
+
+ // Init mapstates
+ for (i = 0; i < views; i++)
+ {
+ if (i)
+ resetmap(&mapstates[i]);
+
+ mapstates[i].req_lat = lat;
+ mapstates[i].req_lon = lon;
+
+ mapstates[i].req_rotation = mapstates[0].req_rotation;
+
+ if (views == mapset.maps)
+ {
+ mapstates[i].dataset[0] = mapset.dataset[i];
+ mapstates[i].path[0] = mapset.path[i];
+ mapstates[i].dataset[1] = NULL;
+ mapstates[i].path[1] = NULL;
+
+ scale2zoom(mapstates[i].dataset[0], mapstates[i].path[0],
+ 1, pixel_size, 0,
+ &mapstates[i].req_scale, &mapstates[i].req_scale);
+
+ mapstates[i].act_xZoom[0] = 1.0;
+ mapstates[i].act_yZoom[0] = 1.0;
+ }
+ else
+ {
+ if (i == 0 && !scaleSet)
+ {
+ mapstates[i].dataset[0] = mapset.dataset[smallest];
+ mapstates[i].path[0] = mapset.path[smallest];
+
+ scale2zoom(mapset.dataset[smallest], mapset.path[smallest],
+ 1, pixel_size, 0,
+ &mapstates[0].req_scale, &mapstates[0].req_scale);
+ }
+
+ // Set scales relative to smallest map
+ if (i)
+ {
+ if (linear)
+ mapstates[i].req_scale = ratio * i * mapstates[0].req_scale;
+ else
+ mapstates[i].req_scale = ratio * mapstates[i - 1].req_scale;
+ }
+
+ selectbestmap(&mapset, &mapstates[i], render_mode, pixel_size);
+ }
+
+ if (noZoom)
+ {
+ mapstates[i].act_xZoom[0] = 1;
+ mapstates[i].act_yZoom[0] = 1;
+ }
+
+ wgs2pixel(mapstates[i].dataset[0], mapstates[i].path[0], lat, lon,
+ &mapstates[i].act_xPixel[0], &mapstates[i].act_yPixel[0]);
+ }
+ }
+
+ if (views == 1)
+ windowed = TRUE;
+
+ if (windowed)
+ {
+ for (i = 0; i < views; i++)
+ {
+ windows[i] = CreateFrameWindow(&mapstates[i]);
+/*
+ g_signal_connect(G_OBJECT(windows[i]), "delete-event",
+ G_CALLBACK(gtk_main_quit), NULL);
+
+ g_signal_connect(G_OBJECT(windows[i]), "key_press_event",
+ G_CALLBACK(key_press), mapstates);*/
+ }
+ }
+ else
+ {
+ windows[0] = CreateFrameWindow(&mapstates[0]);
+/*
+ g_signal_connect(G_OBJECT(windows[0]), "delete-event",
+ G_CALLBACK(gtk_main_quit), NULL);
+
+ g_signal_connect(G_OBJECT(windows[0]), "key_press_event",
+ G_CALLBACK(key_press), mapstates);
+
+ paned = gtk_hpaned_new();
+
+ gtk_container_add(GTK_CONTAINER(windows[0]), paned);
+
+ box1 = gtk_vbox_new(TRUE, 4);
+ box2 = gtk_vbox_new(TRUE, 4);
+
+ gtk_paned_pack1(GTK_PANED(paned), box1, FALSE, FALSE);
+ gtk_paned_pack2(GTK_PANED(paned), box2, FALSE, FALSE);*/
+ }
+
+ for (i = 0; i < views; i++)
+ {
+ canvases[i].mapstate = &mapstates[i];
+ canvases[i].view = windows[i];
+/* canvases[i] = gtk_drawing_area_new();
+
+ gtk_widget_set_size_request(canvases[i], 100, 100);
+
+ gtk_widget_add_events(canvases[i], GDK_BUTTON_PRESS_MASK);
+
+ g_signal_connect(G_OBJECT(canvases[i]), "expose-event",
+ G_CALLBACK(expose), &mapstates[i]);
+
+ g_signal_connect(G_OBJECT(canvases[i]), "button_press_event",
+ G_CALLBACK(button_press), &mapstates[i]);
+*/
+ if (windowed)
+ {
+ //gtk_container_add(GTK_CONTAINER(windows[i]), canvases[i]);
+
+ ShowWindow(windows[i], TRUE);
+ }/*
+ else
+ {
+ if ((i & 1 && (!(views & 1) || i < 2)) ||
+ (!(i & 1) && (views & 1) && (i > 1)))
+ {
+ gtk_box_pack_start_defaults(GTK_BOX(box2), canvases[i]);
+ }
+ else
+ {
+ gtk_box_pack_start_defaults(GTK_BOX(box1), canvases[i]);
+ }
+ }*/
+ }
+
+ if (!windowed)
+ ShowWindow(windows[0], TRUE);
+
+ // Main message loop:
+ while (GetMessage(&msg, NULL, 0, 0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ freemaps(&mapset);
+
+ return 0;
+}
diff --git a/src/util/worldgen.c b/src/util/worldgen.c
new file mode 100644
index 0000000..93b0d69
--- /dev/null
+++ b/src/util/worldgen.c
@@ -0,0 +1,126 @@
+//
+// Copyright (c) 2005 -- Daniel Wallner
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+
+int worldgen(char *path, double latitude, double longitude, double scale)
+{
+ FILE *outfile;
+
+ outfile = fopen(path, "w");
+
+ if (!outfile)
+ {
+ fprintf(stderr, "unable to open output file '%s': %s\n",
+ path,strerror(errno));
+ return 0;
+ }
+
+ fprintf(outfile, "%lf\n0\n0\n%lf\n", scale, -scale);
+ fprintf(outfile, "%lf\n", longitude);
+ fprintf(outfile, "%lf\n", latitude);
+
+ fclose(outfile);
+
+ return 1;
+}
+
+int koordread(char *path)
+{
+ printf( " koordread: %s\n", path);
+
+ FILE *infile = fopen(path, "r");
+
+ char mapname[264];
+ double latitude;
+ double longitude;
+ double scale;
+ long count;
+ long linenumber = 0;
+
+ if (!infile)
+ {
+ fprintf(stderr, "unable to open input file '%s': %s\n",
+ path,strerror(errno));
+ return 1;
+ }
+
+ while ((count = fscanf(infile, "%s %lf %lf %lf\n",
+ mapname, &latitude, &longitude, &scale)) &&
+ count != EOF)
+ {
+ linenumber++;
+
+ if (count != 4)
+ {
+ fprintf(stderr, "Error reading line %ld\n", linenumber);
+ fprintf(stderr, " map name: '%s'\n", mapname);
+ continue;
+ }
+
+ char worldname[264];
+ char *extchar;
+ int is_image;
+
+ fprintf(stderr, "Line: '%s' '%lf' '%lf' '%lf'\n",
+ mapname, latitude, longitude, scale);
+
+ strcpy(worldname, mapname);
+ extchar = strrchr(worldname, '.');
+
+ is_image =
+ strstr(worldname, ".jpg") ||
+ strstr(worldname, ".png") ||
+ strstr(worldname, ".gif");
+
+ if (extchar && is_image)
+ {
+ fprintf(stderr, " is image with extention '%s'\n",extchar);
+
+ strcpy(extchar, ".wld");
+
+ fprintf(stderr, " generating '%s'\n", worldname);
+
+ worldgen(worldname, latitude, longitude, scale);
+ }
+ else
+ {
+ fprintf(stderr, " no image extension, skipping '%s'\n", mapname);
+ }
+ }
+
+ fclose(infile);
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ if (argc != 2)
+ {
+ fprintf(stderr, "usage: worldgen infile\n");
+ return 1;
+ }
+
+ return koordread(argv[1]);
+}
diff --git a/src/waypoint.c b/src/waypoint.c
new file mode 100644
index 0000000..3c54ffe
--- /dev/null
+++ b/src/waypoint.c
@@ -0,0 +1,1087 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+/*
+ * waypoint module:
+ */
+
+#include "config.h"
+#include "gettext.h"
+#include "gpsdrive.h"
+#include "icons.h"
+#include <fcntl.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include "routes.h"
+#include "import_map.h"
+#include "download_map.h"
+#include "icons.h"
+#include "poi.h"
+#include "gui.h"
+#include "gpsdrive_config.h"
+#include "main_gui.h"
+
+#include "gettext.h"
+#include <speech_strings.h>
+#include <speech_out.h>
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+
+extern GtkWidget *mylist;
+extern gint maploaded;
+extern routestatus_struct route;
+extern gint isnight, disableisnight;
+extern color_struct colors;
+extern gint mydebug;
+extern GtkWidget *map_drawingarea;
+extern GdkGC *kontext_map;
+extern gint usesql;
+extern glong mapscale;
+
+#include "mysql/mysql.h"
+
+extern MYSQL mysql;
+extern MYSQL_RES *res;
+extern MYSQL_ROW row;
+extern gdouble alarm_dist;
+extern GtkWidget *posbt;
+gint dontsetwp = FALSE;
+extern gint selected_wp_mode;
+extern GtkWidget *add_wp_lon_text, *add_wp_lat_text;
+extern gint wptotal, wpselected;
+extern GtkWidget *wp4eventbox;
+extern GtkWidget *wp5eventbox, *satsvbox, *satshbox, *satslabel1eventbox;
+extern gdouble posx, posy;
+extern gdouble earthr;
+extern gchar *displaytext;
+extern gint do_display_dsc, textcount;
+extern GtkWidget *destframe;
+extern GTimer *timer, *disttimer;
+extern gdouble gbreit, glang, olddist;
+extern GtkWidget *messagewindow;
+extern gint onemousebutton;
+extern gint real_screen_x, real_screen_y, real_psize, real_smallmenu;
+extern GdkDrawable *drawable;
+extern gchar oldfilename[2048];
+extern poi_type_struct poi_type_list[poi_type_list_max];
+extern int poi_type_list_count;
+extern GtkTreeStore *poi_types_tree;
+extern GList *poi_types_formatted;
+extern coordinate_struct coords;
+extern currentstatus_struct current;
+extern GdkGC *kontext;
+
+gint saytarget = FALSE;
+gint markwaypoint = FALSE;
+gint foundradar;
+GtkWidget *addwaypointwindow;
+wpstruct *wayp;
+gint wpsize = 1000;
+gint maxwp;
+time_t waytxtstamp = 0;
+gint deleteline = 0;
+gint selected_wp_list_line = 0;
+GtkWidget *gotowindow;
+gint setwpactive = FALSE;
+gchar lastradar[40], lastradar2[40];
+gdouble radarbearing;
+/* action=1: radar (speedtrap) */
+GtkWidget *add_wp_name_text, *wptext2;
+GtkWidget *add_wp_comment_text;
+long sortcolumn = 4, sortflag = 0;
+gdouble wp_saved_target_lat = 0;
+gdouble wp_saved_target_lon = 0;
+gdouble wp_saved_posmode_lat = 0;
+gdouble wp_saved_posmode_lon = 0;
+
+gint save_in_db = TRUE;
+
+/* *****************************************************************************
+ * check for Radar WP near me and warn me
+ */
+gint
+watchwp_cb (GtkWidget * widget, guint * datum)
+{
+ gint angle, i, radarnear;
+ gdouble d;
+ gchar buf[400], lname[200], l2name[200];
+ gdouble ldist = 9999.0, l2dist = 9999.0;
+ gdouble tx, ty, lastbearing;
+
+ if ( mydebug >50 ) fprintf(stderr , "watchwp_cb()\n");
+
+ /* calculate new earth radius */
+ earthr = calcR (coords.current_lat);
+
+ if (current.importactive)
+ return TRUE;
+
+ foundradar = FALSE;
+ radarnear = FALSE;
+
+
+ for (i = 0; i < maxwp; i++)
+ {
+ /* test for radar */
+ if (((wayp + i)->action) == 1)
+ {
+ d = calcdist2 ((wayp + i)->lon, (wayp + i)->lat);
+ if (d < 0.6)
+ {
+ lastbearing = radarbearing;
+ tx = -coords.current_lon + (wayp + i)->lon;
+ ty = -coords.current_lat + (wayp + i)->lat;
+ radarbearing = atan (tx / ty);
+ if (!finite (radarbearing))
+ radarbearing = lastbearing;
+
+ if (ty < 0)
+ radarbearing = M_PI + radarbearing;
+ radarbearing -= current.heading;
+ if (radarbearing >= (2 * M_PI))
+ radarbearing -= 2 * M_PI;
+ if (radarbearing < 0)
+ radarbearing += 2 * M_PI;
+ if (radarbearing < 0)
+ radarbearing += 2 * M_PI;
+ angle = radarbearing * 180.0 / M_PI;
+
+ if ((angle < 40) || (angle > 320))
+ {
+ foundradar = TRUE;
+ if (d < ldist)
+ {
+ ldist = d;
+ g_strlcpy (lname,
+ (wayp + i)->name,
+ sizeof (lname));
+ }
+ if (d < 0.2)
+ {
+ foundradar = TRUE;
+ radarnear = TRUE;
+ if (d < l2dist)
+ {
+ l2dist = d;
+ g_strlcpy (l2name,
+ (wayp +
+ i)->name,
+ sizeof
+ (l2name));
+ }
+ }
+ }
+
+ }
+
+ }
+ }
+ if (!foundradar)
+ {
+ g_strlcpy (lastradar, "----", sizeof (lastradar));
+ g_strlcpy (lastradar2, "----", sizeof (lastradar2));
+ }
+ else
+ {
+ if ((strcmp (lname, lastradar)) != 0)
+ {
+ g_strlcpy (lastradar, lname, sizeof (lastradar));
+
+ g_snprintf(
+ buf, sizeof(buf), speech_danger_radar[voicelang],
+ (int) (ldist * 1000.0), (int) current.groundspeed );
+ speech_out_speek (buf);
+
+ if (displaytext != NULL)
+ free (displaytext);
+ displaytext = strdup (buf + 10);
+ displaytext = g_strdelimit (displaytext, "\n", ' ');
+ displaytext = g_strdelimit (displaytext, "\")", ' ');
+
+ do_display_dsc = TRUE;
+ textcount = 0;
+ }
+
+ if (radarnear)
+ if ((strcmp (l2name, lastradar2)) != 0)
+ {
+ g_strlcpy (lastradar2, l2name, sizeof (lastradar2));
+
+ g_snprintf(
+ buf, sizeof(buf), speech_info_radar[voicelang],
+ (int) (ldist * 1000.0) );
+ speech_out_speek (buf);
+ }
+
+ }
+
+ return TRUE;
+}
+
+/* ******************************************************************
+ */
+void check_and_reload_way_txt()
+{
+ gchar mappath[2048];
+
+ if (g_ascii_strncasecmp (local_config.wp_file, "/", 1) != 0)
+ {
+ g_strlcpy (mappath, local_config.dir_home, sizeof (mappath));
+ g_strlcat (mappath, local_config.wp_file, sizeof (mappath));
+ }
+
+ loadwaypoints ();
+}
+
+
+/* *****************************************************************************
+ * Draw waypoints on map
+ */
+void
+draw_waypoints ()
+{
+ gdouble posxdest, posydest;
+ gint k, k2, i, shownwp = 0;
+ gchar txt[200];
+
+ if (mydebug > 10)
+ printf ("draw_waypoints()\n");
+
+ /* draw waypoints */
+ for (i = 0; i < maxwp; i++)
+ {
+ calcxy (&posxdest, &posydest,
+ (wayp + i)->lon, (wayp + i)->lat, current.zoom);
+
+ if ((posxdest >= 0) && (posxdest < SCREEN_X)
+ && (shownwp < MAXSHOWNWP)
+ && (posydest >= 0) && (posydest < SCREEN_Y))
+ {
+ gdk_gc_set_line_attributes (kontext_map, 2, 0, 0, 0);
+ shownwp++;
+ g_strlcpy (txt, (wayp + i)->name, sizeof (txt));
+
+ // Draw Icon(typ) or + Sign
+ if ((wayp + i)->wlan > 0)
+ drawwlan (posxdest, posydest,
+ (wayp + i)->wlan);
+ else
+ drawicon (posxdest, posydest,
+ (wayp + i)->typ);
+
+ // Draw Proximity Circle
+ if ((wayp + i)->proximity > 0.0)
+ {
+ gint proximity_pixels;
+ if (current.mapscale)
+ proximity_pixels =
+ ((wayp + i)->proximity)
+ * current.zoom * PIXELFACT / current.mapscale;
+ else
+ proximity_pixels = 2;
+
+ gdk_gc_set_foreground (kontext_map, &colors.blue);
+
+ gdk_draw_arc (drawable, kontext_map, FALSE,
+ posxdest - proximity_pixels,
+ posydest - proximity_pixels,
+ proximity_pixels * 2,
+ proximity_pixels * 2, 0,
+ 64 * 360);
+ }
+
+
+ { /* draw shadow of text */
+ PangoFontDescription *pfd;
+ PangoLayout *wplabellayout;
+ gint width, height;
+ gchar *tn;
+
+ gdk_gc_set_foreground (kontext_map, &colors.shadow);
+ gdk_gc_set_function (kontext_map, GDK_AND);
+ tn = g_strdelimit (txt, "_", ' ');
+
+ wplabellayout =
+ gtk_widget_create_pango_layout
+ (map_drawingarea, tn);
+ pfd = pango_font_description_from_string
+ (local_config.font_wplabel);
+ pango_layout_set_font_description
+ (wplabellayout, pfd);
+ pango_layout_get_pixel_size (wplabellayout,
+ &width, &height);
+ /* printf("j: %d\n",height); */
+ k = width + 4;
+ k2 = height;
+ if (local_config.showshadow)
+ {
+ gdk_draw_layout_with_colors (drawable,
+ kontext_map,
+ posxdest + 15 + SHADOWOFFSET,
+ posydest - k2 / 2 + SHADOWOFFSET,
+ wplabellayout,
+ &colors.shadow,
+ NULL);
+ }
+ if (wplabellayout != NULL)
+ g_object_unref (G_OBJECT
+ (wplabellayout));
+ /* freeing PangoFontDescription, cause it has been copied by prev. call */
+ pango_font_description_free (pfd);
+
+ }
+ gdk_gc_set_function (kontext_map, GDK_COPY);
+
+
+ gdk_gc_set_function (kontext_map, GDK_AND);
+
+ gdk_gc_set_foreground (kontext_map, &colors.textbacknew);
+ gdk_draw_rectangle (drawable, kontext_map, 1,
+ posxdest + 13, posydest - k2 / 2,
+ k + 1, k2);
+ gdk_gc_set_function (kontext_map, GDK_COPY);
+ gdk_gc_set_foreground (kontext_map, &colors.black);
+ gdk_gc_set_line_attributes (kontext_map, 1, 0, 0, 0);
+ gdk_draw_rectangle (drawable, kontext_map, 0,
+ posxdest + 12,
+ posydest - k2 / 2 - 1, k + 2, k2);
+
+ /* gdk_gc_set_foreground (kontext, &yellow); */
+ {
+ /* prints in pango */
+ PangoFontDescription *pfd;
+ PangoLayout *wplabellayout;
+
+ wplabellayout =
+ gtk_widget_create_pango_layout
+ (map_drawingarea, txt);
+ pfd = pango_font_description_from_string
+ (local_config.font_wplabel);
+ pango_layout_set_font_description
+ (wplabellayout, pfd);
+
+ gdk_draw_layout_with_colors (drawable,
+ kontext_map,
+ posxdest + 15,
+ posydest -
+ k2 / 2,
+ wplabellayout,
+ &colors.wplabel, NULL);
+ if (wplabellayout != NULL)
+ g_object_unref (G_OBJECT
+ (wplabellayout));
+ /* freeing PangoFontDescription, cause it has been copied by prev. call */
+ pango_font_description_free (pfd);
+
+ }
+ }
+ }
+}
+
+
+/* *****************************************************************************
+ */
+gint
+importaway_cb (GtkWidget * widget, guint datum)
+{
+ current.importactive = FALSE;
+ gtk_widget_destroy (widget);
+ g_strlcpy (oldfilename, "XXXXXXXXXXXXXXXXXX", sizeof (oldfilename));
+ return FALSE;
+}
+
+
+/* *****************************************************************************
+ */
+gint
+delwp_cb (GtkWidget * widget, guint datum)
+{
+ gint i, j;
+ gchar *p;
+
+ i = deleteline;
+ if ( mydebug > 0 )
+ g_print ("delwp: remove line %d\n", i);
+ gtk_clist_get_text (GTK_CLIST (mylist), i, 0, &p);
+ j = atol (p) - 1;
+ gtk_clist_remove (GTK_CLIST (mylist), i);
+ if ( mydebug > 0 )
+ g_print ("delwp: remove entry %d\n", j);
+
+ deletesqldata ((wayp + j)->sqlnr);
+ for (i = j; i < (maxwp - 1); i++)
+ *(wayp + i) = *(wayp + i + 1);
+ maxwp--;
+ savewaypoints ();
+ gtk_clist_get_text (GTK_CLIST (mylist), deleteline, 0, &p);
+ selected_wp_list_line = atol (p);
+
+ return TRUE;
+}
+
+/* *****************************************************************************
+ * destroy sel_target window
+ */
+gint
+sel_targetweg_cb (GtkWidget * widget, guint datum)
+{
+ /* gtk_timeout_remove (selwptimeout); */
+ gtk_widget_destroy (GTK_WIDGET (gotowindow));
+ /* restore old target */
+ if (widget != NULL && !route.active) {
+ coords.target_lat = wp_saved_target_lat;
+ coords.target_lon = wp_saved_target_lon;
+ }
+ /* restore old posmode */
+ if (widget != NULL && gui_status.posmode) {
+ coords.posmode_lat = wp_saved_posmode_lat;
+ coords.posmode_lon = wp_saved_posmode_lon;
+ }
+ setwpactive = FALSE;
+
+ return FALSE;
+}
+
+/* *****************************************************************************
+ */
+
+/*
+ * destroy sel_target window event:
+ */
+ gint
+ sel_target_destroy_cb (GtkWidget *widget, guint datum) {
+ selected_wp_mode = FALSE;
+ return TRUE;
+ }
+
+gint
+jumpwp_cb (GtkWidget * widget, guint datum)
+{
+ gint i;
+ gchar *p;
+
+ i = deleteline;
+ if (gui_status.posmode) {
+ gtk_clist_get_text (GTK_CLIST (mylist), i, 3, &p);
+ coordinate_string2gdouble(p, &coords.posmode_lat);
+ gtk_clist_get_text (GTK_CLIST (mylist), i, 4, &p);
+ coordinate_string2gdouble(p, &coords.posmode_lon);
+ }
+
+ if ((!gui_status.posmode) && (!current.simmode))
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (posbt),
+ TRUE);
+ getsqldata ();
+ reinsertwp_cb (NULL, 0);
+ sel_targetweg_cb (NULL, 0);
+ return TRUE;
+}
+
+/* *****************************************************************************
+ */
+gint
+addwaypointchange_cb (GtkWidget * widget, guint datum)
+{
+ gchar *s;
+ gdouble lo, la;
+
+ s = g_strstrip ((char *)
+ gtk_entry_get_text (GTK_ENTRY (add_wp_lon_text)));
+ coordinate_string2gdouble(s, &lo);
+ if ((lo > -181) && (lo < 181))
+ coords.wp_lon = lo;
+ s = g_strstrip ((char *)
+ gtk_entry_get_text (GTK_ENTRY (add_wp_lat_text)));
+ coordinate_string2gdouble(s, &la);
+ if ((la > -181) && (la < 181))
+ coords.wp_lat = la;
+
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ * Add waypoint at coords.wp_lat, coords.wp_lon
+ * with Strings for Name and Type
+ */
+glong
+addwaypoint (gchar * wp_name, gchar * wp_type, gchar * wp_comment, gdouble wp_lat, gdouble wp_lon, gint save_flag)
+{
+ gint i;
+
+ if (usesql && save_in_db)
+ {
+ return insertsqldata (wp_lat, wp_lon, (char *) wp_name,
+ (char *) wp_type, (char *) wp_comment, 3);
+ }
+ else
+ {
+ i = maxwp;
+ (wayp + i)->lat = wp_lat;
+ (wayp + i)->lon = wp_lon;
+ g_strdelimit ((char *) wp_name, " ", '_');
+ g_strdelimit ((char *) wp_comment, " ", '_');
+
+ /* limit waypoint name to 20 chars */
+ g_strlcpy ((wayp + i)->name, wp_name, 40);
+ (wayp + i)->name[20] = 0;
+
+ /* limit waypoint type to 40 chars */
+ g_strlcpy ((wayp + i)->typ, wp_type, 40);
+ (wayp + i)->typ[40] = 0;
+
+ /* limit waypoint comment to 80 chars */
+ g_strlcpy ((wayp + i)->comment, wp_comment, 80);
+ (wayp + i)->comment[80] = 0;
+
+
+ (wayp + i)->wlan = 0;
+
+ maxwp++;
+ if (maxwp >= wpsize)
+ {
+ wpsize += 1000;
+ wayp = g_renew (wpstruct, wayp, wpsize);
+ }
+ savewaypoints ();
+ return 0;
+ }
+}
+
+/* *****************************************************************************
+ * callback from gtk to add waypoint
+ */
+gint
+addwaypoint_gtk_cb (GtkWidget * widget, guint datum)
+{
+ G_CONST_RETURN gchar *s1, *s2;
+ gchar wp_name[80];
+ gchar *wp_type;
+ gchar wp_comment[255];
+
+ s1 = gtk_entry_get_text (GTK_ENTRY (add_wp_name_text));
+ s2 = gtk_entry_get_text (GTK_ENTRY (add_wp_comment_text));
+
+ if (!usesql)
+ save_in_db = FALSE;
+
+ g_strlcpy(wp_name,s1,sizeof(wp_name));
+ g_strlcpy(wp_comment,s2,sizeof(wp_comment));
+
+ gtk_tree_model_get (GTK_TREE_MODEL (poi_types_tree),
+ &current.poitype_iter,
+ POITYPE_NAME, &wp_type,
+ -1);
+
+ addwaypoint (wp_name, wp_type, wp_comment,
+ coords.wp_lat, coords.wp_lon, save_in_db);
+
+ gtk_widget_destroy (GTK_WIDGET (widget));
+ markwaypoint = FALSE;
+
+ g_free (wp_type);
+
+ return TRUE;
+}
+
+/* *****************************************************************************/
+void
+add_wp_change_save_in_cb (GtkWidget *widget, gint user_data)
+{
+ save_in_db = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+}
+
+/* *****************************************************************************
+ * destroy sel_target window
+ */
+gint
+addwaypointdestroy_cb (GtkWidget * widget, guint datum)
+{
+
+ gtk_widget_destroy (GTK_WIDGET (addwaypointwindow));
+ markwaypoint = FALSE;
+
+ return FALSE;
+}
+
+
+/* *****************************************************************************
+ */
+static gint
+select_wptype_cb (GtkComboBox *combo_box, gpointer data)
+{
+ gtk_combo_box_get_active_iter (combo_box, &current.poitype_iter);
+ return FALSE;
+}
+
+
+/* *****************************************************************************
+ */
+gint
+addwaypoint_cb (GtkWidget * widget, gpointer datum)
+{
+ GtkWidget *window;
+ GtkWidget *vbox;
+ gchar buff[40];
+
+ GtkWidget *add_wp_name_label;
+ GtkWidget *add_wp_type_label;
+ GtkWidget *add_wp_comment_label;
+ GtkWidget *add_wp_lon_label;
+ GtkWidget *add_wp_lat_label;
+ GtkWidget *add_wp_button_hbox;
+ GtkWidget *button, *button2;
+ GtkWidget *table_add_wp;
+ GSList *radiobutton_savein_group = NULL;
+ GtkWidget *radiobutton_db;
+ GtkWidget *radiobutton_wp;
+ GtkWidget *add_wp_savein_label;
+ GtkWidget *add_wp_type_combo;
+ GtkCellRenderer *renderer_type_name;
+ GtkCellRenderer *renderer_type_icon;
+
+ addwaypointwindow = window = gtk_dialog_new ();
+
+ gtk_window_set_default_size (GTK_WINDOW (addwaypointwindow), 320, -1);
+ gotowindow = window;
+ markwaypoint = TRUE;
+
+ gtk_window_set_modal (GTK_WINDOW (window), TRUE);
+ gtk_window_set_title (GTK_WINDOW (window), _("Add Point of Interest"));
+
+ vbox = gtk_vbox_new (TRUE, 2);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox, TRUE,
+ TRUE, 2);
+
+ table_add_wp = gtk_table_new (6, 3, FALSE);
+ gtk_box_pack_start (GTK_BOX (vbox), table_add_wp, TRUE, TRUE, 2);
+
+ { /* Name */
+ add_wp_name_text = gtk_entry_new ();
+ add_wp_name_label = gtk_label_new (_("Name:"));
+ gtk_entry_set_max_length (GTK_ENTRY (add_wp_name_text), 80);
+ gtk_window_set_focus (GTK_WINDOW (window), add_wp_name_text);
+
+ gtk_table_attach_defaults (GTK_TABLE (table_add_wp), add_wp_name_label, 0, 1, 0, 1);
+ gtk_table_attach_defaults (GTK_TABLE (table_add_wp), add_wp_name_text, 1, 3, 0, 1);
+ }
+
+ { /* Types */
+ add_wp_type_label = gtk_label_new (_(" Type: "));
+ add_wp_type_combo = gtk_combo_box_new_with_model
+ (GTK_TREE_MODEL (poi_types_tree));
+ renderer_type_icon = gtk_cell_renderer_pixbuf_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (add_wp_type_combo),
+ renderer_type_icon, FALSE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (add_wp_type_combo),
+ renderer_type_icon, "pixbuf", POITYPE_ICON, NULL);
+ renderer_type_name = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (add_wp_type_combo),
+ renderer_type_name, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (add_wp_type_combo),
+ renderer_type_name, "text", POITYPE_TITLE, NULL);
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX(add_wp_type_combo),
+ &current.poitype_iter);
+ g_signal_connect (G_OBJECT (add_wp_type_combo), "changed",
+ G_CALLBACK (select_wptype_cb), NULL);
+
+ gtk_table_attach_defaults (GTK_TABLE (table_add_wp),
+ add_wp_type_label, 0, 1, 1, 2);
+ gtk_table_attach_defaults (GTK_TABLE (table_add_wp),
+ add_wp_type_combo, 1, 3, 1, 2);
+ }
+
+ { /* Comment */
+ add_wp_comment_text = gtk_entry_new ();
+ add_wp_comment_label = gtk_label_new (_(" Comment: "));
+ gtk_entry_set_max_length (GTK_ENTRY (add_wp_comment_text), 255);
+
+ gtk_table_attach_defaults (GTK_TABLE (table_add_wp), add_wp_comment_label, 0, 1, 2, 3);
+ gtk_table_attach_defaults (GTK_TABLE (table_add_wp), add_wp_comment_text, 1, 3, 2, 3);
+ }
+
+ { /* Lat */
+ add_wp_lat_text = gtk_entry_new_with_max_length (20);
+ coordinate2gchar(buff, sizeof(buff), coords.wp_lat, TRUE,
+ local_config.coordmode);
+ gtk_entry_set_text (GTK_ENTRY (add_wp_lat_text), buff);
+ add_wp_lat_label = gtk_label_new (_("Latitude"));
+ gtk_signal_connect (GTK_OBJECT (add_wp_lat_text), "changed",
+ GTK_SIGNAL_FUNC (addwaypointchange_cb),
+ (gpointer) 2);
+
+ gtk_table_attach_defaults (GTK_TABLE (table_add_wp), add_wp_lat_label, 0, 1, 3, 4);
+ gtk_table_attach_defaults (GTK_TABLE (table_add_wp), add_wp_lat_text, 1, 3, 3, 4);
+ }
+
+ { /* Lon */
+ add_wp_lon_text = gtk_entry_new_with_max_length (20);
+ coordinate2gchar(buff, sizeof(buff), coords.wp_lon, FALSE,
+ local_config.coordmode);
+ gtk_entry_set_text (GTK_ENTRY (add_wp_lon_text), buff);
+ add_wp_lon_label = gtk_label_new (_("Longitude"));
+ gtk_signal_connect (GTK_OBJECT (add_wp_lon_text), "changed",
+ GTK_SIGNAL_FUNC (addwaypointchange_cb),
+ (gpointer) 1);
+
+ gtk_table_attach_defaults (GTK_TABLE (table_add_wp), add_wp_lon_label, 0, 1, 4, 5);
+ gtk_table_attach_defaults (GTK_TABLE (table_add_wp), add_wp_lon_text, 1, 3, 4, 5);
+ }
+
+ { /* Save WP in... */
+ if (usesql)
+ {
+ add_wp_savein_label = gtk_label_new (_(" Save waypoint in: "));
+ gtk_table_attach_defaults (GTK_TABLE (table_add_wp), add_wp_savein_label, 0, 1, 5, 6);
+
+ radiobutton_db = gtk_radio_button_new_with_mnemonic (NULL, _("Database"));
+ gtk_table_attach_defaults (GTK_TABLE (table_add_wp), radiobutton_db, 1, 2, 5, 6);
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton_db), radiobutton_savein_group);
+
+ radiobutton_savein_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton_db));
+ radiobutton_wp = gtk_radio_button_new_with_mnemonic (NULL, _("way.txt File"));
+ gtk_table_attach_defaults (GTK_TABLE (table_add_wp), radiobutton_wp, 2, 3, 5, 6);
+ gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton_wp), radiobutton_savein_group);
+ if (save_in_db)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
+ (radiobutton_db), TRUE);
+ }
+ else
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
+ (radiobutton_wp), TRUE);
+ }
+ g_signal_connect (radiobutton_db, "toggled",
+ GTK_SIGNAL_FUNC (add_wp_change_save_in_cb), 0);
+ }
+ }
+
+ { /* Buttons */
+ button = gtk_button_new_from_stock (GTK_STOCK_OK);
+ button2 = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+ GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);
+ gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (addwaypoint_gtk_cb),
+ GTK_OBJECT (window));
+ gtk_signal_connect (GTK_OBJECT (button2), "clicked",
+ GTK_SIGNAL_FUNC (addwaypointdestroy_cb),
+ 0);
+ gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+ GTK_SIGNAL_FUNC (addwaypointdestroy_cb),
+ 0);
+
+ add_wp_button_hbox = gtk_hbox_new (TRUE, 2);
+ gtk_box_pack_start (GTK_BOX (add_wp_button_hbox), button2,
+ TRUE, TRUE, 2);
+ gtk_box_pack_start (GTK_BOX (add_wp_button_hbox), button,
+ TRUE, TRUE, 2);
+ gtk_window_set_default (GTK_WINDOW (window), button);
+ gtk_box_pack_start (GTK_BOX
+ (GTK_DIALOG (window)->action_area),
+ add_wp_button_hbox, TRUE, TRUE, 2);
+ }
+
+ gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
+ gtk_widget_show_all (window);
+ return TRUE;
+}
+
+/* *****************************************************************************
+ */
+gint
+setsortcolumn (GtkWidget * w, gpointer datum)
+{
+ sortflag = !sortflag;
+ sortcolumn = (long) datum;
+
+ if (sortflag)
+ gtk_clist_set_sort_type (GTK_CLIST (mylist),
+ GTK_SORT_ASCENDING);
+ else
+ gtk_clist_set_sort_type (GTK_CLIST (mylist),
+ GTK_SORT_DESCENDING);
+
+ if (w != messagewindow)
+ reinsertwp_cb (NULL, 0);
+ else
+ {
+ gtk_clist_set_sort_column (GTK_CLIST (mylist),
+ sortcolumn);
+ gtk_clist_sort (GTK_CLIST (mylist));
+ }
+ return TRUE;
+}
+
+
+/* *****************************************************************************
+ */
+gint
+click_clist (GtkWidget * widget, GdkEventButton * event, gpointer data)
+{
+
+ g_print ("\nclist: %d, data: %d\n", event->button, selected_wp_list_line);
+ if ((event->button == 3))
+ {
+
+ return TRUE;
+ }
+
+ return FALSE;
+
+}
+
+/* *****************************************************************************
+ * if a waypoint is selected set the target_* variables
+ */
+gint
+setwp_cb (GtkWidget * widget, guint datum)
+{
+ //gchar str[200];
+ gchar b[100], buf[1000], buf2[1000];
+ gchar *p, *tn;
+ p = b;
+
+ deleteline = datum;
+ if (dontsetwp)
+ return TRUE;
+
+ /* enter selected_wp_mode ->
+ * enables map jumping to target_lat/lon */
+ selected_wp_mode = TRUE;
+
+ gtk_clist_get_text (GTK_CLIST (mylist), datum, 0, &p);
+ if (route.edit)
+ {
+ /* g_print("route: %s\n", p); */
+ thisrouteline = atol (p) - 1;
+ insertroutepoints ();
+ return TRUE;
+ }
+ if (route.active) {
+ /* in routingmode do nothing further */
+ return TRUE;
+ }
+ selected_wp_list_line = atol (p);
+ /* g_print("%d\n", selected_wp_list_line); */
+ gtk_clist_get_text (GTK_CLIST (mylist), datum, 1, &p);
+ g_strlcpy (current.target, p, sizeof (current.target));
+
+
+// g_snprintf (str, sizeof (str), "%s: %s", _("To"), current.target);
+// tn = g_strdelimit (str, "_", ' ');
+// gtk_frame_set_label (GTK_FRAME (destframe), tn);
+ gtk_clist_get_text (GTK_CLIST (mylist), datum, 3, &p);
+ coordinate_string2gdouble(p, &coords.target_lat);
+ gtk_clist_get_text (GTK_CLIST (mylist), datum, 4, &p);
+ coordinate_string2gdouble(p, &coords.target_lon);
+ /* if posmode enabled set posmode_lat/lon */
+ if (gui_status.posmode) {
+ coords.posmode_lat = coords.target_lat;
+ coords.posmode_lon = coords.target_lon;
+ }
+ /* gtk_timeout_add (5000, (GtkFunction) sel_targetweg_cb, widget); */
+ g_timer_stop (disttimer);
+ g_timer_start (disttimer);
+ olddist = current.dist;
+
+ tn = g_strdelimit (current.target, "_", ' ');
+ g_strlcpy (buf2, "", sizeof (buf2));
+ if (tn[0] == '*')
+ {
+ g_strlcpy (buf2, "das mobile Ziel ", sizeof (buf2));
+ g_strlcat (buf2, (tn + 1), sizeof (buf2));
+ }
+ else
+ g_strlcat (buf2, tn, sizeof (buf2));
+
+ g_snprintf( buf, sizeof(buf), speech_new_target[voicelang], buf2 );
+ speech_out_speek (buf);
+
+ saytarget = TRUE;
+
+ return TRUE;
+}
+
+
+
+/* *****************************************************************************
+ * save waypoints to way.txt
+ */
+void
+savewaypoints ()
+{
+ gchar la[20], lo[20];
+ FILE *st;
+ gint i, e;
+
+ st = fopen (local_config.wp_file, "w+");
+ if (st == NULL)
+ {
+ perror (local_config.wp_file);
+ }
+ else
+ {
+ for (i = 0; i < maxwp; i++)
+ {
+ g_snprintf (la, sizeof (la), "%10.6f",
+ (wayp + i)->lat);
+ g_snprintf (lo, sizeof (lo), "%10.6f",
+ (wayp + i)->lon);
+ g_strdelimit (la, ",", '.');
+ g_strdelimit (lo, ",", '.');
+
+ if ( (wayp + i)->typ[0] == '\0' ) {
+ g_strlcpy ( (wayp + i)->typ, "unknown",
+ sizeof ((wayp + i)->typ));
+ }
+
+ e = fprintf (st, "%-22s %10s %11s "
+ "%s"
+ " %d %d %d %d %s"
+ "\n",
+ (wayp + i)->name, la, lo,
+ (wayp + i)->typ,
+ (wayp + i)->wlan, (wayp + i)->action,
+ (wayp + i)->sqlnr,
+ (wayp + i)->proximity,
+ (wayp + i)->comment);
+ }
+ fclose (st);
+ }
+
+}
+
+/* *****************************************************************************
+ * load the waypoint from way.txt
+ */
+void
+loadwaypoints ()
+{
+ gchar fn_way_txt[2048];
+ FILE *st;
+ gint i, e, p, wlan, action, sqlnr, proximity;
+ gchar buf[512], slat[80], slong[80], typ[40];
+ struct stat stat_buf;
+
+ if ( 0 == waytxtstamp )
+ wayp = g_new (wpstruct, wpsize);
+
+// g_strlcpy (fn_way_txt, local_config.dir_home, sizeof (fn_way_txt));
+// g_strlcat (fn_way_txt, local_config.wp_file, sizeof (fn_way_txt));
+ g_strlcpy (fn_way_txt, local_config.wp_file, sizeof (fn_way_txt));
+
+
+ /* Check m_time of way.txt file */
+ stat(fn_way_txt, &stat_buf);
+ if ( stat_buf.st_mtime == waytxtstamp )
+ return;
+ waytxtstamp = stat_buf.st_mtime;
+
+
+
+ maxwp = 0;
+ sqlnr = -1;
+ st = fopen (fn_way_txt, "r");
+ if (st == NULL)
+ {
+ perror (fn_way_txt);
+ return;
+ }
+
+ if ( mydebug > 0 )
+ {
+ g_print ("load waypoint file %s\n",fn_way_txt);
+ }
+
+ i = 0;
+ while ((p = fgets (buf, 512, st) != 0))
+ {
+ e = sscanf (buf, "%s %s %s %s %d %d %d %d\n",
+ (wayp + i)->name, slat, slong, typ,
+ &wlan, &action, &sqlnr, &proximity);
+ coordinate_string2gdouble(slat, &((wayp + i)->lat));
+ coordinate_string2gdouble(slong,&((wayp + i)->lon));
+ /* limit waypoint name to 20 chars */
+ (wayp + i)->name[20] = 0;
+ g_strlcpy ((wayp + i)->typ, "unknown", 40);
+ (wayp + i)->wlan = 0;
+ (wayp + i)->action = 0;
+ (wayp + i)->sqlnr = -1;
+ (wayp + i)->proximity = 0;
+
+ if (e >= 3)
+ {
+ (wayp + i)->dist = 0;
+
+ if (e >= 4)
+ g_strlcpy ((wayp + i)->typ, typ, 40);
+
+ if (e >= 5)
+ (wayp + i)->wlan = wlan;
+ if (e >= 6)
+ (wayp + i)->action = action;
+ if (e >= 7)
+ (wayp + i)->sqlnr = sqlnr;
+ if (e >= 8)
+ (wayp + i)->proximity = proximity;
+
+ if ((strncmp((wayp + i)->name, "R-",2)) == 0)
+ (wayp + i)->action = 1;
+
+ i++;
+ maxwp = i;
+
+ if (maxwp >= wpsize)
+ {
+ wpsize += 1000;
+ wayp = g_renew (wpstruct, wayp,
+ wpsize);
+ }
+
+ }
+ }
+
+ fclose (st);
+
+ g_print ("%s reloaded\n", local_config.wp_file);
+
+}
diff --git a/src/waypoint.h b/src/waypoint.h
new file mode 100644
index 0000000..7b4eeb5
--- /dev/null
+++ b/src/waypoint.h
@@ -0,0 +1,52 @@
+/***********************************************************************
+
+Copyright (c) 2001,2002 Fritz Ganter <ganter@ganter.at>
+
+Website: www.kraftvoll.at/software
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+#ifndef GPSDRIVE_WAYPOINT_H
+#define GPSDRIVE_WAYPOINT_H
+
+/*
+ * See waypoint.c for details.
+ */
+
+gint addwaypoint_cb (GtkWidget * widget, gpointer datum);
+gint addwaypoint_gtk_cb (GtkWidget * widget, guint datum);
+gint addwaypointchange_cb (GtkWidget * widget, guint datum);
+gint addwaypointdestroy_cb (GtkWidget * widget, guint datum);
+gint delwp_cb (GtkWidget * widget, guint datum);
+gint jumpwp_cb (GtkWidget * widget, guint datum);
+gint watchwp_cb (GtkWidget * widget, guint * datum);
+glong addwaypoint (gchar * wp_name, gchar * wp_type, gchar * wp_comment, gdouble wp_lat, gdouble wp_lon, gint save_in_db);
+void check_and_reload_way_txt();
+void draw_waypoints();
+void loadwaypoints();
+void mark_waypoint();
+void set_position_to_waypoint();
+void set_waypoint_pos(gdouble lat, gdouble lon);
+gint setwp_cb (GtkWidget * widget, guint datum);
+gint sel_targetweg_cb (GtkWidget * widget, guint datum);
+gint sel_target_destroy_cb (GtkWidget *widget, guint datum);
+void draw_radar();
+gint setsortcolumn (GtkWidget * w, gpointer datum);
+
+#endif /* GPSDRIVE_WAYPOINT_H */
diff --git a/src/wlan.c b/src/wlan.c
new file mode 100644
index 0000000..013594c
--- /dev/null
+++ b/src/wlan.c
@@ -0,0 +1,490 @@
+/***********************************************************************
+
+Copyright (c) 2001-2004 Fritz Ganter <ganter@ganter.at>
+
+Website: www.gpsdrive.de
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+
+/*
+ * wlan_ support module: display
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <sys/time.h>
+
+#include <gmodule.h>
+#include <gdk/gdktypes.h>
+#include "gtk/gtk.h"
+
+#include "gpsdrive.h"
+#include "poi.h"
+#include "wlan.h"
+#include "config.h"
+#include "gettext.h"
+#include "icons.h"
+#include <gpsdrive_config.h>
+#include "gui.h"
+
+#include "gettext.h"
+
+/* Defines for gettext I18n */
+# include <libintl.h>
+# define _(String) gettext(String)
+# ifdef gettext_noop
+# define N_(String) gettext_noop(String)
+# else
+# define N_(String) (String)
+# endif
+
+extern poi_type_struct poi_type_list[poi_type_list_max];
+
+extern gint do_unit_test;
+extern gint maploaded;
+extern gint isnight, disableisnight;
+extern color_struct colors;
+extern currentstatus_struct current;
+extern gint debug, mydebug;
+extern gint usesql;
+extern glong mapscale;
+extern GdkGC *kontext_map;
+
+char txt[5000];
+PangoLayout *wlan_label_layout;
+#include "mysql/mysql.h"
+
+extern MYSQL mysql;
+extern MYSQL_RES *res;
+extern MYSQL_ROW row;
+
+// keep actual visible WLAN Points in Memory
+wlan_struct *wlan_list;
+glong wlan_nr; // current number of wlan to count
+glong wlan_max; // max index of WLANs actually in memory
+glong wlan_limit = -1; // max allowed index (if you need more you have to alloc memory)
+
+int wlan_closed=19; // these will be filled later from the Database
+int wlan_open=19;
+int wlan_wep=19;
+
+gchar wlan_label_font[100];
+GdkColor wlan_colorv;
+PangoFontDescription *pfd;
+PangoLayout *wlan_label_layout;
+
+/* ****************************************************************** */
+
+void wlan_rebuild_list (void);
+
+
+/* *******************************************************
+ */
+void
+wlan_init (void)
+{
+ wlan_limit = 40000;
+ wlan_list = g_new (wlan_struct, wlan_limit);
+ if (wlan_list == NULL)
+ {
+ g_print ("Error: Cannot allocate Memory for %ld wlan\n", wlan_limit);
+ wlan_limit = -1;
+ return;
+ }
+
+ wlan_rebuild_list ();
+}
+
+
+/* *********************************************************
+ */
+gdouble wlan_lat_lr = 0, wlan_lon_lr = 0;
+gdouble wlan_lat_ul = 0, wlan_lon_ul = 0;
+
+int
+wlan_check_if_moved (void)
+{
+ gdouble lat_lr, lon_lr;
+ gdouble lat_ul, lon_ul;
+
+ if (wlan_lat_lr == 0 && wlan_lon_lr == 0 &&
+ wlan_lat_ul == 0 && wlan_lon_ul == 0)
+ return 1;
+
+ calcxytopos (SCREEN_X, SCREEN_Y, &lat_lr, &lon_lr, current.zoom);
+ calcxytopos (0, 0, &lat_ul, &lon_ul, current.zoom);
+
+ if (wlan_lat_lr == lat_lr && wlan_lon_lr == lon_lr &&
+ wlan_lat_ul == lat_ul && wlan_lon_ul == lon_ul)
+ return 0;
+ return 1;
+}
+
+/* *******************************************************
+ * if zoom, xoff, yoff or map are changed
+ * TODO: use the real datatype for reading from database
+ * (don't convert string to double)
+ */
+void
+wlan_rebuild_list (void)
+{
+ char sql_query[5000];
+ char sql_where[5000];
+ struct timeval t;
+ int r, rges;
+ time_t ti;
+
+ gdouble lat_ul, lon_ul;
+ gdouble lat_ll, lon_ll;
+ gdouble lat_ur, lon_ur;
+ gdouble lat_lr, lon_lr;
+ gdouble lat_min, lon_min;
+ gdouble lat_max, lon_max;
+ gdouble lat_mid, lon_mid;
+
+
+ if (!usesql)
+ return;
+
+ if ( current.mapscale > 100000000)
+ return;
+
+ if (!local_config.showwlan)
+ {
+ if (mydebug > 20)
+ printf ("wlan_rebuild_list: WLAN_draw is off\n");
+ return;
+ }
+
+ if (mydebug > 20)
+ {
+ printf
+ ("wlan_rebuild_list: Start\t\t\t\t\t\tvvvvvvvvvvvvvvvvvvvvvvvvvv\n");
+ }
+
+
+ if (!maploaded)
+ return;
+
+ if (current.importactive)
+ return;
+
+
+ // calculate the start and stop for lat/lon according to the displayed section
+ calcxytopos (0, 0, &lat_ul, &lon_ul, current.zoom);
+ calcxytopos (0, SCREEN_Y, &lat_ll, &lon_ll, current.zoom);
+ calcxytopos (SCREEN_X, 0, &lat_ur, &lon_ur, current.zoom);
+ calcxytopos (SCREEN_X, SCREEN_Y, &lat_lr, &lon_lr, current.zoom);
+
+ lat_min = min (lat_ll, lat_ul);
+ lat_max = max (lat_lr, lat_ur);
+ lon_min = min (lon_ll, lon_ul);
+ lon_max = max (lon_lr, lon_ur);
+
+ lat_mid = (lat_min + lat_max) / 2;
+ lon_mid = (lon_min + lon_max) / 2;
+
+ gdouble wlan_posx, wlan_posy;
+ gettimeofday (&t, NULL);
+ ti = t.tv_sec + t.tv_usec / 1000000.0;
+
+ { // Limit the select with WHERE min_lat<lat<max_lat AND min_lon<lon<max_lon
+ g_snprintf (sql_where, sizeof (sql_where),
+ " WHERE ( lat BETWEEN %.6f AND %.6f ) "
+ " AND ( lon BETWEEN %.6f AND %.6f ) "
+ , lat_min, lat_max, lon_min, lon_max
+ );
+ g_strdelimit (sql_where, ",", '.'); // For different LANG
+ if (mydebug > 20)
+ {
+ printf ("wlan_rebuild_list: WLAN mysql where: %s\n", sql_where);
+ }
+ }
+
+
+ g_snprintf (sql_query, sizeof (sql_query),
+ "SELECT lat,lon,macaddr,essid,wep,nettype,cloaked FROM wlan "
+ "%s LIMIT 40000", sql_where);
+
+ if (mydebug > 20)
+ printf ("wlan_rebuild_list: WLAN mysql query: %s\n", sql_query);
+
+ if (dl_mysql_query (&mysql, sql_query)) {
+ printf ("wlan_rebuild_list: Error in query: \n");
+ fprintf (stderr, "wlan_rebuild_list: Error in query: %s\n",
+ dl_mysql_error (&mysql));
+ return;
+ }
+
+ if (!(res = dl_mysql_store_result (&mysql)))
+ {
+ fprintf (stderr, "Error in store results: %s\n",
+ dl_mysql_error (&mysql));
+ dl_mysql_free_result (res);
+ res = NULL;
+ return;
+ }
+
+ rges = r = 0;
+ wlan_nr = 0;
+ while ((row = dl_mysql_fetch_row (res)))
+ {
+ rges++;
+ gdouble lat, lon;
+
+ if (mydebug > 20)
+ fprintf (stderr, "WLAN Query Result: lat:%s\tlon:%s\t%s\t%s\t%s\t%s\t%s\n",
+ row[0], row[1], row[2], row[3], row[4], row[5], row[6]);
+
+ lat = g_strtod (row[0], NULL);
+ lon = g_strtod (row[1], NULL);
+ calcxy (&wlan_posx, &wlan_posy, lon, lat, current.zoom);
+
+ if ((wlan_posx > -50) && (wlan_posx < (SCREEN_X + 50)) &&
+ (wlan_posy > -50) && (wlan_posy < (SCREEN_Y + 50)))
+ {
+ // get next free mem for wlan_list
+ if (wlan_nr > wlan_limit) {
+ wlan_limit = wlan_nr + 10000;
+ if (mydebug > 20)
+ g_print ("Try to allocate Memory for %ld wlan\n", wlan_limit);
+
+ wlan_list = g_renew (wlan_struct, wlan_list, wlan_limit);
+ if (NULL == wlan_list) {
+ g_print ("Error: Cannot allocate Memory for %ld wlan\n", wlan_limit);
+ wlan_limit = -1;
+ return;
+ }
+ }
+
+ // Save retrieved wlan information into structure
+ (wlan_list + wlan_nr)->lat = lat;
+ (wlan_list + wlan_nr)->lon = lon;
+ (wlan_list + wlan_nr)->x = wlan_posx;
+ (wlan_list + wlan_nr)->y = wlan_posy;
+
+ g_snprintf ((wlan_list + wlan_nr)->name,
+ sizeof ((wlan_list + wlan_nr)->name), "%s ( %s )"
+ , row[2], row[3] );
+ (wlan_list + wlan_nr)->nettype = (gint) g_strtod (row[5], NULL);
+ int icon_index = 19;
+ if ( (wlan_list + wlan_nr)->nettype == 0 ) icon_index = wlan_open;
+ if ( (wlan_list + wlan_nr)->nettype == 1 ) icon_index = wlan_closed;
+ if ( (wlan_list + wlan_nr)->nettype == 2 ) icon_index = wlan_wep;
+ (wlan_list + wlan_nr)->poi_type_id = icon_index;
+
+ if ( mydebug > 20 )
+ printf ("DB: %f %f \t( x:%f, y:%f )\t%s\n",
+ (wlan_list + wlan_nr)->lat, (wlan_list + wlan_nr)->lon,
+ (wlan_list + wlan_nr)->x, (wlan_list + wlan_nr)->y,
+ (wlan_list + wlan_nr)->name
+ );
+ wlan_nr++;
+ } else {
+ if ( mydebug > 20 )
+ fprintf( stderr ,"Ignoring Point, becuause it's out of bound\n");
+ }
+ }
+
+
+ wlan_max = wlan_nr;
+
+ // print time for getting Data
+ gettimeofday (&t, NULL);
+ ti = (t.tv_sec + t.tv_usec / 1000000.0) - ti;
+ if (mydebug > 20)
+ printf (_("%ld(%d) rows read in %.2f seconds\n"), wlan_max,
+ rges, (gdouble) ti);
+
+
+ /* remember where the data belongs to */
+ wlan_lat_lr = lat_lr;
+ wlan_lon_lr = lon_lr;
+ wlan_lat_ul = lat_ul;
+ wlan_lon_ul = lon_ul;
+
+ if (!dl_mysql_eof (res))
+ {
+ fprintf (stderr, "wlan_rebuild_list: Error in dl_mysql_eof: %s\n",
+ dl_mysql_error (&mysql));
+ dl_mysql_free_result (res);
+ res = NULL;
+ return;
+ }
+
+ dl_mysql_free_result (res);
+ res = NULL;
+
+ if (mydebug > 20)
+ {
+ printf ("wlan_rebuild_list: End \t\t\t\t\t\t");
+ printf ("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
+ }
+}
+
+
+
+
+
+/* *******************************************************
+ * draw wlan_ on image
+ TODO: find free space on drawing area. So the Text doesn't overlap
+*/
+void
+wlan_draw_list (void)
+{
+ // gint t;
+ // GdkSegment *routes;
+
+ gint i;
+
+ if (!usesql)
+ return;
+
+ if (current.importactive)
+ return;
+
+ if (!maploaded)
+ return;
+
+ if (!local_config.showwlan)
+ {
+ if (mydebug > 20)
+ printf ("wlan_draw_list: WLAN_draw is off\n");
+ return;
+ }
+
+
+ if (mydebug > 20)
+ printf
+ ("wlan_draw_list: Start\t\t\tvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n");
+
+ if (wlan_check_if_moved ())
+ wlan_rebuild_list ();
+
+
+ /* ------------------------------------------------------------------ */
+ /* draw wlan_list wlan points */
+ if (mydebug > 20)
+ printf ("wlan_draw_list: drawing %ld wlans\n", wlan_max);
+
+ for (i = 0; i < wlan_max; i++)
+ {
+ gdouble posx, posy;
+
+ posx = (wlan_list + i)->x;
+ posy = (wlan_list + i)->y;
+
+ if ((posx >= 0) && (posx < SCREEN_X) &&
+ (posy >= 0) && (posy < SCREEN_Y))
+ {
+ gdk_gc_set_line_attributes (kontext_map, 2, 0, 0, 0);
+
+ g_strlcpy (txt, (wlan_list + i)->name, sizeof (txt));
+
+ {
+ GdkPixbuf *icon;
+ int icon_index = (wlan_list + i)->poi_type_id;
+ if (mydebug > 20)
+ printf( "icon_index: %d\n",icon_index);
+
+ icon = poi_type_list[icon_index].icon;
+
+ if (icon != NULL && icon_index > 0)
+ {
+ if (wlan_max < 2000)
+ {
+ int wx = gdk_pixbuf_get_width (icon);
+ int wy = gdk_pixbuf_get_height (icon);
+
+ gdk_draw_pixbuf (drawable, kontext_map, icon,
+ 0, 0,
+ posx - wx / 2,
+ posy - wy / 2,
+ wx, wy, GDK_RGB_DITHER_NONE, 0, 0);
+ }
+ } else {
+ gdk_gc_set_foreground (kontext_map, &colors.red);
+ if (wlan_max < 20000) { // Only draw small + if more than ... Wlan Points
+ draw_plus_sign (posx, posy);
+ } else {
+ draw_small_plus_sign (posx, posy);
+ }
+ }
+
+ // Only draw Text if less than 1000 Wlan Points are to be displayed
+ if (wlan_max < 1000)
+ {
+ draw_label (txt, posx, posy);
+ }
+ }
+ }
+
+
+ }
+ if (mydebug > 20)
+ printf
+ ("wlan_draw_list: End\t\t\t^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
+}
+
+
+/* *******************************************************
+ * query all Info for Wlan Points in area arround lat/lon
+*/
+void
+wlan_query_area (gdouble lat1, gdouble lon1, gdouble lat2, gdouble lon2)
+{
+ gint i;
+ printf ("Query: %f ... %f , %f ... %f\n", lat1, lat2, lon1, lon2);
+
+ for (i = 0; i < wlan_max; i++)
+ {
+ //printf ("check WLAN: %ld: %f %f :%s\n",i,(wlan_list + i)->lat, (wlan_list + i)->lon,(wlan_list + i)->name);
+ if ((lat1 <= (wlan_list + i)->lat) &&
+ ((wlan_list + i)->lat <= lat2) &&
+ (lon1 <= (wlan_list + i)->lon) && ((wlan_list + i)->lon <= lon2))
+ {
+ printf ("Query WLAN: %d: %f %f :%s\n",
+ i, (wlan_list + i)->lat, (wlan_list + i)->lon,
+ (wlan_list + i)->name);
+ }
+ }
+}
+
+/* *******************************************************
+ * get IDs for the different wlan types
+ */
+void get_poi_type_id_for_wlan() {
+ int i;
+ for (i = 0; i < poi_type_list_max; i++)
+ {
+ poi_type_list[i].icon = NULL;
+ if (strcmp (poi_type_list[i].name,"wlan.closed") == 0){
+ wlan_closed=i;
+ } else if (strcmp (poi_type_list[i].name,"wlan.open") == 0){
+ wlan_open=i;
+ } else if (strcmp (poi_type_list[i].name,"wlan.wep") == 0){
+ wlan_wep=i;
+ }
+ }
+}
diff --git a/src/wlan.h b/src/wlan.h
new file mode 100644
index 0000000..ba749c4
--- /dev/null
+++ b/src/wlan.h
@@ -0,0 +1,75 @@
+/***********************************************************************
+
+Copyright (c) 2001,2002 Fritz Ganter <ganter@ganter.at>
+
+Website: www.kraftvoll.at/software
+
+Disclaimer: Please do not use for navigation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*********************************************************************/
+
+
+#ifndef GPSDRIVE_WLAN_H
+#define GPSDRIVE_WLAN_H
+
+/*
+ * See wlan.c for details.
+ */
+
+#include <gtk/gtk.h>
+
+typedef struct
+{
+ gint wp_id;
+ gdouble lon;
+ gdouble lat;
+ gdouble alt;
+ gchar name[80];
+ gint poi_type_id;
+ gdouble proximity;
+ gchar comment[255];
+ gchar url[160];
+ gint source_id;
+ gint nettype;
+ gdouble x; // x position on screen
+ gdouble y; // y position on screen
+}
+wlan_struct;
+
+void wlan_init (void);
+void wlan_rebuild_list (void);
+void wlan_draw_list (void);
+void wlan_query_area ( gdouble lat1, gdouble lon1 ,gdouble lat2, gdouble lon2 );
+void wlan_rebuild_list (void);
+int wlan_check_if_moved (void);
+GdkPixbuf * read_wlan_icon (gchar * icon_name);
+void get_poi_type_id_for_wlan();
+
+#define wlan_type_list_string_length 80
+typedef struct
+{
+ gint poi_type_id;
+ gchar name[wlan_type_list_string_length];
+ gchar icon_name[wlan_type_list_string_length];
+ GdkPixbuf *icon;
+ gint scale_min;
+ gint scale_max;
+} wlan_type_struct;
+#define wlan_type_list_max 4000
+
+
+#endif /* GPSDRIVE_WLAN_H */