1*14546Ssam #ifndef lint
2*14546Ssam static char sccsid[] = "@(#)fed.c 4.2 (Berkeley) 08/11/83";
3*14546Ssam #endif
4*14546Ssam
511510Sralph /*
611510Sralph * Font editor for the HP 2648.
711510Sralph *
811510Sralph * Mark Horton, 1/80
911510Sralph */
1011510Sralph
1111510Sralph #include "fed.h"
1211510Sralph
main(argc,argv)1311510Sralph main(argc,argv)
1411510Sralph int argc;
1511510Sralph char **argv;
1611510Sralph {
1711510Sralph
1811510Sralph signal(SIGINT, onintr);
1911510Sralph signal(SIGQUIT, onsig);
2011510Sralph signal(SIGILL, onsig);
2111510Sralph signal(SIGBUS, onsig);
2211510Sralph signal(SIGSEGV, onsig);
2311510Sralph signal(SIGSYS, onsig);
2411510Sralph
2511510Sralph while (argc > 1 && argv[1][0] == '-') {
2611510Sralph switch(argv[1][1]) {
2711510Sralph case 'T':
2811510Sralph trace = fopen("trace", "w");
2911510Sralph setbuf(trace, tracebuf);
3011510Sralph break;
3111510Sralph case 'i':
3211510Sralph case 'v':
3311510Sralph vidinv();
3411510Sralph break;
3511510Sralph case 'q':
3611510Sralph QUIET = 1;
3711510Sralph break;
3811510Sralph default:
3911510Sralph printf("Bad flag: %s\n", argv[1]);
4011510Sralph }
4111510Sralph argc--; argv++;
4211510Sralph }
4311510Sralph if (argc < 2) {
4411510Sralph fprintf(stderr,"Usage: %s filename\n", argv[0]);
4511510Sralph exit(1);
4611510Sralph }
4711510Sralph
4811510Sralph if (setjmp(env) == 0) {
4911510Sralph initialize();
5011510Sralph editfont(argv[1]);
5111510Sralph }
5211510Sralph
5311510Sralph cmdloop();
5411510Sralph }
5511510Sralph
cmdloop()5611510Sralph cmdloop()
5711510Sralph {
5811510Sralph char cmd;
5911510Sralph
6011510Sralph setjmp(env);
6111510Sralph for (;;) {
6211510Sralph cmd = inchar();
6311510Sralph if (cmd == ESC)
6411510Sralph cmd = esccmd();
6511510Sralph switch (cmd) {
6611510Sralph
6711510Sralph /* ^L: redraw munged up screen */
6811510Sralph case '\14':
6911510Sralph redraw();
7011510Sralph break;
7111510Sralph
7211510Sralph /* b: move cursor to base point of window */
7311510Sralph case 'b':
7411510Sralph cch();
7511510Sralph curs_r = cht[curchar].rcent;
7611510Sralph curs_c = cht[curchar].ccent;
7711510Sralph turnoncurs();
7811510Sralph break;
7911510Sralph
8011510Sralph /* c: toggle whether cursor is on */
8111510Sralph case 'c':
8211510Sralph if (curcurs)
8311510Sralph turnofcurs();
8411510Sralph else
8511510Sralph turnoncurs();
8611510Sralph break;
8711510Sralph
8811510Sralph /* d: draw line of current flavor from pen to cursor */
8911510Sralph case 'd':
9011510Sralph cch();
9111510Sralph bufmod();
9211510Sralph drawline(pen_r, pen_c, curs_r, curs_c);
9311510Sralph turnofcurs();
9411510Sralph turnofrb();
9511510Sralph pen_r = curs_r; pen_c = curs_c;
9611510Sralph syncwind(curwind);
9711510Sralph break;
9811510Sralph
9911510Sralph /* f: fill in the current hole around the cursor */
10011510Sralph case 'f':
10111510Sralph cch();
10211510Sralph bufmod();
10311510Sralph if (trace)
10411510Sralph fprintf(trace, "fillin(%d, %d)\n", curs_r, curs_c);
10511510Sralph if (mat(wind[curwind].val, GLROW, GLCOL, curs_r, curs_c))
10611510Sralph error("Not in a hole");
10711510Sralph fillin(curs_r, curs_c);
10811510Sralph curoff();
10911510Sralph syncwind(curwind);
11011510Sralph break;
11111510Sralph
11211510Sralph /* g <x>: get glyph "x" as current. */
11311510Sralph case 'g':
11411510Sralph if (fontdes == NULL)
11511510Sralph error("No current font file");
11611510Sralph message("get glyph <char>");
11711510Sralph curchar = inchar();
11811510Sralph sprintf(msgbuf, "get glyph %s", rdchar(curchar));
11911510Sralph message(msgbuf);
12011510Sralph getglyph(curchar);
12111510Sralph break;
12211510Sralph
12311510Sralph /* h, left arrow: move cursor left */
12411510Sralph case 'h':
12511510Sralph cch();
12611510Sralph if (curs_c <= 0)
12711510Sralph error("Off edge");
12811510Sralph else
12911510Sralph curs_c--;
13011510Sralph turnoncurs();
13111510Sralph break;
13211510Sralph
13311510Sralph /* j, down arrow: move cursor down */
13411510Sralph case 'j':
13511510Sralph cch();
13611510Sralph if (curs_r >= GLROW-1)
13711510Sralph error("Off edge");
13811510Sralph else
13911510Sralph curs_r++;
14011510Sralph turnoncurs();
14111510Sralph break;
14211510Sralph
14311510Sralph /* k, up arrow: move cursor up */
14411510Sralph case 'k':
14511510Sralph cch();
14611510Sralph if (curs_r <= 0)
14711510Sralph error("Off edge");
14811510Sralph else
14911510Sralph curs_r--;
15011510Sralph turnoncurs();
15111510Sralph break;
15211510Sralph
15311510Sralph /* l, right arrow: move cursor down */
15411510Sralph case 'l':
15511510Sralph cch();
15611510Sralph if (curs_c >= GLCOL-1)
15711510Sralph error("Off edge");
15811510Sralph else
15911510Sralph curs_c++;
16011510Sralph turnoncurs();
16111510Sralph break;
16211510Sralph
16311510Sralph /* m: move the pen to where the cursor is */
16411510Sralph case 'm':
16511510Sralph cch();
16611510Sralph pen_r = curs_r; pen_c = curs_c;
16711510Sralph turnoncurs();
16811510Sralph move(base[curwind].c+curs_c, base[curwind].r+GLROW-1-curs_r);
16911510Sralph turnonrb();
17011510Sralph break;
17111510Sralph
17211510Sralph /* n <x>: make a new glyph with char x */
17311510Sralph case 'n':
17411510Sralph newglyph();
17511510Sralph break;
17611510Sralph
17711510Sralph /* p: print a hard copy on the printer of the screen */
17811510Sralph case 'p':
17911510Sralph printg();
18011510Sralph break;
18111510Sralph
18211510Sralph /* r: toggle rubber band line */
18311510Sralph case 'r':
18411510Sralph if (currb)
18511510Sralph turnofrb();
18611510Sralph else
18711510Sralph turnonrb();
18811510Sralph break;
18911510Sralph
19011510Sralph /* s <what> <where>: set <what> to <where> */
19111510Sralph case 's':
19211510Sralph setcmd();
19311510Sralph break;
19411510Sralph
19511510Sralph /* u: undo previous buffer modifying command */
19611510Sralph case 'u':
19711510Sralph cch();
19811510Sralph undo();
19911510Sralph break;
20011510Sralph
20111510Sralph /* z <n>: set zoom to n. */
20211510Sralph case 'z':
20311510Sralph message("zoom to <level>");
20411510Sralph curzoom = inchar();
20511510Sralph if (curzoom == '\r' || curzoom == '\n')
20611510Sralph curzoom = oldzoom;
20711510Sralph else {
20811510Sralph curzoom -= '0';
20911510Sralph oldzoom = curzoom;
21011510Sralph }
21111510Sralph zoomn(curzoom);
21211510Sralph break;
21311510Sralph
21411510Sralph /* space: reset zoom to last thing user asked for */
21511510Sralph case ' ':
21611510Sralph zoomn(curzoom = oldzoom);
21711510Sralph break;
21811510Sralph
21911510Sralph /* A: artificially embolden/italicize <range> by heavy pen size */
22011510Sralph case 'A':
22111510Sralph bufmod();
22211510Sralph artificial();
22311510Sralph break;
22411510Sralph
22511510Sralph /* B: move base point of window to cursor */
22611510Sralph case 'B':
22711510Sralph cch();
22811510Sralph cht[curchar].rcent = curs_r;
22911510Sralph cht[curchar].ccent = curs_c;
23011510Sralph turnoncurs();
23111510Sralph break;
23211510Sralph
23311510Sralph /*
23411510Sralph * C <from> <to>: copy glyph <from> to <to>.
23511510Sralph * M <from> <to>: move glyph <from> to <to>.
23611510Sralph */
23711510Sralph case 'C':
23811510Sralph case 'M':
23911510Sralph copymove(cmd);
24011510Sralph break;
24111510Sralph
24211510Sralph /* D <char1> <char2>: delete range from font */
24311510Sralph case 'D':
24411510Sralph delchar();
24511510Sralph break;
24611510Sralph
24711510Sralph /* F: display the entire font on the screen. */
24811510Sralph case 'F':
24911510Sralph showfont();
25011510Sralph break;
25111510Sralph
25211510Sralph /* I: invert the current glyph */
25311510Sralph case 'I':
25411510Sralph cch();
25511510Sralph bufmod();
25611510Sralph invert();
25711510Sralph break;
25811510Sralph
25911510Sralph /* K: kill (wipe clean) current glyph. */
26011510Sralph case 'K':
26111510Sralph cch();
26211510Sralph bufmod();
26311510Sralph zermat(wind[curwind].val, GLROW, GLCOL);
26411510Sralph syncwind(curwind);
26511510Sralph if (trace)
26611510Sralph fprintf(trace, "kill: curs_r = %d, curs_c = %d\n", curs_r, curs_c);
26711510Sralph break;
26811510Sralph
26911510Sralph /* P <first> <last> <file>: read partial font */
27011510Sralph case 'P':
27111510Sralph readchars();
27211510Sralph break;
27311510Sralph
27411510Sralph /* Q: quit the editor, not saving work. */
27511510Sralph case 'Q':
27611510Sralph confirm();
27711510Sralph done();
27811510Sralph exit(0);
27911510Sralph
28011510Sralph /* T: typeset a line of input text */
28111510Sralph case 'T':
28211510Sralph typein();
28311510Sralph break;
28411510Sralph
28511510Sralph /* V: toggle video between inverse and normal */
28611510Sralph case 'V':
28711510Sralph togvid();
28811510Sralph break;
28911510Sralph
29011510Sralph /*
29111510Sralph * E <file>: edit new font file <file>.
29211510Sralph * N <file>: write, then edit <file>
29311510Sralph * R <file>: read <file> on top of buffer.
29411510Sralph * W <file>: write out on <file> without quitting
29511510Sralph */
29611510Sralph case 'E':
29711510Sralph case 'N':
29811510Sralph case 'R':
29911510Sralph case 'W':
30011510Sralph fileiocmd(cmd);
30111510Sralph break;
30211510Sralph
30311510Sralph /* Z: exit, writing out work */
30411510Sralph case 'Z':
30511510Sralph message("Z");
30611510Sralph if (inchar() != 'Z') {
30711510Sralph error("No second Z");
30811510Sralph }
30911510Sralph if (changes)
31011510Sralph writeback();
31111510Sralph done();
31211510Sralph exit(0);
31311510Sralph
31411510Sralph /*
31511510Sralph * ".", ">". Set and clear the bit under the cursor.
31611510Sralph */
31711510Sralph case '.':
31811510Sralph case '>':
31911510Sralph bufmod();
32011510Sralph setmat(wind[curwind].val, GLROW, GLCOL, curs_r, curs_c, cmd=='.' ? 1 : 0);
32111510Sralph turnofcurs();
32211510Sralph syncwind(curwind);
32311510Sralph break;
32411510Sralph
32511510Sralph /*
32611510Sralph * "#": edit the numerical parameters
32711510Sralph */
32811510Sralph case '#':
32911510Sralph numedit();
33011510Sralph break;
33111510Sralph
33211510Sralph default:
33311510Sralph sprintf(msgbuf, "No such command as %s", rdchar(cmd));
33411510Sralph message(msgbuf);
33511510Sralph }
33611510Sralph
33711510Sralph }
33811510Sralph }
33911510Sralph
34011510Sralph /*
34111510Sralph * esccmd: a command beginning with an escape.
34211510Sralph * Map it into the corresponding regular command.
34311510Sralph */
34411510Sralph char
esccmd()34511510Sralph esccmd()
34611510Sralph {
34711510Sralph char cmd;
34811510Sralph char *p;
34911510Sralph char escseqbuf[20];
35011510Sralph
35111510Sralph cmd = inchar();
35211510Sralph switch(cmd) {
35311510Sralph case 'A': return ('k'); /* up arrow */
35411510Sralph case 'B': return ('j'); /* down arrow */
35511510Sralph case 'C': return ('l'); /* right arrow */
35611510Sralph case 'D': return ('h'); /* left arrow */
35711510Sralph case 'h': return ('b'); /* home */
35811510Sralph case '2': return ('u'); /* clear tab = undo */
35911510Sralph case '1': return (' '); /* set tab = rezoom */
36011510Sralph case 'J': return ('f'); /* clear display = fill area */
36111510Sralph case 'S': return ('m'); /* roll up = move */
36211510Sralph case 'U': return ('d'); /* next page = draw */
36311510Sralph case 'T': return ('.'); /* roll down = set bit */
36411510Sralph case 'V': return ('>'); /* prev page = clear bit */
36511510Sralph default:
36611510Sralph /*
36711510Sralph * Eat up rest of (possibly long) escape sequence.
36811510Sralph * They all end in an upper case letter, with
36911510Sralph * a few exceptions.
37011510Sralph */
37111510Sralph p = escseqbuf;
37211510Sralph *p++ = '$';
37311510Sralph *p++ = cmd;
37411510Sralph while (!isupper(cmd) && cmd != 'h' && cmd != '\n')
37511510Sralph *p++ = cmd = inchar();
37611510Sralph *p++ = 0;
37711510Sralph sprintf(msgbuf, "Bad escape sequence: %s\n", escseqbuf);
37811510Sralph error(msgbuf);
37911510Sralph }
38011510Sralph }
38111510Sralph
onsig(signo)38211510Sralph onsig(signo)
38311510Sralph int signo;
38411510Sralph {
38511510Sralph char *mes;
38611510Sralph
38711510Sralph switch(signo) {
38811510Sralph case SIGQUIT: mes = "quit"; break;
38911510Sralph case SIGILL: mes = "illegal instruction"; break;
39011510Sralph case SIGBUS: mes = "bus error"; break;
39111510Sralph case SIGSEGV: mes = "segmentation violation"; break;
39211510Sralph case SIGSYS: mes = "bad system call"; break;
39311510Sralph default: mes = "random signal"; break;
39411510Sralph }
39511510Sralph if (trace) {
39611510Sralph fprintf(trace, "%s: core dumped\n", mes);
39711510Sralph fflush(trace);
39811510Sralph }
39911510Sralph signal(SIGILL, SIG_DFL);
40011510Sralph done();
40111510Sralph printf("fed: %s: core dumped\n", mes);
40211510Sralph fflush(stdout);
40311510Sralph abort();
40411510Sralph }
40511510Sralph
onintr()40611510Sralph onintr()
40711510Sralph {
40811510Sralph signal(SIGINT, onintr);
40911510Sralph error("Interrupted");
41011510Sralph longjmp(env);
41111510Sralph }
412