#include <stdio.h>

#include <exec/types.h> 
#include <exec/ports.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <graphics/view.h>
#include <graphics/rastport.h>
#include <graphics/layers.h>
#include <graphics/display.h>
#include <graphics/gfxmacros.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <workbench/icon.h>

#include <auxcfg.h>
#include <spec.h>
#include <mdllib.h>

#define BMHDChunk 1
#define CMAPChunk 2
#define BODYChunk 3
#define CAMGChunk 4
#define Unknown   5


#define TEKPIPENAME0 "ram:liserp0"
#define TEKPIPENAME1 "ram:liserp1"
#define TEKPIPENAME2 "ram:liserp2"
#define TEKPIPENAME3 "ram:liserp3"

#define TMPGCURSOR   "t:gcursor"
#define ASHBDRY      "t:ashbdry"

#define _TEKXMAX 4096
#define _TEKYMAX 3120

extern struct WBStartup *WBenchMsg;
extern struct IconBase *IconBase;

BOOL close_me;

int   cx,cy,cb1,cb2,
      esc,fdstdin,fdstdout,
      ink=2,
       opt=1,
       prt_passes=2,
       prt_lsbmsb=1,
       x_prt_siz=1024,
       y_prt_siz=1024,
       aposx=0,
       aposy=0,
       fdprinter=0,
       pribufptr=0,
       pribufsiz=8190,
      paper=0,
      ptr=0,
      bufsiz=200000,
      nohco=FALSE,
      msizex, msizey,
      sizex, sizey,
      sizex_1, sizey_1,
      sizex_2, sizey_2,
      thickx=1,
      thicky=1,
      txtangle=0,
      sinphi=0,
      cosphi=262144,
      gramode=0,
      flg_half=FALSE,
      hcothick=FALSE,
      bufferonfile=FALSE;

int            fdbuffer, fdptr;
unsigned char  lastchar;

unsigned char   *tekname,
                prt_init[20]="\x1B@",
                prt_gra[20]="\x1BZ",
                prt_halflf[20]="\x1B\x33\x02\n",
                prt_lf[20]="\x1B\x33\x14\n",
                prt_fin[20]="\x1B@\x0C",
                *primaryfont,
                *secondaryfont,
                *defaultprinter,
                *systemcommand,
                *bufferfile,
              *buf,
              *printerbuf,
              *tekbuf,
              *font_1,
              *fontdesc_1,
              *font_2,
              *fontdesc_2,
              *fontfile, *fontdesc;

int            *prop_1,
               fontwidth_1, fontheight_1,
               firstchar_1, offschar_1,
               *prop_2,
               fontwidth_2, fontheight_2,
               firstchar_2, offschar_2,
               *proptab,
               fontwidth, fontheight,
               firstchar, offschar;

int            prop_flag = 1;
int            baseline = 0;

struct CMAPC          /* Definition des CMAP-Chunks               */
{
 int anz;             /* Anzahl der Farben                        */
 struct ColorRegister /* Definition einer Farbe                   */
 {
  UBYTE red;
  UBYTE green;
  UBYTE blue;
 } Color[64];         /* lieber zuviel als zuwenig                */
};

struct FORMC          /* Definition des Anfang-Chunks             */
{
 char  FORMName[4];   /* handelt es sich um ein IFF-Format?       */
 long  len;           /* Gesamte Laenge des Files                 */
 char  ILBM[4];       /* handelt es sich um ILBM-Format?          */
};

struct BMHDC          /* Definition des BMHD                      */
{
 char  BMHDName[4];
 long  lenBMHD;       /* Laenge des BMHD-Chunks                   */
 short Width;         /* Breite des Bildes                        */
 short Height;        /* Hoehe des Bildes                         */
 short xpos;          /* x-Position des Bildes                    */
 short ypos;          /* y-Position des Bildes                    */
 char  Depth;         /* Anzahl der BitPlanes                     */
 char  mask;          /* Mask-Bit                                 */
 char  compression;   /* Bild 'compressed'?                       */
 char  null;
 short color;
 char  xaspect;
 char  yaspect;
 short PWidth;
 short PHeight;
};

struct CHUNKID        /* hier werden die zu analysierenden Bytes  */
{                     /* abgelegt                                 */
 char  Name[4];       /* Name des Chunks                          */
 int   len;           /* Laenge des Chunks                        */
};

struct HEADER         /* diese Struktur enthaelt die Zeichenfolge */
{                     /* um den Chunk zu erkennen.                */
 char bmhd[4];
 char cmap[4];
 char body[4];
 char camg[4];
};

struct CAMGC          /* Definition des CAMG                      */
{
 char CAMGName[4];
 long lenCAMG;
 long ViewModes;
};

struct CMAPC CMAPl;
struct FORMC FORMl;
struct BMHDC BMHDl;
struct CHUNKID CHUNKid;
struct FORMC FORMs = {'F','O','R','M',0,'I','L','B','M'};
struct BMHDC BMHDs = {'B','M','H','D',20,0,0,0,0,0,2,0,0,0,10,11,0,0};
struct CAMGC CAMGs = {'C','A','M','G',4,0};
struct HEADER Header=
{
 'B','M','H','D',    /* BMHD-Chunk                                */
 'C','M','A','P',    /* CMAP-Chunk                                */
 'B','O','D','Y',    /* BODY-Chunk                                */
 'C','A','M','G',    /* CAMG-Chunk                                */
};

char cmap[]="CMAP";
char body[]="BODY";
char form[]="FORM";
char ilbm[]="ILBM";


/* ---------------------------------------------
         User Callback functions
   --------------------------------------------- */
float frline(stream)
FILE *stream;
{
char s[80];

   fgets(s,80,stream);
   return(atosf(s));
}

void Cursor()
{
int x,y,xx,
      leftmargin,
      bottommargin,
      rightmargin,
      topmargin,
      _win_flg;
float tmin,
      tmax,
      ymin,
      ymax,
      real_t,
      real_y,
      yfak,
      tfak,
      xoffset,
      yoffset;
char  s[80];
FILE *fp;

getxy(&x,&y);

fp=fopen(ASHBDRY,"r");
leftmargin = frline(fp);
bottommargin = frline(fp);
rightmargin = frline(fp);
topmargin = frline(fp);
_win_flg = frline(fp);
tmin = frline(fp);
tmax = frline(fp);
ymin = frline(fp);
ymax = frline(fp);
_tica = frline(fp);
fclose(fp);

yfak=(topmargin-bottommargin)/(ymax-ymin);
tfak=(rightmargin-leftmargin)/(tmax-tmin);
xoffset= ((- tmin) * tfak) + leftmargin;
yoffset= ((- ymin) * yfak) + bottommargin;

real_t= (x - xoffset)/tfak;
real_y= (y - yoffset)/yfak;
xx= real_t / _tica;

sprintf(s,"tek x = %d  tek y = %d\ndata:      x=%f    y=%f\nx-channel = %d\n"
           ,x,y,real_t,real_y,xx);
Help(s);
}

void InkPlus()
{
char s[80];

ink = ((ink + 1) & 7);
SetAPen(rp,ink);
sprintf(s,"ink  %d\npaper %d\n",ink,paper);
Help(s);
}

