1: #ifndef lint 2: static char sccsid[] = "@(#)fed.c 4.2 (Berkeley) 8/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: }