xref: /csrg-svn/old/vpr/vtools/fed/fed.c (revision 11510)
1*11510Sralph /*	fed.c	4.1	83/03/09	*/
2*11510Sralph /*
3*11510Sralph  *	Font editor for the HP 2648.
4*11510Sralph  *
5*11510Sralph  *	Mark Horton, 1/80
6*11510Sralph  */
7*11510Sralph 
8*11510Sralph #include "fed.h"
9*11510Sralph 
10*11510Sralph main(argc,argv)
11*11510Sralph int argc;
12*11510Sralph char **argv;
13*11510Sralph {
14*11510Sralph 
15*11510Sralph 	signal(SIGINT, onintr);
16*11510Sralph 	signal(SIGQUIT, onsig);
17*11510Sralph 	signal(SIGILL, onsig);
18*11510Sralph 	signal(SIGBUS, onsig);
19*11510Sralph 	signal(SIGSEGV, onsig);
20*11510Sralph 	signal(SIGSYS, onsig);
21*11510Sralph 
22*11510Sralph 	while (argc > 1 && argv[1][0] == '-') {
23*11510Sralph 		switch(argv[1][1]) {
24*11510Sralph 		case 'T':
25*11510Sralph 			trace = fopen("trace", "w");
26*11510Sralph 			setbuf(trace, tracebuf);
27*11510Sralph 			break;
28*11510Sralph 		case 'i':
29*11510Sralph 		case 'v':
30*11510Sralph 			vidinv();
31*11510Sralph 			break;
32*11510Sralph 		case 'q':
33*11510Sralph 			QUIET = 1;
34*11510Sralph 			break;
35*11510Sralph 		default:
36*11510Sralph 			printf("Bad flag: %s\n", argv[1]);
37*11510Sralph 		}
38*11510Sralph 		argc--; argv++;
39*11510Sralph 	}
40*11510Sralph 	if (argc < 2) {
41*11510Sralph 		fprintf(stderr,"Usage: %s filename\n", argv[0]);
42*11510Sralph 		exit(1);
43*11510Sralph 	}
44*11510Sralph 
45*11510Sralph 	if (setjmp(env) == 0) {
46*11510Sralph 		initialize();
47*11510Sralph 		editfont(argv[1]);
48*11510Sralph 	}
49*11510Sralph 
50*11510Sralph 	cmdloop();
51*11510Sralph }
52*11510Sralph 
53*11510Sralph cmdloop()
54*11510Sralph {
55*11510Sralph 	char cmd;
56*11510Sralph 
57*11510Sralph 	setjmp(env);
58*11510Sralph 	for (;;) {
59*11510Sralph 		cmd = inchar();
60*11510Sralph 		if (cmd == ESC)
61*11510Sralph 			cmd = esccmd();
62*11510Sralph 		switch (cmd) {
63*11510Sralph 
64*11510Sralph 		/* ^L: redraw munged up screen */
65*11510Sralph 		case '\14':
66*11510Sralph 			redraw();
67*11510Sralph 			break;
68*11510Sralph 
69*11510Sralph 		/* b: move cursor to base point of window */
70*11510Sralph 		case 'b':
71*11510Sralph 			cch();
72*11510Sralph 			curs_r = cht[curchar].rcent;
73*11510Sralph 			curs_c = cht[curchar].ccent;
74*11510Sralph 			turnoncurs();
75*11510Sralph 			break;
76*11510Sralph 
77*11510Sralph 		/* c: toggle whether cursor is on */
78*11510Sralph 		case 'c':
79*11510Sralph 			if (curcurs)
80*11510Sralph 				turnofcurs();
81*11510Sralph 			else
82*11510Sralph 				turnoncurs();
83*11510Sralph 			break;
84*11510Sralph 
85*11510Sralph 		/* d: draw line of current flavor from pen to cursor */
86*11510Sralph 		case 'd':
87*11510Sralph 			cch();
88*11510Sralph 			bufmod();
89*11510Sralph 			drawline(pen_r, pen_c, curs_r, curs_c);
90*11510Sralph 			turnofcurs();
91*11510Sralph 			turnofrb();
92*11510Sralph 			pen_r = curs_r; pen_c = curs_c;
93*11510Sralph 			syncwind(curwind);
94*11510Sralph 			break;
95*11510Sralph 
96*11510Sralph 		/* f: fill in the current hole around the cursor */
97*11510Sralph 		case 'f':
98*11510Sralph 			cch();
99*11510Sralph 			bufmod();
100*11510Sralph 			if (trace)
101*11510Sralph 				fprintf(trace, "fillin(%d, %d)\n", curs_r, curs_c);
102*11510Sralph 			if (mat(wind[curwind].val, GLROW, GLCOL, curs_r, curs_c))
103*11510Sralph 				error("Not in a hole");
104*11510Sralph 			fillin(curs_r, curs_c);
105*11510Sralph 			curoff();
106*11510Sralph 			syncwind(curwind);
107*11510Sralph 			break;
108*11510Sralph 
109*11510Sralph 		/* g <x>: get glyph "x" as current. */
110*11510Sralph 		case 'g':
111*11510Sralph 			if (fontdes == NULL)
112*11510Sralph 				error("No current font file");
113*11510Sralph 			message("get glyph <char>");
114*11510Sralph 			curchar = inchar();
115*11510Sralph 			sprintf(msgbuf, "get glyph %s", rdchar(curchar));
116*11510Sralph 			message(msgbuf);
117*11510Sralph 			getglyph(curchar);
118*11510Sralph 			break;
119*11510Sralph 
120*11510Sralph 		/* h, left arrow: move cursor left */
121*11510Sralph 		case 'h':
122*11510Sralph 			cch();
123*11510Sralph 			if (curs_c <= 0)
124*11510Sralph 				error("Off edge");
125*11510Sralph 			else
126*11510Sralph 				curs_c--;
127*11510Sralph 			turnoncurs();
128*11510Sralph 			break;
129*11510Sralph 
130*11510Sralph 		/* j, down arrow: move cursor down */
131*11510Sralph 		case 'j':
132*11510Sralph 			cch();
133*11510Sralph 			if (curs_r >= GLROW-1)
134*11510Sralph 				error("Off edge");
135*11510Sralph 			else
136*11510Sralph 				curs_r++;
137*11510Sralph 			turnoncurs();
138*11510Sralph 			break;
139*11510Sralph 
140*11510Sralph 		/* k, up arrow: move cursor up */
141*11510Sralph 		case 'k':
142*11510Sralph 			cch();
143*11510Sralph 			if (curs_r <= 0)
144*11510Sralph 				error("Off edge");
145*11510Sralph 			else
146*11510Sralph 				curs_r--;
147*11510Sralph 			turnoncurs();
148*11510Sralph 			break;
149*11510Sralph 
150*11510Sralph 		/* l, right arrow: move cursor down */
151*11510Sralph 		case 'l':
152*11510Sralph 			cch();
153*11510Sralph 			if (curs_c >= GLCOL-1)
154*11510Sralph 				error("Off edge");
155*11510Sralph 			else
156*11510Sralph 				curs_c++;
157*11510Sralph 			turnoncurs();
158*11510Sralph 			break;
159*11510Sralph 
160*11510Sralph 		/* m: move the pen to where the cursor is */
161*11510Sralph 		case 'm':
162*11510Sralph 			cch();
163*11510Sralph 			pen_r = curs_r; pen_c = curs_c;
164*11510Sralph 			turnoncurs();
165*11510Sralph 			move(base[curwind].c+curs_c, base[curwind].r+GLROW-1-curs_r);
166*11510Sralph 			turnonrb();
167*11510Sralph 			break;
168*11510Sralph 
169*11510Sralph 		/* n <x>: make a new glyph with char x */
170*11510Sralph 		case 'n':
171*11510Sralph 			newglyph();
172*11510Sralph 			break;
173*11510Sralph 
174*11510Sralph 		/* p: print a hard copy on the printer of the screen */
175*11510Sralph 		case 'p':
176*11510Sralph 			printg();
177*11510Sralph 			break;
178*11510Sralph 
179*11510Sralph 		/* r: toggle rubber band line */
180*11510Sralph 		case 'r':
181*11510Sralph 			if (currb)
182*11510Sralph 				turnofrb();
183*11510Sralph 			else
184*11510Sralph 				turnonrb();
185*11510Sralph 			break;
186*11510Sralph 
187*11510Sralph 		/* s <what> <where>: set <what> to <where> */
188*11510Sralph 		case 's':
189*11510Sralph 			setcmd();
190*11510Sralph 			break;
191*11510Sralph 
192*11510Sralph 		/* u: undo previous buffer modifying command */
193*11510Sralph 		case 'u':
194*11510Sralph 			cch();
195*11510Sralph 			undo();
196*11510Sralph 			break;
197*11510Sralph 
198*11510Sralph 		/* z <n>: set zoom to n. */
199*11510Sralph 		case 'z':
200*11510Sralph 			message("zoom to <level>");
201*11510Sralph 			curzoom = inchar();
202*11510Sralph 			if (curzoom == '\r' || curzoom == '\n')
203*11510Sralph 				curzoom = oldzoom;
204*11510Sralph 			else {
205*11510Sralph 				curzoom -= '0';
206*11510Sralph 				oldzoom = curzoom;
207*11510Sralph 			}
208*11510Sralph 			zoomn(curzoom);
209*11510Sralph 			break;
210*11510Sralph 
211*11510Sralph 		/* space: reset zoom to last thing user asked for */
212*11510Sralph 		case ' ':
213*11510Sralph 			zoomn(curzoom = oldzoom);
214*11510Sralph 			break;
215*11510Sralph 
216*11510Sralph 		/* A: artificially embolden/italicize <range> by heavy pen size */
217*11510Sralph 		case 'A':
218*11510Sralph 			bufmod();
219*11510Sralph 			artificial();
220*11510Sralph 			break;
221*11510Sralph 
222*11510Sralph 		/* B: move base point of window to cursor */
223*11510Sralph 		case 'B':
224*11510Sralph 			cch();
225*11510Sralph 			cht[curchar].rcent = curs_r;
226*11510Sralph 			cht[curchar].ccent = curs_c;
227*11510Sralph 			turnoncurs();
228*11510Sralph 			break;
229*11510Sralph 
230*11510Sralph 		/*
231*11510Sralph 		 * C <from> <to>: copy glyph <from> to <to>.
232*11510Sralph 		 * M <from> <to>: move glyph <from> to <to>.
233*11510Sralph 		 */
234*11510Sralph 		case 'C':
235*11510Sralph 		case 'M':
236*11510Sralph 			copymove(cmd);
237*11510Sralph 			break;
238*11510Sralph 
239*11510Sralph 		/* D <char1> <char2>: delete range from font */
240*11510Sralph 		case 'D':
241*11510Sralph 			delchar();
242*11510Sralph 			break;
243*11510Sralph 
244*11510Sralph 		/* F: display the entire font on the screen. */
245*11510Sralph 		case 'F':
246*11510Sralph 			showfont();
247*11510Sralph 			break;
248*11510Sralph 
249*11510Sralph 		/* I: invert the current glyph */
250*11510Sralph 		case 'I':
251*11510Sralph 			cch();
252*11510Sralph 			bufmod();
253*11510Sralph 			invert();
254*11510Sralph 			break;
255*11510Sralph 
256*11510Sralph 		/* K: kill (wipe clean) current glyph. */
257*11510Sralph 		case 'K':
258*11510Sralph 			cch();
259*11510Sralph 			bufmod();
260*11510Sralph 			zermat(wind[curwind].val, GLROW, GLCOL);
261*11510Sralph 			syncwind(curwind);
262*11510Sralph 			if (trace)
263*11510Sralph 				fprintf(trace, "kill: curs_r = %d, curs_c = %d\n", curs_r, curs_c);
264*11510Sralph 			break;
265*11510Sralph 
266*11510Sralph 		/* P <first> <last> <file>: read partial font */
267*11510Sralph 		case 'P':
268*11510Sralph 			readchars();
269*11510Sralph 			break;
270*11510Sralph 
271*11510Sralph 		/* Q: quit the editor, not saving work. */
272*11510Sralph 		case 'Q':
273*11510Sralph 			confirm();
274*11510Sralph 			done();
275*11510Sralph 			exit(0);
276*11510Sralph 
277*11510Sralph 		/* T: typeset a line of input text */
278*11510Sralph 		case 'T':
279*11510Sralph 			typein();
280*11510Sralph 			break;
281*11510Sralph 
282*11510Sralph 		/* V: toggle video between inverse and normal */
283*11510Sralph 		case 'V':
284*11510Sralph 			togvid();
285*11510Sralph 			break;
286*11510Sralph 
287*11510Sralph 		/*
288*11510Sralph 		 * E <file>: edit new font file <file>.
289*11510Sralph 		 * N <file>: write, then edit <file>
290*11510Sralph 		 * R <file>: read <file> on top of buffer.
291*11510Sralph 		 * W <file>: write out on <file> without quitting
292*11510Sralph 		 */
293*11510Sralph 		case 'E':
294*11510Sralph 		case 'N':
295*11510Sralph 		case 'R':
296*11510Sralph 		case 'W':
297*11510Sralph 			fileiocmd(cmd);
298*11510Sralph 			break;
299*11510Sralph 
300*11510Sralph 		/* Z: exit, writing out work */
301*11510Sralph 		case 'Z':
302*11510Sralph 			message("Z");
303*11510Sralph 			if (inchar() != 'Z') {
304*11510Sralph 				error("No second Z");
305*11510Sralph 			}
306*11510Sralph 			if (changes)
307*11510Sralph 				writeback();
308*11510Sralph 			done();
309*11510Sralph 			exit(0);
310*11510Sralph 
311*11510Sralph 		/*
312*11510Sralph 		 * ".", ">".  Set and clear the bit under the cursor.
313*11510Sralph 		 */
314*11510Sralph 		case '.':
315*11510Sralph 		case '>':
316*11510Sralph 			bufmod();
317*11510Sralph 			setmat(wind[curwind].val, GLROW, GLCOL, curs_r, curs_c, cmd=='.' ? 1 : 0);
318*11510Sralph 			turnofcurs();
319*11510Sralph 			syncwind(curwind);
320*11510Sralph 			break;
321*11510Sralph 
322*11510Sralph 		/*
323*11510Sralph 		 * "#": edit the numerical parameters
324*11510Sralph 		 */
325*11510Sralph 		case '#':
326*11510Sralph 			numedit();
327*11510Sralph 			break;
328*11510Sralph 
329*11510Sralph 		default:
330*11510Sralph 			sprintf(msgbuf, "No such command as %s", rdchar(cmd));
331*11510Sralph 			message(msgbuf);
332*11510Sralph 		}
333*11510Sralph 
334*11510Sralph 	}
335*11510Sralph }
336*11510Sralph 
337*11510Sralph /*
338*11510Sralph  * esccmd: a command beginning with an escape.
339*11510Sralph  * Map it into the corresponding regular command.
340*11510Sralph  */
341*11510Sralph char
342*11510Sralph esccmd()
343*11510Sralph {
344*11510Sralph 	char cmd;
345*11510Sralph 	char *p;
346*11510Sralph 	char escseqbuf[20];
347*11510Sralph 
348*11510Sralph 	cmd = inchar();
349*11510Sralph 	switch(cmd) {
350*11510Sralph 	case 'A':	return ('k');	/* up arrow */
351*11510Sralph 	case 'B':	return ('j');	/* down arrow */
352*11510Sralph 	case 'C':	return ('l');	/* right arrow */
353*11510Sralph 	case 'D':	return ('h');	/* left arrow */
354*11510Sralph 	case 'h':	return ('b');	/* home */
355*11510Sralph 	case '2':	return ('u');	/* clear tab = undo */
356*11510Sralph 	case '1':	return (' ');	/* set tab = rezoom */
357*11510Sralph 	case 'J':	return ('f');	/* clear display = fill area */
358*11510Sralph 	case 'S':	return ('m');	/* roll up = move */
359*11510Sralph 	case 'U':	return ('d');	/* next page = draw */
360*11510Sralph 	case 'T':	return ('.');	/* roll down = set bit */
361*11510Sralph 	case 'V':	return ('>');	/* prev page = clear bit */
362*11510Sralph 	default:
363*11510Sralph 		/*
364*11510Sralph 		 * Eat up rest of (possibly long) escape sequence.
365*11510Sralph 		 * They all end in an upper case letter, with
366*11510Sralph 		 * a few exceptions.
367*11510Sralph 		 */
368*11510Sralph 		p = escseqbuf;
369*11510Sralph 		*p++ = '$';
370*11510Sralph 		*p++ = cmd;
371*11510Sralph 		while (!isupper(cmd) && cmd != 'h' && cmd != '\n')
372*11510Sralph 			*p++ = cmd = inchar();
373*11510Sralph 		*p++ = 0;
374*11510Sralph 		sprintf(msgbuf, "Bad escape sequence: %s\n", escseqbuf);
375*11510Sralph 		error(msgbuf);
376*11510Sralph 	}
377*11510Sralph }
378*11510Sralph 
379*11510Sralph onsig(signo)
380*11510Sralph int signo;
381*11510Sralph {
382*11510Sralph 	char *mes;
383*11510Sralph 
384*11510Sralph 	switch(signo) {
385*11510Sralph 		case SIGQUIT:	mes = "quit"; break;
386*11510Sralph 		case SIGILL:	mes = "illegal instruction"; break;
387*11510Sralph 		case SIGBUS:	mes = "bus error"; break;
388*11510Sralph 		case SIGSEGV:	mes = "segmentation violation"; break;
389*11510Sralph 		case SIGSYS:	mes = "bad system call"; break;
390*11510Sralph 		default:	mes = "random signal"; break;
391*11510Sralph 	}
392*11510Sralph 	if (trace) {
393*11510Sralph 		fprintf(trace, "%s: core dumped\n", mes);
394*11510Sralph 		fflush(trace);
395*11510Sralph 	}
396*11510Sralph 	signal(SIGILL, SIG_DFL);
397*11510Sralph 	done();
398*11510Sralph 	printf("fed: %s: core dumped\n", mes);
399*11510Sralph 	fflush(stdout);
400*11510Sralph 	abort();
401*11510Sralph }
402*11510Sralph 
403*11510Sralph onintr()
404*11510Sralph {
405*11510Sralph 	signal(SIGINT, onintr);
406*11510Sralph 	error("Interrupted");
407*11510Sralph 	longjmp(env);
408*11510Sralph }
409