24
24
#include "converter.h"
26
26
#include "tracks.h"
27
#include "hrm_functions.h"
29
#if GPSD_API_MAJOR_VERSION < 5
30
#define gps_read gps_poll
31
#define gps_open gps_open_r
34
28
#define BUFSIZE 512
35
29
char * distance2scale(float distance, float *factor);
36
static void * get_gps_thread(void *ptr);
30
void * get_gps_thread(void *ptr);
39
33
static GIOChannel *gpsd_io_channel =NULL;
40
static struct gps_data_t libgps_gpsdata;
41
static gboolean libgps_initialized = FALSE;
43
gboolean reconnect_gpsd = TRUE;
45
static guint sid1 = 0;
46
static guint sid3 = 0;
47
static guint watchdog = 0;
48
static guint gps_timer = 0;
34
static struct gps_data_t *libgps_gpsdata = NULL;
36
static guint sid1, sid3;
55
44
int pixel_x, pixel_y, x, y, last_x, last_y;
56
45
static float lat, lon, lat_tmp=0, lon_tmp=0;
57
46
float trip_delta=0;
69
58
gc_3 = gdk_gc_new(pixmap);
70
59
gc_4 = gdk_gc_new(pixmap);
71
60
gc_5 = gdk_gc_new(pixmap);
77
66
gdk_gc_set_rgb_fg_color(gc, &color);
78
67
gdk_gc_set_line_attributes(gc,
79
68
5, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
83
72
color.green = 5000;
84
73
color.blue = 55000;
85
74
gdk_gc_set_rgb_fg_color(gc_2, &color);
86
75
gdk_gc_set_line_attributes(gc_2,
87
76
6, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
91
80
color.green = 35000;
92
81
color.blue = 65500;
93
82
gdk_gc_set_rgb_fg_color(gc_3, &color);
94
83
gdk_gc_set_line_attributes(gc_3,
95
84
7, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
99
88
color.green = 5000;
101
90
gdk_gc_set_rgb_fg_color(gc_4, &color);
102
91
gdk_gc_set_line_attributes(gc_4,
103
92
7, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
107
96
color.green = 65500;
108
97
color.blue = 65500;
109
98
gdk_gc_set_rgb_fg_color(gc_5, &color);
110
99
gdk_gc_set_line_attributes(gc_5,
111
100
11, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
116
if(!gpsdata || reconnect_gpsd)
105
if(!gpsdata || global_reconnect_gpsd)
122
111
trackpoint_t *tp = g_new0(trackpoint_t,1);
124
113
lat = deg2rad(gpsdata->fix.latitude);
125
lon = deg2rad(gpsdata->fix.longitude);
114
lon = deg2rad(gpsdata->fix.longitude);
128
117
pixel_x = lon2pixel(global_zoom, lon);
129
118
pixel_y = lat2pixel(global_zoom, lat);
131
120
x = pixel_x - global_x;
132
121
y = pixel_y - global_y;
135
124
pixel_x = lon2pixel(global_zoom, lon_tmp);
136
125
pixel_y = lat2pixel(global_zoom, lat_tmp);
138
127
last_x = pixel_x - global_x;
139
128
last_y = pixel_y - global_y;
143
if(gpsdata->seen_valid)
132
if(gpsdata->seen_vaild)
145
134
int hand_x, hand_y, hand_wp_x, hand_wp_y;
146
135
double heading_rad, bearing;
148
137
heading_rad = (gpsdata->fix.heading * (1.0 / 180.0)) * M_PI;
150
if(gpsdata->fix.speed>0.3)
139
if(gpsdata->fix.speed>0.3)
152
141
hand_x = 25 * sinf(heading_rad);
153
142
hand_y = -25 * cosf(heading_rad);
251
240
set_mapcenter(gpsdata->fix.latitude, gpsdata->fix.longitude, global_zoom);
259
248
if( gpsdata->valid && lat_tmp!=0 && lon_tmp!=0)
261
trip_delta = 6371.0 * acos(sin(lat) * sin(lat_tmp) +
250
trip_delta = 6371.0 * acos(sin(lat) * sin(lat_tmp) +
262
251
cos(lat) * cos(lat_tmp) * cos(lon_tmp-lon) );
264
253
if(isnan(trip_delta))
270
259
if(trip_delta > TRIP_DELTA_MIN)
272
261
tp->time = gpsdata->fix.time;
275
264
tp->lat_deg = gpsdata->fix.latitude;
276
tp->lon_deg = gpsdata->fix.longitude;
265
tp->lat_deg = gpsdata->fix.longitude;
277
266
tp->alt = gpsdata->fix.altitude;
278
267
tp->speed = gpsdata->fix.speed;
279
268
tp->head = gpsdata->fix.heading;
280
269
tp->hdop = gpsdata->hdop;
283
272
if (trip_delta > SEGMENT_DISTANCE)
287
276
if (trackpoint_list->length > TRACKPOINT_LIST_MAX_LENGTH)
288
277
g_free(g_queue_pop_head(trackpoint_list));
290
279
g_queue_push_tail(trackpoint_list, tp);
294
283
if(trip_counter_on)
296
285
trip_distance += trip_delta;
299
288
if(gpsdata->valid && gpsdata->fix.speed > trip_maxspeed)
300
289
trip_maxspeed = gpsdata->fix.speed;
306
295
trip_time_accumulated = 0;
308
297
if(trip_counter_got_stopped)
299
printf("counter had been stopped \n");
310
300
trip_counter_got_stopped = FALSE;
311
301
trip_time_accumulated = trip_time;
312
302
trip_starttime = 0;
316
if(trip_starttime == 0 && gpsdata->seen_valid)
306
if(trip_starttime == 0 && gpsdata->seen_vaild)
318
308
trip_starttime = gpsdata->fix.time;
322
if(trip_starttime > 0 && gpsdata->seen_valid)
312
if(trip_starttime > 0 && gpsdata->seen_vaild)
324
trip_time = gpsdata->fix.time - trip_starttime + trip_time_accumulated;
314
trip_time = gpsdata->fix.time - trip_starttime + trip_time_accumulated;
327
317
if(trip_time < 0)
329
printf("trip counter halted\n");
339
330
trip_counter_got_stopped = TRUE;
340
331
lat_tmp = lon_tmp = 0;
349
339
if(trip_logger_on && gpsdata->valid)
352
342
if(gpsdata->valid)
366
if(hrm_on && (!hrmdata || global_reconnect_hrm))
368
else if(hrm_on && hrmdata) {
370
if(global_infopane_visible)
380
reconnect_gpsd = TRUE;
359
printf("*** %s(): \n",__PRETTY_FUNCTION__);
361
global_reconnect_gpsd = TRUE;
362
g_source_remove(watchdog);
364
g_source_remove(sid1);
365
g_source_remove(sid3);
387
372
osd_speed(gboolean force_redraw)
390
375
PangoContext *context = NULL;
391
376
PangoLayout *layout = NULL;
392
377
PangoFontDescription *desc = NULL;
398
383
static int x = 10, y = 10;
399
384
static int width = 0, height = 0;
401
386
static double speed_tmp = 0;
403
388
double unit_conv = 1;
405
if(gpsdata && mouse_dx == 0 && mouse_dy == 0)
390
if(gpsdata && mouse_dx == 0 && mouse_dy == 0)
407
392
switch (global_speed_unit)
498
466
if(label == NULL)
499
467
label = GTK_LABEL(lookup_widget(window1, "label4"));
501
469
num_dl_threads = update_thread_number(0);
502
470
if(num_dl_threads && !global_tiles_in_dl_queue)
504
g_snprintf (buffer, BUFSIZE,
505
_("<b>no GPSD found</b>"
507
"<span foreground='#0000ff'><b>D%d</b></span>"),
472
g_snprintf(buffer, BUFSIZE,
473
"<b>no GPSD found</b> - <span foreground='#0000ff'><b>D%d</b></span>",
510
476
else if (num_dl_threads && global_tiles_in_dl_queue)
511
g_snprintf (buffer, BUFSIZE,
512
_("<b>no GPSD found</b>"
514
"<span foreground='#0000ff'><b>D%d</b></span>"
477
g_snprintf(buffer, BUFSIZE,
478
"<b>no GPSD found</b> - <span foreground='#0000ff'><b>D%d</b></span> - <b>[%d]</b>",
517
479
num_dl_threads, global_tiles_in_dl_queue);
519
g_snprintf (buffer, BUFSIZE, _("<b>no GPSD found</b>"));
481
g_snprintf(buffer, BUFSIZE, "<b>no GPSD found</b>");
484
g_snprintf(buffer, BUFSIZE, "<span foreground='#ff0000'><b>New Message arrived. Click here.</b></span>");
521
486
gtk_label_set_label(label, buffer);
602
567
num_dl_threads = update_thread_number(0);
604
569
if(num_dl_threads && !global_tiles_in_dl_queue)
605
g_sprintf(numdl_buf, "<span foreground='#0000ff'><b>D%d</b></span> ",
570
g_sprintf(numdl_buf, "<span foreground='#0000ff'><b>D%d</b></span> ",
607
572
else if (num_dl_threads && global_tiles_in_dl_queue)
608
g_sprintf(numdl_buf, "<span foreground='#0000ff'><b>D%d</b></span>-%d ",
573
g_sprintf(numdl_buf, "<span foreground='#0000ff'><b>D%d</b></span>-%d ",
609
574
num_dl_threads, global_tiles_in_dl_queue);
611
576
g_sprintf(numdl_buf, "%s", "");
614
579
g_snprintf(buffer, BUFSIZE,
615
_("%s%s%s%s<b>%4.1f</b>%s "
616
"<small>trp </small><b>%.2f</b>%s "
617
"<small>alt </small><b>%.0f</b>%s "
618
"<small>hdg </small><b>%.0f</b>° "
619
"<small></small>%d/%.1f"),
620
numdl_buf, dl_buf, tr_buf, ff_buf,
621
gpsdata->fix.speed * 3.6 * unit_conv, speedunit,
622
trip_distance * unit_conv, distunit,
623
gpsdata->fix.altitude * unit_conv_alt, altunit,
624
gpsdata->fix.heading,
625
gpsdata->satellites_used,
580
"%s%s%s%s<b>%4.1f</b>%s "
581
"<small>trp </small><b>%.2f</b>%s "
582
"<small>alt </small><b>%.0f</b>%s "
583
"<small>hdg </small><b>%.0f</b>° "
584
"<small></small>%d/%.1f",
589
gpsdata->fix.speed * 3.6 * unit_conv, speedunit,
590
trip_distance * unit_conv, distunit,
591
gpsdata->fix.altitude * unit_conv_alt, altunit,
592
gpsdata->fix.heading * unit_conv,
593
gpsdata->satellites_used,
597
g_snprintf(buffer, BUFSIZE, "<span foreground='#ff0000'><b>New Message arrived. Click here.</b></span>");
628
599
gtk_label_set_label(label, buffer);
631
602
if(global_infopane_visible)
638
609
time_sec = (time_t)gpsdata->fix.time;
639
610
ts = localtime(&time_sec);
642
strftime(buffer, sizeof(buffer), "<big><b>%a %Y-%m-%d %H:%M:%S</b></big>", ts);
613
strftime(buffer, sizeof(buffer), "<big><b>%a %Y-%m-%d %H:%M:%S</b></big>", ts);
643
614
gtk_label_set_label(label41,buffer);
646
617
switch (global_latlon_unit)
649
620
g_snprintf(buffer, BUFSIZE, "<big><b>%f - %f</b></big>", gpsdata->fix.latitude, gpsdata->fix.longitude);
652
g_snprintf(buffer, BUFSIZE, "<big><b>%s %s</b></big>",
623
g_snprintf(buffer, BUFSIZE, "<big><b>%s %s</b></big>",
653
624
latdeg2latmin(gpsdata->fix.latitude),
654
625
londeg2lonmin(gpsdata->fix.longitude));
657
g_snprintf(buffer, BUFSIZE, "<big><b>%s %s</b></big>",
628
g_snprintf(buffer, BUFSIZE, "<big><b>%s %s</b></big>",
658
629
latdeg2latsec(gpsdata->fix.latitude),
659
630
londeg2lonsec(gpsdata->fix.longitude));
661
632
gtk_label_set_label(label31,buffer);
664
g_snprintf(buffer, BUFSIZE,
665
"<b><span foreground='#0000ff'><span font_desc='50'>%.1f</span></span></b> %s",
635
g_snprintf(buffer, BUFSIZE,
636
"<b><span foreground='#0000ff'><span font_desc='50'>%.1f</span></span></b> %s",
666
637
gpsdata->fix.speed*3.6*unit_conv, speedunit);
667
638
gtk_label_set_label(label38,buffer);
670
641
g_snprintf(buffer, BUFSIZE, "<big><b>%.1f %s</b></big>", gpsdata->fix.altitude * unit_conv_alt, altunit);
671
642
gtk_label_set_label(label39,buffer);
674
645
g_snprintf(buffer, BUFSIZE, "<big><b>%.1f°</b></big> ", gpsdata->fix.heading);
675
646
gtk_label_set_label(label42,buffer);
678
g_snprintf (buffer, BUFSIZE, _("<big><b>%d</b> <small>HDOP</small><b> %.1f</b></big>"),
649
g_snprintf(buffer, BUFSIZE, "<big><b>%d</b> <small>HDOP</small><b> %.1f</b></big>",
679
650
gpsdata->satellites_used, gpsdata->hdop);
680
651
gtk_label_set_label(label43,buffer);
687
658
g_snprintf(buffer, BUFSIZE, "<big><b>%.3f</b></big> <small>%s</small>", trip_distance*unit_conv,distunit);
688
659
gtk_label_set_label(label45,buffer);
692
663
trip_hours = trip_time / 3600;
693
664
trip_minutes = ((int)trip_time%3600)/60;
694
665
trip_seconds = (int)trip_time % 60;
696
667
if (trip_seconds < 10 && trip_minutes < 10)
698
669
g_sprintf(buffer, "<big><b>%d:0%d:0%d</b></big>",trip_hours,trip_minutes,trip_seconds);
738
if (!libgps_initialized)
741
#if GPSD_API_MAJOR_VERSION >= 7 /* API change. gpsd version 3.18 and subsequent. */
742
ret = gps_read(&libgps_gpsdata, NULL, 0);
744
ret = gps_read(&libgps_gpsdata);
746
/* Note that gps_read() will never actually return 0
747
(zero-length reads are converted internally to a -1 return,
748
since they mean that the connection to the daemon has closed),
749
and gps_poll() will never return >0, but both will return
750
<0 to indicate failure; hence the following ">= 0" check:
716
ret = gps_poll(libgps_gpsdata);
754
gpsdata->satellites_used = libgps_gpsdata.satellites_used;
755
gpsdata->hdop = libgps_gpsdata.dop.hdop;
756
gpsdata->fix.time = libgps_gpsdata.fix.time;
719
gpsdata->satellites_used = libgps_gpsdata->satellites_used;
720
gpsdata->hdop = libgps_gpsdata->dop.hdop;
721
gpsdata->fix.time = libgps_gpsdata->fix.time;
757
722
if (isnan(gpsdata->fix.time))
759
724
gpsdata->fix.time = (time_t) 0;
761
gpsdata->valid = (libgps_gpsdata.status != STATUS_NO_FIX);
726
gpsdata->valid = (libgps_gpsdata->status != STATUS_NO_FIX);
762
727
if (gpsdata->valid)
764
gpsdata->seen_valid = TRUE;
765
gpsdata->fix.mode = libgps_gpsdata.fix.mode;
766
gpsdata->fix.latitude = libgps_gpsdata.fix.latitude;
767
gpsdata->fix.longitude = libgps_gpsdata.fix.longitude;
768
gpsdata->fix.speed = libgps_gpsdata.fix.speed;
769
gpsdata->fix.heading = libgps_gpsdata.fix.track;
770
gpsdata->fix.altitude = libgps_gpsdata.fix.altitude;
729
gpsdata->seen_vaild = TRUE;
730
gpsdata->fix.latitude = libgps_gpsdata->fix.latitude;
731
gpsdata->fix.longitude = libgps_gpsdata->fix.longitude;
732
gpsdata->fix.speed = libgps_gpsdata->fix.speed;
733
gpsdata->fix.heading = libgps_gpsdata->fix.track;
734
gpsdata->fix.altitude = libgps_gpsdata->fix.altitude;
773
737
g_source_remove(watchdog);
774
738
watchdog = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT_IDLE,60,reset_gpsd_io,NULL,NULL);
778
fprintf (stderr, _("connection to gpsd LOST\n"));
779
return cb_gpsd_io_error(src, condition, data);
742
printf("gps_poll returned %d\n", ret);
788
/* Set this flag to FALSE *immediately* so that a slow gps_open()
789
doesn't cause successive cb_gps_timer() callbacks to call
790
us *again* before we've even finished *this* invocation--
791
which would create multiple, simultaneous get_gps_thread()
792
threads and all sorts of associated problems:
794
reconnect_gpsd = FALSE;
797
/* Disable the regularly scheduled callback to cb_gps_timer()
798
until after get_gps_thread() has returned, to guard against
799
the situation described above when reconnect_gpsd
800
is re-set by something else (e.g.: the user bouncing
801
on the `Change GPSD' button):
803
g_source_remove (gps_timer);
808
g_source_remove(watchdog);
812
g_source_remove(sid1);
817
g_source_remove(sid3);
821
if (gpsd_io_channel) {
822
g_io_channel_unref (gpsd_io_channel);
823
gpsd_io_channel = NULL;
826
/* Note that we're *not* free'ing the internal gpsdata structure,
827
ever. We'd only immediately reallocate it, so it's not a net win
828
in terms of memory-footprint; and it doesn't contain references
829
to any file-descriptors or other ephemeral resources, so
830
the only thing we'd be doing by re-initialising it would be
831
throwing away our last known fix, etc.
834
if (libgps_initialized) {
835
gps_close(&libgps_gpsdata);
836
libgps_initialized = FALSE;
839
#if GLIB_CHECK_VERSION(2,34,0)
840
g_thread_new("gps thread", &get_gps_thread, (gpointer)NULL);
842
751
g_thread_create(&get_gps_thread, NULL, FALSE, NULL);
847
755
get_gps_thread(void *ptr)
849
if (gps_open(global_server, global_port, &libgps_gpsdata) == 0)
757
libgps_gpsdata = gps_open(global_server, global_port);
851
fprintf (stderr, _("connection to gpsd SUCCEEDED \n"));
853
libgps_initialized = TRUE;
855
/* Unless someone has re-set reconnect_gpsd
856
between when get_gps() set it and now,
857
then it should still be FALSE; if someone else
858
*did* re-set it, then they did it for a reason.
860
Either way, we're better off leaving it alone,
760
fprintf(stderr, "connection to gpsd SUCCEEDED \n");
762
global_reconnect_gpsd = FALSE;
866
766
gpsdata = g_new0(tangogps_gps_data_t,1);
870
gps_stream(&libgps_gpsdata, WATCH_ENABLE, NULL);
770
gps_stream(libgps_gpsdata, WATCH_ENABLE | POLL_NONBLOCK, NULL);
872
772
watchdog = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT_IDLE,60,reset_gpsd_io,NULL,NULL);
875
gpsd_io_channel = g_io_channel_unix_new(libgps_gpsdata.gps_fd);
775
gpsd_io_channel = g_io_channel_unix_new(libgps_gpsdata->gps_fd);
876
776
g_io_channel_set_flags(gpsd_io_channel, G_IO_FLAG_NONBLOCK, NULL);
879
779
sid1 = g_io_add_watch_full(gpsd_io_channel, G_PRIORITY_HIGH_IDLE+200, G_IO_ERR | G_IO_HUP, cb_gpsd_io_error, NULL, NULL);
882
782
sid3 = g_io_add_watch_full(gpsd_io_channel, G_PRIORITY_HIGH_IDLE+200, G_IO_IN | G_IO_PRI, cb_gpsd_data, NULL, NULL);
885
/* Failure. Maybe it's transient--try again
886
on the next cycle: */
887
reconnect_gpsd = TRUE;
890
gps_timer = g_timeout_add (1000, cb_gps_timer, NULL);
935
829
lon2 = pixel2lon(global_zoom, max_bar_length);
937
831
distance = get_distance(lat, lon1, lat, lon2);
939
833
buffer = distance2scale(distance, &factor);
940
834
max_bar_length *= factor;
942
836
gdk_draw_line(map_drawable->window, gc, 4, y, max_bar_length+6, y);
943
gdk_draw_line(map_drawable->window, gc1,5, y, max_bar_length+5, y);
837
gdk_draw_line(map_drawable->window, gc1,5, y, max_bar_length+5, y);
946
840
context = gtk_widget_get_pango_context (map_drawable);
947
841
layout = pango_layout_new (context);
948
842
desc = pango_font_description_new();
950
844
pango_font_description_set_absolute_size (desc, 12 * PANGO_SCALE);
951
845
pango_layout_set_font_description (layout, desc);
952
846
pango_layout_set_text (layout, buffer, strlen(buffer));
956
850
pango_layout_get_pixel_size(layout, &width, &height);
960
854
gdk_gc_set_line_attributes(gc,
961
height+2, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_ROUND);
855
height+2, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_ROUND);
963
gdk_gc_set_line_attributes(gc1,
964
height, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_ROUND);
857
gdk_gc_set_line_attributes(gc1,
858
height, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_ROUND);
966
860
gdk_draw_line(map_drawable->window, gc1, 22, y-height/2+6, 20+width+6, y-height/2+6);
970
gdk_draw_layout(map_drawable->window,
864
gdk_draw_layout(map_drawable->window,
978
872
pango_font_description_free (desc);
979
873
g_object_unref (layout);