|
|
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.