void InkMinus()
{
char s[80];

ink = ((ink - 1) & 7);
SetAPen(rp,ink);
sprintf(s,"ink  %d\npaper %d\n",ink,paper);
Help(s);
}

void PaperPlus()
{
char s[80];

paper = ((paper + 1) & 7);
sprintf(s,"ink  %d\npaper %d\n",ink,paper);
Help(s);
}

void PaperMinus()
{
char s[80];

paper = ((paper - 1) & 7);
sprintf(s,"ink  %d\npaper %d\n",ink,paper);
Help(s);
}

help()
{
printf("this program opens a graphic window and makes the rastport public\n");
printf("    -p n         specifies a number for the pipe.\n");
printf("    -buf n       change size of vector buffer(used for hardcopy)\n");
printf("            The Vectorbuffer may also be specified in Aux_Config\n");
printf("            If you are very low on memory, you may specify a filename\n");
printf("    -nohco       display only, no buffer for hardcopy\n");
printf("    -paper n     specifies background colour\n");
printf("    -ink n       specifies drawing colour\n");
printf("    -left n      left edge\n");
printf("    -top n       top edge\n");
printf("    -xsize n     horizontal size\n");
printf("    -ysize n     vertical size\n");
   return(0);
}

posita(x,y)
int x,y;
{
int xx,yy;

   cx = x;
   cy = y;

   if(!nohco) {
     gfxbufin(0x1d);
     cvtxy(x,y);
   }

   xx=my_window->Width; xx=xx-1;
   yy=my_window->Height; yy=yy-32;
   xx=(xx*x)/_TEKXMAX;
   yy=16+((yy*(_TEKYMAX-y))/_TEKYMAX);
   Move(rp,xx,yy);
   return(0);
}

vectoa(x,y)
int x,y;
{
int xx,yy;

   cx = x;
   cy = y;

   if(!nohco) cvtxy(x,y);

   xx=my_window->Width; xx=xx-1;
   yy=my_window->Height; yy=yy-32;
   xx=(xx*x)/_TEKXMAX;
   yy=16+((yy*(_TEKYMAX-y))/_TEKYMAX);
   Draw(rp,xx,yy);
   return(0);
}

cls()
{
int xx,yy;

   xx=my_window->Width;
   yy=my_window->Height;
   SetAPen(rp,paper);
   RectFill(rp,2,10,xx-3,yy-2);
   SetAPen(rp,ink);
   return(0);
}

dperas()
{
   cls();
   ptr=0;

   sizex = sizex_1;
   sizey = sizey_1;
   fontfile = font_1;
   proptab = prop_1;
   fontdesc = fontdesc_1;
   fontheight = fontheight_1;
   fontwidth = fontwidth_1;
   firstchar = firstchar_1;
   offschar = offschar_1;
   prop_flag = 1;

   if(bufferonfile) {
      close(fdbuffer);
      fdbuffer = creat(bufferfile,0666);
      close(fdbuffer);
      fdbuffer = open(bufferfile,2,0666);
   }
   return(0);  
}

getxy(x,y)
int *x,*y;
{
int xx,yy,n;
int newx, newy, oldx, oldy;

   xx=my_window->Width;
   yy=my_window->Height;
   oldx = xx / 2;
   oldy = yy / 2;

   WindowToFront(my_window);
   ActivateWindow(my_window);

   SetDrMd(rp, COMPLEMENT);
   SetAPen(rp, 7);
   Delay(5);

   Move(rp,oldx,0); Draw(rp,oldx,yy);
   Move(rp,0,oldy); Draw(rp,xx,oldy);

   *x = -1; *y = -1;
   while((*x < 0) || (*x > xx) || (*y < 0) || (*y > yy)) {
/* wait for mouse button */
      while((*((UBYTE*)0xbfe001))&64) {
         Delay(5L);
         Move(rp,oldx,0); Draw(rp,oldx,yy);
         Move(rp,0,oldy); Draw(rp,xx,oldy);
         newx=my_window->MouseX;
         if(newx < 0) newx = 0;
         if(newx > xx) newx = xx;
         newy=my_window->MouseY;
         if(newy < 0) newy = 0;
         if(newy > yy) newy = yy;
         Move(rp,newx,0); Draw(rp,newx,yy);
         Move(rp,0,newy); Draw(rp,xx,newy);
         oldx = newx; oldy = newy;
      }
      n=0;
      *x=my_window->MouseX;
      *y=my_window->MouseY;
   }

   Move(rp,oldx,0); Draw(rp,oldx,yy);
   Move(rp,0,oldy); Draw(rp,xx,oldy);

   *x = (( *x * _TEKXMAX) / xx);
   *y = _TEKYMAX - (( *y * _TEKYMAX) / yy);

   SetDrMd(rp,JAM1);
   SetAPen(rp, ink);
   return(0);
}

gfxtext(s)
char s[];
{
int n;
char c,z[256];

   c=s[0];
   if(c==0x1b) {   /* chage text size */
      c=s[1];
      switch(c) {
      case ';':                    /* smallest text size */
         sizex = msizex / 2;
         sizey = msizey / 2;
         break;
      case ':':                    /* small text size */
         sizex = (msizex * 2) / 3;
         sizey = (msizey * 2) / 3;
         break;
      case '9':
         sizex = msizex;            /* normal text size */
         sizey = msizey;
         break;
      case '8':
         sizex = 2*msizex;          /* big text size */
         sizey = 2*msizey;
         break;
      }
      n=0;
      while(c>0) {
         c=s[n+2];
         z[n++]=c;
      }
      plotstr(z);
   } else {
      plotstr(s);
   }
   return(0);
}

textlen(s,l)
char *s;
int *l;
{
int c,i,n;

   i = 0; n = 0;
   while(s[i] != 0) {
      c = s[i++];
      if(c == 92) {     /* meta character BACKSLASH ! */
         i++;           /* ignore next character */
         continue;
      }
      if(prop_flag == 1) {
         n = n + sizex * proptab[c];
      } else {
         n = n + sizex * fontwidth;
      }
   }
   n = n >> 1; /* ????????????????????! */
   *l = n;
   return(0);
}

textheight(h)
int *h;
{
   *h = sizey * fontheight;
   return(0);
}

setcolour(n)
int n;
{
ink = n & 15;
paper = n / 16;
SetAPen(rp,ink);
   return(0);
}

rmtek()
{
   close_me = TRUE;
   return(0);
}

textparam(sx,sy,tx,ty,w,name)
int sx,sy,tx,ty,w;
char name[];
{
   if(sx>0) {sizex=sx; msizex=sx; sizex_1=sx;}
   if(sy>0) {sizey=sy; msizey=sy; sizey_1=sx;}
   if(tx>0) thickx=tx;
   if(ty>0) thicky=ty;
   if(name[0]!=0) {
      readfont(name);
      fontdesc_1 = fontdesc;
      fontheight_1 = fontheight;
      fontwidth_1 = fontwidth;
      firstchar_1 = firstchar;
      offschar_1 = offschar;
   }
   txtangle=w;
   rotmat(w);
   return(0);
}

