extern int read_display(gdImagePtr *im);
extern int write_display(gdImagePtr *im);


// Tooks a gd-color value which is created with gdTrueColor
// and uses an alpha value on it. 
// After split up the the color into rgb-values, they are 
// combined with gdTrueColorAlpha and given back.
int addalpha(int colorvalue,int alpha)
{
 int r,g,b;

 r=gdTrueColorGetRed(colorvalue);
 g=gdTrueColorGetGreen(colorvalue);
 b=gdTrueColorGetBlue(colorvalue);
 return gdTrueColorAlpha(r,g,b,alpha);
}



// clear touchscreenbuffer and wait for touch 
int wait_for_ts()
{
  int x,y;
  static int pen = 0;

  while (TsScreen_pen(&x,&y,&pen));
  while (! TsScreen_pen(&x,&y,&pen));
  return 0;
}

// Look for the given option in the configfile and return
// corresponding value of that variable.
char *loadconfigline(char *search)
{
   FILE *source;
   char line[LINELENGTH];
   char tmpline[LINELENGTH];
   int tmplength;
   int pos;
   int i;
   static char outcome[LINELENGTH];
   char *outcomeptr;

   if((source=fopen(configfile,"r")) == NULL)
      {
         fprintf(stderr,"could not open %s\n",configfile);
         exit (1);
      }

   while(fgets(line,LINELENGTH,source))
   {
     // ignore # remarks
     if (line[0] != '#') {

        // remove spaces
        tmplength=0;
        for (i=0; line[i] != '\0'; i++ ) {
          if ( line[i] != ' ' ) {
            tmpline[tmplength]=line[i];
            tmplength++;
          }
        }
        tmpline[tmplength]='\0';
        strcpy(line,tmpline);

        // remove newline character
        pos=0;
        for (i=0; line[i] != '\0'; i++ )
          pos++;
        line[pos-1]='\0';

        // change all in lowercase
        for ( i=0; line[i] != '\0'; i++ ) {
          if ( line[i] >= 'A' && line[i] <= 'Z' )
             line[i] += 32;
        }

        // search and (if so) give the finding back
        if ( strstr(line,search)  ) {
          outcomeptr=strstr(line,"=");
          // skip equal sign (=)
          outcomeptr++;
          strcpy(outcome, outcomeptr);
	  fclose(source);
          return( outcome );
        }
     }
   }
// if nothing is found a empty string is given back
strcpy(outcome, "");
fprintf(stderr,"loadconfigline: didnt find option > %s <\n",search);
fclose(source);
return outcome;
}



int loadpng(gdImagePtr *im, int knr) {
 FILE *in;
 char filename[255];
 char line1[255]="";
 char line2[255]="";
 char line3[255]="";
 int xstart=toplefttile_x;
 int ystart=toplefttile_y;
 int x,y;
 int xzl,yzl;
 int c,c2;
 gdImagePtr tmp;
 int textcol,gridcol;

 if (tile[knr] != 0)
   return 0;

 if ( knr > (xtiles*ytiles) ) {
   if (debug)
     printf("loadpng error: knr > xtiles*ytiles\n");
   return 0; // ignore errors silently
 }
 // 0,0,0,128 means black (with little translucence)
 textcol = gdTrueColorAlpha(0,0,0,140);
 // 128,0,0,128 means reddish (with a little more translucence)
 gridcol= gdTrueColorAlpha(128,0,0,64);
 // tile of the top left corner: 17-68714-44416.png
 // => http://openstreetmap.org/?lat=50.11714&lon=8.62005&zoom=17&layers=B0FT
 // x1=68674
 // x2=68690
 // y1=44386
 // y2=44400
 // xtiles=(x2-x1)+1 => 17
 // ytiles=(y2-y1)+1 => 15
 x=xstart+((knr-1) % xtiles);
 y=ystart+((knr-1) / xtiles);
 sprintf( filename, "./%d/%d/%d.png", zoomlevel,x,y );
 sprintf( line1, "./%d/%d/%d.png", zoomlevel,x,y );
 sprintf( line2, "KNR: %d (%d / %d)", 
          knr, (((knr-1) % xtiles)+1),
	       (((knr-1) / xtiles)+1)  );

   if (debug)
     printf("load %s\n",filename);
 if ( (in=fopen( filename, "rb")) == NULL )
 {
   if (debug)
     printf("could not open %s\n",filename);
   tmp = gdImageCreate(xtilesize,ytilesize);
   gdImageFill(tmp,1,1, gdImageColorAllocate(tmp,90,90,90));
   sprintf( line3, "not found: %s",filename );
 }
 else 
 {
    tmp = gdImageCreateFromPng(in);
    if (!tmp)
    {
      if (debug)
        printf("Broken png-file: %s\n ",filename);
      tmp = gdImageCreate(xtilesize,ytilesize);
      gdImageFill(tmp,1,1, gdImageColorAllocate(tmp,90,90,90));
      sprintf( line3, "broken png-file: %s",filename );
      fclose (in);
    }
 }

 *im = gdImageCreateTrueColor(xtilesize,ytilesize);
 
 // loadpng copes with 256 color and truecolor PNGs
 if ( gdImageTrueColor(tmp) ) {
   if (debug)
     printf("%s is not a 256c palette image. Converting it\n",filename);
   gdImageCopy(*im,tmp,0,0,0,0,gdImageSX(tmp),gdImageSY(tmp));
 }
 else 
 {
    // copy all pixel in the newly created truecolor-image
    for (yzl=0 ; yzl<=(gdImageSY(tmp)-1); yzl++ ) {
       for (xzl=0 ; xzl<=(gdImageSX(tmp)-1); xzl++ ) {
         c  = gdImageGetPixel(tmp, xzl,yzl);
         c2 = gdTrueColor(tmp->red[c], tmp->green[c], tmp->blue[c] );
         gdImageSetPixel(*im,xzl,yzl,c2);
       }
    }
 }

 if (debug) {
   gdImageRectangle(*im,0,0,255,255,gridcol);
   gdImageString(*im, gdFontGetSmall(), 10, 10, line1, textcol);
   gdImageString(*im, gdFontGetSmall(), 10, 25, line2, textcol);
   gdImageString(*im, gdFontGetSmall(), 10, 40, line3, textcol);
 }
 gdImageDestroy(tmp);
 return 0;
}

