static void cooked_pvt(void) { char scr[128]; if (isnan(session.gpsdata.fix.time) == 0) { (void)unix_to_iso8601(session.gpsdata.fix.time, scr, sizeof(scr)); } else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(cookedwin, 1, 7, "%-24s", scr); if (session.gpsdata.fix.mode >= MODE_2D && isnan(session.gpsdata.fix.latitude) == 0) { (void)snprintf(scr, sizeof(scr), "%s %c", deg_to_str(deg_ddmmss, fabs(session.gpsdata.fix.latitude)), (session.gpsdata.fix.latitude < 0) ? 'S' : 'N'); } else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(cookedwin, 1, 37, "%-17s", scr); if (session.gpsdata.fix.mode >= MODE_2D && isnan(session.gpsdata.fix.longitude) == 0) { (void)snprintf(scr, sizeof(scr), "%s %c", deg_to_str(deg_ddmmss, fabs(session.gpsdata.fix.longitude)), (session.gpsdata.fix.longitude < 0) ? 'W' : 'E'); } else (void)snprintf(scr, sizeof(scr), "n/a"); (void)mvwprintw(cookedwin, 1, 60, "%-17s", scr); }
/* 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); }
/* runs on each sentence */ static void update_panel(struct gps_data_t *gpsdata, char *message, size_t len UNUSED, int level UNUSED) { unsigned int i; int newstate; XmString string[MAXCHANNELS + 1]; char s[128], *latlon, *sp; /* the raw data sisplay */ if (message[0] != '\0') while (isspace(*(sp = message + strlen(message) - 1))) *sp = '\0'; XmTextFieldSetString(status, message); /* This is for the satellite status display */ if (gpsdata->satellites) { string[0] = XmStringCreateSimple( "PRN: Elev: Azim: SNR: Used:"); for (i = 0; i < MAXCHANNELS; i++) { if (i < (unsigned int)gpsdata->satellites) { (void)snprintf(s, sizeof(s), " %3d %2d %3d %2d %c", gpsdata->PRN[i], gpsdata->elevation[i], gpsdata->azimuth[i], gpsdata->ss[i], gpsdata->used[i] ? 'Y' : 'N'); } else (void)strlcpy(s, " ", sizeof(s)); string[i + 1] = XmStringCreateSimple(s); } XmListReplaceItemsPos(satellite_list, string, (int)sizeof(string), 1); #ifndef S_SPLINT_S for (i = 0; i < (sizeof(string)/sizeof(string[0])); i++) XmStringFree(string[i]); #endif /* S_SPLINT_S */ } /* here are the value fields */ if (isnan(gpsdata->fix.time)==0) { (void)unix_to_iso8601(gpsdata->fix.time, s, sizeof(s)); XmTextFieldSetString(text_1, s); } else XmTextFieldSetString(text_1, "n/a"); if (gpsdata->fix.mode >= MODE_2D) { latlon = deg_to_str(deg_type, fabs(gpsdata->fix.latitude)); (void)snprintf(s, sizeof(s), "%s %c", latlon, (gpsdata->fix.latitude < 0) ? 'S' : 'N'); XmTextFieldSetString(text_2, s); } else XmTextFieldSetString(text_2, "n/a"); if (gpsdata->fix.mode >= MODE_2D) { latlon = deg_to_str(deg_type, fabs(gpsdata->fix.longitude)); (void)snprintf(s, sizeof(s), "%s %c", latlon, (gpsdata->fix.longitude < 0) ? 'W' : 'E'); XmTextFieldSetString(text_3, s); } else XmTextFieldSetString(text_3, "n/a"); if (gpsdata->fix.mode == MODE_3D) { (void)snprintf(s, sizeof(s), "%f %s", gpsdata->fix.altitude * altunits->factor, altunits->legend); XmTextFieldSetString(text_4, s); } else XmTextFieldSetString(text_4, "n/a"); if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track)==0) { (void)snprintf(s, sizeof(s), "%f %s", gpsdata->fix.speed * speedunits->factor, speedunits->legend); XmTextFieldSetString(text_5, s); } else XmTextFieldSetString(text_5, "n/a"); if (gpsdata->fix.mode >= MODE_2D && isnan(gpsdata->fix.track)==0) { (void)snprintf(s, sizeof(s), "%f degrees", gpsdata->fix.track); XmTextFieldSetString(text_6, s); } else XmTextFieldSetString(text_6, "n/a"); if (isnan(gpsdata->fix.eph)==0) { (void)snprintf(s, sizeof(s), "%f %s", gpsdata->fix.eph * altunits->factor, altunits->legend); XmTextFieldSetString(text_7, s); } else XmTextFieldSetString(text_7, "n/a"); if (isnan(gpsdata->fix.epv)==0) { (void)snprintf(s, sizeof(s), "%f %s", gpsdata->fix.epv * altunits->factor, altunits->legend); XmTextFieldSetString(text_8, s); } else XmTextFieldSetString(text_8, "n/a"); if (gpsdata->fix.mode == MODE_3D && isnan(gpsdata->fix.climb)==0) { (void)snprintf(s, sizeof(s), "%f %s/sec", gpsdata->fix.climb * altunits->factor, altunits->legend); XmTextFieldSetString(text_9, s); } else XmTextFieldSetString(text_9, "n/a"); if (gpsdata->set & DEVICEID_SET) { (void)strlcpy(s, "xgps: ", sizeof(s)); (void)strlcpy(s+6, gpsdata->gps_id, sizeof(s)-6); set_title(s); } if (gpsdata->online == 0) { newstate = 0; (void)strlcpy(s, "OFFLINE", sizeof(s)); } else { newstate = gpsdata->fix.mode; switch (gpsdata->fix.mode) { case MODE_2D: (void)snprintf(s, sizeof(s), "2D %sFIX", (gpsdata->status == STATUS_DGPS_FIX) ? "DIFF " : ""); break; case MODE_3D: (void)snprintf(s, sizeof(s), "3D %sFIX", (gpsdata->status == STATUS_DGPS_FIX) ? "DIFF " : ""); break; default: (void)strlcpy(s, "NO FIX", sizeof(s)); break; } } if (newstate != state) { timer = time(NULL); state = newstate; } (void)snprintf(s + strlen(s), sizeof(s) - strlen(s), " (%d secs)", (int) (time(NULL) - timer)); XmTextFieldSetString(text_10, s); draw_graphics(gpsdata); XtRemoveTimeOut(timeout); timeout = XtAppAddTimeOut(app, 2000, handle_time_out, NULL); }
/*@-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); } }