#include "../cda.h" #include "../filenames.h" #include "../dl.h" #include "../libwe.h" #include "../libtk.h" EXT DL shapemode(); /* * Wire diagram editor. * * * This module contains the main editor program. It uses graphics subroutines * from the directory libwe and general purpose subroutines from the directory libgp. * Subroutines specific to the Tektronix 4014 are found in the directory libtk * Subroutines specific to the Chromatics XXXX are found in the directory libcg * * Usage: * draw- [ file ] * * If no file is specified, the display list is initialized from the library 'drawlib' * * */ ERR mainjmp; FILENAME chpname; /* * Ask for acknowledgement for certain commands. * * return=1 if user inputs '*', 0 otherwise */ ack() { echo('*'); return(key() == '*'); } /* * Main command loop processor. */ cmdloop() { REG CHAR k; FILENAME fn; REG DL h; REG DL head=first('M'); DL newhead; INT D=1; /* redraw */ INT M; ITEM nn; while(1) { setjmp(onerror); if(D) { D=0; redraw(head); } M=0; newhead=0; h=head; k=prompt('%'); switch(k) { case '.': if(any(h->type, "LB")) D++; M++; break; case 'B': newhead=first('B'); if(newhead==nil(DL)) newhead=newdlh(BEFORE, last(k), k, 0); D++; break; case 'L': case 'S': newhead=shapemode(); D++; break; case 'l': D++; if(h->type=='L') newhead=next('L', h); else newhead=first('L'); if(newhead==0) M++; break; case ESC: case '@': k='@'; echo('@'); case 'c': case 'w': if( (h=item(k))!=0 ) newhead=h; break; case 'q': if (modified) { modified=0; error("file not written"); } case 'Q': return; case 'a': case 'e': case 'z': path(h,k,lastnum); break; case 'b': boardset(h); M++; break; case 'd': if(M=maindel(h)){ head=0; } break; case 'f': if(lastnam[0]) setname(lastnam); reply(filename); break; case 'g': gluepin(h); break; case 'h': if(text(h,lastnum)) { M++; } break; case 'D': recurse(h); M++; D++; break; case 'J': newhead=join(h); break; case 'K': squares(h,0); break; case 'k': squares(h,10); break; case 'i': inventory(); break; case 'n': case 'N': rdname(nn, sizeof(nn)); newhead=newname(h, k, nn); break; case 'p': newhead=setpin(h); if (newhead == 0) break; if(h!=newhead){ M++; } break; case 'P': rdname(lastnam, sizeof(lastnam)); lastnum=geti(lastnam); setpag(lastnum); break; case 's': k='a'; case 'o': achip(h,k,lastnum); break; case 'r': redraw(h); break; case 'm': case 't': case 'M': case 'T': case 'U': M=movearea(h, k); if (head->type == 'L') M = 0; break; case 'v': case 'V': label(h, lastnum, k); break; case 'x': setext(h); D++; break; case 'X': markext(h); break; case '+': setscale(); D++; break; case '-': scaledown(0); D++; break; case '=': mvwind(); D++; break; case '<': if (modified) { modified=0; error("drawing modified"); } rdname(fn, sizeof(fn)); input(fn); head=0; M++; D++; break; case '>': head=0; M++; rdname(fn, sizeof(fn)); namgen(); output(fn); modified=0; break; case '\\': if(ack()) debug++; else debug=0; break; case '!': mode(ALPHA); place(crlf); full(); fixtty(0); shell(); fixtty(1); echo('!'); break; case '?': erase(); textat(point(0, 748), crlf); style(8, 0, 0); help(drawhelp, h->type); style(0, 0, 0); break; case ':': who(h); break; case '#': prxy(); break; default: error("illegal command"); } if(M) { cleanall(); newhead=first('M'); if(head==0) head=newhead; } if(newhead) { switch(head->type) { case 'L': D++; shapout(head); case 'B': D++; break; } head=newhead; } switch(head->type) { case 'c': break; case 'L': fixext(head); case 'w': case 'B': head=cleanwire(head); break; } } } /* * List the names of the items in the display list. */ inventory() { erase(); textat(point(0, 700), crlf); listem('c', "Chips"); listem('w', "Wires"); listem('L', "Shapes"); } /* * Main program. * * If no file name is specified, the library 'drawlib' * is taken as the initial input. */ main(argc, argv) STRING argv[]; { FILENAME fn; ADR cor; if(setjmp(mainjmp)==0) { cor=sbrk(0); stdsigs(); if (argc > 1 && *argv[1] == '-' && *argv[2] == 0){ argc--; argv++; debug++; } fixtty(1); scaledown(1); if(setjmp(onerror)==0){ if(argc <2) { input(drawlib); filename[0]=0; } else { fncopy(argv[1], fn); if (access(argv[1], 0) == 0) { movstr(argv[1], fn); input(fn); } else { input(drawlib); setname(argv[1]); } } } } else{ /* this is a cheap way to initialize variables */ brk(cor); input(chpname); setname(chpname); } modified=0; cmdloop(); fixtty(0); if(debug) abort(); exit(0); } /* * delete from '%' level */ maindel(h) DL h; { REG INT k; REG INT r=0; REG DL p; DL1 p1; switch(k=key()){ case 'a': delarea(h); break; case 'L': case 'S': if(h->type!='L') h=shapemode(); case 'B': case 'c': case 'w': delitem(h, k); r++; break; case 'h': case 'v': case 'V': case 'X': delthing(h, k); break; case 'p': chkhd(h, "wL"); must(cursor(p1)); if(p = findxact(k, h, p1)) delete(p); else error("not found"); break; case 'x': delx(h); break; case 's': case 'o': delshape(h); break; case 'e': delpath(h); break; case 'l': delwire(h); break; default: error("illegal command"); } return(r); } /* * Shape mode processor. */ DL shapemode() { REG DL head; REG STRING cp; rdname(lastnam, sizeof(lastnam)); cp=lastnam; if (*cp == 0) error("name required"); head=findL(cp); return(head); } /* * normalise shape definition. * * h=head */ shapout(h) REG DL h; { REG DL p; DL q; q=minpt(h); p=h; while(p=nexta('L',p)) { if (p->type != 'x') { p->x -= q->x; p->y -= q->y; } } } /* * List the names of entries with a specified type. * * t=type * tn=title string */ listem(t, tn) REG CHAR t; REG STRING tn; { REG DL p; style(16, -1, 0); place(crlf); place(tn); pad("", 132); style(0, -1, 0); p=dstart; while(p=next(t,p)) pad(dln(p)->name, 10); pad("", 132); } recurse(h) DL h; { REG STRING np; np=movstr(dln(h)->name+upbstr(dln(h)->name)+1, chpname); movstr(".g", np); if(isfile(chpname)) { INT pid, status; if(pid=fork()) { while(wait(&status)!=pid); } else{ longjmp(mainjmp,1); exit(72); } } else{ error("not a macro"); } return(0); } /* * Output a string and pad with blanks to a specified field width. * * cp=string * n=field width -- enough blanks will be output so that the final column * position will be a multiple of this number */ pad(cp, n) STRING cp; { LOC INT col; REG INT sl; place(cp); col += upbstr(cp); sl=n - col%n; col += sl; if(col > 100){ col=0; place(crlf); } else while(--sl >= 0) place(blank); }