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