Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!sri-unix!rutgers!super.upenn.edu!dsl.cis.upenn.edu!bradley From: bradley@dsl.cis.upenn.edu (John Bradley) Newsgroups: comp.windows.x Subject: xsplot - a SPICE plotting program for X V10.4 (part 1 of 4) Message-ID: <1841@super.upenn.edu> Date: Mon, 24-Aug-87 19:04:47 EDT Article-I.D.: super.1841 Posted: Mon Aug 24 19:04:47 1987 Date-Received: Tue, 25-Aug-87 06:48:56 EDT Sender: news@super.upenn.edu Reply-To: bradley@dsl.cis.upenn.edu.UUCP (John Bradley) Distribution: na Organization: University of Pennsylvania Lines: 2147 xsplot is an X program (10.4) for viewing, plotting, and analyzing SPICE output. It will drive an HP-GL plotter for hardcopy. It can be used to look at non-SPICE data, also. Why, it could be the Neatest Thing Ever. Probably not, though. Runs just dandy on Berkeley 4.2 Unix variants (on the IBM RT under 4.2 and 4.3, and on random Vaxen under Ultrix 1.2 and 2.0) --John Bradley - University of Pennsylvania - bradley@cis.upenn.edu Part 1 of 4 ------------------------cut here----------------------------------------- #!/bin/sh # to extract, remove the header and type "sh filename" if `test ! -d ./xsplot` then mkdir ./xsplot echo "mkdir ./xsplot" fi if `test ! -s ./xsplot/xsplotio.c` then echo "writing ./xsplot/xsplotio.c" cat > ./xsplot/xsplotio.c << '\Rogue\Monster\' /************************************************************************/ /* SPLOTIO.C */ /*----------------------------------------------------------------------*/ /* Library of routines to handle file i/o, spice parsing. */ /*----------------------------------------------------------------------*/ /* int OpenFiles (fname); */ /* int OpenSpice (); */ /* int LoadNewAnal (anum); */ /* int LoadAnal (anum); */ /* int expfname (name); */ /* int killtmps (); */ /* char* FixName (name); */ /************************************************************************/ #include "xsplot.h" #include static char *homedir; char *getenv(); static char outfname[128]; static FILE *outfile; static int NOPAGE; /* whether or not the NOPAGE option has been set */ static char pst[256]; /* used for printf's */ /************************************************************************/ char *FixName(name) char *name; { /* returns file name (strips off directory names) (ie: "/usr/fish/beebo/crap" returns "crap") */ char *sp; sp = rindex(name,'/'); if (sp) return sp+1; else return name; } /************************************************************************/ static char *tfname(buf,i) char *buf; int i; { sprintf(buf,"/tmp/S%ld.%s.t%d",pid,FixName(outfname),i); return(buf); } /************************************************************************/ killtmps() { /* kills all '.tn' files created by this process. Called when quitting */ extern int errno; sprintf(pst,"rm -f /tmp/S%ld.*",pid); system(pst); /* yeah, I'm pretty embarrassed about it, too... */ } /************************************************************************/ int OpenFiles() { homedir = getenv("HOME"); if (homedir == NULL) homedir = "."; if (OpenSpice()) Quit(); LoadNewAnal(0); } /************************************************************************/ int OpenSpice() { int i,err; strcpy(outfname,basfname); if (expfname(outfname)) { sprintf(pst,"ERROR: unable to open '%s'",outfname); ErrBox(pst,3); return 1; } /* strcat(outfname,".out"); */ NOPAGE=0; outfile = fopen(outfname,"r"); if (outfile==0) { sprintf(pst,"ERROR: unable to open '%s'",outfname); ErrBox(pst,3); return 1; } err=MakeTmpFiles(); fclose(outfile); return(err); } /************************************************************************/ static int MakeTmpFiles() /* parses .OUT file into files (one file per analysis) */ /* also loads up the anals array with stuff */ { int i,j,k,done,err; FILE *tmpfile; char linebuf[255], tmpfname[80]; float tdat[MYPERANAL+1]; Anal *ap; if (FindAnals()) return 1; if (Anals2Labs()) return 1; ConvertAnals(); if (NOPARSE) return 0; sprintf(pst,"Parsing file '%s'. Please wait.",outfname); ErrBox(pst,1); rewind(outfile); for (i=0; itype)) { /* go to beginning of data */ fclose(tmpfile); return 1; } numpts = done = 0; putw(numpts,tmpfile); /* write a dummy value for numpts */ while (!done) { /* write the data to the tmp file */ /* read a line of data */ for (j=0; jnumys+1; j++) { done = done || (fscanf(outfile,"%s",linebuf)==-1); tdat[j]=atof(linebuf); if (tdat[j]==0.0) { if (linebuf[0]!='0') done=1; /* read a non-numeric */ else if (strcmp(linebuf,"0.")==0) /* some Fortran comps print '0.0' as '0. e00', which fools scanf, hence the second fscanf */ fscanf(outfile,"%*s"); } } if (!done) { numpts++; if (numpts % 20==0) { sprintf(pst,"Writing tmp file '%s': %4d points", tmpfname,numpts); ErrBox(pst,0); } fwrite(tdat,sizeof(float),ap->numys+1,tmpfile); } } rewind(tmpfile); /* fill in the right val for numpts */ putw(numpts,tmpfile); fclose(tmpfile); sprintf(pst,"Writing tmp file '%s': %4d points",tmpfname,numpts); ErrBox(pst,0); ap->numpts = numpts; } /* repeat for each tmpfile/analysis */ return 0; } /************************************************************************/ static int FindAnals() /* reads the input listing. copies lines starting with .PRINT to analtitle fields in anals array. Also notes whether the NOPAGE option has been set */ { char linebuf[256],*err; char a[5][20]; int i; rewind(outfile); numanals=0; while (fgets(linebuf,256,outfile)==linebuf) { a[0][0]='\0'; sscanf(linebuf,"%s %s %s %s %s",a[0],a[1],a[2],a[3],a[4]); for (i=0; i<5; i++) a[i][19]='\0'; if (strncmp(a[0],".OPT",4)==0) { for (i=1; i<5; i++) if (strcmp("NOPAGE",a[i])==0) NOPAGE=1; } else if (strcmp(a[0],".PRINT")==0) { /* clear out previous title (yes, it's necessary) */ for (i=0; i<80; i++) anals[numanals].title[i]=' '; strncpy(anals[numanals].title,linebuf,80); numanals++; if (numanals==MAXANAL) numanals--; } else if (strcmp(a[0],".END")==0) break; } return 0; } /************************************************************************/ static int Anals2Labs() /* takes anals array and gets the labels from the titles */ /* labs[0] is filled in automatically by ConvertAnals */ { int i,j,c,done; Anal *ap; if (!numanals) { sprintf(pst,"Unable to find any analyses in this spice file. Loading aborted"); ErrBox(pst,4); return 1; } for (i=0; ilabels[j][0]='\0'; /* split the ".PRINT" line into args, tossing first two */ sscanf(ap->title,"%*s %*s %s %s %s %s %s %s %s %s\n", ap->labels[1], ap->labels[2], ap->labels[3], ap->labels[4], ap->labels[5], ap->labels[6], ap->labels[7], ap->labels[8]); /* numys = (count arguments) */ for (j=1; j<=MYPERANAL; j++) { c = ap->labels[j][0]; if (!isalpha(c)) break; } ap->numys=j-1; } return 0; } /************************************************************************/ static ConvertAnals() /* take anals array and convert the titles to something approaching english */ { int i; char atype[80]; for (i=0; inumpts = getw(tmpfile); if (numpts>MAXPTS) numpts=MAXPTS; for (i=0; inumys,tmpfile); for (j=0; jlabels[0]); for (i=0; ilabels[ind[i]+1]); } /* figure out what the units should be */ switch (theAnal->type) { case DC: units[0]="V"; break; case AC: units[0]="Hz"; break; case TRANS: units[0]="S"; break; } for (i=0; i0; i--) fgets(linebuf,255,outfile); } /**************************************************************************/ int expfname(fname) char *fname; { /* expands ~s in file names. Returns the name in 'name', returns 0 if okay, 1 if error occurred (user name not found) */ struct passwd *entry; char *cp, *sp, *up, uname[64], tmp[256]; if (*fname != '~') return 0; /* doesn't start with a tilde, don't expand */ /* look for the first '/' after the tilde */ sp = index(fname,'/'); if (sp == 0) return 1; /* no '/' after the tilde. Invalid fname */ /* uname equals the string between the ~ and the / */ for (cp=fname+1,up=uname; cppw_dir); strcat(tmp,sp); endpwent(); } strcpy(fname,tmp); /* return expanded file name */ return 0; } \Rogue\Monster\ else echo "will not over write ./xsplot/xsplotio.c" fi if `test ! -s ./xsplot/xsplotmac.c` then echo "writing ./xsplot/xsplotmac.c" cat > ./xsplot/xsplotmac.c << '\Rogue\Monster\' /************************************************************************/ /* xsplotmac.c - Macintosh-like stuff, random graphic routines, */ /* window/subwindow/button creation/redraw */ /*----------------------------------------------------------------------*/ /* InvTitleBar (); */ /* DrawTitleBar (); */ /* CreateMainWindow(name,geom); */ /* CreateSubwindows(); */ /* CreateStuff (); */ /* CreateButtons (); */ /* MakeButton (bnum,win,x,y,w,h,st) */ /* MakeCB (bnum,win,x,y); */ /* MapButtons (); */ /* RedrawIcon (); */ /* RedrawBut (bnum); */ /* RedrawCB (bnum); */ /* RedrawPanel (w,wwidth,str); */ /* RedrawOffPan (); */ /* InvertBut (bnum); */ /* DrawArrs (); */ /* DashLine (window,x1,y1,x2,y2,color,pattern); */ /* SetVertex (vert,x,y,flags); */ /* MakeRect (x1,y1,x2,y2); */ /* Frame (win,x1,y1,x2,y2,width,color,func); */ /************************************************************************/ #include "xsplot.h" #include "cursor" /* nnw arrow cursor */ #include "cursor.mask" /* and mask */ #include "cursx" /* small x-shaped */ #include "cursx.mask" /* cursor and mask */ #include "icon" /* program icon */ #include "titlebar.bm" /* titlebar bitmap */ #include "arrows.h" /* bitmaps for trace location arrows */ /* checkerboard used in mono mode */ static short stip_bits[] = { 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa}; /* cross-weave bitmap */ static short chek_bits[] = { 0x5555, 0x8888, 0x5555, 0x2222, 0x5555, 0x8888, 0x5555, 0x2222, 0x5555, 0x8888, 0x5555, 0x2222, 0x5555, 0x8888, 0x5555, 0x2222}; /* 75% gray */ static short dkgray_bits[] = { 0xaaaa, 0xffff, 0xaaaa, 0xffff, 0xaaaa, 0xffff, 0xaaaa, 0xffff, 0xaaaa, 0xffff, 0xaaaa, 0xffff, 0xaaaa, 0xffff, 0xaaaa, 0xffff}; /***********************************/ InvTitleBar() { tbInvert = !tbInvert; if (tbInvert) { if (mono) XChangeBackground(titleW,gridBpix); else XChangeBackground(titleW,mainBpix); } else XChangeBackground(titleW,mainFpix); XClear(titleW); DrawTitleBar(); } /***********************************/ DrawTitleBar() { int i, cfore, cback; if (tbInvert) XPixmapPut(titleW,0,0,(WIDTH-titlebar_width)/2,0,titlebar_width, titlebar_height, titlePixInv, GXcopy, AllPlanes); else XPixmapPut(titleW,0,0,(WIDTH-titlebar_width)/2,0,titlebar_width, titlebar_height, titlePix, GXcopy, AllPlanes); } /***********************************/ CreateMainWindow(name,geom) char *name,*geom; { char default_geom[20]; OpaqueFrame frame; sprintf (default_geom, "%dx%d+%d+%d",WIDTH,HEIGHT, (DisplayWidth()-WIDTH)/2,(DisplayHeight()-HEIGHT)/2); frame.bdrwidth = 2; frame.border = mainFpix; frame.background = mainBpix; mainW = XCreate("xSplot",name,geom,default_geom,&frame,WIDTH,HEIGHT); if (!mainW) FatalError("Can't open main window"); } /***********************************/ CreateSubwindows() { iconW =XCreateWindow(RootWindow,0,0,icon_width,icon_height,0,0,mainBpix); titleW=XCreateWindow(mainW,-1,-1,WIDTH,20,1,mainFpix,mainFpix); gridW =XCreateWindow(mainW,15-5,50-5,GSIZE+3,GSIZE+3,3,mainFpix,gridBpix); presetW = XCreateWindow(mainW,PREX,PREY,PREW,PREH,1,panFpix, panBpix); traceW = XCreateWindow(mainW,TRAX,TRAY,TRAW,TRAH,1,panFpix, panBpix); scaleW = XCreateWindow(mainW,SCAX,SCAY,SCAW,SCAH,1,panFpix, panBpix); measureW= XCreateWindow(mainW,MSRX,MSRY,MSRW,MSRH,1,panFpix, panBpix); offsetW = XCreateWindow(mainW,OFFX,OFFY,OFFW,OFFH,1,panFpix, panBpix); commandW= XCreateWindow(mainW,OFFX,OFFY,OFFW,OFFH,1,panFpix, panBpix); modifyW = XCreateWindow(mainW,MODX,MODY,MODW,MODH,1,panFpix, panBpix); miscW = XCreateWindow(mainW,MISX,MISY,MISW,MISH,1,panFpix, panBpix); errW = XCreateWindow(mainW,10,HEIGHT-23,WIDTH-20,13,1,errFpix,errBpix); diversW = XCreateWindow(mainW,115-4,100-4,200,300,3,dlgFpix,dlgBpix); LoadDlog= XCreateWindow(mainW,25-3, 150,380,100,3,dlgFpix,dlgBpix); SwitchDlog=XCreateWindow(mainW,115-3,150,200,100,3,dlgFpix,dlgBpix); CurvDlog= XCreateWindow(mainW,115-3,100,200,300,3,dlgFpix,dlgBpix); PlotDlog= XCreateWindow(mainW,25-3, 175,380,70, 3,dlgFpix,dlgBpix); PlotNDlog= XCreateWindow(mainW,25-3, 160,380,100,3,dlgFpix,dlgBpix); HelpDlog= XCreateWindow(mainW,25-3, 125,380,200,3,dlgFpix,dlgBpix); AboutDlog =XCreateWindow(mainW,15-4,50-4,GSIZE,GSIZE,3,mainFpix,gridBpix); XSelectInput(iconW, ExposeWindow); XSelectInput(titleW,ExposeWindow|ButtonPressed); XSelectInput(gridW, ExposeWindow|ButtonPressed|ButtonReleased); XSelectInput(presetW, ExposeWindow); XSelectInput(traceW, ExposeWindow); XSelectInput(scaleW, ExposeWindow); XSelectInput(measureW, ExposeWindow); XSelectInput(offsetW, ExposeWindow); XSelectInput(modifyW, ExposeWindow); XSelectInput(miscW, ExposeWindow); XSelectInput(commandW, ExposeWindow); XSelectInput(errW, ExposeWindow); XSelectInput(diversW, ExposeWindow); XSelectInput(LoadDlog, ExposeWindow|ButtonPressed); XSelectInput(SwitchDlog,ExposeWindow|ButtonPressed); XSelectInput(CurvDlog, ExposeWindow|ButtonPressed); XSelectInput(PlotDlog, ExposeWindow|ButtonPressed); XSelectInput(PlotNDlog, ExposeWindow|ButtonPressed); XSelectInput(HelpDlog, ExposeWindow|ButtonPressed); XSelectInput(AboutDlog, ExposeWindow|ButtonPressed); } /***********************************/ CreateStuff() { Bitmap tmpBits; int i; tmpBits = XStoreBitmap(titlebar_width,titlebar_height,titlebar_bits); titlePix = XMakePixmap (tmpBits,mainFcol,mainBcol); titlePixInv = XMakePixmap (tmpBits,mainBcol,mainFcol); XFreeBitmap(tmpBits); if (mono) { /* panels and main background are stippled in mono mode */ tmpBits = XStoreBitmap(16,16,stip_bits); panBpix = XMakePixmap(tmpBits,ForeColor,BackColor); XFreeBitmap(tmpBits); tmpBits = XStoreBitmap(16,16,chek_bits); mainBpix = XMakePixmap(tmpBits,ForeColor,BackColor); XFreeBitmap(tmpBits); } else { /* but solid color in color mode */ panBpix = XMakeTile(panBcol); mainBpix= XMakeTile(mainBcol); } gridFpix = XMakeTile(gridFcol); gridBpix = XMakeTile(gridBcol); panFpix = XMakeTile(panFcol); butFpix = XMakeTile(butFcol); butBpix = XMakeTile(butBcol); mainFpix = XMakeTile(mainFcol); dlgFpix = XMakeTile(dlgFcol); dlgBpix = XMakeTile(dlgBcol); errFpix = XMakeTile(errFcol); errBpix = XMakeTile(errBcol); for (i=0; i<4; i++) trpix[i] = XMakeTile(trcol[i]); leftmask = XStoreBitmap(arr_width,arr_height,arrl_mask_bits); rightmask = XStoreBitmap(arr_width,arr_height,arrr_mask_bits); upmask = XStoreBitmap(arr_width,arr_height,arru_mask_bits); downmask = XStoreBitmap(arr_width,arr_height,arrd_mask_bits); if (mono) { linepats[0]=XMakePattern(0xffff,16,1); linepats[1]=XMakePattern(0xaaaa,16,1); linepats[2]=XMakePattern(0xcccc,16,1); linepats[3]=XMakePattern(0xbbbb,16,1); } RBoxPat[0]=XMakePattern(0xc0,8,2); RBoxPat[1]=XMakePattern(0x30,8,2); RBoxPat[2]=XMakePattern(0x0c,8,2); RBoxPat[3]=XMakePattern(0x03,8,2); GridPat2=XMakePattern(PAT2,16,1); GridPat4=XMakePattern(PAT4,16,1); arrow=XCreateCursor(cursor_width,cursor_height,cursor_bits, cursor_mask_bits,cursor_x_hot,cursor_y_hot,mainFcol,mainBcol,GXcopy); cursx=XCreateCursor(cursx_width,cursx_height,cursx_bits, cursx_mask_bits,cursx_x_hot,cursx_y_hot,mainFcol,mainBcol,GXcopy); } /***********************************/ CreateButtons() { #define BH 19 int i; MakeButton(&butts[ 0],scaleW,24,16, 68,BH,"linear",butfinfo); MakeButton(&butts[ 1],scaleW,24,16+BUTH,68,BH,"linear",butfinfo); for (i=0; i<5; i++) { MakeButton(&butts[i*2+2],offsetW,60, 16+BUTH*i,65,BH,"",butfinfo); MakeButton(&butts[i*2+3],offsetW,60+70,16+BUTH*i,65,BH,"",butfinfo); } MakeButton(&butts[12],modifyW,5, 16, 87,BH,"Reset",butfinfo); MakeButton(&butts[13],modifyW,5, 16+BUTH, 41,BH,"<-", butfinfo); MakeButton(&butts[14],modifyW,51,16+BUTH, 41,BH,"->", butfinfo); MakeButton(&butts[15],modifyW,5, 16+BUTH*2,41,BH,"<<-", butfinfo); MakeButton(&butts[16],modifyW,51,16+BUTH*2,41,BH,"->>", butfinfo); MakeButton(&butts[17],modifyW,5, 16+BUTH*3,41,BH,"<<<-", butfinfo); MakeButton(&butts[18],modifyW,51,16+BUTH*3,41,BH,"->>>", butfinfo); MakeButton(&butts[22],miscW,5,16, 87,BH,"Commands",butfinfo); MakeButton(&butts[21],miscW,5,16+BUTH, 87,BH,"Y-Lock", butfinfo); MakeButton(&butts[20],miscW,5,16+BUTH*2,87,BH,"Undo", butfinfo); MakeButton(&butts[19],miscW,5,16+BUTH*3,87,BH,"Redraw", butfinfo); MakeButton(&butts[25],commandW,5, 16, 190,BH,"Load Data File", butfinfo); MakeButton(&butts[24],commandW,5, 16+BUTH, 190,BH,"Switch Analysis",butfinfo); MakeButton(&butts[26],commandW,5, 16+BUTH*2,92, BH,"Curves", butfinfo); MakeButton(&butts[23],commandW,5+98,16+BUTH*2,92, BH,"Big Picture", butfinfo); MakeButton(&butts[38],commandW,5, 16+BUTH*3,92, BH,"Plot", butfinfo); MakeButton(&butts[39],commandW,5+98,16+BUTH*3,92, BH,"Help", butfinfo); MakeButton(&butts[27],commandW,5, 16+BUTH*4,92, BH,"Digital", butfinfo); MakeButton(&butts[37],commandW,5+98,16+BUTH*4,92, BH,"Quit", butfinfo); MakeButton(&butts[28],presetW,5, 16,15,BH,"1", butfinfo); MakeButton(&butts[29],presetW,5+20, 16,15,BH,"2", butfinfo); MakeButton(&butts[30],presetW,5+40, 16,15,BH,"3", butfinfo); MakeButton(&butts[31],presetW,5+60, 16,15,BH,"4", butfinfo); MakeButton(&butts[32],presetW,5+80, 16,15,BH,"5", butfinfo); MakeButton(&butts[33],presetW,5+100,16,15,BH,"6", butfinfo); MakeButton(&butts[34],presetW,5+120,16,15,BH,"7", butfinfo); MakeButton(&butts[35],presetW,5+140,16,15,BH,"8", butfinfo); MakeButton(&butts[36],presetW,5+160,16,30,BH,"Set",butfinfo); MakeCB(0,measureW,5, 16); MakeCB(1,measureW,5+CBW+5,16); MakeCB(2,measureW,5, 16+CBH+5); MakeCB(3,measureW,5+CBW+5,16+CBH+5); } /********************/ MakeButton(bp,win,x,y,w,h,st,bfinf) Button *bp; Window win; short x,y,w,h; char *st; FontInfo *bfinf; /********************/ { bp->win = XCreateWindow(win,x,y,w-4,h-4,2,butFpix,butBpix); bp->x = x+2; bp->y = y+2; bp->w = w-4; bp->h = h-4; bp->st = st; bp->invert=0; bp->finfo = bfinf; XSelectInput(bp->win,ExposeWindow|ButtonPressed|ButtonReleased); } /********************/ MakeCB(bnum,win,x,y) int bnum; Window win; short x,y; /********************/ { if (mono) CButts[bnum].win = XCreateWindow(win,x,y,CBW-4,CBH-4,2,butFpix,butBpix); else CButts[bnum].win = XCreateWindow(win,x,y,CBW-4,CBH-4,2, butFpix,trpix[bnum]); XSelectInput(CButts[bnum].win,ExposeWindow|ButtonPressed); } /********************/ MapButtons() { int i; for (i=0; ist,bp->finfo,0,0); if (bp->invert) { textc=butBcol; backc=butFcol; } else { textc=butFcol; backc=butBcol; } XClear(bp->win); XText(bp->win,(bp->w-width)/2,(bp->h - bp->finfo->height)/2, bp->st, strlen(bp->st), bp->finfo->id, textc, backc); } /********************/ RedrawCB(bnum) int bnum; { int width, textc, backc; Window w; w = CButts[bnum].win; XClear(w); if (mono) DashLine(w,1,(CBH-4)/2,CBW-5,(CBH-4)/2,ForeColor,linepats[bnum]); if (bnum==selCB) Frame(w,0,0,CBW-5,CBH-5,2,butFcol,GXcopy); } /********************/ RedrawPanel(w,wwidth,str) Window w; int wwidth; char *str; { static char *gridlab[2]={"X:","Y:"}; int swidth,i,y; swidth = XStringWidth(str,butfinfo,0,0); XPixSet(w,0,0,wwidth,11,panFcol); XText(w,(wwidth-swidth)/2,0,str,strlen(str),butfont,panBcol,panFcol); if (w==traceW) DrawArrs(); else if (w==scaleW) { for (i=0; i<2; i++) { /* labels */ y=16+i*24; if (mono) { XPixSet(scaleW,5,y,14,19,BackColor); XLine (scaleW,5,y, 18,y, 1,1,ForeColor,GXcopy,AllPlanes); XLine (scaleW,5,y+18,18,y+18,1,1,ForeColor,GXcopy,AllPlanes); } XTextMask(scaleW,5,y+4,gridlab[i],strlen(gridlab[i]), butfont,panFcol); } } } /********************/ RedrawOffPan() { #define S1 "Offset" #define S2 "Range" int swidth,i,y; XPixSet(offsetW,0,0,OFFW,11,panFcol); swidth = XStringWidth(S1,butfinfo,0,0); XText(offsetW,60+(65-swidth)/2,0,S1,strlen(S1),butfont,panBcol,panFcol); swidth = XStringWidth(S2,butfinfo,0,0); XText(offsetW,60+70+(65-swidth)/2,0,S2,strlen(S2),butfont,panBcol,panFcol); for (i=0; i<=numy; i++) { /* labels */ char *st; y=16+i*24; if (mono) { XPixSet(offsetW,5,y,50,19,BackColor); XLine(offsetW,5,y, 54,y, 1,1,ForeColor,GXcopy,AllPlanes); XLine(offsetW,5,y+18,54,y+18,1,1,ForeColor,GXcopy,AllPlanes); } if (i) st = ylist[i-1].label; else st = xlist.label; if (i) XTextMask(offsetW,5,y+4,st,strlen(st),butfont,trcol[i-1]); else XTextMask(offsetW,5,y+4,st,strlen(st),butfont,panFcol); if (mono && i) { DashLine(offsetW, 6, y+2, 53, y+2, ForeColor,linepats[i-1]); DashLine(offsetW, 6, y+16, 53, y+16, ForeColor,linepats[i-1]); } } } /********************/ InvertBut(bp) Button *bp; { bp->invert = ~(bp->invert); if (bp->invert) XChangeBackground(bp->win,butFpix); else XChangeBackground(bp->win,butBpix); XClear(bp->win); RedrawBut(bp); XFlush(); } /*********************/ DrawArrs() { int fc, bc; fc=trcol[selCB]; bc=gridBcol; if (LeftArr) XBitmapBitsPut(traceW,15,16,arr_width,arr_height,arrl_bits, fc,fc,leftmask,GXcopy,AllPlanes); else XBitmapBitsPut(traceW,15,16,arr_width,arr_height,arrl_bits, bc,fc,leftmask,GXcopy,AllPlanes); if (RightArr) XBitmapBitsPut(traceW,65,16,arr_width,arr_height,arrr_bits, fc,fc,rightmask,GXcopy,AllPlanes); else XBitmapBitsPut(traceW,65,16,arr_width,arr_height,arrr_bits, bc,fc,rightmask,GXcopy,AllPlanes); if (UpArr[selCB]) XBitmapBitsPut(traceW,115,16,arr_width,arr_height,arru_bits, fc,fc,upmask,GXcopy,AllPlanes); else XBitmapBitsPut(traceW,115,16,arr_width,arr_height,arru_bits, bc,fc,upmask,GXcopy,AllPlanes); if (DownArr[selCB]) XBitmapBitsPut(traceW,165,16,arr_width,arr_height,arrd_bits, fc,fc,downmask,GXcopy,AllPlanes); else XBitmapBitsPut(traceW,165,16,arr_width,arr_height,arrd_bits, bc,fc,downmask,GXcopy,AllPlanes); } /***************************/ DashLine(w,x1,y1,x2,y2,color,pattern) /* draws a Dashed line in window w */ Window w; short x1,y1,x2,y2; int color; Pattern pattern; { Vertex verts[2]; SetVertex(&verts[0],x1,y1,0); SetVertex(&verts[1],x2,y2,0); XDrawDashed(w,verts,2,1,1,color,pattern,GXcopy,AllPlanes); } /****************************/ SetVertex(vert,x,y,flags) Vertex *vert; short x,y; unsigned short flags; { vert->x=x; vert->y=y; vert->flags=flags; } /****************************/ MakeRect(x1,y1,x2,y2) int x1,y1,x2,y2; { /* stores the four lines that make the rectangle in the first five elements of 'curve', for use with XDraw */ SetVertex(curve, x1,y1,0); SetVertex(curve+1,x1,y2,0); SetVertex(curve+2,x2,y2,0); SetVertex(curve+3,x2,y1,0); SetVertex(curve+4,x1,y1,0); } /****************************/ Frame(win,x1,y1,x2,y2,w,color,func) /* draws a rectangle of thickness 'w' */ Window win; /* from x1,y1 to x2,y2 */ short x1,y1,x2,y2; int color,w,func; { short tmp,wide,high; int planes; if (func==GXinvert) { if (mono) planes=1; else planes=selCB+4; } else planes=AllPlanes; /* get x1,y1 to be top left, and x2,y2 to be bot right */ if (x2 ./splotter/color.h << '\Rogue\Monster\' /* Color definitions. */ #define NONE 0 #define RED 1 #define GREEN 2 #define BLUE 3 #define BLACK 4 #define BROWN 5 #define ORANGE 6 #define VIOLET 7 #define FT_BLACK 8 /* Defined trace color order, a la SPLOT. */ #define FIRST_C GREEN #define SECOND_C RED #define THIRD_C BLUE #define FOURTH_C ORANGE \Rogue\Monster\ else echo "will not over write ./splotter/color.h" fi if `test ! -s ./splotter/lines.h` then echo "writing ./splotter/lines.h" cat > ./splotter/lines.h << '\Rogue\Monster\' /* Line type data and definitions. */ #define TYPE_MASK 0xffff0000 #define VAL_MASK 0x0000ffff #define SOLID 0x00010000 #define THICK 0x00020000 #define DOT_2 0x00040000 #define DOT_4 0x00080000 int y_divs[] = { 0, SOLID| 40, SOLID| 80, SOLID|120, SOLID|160, THICK|200, SOLID|240, SOLID|280, SOLID|320, SOLID|360, 0 }; int x_divs[7][51] = { { 0, SOLID| 40, SOLID| 80, SOLID|120, SOLID|160, THICK|200, SOLID|240, SOLID|280, SOLID|320, SOLID|360, 0 }, { 0, SOLID|120, SOLID|191, SOLID|241, SOLID|280, SOLID|311, SOLID|338, SOLID|361, SOLID|382, 0 }, { 0, SOLID| 40, SOLID| 64, SOLID| 80, SOLID| 93, SOLID|104, SOLID|113, SOLID|120, SOLID|127, THICK|133, SOLID|173, SOLID|197, SOLID|214, SOLID|227, SOLID|237, SOLID|246, SOLID|254, SOLID|261, THICK|267, SOLID|307, SOLID|330, SOLID|347, SOLID|360, SOLID|370, SOLID|379, SOLID|387, SOLID|394, 0 }, { 0,SOLID|19, SOLID|28, SOLID|34, SOLID|38, THICK|40, SOLID|40 +19,SOLID|40 +28,SOLID|40 +34,SOLID|40 +38,THICK|80, SOLID|80 +19,SOLID|80 +28,SOLID|80 +34,SOLID|80 +38,THICK|120, SOLID|120+19,SOLID|120+28,SOLID|120+34,SOLID|120+38,THICK|160, SOLID|160+19,SOLID|160+28,SOLID|160+34,SOLID|160+38,THICK|200, SOLID|200+19,SOLID|200+28,SOLID|200+34,SOLID|200+38,THICK|240, SOLID|240+19,SOLID|240+28,SOLID|240+34,SOLID|240+38,THICK|280, SOLID|280+19,SOLID|280+28,SOLID|280+34,SOLID|280+38,THICK|320, SOLID|320+19,SOLID|320+28,SOLID|320+34,SOLID|320+38,THICK|360, SOLID|360+19,SOLID|360+28,SOLID|360+34,SOLID|360+38,0}, { 0, SOLID|120, SOLID|191, SOLID|241, SOLID|280, SOLID|311, SOLID|338, SOLID|361, SOLID|382, 0 }, { 0, SOLID| 40, SOLID| 64, SOLID| 80, SOLID| 93, SOLID|104, SOLID|113, SOLID|120, SOLID|127, THICK|133, SOLID|173, SOLID|197, SOLID|214, SOLID|227, SOLID|237, SOLID|246, SOLID|254, SOLID|261, THICK|267, SOLID|307, SOLID|330, SOLID|347, SOLID|360, SOLID|370, SOLID|379, SOLID|387, SOLID|394, 0 }, { 0,SOLID|19, SOLID|28, SOLID|34, SOLID|38, THICK|40, SOLID|40 +19,SOLID|40 +28,SOLID|40 +34,SOLID|40 +38,THICK|80, SOLID|80 +19,SOLID|80 +28,SOLID|80 +34,SOLID|80 +38,THICK|120, SOLID|120+19,SOLID|120+28,SOLID|120+34,SOLID|120+38,THICK|160, SOLID|160+19,SOLID|160+28,SOLID|160+34,SOLID|160+38,THICK|200, SOLID|200+19,SOLID|200+28,SOLID|200+34,SOLID|200+38,THICK|240, SOLID|240+19,SOLID|240+28,SOLID|240+34,SOLID|240+38,THICK|280, SOLID|280+19,SOLID|280+28,SOLID|280+34,SOLID|280+38,THICK|320, SOLID|320+19,SOLID|320+28,SOLID|320+34,SOLID|320+38,THICK|360, SOLID|360+19,SOLID|360+28,SOLID|360+34,SOLID|360+38,0} }; \Rogue\Monster\ else echo "will not over write ./splotter/lines.h" fi if `test ! -s ./splotter/makefile` then echo "writing ./splotter/makefile" cat > ./splotter/makefile << '\Rogue\Monster\' CFLAGS = -g splotter: splotter.o cc ${CFLAGS} -o splotter splotter.o splotter.o: scaling.h lines.h plot.h color.h \Rogue\Monster\ else echo "will not over write ./splotter/makefile" fi if `test ! -s ./splotter/plot.h` then echo "writing ./splotter/plot.h" cat > ./splotter/plot.h << '\Rogue\Monster\' #define pen_up() fprintf(out, "PU") #define pen_down() fprintf(out, "PD") #define plot_to(x, y) fprintf(out, "PA%d,%d;", x, y) #define rplot_to(x, y) fprintf(out, "PR%d,%d;", x, y) #define fplot_to(x, y) fprintf(out, "PA%f,%f;", x, y) #define select_pen(x) if(pc != x) {fprintf(out, "SP%d;", x); pc = x;} #define def_line() fprintf(out, "LT;") #define line_type(x,y) fprintf(out, "LT%d,%d;", x, y) #define clip_set() fprintf(out, "IW%d,%d,%d,%d;", 0, 0, (int)RBOX_SIZE,\ (int)RBOX_SIZE) #define clip_clear() fprintf(out, "IW;") #define set_slow() fprintf(out, "VS5;") #define set_fast() fprintf(out, "VS30;") #define low_acc() fprintf(out, "AS1;") #define high_acc() fprintf(out, "AS;") /* Label functions. */ #define label(l) fprintf(out, "LB%s\003", l) #define flabel(l) fprintf(out, "LB%f\003", l) #define label_2(m, e) fprintf(out, "LB%de2^%d\003", m, e) #define label_10(m, e) fprintf(out, "LB%de10^%d\003", m, e) #define label_size(s) fprintf(out, "SR%f,%f;", s, s) #define label_origin(s) fprintf(out, "LO%d;", s) #define horiz_label() fprintf(out, "DI;") #define vert_label() fprintf(out, "DI0,-1;") \Rogue\Monster\ else echo "will not over write ./splotter/plot.h" fi if `test ! -s ./splotter/scaling.h` then echo "writing ./splotter/scaling.h" cat > ./splotter/scaling.h << '\Rogue\Monster\' /* These definitions are for defining paper scaling. */ /* Paper space definitions. */ #define BORDER 500.0 #define RBOX_SIZE 400.0 #define ADJUST 250.0 /* Tick mark constants. */ #define MINOR_TICK 3 #define NUM_TICKS 50 #define TICK_MOD 5 #define TICK_DIST (int)(RBOX_SIZE/NUM_TICKS) /* Misc. scaling definitions. */ #define X_RANGE (MAXX - MINX) #define Y_RANGE (MAXY - MINY) #define BOX_SIZE (Y_RANGE - 2.0 * BORDER) #define G_R (RBOX_SIZE/BOX_SIZE) #define BO_x ( (X_RANGE - BOX_SIZE) / 2.0 + MINX) #define BO_y ( (Y_RANGE - BOX_SIZE) / 2.0 + MINY) /* Scaled P1 and P2 values. */ #define P1Rx (MINX - BO_x + (asize?0:ADJUST)) #define P2Rx (MAXX - BO_x + (asize?0:ADJUST)) #define P1Ry (MINY - BO_y - (asize?ADJUST:0)) #define P2Ry (MAXY - BO_y - (asize?ADJUST:0)) /* Header labeling constants. */ #define H_LABEL_SIZE 2.0 #define FNAME_Y 430 #define ANNAME_Y 415 #define H_O_TYPE 5 /* Axis labeling constants. */ #define A_LABEL_SIZE .5 #define A_O_TYPE 5 #define CLOSE_OFF 50 #define FAR_OFF 100 #define X_OFF -40 \Rogue\Monster\ else echo "will not over write ./splotter/scaling.h" fi if `test ! -s ./splotter/splotter.c` then echo "writing ./splotter/splotter.c" cat > ./splotter/splotter.c << '\Rogue\Monster\' #include #include "scaling.h" #include "plot.h" #include "lines.h" #include "color.h" #define DISPLAY_FILE "/usr/vlsi/berk/lib/displays" /* Misc. definitions. */ #define MAX_TRACES 4 #define MAX_POINTS 900 #define BUF_SIZE 256 /* Paper size defintions, a la P1 and P2. */ /* For A size paper defaults. */ float MINY = 320.0; float MAXY = 7520.0; float MINX = 80.0; float MAXX = 10080.0; int asize = 1; typedef union f_i{ float f; int i; } F_I; typedef struct axis_des { F_I offset, range; } AXIS_DES; AXIS_DES x_axis_des; AXIS_DES y_axis_des[MAX_TRACES]; /* Pen color. */ int pc; char * plotter = "plot1"; char f_name[BUF_SIZE]; char an_name[BUF_SIZE]; int grid_type; int num_traces; int * traces; int * x_trace; int num_read; FILE * out; int is_tty; main(argc, argv) /* Process command line arguments. * Allocate data, open files, * call routines. */ int argc; char ** argv; { char * get_display(); char * in_fname = NULL, * out_fname = NULL; char * arg_ptr; /* Pointer to command args. */ /* Process command line arguments. */ for(argv++; *argv != NULL; argv++) if( *(arg_ptr = *argv) == '-') while(*++arg_ptr != '\0') switch(*arg_ptr){ case 'i': in_fname = *++argv; break; case 'o': out_fname = *++argv; break; case 'a': MINX = 80.0; MAXX = 10080.0; MINY = 320.0; MAXY = 7520.0; asize = 1; break; case 'b': MINX = 620.0; MAXX = 15820.0; MINY = 80; MAXY = 10080; asize = 0; break; case 'p': plotter = *++argv; break; } if(in_fname == NULL) in_fname = get_display(); if(strcmp(in_fname, "-")) if( freopen(in_fname, "r", stdin) == NULL) error("can't open %s\n", in_fname); read_data(); #ifdef PDEBUG print_data(); #endif if(out_fname == NULL){ char command[BUF_SIZE]; sprintf(command, "lpr -P%s -J \"%s\" -T \"%s\"", plotter, f_name, an_name); if((out = popen(command, "w")) == NULL) error("pipe error to printer - help\n"); } else if(strcmp(out_fname, "-")){ if( (out = fopen(out_fname, "w")) == NULL) error("can't open %s\n", out_fname); } else out = stdout; is_tty = isatty(out->_file); if(is_tty) init_plot(); startup(); set_grid(); plot_grid(); label_grid(); plot_traces(); label_it(); select_pen(NONE); closeup(); } char * get_display(str) { char line[BUF_SIZE]; FILE * f; char text_d[BUF_SIZE], disp_d[BUF_SIZE]; char * ttyname(); char * tty; if((f = fopen(DISPLAY_FILE, "r")) == NULL) error("can't open display file %s\n", DISPLAY_FILE); if( (tty = ttyname(0)) == NULL ) error("can't find my ttyname\n"); while(fgets(line, BUF_SIZE, f) != NULL){ if(sscanf(line, "%s %s", text_d, disp_d) != 2) error("display file format error\n"); if(!strcmp(text_d, tty)){ if((tty = (char *)malloc(strlen(disp_d + 1))) == NULL) error("memory error\n"); strcpy(tty, disp_d); return(tty); } } error("can't find text %s in display file\n", tty); } init_plot() { fprintf(out, "\33.J\33.@1024;2:\33.P1:"); fprintf(out, "\33.N;19:\33.I300;;17:\33.M;;;10:"); } startup() { /* Set plotter up. */ fprintf(out, "\33.(RO;DFIP;AP5;"); } closeup() { /* Close plotter up. */ fprintf(out, "DFPG1;\33.)"); } set_grid() { fprintf(out, "IP%d,%d,%d,%d;", (int)MINX, (int)MINY, (int)MAXX, (int)MAXY); fprintf(out, "SC%.2f,%.2f,%.2f,%.2f;", P1Rx*G_R,P2Rx*G_R,P1Ry*G_R,P2Ry*G_R); } read_data() { int i; int j; int * x_ptr, * t_ptr; if(gets(f_name) == NULL) error("error reading file name\n", 0); if(gets(an_name) == NULL) error("error reading analysis name\n", 0); if(scanf("%d ", &grid_type) != 1) error("error reading grid type\n", 0); if(scanf("%d ", &num_traces) != 1) error("error reading number of traces\n", 0); switch(grid_type){ case 0: if(scanf("%f %f ", &x_axis_des.offset.f, &x_axis_des.range.f) != 2) error("error reading x-axis\n"); break; case 1: case 2: case 3: if(scanf("10^%d %d ", &x_axis_des.offset.i, &x_axis_des.range.i) != 2) error("error reading x-axis\n"); break; case 4: case 5: case 6: if(scanf("2^%d %d ", &x_axis_des.offset.i, &x_axis_des.range.i) != 2) error("error reading x-axis\n"); break; default: error("internal error - help\n"); break; } for(i = 0; i < num_traces; i++) if( scanf("%f %f ", &y_axis_des[i].offset.f, &y_axis_des[i].range.f) != 2) error("error reading y-axis\n"); if( (x_trace = (int *)calloc(MAX_POINTS, sizeof(int))) == NULL) error("memory error - help\n", 0); if((traces = (int *)calloc(MAX_POINTS*num_traces,sizeof(int))) == NULL) error("memory error - help\n", 0); for(x_ptr = x_trace, t_ptr = traces, i = 0, num_read = 0; i < MAX_POINTS; i++, num_read++, x_ptr++){ if(scanf("%d ", x_ptr) != 1) break; for(j = 0; j < num_traces; j++, t_ptr++) if(scanf("%d ", t_ptr) != 1) error("format error last line\n"); } } #ifdef PDEBUG print_data() { int i; int j; fprintf(stderr, "%s\n%s\n%d\n%d\n", f_name, an_name, grid_type, num_traces); switch(grid_type){ case 0: fprintf(stderr, "%f %f\n", x_axis_des.offset.f, x_axis_des.range.f); break; case 1: case 2: case 3: fprintf(stderr, "10^%d %d\n", x_axis_des.offset.i, x_axis_des.range.i); break; case 4: case 5: case 6: fprintf(stderr, "2^%d %d\n", x_axis_des.offset.i, x_axis_des.range.i); break; default: error("debug error - help\n"); break; } for(i = 0; i < num_traces; i++) fprintf(stderr, "%f %f\n", y_axis_des[i].offset.f, y_axis_des[i].range.f); for(i = 0; i < num_read; i++){ fprintf(stderr, "%d ", x_trace[i]); for(j = 0; j < num_traces; j++) fprintf(stderr, "%d ", traces[j][i]); fprintf(stderr, "\n"); } } #endif plot_grid() { int i; int coord; float f_coord; int l_type; int sw = 0; int *l_ptr; set_fast(); low_acc(); /* Draw Box. */ select_pen(BLACK); plot_to(0,0); draw_rbox((int)RBOX_SIZE); fplot_to(-.5, -.5); draw_rbox((int)RBOX_SIZE + 1); plot_to(-1,-1); draw_rbox((int)RBOX_SIZE+2); /* Draw Y grid. */ for(l_ptr = &y_divs[1]; *l_ptr; l_ptr++){ coord = VAL_MASK & *l_ptr; f_coord = (float)coord; l_type = TYPE_MASK & *l_ptr; if(!sw){ plot_to(0, coord); fline_to(0.0, f_coord, RBOX_SIZE, f_coord, l_type); } else{ plot_to((int)RBOX_SIZE, coord); fline_to(RBOX_SIZE, f_coord, 0.0, f_coord, l_type); } sw = !sw; } /* Draw X grid. */ for(l_ptr = &x_divs[grid_type][1]; *l_ptr; l_ptr++){ coord = VAL_MASK & *l_ptr; f_coord = (float)coord; l_type = TYPE_MASK & *l_ptr; if(!sw){ plot_to(coord, 0); fline_to(f_coord, 0.0, f_coord, RBOX_SIZE, l_type); } else{ plot_to(coord, (int)RBOX_SIZE); fline_to(f_coord, RBOX_SIZE, f_coord, 0.0, l_type); } sw = !sw; } if(!grid_type){ /* Must do tick marks for linear grid. */ def_line(); select_pen(BLACK); set_slow(); for(i = 1; i < NUM_TICKS; i++) if(i%TICK_MOD){ plot_to(i*TICK_DIST, (int)RBOX_SIZE/2-MINOR_TICK); pen_down(); plot_to(i*TICK_DIST, (int)RBOX_SIZE/2+MINOR_TICK); pen_up(); } else{ /* don't plot major tick marks */ } for(i = 1; i < NUM_TICKS; i++) if(i%TICK_MOD){ plot_to((int)RBOX_SIZE/2-MINOR_TICK, i*TICK_DIST); pen_down(); plot_to((int)RBOX_SIZE/2+MINOR_TICK, i*TICK_DIST); pen_up(); } else{ /* don't plot major tick marks */ } } set_fast(); high_acc(); } label_grid() { int i, j; int * l_ptr; float label_acc, label_inc; int m, e; int label_loc = X_OFF; label_origin(A_O_TYPE); label_size(A_LABEL_SIZE); vert_label(); select_pen(BLACK); l_ptr = &x_divs[grid_type][1]; switch(grid_type){ case 0: label_inc = x_axis_des.range.f; label_acc = x_axis_des.offset.f - 4 * label_inc; for(i = 0; i < 9; i++, l_ptr++){ plot_to(VAL_MASK & *l_ptr, label_loc); flabel(label_acc); label_acc += label_inc; } break; case 1: e = x_axis_des.offset.i; for(i = 2; i < 10; i++, l_ptr++){ plot_to(VAL_MASK & *l_ptr, label_loc); label_10(i, e); } break; case 2: e = x_axis_des.offset.i; for(i = 0; i < 3; i++, e++) for(j = (i?1:2); j < 10; j++, l_ptr++){ plot_to(VAL_MASK & *l_ptr, label_loc); label_10(j, e); } break; case 3: e = x_axis_des.offset.i + 1; for(i = 1; i < 10; i++, e++, l_ptr++){ l_ptr += 4; plot_to(VAL_MASK & *l_ptr, label_loc); label_10(1, e); } break; case 4: e = x_axis_des.offset.i; for(i = 2; i < 10; i++, l_ptr++){ plot_to(VAL_MASK & *l_ptr, label_loc); label_2(i, e); } break; case 5: e = x_axis_des.offset.i; for(i = 0; i < 3; i++, e++) for(j = (i?2:1); j < 10; j++, l_ptr++){ plot_to(VAL_MASK & *l_ptr, label_loc); label_2(j, e); } break; case 6: e = x_axis_des.offset.i + 1; for(i = 1; i < 10; i++, e++, l_ptr++){ l_ptr += 4; plot_to(VAL_MASK & *l_ptr, label_loc); label_2(1, e); } break; } } plot_traces() { int i, j; int * t_ptr, * x_ptr, * l_ptr; float label_acc, label_inc; int label_loc; low_acc(); set_slow(); label_size(A_LABEL_SIZE); label_origin(A_O_TYPE); horiz_label(); for(i = 0; i < num_traces; i++){ switch(i){ case 0: select_pen(FIRST_C); break; case 1: select_pen(SECOND_C); break; case 2: select_pen(THIRD_C); break; case 3: select_pen(FOURTH_C); break; default: select_pen(RED); break; } x_ptr = x_trace; t_ptr = traces + i; plot_to(*x_ptr, *t_ptr); pen_down(); clip_set(); for(j = 1; j < num_read; j++){ x_ptr++; t_ptr += num_traces; plot_to(*x_ptr, *t_ptr); } for(j -= 2; j >= 0; j--){ x_ptr--; t_ptr -= num_traces; plot_to(*x_ptr, *t_ptr); } clip_clear(); pen_up(); switch(i){ case 0: label_loc = -CLOSE_OFF; break; case 1: label_loc = (int)RBOX_SIZE + CLOSE_OFF; break; case 2: label_loc = -FAR_OFF; break; case 3: label_loc = (int)RBOX_SIZE + FAR_OFF; break; } label_inc = y_axis_des[i].range.f; label_acc = y_axis_des[i].offset.f - 4 * label_inc; for(l_ptr = &y_divs[1]; *l_ptr; l_ptr++){ plot_to(label_loc, VAL_MASK & *l_ptr); flabel(label_acc); label_acc += label_inc; } } high_acc(); set_fast(); } label_it() { label_size(H_LABEL_SIZE); label_origin(H_O_TYPE); select_pen(VIOLET); plot_to((int)(RBOX_SIZE/2.0), FNAME_Y); label(f_name); plot_to((int)(RBOX_SIZE/2.0), ANNAME_Y); label(an_name); } draw_rbox(size) int size; { pen_down(); rplot_to(size, 0); rplot_to(0, size); rplot_to(-size, 0); rplot_to(0, -size); pen_up(); } line_to(x, y, type) int x, y, type; { int tpc; int slow = 1; if(type != -1) switch(type){ case DOT_2: line_type(-2, 1); set_slow(); break; case DOT_4: tpc = pc; select_pen(FT_BLACK); line_type(-1, 1); set_slow(); break; case SOLID: default: def_line(); slow = 0; break; } pen_down(); plot_to(x, y); pen_up(); if(type == DOT_4) select_pen(tpc); if(slow) set_fast(); } fline_to(xf, yf, xt, yt, type) float xf, yf, xt, yt; int type; { int tpc; int slow = 1; if(type != -1) switch(type){ case DOT_2: line_type(-2, 1); set_slow(); break; case DOT_4: tpc = pc; select_pen(FT_BLACK); line_type(-1, 1); set_slow(); break; case SOLID: case THICK: default: def_line(); slow = 0; break; } pen_down(); if(type == THICK) if(xf == xt){ /* Verticla line. */ fplot_to(xf - (float).5, yt); fplot_to(xt - (float).5, yt); fplot_to(xt, yt); fplot_to(xf, yf); fplot_to(xf + (float).5, yf); fplot_to(xt + (float).5, yt); } else{ /* Horizontal line. */ fplot_to(xf, yf - (float).5); fplot_to(xt, yt - (float).5); fplot_to(xt, yt); fplot_to(xf, yf); fplot_to(xf, yf + (float).5); fplot_to(xt, yt + (float).5); } else fplot_to(xt, yt); pen_up(); if(type == DOT_4) select_pen(tpc); if(slow) set_fast(); } error(str, num) char * str; int num; { fprintf(stderr, str, num); exit(1); } \Rogue\Monster\ else echo "will not over write ./splotter/splotter.c" fi if `test ! -s ./splotter/splotter.l` then echo "writing ./splotter/splotter.l" cat > ./splotter/splotter.l << '\Rogue\Monster\' .TH SPLOTTER local .UC 4 .SH NAME splotter \- plot spif format file (from splot) on HPGL plotters .SH SYNTAX .B splotter [ .B -ioabcr ] [ arguments... ] .br .SH DESCRIPTION .PP .I Splotter takes as input a file in .B spif format. .B Spif is a specialized intermediate file format for plotting .B SPICE output. .B Spif was developed at the .B Digital .B Systems .B Laboratory, .B University .B of .B Pennsylvania. .B Spif files are generated by .I splot, a program distributed by the .B DSL. .PP The simplest usage of .I splotter is described in this paragraph, and the following paragraphs describe more advanced features. To generate .B spif files, one must use the .I plot command in .I splot. For simple operation, select the serial line option from the .I plot command. This will send the .B spif file to the text terminal associated with the graphics display that .I splot is running on. So, from the text terminal, type the command .I 'splotter'. Then from within .I splot, plot to the serial line. Whatever was on the .I splot display window will magically appear at the plotter. That's all there is to it. Please note that this trick only works with text-display pairs that are hardwired and specified in the file ~cad/lib/displays. .PP There are several options to .I splotter as follows: .TP .B -i The folowing argument is taken as the input .B spif file. The default is the graphics display specified in ~cad/lib/displays. .TP .B -o The following argument is taken as the output file. The default is to spool to the plotter. The defualt plotter is called .I 'plot1'. .TP .B -a .I Splotter will assume 'A' size paper. This is the default. .TP .B -h Print a banner page. If not asserted, the users name - as specified in the .I gcos field of the password entry - and time are printed on the plot. The default is to not print the banner page. .TP .B -b .I Splotter will assume 'B' size paper. .B -a is the default. .TP .B -p The following argument is taken as the name of the plotter to spool to, if the .B -o option is not used. The default is .I 'plot1'. .TP .B -c Do not clip the traces to the grid window. This option is for plotters which do not clip properly. If the plot comes out without the traces, try this option. The default is to clip. .TP .B -r The following argument specifies the number of times the traces are drawn. Each time a trace is drawn, it is drawn forwards and backwards. The default is one. .TP .B -u The filename specified by the -i option is unlinked after it is printed. .PP .I Splotter supports a number of environment settings for tailoring it to the user's likes. The environment variable is called .I 'SPLOTOPTS'. It has the form 'option=value,option=value,....'. Do not use any extra spaces in the specification. The following environment options are available: .TP 10 .B slow Sets the slow plotter speed for drawing traces. The acceptable range is 5 to 80 cm/s. The default is 5. .TP 10 .B fast Sets the fast speed for the plotter. The range is 5 to 80 cm/s. The default is 30. .TP 10 .B penX Sets the pen color of trace number X. Legal pens are pen1, pen2, pen3, pen4. See below for color values. The respective defaults are green, red, blue, and orange. .TP 10 .B gridc Sets the pen color for drawing the grid. See below for color values. The default is black. .TP 10 .B gridl Sets the pen color for labeling the x-axis of the grid. See below for color values. The default is black. .TP 10 .B namec Sets the pen color for drawing the users name and time if the .B -h option is not specified. See below for color values. The default is brown. .TP 10 .B headc Sets the pen color for drawing the header strings. These are the name of the file, and the analysis type. See below for color values. The default is violet. .TP 10 .B size Set the expected paper size. If 'a' is specified, 'A' size paper is expected. Otherwise 'B' size paper is expected. The default is 'a'. .PP The following colors are available: red, green, blue, black, brown, orange, and violet. These pens reside in pen carriage locations 1 to 7, respectively, for the .I HP75xx plotters. Two other colors are available. The color 'none' specifies that no pen is to be used. The color 'eight' specifies the pen in carriage position 8. This color is unspecified. .PP As an example, suppose the user does not want a banner page or his name printed on the plot. To accomplish this, set .I SPLOTOPTS to "namec=none". .SH FILES /usr/local/splotter .br /usr/local/warmup pen exerciser .br /usr/cad/lib/displays text-graphic display link file .SH BUGS AND CAVEATS .PP .I Splotter .B cannot guarantee the quality of pen traces that come out of the plotter. To help warm up the plotter pens, run the program 'warmup' to exercise the pens. However, .B DO .B NOT attempt to clean the pens by hand. If you do, you may be ejected from the .B DSL. Report any bugs to a .B DSL staff member. .SH SEE ALSO hplot(local) .SH AUTHOR David P. Feldman .br Digital Systems Laboratory .br University of Pennsylvania \Rogue\Monster\ else echo "will not over write ./splotter/splotter.l" fi if `test ! -s ./splotter/README` then echo "writing ./splotter/README" cat > ./splotter/README << '\Rogue\Monster\' Notes on splotter: Splotter is the program that takes data generated by xsplot and plots it. It will (in theory) drive any HP-GL plotter, though we only have a HP 7550A, so who knows... Anyhow, splotter takes the data from xsplot, converts it to HP-GL commands, and execs 'lpr' to print it on 'plot1'. This has several nice features. One is that queueing is automatically dealt with. Another is that lpr allows you to print on remote machines. For example, on my RT workstation, I have the following entry in my /etc/printcap file: #plotter 'plot1' on dsl plot1:\ :lp=:rm=dsl.cis.upenn.edu:rp=plot1:sd=/usr/spool/plot1d and on 'dsl.cis.upenn.edu' (the VAX that the plotter is hooked to) I've got the following: plot1|7550a|hp7550a:\ :lp=/dev/plot1:sd=/usr/spool/plot1:lf=/usr/adm/plot-log:br#9600:\ :fs#0x200003:fc#0dffffc:af=/usr/adm/plot.acct:mc#1:sf:sh:\ :if=/etc/plotif:of=/usr/lib/lpf: Needless to say, it works. Your mileage may vary. Anyhow, regarding the splotter man page, it contains a lot of information that you won't need to know if you're running xsplot. (We have versions of splot running on PCs (EGA and PGA), and they have to go through some extra steps to get the data up to the host machine.) If you're running xsplot, and have splotter installed, you probably will never have to actually run splotter by hand, as xsplot will do that for you. However, if you have splotter and xsplot running on different machines (for whatever reason), all you have to know to run it is "splotter -i spiffile". John Bradley - University of Pennsylvania - bradley@cis.upenn.edu P.S. You may wish to refer any plotter-related questions to the author. (David Feldman - david@dsl.cis.upenn.edu) I don't *do* hardware. \Rogue\Monster\ else echo "will not over write ./splotter/README" fi echo "Finished archive 1 of 4" exit