+diff -ur gps3d-1.20/Makefile gps3d-1.20-pere/Makefile
+--- gps3d-1.20/Makefile Fri Mar 29 17:15:14 2002
++++ gps3d-1.20-pere/Makefile Sat Jan 1 23:29:03 2005
+@@ -1,6 +1,6 @@
+
+ LDFLAGS= -s
+-CFLAGS= -g0 -O99 -fomit-frame-pointer -I. -DNDEBUG -DX11
++CFLAGS= -g -O99 -fomit-frame-pointer -I. -DNDEBUG -DX11
+
+ #LDFLAGS= -g
+ #CFLAGS= -g3 -O0 -Wall -I. -D_DEBUG
+@@ -56,7 +56,7 @@
+ gps \
+ gpsd \
+ viz
+-
++
+
+ all: ${ALL}
+
+@@ -67,7 +67,7 @@
+ ${CC} ${LDFLAGS} -o gpsd ${GPSD_OBJ} -lm
+
+ viz:${VIZ_OBJ}
+- ${CC} ${LDFLAGS} -o viz ${VIZ_OBJ} -L/usr/X11R6/lib -lGL -lX11 -lXext -lm
++ ${CC} ${LDFLAGS} -o viz ${VIZ_OBJ} -L/usr/X11R6/lib -lGL -lX11 -lXext -lgps -lm
+
+ clean:
+ -rm -f *.o core ${ALL}
+diff -ur gps3d-1.20/viz_app.h gps3d-1.20-pere/viz_app.h
+--- gps3d-1.20/viz_app.h Fri Mar 29 17:15:14 2002
++++ gps3d-1.20-pere/viz_app.h Sun Jan 2 00:23:59 2005
+@@ -8,7 +8,7 @@
+ void loop();
+ void newChannel(void*,int (*callback)(void*),void*);
+
+-int gpsInput();
++int gpsInput(void *data);
+ void gpsCharInput(uint8_t);
+ void *gpsSocket();
+ void gpsOutput(const char *);
+@@ -27,12 +27,15 @@
+ void paintSquareInfo(double,double,double,double,double,double);
+ void newGGA(const uint8_t*,const uint8_t*,const uint8_t*);
+ void newFix(const uint8_t*,const uint8_t*,const uint8_t*,const uint8_t*,const uint8_t*);
++void newFixValue(double latitude, double longitude, double timestamp);
+ void paintGreatcircle(double,double,double,double,int,double*,double*);
+ void toggleAutomap();
+ void paintAuxInfo();
+
+ void paintSatellites();
+ void newSolution(const uint8_t [][81],int);
++void newSolutionValue(const int prn_used[], int nFields);
++void newSatelliteFixValue(int prn, double elevation, double azimuth);
+ void newSatelliteFix(
+ const uint8_t*,
+ const uint8_t*,
+diff -ur gps3d-1.20/viz_brush.cpp gps3d-1.20-pere/viz_brush.cpp
+--- gps3d-1.20/viz_brush.cpp Fri Mar 29 17:15:14 2002
++++ gps3d-1.20-pere/viz_brush.cpp Sat Jan 1 22:39:56 2005
+@@ -18,7 +18,7 @@
+ while(size--)
+ {
+ uint8_t c= *(buffer++);
+- gpsCharInput(c);
++ //gpsCharInput(c);
+ }
+ return 0;
+ }
+diff -ur gps3d-1.20/viz_fix.cpp gps3d-1.20-pere/viz_fix.cpp
+--- gps3d-1.20/viz_fix.cpp Fri Mar 29 17:15:14 2002
++++ gps3d-1.20-pere/viz_fix.cpp Sat Jan 1 23:15:46 2005
+@@ -125,32 +125,14 @@
+ trash();
+ }
+
+-void newFix(
+-const uint8_t *latitude,
+-const uint8_t *latitudeSign,
+-const uint8_t *longitude,
+-const uint8_t *longitudeSign,
+-const uint8_t *timeStamp
+-)
++void newFixValue(double latitude, double longitude, double timestamp)
+ {
+- double tmpLa;
+- double tmpLo;
+- if(parseNMEAAngle(latitude,latitudeSign,&tmpLa)<0) return;
+- if(parseNMEAAngle(longitude,longitudeSign,&tmpLo)<0) return;
+- if(tmpLa!=la || tmpLo!=lo)
++ if(latitude!=la || longitude!=lo)
+ {
+- double hr= (timeStamp[0]-'0')*10 + (timeStamp[1]-'0');
+- double mm= (timeStamp[2]-'0')*10 + (timeStamp[3]-'0');
+- double ss= (timeStamp[4]-'0')*10 + (timeStamp[5]-'0');
+- ss+= (timeStamp[6]-'0')/10.0 + (timeStamp[7]-'0')/100.0;
+- ss+= mm*60;
+- ss+= hr*3600;
+-
+- la= tmpLa;
+- lo= tmpLo;
+- stamp= ss;
++ la = latitude;
++ lo = longitude;
++ stamp = timestamp;
+ trash();
+-
+ }
+
+ if(autoMap)
+@@ -172,6 +154,30 @@
+
+ double dist= system::sqrt(pos[0] + pos[1] + pos[2]);
+ getHTTPMap(0,la,lo,dist);
++ }
++}
++
++void newFix(
++const uint8_t *latitude,
++const uint8_t *latitudeSign,
++const uint8_t *longitude,
++const uint8_t *longitudeSign,
++const uint8_t *timeStamp
++)
++{
++ double tmpLa;
++ double tmpLo;
++ if(parseNMEAAngle(latitude,latitudeSign,&tmpLa)<0) return;
++ if(parseNMEAAngle(longitude,longitudeSign,&tmpLo)<0) return;
++
++ {
++ double hr= (timeStamp[0]-'0')*10 + (timeStamp[1]-'0');
++ double mm= (timeStamp[2]-'0')*10 + (timeStamp[3]-'0');
++ double ss= (timeStamp[4]-'0')*10 + (timeStamp[5]-'0');
++ ss+= (timeStamp[6]-'0')/10.0 + (timeStamp[7]-'0')/100.0;
++ ss+= mm*60;
++ ss+= hr*3600;
++ newFixValue(tmpLa, tmpLo, ss);
+ }
+ }
+
+diff -ur gps3d-1.20/viz_gps.cpp gps3d-1.20-pere/viz_gps.cpp
+--- gps3d-1.20/viz_gps.cpp Fri Mar 29 17:15:14 2002
++++ gps3d-1.20-pere/viz_gps.cpp Sun Jan 2 00:25:59 2005
+@@ -1,6 +1,7 @@
+
+ #include <viz_app.h>
+ #include <viz_system.h>
++#include <gps.h>
+
+ static int checksum(
+ const uint8_t *s
+@@ -9,19 +10,19 @@
+ uint8_t sum1= 0;
+ while(1)
+ {
+- uint8_t c= *(s++);
+- if(c==0 || c=='*') break;
+- sum1^= c;
++ uint8_t c= *(s++);
++ if(c==0 || c=='*') break;
++ sum1^= c;
+ }
+
+ uint32_t sum2= 0;
+ while(1)
+ {
+- int c= *(s++);
+- c-= (c>'9' ? 'A'-10 : '0');
+- if(c<0 || c>15) break;
+- sum2<<= 4;
+- sum2+= c;
++ int c= *(s++);
++ c-= (c>'9' ? 'A'-10 : '0');
++ if(c<0 || c>15) break;
++ sum2<<= 4;
++ sum2+= c;
+ }
+
+ return sum2!=(uint32_t)sum1;
+@@ -123,101 +124,89 @@
+ }
+ }
+
+-void gpsCharInput(
+-uint8_t c
+-)
++static int process_status(struct gps_data_t *status)
+ {
+- static uint8_t *p;
+- static int state= 0;
+- static uint8_t buffer[81];
+- switch(state)
+- {
+- case 0:
+- if(c=='\n') state= 1;
+- break;
+- case 1:
+- if(c=='$') state= 2;
+- else if(c=='\n') state= 1;
+- else state= 0;
+- p= buffer;
+- break;
+- case 2:
+- if(c=='\r')
+- {
+- p[0]= 0;
+- state= 0;
+- sentence(buffer);
+- }
+- else
+- {
+- *(p++)= c;
+- if(p-buffer>=80) state= 0;
+- }
+- break;
++#if 0 /* Not supported yet */
++ if (1)
++ newGGA(utc, quality, altitude);
++ newTrackFix(latitude,latitudesign, longitude, longitudesign);
++ newWaypoint(latitude, latitudeSign, longitude, longitudeSign,
++ ?, ?, name, ?, ?);
++#endif
++ if (status->latlon_stamp.changed)
++ {
++ system::error(0,"info: Got new GPS pos\n");
++ newFixValue(status->latitude, status->longitude,
++ status->latlon_stamp.last_refresh);
++ status->latlon_stamp.changed = 0;
++ }
++
++ if (status->satellite_stamp.changed)
++ {
++ system::error(0,"info: Got %d GPS satellite fixes\n",
++ status->satellites);
++ for (int i = 0; i < status->satellites; ++i)
++ {
++ newSatelliteFixValue(status->PRN[i], status->elevation[i],
++ status->azimuth[i]);
++ }
++ status->satellite_stamp.changed = 0;
++ }
++ if (status->fix_quality_stamp.changed)
++ {
++ int prn_used[MAXCHANNELS];
++ system::error(0,"info: Got GPS satellite solution (%d)\n",
++ status->satellites_used);
++ for (int i = 0; i < status->satellites; ++i)
++ {
++ prn_used[i] = status->PRN[i];
++ }
++ newSolutionValue(status->used, status->satellites_used);
++ status->fix_quality_stamp.changed = 0;
+ }
++ return 0;
+ }
+
+-int gpsInput()
++static struct gps_data_t *status = NULL;
++
++int gpsInput(void *data)
+ {
+- while(1)
++ if (gps_poll(status))
+ {
+- uint8_t c;
+- int r= system::readSocket(gpsSocket(),&c,1);
+- if(r==1) gpsCharInput(c);
+- else break;
++ return process_status(status);
+ }
+ return 0;
+ }
+
+-void *gpsSocket()
++
++void *gpsSocket(void)
+ {
+ static int init= 0;
+- static void *socket;
+ if(init==0)
+ {
+- int port;
+- const char *sport= getPort();
+- const char *server= getServer();
+- if(1!=system::sscanf(sport,"%d",&port)) port= 2222;
+- socket= system::makeSocket(server,port);
+- if(socket==(void*)-1) system::error(0,"warning: can't connect to GPS server %s:%d\n",server,port);
+- else system::error(0,"info: Connected to GPS server %s:%d\n",server,port);
+- init= 1;
++ char *port= (char*)getPort();
++ char *server= (char*)getServer();
++ status = gps_open(server, DEFAULT_GPSD_PORT);
++ if(status==NULL)
++ system::error(0,"warning: can't connect to GPS server %s:%s\n",server,port);
++ else
++ {
++ system::error(0,"info: Connected to GPS server %s:%s\n",server,port);
++ gps_query(status, "w+x\n");
++ init= 1;
++ }
+ }
+- return socket;
++ if (status)
++ return (void*)status->gps_fd;
++ else
++ return (void*)-1;
+ }
+
++/* gpsd do not accept input, and can't handle talkback. Disabled. */
+ void gpsOutput(
+ const char *msg
+ )
+ {
+- uint8_t buf[160];
+- system::sprintf((char*)buf,"$PMGNCMD,%s*XX\r\n",msg);
+-
+- uint8_t sum= 0;
+- uint8_t *p= buf+1;
+- while(1)
+- {
+- uint8_t c= *(p++);
+- if(c=='*') break;
+- sum^= c;
+- }
+-
+- static const uint8_t *tohex= (const uint8_t *)"0123456789ABCDEF";
+- p[0]= tohex[(sum>>4)&0xF];
+- p[1]= tohex[(sum>>0)&0xF];
+-
+- int n= 4+p-buf;
+- while(n)
+- {
+- int r= system::writeSocket(gpsSocket(),buf,n);
+- if(r>=0) n-= r;
+- else if(system::lastError()!=system::eAgain && system::lastError()!=system::eInterrupt)
+- {
+- system::error(0,"warning: can't write to gps socket\n");
+- break;
+- }
+- }
+ }
+
+ void gpsLoadTrackFile(
+diff -ur gps3d-1.20/viz_satellite.cpp gps3d-1.20-pere/viz_satellite.cpp
+--- gps3d-1.20/viz_satellite.cpp Fri Nov 24 01:19:49 2000
++++ gps3d-1.20-pere/viz_satellite.cpp Sat Jan 1 23:49:05 2005
+@@ -4,14 +4,15 @@
+ #include <viz_system.h>
+
+ #define TRAJSIZE 10000
+-static int trajSizes[50];
+-static int trajColor[50];
+-static double lastSatAzimuth[50];
+-static double lastSatElevation[50];
+-static double satX[50][TRAJSIZE];
+-static double satY[50][TRAJSIZE];
+-static double satZ[50][TRAJSIZE];
+-static double satT[50][TRAJSIZE];
++#define MAXSATELLITES 50
++static int trajSizes[MAXSATELLITES];
++static int trajColor[MAXSATELLITES];
++static double lastSatAzimuth[MAXSATELLITES];
++static double lastSatElevation[MAXSATELLITES];
++static double satX[MAXSATELLITES][TRAJSIZE];
++static double satY[MAXSATELLITES][TRAJSIZE];
++static double satZ[MAXSATELLITES][TRAJSIZE];
++static double satT[MAXSATELLITES][TRAJSIZE];
+
+ // earthRadius = 6 378 136 meters
+ // GPS satellites orbit at 20 180 000 meters altitude (from ground)= 26558136 from earth center
+@@ -52,14 +53,30 @@
+ return valid;
+ }
+
++void newSolutionValue(const int prn_used[], int nFields)
++{
++ int tj[MAXSATELLITES];
++ system::memset(tj,0,sizeof(tj));
++ if(nFields>15) nFields=15;
++ for(int j=3; j<nFields; ++j)
++ {
++ tj[prn_used[j]] = 1;
++ }
++
++ if(system::memcmp(trajColor,tj,sizeof(tj)))
++ {
++ system::memcpy(trajColor,tj,sizeof(tj));
++ trash();
++ }
++}
++
+ void newSolution(
+ const uint8_t sol[][81],
+ int nFields
+ )
+ {
+- int tj[50];
+- int size= 50*sizeof(int);
+- system::memset(tj,0,size);
++ int tj[MAXSATELLITES];
++ system::memset(tj,0,sizeof(tj));
+ if(nFields>15) nFields=15;
+ for(int j=3; j<nFields; ++j)
+ {
+@@ -70,9 +87,9 @@
+ }
+ }
+
+- if(system::memcmp(trajColor,tj,size))
++ if(system::memcmp(trajColor,tj,sizeof(tj)))
+ {
+- system::memcpy(trajColor,tj,size);
++ system::memcpy(trajColor,tj,sizeof(tj));
+ trash();
+ }
+ }
+@@ -106,30 +123,18 @@
+ return sphereIntersect(result,0,aSquared,r,d);
+ }
+
+-void newSatelliteFix(
+-const uint8_t *prn,
+-const uint8_t *elevation,
+-const uint8_t *azimuth,
+-const uint8_t *
+-)
++void newSatelliteFixValue(int prn, double elevation, double azimuth)
+ {
+- int num;
+- double e;
+- double a;
+- if(lastStamp()<0) return;
+- if(1!=system::sscanf((const char*)prn,"%d",&num)) return;
+- if(1!=system::sscanf((const char*)elevation,"%lf",&e)) return;
+- if(1!=system::sscanf((const char*)azimuth,"%lf",&a)) return;
+
+- if(e>90.0) return;
+- if(a>360.0) return;
+- if(num>=50) return;
++ if(elevation>90.0) return;
++ if(azimuth>360.0) return;
++ if(prn>=MAXSATELLITES) return;
+
+- int pnum= trajSizes[num];
++ int pnum= trajSizes[prn];
+ if(
+ pnum==0 ||
+- lastSatAzimuth[num]!=a ||
+- lastSatElevation[num]!=e
++ lastSatAzimuth[prn]!=azimuth ||
++ lastSatElevation[prn]!=elevation
+ )
+ {
+ double sat[3];
+@@ -138,23 +143,40 @@
+ int correct= ae2xyz(
+ la,
+ lo,
+- a,
+- e,
++ azimuth,
++ elevation,
+ altitudeSquared,
+ sat
+ );
+ if(correct)
+ {
+ int mod= pnum%TRAJSIZE;
+- satX[num][mod]= sat[0];
+- satY[num][mod]= sat[1];
+- satZ[num][mod]= sat[2];
+- satT[num][mod]= lastStamp();
+- trajSizes[num]= ++pnum;
++ satX[prn][mod]= sat[0];
++ satY[prn][mod]= sat[1];
++ satZ[prn][mod]= sat[2];
++ satT[prn][mod]= lastStamp();
++ trajSizes[prn]= ++pnum;
+ trash();
+ }
+ }
+ }
++void newSatelliteFix(
++const uint8_t *prn,
++const uint8_t *elevation,
++const uint8_t *azimuth,
++const uint8_t *
++)
++{
++ int num;
++ double e;
++ double a;
++ if(lastStamp()<0) return;
++ if(1!=system::sscanf((const char*)prn,"%d",&num)) return;
++ if(1!=system::sscanf((const char*)elevation,"%lf",&e)) return;
++ if(1!=system::sscanf((const char*)azimuth,"%lf",&a)) return;
++
++ newSatelliteFixValue(num, e, a);
++}
+
+ static inline void satPos(
+ int i,
+@@ -169,7 +191,7 @@
+
+ void paintSatellites()
+ {
+- for(int i=0;i<50;++i)
++ for(int i=0;i<MAXSATELLITES;++i)
+ {
+ int start= 0;
+ int nPoints= trajSizes[i];