|
|
1.1 ! root 1: #include <X/mit-copyright.h> ! 2: ! 3: /* Copyright Massachusetts Institute of Technology 1984, 1985 */ ! 4: ! 5: #ifndef lint ! 6: static char *rcsid_gcmd_c = "$Header: gcmd.c,v 10.6 86/02/01 16:18:44 tony Rel $"; ! 7: #endif lint ! 8: ! 9: char *malloc(), *strcpy(); ! 10: ! 11: #include "gedit.h" ! 12: ! 13: int mult = 1; /* command multiplier */ ! 14: int dx,dy,ends; /* used during select operation */ ! 15: int redo; /* set to one if arc cache should be recalculated */ ! 16: struct prototype *previous = NULL; /* last proto to be edited */ ! 17: ! 18: /* process command input from user -- return 1 if it's time to exit, 0 otherwise */ ! 19: command() ! 20: { register int ch; ! 21: fptr cmd; ! 22: extern char mousechanged; ! 23: char buf[100]; ! 24: ! 25: while (mousechanged) { ! 26: ch = track(); ! 27: if (ch & (RECENTER+REDISPLAY)) { ! 28: if (ch & RECENTER) { ! 29: new_window(&cur_state,cur_state.curx,cur_state.cury); ! 30: remouse(cur_state.curx, cur_state.cury, 1); ! 31: } ! 32: redisplay(); ! 33: } ! 34: if (!UserReady()) return(0); ! 35: } ! 36: ! 37: ch = UserChar() & 0xFF; ! 38: if (ch == 0377) return(0); ! 39: ! 40: cmd = dispatch[ch]; ! 41: if (cmd == NULL) { ! 42: Beep(); ! 43: sprintf(buf, "unrecognized command: 0%o", ch); ! 44: msg(buf); ! 45: } else { ! 46: ch = (*cmd)(); ! 47: if (!(ch & MULTIPLIER)) mult = 1; ! 48: if (ch & (RECENTER+REDISPLAY)) { ! 49: if (ch & RECENTER) { ! 50: new_window(&cur_state,cur_state.curx,cur_state.cury); ! 51: remouse(cur_state.curx, cur_state.cury, 1); ! 52: } ! 53: redisplay(); ! 54: } ! 55: if (ch & DONE) return(1); ! 56: } ! 57: ! 58: return(0); ! 59: } ! 60: ! 61: /* go back to editing last thing we were working on */ ! 62: editlast() ! 63: { struct prototype *temp; ! 64: ! 65: if (previous == NULL) return(0); ! 66: ! 67: if (temp = cur_state.curobj) temp->recent = cur_state; ! 68: cur_state = previous->recent; ! 69: previous = temp; ! 70: return(REDISPLAY); ! 71: } ! 72: ! 73: /* accept angle for SEGMENT */ ! 74: angle() ! 75: { register gptr p; ! 76: char buf[100]; ! 77: ! 78: if ((p = cur_state.editee) == NULL) goto done; ! 79: if (p->s.type != SEGMENT) goto done; ! 80: sprintf(buf,"angle = %d, new value (2048 units in a circle): ",p->s.angle); ! 81: if (userinput("",buf)) ! 82: goto done; ! 83: if (typein[0] == 0) goto done; ! 84: p->s.angle = atoi(typein) & 2047; ! 85: redo = 1; ! 86: ! 87: done: return(0); ! 88: } ! 89: ! 90: /* resize window and redisplay */ ! 91: fixwindow() ! 92: { new_window(&cur_state, ! 93: (cur_state.worgx+cur_state.wmaxx)>>1, ! 94: (cur_state.worgy+cur_state.wmaxy)>>1); ! 95: remouse(cur_state.curx, cur_state.cury, 1); ! 96: return(REDISPLAY); ! 97: } ! 98: ! 99: /* recenter window at cursor position */ ! 100: setwindow() ! 101: { return(RECENTER); ! 102: } ! 103: ! 104: /* frob orient parameter of selected object */ ! 105: rotateobj() ! 106: { register gptr p; ! 107: short temp; ! 108: ! 109: if ((p = cur_state.editee) != NULL) switch (p->s.type) { ! 110: case SEGMENT: if (p->s.angle == 0) break; ! 111: temp = p->s.x1; p->s.x1 = p->s.x2; p->s.x2 = temp; ! 112: temp = p->s.y1; p->s.y1 = p->s.y2; p->s.y2 = temp; ! 113: cur_state.whichend = 3 - cur_state.whichend; ! 114: redo = 1; ! 115: break; ! 116: ! 117: case LABEL: p->l.orient += 1; ! 118: if (p->l.orient > BR) p->l.orient = CC; ! 119: break; ! 120: ! 121: case OBJECT: p->o.orient += 1; ! 122: if (p->o.orient > RWEST) p->o.orient = NORTH; ! 123: break; ! 124: } ! 125: ! 126: return(0); ! 127: } ! 128: ! 129: /* edit selected object */ ! 130: editobj() ! 131: { register gptr p; ! 132: ! 133: if ((p = cur_state.editee) != NULL) switch (p->s.type) { ! 134: case LABEL: if (userinput(p->l.string,"edit label: ")) break; ! 135: if (strlen(typein) <= strlen(p->l.string)) ! 136: strcpy(p->l.string,typein); ! 137: else { ! 138: free(p->l.string); ! 139: if ((p->l.string = malloc((unsigned)(strlen(typein)+1))) == NULL) { ! 140: msg("out of room!"); ! 141: break; ! 142: } ! 143: strcpy(p->l.string,typein); ! 144: } ! 145: break; ! 146: ! 147: case OBJECT: cur_state.curobj->recent = cur_state; ! 148: previous = cur_state.curobj; ! 149: cur_state = p->o.proto->recent; ! 150: return(REDISPLAY); ! 151: } ! 152: ! 153: return(0); ! 154: } ! 155: ! 156: /* rescale subpicture */ ! 157: rescale() ! 158: { register gptr p; ! 159: register int ch; ! 160: char buf[100]; ! 161: int in1,in2; ! 162: ! 163: if ((p = cur_state.editee)==NULL || p->o.type!=OBJECT) return(0); ! 164: sprintf(buf,"subpicture scale = %d:%d, new scale: ",p->o.mscale,p->o.dscale); ! 165: if (userinput("",buf)) return(0); ! 166: ch = sscanf(typein,"%d:%d",&in1,&in2); ! 167: if (ch == 1) { ! 168: p->o.mscale = in1; ! 169: p->o.dscale = 1; ! 170: } else if (ch == 2) { ! 171: p->o.mscale = in1; ! 172: p->o.dscale = in2; ! 173: } else return(0); ! 174: remouse(cur_state.curx, cur_state.cury, 1); ! 175: return(REDISPLAY); ! 176: } ! 177: ! 178: /* delete object */ ! 179: delobj() ! 180: { register gptr p; ! 181: ! 182: if ((p = cur_state.editee) == NULL) return(0); ! 183: deselect(0); ! 184: remove(p); ! 185: return(0); ! 186: } ! 187: ! 188: /* abort current selection */ ! 189: quit() ! 190: { deselect(REDISPLAY); ! 191: return(0); ! 192: } ! 193: ! 194: /* drop current selection where cursor is */ ! 195: letgo() ! 196: { deselect(UPDATE+REDISPLAY); ! 197: return(0); ! 198: } ! 199: ! 200: /* drop current selection with same offset as last time */ ! 201: lastgo() ! 202: { deselect(UPDATE+USEOFFSET+REDISPLAY); ! 203: return(0); ! 204: } ! 205: ! 206: /* select nearby object */ ! 207: selobj() ! 208: { register gptr p; ! 209: register int in1 = 0; ! 210: ! 211: if ((p = cur_state.editee) == NULL) { ! 212: if ((p = cur_state.curobj->body) == NULL) return(0); ! 213: in1 = 1; ! 214: } else p = p->s.next; ! 215: ! 216: while (1) { ! 217: if (p == NULL) { ! 218: if (!in1) { ! 219: in1 = 1; ! 220: p = cur_state.curobj->body; ! 221: continue; ! 222: } else break; ! 223: } else if (p == cur_state.editee) break; ! 224: ! 225: if (nearby(p)) { selectobj(p,0); break; } ! 226: else p = p->s.next; ! 227: } ! 228: ! 229: return(0); ! 230: } ! 231: ! 232: /* create a new line segment */ ! 233: newline() ! 234: { register gptr p; ! 235: ! 236: if ((p = (gptr)malloc(sizeof(struct segment))) == NULL) ! 237: msg("out of room!"); ! 238: else { ! 239: p->s.type = SEGMENT; ! 240: p->s.x2 = cur_state.curx; ! 241: p->s.y2 = cur_state.cury; ! 242: p->s.angle = 0; ! 243: p->s.cache = NULL; ! 244: newobj(p); ! 245: } ! 246: return(0); ! 247: } ! 248: ! 249: /* finish creation of new object */ ! 250: newobj(p) ! 251: register gptr p; ! 252: { p->s.next = cur_state.curobj->body; ! 253: cur_state.curobj->body = p; ! 254: cur_state.curobj->modified = 1; ! 255: p->s.parent = cur_state.curobj; ! 256: p->s.x1 = cur_state.curx; ! 257: p->s.y1 = cur_state.cury; ! 258: dx = dy = 0; ! 259: ends = 2; ! 260: selectobj(p,1); ! 261: } ! 262: ! 263: /* instantiate an object */ ! 264: instantiate() ! 265: { register gptr p; ! 266: register struct prototype *new; ! 267: char buf[100]; ! 268: ! 269: if (userinput("","name of definition to instantiate: ")) return(0); ! 270: new = read_def(typein); ! 271: if (new->body == NULL) { ! 272: sprintf(buf,"definition for %s not found",new->name); ! 273: msg(buf); ! 274: retdef: free(new->name); ! 275: directory = new->next; /* remove dir entry */ ! 276: free((char *)new); ! 277: return(0); ! 278: }; ! 279: if ((p = (gptr)malloc(sizeof(struct object))) == NULL) { ! 280: msg("out of room!"); ! 281: goto retdef; ! 282: } ! 283: p->o.type = OBJECT; ! 284: p->o.orient = NORTH; ! 285: p->o.proto = new; ! 286: p->o.mscale = p->o.dscale = 1; ! 287: newobj(p); ! 288: return(0); ! 289: } ! 290: ! 291: /* new label */ ! 292: newlabel() ! 293: { register gptr p; ! 294: ! 295: if (userinput("","label: ")) return(0); ! 296: if ((p = (gptr)malloc(sizeof(struct label))) == NULL) { ! 297: msg("out of room!"); ! 298: return(0); ! 299: } ! 300: p->l.type = LABEL; ! 301: p->l.orient = CC; ! 302: if ((p->l.string = malloc((unsigned) (strlen(typein)+1))) == NULL) { ! 303: msg("out of room!"); ! 304: free((char *) p); ! 305: return(0); ! 306: } ! 307: strcpy(p->l.string,typein); ! 308: newobj(p); ! 309: return(0); ! 310: } ! 311: ! 312: /* start editing new .def file */ ! 313: newin() ! 314: { if (userinput("","name of definition to edit: ") || typein[0]==0) ! 315: return(0); ! 316: ! 317: previous = cur_state.curobj; ! 318: cur_state.curobj->recent = cur_state; ! 319: cur_state = read_def(typein)->recent; ! 320: return(REDISPLAY); ! 321: } ! 322: ! 323: /* write out current .def file */ ! 324: newout() ! 325: { if (userinput(cur_state.curobj->name,"name of output file: ")) return(0); ! 326: if (typein[0] == 0) return(0); ! 327: if (strcmp(typein,cur_state.curobj->name) != 0) { ! 328: if (strlen(typein) <= strlen(cur_state.curobj->name)) ! 329: strcpy(cur_state.curobj->name,typein); ! 330: else { ! 331: free(cur_state.curobj->name); ! 332: if ((cur_state.curobj->name = malloc((unsigned) (strlen(typein)+1))) == NULL) { ! 333: msg("out of room!"); ! 334: return(0); ! 335: } ! 336: strcpy(cur_state.curobj->name,typein); ! 337: } ! 338: } ! 339: write_defn(cur_state.curobj); ! 340: banner(); ! 341: return(0); ! 342: } ! 343: ! 344: /* snap cursor to grid */ ! 345: snap() ! 346: { return(remouse(snap_coord(cur_state.curx), ! 347: snap_coord(cur_state.cury), 0)); ! 348: } ! 349: ! 350: snap_coord(coord) ! 351: register int coord; ! 352: { register int mask = ~(cur_state.csize - 1); ! 353: ! 354: coord += cur_state.csize >> 1; ! 355: coord &= mask; ! 356: return(coord); ! 357: } ! 358: ! 359: /* move cursor to the right */ ! 360: mright() ! 361: { return(remouse(cur_state.curx + mult*cur_state.csize, ! 362: cur_state.cury, 0)); ! 363: } ! 364: ! 365: /* move cursor to the left */ ! 366: mleft() ! 367: { return(remouse(cur_state.curx - mult*cur_state.csize, ! 368: cur_state.cury, 0)); ! 369: } ! 370: ! 371: /* move cursor up */ ! 372: mup() ! 373: { return(remouse(cur_state.curx, ! 374: cur_state.cury + mult*cur_state.csize, 0)); ! 375: } ! 376: ! 377: /* move cursor down */ ! 378: mdown() ! 379: { return(remouse(cur_state.curx, ! 380: cur_state.cury - mult*cur_state.csize, 0)); ! 381: } ! 382: ! 383: /* make cursor larger */ ! 384: curup() ! 385: { if (cur_state.csize < 128) cur_state.csize <<= 1; ! 386: return(0); ! 387: } ! 388: ! 389: /* make cursor smaller */ ! 390: curdown() ! 391: { if (cur_state.csize > 1) cur_state.csize >>= 1; ! 392: return(0); ! 393: } ! 394: ! 395: /* multiply multiplier */ ! 396: multiplier() ! 397: { mult <<= 2; ! 398: return(MULTIPLIER); ! 399: } ! 400: ! 401: /* rescale picture */ ! 402: scale() ! 403: { register int ch; ! 404: int in1,in2; ! 405: ! 406: if (userinput("","new scale (screen:defn): ")) return(0); ! 407: ch = sscanf(typein,"%d:%d",&in1,&in2); ! 408: if (ch == 1) { ! 409: cur_state.mscale = in1; ! 410: cur_state.dscale = 1; ! 411: } else if (ch == 2) { ! 412: cur_state.mscale = in1; ! 413: cur_state.dscale = in2; ! 414: } else return(1); ! 415: ! 416: return(RECENTER); ! 417: } ! 418: ! 419: /* Scale picture up/down by factor of +n/-n: ! 420: */ ! 421: ! 422: magnify(n) ! 423: { if (n<0) /* Make it smaller? */ ! 424: { n = -n; ! 425: if ((cur_state.mscale % n) == 0) cur_state.mscale /= n; ! 426: else cur_state.dscale *= n; ! 427: } ! 428: else if (n > 0) ! 429: { if ((cur_state.dscale % n) == 0) cur_state.dscale /= n; ! 430: else cur_state.mscale *= n; ! 431: } ! 432: return RECENTER; ! 433: } ! 434: ! 435: scaleup() ! 436: { return magnify(4); ! 437: } ! 438: scaledn() ! 439: { return magnify(-4); ! 440: } ! 441: ! 442: /* move origin */ ! 443: neworg() ! 444: { adj_org(cur_state.curobj,cur_state.curx,cur_state.cury); ! 445: cur_state.curobj->modified = 1; ! 446: remouse(0, 0, 0); ! 447: return(RECENTER); ! 448: } ! 449: ! 450: /* move cursor to origin */ ! 451: home() ! 452: { remouse(0, 0, 0); ! 453: return(RECENTER); ! 454: } ! 455: ! 456: /* finished editing current picture */ ! 457: stop() ! 458: { deselect(UPDATE+REDISPLAY); ! 459: return(DONE); ! 460: } ! 461: ! 462: /* toggle grid flag */ ! 463: toggle() ! 464: { cur_state.grid ^= 1; ! 465: return(REDISPLAY); ! 466: } ! 467: ! 468: /* get some input from the user, leave in typein array. Return 1 ! 469: * if user aborted, 0 if he thinks there's something worth reading. ! 470: */ ! 471: userinput(seed,cue) ! 472: char *seed,*cue; ! 473: { register int ch; ! 474: register char *p = typein; ! 475: char temp[100],save[100]; ! 476: int curcol,times,mch; ! 477: ! 478: strcpy(typein,seed); ! 479: sprintf(temp,cue); ! 480: prompt = temp; ! 481: curcol = strlen(prompt); ! 482: times = 1; ! 483: mch = mousechanged; ! 484: mousechanged = 0; ! 485: goto redraw; ! 486: ! 487: while (1) { ! 488: if (mousechanged || UserReady()) { ! 489: if (mousechanged) { ! 490: mch = 1; ! 491: mousechanged = 0; ! 492: continue; ! 493: } ! 494: switch (ch = UserChar() & 0xFF) { ! 495: default: times = 1; ! 496: if (ch < ' ' || ch > 0177) { ! 497: Beep(); ! 498: break; ! 499: } ! 500: if (*p == 0) { /* char at end */ ! 501: *p++ = ch; ! 502: *p = 0; ! 503: disp_char(ch,curcol * chrwid,0,0,NORMAL,1); ! 504: curcol += 1; ! 505: break; ! 506: } ! 507: strcpy(save,p); /* insert char */ ! 508: *p++ = ch; ! 509: curcol += 1; ! 510: strcpy(p,save); ! 511: goto redraw; ! 512: ! 513: case 'C'-0100: ! 514: case 'Q'-0100: ! 515: case 'G'-0100: ! 516: prompt = NULL; ! 517: clearprompt(); ! 518: mousechanged = mch; ! 519: return(1); ! 520: ! 521: case 'A'-0100: ! 522: p = typein; ! 523: curcol = strlen(prompt); ! 524: ctldone: times = 1; ! 525: break; ! 526: ! 527: case 'B'-0100: ! 528: case 'H'-0100: ! 529: while (p!=typein && times>0) { ! 530: times -= 1; ! 531: p -= 1; ! 532: curcol -= 1; ! 533: } ! 534: goto ctldone; ! 535: ! 536: case 'D'-0100: ! 537: while (*p && times>0) { ! 538: strcpy(p,p+1); ! 539: times -= 1; ! 540: } ! 541: goto redraw; ! 542: ! 543: case 'E'-0100: ! 544: for (p=prompt, curcol=0; *p; p+=1, curcol+=1); ! 545: for (p = typein; *p; p += 1) curcol += 1; ! 546: goto ctldone; ! 547: ! 548: case 'F'-0100: ! 549: while (*p && times>0) { ! 550: times -= 1; ! 551: p += 1; ! 552: curcol += 1; ! 553: } ! 554: goto ctldone; ! 555: ! 556: case 'K'-0100: ! 557: *p = 0; ! 558: goto redraw; ! 559: ! 560: case 'Y'-0100: ! 561: new_window(&cur_state,cur_state.curx,cur_state.cury); ! 562: case 'L'-0100: ! 563: redisplay(); ! 564: goto redraw; ! 565: ! 566: case 'U'-0100: ! 567: times <<= 2; ! 568: break; ! 569: ! 570: case '\r': ! 571: case '\n': ! 572: case 033: prompt = NULL; ! 573: clearprompt(); ! 574: mousechanged = mch; ! 575: return(0); ! 576: ! 577: case 0177: ! 578: while (p!=typein && times>0) { ! 579: strcpy(p-1,p); ! 580: p -= 1; ! 581: curcol -= 1; ! 582: times -= 1; ! 583: } ! 584: goto redraw; ! 585: ! 586: redraw: msg(prompt); ! 587: incol += disp_str(typein, incol * chrwid, 0, 0, NORMAL,1); ! 588: times = 1; ! 589: break; ! 590: } ! 591: } else { ! 592: incol = curcol; ! 593: DpyUp(1); ! 594: } ! 595: } ! 596: } ! 597: ! 598: /* given center, calculate various window coords */ ! 599: new_window(s,cx,cy) ! 600: register struct state *s; ! 601: { int wx,wy; ! 602: ! 603: /* half-width of window in defn coords */ ! 604: wx = (wmaxx - wminx) >> 1; ! 605: wx *= s->dscale; ! 606: wx /= s->mscale; ! 607: ! 608: /* half-height of window in defn coords */ ! 609: wy = (wmaxy - wminy) >> 1; ! 610: wy *= s->dscale; ! 611: wy /= s->mscale; ! 612: ! 613: s->worgx = cx - wx; ! 614: s->worgy = cy - wy; ! 615: s->wmaxx = cx + wx; ! 616: s->wmaxy = cy + wy; ! 617: } ! 618: ! 619: #define abs(x) ((x) < 0 ? -(x) : (x)) ! 620: ! 621: /* see if an object is "near enough" to the cursor, sets dx, dy, ends */ ! 622: nearby(p) ! 623: register gptr p; ! 624: { switch (p->s.type) { ! 625: case SEGMENT: dx = p->s.x2 - cur_state.curx; ! 626: dy = p->s.y2 - cur_state.cury; ! 627: if (abs(dx) <= cur_state.csize && ! 628: abs(dy) <= cur_state.csize) { ! 629: ends = 2; ! 630: return(1); ! 631: } ! 632: case OBJECT: ! 633: case LABEL: dx = p->s.x1 - cur_state.curx; ! 634: dy = p->s.y1 - cur_state.cury; ! 635: if (abs(dx) <= cur_state.csize && ! 636: abs(dy) <= cur_state.csize) { ! 637: ends = 1; ! 638: return(1); ! 639: } ! 640: break; ! 641: } ! 642: ! 643: return(0); ! 644: } ! 645: ! 646: /* unselect currently selected object: ! 647: * update & UPDATE update object's info ! 648: * + USEOFFSET -- use lxoff, lyoff ! 649: * update & REDISPLAY redisplay when done ! 650: */ ! 651: deselect(update) ! 652: { register gptr p = cur_state.editee; ! 653: register int temp; ! 654: gptr save; ! 655: ! 656: if (p == NULL) return; /* nothing to do */ ! 657: ! 658: if (update & UPDATE) { ! 659: switch (p->s.type) { ! 660: case SEGMENT: if (cur_state.whichend == 2) { ! 661: if (update & USEOFFSET) { ! 662: p->s.x2 += cur_state.lxoff; ! 663: p->s.y2 += cur_state.lyoff; ! 664: } else { ! 665: temp = cur_state.curx + cur_state.xoff; ! 666: cur_state.lxoff = temp - p->s.x2; ! 667: p->s.x2 = temp; ! 668: temp = cur_state.cury + cur_state.yoff; ! 669: cur_state.lyoff = temp - p->s.y2; ! 670: p->s.y2 = temp; ! 671: } ! 672: break; ! 673: }; ! 674: case LABEL: ! 675: case OBJECT: if (update & USEOFFSET) { ! 676: p->s.x1 += cur_state.lxoff; ! 677: p->s.y1 += cur_state.lyoff; ! 678: } else { ! 679: temp = cur_state.curx + cur_state.xoff; ! 680: cur_state.lxoff = temp - p->s.x1; ! 681: p->s.x1 = temp; ! 682: temp = cur_state.cury + cur_state.yoff; ! 683: cur_state.lyoff = temp - p->s.y1; ! 684: p->s.y1 = temp; ! 685: } ! 686: break; ! 687: } ! 688: cur_state.curobj->modified = 1; ! 689: } ! 690: ! 691: if (p->s.type == SEGMENT) newalist(&p->s,p->s.x1,p->s.y1,p->s.x2,p->s.y2); ! 692: ! 693: cur_state.editee = NULL; ! 694: ! 695: /* to update display we only have to redraw selected object */ ! 696: if (update & REDISPLAY) { ! 697: save = p->s.next; ! 698: p->s.next = NULL; ! 699: display(p,0,0,NORTH,1,1,NORMAL); ! 700: p->s.next = save; ! 701: } ! 702: } ! 703: ! 704: /* update database to reflect newly selected object */ ! 705: selectobj(p,new) ! 706: register gptr p; ! 707: { deselect(UPDATE+REDISPLAY); ! 708: cur_state.editee = p; ! 709: cur_state.xoff = 0; ! 710: cur_state.yoff = 0; ! 711: cur_state.whichend = ends; ! 712: if (!new) { ! 713: if (remouse(cur_state.curx+dx, cur_state.cury+dy,1)) { ! 714: new_window(&cur_state,cur_state.curx+dx,cur_state.cury+dy); ! 715: remouse(cur_state.curx, cur_state.cury, 1); ! 716: } ! 717: redisplay(); ! 718: } ! 719: } ! 720: ! 721: /* redisplay entire screen */ ! 722: redisplay() ! 723: { ! 724: clearscreen(); ! 725: if (cur_state.curobj != NULL) { ! 726: display(cur_state.curobj->body,0,0,NORTH,1,1,NORMAL); ! 727: ctext("*",0,0,CC,NORMAL); ! 728: } ! 729: ! 730: /* grid points fall every csize points */ ! 731: if (cur_state.grid) disp_grid(); ! 732: ! 733: return(0); /* return code when used as a command */ ! 734: } ! 735: ! 736: /* return appropriately oriented x and y coords */ ! 737: xorient(x,y,orient) ! 738: { switch (orient) { ! 739: case NORTH: return(x); ! 740: case EAST: return(y); ! 741: case SOUTH: return(-x); ! 742: case WEST: return(-y); ! 743: case RNORTH: return(-x); ! 744: case REAST: return(-y); ! 745: case RSOUTH: return(x); ! 746: case RWEST: return(y); ! 747: } ! 748: /*NOTREACHED*/ ! 749: } ! 750: ! 751: yorient(x,y,orient) ! 752: { switch (orient) { ! 753: case NORTH: return(y); ! 754: case EAST: return(-x); ! 755: case SOUTH: return(-y); ! 756: case WEST: return(x); ! 757: case RNORTH: return(y); ! 758: case REAST: return(-x); ! 759: case RSOUTH: return(-y); ! 760: case RWEST: return(x); ! 761: } ! 762: /*NOTREACHED*/ ! 763: } ! 764: ! 765: /* display objects with specified translation and rotation */ ! 766: display(o,x,y,orient,mscale,dscale,dflag) ! 767: register gptr o; ! 768: { short tx,ty; ! 769: short ex,ey; ! 770: ! 771: while (o != NULL) { ! 772: tx = xorient(o->l.x, o->l.y, orient); ! 773: tx *= mscale; tx /= dscale; ! 774: tx += x; ! 775: ty = yorient(o->l.x, o->l.y, orient); ! 776: ty *= mscale; ty /= dscale; ! 777: ty += y; ! 778: ! 779: if (cur_state.editee != o) switch (o->s.type) { ! 780: case LABEL: ! 781: ctext(o->l.string,tx,ty,lcomp[orient][o->l.orient],dflag); ! 782: break; ! 783: ! 784: case OBJECT: ! 785: display(o->o.proto->body,tx,ty, ! 786: ocomp[orient][o->o.orient], ! 787: mscale * o->o.mscale, dscale * o->o.dscale, ! 788: dflag); ! 789: break; ! 790: ! 791: case SEGMENT: ! 792: if (o->s.cache != NULL) { ! 793: display(o->s.cache,x,y,orient,mscale,dscale,dflag); ! 794: break; ! 795: } ! 796: ex = xorient(o->s.x2, o->s.y2, orient); ! 797: ex *= mscale; ex /= dscale; ! 798: ex += x; ! 799: ey = yorient(o->s.x2, o->s.y2, orient); ! 800: ey *= mscale; ey /= dscale; ! 801: ey += y; ! 802: cline(tx,ty,ex,ey,dflag); ! 803: break; ! 804: } ! 805: o = o->s.next; ! 806: } ! 807: } ! 808: ! 809: /* output a message on the bottom-most line */ ! 810: msg(string) ! 811: char *string; ! 812: { ! 813: clearprompt(); ! 814: incol += disp_str(string, incol * chrwid, 0, 0, NORMAL,1); ! 815: } ! 816: ! 817: /* display text string with proper orientation clipped by current window */ ! 818: ctext(string,x,y,orient,dflag) ! 819: register char *string; ! 820: { register int i = (strlen(string) * chrwid) >> 1; ! 821: ! 822: /* first translate and scale to the window coord system */ ! 823: y -= cur_state.worgy; ! 824: x -= cur_state.worgx; ! 825: ! 826: y *= cur_state.mscale; y /= cur_state.dscale; ! 827: x *= cur_state.mscale; x /= cur_state.dscale; ! 828: ! 829: /* adjust for character orientation */ ! 830: switch (orient) { ! 831: case CC: x -= i; y -= (chrhgt >> 1); break; ! 832: case TC: x -= i; y -= chrhgt; break; ! 833: case BC: x -= i; break; ! 834: case CL: y -= (chrhgt >> 1); break; ! 835: case TL: y -= chrhgt; break; ! 836: case BL: break; ! 837: case CR: x -= i+i; y -= (chrhgt >> 1); break; ! 838: case TR: x -= i+i; y -= chrhgt; break; ! 839: case BR: x -= i+i; ! 840: } ! 841: ! 842: /* only display chars that lie within current window */ ! 843: x += wminx; ! 844: y += wminy; ! 845: if (y <= wmaxy && y+chrhgt >= wminy && ! 846: x <= wmaxx && x+(strlen(string)*chrwid) >= wminx) ! 847: disp_str(string,x,y,0,dflag,0); ! 848: } ! 849: ! 850: /* draw a clipped vector */ ! 851: #define code(x,y) \ ! 852: ((x<wminx ? 1 : x>wmaxx ? 2 : 0) + (y<wminy ? 4 : y>wmaxy ? 8 : 0)) ! 853: ! 854: cline(fx,fy,tx,ty,dflag) ! 855: { ! 856: ! 857: /* first translate and scale to the window coord system */ ! 858: fx -= cur_state.worgx; ! 859: fy -= cur_state.worgy; ! 860: tx -= cur_state.worgx; ! 861: ty -= cur_state.worgy; ! 862: ! 863: fy *= cur_state.mscale; fy /= cur_state.dscale; ! 864: fx *= cur_state.mscale; fx /= cur_state.dscale; ! 865: ty *= cur_state.mscale; ty /= cur_state.dscale; ! 866: tx *= cur_state.mscale; tx /= cur_state.dscale; ! 867: ! 868: fx += wminx; fy += wminy; ! 869: tx += wminx; ty += wminy; ! 870: ! 871: if ((code(fx,fy) & code(tx,ty)) == 0) ! 872: line(fx,fy,tx,ty,dflag); ! 873: } ! 874: ! 875: /* display grid points at csize intervals */ ! 876: disp_grid() ! 877: { int x,y,incrx,incry; ! 878: ! 879: /* find window coord of lower left grid point */ ! 880: x = cur_state.worgx + cur_state.csize - 1; ! 881: x &= ~(cur_state.csize - 1); ! 882: x -= cur_state.worgx; ! 883: x *= cur_state.mscale; x /= cur_state.dscale; ! 884: ! 885: y = cur_state.worgy + cur_state.csize - 1; ! 886: y &= ~(cur_state.csize - 1); ! 887: y -= cur_state.worgy; ! 888: y *= cur_state.mscale; y /= cur_state.dscale; ! 889: ! 890: x += wminx; ! 891: y = wmaxy - y - wminy; ! 892: ! 893: incrx = (cur_state.csize * cur_state.mscale) / cur_state.dscale; ! 894: if (incrx <= 0) incrx = 8; ! 895: else while (incrx < 8) incrx <<= 1; ! 896: incry = incrx; ! 897: ! 898: drawgrid(x,y,incrx,incry); ! 899: } ! 900: ! 901: /* Xor drawing cursor and selected object */ ! 902: dcurxor() ! 903: { register gptr p; ! 904: int x,y; ! 905: ! 906: if (cur_state.curobj == NULL) return; /* no object on screen */ ! 907: ! 908: if ((p = cur_state.editee) != NULL) { ! 909: if (p->s.type == SEGMENT && (redo || (p->s.angle != 0 && ! 910: (cur_state.curx!=cur_state.oldx || ! 911: cur_state.cury!=cur_state.oldy)))) { ! 912: cur_state.oldx = cur_state.curx; ! 913: cur_state.oldy = cur_state.cury; ! 914: redo = 0; ! 915: if (cur_state.whichend == 2) ! 916: newalist(&p->s,p->s.x1,p->s.y1, ! 917: cur_state.curx + cur_state.xoff, ! 918: cur_state.cury + cur_state.yoff); ! 919: else ! 920: newalist(&p->s,cur_state.curx + cur_state.xoff, ! 921: cur_state.cury + cur_state.yoff, ! 922: p->s.x2,p->s.y2); ! 923: } ! 924: switch(p->s.type) { ! 925: case SEGMENT: ! 926: if (p->s.cache != NULL) { ! 927: for (p = p->s.cache; p != NULL; p = p->s.next) ! 928: cline(p->s.x1,p->s.y1,p->s.x2,p->s.y2,HIGHLIGHT); ! 929: break; ! 930: } ! 931: if (cur_state.whichend == 2) { x = p->s.x1; y = p->s.y1; } ! 932: else { x = p->s.x2; y = p->s.y2; } ! 933: cline(x,y, ! 934: cur_state.curx + cur_state.xoff, ! 935: cur_state.cury + cur_state.yoff,HIGHLIGHT); ! 936: break; ! 937: ! 938: case LABEL: ! 939: ctext(p->l.string, ! 940: cur_state.curx + cur_state.xoff, ! 941: cur_state.cury + cur_state.yoff, ! 942: p->l.orient, ! 943: HIGHLIGHT); ! 944: break; ! 945: ! 946: case OBJECT: ! 947: display(p->o.proto->body, ! 948: cur_state.curx + cur_state.xoff, ! 949: cur_state.cury + cur_state.yoff, ! 950: p->o.orient,p->o.mscale,p->o.dscale, ! 951: HIGHLIGHT); ! 952: return; /* no cursor needed here */ ! 953: } ! 954: } ! 955: ! 956: /* draw x-shaped graphic cursor */ ! 957: cline(cur_state.curx - cur_state.csize, ! 958: cur_state.cury - cur_state.csize, ! 959: cur_state.curx + cur_state.csize, ! 960: cur_state.cury + cur_state.csize, ! 961: HIGHLIGHT); ! 962: cline(cur_state.curx - cur_state.csize, ! 963: cur_state.cury + cur_state.csize, ! 964: cur_state.curx + cur_state.csize, ! 965: cur_state.cury - cur_state.csize, ! 966: HIGHLIGHT); ! 967: } ! 968: ! 969: /* Help stuff */ ! 970: Help() ! 971: { struct prototype *help_proto; ! 972: char buf[100]; ! 973: ! 974: help_proto = read_def(HELPFILE); /* Load the file, if any. */ ! 975: ! 976: if (help_proto->body == NULL) { ! 977: sprintf(buf, "Can't read '%s.DEF' -- NO HELP", HELPFILE); ! 978: msg(buf); ! 979: return 0; ! 980: } ! 981: previous = cur_state.curobj; ! 982: if (cur_state.curobj) cur_state.curobj->recent = cur_state; ! 983: cur_state = help_proto->recent; ! 984: return REDISPLAY; ! 985: } ! 986: ! 987: /* Adjust coordinates in body of an object by the origin of that object. ! 988: * This routine is called after an object is edited, so that an adjusted ! 989: * subpicture origin is reflected immediately in pictures which reference ! 990: * it. ! 991: */ ! 992: adj_org(p,adjx,adjy) ! 993: register struct prototype *p; ! 994: { register gptr o; ! 995: struct prototype temp; ! 996: ! 997: for (o = p->body; o != NULL; o = o->s.next) switch (o->s.type) { ! 998: case SEGMENT: o->s.x1 -= adjx; ! 999: o->s.y1 -= adjy; ! 1000: o->s.x2 -= adjx; ! 1001: o->s.y2 -= adjy; ! 1002: if (o->s.cache) { ! 1003: temp.body = o->s.cache; ! 1004: adj_org(&temp,adjx,adjy); ! 1005: } ! 1006: break; ! 1007: ! 1008: case LABEL: o->l.x -= adjx; ! 1009: o->l.y -= adjy; ! 1010: break; ! 1011: ! 1012: case OBJECT: o->o.x -= adjx; ! 1013: o->o.y -= adjy; ! 1014: break; ! 1015: } ! 1016: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.