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