remove_tek()
{
int n;
   n=1;
   while(n>0) {
      unlink(tekname);
      n=open(tekname,0);
      if(n>0) close(tekname);
   }
   return(0);
}


cvtxy(xx,yy)
int xx,yy;
{
int i,xh,xl,yh,yl;
int x4, y4;

   x4 = xx >> 2; y4 = yy >> 2;
   yh = y4 >> 5; yl = y4 & 31;
   xh = x4 >> 5; xl = x4 & 31;
   i = (xx & 3) + 4 * (yy & 3);
   gfxbufin(yh | 32);
   gfxbufin(i | 96);
   gfxbufin(yl | 96);
   gfxbufin(xh | 32);
   gfxbufin(xl | 64);
   return(0);
}

unsigned char getbuf(p)
int p;
{
   if(bufferonfile) {
      if(p == fdptr - 1) return(lastchar);
      if(p == fdptr) {
         read(fdbuffer,&lastchar,1);
         fdptr++;
         return(lastchar);
      }
      lseek(fdbuffer,p,0);
      read(fdbuffer,&lastchar,1);
      fdptr = p + 1;
      return(lastchar);
   } else {
      return(buf[p]);
   }
}


gettekxy(p,x,y)
int *p,*x,*y;
{
int xx,yy,i,l,h,ptr,k,z1,z2;
char c;

   z1 = -1; z2 = -1;
   xx = -1 ; yy = -1;
   ptr = *p;
   for(k=1;k<10;k++) {
      c=getbuf(ptr++);
      i=(c & 0xe0);
      switch(i) {
      case 32:
         h = (c & 31);
         break;
      case 64:
         l = (c & 31);
         xx = (h*32 + l) << 2;
         if(z2 != -1) xx = xx | z2;
         break;
      case 96:
         l = (c & 31);
         if(z1 != -1) {
            yy = h*32 + l;
            yy = (yy << 2) | (z1 >> 2);
            z2 = z1 & 3;
         } else {
            yy = (h*32 + l) << 2;
            z1 = l & 15;
         }
         break;
      }
      if((xx != -1) && (yy != -1)) break;
   }
   *x = xx; *y = yy; *p = ptr;
   return(0);
}

gfxbufin(c)
char c;
{
   if(bufferonfile) {
      write(fdbuffer,&c,1); 
      ptr++; fdptr++;
   } else {
      if(ptr<bufsiz) buf[ptr++]=c;
   }
   return(0);
}


/* *********************************************************************

                  Vector font utilities

   ********************************************************************* */

/* ------------------------------------------------------------------
      Read Vector font from file (as defined in Aux_Config)
   ------------------------------------------------------------------ */
readfont(name)
char *name;
{
int n,i,m,xx,max;
int yy,base;
unsigned char *ptr;
int fd;

   fd = open(name,0);
   read(fd,fontfile,16384);
   close(fd);
   n = 0;
   while(fontfile[n] != 0x1a) if(n++ > 32767) break;
   i = fontfile[n+1] + 256 * fontfile[n + 2];
   ptr = &fontfile[i];
   if(ptr[0] != 0x2b) {
      printf("no font file\n");
      exit(0);
   }
   offschar = i + ptr[5] + 256 * ptr[6];
   firstchar = ptr[4];
   fontheight = ptr[8] + ptr[11];
   fontdesc = &ptr[18];
   base = 0;
   m = 128 - firstchar;
   for(n = 0; n < m; n++) {         /* check fontwidth, generate prop table */
      i = offschar + fontdesc[2 * n] + 256 * fontdesc[2 * n + 1];
      ptr = &fontfile[i];
      i = 0; max = 0;
      while((ptr[i] & 0x80) != 0) {
         xx = ptr[i++]; yy = ptr[i++];
         xx = xx & 0x7f; yy = yy & 0x7f;
         if(xx > max) max = xx;
         if((yy & 0x40) != 0) {
            yy = (yy & 0x3f) - 0x3f;
            if(yy < base) base = yy;
         }
      }
      max = max + 2;
      proptab[n + firstchar + 1] = max;
   }
   base = -1 * base; fontheight = 0;
   for(n = 0; n < m; n++) {         /* move baseline */
      i = offschar + fontdesc[2 * n] + 256 * fontdesc[2 * n + 1];
      ptr = &fontfile[i];
      i = 0; max = 0;
      while((ptr[i] & 0x80) != 0) {
         i++; yy = ptr[i];
         xx = yy; yy = yy & 0x7f;
         if((yy & 0x40) != 0) yy = (yy & 0x3f) - 0x3f;
         yy = yy + base;
         if(yy > fontheight) fontheight = yy;
         yy = yy | (xx & 0x80);
         ptr[i++] = yy;
      }
   }
   fontheight = fontheight / 2;
   proptab[' '] = proptab['i'];
   fontwidth = proptab['W'];
   return(0);
}


/* ------------------------------------------------------------------
      Rotation
   ------------------------------------------------------------------ */
rotate(xx,yy)
int *xx,*yy;
{
int rx,ry,x,y;

   x = *xx ; y = *yy;
   rx = ((x * cosphi) >> 19) - (( y * sinphi) >> 19);
   ry = (( y * cosphi) >> 19) + ((x * sinphi) >> 19);
   *xx = rx ; *yy = ry;
   return(0);
}
/* ------------------------------------------------------------------
      plot one single character
   ------------------------------------------------------------------ */
plotchar(c)
int c;
{
int xx,yy;
int ix,iy;
int i,n;
unsigned char *ptr;

   ix = cx; iy = cy;

   posita(ix,iy);

   n = c - firstchar - 1;
   i = offschar + fontdesc[2 * n] + 256 * fontdesc[2 * n + 1];
   ptr = &fontfile[i];
   i = 0;
   while((ptr[i] & 0x80) != 0) {
      xx = ptr[i++]; yy = ptr[i++];
      n = 0;
      if((yy & 0x80) != 0) n = 1;
      xx = xx & 0x7f; yy = yy & 0x7f;
      xx = xx * sizex;
      yy = yy * sizey;
      rotate(&xx,&yy);
      if(n == 1) {
         vectoa(ix + xx, iy + yy);
      } else {
         posita(ix + xx, iy + yy);
      }
   }
   xx = sizex * fontwidth; yy = 0;
   if(prop_flag == 1) xx = sizex * proptab[c];
   rotate(&xx ,&yy);
   cx = ix + xx;
   cy = iy + yy;
   return(0);
}

/* ------------------------------------------------------------------
      plot string
   ------------------------------------------------------------------ */
