*
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <math.h>
#include "viking.h"
#include <string.h>
#include <glib.h>
#include <glib/gprintf.h>
+#ifdef HAVE_LIBGPS
#include <gps.h>
+#else
+#define DEFAULT_GPSD_PORT "0"
+#endif
#define DISCONNECT_UPDATE_SIGNAL(vl, val) g_signal_handlers_disconnect_matched(vl, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, val)
static VikGpsLayer *vik_gps_layer_create (VikViewport *vp);
static void gps_layer_add_menu_items( VikGpsLayer *vtl, GtkMenu *menu, gpointer vlp );
static void gps_layer_drag_drop_request ( VikGpsLayer *val_src, VikGpsLayer *val_dest, GtkTreeIter *src_item_iter, GtkTreePath *dest_path );
+#ifdef HAVE_LIBGPS
static void realtime_tracking_draw(VikGpsLayer *vgl, VikViewport *vp);
+#endif
static void gps_upload_cb( gpointer layer_and_vlp[2] );
static void gps_download_cb( gpointer layer_and_vlp[2] );
static void gps_empty_upload_cb( gpointer layer_and_vlp[2] );
static void gps_empty_download_cb( gpointer layer_and_vlp[2] );
static void gps_empty_all_cb( gpointer layer_and_vlp[2] );
+#ifdef HAVE_LIBGPS
static void gps_start_stop_tracking_cb( gpointer layer_and_vlp[2] );
+#endif
typedef enum {GARMIN_P = 0, MAGELLAN_P, NUM_PROTOCOLS} vik_gps_proto;
static gchar * params_protocols[] = {"Garmin", "Magellan", NULL};
} GpsSession;
static void gps_session_delete(GpsSession *sess);
-static gchar *params_groups[] = {"Data Mode", "Realtime Tracking Mode"};
+static gchar *params_groups[] = {
+ "Data Mode",
+#ifdef HAVE_LIBGPS
+ "Realtime Tracking Mode",
+#endif
+};
+
enum {GROUP_DATA_MODE, GROUP_REALTIME_MODE};
static VikLayerParam gps_layer_params[] = {
{ "gps_protocol", VIK_LAYER_PARAM_UINT, GROUP_DATA_MODE, "GPS Protocol:", VIK_LAYER_WIDGET_COMBOBOX, params_protocols, NULL},
{ "gps_port", VIK_LAYER_PARAM_UINT, GROUP_DATA_MODE, "Serial Port:", VIK_LAYER_WIDGET_COMBOBOX, params_ports, NULL},
+#ifdef HAVE_LIBGPS
{ "record_tracking", VIK_LAYER_PARAM_BOOLEAN, GROUP_REALTIME_MODE, "Recording tracks", VIK_LAYER_WIDGET_CHECKBUTTON},
{ "center_start_tracking", VIK_LAYER_PARAM_BOOLEAN, GROUP_REALTIME_MODE, "Jump to current position on start", VIK_LAYER_WIDGET_CHECKBUTTON},
{ "centered_tracking", VIK_LAYER_PARAM_BOOLEAN, GROUP_REALTIME_MODE, "Keep current position at center", VIK_LAYER_WIDGET_CHECKBUTTON},
{ "gpsd_host", VIK_LAYER_PARAM_STRING, GROUP_REALTIME_MODE, "Gpsd Host:", VIK_LAYER_WIDGET_ENTRY},
{ "gpsd_port", VIK_LAYER_PARAM_STRING, GROUP_REALTIME_MODE, "Gpsd Port:", VIK_LAYER_WIDGET_ENTRY},
+#endif
};
-enum {PARAM_PROTOCOL=0, PARAM_PORT, PARAM_REALTIME_REC, PARAM_REALTIME_CENTER_START, PARAM_REALTIME_CENTERED, PARAM_GPSD_HOST, PARAM_GPSD_PORT, NUM_PARAMS};
+enum {
+ PARAM_PROTOCOL=0, PARAM_PORT,
+#ifdef HAVE_LIBGPS
+ PARAM_REALTIME_REC, PARAM_REALTIME_CENTER_START, PARAM_REALTIME_CENTERED, PARAM_GPSD_HOST, PARAM_GPSD_PORT,
+#endif
+ NUM_PARAMS};
VikLayerInterface vik_gps_layer_interface = {
"GPS",
(VikLayerFuncDragDropRequest) gps_layer_drag_drop_request,
};
-enum {TRW_DOWNLOAD=0, TRW_UPLOAD, TRW_REALTIME, NUM_TRW};
-static gchar * trw_names[] = {"GPS Download", "GPS Upload", "GPS Realtime Tracking"};
+enum {TRW_DOWNLOAD=0, TRW_UPLOAD,
+#ifdef HAVE_LIBGPS
+ TRW_REALTIME,
+#endif
+ NUM_TRW};
+static gchar * trw_names[] = {
+ "GPS Download", "GPS Upload",
+#ifdef HAVE_LIBGPS
+ "GPS Realtime Tracking",
+#endif
+};
+#ifdef HAVE_LIBGPS
typedef struct {
struct gps_data_t gpsd;
VikGpsLayer *vgl;
} VglGpsd;
+#endif
+#ifdef HAVE_LIBGPS
typedef struct {
struct gps_fix_t fix;
gboolean dirty; /* needs to be saved */
} GpsFix;
+#endif
struct _VikGpsLayer {
VikLayer vl;
VikTrwLayer * trw_children[NUM_TRW];
GList * children; /* used only for writing file */
int cur_read_child; /* used only for reading file */
+#ifdef HAVE_LIBGPS
VglGpsd *vgpsd;
gboolean realtime_tracking;
GMutex *realtime_tracking_mutex;
GdkGC *realtime_track_pt_gc;
GdkGC *realtime_track_pt1_gc;
GdkGC *realtime_track_pt2_gc;
+#endif
/* params */
guint protocol_id;
else
g_warning("Unknown serial port device");
break;
+#ifdef HAVE_LIBGPS
case PARAM_GPSD_HOST:
if (vgl->gpsd_host)
g_free(vgl->gpsd_host);
case PARAM_REALTIME_CENTERED:
vgl->realtime_keep_at_center = data.b;
break;
+#endif
default:
g_warning("gps_layer_set_param(): unknown parameter");
}
case PARAM_PORT:
rv.u = vgl->serial_port_id;
break;
+#ifdef HAVE_LIBGPS
case PARAM_GPSD_HOST:
rv.s = vgl->gpsd_host ? vgl->gpsd_host : "";
break;
case PARAM_REALTIME_CENTERED:
rv.b = vgl->realtime_keep_at_center;
break;
+#endif
default:
g_warning("gps_layer_get_param(): unknown parameter");
}
vgl->children = NULL;
vgl->cur_read_child = 0;
+#ifdef HAVE_LIBGPS
vgl->realtime_tracking_mutex = g_mutex_new();
vgl->realtime_tracking = FALSE;
vgl->vgpsd = NULL;
vgl->realtime_gpsd_unit = gpsd_units();
// fprintf(stderr, "DEBUG: gpsd_unit = %d\n", vgl->realtime_gpsd_unit);
vgl->realtime_track = NULL;
+#endif
/* Setting params here */
vgl->protocol_id = 0;
if (!vik_viewport_get_half_drawn( VIK_VIEWPORT(data)))
vik_layer_draw ( vl, data );
}
+#ifdef HAVE_LIBGPS
if (vgl->realtime_tracking) {
if (VIK_LAYER(vgl) == trigger) {
if ( vik_viewport_get_half_drawn ( VIK_VIEWPORT(data) ) ) {
if (!vik_viewport_get_half_drawn( VIK_VIEWPORT(data)))
realtime_tracking_draw(vgl, VIK_VIEWPORT(data));
}
+#endif
}
static void gps_layer_change_coord_mode ( VikGpsLayer *vgl, VikCoordMode mode )
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_widget_show ( item );
+#ifdef HAVE_LIBGPS
item = gtk_menu_item_new_with_label ( vgl->realtime_tracking ?
"Stop realtime tracking" :
"Start realtime tracking" );
item = gtk_menu_item_new();
gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
gtk_widget_show ( item );
+#endif
item = gtk_menu_item_new_with_label ( "Empty Upload" );
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(gps_empty_upload_cb), pass_along );
disconnect_layer_signal(VIK_LAYER(vgl->trw_children[i]), vgl);
g_object_unref(vgl->trw_children[i]);
}
+#ifdef HAVE_LIBGPS
if (vgl->realtime_track_gc != NULL)
g_object_unref(vgl->realtime_track_gc);
if (vgl->realtime_track_bg_gc != NULL)
g_object_unref(vgl->realtime_track_pt2_gc);
if (vgl->realtime_tracking_mutex != NULL)
g_mutex_free(vgl->realtime_tracking_mutex);
+#endif
}
gboolean vik_gps_layer_delete ( VikGpsLayer *vgl, GtkTreeIter *iter )
vik_trw_layer_delete_all_tracks ( vgl-> trw_children[TRW_DOWNLOAD]);
}
+#ifdef HAVE_LIBGPS
static void realtime_tracking_draw(VikGpsLayer *vgl, VikViewport *vp)
{
struct LatLon ll;
{
struct LatLon ll;
GList *last_tp;
+
+ /* Note that fix.time is a double, but it should not affect the precision
+ for most GPS */
+ time_t cur_timestamp = vgl->realtime_fix.fix.time;
+ time_t last_timestamp = vgl->last_fix.fix.time;
+
+ if (cur_timestamp < last_timestamp) {
+ return;
+ }
+
if (vgl->realtime_record && vgl->realtime_fix.dirty) {
gboolean replace = FALSE;
int heading = (int)floor(vgl->realtime_fix.fix.track);
if (((last_tp = g_list_last(vgl->realtime_track->trackpoints)) != NULL) &&
(vgl->realtime_fix.fix.mode > MODE_2D) &&
(vgl->last_fix.fix.mode <= MODE_2D) &&
- (1.0 > vgl->realtime_fix.fix.time - vgl->last_fix.fix.time)) {
+ ((cur_timestamp - last_timestamp) < 2)) {
g_free(last_tp->data);
vgl->realtime_track->trackpoints = g_list_delete_link(vgl->realtime_track->trackpoints, last_tp);
replace = TRUE;
}
- if (forced || replace ||
- ((heading < last_heading) && (heading < (last_heading - 3))) ||
- ((heading > last_heading) && (heading > (last_heading + 3))) ||
- ((alt != VIK_DEFAULT_ALTITUDE) && (alt != last_alt))) {
+ if (replace ||
+ ((cur_timestamp != last_timestamp) &&
+ ((forced ||
+ ((heading < last_heading) && (heading < (last_heading - 3))) ||
+ ((heading > last_heading) && (heading > (last_heading + 3))) ||
+ ((alt != VIK_DEFAULT_ALTITUDE) && (alt != last_alt)))))) {
/* TODO: check for new segments */
VikTrackpoint *tp = vik_trackpoint_new();
tp->newsegment = FALSE;
gps_poll(&vgl->vgpsd->gpsd);
return TRUE;
}
+#endif
static gchar *make_track_name(VikTrwLayer *vtl)
{
}
+#ifdef HAVE_LIBGPS
static void gps_start_stop_tracking_cb( gpointer layer_and_vlp[2])
{
VikGpsLayer *vgl = (VikGpsLayer *)layer_and_vlp[0];
if (vgl->realtime_tracking) {
struct gps_data_t *gpsd = gps_open(vgl->gpsd_host, vgl->gpsd_port);
if (gpsd == NULL) {
- fprintf(stderr, "DEBUG: %s(): gps_open failed\n", __PRETTY_FUNCTION__);
+ GtkWidget *dialog = gtk_message_dialog_new (VIK_GTK_WINDOW_FROM_LAYER(vgl),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "Failed to connect to gpsd at %s (port %s)",
+ vgl->gpsd_host, vgl->gpsd_port);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
vgl->realtime_tracking = FALSE;
return;
}
g_mutex_unlock(vgl->realtime_tracking_mutex);
}
}
+#endif