xref: /csrg-svn/old/vpr/vtools/fed/fed.c (revision 14546)
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