plotstr(s)
char s[];
{
int i,mx,my,tx,ty;
int msizex, msizey, mprop;
unsigned char c;

   cy = cy - 4;
   msizex = sizex;
   msizey = sizey;
   mprop = prop_flag;
   mx = cx ; my = cy;
   for(tx=0;tx<thickx;tx++) {
      for(ty=0;ty<thicky;ty++) {
         cx = mx + tx;
         cy = my + ty;
         i=0;
         baseline = 0;
         sizex = msizex;
         sizey = msizey;
         fontfile = font_1;
         proptab = prop_1;
         fontdesc = fontdesc_1;
         fontheight = fontheight_1;
         fontwidth = fontwidth_1;
         firstchar = firstchar_1;
         offschar = offschar_1;
         prop_flag = mprop;

         while(1==1) {
            c = s[i++];
            if(c==0) break;
            if(c==92) {   /* meta character BACKSLASH ! */
               c = s[i++];
               switch(c) {
                  case 'u':   /* superscript */
                     baseline = baseline +1;
                     if(baseline > 0) {
                        cy = cy + ((sizey * fontheight) >> 1);
                        sizex = (sizex << 2) / 5;
                        sizey = (sizey << 2) / 5;
                        continue;
                     }
                     if(baseline == 0) {
                        cy = my + ty;
                        sizex = msizex;
                        sizey = msizey;
                        continue;
                     }
                     if(baseline < 0) {
                        cy = cy + ((sizey * fontheight) >> 1);
                        sizex = (5 * sizex) >> 2;
                        sizey = (5 * sizey) >> 2;
                        continue;
                     }
                  case 'd':   /* subscript */
                     baseline = baseline -1;
                     if(baseline < 0) {
                        cy = cy - ((sizey * fontheight) >> 1);
                        sizex = (sizex << 2) / 5;
                        sizey = (sizey << 2) / 5;
                        continue;
                     }
                     if(baseline == 0) {
                        cy = my + ty;
                        sizex = msizex;
                        sizey = msizey;
                        continue;
                     }
                     if(baseline > 0) {
                        cy = cy - ((sizey * fontheight) >> 1);
                        sizex = (5 * sizex) >> 2;
                        sizey = (5 * sizey) >> 2;
                        continue;
                     }
                  case '1':   /* primary font */
                        fontfile = font_1;
                        proptab = prop_1;
                        fontdesc = fontdesc_1;
                        fontheight = fontheight_1;
                        fontwidth = fontwidth_1;
                        firstchar = firstchar_1;
                        offschar = offschar_1;
                        continue;
                  case '2':   /* secondary font */
                        fontfile = font_2;
                        proptab = prop_2;
                        fontdesc = fontdesc_2;
                        fontheight = fontheight_2;
                        fontwidth = fontwidth_2;
                        firstchar = firstchar_2;
                        offschar = offschar_2;
                        continue;
                  case '0':   /* proportional off */
                        prop_flag = 0;
                        continue;
                  case 'b':   /* backspace */
                        cx = (cx - (sizex * fontwidth) >> 1);
                        continue;
               }
            }
            plotchar(c);
         }
      }
   }
   baseline = 0;
   sizex = msizex;
   sizey = msizey;
   fontfile = font_1;
   proptab = prop_1;
   fontdesc = fontdesc_1;
   fontheight = fontheight_1;
   fontwidth = fontwidth_1;
   firstchar = firstchar_1;
   offschar = offschar_1;
   prop_flag = mprop;
   return(0);
}

/* ----------------------------------------------------
       Calculate rotation matrix
   ---------------------------------------------------- */

rotmat(n)
int n;      /* Angle in degree */
{
float phi,cphi,sphi;

   phi = ((float) n) * 3.1415926 / 180.0;
   cphi = 262144 * cos( phi );
   sphi = 262144 * sin( phi );
   sinphi = (int) sphi;
   cosphi = (int) cphi;
   return(0);
}

xtoi(s)
char  s[];
{  int i,m,l,e;
   char c;

   l=strlen(s); e=0;
   for( i = 0 ; i < l ; i++ ) {
      c = s[i] ; c = toupper(c) ;
      m = c - '0' ;
      if( m > 9 ) m = m - 7 ;
      e = 16 * e + m ;
   } ;
   return(e) ;
}

/* ****************************************************************

                  HARDCOPY and related functions

   **************************************************************** */
void hco_()
{
hco(defaultprinter);
}

hco(str)
char str[];
{
unsigned char *bitplane;
char z[80];
int n;

   pribufsiz=8190;
   pribufptr=0;
   printerbuf=(unsigned char *)calloc(pribufsiz+2,sizeof(char));
   if(buf==NULL) {
      fprintf(stderr,"could not allocate printer buffer %d bytes\n",pribufsiz);
      return(0);
   }


   strcpy(z,defaultprinter);
   if(str[0]!=0) strcpy(z,str);
   fdprinter=auxopen(z);
   strcpy(systemcommand,auxparams[4]);

   n=5;
   prt_passes=atoi(auxparams[n]); n=n+1;
   prt_lsbmsb=atoi(auxparams[n]); n=n+1;
   x_prt_siz=atoi(auxparams[n]); n=n+1;
   y_prt_siz=atoi(auxparams[n]); n=n+1;

   if(prt_lsbmsb == 10) {
      save_ps(auxparams[0],x_prt_siz,y_prt_siz);
      system2(systemcommand);
      return(0);
   }
   if(prt_lsbmsb == 11) {
      save_hpgl(auxparams[0],x_prt_siz,y_prt_siz);
      system2(systemcommand);
      return(0);
   }

   cvtbs(prt_init,auxparams[n]); n=n+1;
   cvtbs(prt_gra,auxparams[n]); n=n+1;
   cvtbs(prt_halflf,auxparams[n]); n=n+1;
   cvtbs(prt_lf,auxparams[n]); n=n+1;
   cvtbs(prt_fin,auxparams[n]);

   if(fdprinter <= 0) {
      fdprinter = creat(auxparams[0],0666);
      if(fdprinter <= 0) return(0);
   }

   n = (x_prt_siz * y_prt_siz) / 8;     /* length of buffer needed */
   n = n + 1024;                        /* to go shure */
   bitplane=(unsigned char *)calloc(n,sizeof(char));
   if(buf==NULL) {
      fprintf(stderr,"could not allocate shadow memory %d bytes\n",n);
      free(printerbuf);
      close(fdprinter);
      return(0);
   }
   redrawhco(bitplane);
   printout(bitplane);
   close(fdprinter);
   free(bitplane); free(printerbuf); 
   system2(systemcommand);
   return(0);
}

strtoprt(s)
unsigned char s[];
{
int n;
unsigned char c;

   n=0;
   while(1==1) {
      c=s[n++];
      if(c==0) break;
      pribufin(c);
   }
   return(0);
}

pribufin(c)
unsigned char c;
{
   if(pribufptr>=pribufsiz) pribufflush();
   printerbuf[pribufptr++]=c;
   return(0);
}

pribufflush()
{
write(fdprinter,printerbuf,pribufptr); 
pribufptr=0;
   return(0);
}

redrawhco(bitplane)
unsigned char *bitplane;
{
int x,y,p;
char c;

   p=0;
   while(getbuf(p)!=0x1d) p = p + 1;   /* find posita first */

   while(p<ptr) {                      /* scan vector buffer */

      c=getbuf(p);
      if(c==0x1d) {
         p=p+1;
         gettekxy(&p,&x,&y);
         if((x>_TEKXMAX) | (y>_TEKYMAX)) {
            while(getbuf(p)!=0x1d) p=p+1;
            continue;
         }
         draw_to(bitplane,FALSE,x,y);
         continue;
      }
      if(c>31) {
         gettekxy(&p,&x,&y);
         if((x>_TEKXMAX) | (y>_TEKYMAX)) {
            while(getbuf(p)!=0x1d) p=p+1;
            continue;
         }
         draw_to(bitplane,TRUE,x,y);
         continue;
      }
      while(getbuf(p)!=0x1d) p=p+1;          /* find next posita */
   }
   return(0);
}


