Annotation of 43BSD/contrib/X/xgedit/gcmd.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.