// getcolor gets the color at a given point. It 
// take virtual coordinates which will automatically
// converted in the coordinated whithin the right tile.
int getcolor(int xreal,int yreal)
{
 int knr;         // tile number
 int c;           // color (has to split up width gdTrueColorGetRed(c))
 int xkpos,ykpos; // coordinates within a tile (0..255)

 xkpos=xreal % xtilesize;
 ykpos=yreal % ytilesize;
 
 knr=(yreal/ytilesize)*xtiles+(xreal/xtilesize)+1;

 c = gdImageGetPixel(tile[knr], xkpos,ykpos);
// comment out if there are arbitrary crashs when scrolling
// if (tile[knr] != NULL) 
// {
//   c = gdImageGetPixel(tile[knr], xkpos,ykpos);
// }
// else 
// {
//   c=gdTrueColor(255,255,0);
//   fprintf(stderr,"Tile not in memory error at (x/y): %d / %d\n",xreal,yreal);
// }

 return c;
}


// The function gets an x/y pair and a percent-value (meanpct).
// x/y are display-coordinates and result from a touch
// on the touchscreen.
// detect_direction divides the screen into 9 fields.
// Therefore two lines for x (x1mean and x2mean) and two
// lines for y (y1mean and y2mean) are needed. How much
// they are equally arranged around the real mean which
// is (ScreenWidth/2 and ScreenHeight/2) is specified
// which the percent-value.
int detect_direction(int x,int y,int meanpct)
{
  int x1mean,y1mean,x2mean,y2mean;
  int direction=0;

  x1mean=ScreenWidth/2-(ScreenWidth*meanpct)/100;
  y1mean=ScreenHeight/2-(ScreenHeight*meanpct)/100;
  x2mean=ScreenWidth/2+(ScreenWidth*meanpct)/100;
  y2mean=ScreenHeight/2+(ScreenHeight*meanpct)/100;

   if ( x > x2mean  ) {
       // right part of the screen
       if ( y < y1mean  ) 
         direction=topright;
       else if ( y > y2mean ) 
         direction=downright;
       else 
         direction=right; 
   }
   else if (x < x1mean) {
       // left part of the screen
       if ( y < y1mean  ) 
         direction=topleft;
       else if ( y > y2mean ) 
         direction=downleft;
       else 
         direction=left; 
   }
   if ( (x > x1mean) && (x < x2mean) ) {
       // (upright) middle part of the screen
       if ( y < y1mean  ) 
         direction=top;
       else if ( y > y2mean ) 
         direction=down;
       else 
         direction=center; 
   }
  return direction;
}