redraw2()
{
int x,y,p;
int sto_nohco;
int sto_ptr;
char c;

   if(nohco) return(0);

   Forbid();  /* taskswitching */

   sto_nohco = nohco;
   sto_ptr = ptr;
   nohco = TRUE;
   
   cls();
   ptr = sto_ptr;

   p=0;
   while(getbuf(p)!=0x1d) p = p + 1;   /* find posita first */

   while(p<ptr) {                      /* scan vector buffer */

      c=getbuf(p);
      if(c==0x1d) {
         p=p+1;
         gettekxy(&p,&x,&y);
         if((x>_TEKXMAX) | (y>_TEKYMAX)) {
            while(getbuf(p)!=0x1d) p=p+1;
            continue;
         }
         posita(x,y);
         continue;
      }
      if(c>31) {
         gettekxy(&p,&x,&y);
         if((x>_TEKXMAX) | (y>_TEKYMAX)) {
            while(getbuf(p)!=0x1d) p=p+1;
            continue;
         }
         vectoa(x,y);
         continue;
      }
      while(getbuf(p)!=0x1d) p=p+1;          /* find next posita */
   }
   nohco = sto_nohco;
   ptr = sto_ptr;
   Permit();      /* Taskswitching */
   return(0);
}
      
/* --------------------------------------------------------------- */
/*       Draw a line                                               */
/* --------------------------------------------------------------- */
draw_to(bitplane,pen_down,x,y)
unsigned char *bitplane;
int pen_down,x,y;
{
   int   xinc,yinc,
         xcount,ycount,
         fx,fy;


   x = (x_prt_siz * x) / _TEKXMAX ;
   y = (y_prt_siz * y) / _TEKYMAX ; y=y_prt_siz-y;

   if(pen_down == TRUE) {
      xinc=liabs(x-aposx);
      yinc=liabs(y-aposy);
      fx=lisgn(x-aposx);
      fy=lisgn(y-aposy);
      xcount=xinc;
      ycount=yinc;
      do {
         set_pixel(bitplane,aposx,aposy);
         if(hcothick) {
            set_pixel(bitplane,aposx+1,aposy);
            set_pixel(bitplane,aposx,aposy+1);
            set_pixel(bitplane,aposx+1,aposy+1);
         }
         if(xcount>ycount) {
            ycount=ycount+yinc ; aposx=aposx+fx;
         } else {
            xcount=xcount+xinc ; aposy=aposy+fy;
         }
      } while((liabs(x-aposx)>=1) || (liabs(y-aposy)>=1));
   }
   aposx=x; aposy=y;
   return(0);
}

liabs(x)
int x;
{
   if(x>=0) return(x);
   return(-x);
}

lisgn(x)
int  x;
{
   if(x>0) return(1L);
   if(x<0) return(-1L);
   return(0L);
}

/* --------------------------------------------------------------- */
/*       plot one pixel                                            */
/* --------------------------------------------------------------- */
set_pixel(bitplane,x,y)
unsigned char *bitplane;
int x,y;
{
   register int  byte,bit,n;



   byte=y*(x_prt_siz>>3)+(x>>3);
   bit= x & 7; n=128>>bit;
   bitplane[byte] |= n;
   return(0);
}

/* --------------------------------------------------------------- */
/*       get one pixel from shadow memory                          */
/* --------------------------------------------------------------- */
get_pixel(bitplane,x,y)
unsigned char *bitplane;
int x,y;
{
   register int   byte,bit;
   register unsigned char c;

   byte=y*(x_prt_siz>>3)+(x>>3);
   bit=7-(x & 7);
   c=((bitplane[byte])>>bit) & 1;
   return((int)c);
}

/* ----------------------------------------------------------- */
/*       get one byte ready to print from shadow memory        */
/* ----------------------------------------------------------- */
get_prtbyte(bitplane,x,y)
unsigned char *bitplane;
int x,y;
{
   int    i,m;
   long   n;

   m=0; n=0; x=x_prt_siz-x;
   for(i=1; i<=8; ++i) {
      n=n+prt_passes;
      m=2*m+get_pixel(bitplane,x-n,y);
   }
   return(m);
}

/* ----------------------------------------------------------- */
/*       make hardcopy of shadow memory                        */
/* ----------------------------------------------------------- */
printout(bitplane)
unsigned char *bitplane;
{
   long  x,y,i;
   unsigned char c;


   strtoprt(prt_init); pribufflush();

   if(prt_lsbmsb == 2) {              /* trap HP raster row graphics */
      hp_rasterrow(bitplane);
      return(0);
   }

   if(prt_lsbmsb == 3) {              /* trap HP DeskJet 500 */
      hp_deskjet(bitplane);
      return(0);
   }

   /* it follows the epson style printout routine */

   x=0;
   while(x<x_prt_siz) {
      y=0;
      for(i=1; i<=prt_passes; ++i) {
         prt_gra_out(y_prt_siz);
         while(y<y_prt_siz) {
            c=get_prtbyte(bitplane,x,y++);
            pribufin(c);
         }
         strtoprt(prt_halflf); 
         y=0; ++x;
      }
      strtoprt(prt_lf); pribufflush();
      x=x+7*prt_passes;
   }

   strtoprt(prt_fin); pribufflush();
   return(0);
}

/* -----------------------------
   HP mode raster row graphics 
   ----------------------------- */

hp_rasterrow(bitplane)
unsigned char *bitplane;
{
   int  n,x,m,i;
   unsigned char c;


   m = x_prt_siz / 8;
   n = (y_prt_siz -1) * m;
   x=0;
   while(x<n) {
      strtoprt(prt_gra);
      for(i=0; i<m; i++) {
         c=bitplane[x++];
         pribufin(c);
      }
      pribufflush();
   }
   strtoprt(prt_fin); pribufflush();
   return(0);
}

/* -----------------------------
      HP DeskJet mode  
   ----------------------------- */

hp_deskjet(bitplane)
unsigned char *bitplane;
{
int  x,y,i;
unsigned char c;

   x=0;
   while(x<x_prt_siz) {
      y = y_prt_siz - 1;
      strtoprt(prt_gra);
      while(y >= 0) {
         c = 0;
         for(i = 0; i < 8; i++) {
            c = (2 * c) + get_pixel(bitplane,x,y--);
         }
         pribufin(c);
      }
      pribufflush();
      x = x + 1;
   }
   strtoprt(prt_fin); pribufflush();
   return(0);
}

/* ------------------------------------------------------------ */
/* some printer dependend routines:                             */
/* ------------------------------------------------------------ */

prt_gra_out(x)
int  x;
{
unsigned char c1,c2;

   c1=x/256; c2=x-256*c1;
   strtoprt(prt_gra);
   if(prt_lsbmsb==1) {
      pribufin(c2);
      pribufin(c1);
   } else {
      pribufin(c1);
      pribufin(c2);
   }
   return(0);
}


