/* This gets called once for each new sentence. */ static void update_lcd(struct gps_data_t *gpsdata) { char tmpbuf[255]; char *gridsquare; /* Get our location in Maidenhead. */ gridsquare = maidenhead(gpsdata->fix.latitude,gpsdata->fix.longitude); /* Fill in the latitude and longitude. */ if (gpsdata->fix.mode >= MODE_2D) { int track; char *s; s = deg_to_str(deg_type, fabs(gpsdata->fix.latitude)); snprintf(tmpbuf, sizeof(tmpbuf) - 1, "widget_set gpsd one 1 1 {Lat: %s %c}\n", s, (gpsdata->fix.latitude < 0) ? 'S' : 'N'); send_lcd(tmpbuf); s = deg_to_str(deg_type, fabs(gpsdata->fix.longitude)); snprintf(tmpbuf, sizeof(tmpbuf) - 1, "widget_set gpsd two 1 2 {Lon: %s %c}\n", s, (gpsdata->fix.longitude < 0) ? 'W' : 'E'); send_lcd(tmpbuf); /* As a pilot, a heading of "0" gives me the heebie-jeebies (ie, 0 == "invalid heading data", 360 == "North"). */ track=(int)(gpsdata->fix.track); if (track == 0) track = 360; snprintf(tmpbuf, sizeof(tmpbuf) - 1, "widget_set gpsd three 1 3 {%.1f %s %d deg}\n", gpsdata->fix.speed*speedfactor, speedunits, track); send_lcd(tmpbuf); } else { send_lcd("widget_set gpsd one 1 1 {Lat: n/a}\n"); send_lcd("widget_set gpsd two 1 2 {Lon: n/a}\n"); send_lcd("widget_set gpsd three 1 3 {n/a}\n"); } /* Fill in the altitude and fix status. */ if (gpsdata->fix.mode == MODE_3D) { int n; for(n=0;n<CLIMB-2;n++) climb[n]=climb[n+1]; climb[CLIMB-1]=gpsdata->fix.climb; avgclimb=0.0; for(n=0;n<CLIMB;n++) avgclimb+=climb[n]; avgclimb/=CLIMB; snprintf(tmpbuf, sizeof(tmpbuf) - 1, "widget_set gpsd four 1 4 {%d %s %s %d fpm }\n", (int)(gpsdata->fix.altitude*altfactor), altunits, gridsquare, (int)(avgclimb * METERS_TO_FEET * 60)); } else { snprintf(tmpbuf, sizeof(tmpbuf) - 1, "widget_set gpsd four 1 4 {n/a}\n"); } send_lcd(tmpbuf); }
/*@-mustfreefresh@*/ static void update_gps_panel(struct gps_data_t *gpsdata) /* This gets called once for each new GPS sentence. */ { int i; int newstate; char scr[128], *s; /* This is for the satellite status display. Originally lifted from * xgps.c. Note that the satellite list may be truncated based on * available screen size, or may only show satellites used for the * fix. */ if (gpsdata->satellites_visible != 0) { if (display_sats >= MAX_POSSIBLE_SATS) { for (i = 0; i < MAX_POSSIBLE_SATS; i++) { if (i < gpsdata->satellites_visible) { (void)snprintf(scr, sizeof(scr), " %3d %02d %03d %02d %c", gpsdata->skyview[i].PRN, gpsdata->skyview[i].elevation, gpsdata->skyview[i].azimuth, (int)gpsdata->skyview[i].ss, gpsdata->skyview[i].used ? 'Y' : 'N'); } else { (void)strlcpy(scr, "", sizeof(scr)); } (void)mvwprintw(satellites, i + 2, 1, "%-*s", SATELLITES_WIDTH - 3, scr); } } else { int n = 0; for (i = 0; i < MAX_POSSIBLE_SATS; i++) { if (n < display_sats) { if ((i < gpsdata->satellites_visible) && (gpsdata->skyview[i].used || (gpsdata->satellites_visible <= display_sats))) { (void)snprintf(scr, sizeof(scr), " %3d %02d %03d %02d %c", gpsdata->skyview[i].PRN, gpsdata->skyview[i].elevation, gpsdata->skyview[i].azimuth, (int)gpsdata->skyview[i].ss, gpsdata->skyview[i].used ? 'Y' : 'N'); (void)mvwprintw(satellites, n + 2, 1, "%-*s", SATELLITES_WIDTH - 3, scr); n++; } } } if (n < display_sats) { for (i = n; i <= display_sats; i++) { (void)mvwprintw(satellites, i + 2, 1, "%-*s", SATELLITES_WIDTH - 3, ""); } } } } /* Print time/date. */ if (isnan(gpsdata->fix.time) == 0) { (void)unix_to_iso8601(gpsdata->fix.time, scr, sizeof(scr)); } else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(datawin, 1, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); /* Fill in the latitude. */ if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.latitude) == 0) { (void)snprintf(scr, sizeof(scr), "%s %c", deg_to_str(deg_type, fabs(gpsdata->fix.latitude)), (gpsdata->fix.latitude < 0) ? 'S' : 'N'); } else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(datawin, 2, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); /* Fill in the longitude. */ if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.longitude) == 0) { (void)snprintf(scr, sizeof(scr), "%s %c", deg_to_str(deg_type, fabs(gpsdata->fix.longitude)), (gpsdata->fix.longitude < 0) ? 'W' : 'E'); } else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(datawin, 3, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); /* Fill in the altitude. */ if (gpsdata->fix.mode >= MODE_3D && isnan(gpsdata->fix.altitude) == 0) (void)snprintf(scr, sizeof(scr), "%.1f %s", gpsdata->fix.altitude * altfactor, altunits); else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(datawin, 4, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); /* Fill in the speed. */ if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track) == 0) (void)snprintf(scr, sizeof(scr), "%.1f %s", gpsdata->fix.speed * speedfactor, speedunits); else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(datawin, 5, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); /* Fill in the heading. */ if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track) == 0) { double magheading = true2magnetic(gpsdata->fix.latitude, gpsdata->fix.longitude, gpsdata->fix.track); if (!magnetic_flag || isnan(magheading) != 0) { (void)snprintf(scr, sizeof(scr), "%.1f deg (true)", gpsdata->fix.track); } else { (void)snprintf(scr, sizeof(scr), "%.1f deg (mag) ", magheading); } } else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(datawin, 6, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); /* Fill in the rate of climb. */ if (gpsdata->fix.mode >= MODE_3D && isnan(gpsdata->fix.climb) == 0) (void)snprintf(scr, sizeof(scr), "%.1f %s/min", gpsdata->fix.climb * altfactor * 60, altunits); else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(datawin, 7, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); /* Fill in the GPS status and the time since the last state * change. */ if (gpsdata->online == 0) { newstate = 0; (void)snprintf(scr, sizeof(scr), "OFFLINE"); } else { newstate = gpsdata->fix.mode; switch (gpsdata->fix.mode) { case MODE_2D: (void)snprintf(scr, sizeof(scr), "2D %sFIX (%d secs)", (gpsdata->status == STATUS_DGPS_FIX) ? "DIFF " : "", (int)(time(NULL) - status_timer)); break; case MODE_3D: (void)snprintf(scr, sizeof(scr), "3D %sFIX (%d secs)", (gpsdata->status == STATUS_DGPS_FIX) ? "DIFF " : "", (int)(time(NULL) - status_timer)); break; default: (void)snprintf(scr, sizeof(scr), "NO FIX (%d secs)", (int)(time(NULL) - status_timer)); break; } } (void)mvwprintw(datawin, 8, DATAWIN_VALUE_OFFSET, "%-*s", 27, scr); /* Note that the following fields are exceptions to the * sizing rule. The minimum window size does not include these * fields, if the window is too small, they get excluded. This * may or may not change if/when the output for these fields is * fixed and/or people request their permanence. They're only * there in the first place because I arbitrarily thought they * sounded interesting. ;^) */ if (window_length >= (MIN_GPS_DATAWIN_SIZE + 5)) { /* Fill in the estimated horizontal position error. */ if (isnan(gpsdata->fix.epx) == 0) (void)snprintf(scr, sizeof(scr), "+/- %d %s", (int)(gpsdata->fix.epx * altfactor), altunits); else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(datawin, 9, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22, scr); if (isnan(gpsdata->fix.epy) == 0) (void)snprintf(scr, sizeof(scr), "+/- %d %s", (int)(gpsdata->fix.epy * altfactor), altunits); else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(datawin, 10, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22, scr); /* Fill in the estimated vertical position error. */ if (isnan(gpsdata->fix.epv) == 0) (void)snprintf(scr, sizeof(scr), "+/- %d %s", (int)(gpsdata->fix.epv * altfactor), altunits); else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(datawin, 11, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22, scr); /* Fill in the estimated track error. */ if (isnan(gpsdata->fix.epd) == 0) (void)snprintf(scr, sizeof(scr), "+/- %d deg", (int)(gpsdata->fix.epd)); else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(datawin, 12, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22, scr); /* Fill in the estimated speed error. */ if (isnan(gpsdata->fix.eps) == 0) (void)snprintf(scr, sizeof(scr), "+/- %d %s", (int)(gpsdata->fix.eps * speedfactor), speedunits); else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(datawin, 13, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22, scr); /* Fill in the time offset. */ if (isnan(gpsdata->fix.time) == 0) (void)snprintf(scr, sizeof(scr), "%.3f", (double)(timestamp()-gpsdata->fix.time)); else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(datawin, 14, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22, scr); /* Fill in the grid square (esr thought *this* one was interesting). */ /*@-branchstate@*/ if (isnan(gpsdata->fix.longitude)==0 && isnan(gpsdata->fix.latitude)==0) s = maidenhead(gpsdata->fix.latitude,gpsdata->fix.longitude); else s = "n/a"; (void)mvwprintw(datawin, 15, DATAWIN_VALUE_OFFSET + 5, "%-*s", 22, s); /*@+branchstate@*/ } /* Be quiet if the user requests silence. */ /*@-modobserver@*/ if (!silent_flag && raw_flag && (s = (char *)gps_data(gpsdata)) != NULL) { char *p; for (p = s + strlen(s); --p > s && isspace(*p); *p = '\0') ; (void)wprintw(messages, "%s\n", s); } /*@+modobserver@*/ /* Reset the status_timer if the state has changed. */ if (newstate != state) { status_timer = time(NULL); state = newstate; } (void)wrefresh(datawin); (void)wrefresh(satellites); if (raw_flag) { (void)wrefresh(messages); } }