// int smallzoom()
// {
// // Draws a small filled rectangle in the downright corner.
// // A cross represents the current position within the whole map.
// //
// // First task: finding the right proportions for the x and y-size
// // of the smallzoom-Window => szwidth and szheight
// //
// // Precondition: 
// // Neither szwidth nor szheight may exceed maxx and maxy.
// // We assume 80 pixel for both variables in the following example.
// // 
// // first case: xtiles > ytiles
// //  szwidth=maxx;
// //  szheight=maxx*ytiles/xtiles;
// // second case: xtiles <= ytiles
// //  szheight=maxy;
// //  szwidth=maxy*xtiles/ytiles;
// //  
// // Second task: finding the right x and y value within the smallzoom
// // for marking with a cross. => szxpos and szypos
// // a) which tile (tilenumber) is displayed in the center of screen?
// // b) which coordinates result this? => kachelx1 and kachely1
// // c) these coordinates must put into the right proportions concerning
// //    szwidth and szheight:
// //    szxpos=kachelx1*szwidth/ytiles;
// //    szypos=kachely1*szheight/ytiles;
// 
//   int xmitte,ymitte;
//   int knrmitte;
//   int kachelx1;  // X-koord. (1..xtiles) von knrmitte
//   int kachely1;  // Y-koord. (1..ytiles) von knrmitte
//   int szbackground;
//   int szborder;
//   int maxx=80;
//   int maxy=80;
//   int szx1,szx2,szy1,szy2;
//   int szwidth,szheight;    // width and height of the sz-rectangle
//   int crossx,crossy;       // coords of the cross
// 
//   
//   szbackground=addalpha(lemonchiffon1col,30);
//   szborder=darkgreycol;
//   if ( xtiles > ytiles ) {
//     szwidth=maxx;
//     szheight=maxx*ytiles/xtiles;
//   }
//   else {
//     szheight=maxy;
//     szwidth=maxy*xtiles/ytiles;
//   }
//   read_display(&gddisplay);
//   szx2=gdImageSX(gddisplay);
//   szy2=gdImageSY(gddisplay);
//   szx1=szx2-szwidth+1;
//   szy1=szy2-szheight+1;
// 
//   gdImageFilledRectangle(gddisplay, szx1, szy1, szx2,szy2, szbackground);
//   gdImageRectangle(gddisplay, szx1, szy1, szx2,szy2, szborder);
// 
// // ----------------- draw cross START ------------------
//   xmitte=xvp+(ScreenWidth/2);
//   ymitte=yvp+(ScreenHeight/2);
//   knrmitte=(ymitte/ytilesize)*xtiles+(xmitte/xtilesize)+1;
//   kachelx1=((knrmitte-1) % xtiles);  
//   kachely1=(knrmitte-1) / xtiles;
//   crossx=kachelx1*szwidth/xtiles;   // within the smallzoom image
//   crossx+=szx1;                       // absolute position
//   crossy=kachely1*szheight/ytiles;  // within the smallzoom image
//   crossy+=szy1;                       // absolute position
// 
//   gdImageLine(gddisplay, crossx-2,crossy-2,crossx+2,crossy+2,blackcol); 
//   gdImageLine(gddisplay, crossx+2,crossy-2,crossx-2,crossy+2,blackcol); 
//   gdImageSetPixel(gddisplay,crossx,crossy,whitecol); 
//   
// // ----------------- draw cross END ------------------
// 
//   write_display(&gddisplay);
//   wait_for_ts();
// 
//  return 0;
// }