/* convert string which includes the backslash */

cvtbs(s2,s1)
char s2[] , s1[];
{  int   l , i2 , i1 ;
   char  c , cc , s[8];

   l=strlen(s1); i2=0 ;
   for (i1 = 0; i1 <= l; i1++) {
      c=s1[i1];
      if(c == ' ') continue;
      if(c == '\\') {
         cc=s1[++i1];
         switch(cc) {
         case 'n':
            c='\n' ;  break ;
         case 'f':
            c='\f' ;  break ;
         case 't':
            c='\t' ;  break ;
         case 'b':
            c='\b' ;  break ;
         case 'x': /* hexadecimal conversion */
            s[0]=s1[++i1] ; s[1]=s1[++i1] ; s[2]=0 ;
            c=xtoi(s) ; break ;
         default:
            ; } ;
         } ;
      s2[i2++]=c ; }
   s2[i2]=0 ;
   return(i2-1);
}

/* ---------------------------------------------------------------
   Special actions: set text parameters and make hardcopy
   --------------------------------------------------------------- */
do_special(param)
char param[];
{
int i,n,sx,sy,tx,ty,w;
char s[80];

   sscanf(param,"%d",&n);

   hcothick = FALSE;
   if(n > 127) {
      hcothick = TRUE;
      n = n && 127;
   }

   strcpy(s,"");
   switch(n) {
   case 0 :                                     /* textparam */
      sscanf(param,"%d %d %d %d %d %d %s",&i,&sx,&sy,&tx,&ty,&w,s);
      if(sx>0) {sizex=sx; msizex=sx;}
      if(sy>0) {sizey=sy; msizey=sy;}
      if(tx>0) thickx=tx;
      if(ty>0) thicky=ty;
      if(s[0]!=0) readfont(s);
      txtangle=w;
      rotmat(w);
      break;
   case 1 :                                     /* hco */
      sscanf(param,"%d %s",&i,s);
      hco(s);
      break;
   case 2 :
      sscanf(param,"%d %s",&i,s);               /* print HP-GL */
      save_hpgl(s,0,0);
      break;
   case 3 :
      sscanf(param,"%d %s",&i,s);               /* print PostScript */
      save_ps(s,0,0);
      break;
   case 4 :
      sscanf(param,"%d %s",&i,s);               /* print Amiga IFF */
      save_iff(s);
      break;
   case 5 :
      sscanf(param,"%d %s",&i,s);               /* print Aegis Draw */
      save_adraw(s,0,0);
      break;
   case 6 :
      sscanf(param,"%d %s",&i,s);               /* print DXF */
      save_dxf(s,0,0);
      break;
   }
   return(0);
}

teknewopen()
{
int   n,_tek4014;
char  c,s[80],z[80];

   strcpy(s,"gfx");
   c=_tekpipe+48;
   z[0]=c; z[1]=0;
   strcat(s,z);
   _tek4014=auxopen(s); /* _tekpipe is defined in spec.h */
   if(_tek4014 > 0) close(_tek4014);
   strcpy(tekname,auxparams[0]);
   strcpy(primaryfont,auxparams[1]);
   sizex_1 = atoi(auxparams[2]);
   sizey_1 = atoi(auxparams[3]);
   sizex = sizex_1; sizey = sizey_1;
   msizex = sizex; msizey = sizey;
   strcpy(secondaryfont,auxparams[4]);
   sizex_2 = atoi(auxparams[5]);
   sizey_2 = atoi(auxparams[6]);
   strcpy(bufferfile,auxparams[7]);
   if(bufferfile[0] > '9') {
      bufferonfile = TRUE;
   } else {
      bufferonfile = FALSE;
      bufsiz = atoi(bufferfile);
   }
   strcpy(defaultprinter,auxparams[8]);
   _tek4014=creat(tekname,0777);
   if(_tek4014 <= 0) {
      fprintf(stderr,"failed to open graphic file\n");
/*      close_gfx(my_window); */
      exit(-1);
   }
      n = (int) *posita; write(_tek4014,&n,4);
      n = (int) *vectoa; write(_tek4014,&n,4);
      n = (int) *dperas; write(_tek4014,&n,4);
      n = (int) *gfxtext; write(_tek4014,&n,4);
      n = (int) *getxy; write(_tek4014,&n,4);
      n = (int) *setcolour; write(_tek4014,&n,4);
      n = (int) *rmtek; write(_tek4014,&n,4);
      n = (int) *textparam; write(_tek4014,&n,4);
      n = (int) *hco; write(_tek4014,&n,4);
      n = (int) *do_special; write(_tek4014,&n,4);
      n = (int) *textlen; write(_tek4014,&n,4);
      n = (int) *textheight; write(_tek4014,&n,4);
   close(_tek4014);
   return(0);
}


/* ---------------------------------------------------------------

      Diverse Vektororientierte Ausgabe formate:

      HP-GL , DXF, PostScript

   --------------------------------------------------------------- */

vector_out(output,x_faktor,y_faktor,x_ofs,y_ofs,move_to,draw_to,bugfix)
 FILE *output;
 char move_to[], draw_to[];
 float x_faktor, y_faktor;
 float x_ofs, y_ofs;
 int bugfix;
{
int x,y,p;
float fx,fy,ofx,ofy;
char c;
int linecount;          /* This variable is introduced to work around a "bug" in most
                           PostScript interpreters, which have only restricted memory
                           capacities                                                 */

   p=0; linecount = 0;
   while(getbuf(p)!=0x1d) p = p + 1;   /* find posita first */

   while(p<ptr) {                      /* scan vector buffer */

      c=getbuf(p);
      if(c==0x1d) {
         p=p+1;
         gettekxy(&p,&x,&y);
         if((x < 0) | (y < 0) | (x>_TEKXMAX) | (y>_TEKYMAX)) {
            while(getbuf(p)!=0x1d) p=p+1;
            continue;
         }
         ofx = (x_faktor * x) + x_ofs;
         ofy = (y_faktor * y) + y_ofs;
         if(bugfix != 2) fprintf(output,move_to,ofx,ofy);
         linecount = 0;
         continue;
      }
      if(c>31) {
         gettekxy(&p,&x,&y);
         if((x < 0) | (y < 0) | (x>_TEKXMAX) | (y>_TEKYMAX)) {
            while(getbuf(p)!=0x1d) p=p+1;
            continue;
         }
         fx = (x_faktor * x) + x_ofs;
         fy = (y_faktor * y) + y_ofs;
         if(bugfix == 2) {   /* DXF special treatment */
            fprintf(output,move_to,ofx,ofy);
            ofx = fx; ofy = fy;
         }
         fprintf(output,draw_to,fx,fy);
         if((linecount++ > 20) && (bugfix == 1)) {   /* work around PostScript "bug" */
            linecount = 0;
            fprintf(output,move_to,fx,fy);
         }
         continue;
      }
      while(getbuf(p)!=0x1d) p = p + 1;   /* find next posita */
   }
   return(0);
}

save_hpgl_()
{
char s[80];

   FileSelect("Select HP-GL file",s);
   save_hpgl(s,0,0);
   return(0);
}

save_hpgl(s,xsize,ysize)
char *s;
int xsize, ysize;
{
FILE *output;
float x_factor, y_factor;

   x_factor = (float) xsize / 100.0; if(xsize == 0) x_factor = 2.25;
   y_factor = (float) ysize / 100.0; if(ysize == 0) y_factor = 2.25;

   output = fopen(s,"w");
   fprintf(output,"IN;\nLT;\n1;\n");
   vector_out(output,x_factor,y_factor,0.0,0.0,
      "PU;PA %5.0f,%5.0f;\n",
      "PD;PA %5.0f,%5.0f;\n",0);
   fprintf(output,"PU;SP;IP;SC;PA 0,7650\n");
   fclose(output);
   return(0);
}

save_adraw_()
{
char s[80];

   FileSelect("Select adraw file",s);
   save_adraw(s,0,0);
   return(0);
}

save_adraw(s,xsize,ysize)
char *s;
int xsize, ysize;
{
FILE *output;
float x_factor, y_factor;

   x_factor = 0.24;
   y_factor = 0.24;

   output = fopen(s,"w");
   fprintf(output,"81086 0.00000 0.00000 1000.0 1000.0 0 1.00000 \"lise.out\"\n-1\n");
   fprintf(output,"1 52 0.0 0.0 1000.0 1000.0 0 0 0 0 0\n");
   vector_out(output,x_factor,y_factor,0.0,0.0,
      "   0\n1 52 0.0 0.0 1000.0 1000.0 0 0 0 0 0\n   1 %4.3f %4.3f\n",
      "   1 %4.3f %4.3f\n",0);
   fprintf(output,"   0\n-1\n");
   fclose(output);
   return(0);
}

save_dxf_()
{
char s[80];

   FileSelect("Select DXF file",s);
   save_dxf(s,0,0);
   return(0);
}

save_dxf(s,xsize,ysize)
char *s;
int xsize, ysize;
{
FILE *output;
float x_factor, y_factor;

   x_factor = 0.24;
   y_factor = 0.24;

   output = fopen(s,"w");
   fprintf(output,"0\nSECTION\n");
   fprintf(output,"2\nENTITIES\n");

   vector_out(output,x_factor,y_factor,0.0,0.0,
      "0\nLINE\n8\n0\n10\n %4.3f\n20\n %4.3f\n",
      "11\n %4.3f\n21\n %4.3f\n",2);

   fprintf(output,"0\nENDESEC\n");
   fprintf(output,"0\nEOF\n");

   fclose(output);
   return(0);
}

save_ps_()
{
char s[80];

   FileSelect("Select PostScript file",s);
   save_ps(s,0,0);
   return(0);
}

save_ps(str,xsize,ysize)
char *str;
int xsize, ysize;
{
char s[80];
FILE *output;
float x_factor, y_factor;

   x_factor = (float) xsize / 100.0; if(xsize == 0) x_factor = 0.125;
   y_factor = (float) ysize / 100.0; if(ysize == 0) y_factor = 0.125;

   if(str[0] == 0) {
      FileSelect("Select PostScript file",s);
   } else {
      strcpy(s,str);
   }
   output = fopen(s,"w");
   fprintf(output,"%c!PS-Adobe-1.0\n",'%');
   vector_out(output, x_factor, y_factor, 10.0, 30.0,
      "0.4 setlinewidth\nstroke\n%4.2f %4.2f moveto\n",
      "%4.1f99 %4.1f99 lineto\n",1);
   fprintf(output,"0.4 setlinewidth\nstroke\nshowpage\n");
   fclose(output);
   return(0);
}

/* --------------------------------------------------------------------
      IFF save routinen
   -------------------------------------------------------------------- */
save_iff_()
{
char s[80];

   FileSelect("Select IFF file",s);
   save_iff(s);
   return(0);
}

save_iff(str)
char *str;
{
unsigned char *bitplane;
int n;
char  s[80];

   if(str[0] == 0) {
      FileSelect("Select IFF file",s);
   } else {
      strcpy(s,str);
   }

   x_prt_siz = 2048;
   y_prt_siz = 2048;

   n = (x_prt_siz * y_prt_siz) / 8;     /* length of buffer needed */
   n = n + 1024;                        /* to go shure */
   bitplane=(unsigned char *)calloc(n,sizeof(char));
   if(buf==NULL) {
      fprintf(stderr,"could not allocate shadow memory %d bytes\n",n);
      return(0);
   }
   redrawhco(bitplane);
   mem_iff(s,bitplane,x_prt_siz,y_prt_siz);
   free(bitplane);
   return(0);
}


mem_iff(name,ptr,width,height)
char name[];
unsigned char *ptr;
int width,height;
{
int output;
 static long i,j,anzcol,lenheader,lenfile,lencmap,lenbody;
 static BYTE r,g,b;

   output = creat(name,0);

 /* Initialisierung des BMHD-Chunks */
 BMHDs.Height=height;
 BMHDs.Width=width;
 BMHDs.Depth=1;
 BMHDs.compression=0;
 BMHDs.PWidth=BMHDs.Width;
 BMHDs.PHeight=BMHDs.Height;
 if(BMHDs.Height>=400) BMHDs.yaspect *= 2;
 if(BMHDs.Width>=640) BMHDs.xaspect *= 2;
 CAMGs.ViewModes= HIRES | LACE;
 /* Anzahl der Farben? */
 j=BMHDs.Depth;
 if(j>5) j=5;  /* maximal 32 Farbregister abspeichern! */
 for(i=0,anzcol=1;i<j;anzcol *= 2,++i);
 lencmap = anzcol*3;
 lenbody=BMHDs.Width/8*BMHDs.Height*BMHDs.Depth;
 lenheader=sizeof(FORMs)-8+sizeof(BMHDs)+sizeof(CAMGs)+lencmap+8+8;
 lenfile=lenheader+lenbody;
 FORMs.len=lenfile;
 /* Speichern des FORM-Chunks */
   write(output,&FORMs,sizeof(FORMs));
 /* Speichern des BMHD-Chunks */
   write(output,&BMHDs,sizeof(BMHDs));
 /* Speichern des CAMG-Chunks */
   write(output,&CAMGs,sizeof(CAMGs));
 /* Speichern des CMAP-Chunks */
   write(output,&cmap,4);
   write(output,&lencmap,4);
   lencmap+=8;
   r = 255; g = 255; b = 255;
   write(output,&r,1); write(output,&g,1); write(output,&b,1);
   r = 0; g = 0; b = 0;
   write(output,&r,1); write(output,&g,1); write(output,&b,1);
 
 /* Speichern des BODY-Chunks */
   write(output,&body,4);
   write(output,&lenbody,4);
   write(output,ptr,(width * height) >> 3);
   
   close(output);                    /* File schliessen */
   return(0);
}