// description: see smallzoom
// fastsmallzoom draws directly to the screen.
// the former smallzoom in contrast use gdlib
void fastsmallzoom()
{
int xmitte,ymitte;
int knrmitte;
int kachelx1;  // X-koord. (1..xtiles) von knrmitte
int kachely1;  // Y-koord. (1..ytiles) von knrmitte
int szbackground;
int szborder;
int maxx=80;
int maxy=80;
int szx1,szx2,szy1,szy2;
int szwidth,szheight;    // width and height of the sz-rectangle
int crossx,crossy;       // coords of the cross

  szbackground=(lemonchiffon1col);
  szborder=darkgreycol;
  if ( xtiles > ytiles ) {
    szwidth=maxx;
    szheight=maxx*ytiles/xtiles;
  }
  else {
    szheight=maxy;
    szwidth=maxy*xtiles/ytiles;
  }
//  read_display(&gddisplay);
//  szx2=gdImageSX(gddisplay);
//  szy2=gdImageSY(gddisplay);
  szx2=ScreenWidth;
  szy2=ScreenHeight;
  szx1=szx2-szwidth+1;
  szy1=szy2-szheight+1;

  FB_FilledRect(szx1,szy1,ScreenWidth,ScreenHeight,szbackground);
  FB_Rect(szx1,szy1,ScreenWidth,ScreenHeight,szborder);
// ----------------- draw cross START ------------------
  xmitte=xvp+(ScreenWidth/2);
  ymitte=yvp+(ScreenHeight/2);
  knrmitte=(ymitte/ytilesize)*xtiles+(xmitte/xtilesize)+1;
  kachelx1=((knrmitte-1) % xtiles);  
  kachely1=(knrmitte-1) / xtiles;
  crossx=kachelx1*szwidth/xtiles;   // within the smallzoom image
  crossx+=szx1;                       // absolute position
  crossy=kachely1*szheight/ytiles;  // within the smallzoom image
  crossy+=szy1;                       // absolute position

  FB_PutPixel(crossx,crossy,browncol);
  FB_PutPixel(crossx-1,crossy-1,gray40col);
  FB_PutPixel(crossx+1,crossy-1,gray40col);
  FB_PutPixel(crossx+1,crossy+1,gray40col);
  FB_PutPixel(crossx-1,crossy+1,gray40col);
  FB_PutPixel(crossx-2,crossy-2,blackcol);
  FB_PutPixel(crossx+2,crossy-2,blackcol);
  FB_PutPixel(crossx+2,crossy+2,blackcol);
  FB_PutPixel(crossx-2,crossy+2,blackcol);
// ----------------- draw cross END ------------------
}

// function for calculating latitude/longitude from x/y
// xytogeo uses the calibration data from configfile.
int xytogeo(int xpixel,int ypixel,double *latitude,double *longitude)
{
  double longdifference;
  double latdifference;
  double xfactor;
  double yfactor;
  double lat0;
  double long0;
  int    xdifference;
  int    ydifference;

  longdifference = cali_long2-cali_long1;
  latdifference  = cali_lat2-cali_lat1;
  xdifference    = cali_x2-cali_x1;
  ydifference    = cali_y2-cali_y1;

  xfactor = (longdifference / xdifference);
  yfactor = (latdifference / ydifference);

  //  cali_x1 und cali_y2 give the referencepoint ( = calibration point)
  //  Number 1. Its not necessary that x=1 and y=1. Its possible and this
  //  is also much more easier to use an calibration point inside the image.
  //  Therefore the left (long0) and upper (lat0) boundaries has to be 
  //  calculated:
  lat0  = cali_lat1  - (yfactor*cali_y1);
  long0 = cali_long1 - (xfactor*cali_x1);

  *latitude  = lat0  + yfactor*ypixel;
  *longitude = long0 + xfactor*xpixel;

  return 0;
}


// read settings from configfile (uses loadconfigline)
int read_config()
{
// its possible to invoke read_config several times (via
// the "reread config" button. But most of the variables
// should not be changed in the meantime.
  // initialize variables
  xtiles=0;
  ytiles=0;
  xvp=0;
  yvp=0;
  xtilesize=0;
  ytilesize=0;
  xvpstart=0;
  yvpstart=0;
  scrollstep=20;
  xvpsize=ScreenWidth;
  yvpsize=ScreenHeight;
  cachemaxtiles=9;
  toplefttile_x=0;
  toplefttile_y=0;
  zoomlevel=17;
  debug=0;
  showsz=1;
  screenrecord=0;
  killttn=0;
  cali_lat1  = 0;
  cali_lat2  = 0;
  cali_long1 = 0;
  cali_long2 = 0;
  cali_x1    = 0;
  cali_x2    = 0;
  cali_y1    = 0;
  cali_y2    = 0;

  xtiles        = atoi(loadconfigline("xtiles"));         
  ytiles        = atoi(loadconfigline("ytiles"));        
  xtilesize     = atoi(loadconfigline("xtilesize"));    
  ytilesize     = atoi(loadconfigline("ytilesize"));    
  scrollstep    = atoi(loadconfigline("scrollstep"));   

  ScreenWidth   = atoi(loadconfigline("screenwidth"));        
  ScreenHeight  = atoi(loadconfigline("screenheight"));        

  xvpsize       = atoi(loadconfigline("xvpsize"));        
  yvpsize       = atoi(loadconfigline("yvpsize"));        
  // if xvpsize is not set in config.txt uses ScreenWidth
  if (xvpsize==0)
    xvpsize = ScreenWidth;
  // if yvpsize is not set in config.txt uses ScreenHeight
  if (yvpsize==0)
    yvpsize = ScreenHeight;

  cachemaxtiles = atoi(loadconfigline("cachemaxtiles"));  
  debug         = atoi(loadconfigline("debug"));          
  toplefttile_x = atoi(loadconfigline("toplefttile_x"));  
  toplefttile_y = atoi(loadconfigline("toplefttile_y"));  
  zoomlevel     = atoi(loadconfigline("zoomlevel"));      
  xvpstart      = atoi(loadconfigline("xvpstart"));       
  yvpstart      = atoi(loadconfigline("yvpstart"));       
  showsz        = atoi(loadconfigline("showsz"));         
  screenrecord  = atoi(loadconfigline("screenrecord"));   
  killttn       = atoi(loadconfigline("killttn"));        

  cali_lat1     = atof(loadconfigline("cali_lat1"));      
  cali_lat2     = atof(loadconfigline("cali_lat2"));      
  cali_long1    = atof(loadconfigline("cali_long1"));     
  cali_long2    = atof(loadconfigline("cali_long2"));      
  cali_x1       = atoi(loadconfigline("cali_x1"));         
  cali_x2       = atoi(loadconfigline("cali_x2"));         
  cali_y1       = atoi(loadconfigline("cali_y1"));         
  cali_y2       = atoi(loadconfigline("cali_y2"));         
  strcpy(mapname,loadconfigline("mapname"));
  strcpy(gpsfifo_name,loadconfigline("gpsfifo"));

  xvp=xvpstart;       // Viewpoint: real coordinates of the upper left corner
  yvp=yvpstart;       // of the visible screen

  return 0;
}

int get_mem_from_proc()
{
 #define LINELENGTH 255
 FILE *fp;
 char line[LINELENGTH];
 int wert;
 int dummy;

  if((fp=fopen("/proc/self/statm","r")) == NULL)
  {
    printf("error reading from file\n");
    return 0;
  }
  if ( fgets(line,LINELENGTH,fp) )
    sscanf( line, "%d %d %d %d %d %d %d", &dummy,&wert,&dummy,&dummy,&dummy,&dummy,&dummy);
  else
    wert=0;
  fclose(fp);

  return wert;
}



int write_geopos_to_file(double latitude,double longitude)
{
 #define LINELENGTH 255
 FILE *fp;

  if((fp=fopen(geoposfilename,"w")) == NULL)
  {
    fprintf(stderr,"error opening %s for writing\n",geoposfilename);
    return 1;
  }
  if (! fprintf(fp,"%lf %lf",latitude,longitude) )
  {
    fprintf(stderr,"error writing to file %s\n",geoposfilename);
    return 1;
  }
  fclose(fp);

  return 0;
}

void display_config_info()
{
  int leftmargin1=10;
  int leftmargin2=170;
  int linespacing=10;
  int y=10;
  char s[LINELENGTH];
  FILE *fp;
  char line[LINELENGTH];
  double latitude;
  double longitude;

  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "Mapname: ");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, mapname);
  y=y+linespacing; 

  sprintf( s, "%d",debug );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "Debug:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%d",killttn );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "killttn:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%d",xtiles );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "xtiles:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%d",ytiles );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "ytiles:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%d",zoomlevel );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "zoomlevel:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%d",toplefttile_x );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "toplefttile_x:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%d",toplefttile_y );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "toplefttile_y:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%d",showsz );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "showsz:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%d",screenrecord );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "screenrecord:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%d",scrollstep );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "scrollstep:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 
  y=y+linespacing; 

  sprintf( s, "%f",cali_lat1 );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "cali_lat1:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%f",cali_long1 );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "cali_long1:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%f",cali_lat2 );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "cali_lat2:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%f",cali_long2 );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "cali_long2:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%d",cali_x1 );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "cali_x1:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%d",cali_y1 );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "cali_y1:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%d",cali_x2 );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "cali_x2:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 

  sprintf( s, "%d",cali_y2 );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "cali_y2:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 
  y=y+linespacing; 

  // get content from geoposfilename
  if((fp=fopen(geoposfilename,"r")) == NULL)
    fprintf(stderr,"Error reading from geoposfile %s\n",geoposfilename);
  else
  {
    if ( fgets(line,LINELENGTH,fp) )
    {
      sscanf( line, "%lf %lf", &latitude,&longitude);
      if (debug)
        fprintf(stderr,"Lat/Long from geoposfile: %f/%f\n",latitude,longitude);
    }
    fclose(fp);
  }

  sprintf( s, "%f",latitude );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "last latitude:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 
 
  sprintf( s, "%f",longitude );
  FbRender_BlitText(leftmargin1,y, WHITE, BLACK, "last longitude:");
  FbRender_BlitText(leftmargin2,y, WHITE, BLACK, s);
  y=y+linespacing; 
 
  FbRender_Flush();
  wait_for_ts();
}