main(argc,argv)
int argc;
char *argv[];
{
char z[80];
int wx = 500,
    wy = 400,
    wl = -1,
    wt = -1;

  _MAXSPCLEN = 16; /* prevent wasting of memory */

  if(checkopt(argc,argv,"-paper",z)) paper=atoi(z);
  if(checkopt(argc,argv,"-ink",z)) ink=atoi(z);
  if(checkopt(argc,argv,"-left",z)) wl=atoi(z);
  if(checkopt(argc,argv,"-top",z)) wt=atoi(z);
  if(checkopt(argc,argv,"-xsize",z)) wx = atoi(z);
  if(checkopt(argc,argv,"-ysize",z)) wy = atoi(z);

/* --- window geometry and name */
  my_new_window = init_window(wx,wy,"tek-Amiga",0,1);
  if(wl > 0)my_new_window->LeftEdge = wl;
  if(wt > 0)my_new_window->TopEdge = wt;

/* ----- initializing menus and requesters */

   add_item(-1,-1,NEW_MENU,"project",0,0); 
      fn_number++;
   add_item(-1,-1,MENU,"Hard Copy",0,0); 
      fn_command[fn_number] = (void *)hco_;
      fn_number++;
   add_item(-1,-1,MENU,"Save IFF",0,0); 
      fn_command[fn_number] = (void *)save_iff_;
      fn_number++;
   add_item(-1,-1,MENU,"Save HP-GL",0,0); 
      fn_command[fn_number] = (void *)save_hpgl_;
      fn_number++;
   add_item(-1,-1,MENU,"Save ADRAW",0,0); 
      fn_command[fn_number] = (void *)save_adraw_;
      fn_number++;
   add_item(-1,-1,MENU,"Save DXF",0,0); 
      fn_command[fn_number] = (void *)save_dxf_;
      fn_number++;
   add_item(-1,-1,MENU,"Save PostScript",0,0); 
      fn_command[fn_number] = (void *)save_ps_;
      fn_number++;
   add_item(-1,-1,MENU,"Clear",0,0); 
      fn_command[fn_number] = (void *)dperas;
      fn_number++;
   add_item(-1,-1,MENU,"Redraw",0,0); 
      fn_command[fn_number] = (void *)redraw2;
      fn_number++;
   add_item(-1,-1,MENU,"Cursor",0,0); 
      fn_command[fn_number] = (void *)Cursor;
      fn_number++;
   add_item(-1,-1,NEW_MENU,"colour",0,0); 
      fn_number++;
   add_item(-1,-1,MENU,"Ink +",0,0); 
      fn_command[fn_number] = (void *)InkPlus;
      fn_number++;
   add_item(-1,-1,MENU,"Ink -",0,0); 
      fn_command[fn_number] = (void *)InkMinus;
      fn_number++;
   add_item(-1,-1,MENU,"Paper +",0,0); 
      fn_command[fn_number] = (void *)PaperPlus;
      fn_number++;
   add_item(-1,-1,MENU,"Paper -",0,0); 
      fn_command[fn_number] = (void *)PaperMinus;
      fn_number++;

   tekname = (unsigned char *) malloc(80);
   primaryfont = (unsigned char *) malloc(80);
   secondaryfont = (unsigned char *) malloc(80);
   defaultprinter = (unsigned char *) malloc(80);
   systemcommand = (unsigned char *) malloc(80);
   bufferfile = (unsigned char *) malloc(80);

   teknewopen();
   if(checkopt(argc,argv,"-buf",z)) {
      strcpy(bufferfile,z);
      if(bufferfile[0] > '9') {
         bufferonfile = TRUE;
      } else {
         bufferonfile = FALSE;
         bufsiz = atoi(bufferfile);
      }
   }

   if(checkopt(argc,argv,"-nohco",z)) nohco=TRUE;

   if(bufferonfile) {
      fdbuffer = creat(bufferfile,0666);
      close(fdbuffer);
      fdbuffer = open(bufferfile,2,0666);
   } else {
      if(bufsiz < 1024) {
         nohco = TRUE;
      } else {
         if(!nohco) buf = (unsigned char *)malloc(bufsiz+10);
      }
   }

   font_1 = (unsigned char *) malloc(16384);
   font_2 = (unsigned char *) malloc(16384);
   prop_1 = (int *) calloc(256,sizeof(int));
   prop_2 = (int *) calloc(256,sizeof(int));

   fontfile = font_2; proptab = prop_2;
   readfont(secondaryfont);
   fontdesc_2 = fontdesc;
   fontheight_2 = fontheight;
   fontwidth_2 = fontwidth;
   firstchar_2 = firstchar;
   offschar_2 = offschar;

   fontfile = font_1; proptab = prop_1;
   readfont(primaryfont);
   fontdesc_1 = fontdesc;
   fontheight_1 = fontheight;
   fontwidth_1 = fontwidth;
   firstchar_1 = firstchar;
   offschar_1 = offschar;

  my_window = (struct Window *) OpenWindow( my_new_window );
  SetMenuStrip( my_window, menu_bar );
  if(my_window == NULL)
  {
    CloseLibrary( IntuitionBase );
    exit();  
  }
  rp = my_window->RPort;
  SetDrMd(rp,JAM1);          /* Drawmode setzen */
  SetAPen(rp,2);             /* Farbregister zum Zeichnen setzen */

  fin_flg = FALSE;
  MainLoop2(my_window);

  remove_tek();
  CloseLibrary(IntuitionBase);
  CloseLibrary(GfxBase);

  free(font_1); free(font_2); free(prop_1); free(prop_2);
  free(tekname); free(primaryfont); free(secondaryfont);
  free(defaultprinter); free(systemcommand); free(bufferfile);
  if(bufferonfile) {
      close(fdbuffer);
      unlink(bufferfile);
   } else {
     if (!nohco) free(buf);
  }

  exit(0);
}

MainLoop2(window)
struct Window *window;
{
int wx,wy;
ULONG class;
ULONG code;
struct IntuiMessage *my_message;
struct Gadget *my_gadget;

  close_me = FALSE;
  wx = window->Width;
  wy = window->Height;
  while( close_me == FALSE )
  {
    Delay(20);

    while(my_message=(struct IntuiMessage *)GetMsg(window->UserPort))
    {
      class = my_message->Class;      /* Save the IDCMP flag. */
      code = my_message->Code;
      ReplyMsg( my_message );
      switch( class )
      {
        case CLOSEWINDOW:  /* The user selected the Close window gadget! */
               close_me=TRUE;
               break;
             
        case GADGETDOWN:   /* The user has selected a gadget: */
               close_me=read_gadgets(my_message,window);
               break;

        case GADGETUP:     /* The user has released a gadget: */
              my_gadget = (struct Gadget *) my_message->IAddress;
              if(my_gadget->GadgetType == STRGADGET) {
                  close_me=read_gadgets(my_message,window);
               }
               break;
        case MENUPICK:
               CallBack_menu(code);
               break;
      }
      if((wx != window->Width) || (wy != window->Height)) {
         redraw2();
         wx = window->Width;
         wy = window->Height;
      }
    }
  }
  close_gfx(window);
  return(0);
}

system2(str)
char *str;
{
struct FileHandle *input, *output;

   if(instr("IGNORE",str) >= 0) return(0);

   input = (struct FileHandle *) Open("nil:",MODE_OLDFILE);
   output = (struct FileHandle *) Open("nil:",MODE_NEWFILE);
   Execute(str,input,output);
   Close(input);
   Close(output);
   return(0);
}
