Annotation of 43BSDReno/contrib/jove/mac.c, revision 1.1.1.1

1.1       root        1: /***************************************************************************
                      2:  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
                      3:  * is provided to you without charge, and with no warranty.  You may give  *
                      4:  * away copies of JOVE, including sources, provided that this notice is    *
                      5:  * included in all the files.                                              *
                      6:  ***************************************************************************/
                      7: 
                      8: 
                      9: /* (C) 1986, 1987, 1988 Ken Mitchum. This code is intended only for use with Jove. */
                     10: 
                     11: #include "tune.h"
                     12: #ifdef MAC
                     13: #define _mac
                     14: #include <MacTypes.h>
                     15: #include "jove.h"
                     16: #include <QuickDraw.h>
                     17: #include <WindowMgr.h>
                     18: #include <FontMgr.h>
                     19: #include <ListMgr.h>
                     20: #include <EventMgr.h>
                     21: #include <ControlMgr.h>
                     22: #include <DialogMgr.h>
                     23: #include <ResourceMgr.h>
                     24: #include <ToolboxUtil.h>
                     25: #include <HFS.h>
                     26: #include <StdFilePkg.h>
                     27: #include <MenuMgr.h>
                     28: #include <pascal.h>
                     29: #include <errno.h>
                     30: #include <SegmentLdr.h>
                     31: #include "mac.h"
                     32: #include "termcap.h"
                     33: 
                     34: /***************************************************/
                     35: 
                     36: /* these normally reside in "tune.c" which we don't use */
                     37: 
                     38: char *CmdDb;   /* see InitMac() */
                     39: char *p_tempfile = ".jrecXXX";
                     40: char *d_tempfile = ".joveXXX";
                     41: char *Joverc = ".joverc";
                     42: 
                     43: 
                     44: void putcurs(),curset(),putp(),dellines(),inslines();
                     45: 
                     46: static Rect LimitRect; /* bounds we can't move past */
                     47: 
                     48: struct wind_config {
                     49:        int w_width;    /* pixel width of the Mac window */
                     50:        int     w_height;
                     51:        int     w_rows; /* rows of characters which fit the window */
                     52:        int     w_cols;
                     53: } wc_std, wc_user, *wc;
                     54: 
                     55: static WindowPtr theScreen;
                     56: 
                     57: int
                     58:        errno,
                     59:        EventCmd,
                     60:        Keyonly,
                     61:        Macmode,
                     62:        Bufchange,
                     63:        Modechange,
                     64:        Windchange;
                     65: 
                     66: /* Initialization Routines. */
                     67: 
                     68: void InitBinds()
                     69: {
                     70:        struct cmd *c;
                     71:        data_obj **p;
                     72:        int i;
                     73: 
                     74:        p = MainKeys;
                     75:        for(i= 0; i < NCHARS; i++) {
                     76:                c = (struct cmd *) *p;
                     77:                c->c_map = F_MAINMAP;
                     78:                c->c_key = i;
                     79:                p++;
                     80:        }
                     81: 
                     82:        p = EscKeys;
                     83:        for(i= 0; i < NCHARS; i++) {
                     84:                c = (struct cmd *) *p;
                     85:                c->c_map = F_PREF1MAP;
                     86:                c->c_key = i;
                     87:                p++;
                     88:        }
                     89:        p = CtlxKeys;
                     90:        for(i= 0; i < NCHARS; i++) {
                     91:                c = (struct cmd *) *p;
                     92:                c->c_map = F_PREF2MAP;
                     93:                c->c_key = i;
                     94:                p++;
                     95:        }
                     96: 
                     97: }
                     98: 
                     99: static WindowPtr window;
                    100: static Rect r;
                    101: static CursHandle cross;
                    102: 
                    103: void InitEvents()
                    104: {
                    105:        void InitSysMenu();
                    106: 
                    107:        window = theScreen;
                    108:        InitSysMenu();
                    109:        SetRect(&r,window->portRect.left,
                    110:        window->portRect.top,
                    111:        window->portRect.right - SCROLLWIDTH,
                    112:        window->portRect.bottom - SCROLLWIDTH);
                    113:        cross = GetCursor(crossCursor);
                    114: }
                    115: 
                    116: void MacInit()
                    117: {
                    118:        char *gethome();
                    119:        void tn_init();
                    120: 
                    121:        tn_init();
                    122:        getdir();
                    123:        gethome();      /* before anyone changes it */
                    124:        CmdDb = malloc(strlen(gethome()) + 10);
                    125:        strcpy(CmdDb,gethome());
                    126:        strcat(CmdDb,"/cmds.doc");
                    127:        InitBinds();
                    128: }
                    129: 
                    130: 
                    131: /* dummy routines. */
                    132: 
                    133: int dummy(){}
                    134: 
                    135: SIGRESULT (*signal(sig,func)) proto((int))
                    136: int sig;
                    137: SIGRESULT (*func) proto((int));
                    138: {
                    139:        return(&dummy);
                    140: }
                    141: 
                    142: dorecover() {}
                    143: 
                    144: 
                    145: /* Surrogate unix-style file i/o routines for Jove. These replace the
                    146:    routines distributed in the libraries. They work with Jove, but may
                    147:    not be general enough for other purposes. */
                    148: 
                    149: #include <io.h>
                    150: #define NFILES 10
                    151: 
                    152: /* #define fsetup(p) { \
                    153:  *     (p).ioCompletion = 0; \
                    154:  *     (p).ioVRefNum = cur_vol; \
                    155:  *     (p).ioDirID = cur_dir; \
                    156:  *     (p).ioFVersNum = 0; \
                    157:  * }
                    158:  * #define isetup(p) {(p).ioCompletion = 0; (p).ioVRefNum = cur_vol;}
                    159:  */
                    160: 
                    161: static int cur_vol;    /* Disk or volume number */
                    162: static long cur_dir;   /* Directory number */
                    163: static int cur_vref;   /* ugh.. Vref for volume + directory */
                    164: 
                    165: struct ftab {
                    166:        int inuse;      /* 0 = closed 1 = binary 2 = text*/
                    167:        int refnum;     /* Mac file reference number */
                    168: } ft[NFILES];
                    169: 
                    170: fsetup(p)
                    171: HParmBlkPtr p;
                    172: {
                    173:        byte_zero(p,sizeof(HParamBlockRec));
                    174:        p->fileParam.ioVRefNum = cur_vol;
                    175:        p->fileParam.ioDirID = cur_dir;
                    176:        p->fileParam.ioFVersNum = 0;
                    177: }
                    178: 
                    179: isetup(p)
                    180: HIOParam *p;
                    181: {
                    182:        byte_zero(p,sizeof(HIOParam));
                    183:        p->ioVRefNum = cur_vol;
                    184: }
                    185: 
                    186: 
                    187: /* Kludge to convert Macintosh error codes to something like Unix. */
                    188: 
                    189: static int cvt_err(err)        /* some of these don't make sense... */
                    190: {
                    191:        switch(err) {
                    192:                case noErr: errno = 0; return(0);
                    193:                case dirFulErr: errno = ENOSPC; break;
                    194:                case dskFulErr: errno = ENOSPC; break;
                    195:                case nsvErr: errno = ENOENT; break;
                    196:                case ioErr: errno = EIO; break;
                    197:                case bdNamErr: errno = EINVAL; break;
                    198:                case fnOpnErr: errno = EBADF; break;    /* dubious... */
                    199:                case eofErr: errno = ESPIPE; break;             /* ditto */
                    200:                case posErr: errno = ESPIPE; break;
                    201:                case mFulErr:
                    202:                case tmfoErr:
                    203:                case fnfErr: errno = ENOENT; break;
                    204:                case wPrErr: errno = EROFS; break;
                    205:                case fLckdErr: errno = EACCES; break;
                    206:                case fBsyErr: errno = EBUSY; break;
                    207:                case dupFNErr: errno = EEXIST; break;
                    208:                case opWrErr:
                    209:                case paramErr: errno = EINVAL; break;
                    210:                case rfNumErr: errno = EBADF; break;
                    211:                case gfpErr:
                    212:                case volOffLinErr: errno = ENODEV; break;
                    213:                case permErr: errno = EACCES; break;
                    214:                case volOnLinErr: errno = ENODEV; break;
                    215:                case nsDrvErr: errno = ENODEV; break;
                    216:                case noMacDskErr: errno = EIO; break;
                    217:                case extFSErr: errno = EIO; break;
                    218:                case fsRnErr:
                    219:                case badMDBErr:
                    220:                case wrPermErr: errno = EPERM; break;
                    221:                default: errno = ENOENT;
                    222:        }
                    223:        return(-1);
                    224: }
                    225: 
                    226: static char *cvt_fnm(file)
                    227: char *file;
                    228: {
                    229:        static char nm[255];
                    230:        char *t;
                    231: 
                    232: 
                    233:        if(*file == '/') strcpy(nm,file + 1); /* full path */
                    234:        else {
                    235:                if(strchr(file + 1, '/') != NULL)
                    236:                        strcpy(nm,"/"); /* make a partial pathname */
                    237:                else *nm = '\0';
                    238:                strcat(nm,file);
                    239:        }
                    240:        t = nm;
                    241:        while(*t) {
                    242:                if(*t == '/') *t = ':';
                    243:                t++;
                    244:        }
                    245:        return(nm);
                    246: }
                    247: 
                    248: int creat(name,perm)   /* permission mode is irrelevant on a Mac */
                    249: char *name;
                    250: {
                    251:        int fd, err;
                    252:        char *nm;
                    253:        HParamBlockRec p;
                    254: 
                    255:        if(is_dir(name)) {
                    256:                errno = EACCES;
                    257:                return(-1);
                    258:        }
                    259:        nm = cvt_fnm(name);     /* convert filename to Mac type name */
                    260:        CtoPstr(nm);
                    261:        for(fd = 0; fd < NFILES && ft[fd].inuse; fd++);
                    262:        if(fd == NFILES) {
                    263:                errno = EMFILE;
                    264:                return(-1);
                    265:        }
                    266:        fsetup(&p);     /* try to delete it, whether it is there or not. */
                    267:        p.fileParam.ioNamePtr = (StringPtr) nm;
                    268:        if((err = PBHDelete(&p,0)) != noErr && err != fnfErr) return(cvt_err(err));
                    269:        if(do_creat(&p,nm) != 0) return(-1);
                    270:        else {
                    271:                ft[fd].inuse++;
                    272:                ft[fd].refnum = p.ioParam.ioRefNum;
                    273:                return(fd + 1);
                    274:        }
                    275: }
                    276: 
                    277: int open(name,mode)
                    278: char *name;
                    279: {
                    280:        int fd, err;
                    281:        char *nm;
                    282:        HParamBlockRec p;
                    283: 
                    284:        if(is_dir(name)) {
                    285:                errno = EACCES;
                    286:                return(-1);
                    287:        }
                    288: 
                    289:        nm = cvt_fnm(name);     /* convert filename to Mac type name */
                    290:        CtoPstr(nm);
                    291:        for(fd = 0; fd < NFILES && ft[fd].inuse; fd++);
                    292:        if(fd == NFILES) {
                    293:                errno = EMFILE;
                    294:                return(-1);
                    295:        }
                    296:        fsetup(&p);
                    297:        if((mode & 3) == O_RDONLY) p.ioParam.ioPermssn = fsRdPerm;
                    298:        if((mode & 3) == O_WRONLY) p.ioParam.ioPermssn = fsWrPerm;
                    299:        if((mode & 3) == O_RDWR) p.ioParam.ioPermssn = fsRdWrPerm;
                    300:        p.ioParam.ioNamePtr = (StringPtr) nm;
                    301:        p.ioParam.ioMisc = 0;
                    302:        if((err = PBHOpen(&p,0)) != noErr && err != fnfErr) return(cvt_err(err));
                    303:        if(err == noErr && mode & O_CREAT && mode & O_EXCL) {
                    304:                PBClose(&p,0);
                    305:                errno = EEXIST;
                    306:                return(-1);
                    307:        }
                    308:        if(err == fnfErr) {
                    309:                if(mode & O_CREAT) {
                    310:                        if(do_creat(&p,nm) != 0) return(-1);
                    311:                } else {
                    312:                        errno = ENOENT;
                    313:                        return(-1);
                    314:                }
                    315:        }
                    316:        ft[fd].inuse++;
                    317:        ft[fd].refnum = p.ioParam.ioRefNum;
                    318:        if(mode & O_APPEND)     p.ioParam.ioPosMode = fsFromLEOF;
                    319:        else p.ioParam.ioPosMode = fsFromStart;
                    320:        p.ioParam.ioPosOffset = 0;
                    321:        if((err = PBSetFPos(&p,0)) != noErr) {
                    322:                ft[fd].inuse = 0;
                    323:                return(cvt_err(err));
                    324:        }
                    325:        errno = 0;
                    326:        return(fd + 1);
                    327: }
                    328: 
                    329: static int do_creat(p,nm)
                    330: HParmBlkPtr p;
                    331: char *nm;
                    332: {
                    333:        int err;
                    334: 
                    335:        fsetup(p);
                    336:        p->fileParam.ioNamePtr = (StringPtr) nm;
                    337:        if((err = PBHCreate(p,0)) != noErr) return(cvt_err(err));
                    338:        fsetup(p);
                    339:        p->fileParam.ioNamePtr = (StringPtr) nm;
                    340:        p->fileParam.ioFDirIndex = 0;
                    341:        if((err = PBHGetFInfo(p,0)) != noErr) return(cvt_err(err));
                    342:        p->fileParam.ioDirID = cur_dir;
                    343:        p->fileParam.ioFlFndrInfo.fdType = 'TEXT';
                    344:        p->fileParam.ioFlFndrInfo.fdCreator = 'JV01';
                    345:        p->fileParam.ioFlFndrInfo.fdFlags = 0;
                    346:        p->fileParam.ioFVersNum = 0;
                    347:        if((err = PBHSetFInfo(p,0)) != noErr) return(cvt_err(err));
                    348:        fsetup(p);
                    349:        p->ioParam.ioNamePtr = (StringPtr) nm;
                    350:        p->ioParam.ioPermssn = fsRdWrPerm;
                    351:        p->ioParam.ioMisc = 0;
                    352:        if(cvt_err(PBHOpen(p,0))) return(-1);
                    353:        return(0);
                    354: }
                    355: 
                    356: 
                    357: int close(fd)
                    358: {
                    359:        int err;
                    360:        HParamBlockRec p;
                    361: 
                    362:        fsetup(&p);
                    363:        p.ioParam.ioRefNum = ft[--fd].refnum;
                    364:        ft[fd].inuse = 0;
                    365: /*     if(cvt_err(PBFlushFile(&p,0)) < 0) return(-1);
                    366:        fsetup(&p); */
                    367:        if(cvt_err(PBClose(&p,0)) < 0) return(-1);
                    368:        fsetup(&p);
                    369:        p.ioParam.ioNamePtr = 0;
                    370:        if(cvt_err(PBFlushVol(&p,0)) < 0) return(-1);
                    371: }
                    372: 
                    373: int read(fd,buf,n)
                    374: char *buf;
                    375: unsigned n;
                    376: {
                    377:        int err;
                    378:        IOParam p;
                    379:        if(fd == 0) return(con_read(buf,n));
                    380:        if(ft[--fd].inuse == 0) {
                    381:                errno = EBADF;
                    382:                return(-1);
                    383:        }
                    384:        isetup(&p);
                    385:        p.ioRefNum = ft[fd].refnum;
                    386:        p.ioBuffer = buf;
                    387:        p.ioReqCount = n;
                    388:        p.ioPosMode = fsFromMark;
                    389:        p.ioPosOffset = 0;
                    390:        if((err = PBRead(&p,0)) != noErr && err != eofErr) {
                    391:                cvt_err(err);
                    392:                return(-1);
                    393:        }
                    394:        while(n--) {
                    395:                if(*buf == '\r') *buf = '\n';   /* convert from Mac style */
                    396:                buf++;
                    397:        }
                    398:        errno = 0;
                    399:        return(p.ioActCount);
                    400: }
                    401: 
                    402: int write(fd,buf,n)
                    403: char *buf;
                    404: unsigned n;
                    405: {
                    406:        int err;
                    407:        IOParam p;
                    408:        char *obuf, *s;
                    409: 
                    410:        if(fd == 0) return(con_write(buf,n));
                    411: 
                    412:        s = obuf = malloc(n + 1);
                    413:        if(obuf == 0)  return(-1);      /* shouldn't happen... */
                    414:        if(ft[--fd].inuse == 0) {
                    415:                errno = EBADF;
                    416:                free(obuf);
                    417:                return(-1);
                    418:        }
                    419:        isetup(&p);
                    420:        p.ioRefNum = ft[fd].refnum;
                    421:        p.ioBuffer = obuf;
                    422:        p.ioReqCount = (long) n;
                    423:        p.ioPosMode = fsFromMark;
                    424:        p.ioPosOffset = 0L;
                    425:        while(n--) {
                    426:                if(*buf == '\n') *s = '\r';     /* make it look like Mac files */
                    427:                else(*s = *buf);
                    428:                buf++;
                    429:                s++;
                    430:        }
                    431:        if((err = PBWrite(&p,0)) != noErr) {
                    432:                free(obuf);
                    433:                return(-1);
                    434:        }
                    435:        free(obuf);
                    436:        return((int) p.ioActCount);
                    437: }
                    438: 
                    439: long lseek(fd,offset,type)     /* The Mac version of this doesn't allocate new space. */
                    440: long offset;
                    441: unsigned type;
                    442: {
                    443:        int err;
                    444:        long cur_mark, eof, new_mark;
                    445:        IOParam p;
                    446: 
                    447:        if(ft[--fd].inuse == 0) {
                    448:                errno = EBADF;
                    449:                return(-1);
                    450:        }
                    451: 
                    452:        isetup(&p);
                    453:        p.ioRefNum = ft[fd].refnum;
                    454:        if((err = PBGetFPos(&p,0)) != noErr) {
                    455:                cvt_err(err);
                    456:                return(-1);
                    457:        }
                    458:        cur_mark = p.ioPosOffset;
                    459:        isetup(&p);
                    460:        p.ioRefNum = ft[fd].refnum;
                    461:        if((err = PBGetEOF(&p,0)) != noErr) {
                    462:                cvt_err(err);
                    463:                return(-1);
                    464:        }
                    465:        eof = (long) p.ioMisc;
                    466:        switch(type) {
                    467:                case 0 :
                    468:                        new_mark = offset;
                    469:                        break;
                    470:                case 1 :
                    471:                        new_mark = offset + cur_mark;
                    472:                        break;
                    473:                case 2 :
                    474:                        new_mark = offset + eof;
                    475:        }
                    476:        if(new_mark > eof) {            /* need more space in file */
                    477:                isetup(&p);
                    478:                p.ioRefNum = ft[fd].refnum;
                    479:                p.ioMisc = (Ptr) new_mark;
                    480:                if((err = PBSetEOF(&p,0)) != noErr) {
                    481:                        cvt_err(err);
                    482:                        return(-1);
                    483:                }
                    484: /*             if((err = PBAllocContig(&p,0)) != noErr) {
                    485:                        cvt_err(err);
                    486:                        return(-1);
                    487:                }*/
                    488:        }
                    489:        isetup(&p);
                    490:        p.ioRefNum = ft[fd].refnum;
                    491:        p.ioPosOffset = new_mark;
                    492:        p.ioPosMode = fsFromStart;
                    493:        if((err = PBSetFPos(&p,0)) != noErr) {
                    494:                cvt_err(err);
                    495:                return(-1);
                    496:        }
                    497:        errno = 0;
                    498:        return(p.ioPosOffset);
                    499: }
                    500: 
                    501: int unlink(name)
                    502: char *name;
                    503: {      int fd, err;
                    504:        char *nm;
                    505:        HParamBlockRec p;
                    506: 
                    507:        nm = cvt_fnm(name);     /* convert filename to Mac type name */
                    508:        CtoPstr(nm);
                    509:        fsetup(&p);     /* try to delete it, whether it is there or not. */
                    510:        p.fileParam.ioNamePtr = (StringPtr) nm;
                    511:        if((err = PBHDelete(&p,0)) != noErr && err != fnfErr) return(cvt_err(err));
                    512:        return;
                    513: }
                    514: 
                    515: /* Console read and write routines */
                    516: 
                    517: static int con_write(buf,size)
                    518: unsigned  size;
                    519: char *buf;
                    520: {
                    521:        while(size--) putp(*buf++);
                    522:        return(size);
                    523: }
                    524: 
                    525: static int con_read(buf,size)
                    526: unsigned size;
                    527: char *buf;
                    528: {
                    529:        unsigned n;
                    530:        int p;
                    531: 
                    532: 
                    533:        n = 0;
                    534:        do {
                    535:                p = rawgetc();
                    536: #ifdef O_META
                    537:                if(p & 0x7f) p &= 0x7f;         /* was normal ascii char */
                    538: #endif
                    539:                *buf++ = p;
                    540:                n++;
                    541:        } while (rawchkc() && n <= size);
                    542:        return(n);
                    543: }
                    544: 
                    545: 
                    546: /* This didn't seem to be any place else */
                    547: 
                    548: int abs(n)
                    549: int n;
                    550: {
                    551:        return(n >= 0 ? n : -n);
                    552: 
                    553: }
                    554: 
                    555: /* Simplified stat() routine emulates what is needed most. */
                    556: 
                    557: int stat(fname,buf)
                    558: char *fname;
                    559: struct stat *buf;
                    560: {
                    561:        CInfoPBRec p;
                    562:        char *nm;
                    563: 
                    564:        nm = cvt_fnm(fname);
                    565:        CtoPstr(nm);
                    566:        byte_zero(&p,sizeof(CInfoPBRec));
                    567:        p.hFileInfo.ioCompletion = 0;
                    568:        p.hFileInfo.ioNamePtr = (StringPtr) nm;
                    569:        p.hFileInfo.ioFVersNum = 0;
                    570:        p.hFileInfo.ioFDirIndex = 0;
                    571:        p.hFileInfo.ioVRefNum = cur_vol;
                    572:        p.hFileInfo.ioDirID = cur_dir;
                    573: 
                    574:        switch (PBGetCatInfo(&p,0)) {
                    575: 
                    576:                case noErr :    errno = 0;
                    577:                                                break;
                    578:                case nsvErr:
                    579:                case paramErr:
                    580:                case bdNamErr :
                    581:                case fnfErr:    errno = ENOENT;
                    582:                                                break;
                    583:                case ioErr:             errno = EIO;
                    584:                                                break;
                    585:                default :               errno = ENOENT;
                    586:                                                break;
                    587:        }
                    588:        buf->st_dev = p.hFileInfo.ioVRefNum + 1;        /* don't want 0 */
                    589:        buf->st_ino = p.hFileInfo.ioDirID;
                    590:        buf->st_size = p.hFileInfo.ioFlLgLen;
                    591:        buf->st_mtime = p.hFileInfo.ioFlMdDat;
                    592:        buf->st_mode = (p.hFileInfo.ioFlAttrib & 0x10) ? S_IFDIR : 0;
                    593:        PtoCstr(nm);
                    594:        return(errno == 0 ? 0 : -1);
                    595: }
                    596: 
                    597: int is_dir(fname)
                    598: char *fname;
                    599: {
                    600:        struct stat s;
                    601:        if((stat(fname,&s) == 0) && (s.st_mode & S_IFDIR)) return(1);
                    602:        return(0);
                    603: }
                    604: 
                    605: /* Directory related routines. Jove keeps track of the true Volume (disk) number and
                    606:    directory number, and avoids "Working Directory Reference Numbers", which are
                    607:    confusing. */
                    608: 
                    609: static int getdir()    /* call this only once, during startup. */
                    610: {
                    611:        WDPBRec p;
                    612: 
                    613:        p.ioCompletion = 0;
                    614:        p.ioNamePtr = 0;
                    615:        if(PBHGetVol(&p,0) != noErr) return(-1);        /* BIG trouble */
                    616:        cur_vol = p.ioWDVRefNum;
                    617:        cur_dir = p.ioWDDirID;
                    618:        SFSaveDisk = 0 - cur_vol;       /* these are for SF dialogs */
                    619:        CurDirStore = cur_dir;
                    620: }
                    621: 
                    622: static int setdir(vol,dir)
                    623: long dir;
                    624: {
                    625:        WDPBRec p;
                    626: 
                    627:        p.ioCompletion = 0;
                    628:        p.ioNamePtr = 0;
                    629:        p.ioVRefNum = vol;
                    630:        p.ioWDDirID = dir;
                    631:        if(PBHSetVol(&p,0) != noErr) return(-1);
                    632:        cur_vol = vol;
                    633:        cur_dir = dir;
                    634:        SFSaveDisk = 0 - vol;   /* these are for SF dialogs */
                    635:        CurDirStore = dir;
                    636: 
                    637: 
                    638: }
                    639: 
                    640: int chdir(dir)
                    641: char *dir;
                    642: {
                    643:        CInfoPBRec d;
                    644:        WDPBRec p;
                    645:        char *t;
                    646:        char *nm;
                    647: 
                    648:        if(strcmp(dir,"/") == 0) return(-1); /* There is no root... */
                    649:        nm = malloc(strlen(dir) + 2);
                    650:        if(nm == 0) return(-1);
                    651: 
                    652:        strcpy(nm,dir);
                    653:        t = nm;
                    654:        while(*t) {
                    655:                if(*t == '/') *t = ':';
                    656:                t++;
                    657:        }
                    658:        t = nm;
                    659:        while(*t == ':') t++;   /*get rid of initial slashes */
                    660:        strcat(nm,":");
                    661:        CtoPstr(t);
                    662: 
                    663:        d.dirInfo.ioCompletion = 0;                     /* get the directory number */
                    664:        d.dirInfo.ioNamePtr = (StringPtr) t;
                    665:        d.dirInfo.ioVRefNum = cur_vol;
                    666:        d.dirInfo.ioFDirIndex = 0;
                    667:        d.dirInfo.ioDrDirID = 0;
                    668:        PBGetCatInfo(&d,0);
                    669:        free(nm);
                    670:        if(d.dirInfo.ioResult != noErr || ((d.dirInfo.ioFlAttrib & 0x10) == 0)) return(-1);
                    671:        if(setdir(d.dirInfo.ioVRefNum,d.dirInfo.ioDrDirID) < 0)return(-1);
                    672:        return(0);
                    673: }
                    674: 
                    675: /* Scandir returns the number of entries or -1 if the directory cannot
                    676:    be opened or malloc fails. */
                    677: 
                    678: int scandir(dir, nmptr, qualify, sorter) /* this function has NOT been debugged */
                    679: char   *dir;
                    680: char   ***nmptr;
                    681: int    (*qualify) proto((char *));
                    682: int    (*sorter) proto((UnivConstPtr, UnivConstPtr));
                    683: {
                    684:        CInfoPBRec d;
                    685:        Str255 buf;
                    686:        long DirID;
                    687:        char    **ourarray, *nm, *t;
                    688:        unsigned int nalloc = 10,
                    689:                        nentries = 0, index = 1;
                    690:        char *getwd();
                    691: 
                    692:        if(strcmp(dir,"/") == 0) return(-1); /* There is no root... */
                    693:        if(strcmp(dir,".") == 0) dir = getwd();
                    694:        nm = malloc(strlen(dir) + 2);
                    695:        if(nm == 0) return(-1);
                    696: 
                    697:        strcpy(nm,dir);
                    698:        t = nm;
                    699:        while(*t) {
                    700:                if(*t == '/') *t = ':';
                    701:                t++;
                    702:        }
                    703:        t = nm;
                    704:        while(*t == ':') t++;   /*get rid of initial slashes */
                    705:        strcat(nm,":");
                    706:        CtoPstr(t);
                    707: 
                    708:        byte_zero(&d,sizeof(CInfoPBRec));
                    709:        d.dirInfo.ioCompletion = 0;                     /* get the directory number */
                    710:        d.dirInfo.ioNamePtr = (StringPtr) t;
                    711:        d.dirInfo.ioVRefNum = cur_vol;
                    712:        d.dirInfo.ioFDirIndex = 0;
                    713:        d.dirInfo.ioDrDirID = 0;
                    714:        PBGetCatInfo(&d,0);
                    715:        PtoCstr(t);
                    716:        free(nm);
                    717:        if(d.dirInfo.ioResult != noErr || ((d.dirInfo.ioFlAttrib & 0x10) == 0)) return(-1);
                    718:        DirID = d.dirInfo.ioDrDirID;
                    719:        if ((ourarray = (char **) malloc(nalloc * sizeof (char *))) == 0)
                    720: memfail:       complain("[Malloc failed: cannot scandir]");
                    721:        while (1) {
                    722:                byte_zero(&d,sizeof(CInfoPBRec));
                    723:                d.dirInfo.ioCompletion = (long) 0;
                    724:                d.dirInfo.ioVRefNum = cur_vol;
                    725:                d.dirInfo.ioFVersNum = 0;
                    726:                d.dirInfo.ioNamePtr = buf;
                    727:                d.dirInfo.ioFDirIndex = index++;
                    728:                d.dirInfo.ioVRefNum = cur_vol;
                    729:                d.dirInfo.ioDrDirID = DirID;
                    730:                if(PBGetCatInfo(&d,0) != noErr) break;  /* we are done, then */
                    731:                PtoCstr((char *) buf);
                    732: /*             if(d.dirInfo.ioFlAttrib & 0x10) strcat(buf,"/");*/
                    733:                if (qualify != 0 && (*qualify)((char *) buf) == 0)
                    734:                        continue;
                    735:                if (nentries == nalloc) {
                    736:                        ourarray = (char **) realloc((char *) ourarray, (nalloc += 10) * sizeof (char *));
                    737:                        if (ourarray == 0)
                    738:                                goto memfail;
                    739:                }
                    740:                ourarray[nentries] = (char *) malloc(strlen(buf)+1);
                    741:                null_ncpy(ourarray[nentries], (char *) buf, strlen((char *) buf));
                    742:                nentries += 1;
                    743:        }
                    744:        if ((nentries + 1) != nalloc)
                    745:                ourarray = (char **) realloc((char *) ourarray,
                    746:                                        ((nentries + 1) * sizeof (char *)));
                    747:        if (sorter != 0)
                    748:                qsort((char *) ourarray, nentries, sizeof (char **), sorter);
                    749:        *nmptr = ourarray;
                    750:        ourarray[nentries] = 0;         /* guaranteed 0 pointer */
                    751:        return nentries;
                    752: }
                    753: 
                    754: void freedir(dir, nentries)
                    755: char ***dir;
                    756: int nentries;
                    757: {
                    758:        char **ptr = *dir;
                    759:        while(nentries--) free(*ptr++);
                    760: }
                    761: 
                    762: int
                    763: alphacomp(a, b)
                    764: UnivConstPtr   a,
                    765:        b;
                    766: {
                    767:        return strcmp(*(const char **)a, *(const char **)b);
                    768: }
                    769: 
                    770: int
                    771: chkCWD(name)   /* eventually, may check validity of cwd */
                    772: char *name;
                    773: {
                    774:        return(1);
                    775: }
                    776: 
                    777: 
                    778: char *getwd()
                    779: {
                    780:        CInfoPBRec d;
                    781:        static char ret[255];
                    782:        char nm[50], tmp[255];
                    783: 
                    784:        ret[0] = '\0';
                    785:        d.dirInfo.ioDrDirID = cur_dir;
                    786:        for(;;) {
                    787:                d.dirInfo.ioCompletion = 0;
                    788:                d.dirInfo.ioNamePtr = (StringPtr) nm;
                    789:                d.dirInfo.ioVRefNum = cur_vol;
                    790:                d.dirInfo.ioFDirIndex = -1;
                    791: 
                    792:                PBGetCatInfo(&d,0);
                    793:                if(d.dirInfo.ioResult != noErr) return(0);
                    794:                PtoCstr((char *) nm);
                    795:                strcpy(tmp,ret);
                    796:                strcpy(ret,"/");
                    797:                strcat(ret,nm);
                    798:                strcat(ret,tmp);
                    799:                if(d.dirInfo.ioDrDirID == 2) break;     /* home directory */
                    800:                d.dirInfo.ioDrDirID = d.dirInfo.ioDrParID;
                    801:        }
                    802:        return(ret);
                    803: }
                    804: 
                    805: static char *gethome()         /* this will be startup directory */
                    806: {
                    807:        static char *ret = 0;
                    808: 
                    809: 
                    810:        if(ret == 0) {
                    811:                char *item = getwd();
                    812:                ret = malloc(strlen(item)+1);
                    813:                strcpy(ret,item);
                    814:        }
                    815:        return(ret);
                    816: }
                    817: 
                    818: 
                    819: 
                    820: /* Routines that put up and manipulate the "About Jove" dialog. */
                    821: 
                    822: 
                    823: /* (ORIGINALLY IN) about_j.c. */
                    824: 
                    825: 
                    826: #define DLOGNAME "\pABOUT_JDLOG"
                    827: 
                    828: #define DONE_ITEM 1
                    829: #define LIST_ITEM 2
                    830: 
                    831: 
                    832: #define DWIDTH 460             /* there should be an easy way to get this */
                    833: #define DHEIGHT 240            /* from the resource file! */
                    834: 
                    835: WindowPtr makedisplay();
                    836: ListHandle makelist();
                    837: 
                    838: 
                    839: static WindowPtr theWindow;
                    840: static ListHandle theList;
                    841: static Rect theListRect;
                    842: static EventRecord theEvent;
                    843: 
                    844: 
                    845: 
                    846: static void about_j()
                    847: {
                    848:        void do_list(), do_events();
                    849: 
                    850:        WindowPtr OldWindow;
                    851: 
                    852:        GetPort(&OldWindow);
                    853: 
                    854:        if((theWindow = makedisplay()) == 0) return;
                    855:        SetPort(theWindow);
                    856:        if(theList = makelist()) {
                    857:                LActivate(1,theList);
                    858:                do_list();
                    859:                ShowWindow(theWindow);
                    860:                do_events();
                    861:        }
                    862:        SetPort(OldWindow);
                    863:        LDispose(theList);
                    864:        DisposDialog(theWindow);
                    865: 
                    866:        return;
                    867: }
                    868: 
                    869: 
                    870: static WindowPtr makedisplay()
                    871: {
                    872:        static int dlogid = 0;
                    873:        DialogPtr theDialog;
                    874:        Handle theHandle;
                    875:        Handle theResource;
                    876:        Str255 buf;
                    877:        long itemType;
                    878:        Rect theRect;
                    879:        short dh,dv;    /* to center dialog on the screen */
                    880:        Str255 nostring;
                    881: 
                    882:        if(dlogid == 0) {
                    883:                if((theResource = GetNamedResource('DLOG',DLOGNAME)) == 0)
                    884:                        return((WindowPtr) 0);
                    885:                itemType = 'DLOG';
                    886:                GetResInfo(theResource,&dlogid,&itemType,buf);
                    887:        }
                    888: 
                    889:        theDialog = GetNewDialog(dlogid,(long) 0,(WindowPtr) -1);
                    890:        strcpy((char *) nostring,"\p");
                    891:        ParamText("\pMacJove - Copyright (C) 1986, 1987, 1988 J. Payne, K. Gegenfurtner,",
                    892:        "\pK. Mitchum. Portions (C) THINK Technologies, Inc.",nostring,nostring);
                    893: 
                    894:        dh = screenBits.bounds.left + (screenBits.bounds.right - DWIDTH) / 2;
                    895:        dv = screenBits.bounds.top  + (screenBits.bounds.bottom - DHEIGHT) / 2;
                    896:        MoveWindow((WindowPtr)theDialog,dh,dv,0);
                    897:        ShowWindow((WindowPtr)theDialog);
                    898: 
                    899: 
                    900:        GetDItem(theDialog,LIST_ITEM,&itemType,&theHandle,&theRect);
                    901:        theListRect = theRect;
                    902:        theListRect.right -= 15;
                    903:        ((WindowPtr)theDialog)->txFont = FONT;
                    904:        ((WindowPtr)theDialog)->txSize = TEXTSIZE;
                    905: 
                    906:        return((WindowPtr) theDialog);
                    907: }
                    908: 
                    909: static void do_display()               /* draw necessary controls, lines */
                    910: {
                    911:        Rect rViewF;            /* framing rect for list */
                    912:        int offset;
                    913: 
                    914:        rViewF = theListRect;
                    915: 
                    916:        rViewF.left--;
                    917:        rViewF.top--;
                    918:        rViewF.right++;
                    919:        rViewF.bottom++;
                    920:        FrameRect(&rViewF);
                    921: 
                    922:        DrawControls(theWindow);
                    923: 
                    924: }
                    925: 
                    926: static ListHandle makelist()
                    927: {
                    928:        Point csize;
                    929:        Rect dataBounds, rView; /* list boundaries */
                    930: 
                    931:        csize.h = csize.v = 0;
                    932:        SetRect(&dataBounds,0,0,1,0);
                    933:        return(LNew(&theListRect,&dataBounds,csize,0,theWindow,0,0,0,1));
                    934: }
                    935: 
                    936: static void do_list()
                    937: {
                    938:        void printbind();
                    939: 
                    940:        int row, col;
                    941:        struct cmd *f;
                    942:        Str255 buf;
                    943:        Point theCell;
                    944: 
                    945:        theCell.h = 0;
                    946: 
                    947:        for(f = commands, row = 0; f->Name; f++, row++) {
                    948:                LAddRow(1,row,theList);
                    949:                theCell.v = row;
                    950: 
                    951:                printbind(f,buf);
                    952:                strcat(buf,f->Name);
                    953:                LSetCell(buf,strlen((char *)buf),theCell,theList);
                    954: 
                    955:        }
                    956: }
                    957: static void printbind(f,buf)
                    958: struct cmd *f;
                    959: char *buf;
                    960: {
                    961:        char c;
                    962: 
                    963:        if(f->c_map == 0 || (c = f->c_key) == 0x7f) {
                    964:                strcpy(buf,"        ");
                    965:                return;
                    966:        }
                    967:        switch(f->c_map) {
                    968:                case F_MAINMAP :
                    969:                        strcpy(buf,"     ");
                    970:                        break;
                    971: 
                    972:                case F_PREF1MAP :
                    973:                        strcpy(buf," ESC ");
                    974:                        break;
                    975: 
                    976:                case F_PREF2MAP :
                    977:                        strcpy(buf,"  ^X ");
                    978:                        break;
                    979:        }
                    980:        if(c < ' ') {
                    981:                buf[5] = '^';           /* control char */
                    982:                c |= 0x40;
                    983:        }
                    984:        else buf[5] = ' ';
                    985:        if(c >= 'a' && c<= 'z') c &= 0x5f;
                    986:        buf[6] = c;
                    987:        buf[7] = ' ';
                    988:        buf[8] = '\0';
                    989: }
                    990: 
                    991: 
                    992: 
                    993: static pascal Boolean ProcFilter(theDialog,event,itemHit)
                    994: DialogPtr theDialog;
                    995: EventRecord *event;
                    996: int *itemHit;
                    997: {
                    998:        theEvent = *event;
                    999:        if(theEvent.what == keyDown && theEvent.message & charCodeMask == '\r') {
                   1000:                *itemHit = 1;
                   1001:                return(TRUE);
                   1002:        }
                   1003:        if(theEvent.what == activateEvt && (WindowPtr) theEvent.message == theWindow) {
                   1004:                LDoDraw(1,theList);
                   1005:                LActivate(1,theList);
                   1006:        }
                   1007:        if(theEvent.what == updateEvt && (WindowPtr) theEvent.message == theWindow) {
                   1008:                BeginUpdate(theWindow);
                   1009:                do_display();
                   1010:                DrawDialog(theWindow);
                   1011:                LUpdate((GrafPtr) theWindow->visRgn,theList);
                   1012:                EndUpdate(theWindow);
                   1013:        }
                   1014: 
                   1015:        return(FALSE);
                   1016: }
                   1017: 
                   1018: 
                   1019: void do_events()
                   1020: {
                   1021:        int item,done;
                   1022:        Point p;
                   1023: 
                   1024:        done = 0;
                   1025: 
                   1026:        while(!done) {
                   1027:                ModalDialog(ProcFilter,&item);
                   1028:                switch(item) {
                   1029:                        case DONE_ITEM :
                   1030:                                done = 1;
                   1031:                        case LIST_ITEM :
                   1032:                                p = theEvent.where;
                   1033:                                GlobalToLocal(&p);
                   1034:                                LClick(p,theEvent.modifiers,theList);
                   1035:                }
                   1036:        }
                   1037: }
                   1038: 
                   1039: /* Window and Control related routines. */
                   1040: 
                   1041: /* (ORIGINALLY IN) tcon.c.
                   1042:    control handler routines for Jove. K. Mitchum 12/86 */
                   1043: 
                   1044: 
                   1045: #define MINC 0
                   1046: #define MAXC ((int)100)
                   1047: #define INITC 0
                   1048: #define EVENTLIST (mDownMask | keyDownMask )
                   1049: 
                   1050: extern int UpdModLine;
                   1051: extern long GetCRefCon();      /* omitted in ControlMgr.h */
                   1052: 
                   1053: static Point p;
                   1054: static intext; /* mouse down in jove text */
                   1055: 
                   1056: void docontrols()      /* called from redisplay routines */
                   1057: {
                   1058:        void MakeScrollBar(),
                   1059:                AdjustScrollBar(),
                   1060:                drawfluff();
                   1061: 
                   1062:        Window *w;
                   1063:        int top;
                   1064: 
                   1065:        w = fwind;
                   1066:        top = 0;
                   1067:        do {
                   1068:                if(w->w_control) HideControl(w->w_control);
                   1069:                w = w->w_next;
                   1070:        } while (w != fwind);
                   1071:        w = fwind;
                   1072:        do {
                   1073:                w->w_topline = top;
                   1074:                if(w->w_control) AdjustScrollBar(w);
                   1075:                else MakeScrollBar(w);
                   1076:                ShowControl(w->w_control);
                   1077:                top += w->w_height;
                   1078:                w = w->w_next;
                   1079:        } while(w != fwind);
                   1080:        Windchange = 0;
                   1081:        drawfluff();
                   1082: }
                   1083: 
                   1084: 
                   1085: void MakeScrollBar(w)  /* set up control */
                   1086: Window *w;
                   1087: {
                   1088:        Rect BarRect;
                   1089:        int wheight, wtop;
                   1090: 
                   1091:        WindowPtr window = theScreen;
                   1092:        wheight = w->w_height;
                   1093:        wtop = w->w_topline;
                   1094:        SetRect(&BarRect,window->portRect.right - SCROLLWIDTH + 1,
                   1095:                window->portRect.top -2 + wtop * HEIGHT,
                   1096:                window->portRect.right +1,
                   1097:                window->portRect.top + ((wheight + wtop) * HEIGHT + 1));
                   1098:                w->w_control = ((char **) NewControl(window,&BarRect,"/psbar",1,INITC,
                   1099:                MINC,MAXC,scrollBarProc,w));
                   1100: }
                   1101: 
                   1102: void AdjustScrollBar(w)        /* redo existing control */
                   1103: Window *w;
                   1104: {
                   1105:        int wtop,wheight;
                   1106:        ControlHandle handle;
                   1107:        WindowPtr window;
                   1108: 
                   1109:        handle = (ControlHandle) w->w_control;
                   1110:        wtop = w->w_topline;
                   1111:        wheight = w->w_height;
                   1112:        window = (*handle)->contrlOwner;
                   1113: 
                   1114:        if(handle == 0) return;
                   1115: 
                   1116:        SizeControl(handle,SCROLLWIDTH,wheight * HEIGHT + 1);
                   1117: 
                   1118:        MoveControl(handle,window->portRect.right - SCROLLWIDTH + 1,
                   1119:                window->portRect.top -1 + wtop * HEIGHT);
                   1120: 
                   1121: }
                   1122: 
                   1123: void SetScrollBar(handle)      /* set value of the bar */
                   1124: ControlHandle handle;
                   1125: {
                   1126: 
                   1127:        SetCtlValue(handle,ltoc());
                   1128: }
                   1129: 
                   1130: static void drawfluff()                /* draw controls and dividers */
                   1131: {
                   1132:        Window *w = fwind;
                   1133: 
                   1134:        DrawControls(theScreen);
                   1135:        DrawGrowIcon(theScreen);
                   1136: }
                   1137: 
                   1138: void RemoveScrollBar(w)
                   1139: Window *w;
                   1140: {
                   1141:        if(w->w_control) DisposeControl(w->w_control);
                   1142:        w->w_control = 0;
                   1143: 
                   1144: }
                   1145: 
                   1146: static pascal void DScroll(control,part)
                   1147: ControlHandle control;
                   1148: int part;
                   1149: {
                   1150:        DownScroll();
                   1151:        redisplay();
                   1152: }
                   1153: 
                   1154: static pascal void UScroll(control,part)
                   1155: ControlHandle control;
                   1156: int part;
                   1157: {
                   1158:        UpScroll();
                   1159:        redisplay();
                   1160: }
                   1161: 
                   1162: static pascal void NPage(control,part)
                   1163: ControlHandle control;
                   1164: int part;
                   1165: {      NextPage();
                   1166:        redisplay();
                   1167: }
                   1168: 
                   1169: static pascal void PPage(control,part)
                   1170: ControlHandle control;
                   1171: int part;
                   1172: {      PrevPage();
                   1173:        redisplay();
                   1174: }
                   1175: 
                   1176: static long npos;      /* number of lines in buffer */
                   1177: 
                   1178: static int ltoc()      /* calculate ctlvalue for line position */
                   1179: {
                   1180:        register long ipos;
                   1181:        register Line   *lp = curbuf->b_first;
                   1182: 
                   1183:        for (npos = 1; lp ; npos++, lp = lp->l_next)  {
                   1184:                if(lp == curline) ipos = npos;
                   1185:        }
                   1186:        return((int) ((ipos * MAXC) / npos));
                   1187: }
                   1188: 
                   1189: static Line *ctol(ctlv)        /* find buffer line for ctlvalue */
                   1190: int ctlv;
                   1191: {
                   1192: extern char *itoa();
                   1193:        register long ipos;
                   1194:        register Line   *lp = curbuf->b_first;
                   1195: 
                   1196:        ipos = (npos * ctlv)/MAXC;
                   1197:        while (ipos-- && lp->l_next) lp = lp->l_next;
                   1198:        return(lp);
                   1199: }
                   1200: 
                   1201: static void doWind(event,window)
                   1202: EventRecord *event;
                   1203: WindowPtr window;
                   1204: {
                   1205: #define track() TrackControl(whichControl,p,(ProcPtr) 0)
                   1206: 
                   1207:        ControlHandle whichControl;
                   1208:        Window *jwind, *cwind;
                   1209:        int notcurwind;
                   1210:        int cpart;      /* control part */
                   1211:        int oldval,newval,thumb = 0;
                   1212: 
                   1213:        p = event->where;
                   1214:        intext = 0;
                   1215:        notcurwind = 0;
                   1216:        GlobalToLocal(&p);
                   1217: 
                   1218:        if(event->what == mouseDown) {
                   1219:                if((cpart = FindControl(p,window,&whichControl)) == 0) return;
                   1220:                if((jwind = (Window *) (*whichControl)->contrlRfCon) !=  curwind) {
                   1221:                        notcurwind++;
                   1222:                        cwind = curwind;
                   1223:                        SetWind(jwind);
                   1224:                }
                   1225:                switch (cpart) {
                   1226:                        case inUpButton :       TrackControl(whichControl,p,(ProcPtr) DScroll); break;
                   1227:                        case inDownButton :     TrackControl(whichControl,p,(ProcPtr) UScroll); break;
                   1228:                        case inPageUp :         TrackControl(whichControl,p,(ProcPtr) PPage); break;
                   1229:                        case inPageDown :       TrackControl(whichControl,p,(ProcPtr) NPage); break;
                   1230:                        case inThumb :          if(track()) {
                   1231:                                                                        newval = GetCtlValue(whichControl);
                   1232: 
                   1233:                                                                        if(newval == MAXC) Eof();
                   1234:                                                                        else if(newval == MINC) Bof();
                   1235:                                                                        else SetLine(ctol(newval));
                   1236:                                                                }
                   1237:                                                                break;
                   1238: 
                   1239:                }
                   1240:                if(notcurwind) {
                   1241:                        SetWind(cwind);
                   1242:                        redisplay();
                   1243:                }
                   1244:                redisplay();    /* again, to set the cursor */
                   1245:        }
                   1246:        else {
                   1247:                if(findtext()) redisplay();
                   1248:        }
                   1249: }
                   1250: 
                   1251: #define std_state(w) (*((WStateData **)((WindowPeek)((w)))->dataHandle))->stdState
                   1252: #define user_state(w) (*((WStateData **)((WindowPeek)((w)))->dataHandle))->userState
                   1253: 
                   1254: static void doDrag(event,window)
                   1255: EventRecord *event;
                   1256: WindowPtr window;
                   1257: {
                   1258:        Rect old_std;
                   1259:        
                   1260:        old_std = std_state(window);
                   1261:                
                   1262: 
                   1263:        DragWindow(window, event->where, &LimitRect);
                   1264:        if(wc == &wc_std) {
                   1265:                wc_user = wc_std;
                   1266:                user_state(theScreen) = std_state(theScreen);
                   1267:                ZoomWindow(window,7,1);
                   1268:                wc = &wc_user;
                   1269:                Reset_std();
                   1270:        }
                   1271: }
                   1272: 
                   1273: static void doGrow(event,window)
                   1274: EventRecord *event;
                   1275: WindowPtr window;
                   1276: {
                   1277:        long size;
                   1278: 
                   1279:        /* zero means user didn't change anything */
                   1280:        if(size = GrowWindow(window, event->where, &LimitRect)) {
                   1281:                if(wc == &wc_std) {
                   1282:                        wc_user = wc_std;
                   1283:                        user_state(theScreen) = std_state(theScreen);
                   1284:                        ZoomWindow(window,7,1);
                   1285:                        wc = &wc_user;
                   1286:                        Reset_std();
                   1287:                }
                   1288:                if(wc_adjust(LoWord(size),HiWord(size),wc,0)) {
                   1289:                        EraseRect(&window->portRect);
                   1290:                        SizeWindow(window,wc->w_width,wc->w_height,TRUE);
                   1291:                        win_reshape();  /* no signals here... */
                   1292:                }
                   1293:        }
                   1294: }
                   1295: 
                   1296: static void doZoomIn(event,window)
                   1297: EventRecord *event;
                   1298: WindowPtr window;
                   1299: {
                   1300:        if(TrackBox(window, event->where, 7) == TRUE){
                   1301:                        EraseRect(&window->portRect);
                   1302:                        ZoomWindow(window,7,1);
                   1303:                        wc = &wc_user;
                   1304:                        win_reshape();  /* we do our own toggle, not ZoomWindow() */
                   1305:                }       
                   1306: }
                   1307: static void doZoomOut(event,window)
                   1308: EventRecord *event;
                   1309: WindowPtr window;
                   1310: {
                   1311:        if(TrackBox(window, event->where, 8) == TRUE) {
                   1312:                        EraseRect(&window->portRect);
                   1313:                        ZoomWindow(window,8,1);
                   1314:                        wc = &wc_std;
                   1315:                        win_reshape();  /* we do our own toggle, not ZoomWindow() */
                   1316:                }       
                   1317: }
                   1318: 
                   1319: static void doGoAway(event,window)
                   1320: EventRecord *event;
                   1321: WindowPtr window;
                   1322: {
                   1323:        if(TrackGoAway(window, event->where) == TRUE) Leave();
                   1324: }
                   1325: 
                   1326: static Window *rtowind(row)    /* return jove window row is in */
                   1327: int row;
                   1328: {
                   1329:        Window *w = fwind;
                   1330: 
                   1331:        do {
                   1332:                if((w->w_topline <= row) && ((w->w_height + w->w_topline) > row))
                   1333:                        return(w);
                   1334:                w = w->w_next;
                   1335:        } while(w != fwind);
                   1336:        return(0);
                   1337: }
                   1338: 
                   1339: static Line *windtol(w,row)            /* return line for row in window */
                   1340: Window *w;
                   1341: int row;
                   1342: {
                   1343:        Line *l = w->w_top;
                   1344: 
                   1345:        while(row--) if((l = l->l_next) == 0) return(0);
                   1346:        return(l);
                   1347: }
                   1348: 
                   1349: 
                   1350: static int findtext()          /* locate and move the point to match the mouse */
                   1351: {
                   1352:        int row,col;
                   1353:        long ticks;
                   1354:        EventRecord event;
                   1355:        Window *w;
                   1356:        Line *l;
                   1357:        
                   1358:        ticks = Ticks;
                   1359:        ptoxy(p,&row,&col);
                   1360:        if((w = rtowind(row)) == 0) return(0);
                   1361:        if(w != curwind) SetWind(w);
                   1362:        row -= w->w_topline;            /* now have row number in window */
                   1363:        if(row >= w->w_height -1) return(0);
                   1364:        if((l = windtol(w,row)) == 0) return(0);
                   1365:        if(l->l_dline == 0) return(0);
                   1366:        this_cmd = LINECMD;
                   1367:        SetLine(l);             /* Curline is in linebuf now */
                   1368:        if(w->w_flags & W_NUMLINES) col -= 8;   /* adjust for line numbers */
                   1369:        if(col < 0) col = 0;
                   1370:        curchar = how_far(curline, col);
                   1371:        do {
                   1372:                if(GetNextEvent(mUpMask,&event) && (event.when < ticks + DoubleTime)) {
                   1373:                        set_mark();
                   1374:                        break;
                   1375:                }
                   1376:        } while ((Ticks - ticks) < DoubleTime);
                   1377:        return(1);
                   1378: }
                   1379: 
                   1380: 
                   1381: static int ptoxy(p,row,col)    /* convert Point to terminal x,y coordinate */
                   1382: Point p;
                   1383: int *row,*col;
                   1384: {
                   1385:        *row = (p.v / HEIGHT);
                   1386:        *col = (p.h / WIDTH );
                   1387:        if((*row > MAXROW) || (*col > MAXCOL)) return(ERROR);
                   1388:        return(0);
                   1389: }
                   1390: 
                   1391: /* Event-related routines. The Event loop is CheckEvents(), and is called whenever
                   1392:    a console read occurs or a call to charp(). During certain activities, such as ask(),
                   1393:    etc. non-keyboard events are ignored. This is set by the variable Keyonly.
                   1394:    As an update or activate event generates a call to redisplay(), it is important
                   1395:    that redisplay() and related routines NOT check for keyboard characters. */
                   1396: 
                   1397: /* (ORIGINALLY IN) tevent.c
                   1398:        event handler for Jove. K Mitchum 12/86 */
                   1399: 
                   1400: 
                   1401: #define SYS_ID 100
                   1402: #define NOFUNC ((void (*)()) 0)
                   1403: #define NEVENTS 16
                   1404: 
                   1405: extern void doMouse(),dokeyDown(),doUpdate(),doActivate();
                   1406: static MenuHandle SysMenu;
                   1407: static void (*eventlist[])() =
                   1408: {
                   1409:        NOFUNC, /* nullEvent */
                   1410:        doMouse,/* mouseDown */
                   1411:        doMouse, /* mouseUp */
                   1412:        dokeyDown, /* keyDown */
                   1413:        NOFUNC, /* keyUp */
                   1414:        dokeyDown, /* autoKey */
                   1415:        doUpdate, /* updateEvt */
                   1416:        NOFUNC, /* diskEvt */
                   1417:        doActivate, /* activateEvt */
                   1418:        NOFUNC, /* not  used */
                   1419:        NOFUNC, /* networkEvt = 10 */
                   1420:        NOFUNC, /* driverEvt */
                   1421:        NOFUNC, /* app1Evt */
                   1422:        NOFUNC, /* app2Evt */
                   1423:        NOFUNC, /* app3Evt */
                   1424:        NOFUNC  /* app4Ev */
                   1425: };
                   1426: 
                   1427: 
                   1428: 
                   1429: static void CheckEvents()
                   1430: {
                   1431:        void SetBufMenu(),
                   1432:                MarkModes();
                   1433: 
                   1434:        static EventRecord theEvent;
                   1435:        static Point Mousep;
                   1436:        static long time = 0;
                   1437: 
                   1438: 
                   1439:        static void (*fptr)();
                   1440: 
                   1441: 
                   1442:        if(FrontWindow() == window) {
                   1443:                GetMouse(&Mousep);
                   1444:                if(PtInRect(Mousep,&r))
                   1445:                        SetCursor(*cross);
                   1446:                else SetCursor(&arrow);
                   1447:        }
                   1448: 
                   1449:        SystemTask();
                   1450:        if(EventCmd && !Keyonly) return;
                   1451:        if(Bufchange != 0) SetBufMenu();
                   1452:        if(Modechange != 0) MarkModes();
                   1453:        while(GetNextEvent(everyEvent,&theEvent)) {
                   1454:                if ((theEvent.what < NEVENTS) && (fptr = eventlist[theEvent.what])) {
                   1455:                        (*fptr)(&theEvent);
                   1456:                }
                   1457:                SystemTask();
                   1458:        }
                   1459:        if((Ticks - time) > 3600) {
                   1460:                time = Ticks;
                   1461:                UpdModLine = YES;
                   1462:                redisplay();
                   1463:        }
                   1464: }
                   1465: 
                   1466: static void InitSysMenu()
                   1467: {
                   1468:        void InitLocalMenus();
                   1469: 
                   1470:        SysMenu = NewMenu(SYS_ID,"\p\24");
                   1471:        AppendMenu(SysMenu,"\pAbout Jove");
                   1472:        AddResMenu(SysMenu,'DRVR');
                   1473:        InsertMenu(SysMenu,0);
                   1474:        InitLocalMenus();
                   1475:        DrawMenuBar();
                   1476: }
                   1477: 
                   1478: extern void doWind(),doGoAway(),doSysMenu(),doSysClick(),
                   1479:         doDrag(), doGrow(), doZoomIn(), doZoomOut();
                   1480: #define NMEVENTS 9
                   1481: static void (*mouselist[])() =
                   1482: {
                   1483:        NOFUNC, /* inDesk */
                   1484:        doSysMenu, /* inMenuBar */
                   1485:        doSysClick, /* inSysWindow */
                   1486:        doWind, /* inContent */
                   1487:        doDrag, /* inDrag */
                   1488:        doGrow, /* inGrow */
                   1489:        doGoAway, /* inGoAway */
                   1490:        doZoomIn,       /* inZoomIn */
                   1491:        doZoomOut       /* inZoomOut */
                   1492: };
                   1493: 
                   1494: 
                   1495: static void doMouse(event)
                   1496: EventRecord *event;
                   1497: {
                   1498:        WindowPtr theWindow;
                   1499:        int wpart;
                   1500:        void (*fptr)();
                   1501: 
                   1502:        if(Keyonly) {
                   1503:                if(event->what == mouseDown) SysBeep(2);
                   1504:                return;
                   1505:        }
                   1506:        wpart = FindWindow(event->where,&theWindow);
                   1507:        if ((wpart < NMEVENTS) && (fptr = mouselist[wpart])) {
                   1508:                (*fptr)(event,theWindow);
                   1509:        }
                   1510: 
                   1511: }
                   1512: 
                   1513: static void doSysMenu(event,window)
                   1514: EventRecord *event;
                   1515: WindowPtr window;
                   1516: {
                   1517:        void ProcMenu();
                   1518: 
                   1519:        int Menu,Item;
                   1520:        long result = MenuSelect(event->where);
                   1521:        Menu = (result >> 16) & 0xffff;
                   1522:        Item = result & 0xffff;
                   1523:        if(Item == 0) return;   /* no choice made */
                   1524: 
                   1525:        if(Menu == SYS_ID) {                    /* apple menu */
                   1526:                Str255 Name;
                   1527:                GrafPtr Port;
                   1528: 
                   1529:                if(Item == 1) about_j();
                   1530:                else {
                   1531:                        GetItem(SysMenu,Item,Name);
                   1532:                        GetPort(&Port);
                   1533:                        OpenDeskAcc(Name);
                   1534:                        SetPort(Port);
                   1535:                }
                   1536:        }
                   1537:        else ProcMenu(Menu,Item);
                   1538:        HiliteMenu(0);
                   1539:        EventCmd = 1;
                   1540:        menus_on();
                   1541:        return;
                   1542: 
                   1543: }
                   1544: 
                   1545: static void doSysClick(event,window)
                   1546: EventRecord *event;
                   1547: WindowPtr window;
                   1548: {
                   1549:        SystemClick(event,window);
                   1550: }
                   1551: 
                   1552: 
                   1553: static void doUpdate(event)
                   1554: EventRecord *event;
                   1555: {
                   1556:        WindowPtr theWindow, oldPort;
                   1557: 
                   1558:        theWindow = (WindowPtr) event->message;
                   1559: 
                   1560:        GetPort(&oldPort);
                   1561:        SetPort(theWindow);
                   1562:        BeginUpdate(theWindow);
                   1563:        p_refresh();
                   1564:        drawfluff();
                   1565:        EndUpdate(theWindow);
                   1566:        SetPort(oldPort);
                   1567: }
                   1568: 
                   1569: static void doActivate(event)
                   1570: EventRecord *event;
                   1571: {
                   1572:        WindowPtr theWindow;
                   1573:        ControlHandle control;
                   1574:        int hilite;
                   1575: 
                   1576:        theWindow = (WindowPtr) event->message;
                   1577:        SetPort(theWindow);
                   1578:        if(event->modifiers & activeFlag) {
                   1579:                hilite = 0;
                   1580:        }
                   1581:        else hilite = 255;
                   1582:        for(control = (ControlHandle) (((WindowPeek) theWindow)->controlList);
                   1583:                 (control != 0); control = (*control)->nextControl) {
                   1584:                        HiliteControl(control,hilite);
                   1585:        }
                   1586: }
                   1587: 
                   1588: /* Keyboard routines. The Option key was formerly used as a meta key.
                   1589:    However, to take advantage of the full (non-ASCII) character set,
                   1590:    this was removed. The corresponding code is ifdeffed O_META. */
                   1591: 
                   1592: /* (ORIGINALLY IN) tkey.c
                   1593:    keyboard routines for Macintosh. K Mitchum 12/86 */
                   1594: 
                   1595: extern jmp_buf auxjmp;
                   1596: 
                   1597: static nchars = 0;
                   1598: static char charbuf[MCHARS];
                   1599: /* the following kludges a meta key out of the option key by
                   1600: sending an escape sequence back to the dispatch routines. this is
                   1601: not elegant but it works, and doesn't alter escape sequences for
                   1602: those that prefer them. to remap the control or meta keys,
                   1603: see mackeys.h. */
                   1604: 
                   1605: static void dokeyDown(event)
                   1606: EventRecord *event;
                   1607: {
                   1608:        unsigned mods;
                   1609:        register c;
                   1610:        static int cptr = 0;
                   1611: 
                   1612:        if(MCHARS - nchars < 2) return;
                   1613: 
                   1614:        c  = (char)((event->message)&(charCodeMask));
                   1615: 
                   1616:        mods = event->modifiers;
                   1617: 
                   1618: #ifdef O_META
                   1619:        if (mods & (optionKey | cmdKey | controlKey)) {
                   1620: #else
                   1621:        if (mods & (cmdKey | controlKey)) {
                   1622: #endif
                   1623: /*             if(mods & shiftKey)
                   1624:                        c  = sh_keycodes[(((event->message)&(keyCodeMask))>>8)];
                   1625:                else
                   1626:                        c  = nsh_keycodes[(((event->message)&(keyCodeMask))>>8)];*/
                   1627: #ifdef O_META
                   1628:                if(mods & optionKey) {          /* make escape sequence */
                   1629:                        if(mods & cmdKey) c &= 0x1f;
                   1630:                        charbuf[cptr++] = '\033';
                   1631:                        cptr &= NMASK;          /* zero if necessary */
                   1632:                        nchars++;
                   1633:                }
                   1634:                else
                   1635: #endif
                   1636:                {       /* command key (control key) */
                   1637:                        if((c == '2') || (c == '\\') || (c == ' ')) c = 0;      /* so we have a null char */
                   1638:                        if(c != '`') c &= 0x1f;         /* make a control char */
                   1639:                }
                   1640:        }
                   1641:        else {
                   1642:                if(c == '`') c = '\033';        /* for those used to escapes */
                   1643:        }
                   1644: 
                   1645:        charbuf[cptr++] = c;
                   1646:        cptr &= NMASK;
                   1647:        nchars++;
                   1648: }
                   1649: 
                   1650: static int rawgetc()
                   1651: {
                   1652:        static int cptr = 0;
                   1653:        register c;
                   1654: 
                   1655:        if(EventCmd) longjmp(auxjmp,0);
                   1656:        while(nchars <= 0) {
                   1657:                nchars = 0;
                   1658:                if(EventCmd) longjmp(auxjmp,0);
                   1659:                CheckEvents();  /* ugh! WAIT for a character */
                   1660:        }
                   1661:        nchars--;
                   1662:        c = charbuf[cptr++];
                   1663:        cptr &= NMASK;          /* zero if necessary */
                   1664:        return(c);
                   1665: }
                   1666: 
                   1667: int rawchkc()
                   1668: {
                   1669:        if(EventCmd) longjmp(auxjmp,0);
                   1670:        if(nchars == 0) CheckEvents();  /* this should NOT be necessary! */
                   1671:        return(nchars > 0);
                   1672: }
                   1673: 
                   1674: /* Routines for calling the standard file dialogs, when macify is ON. If the user
                   1675:    changes the directory using the file dialogs, Jove's notion of the current directory
                   1676:    is updated. */
                   1677: 
                   1678: 
                   1679: /* (ORIGINALLY IN) tmacf.c. K. Mitchum 12/86.
                   1680:    Macify routines for jove. */
                   1681: 
                   1682: int CurrentVol;                        /* see tfile.c */
                   1683: 
                   1684: 
                   1685: #define TYPES  (-1)
                   1686: 
                   1687: static Point px = {100,100};
                   1688: static char pmess[] = "\pSave file as: ";
                   1689: 
                   1690: static pascal Boolean Ffilter(p)
                   1691: FileParam *p;
                   1692: {
                   1693:        if(p->ioFlFndrInfo.fdType == 'APPL') return TRUE;
                   1694:        PtoCstr((char *) p->ioNamePtr);
                   1695:        if(strcmp(p->ioNamePtr,d_tempfile) == 0) {
                   1696:                CtoPstr((char *) p->ioNamePtr);
                   1697:                return TRUE;
                   1698:        }
                   1699:        CtoPstr((char *) p->ioNamePtr);
                   1700:        return FALSE;
                   1701: }
                   1702: 
                   1703: static void check_dir()
                   1704: {
                   1705:        if(cur_vol != 0 - SFSaveDisk || cur_dir != CurDirStore) {
                   1706:                setdir(0 - SFSaveDisk, CurDirStore);
                   1707:                UpdModLine = YES;       /* make sure jove knows the change */
                   1708:                Modechange++;
                   1709:                setCWD(getwd());
                   1710:        }
                   1711: }
                   1712: 
                   1713: char *gfile(namebuf)   /* return a filename to get */
                   1714: char *namebuf;
                   1715: {
                   1716:        SFReply frec;
                   1717:        char ans[FILESIZE];
                   1718: 
                   1719:        SFSaveDisk = 0 - cur_vol;       /* in case a Desk Accessory changed them */
                   1720:        CurDirStore = cur_dir;
                   1721:        SFGetFile(px,0L,Ffilter,TYPES,0L,0L,&frec);
                   1722:        check_dir();    /* see if any change, set if so */
                   1723:        if(frec.good) {
                   1724:                EventRecord theEvent;
                   1725:                while(GetNextEvent(updateMask,&theEvent) == 0);
                   1726:                doUpdate(&theEvent);
                   1727:                PtoCstr((char *)frec.fName);
                   1728:                strcpy(ans,frec.fName);
                   1729:                CtoPstr((char *)frec.fName);
                   1730:                PathParse(ans,namebuf);
                   1731:                return(namebuf);
                   1732:        }
                   1733:        return(char *) 0;
                   1734: }
                   1735: 
                   1736: char *pfile(namebuf)
                   1737: char *namebuf;
                   1738: {
                   1739:        SFReply frec;
                   1740:        char *t, *nm;
                   1741:        SFSaveDisk = 0 - cur_vol;       /* in case a Desk Accessory changed them */
                   1742:        CurDirStore = cur_dir;
                   1743:        strncpy(namebuf,filename(curbuf),63);
                   1744:        nm = cvt_fnm(namebuf);
                   1745:        CtoPstr(nm);
                   1746:        SFPutFile(px,pmess,nm,0L,&frec);
                   1747:        check_dir();    /* see if any change, set if so */
                   1748:        if(frec.good) {
                   1749:                EventRecord theEvent;
                   1750:                while(GetNextEvent(updateMask,&theEvent) == 0);
                   1751:                doUpdate(&theEvent);
                   1752:                t = (char *)frec.fName;
                   1753:                PtoCstr((char *)frec.fName);
                   1754:                while(*t == ':') t++;   /* convert to unix style */
                   1755:                nm = t;
                   1756:                while(*nm) {
                   1757:                        if(*nm == ':') *nm = '/';
                   1758:                        nm++;
                   1759:                }
                   1760:                PathParse(t,namebuf);
                   1761:                return(namebuf);
                   1762:        }
                   1763:        return(char *) 0;
                   1764: }
                   1765: 
                   1766: 
                   1767: /* getArgs() returns an argument list based on documents clicked on by the user. */
                   1768: 
                   1769: int getArgs(avp)
                   1770: char ***avp;
                   1771: {
                   1772:        int argc, nargs, type, old_vol;
                   1773:        long old_dir;
                   1774:        char **argv;
                   1775:        char *pathname;
                   1776:        AppFile p;
                   1777:        WDPBRec d;
                   1778: 
                   1779:        old_vol = cur_vol;
                   1780:        old_dir = cur_dir;
                   1781: 
                   1782:        CountAppFiles(&type,&nargs);
                   1783:        if(nargs > 0) { /* files to open... */
                   1784:                argv = (char **) malloc((nargs + 2) * sizeof(char *));
                   1785:                for(argc = 1; argc <= nargs; argc++) {
                   1786:                        GetAppFiles(argc,&p);
                   1787:                        if(type == 0) {
                   1788:                                PtoCstr((char *)p.fName);
                   1789:                                d.ioCompletion = 0;
                   1790:                                d.ioNamePtr = 0;
                   1791:                                d.ioVRefNum = p.vRefNum;
                   1792:                                d.ioWDIndex = 0;
                   1793:                                PBGetWDInfo(&d,0);
                   1794:                                cur_vol = d.ioWDVRefNum;
                   1795:                                cur_dir = d.ioWDDirID;
                   1796:                                pathname = getwd();
                   1797:                                argv[argc] = malloc(strlen((char *)p.fName) + strlen(pathname) + 2);
                   1798:                                strcpy(argv[argc],pathname);
                   1799:                                strcat(argv[argc],"/");
                   1800:                                strcat(argv[argc],(char *)p.fName);
                   1801:                        }
                   1802:                        ClrAppFiles(argc);
                   1803:                }
                   1804:                if(type != 0) argc = 1;
                   1805:        }
                   1806:        else {
                   1807:                argv = (char **) malloc(2 * sizeof(char*));
                   1808:                argc = 1;
                   1809:        }
                   1810:        argv[0] = "jove";
                   1811: 
                   1812:        argv[argc] = 0;
                   1813:        *avp = argv;
                   1814:        cur_dir = old_dir;
                   1815:        cur_vol = old_vol;
                   1816:        return(argc);
                   1817: }
                   1818: 
                   1819: /* Limited version of getenv() */
                   1820: 
                   1821: char *getenv(item)
                   1822: char *item;
                   1823: {
                   1824:        char *ret = 0, *str = 0;
                   1825: 
                   1826:        if(strcmp(item,"CWD") == 0) str = getwd();
                   1827:        if(strcmp(item,"HOME") == 0) str = gethome();
                   1828:        if(str) {
                   1829:                ret = malloc(strlen(str) + 1);
                   1830:                strcpy(ret,str);
                   1831:        }
                   1832:        return(ret);
                   1833: }
                   1834: 
                   1835: char *mktemp(name)
                   1836: char *name;
                   1837: {
                   1838:        return name;
                   1839: }
                   1840: 
                   1841: 
                   1842: /* Menu routines. The menus items are set up in a similar manner as keys, and
                   1843:    are bound prior to runtime. See menumaps.txt, which must be run through setmaps.
                   1844:    Unlike keys, menu items may be bound to variables, and to buffers. Buffer binding
                   1845:    is only done at runtime. */
                   1846: 
                   1847: static void InitLocalMenus()
                   1848: {
                   1849:        void InitMenu(),
                   1850:                make_edits();
                   1851: 
                   1852:        int i;
                   1853:        for(i = 0; i < NMENUS; i++) {
                   1854:                InitMenu(&Menus[i]);
                   1855:                if(i == 0) make_edits(Menus[i].menu_id + 1);
                   1856:        }
                   1857: }
                   1858: 
                   1859: static void InitMenu(M)
                   1860: struct menu *M;
                   1861: {
                   1862:        int i;
                   1863:        data_obj *d;
                   1864:        char *name;
                   1865: 
                   1866:        if(M->menu_id == 0) return;
                   1867:        M->Mn = NewMenu(M->menu_id,CtoPstr(M->Name));
                   1868:        PtoCstr(M->Name);
                   1869: 
                   1870:        for(i = 0; i < NMENUITEMS; i++) {
                   1871:                d = (M->m[i]);
                   1872:                if(d == 0) break;       /* last item... */
                   1873:                switch (d->Type & TYPEMASK) {
                   1874:                        case (STRING) :
                   1875:                                AppendMenu(M->Mn,CtoPstr(d->Name));
                   1876:                                PtoCstr(d->Name);
                   1877:                                break;
                   1878:                        case (VARIABLE) :
                   1879:                                SetItemMark(M->Mn,i + 1, 0x12);
                   1880:                        case (FUNCTION) :
                   1881:                                CtoPstr(name = ((data_obj *) d)->Name);
                   1882:                                AppendMenu(M->Mn,name);
                   1883:                                PtoCstr(name);
                   1884:                }
                   1885:        }
                   1886:        InsertMenu(M->Mn,0);
                   1887: }
                   1888: 
                   1889: static void ProcMenu(menuno,itemno)
                   1890: int menuno,itemno;
                   1891: {
                   1892:        void MacSetVar();
                   1893: 
                   1894:        int i;
                   1895:        data_obj *d;
                   1896: 
                   1897:        for(i = 0; i < NMENUS && Menus[i].menu_id != menuno; i++);
                   1898:        if(i < NMENUS) {        /* found the menu */
                   1899:                itemno--;
                   1900:                d = Menus[i].m[itemno];
                   1901:                switch(d->Type & TYPEMASK) {
                   1902:                        case FUNCTION :
                   1903:                                ExecCmd((data_obj *) d);
                   1904:                                break;
                   1905:                        case BUFFER :
                   1906:                                        SetABuf(curbuf);
                   1907:                                        tiewind(curwind,(Buffer *) d);
                   1908:                                        SetBuf((Buffer *) d);
                   1909:                                break;
                   1910:                        case VARIABLE :
                   1911:                                        MacSetVar((struct variable *) d,i,itemno);
                   1912:                                break;
                   1913:                        default :
                   1914:                                break;
                   1915:                }
                   1916: 
                   1917:        }
                   1918: }
                   1919: 
                   1920: 
                   1921: 
                   1922: 
                   1923: 
                   1924: 
                   1925: static void make_edits(menu)   /* add dummy edit menu */
                   1926: int menu;
                   1927: {
                   1928:        MenuHandle M;
                   1929:        int item;
                   1930:        char *fname;
                   1931: 
                   1932:        M = NewMenu((menu),"\pEdit");
                   1933:        AppendMenu(M,"\pUndo/Z;(-;Cut/X;Copy/C;Paste/V;Clear;Select All;(-;Show Clipboard");
                   1934:        InsertMenu(M,0);
                   1935:        DisableItem(M,0);
                   1936: }
                   1937: 
                   1938: void menus_off()
                   1939: {
                   1940:        int i;
                   1941:        if(Keyonly || EventCmd) return;
                   1942:        
                   1943: #ifdef MENU_DISABLE            /* NOBODY likes this, but it's here if you want it... */
                   1944:        DisableItem(SysMenu,0);
                   1945:        for(i = 0; i < NMENUS; i++)
                   1946:                if(Menus[i].Mn) DisableItem(Menus[i].Mn,0);
                   1947:        DrawMenuBar();
                   1948: #endif
                   1949:        Keyonly = 1;
                   1950: }
                   1951: 
                   1952: void menus_on()
                   1953: {
                   1954:        int i;
                   1955: 
                   1956:        if(Keyonly == 0) return;
                   1957: #ifdef MENU_DISABLE
                   1958:        EnableItem(SysMenu,0);
                   1959:        for(i = 0; i < NMENUS; i++)
                   1960:                if(Menus[i].Mn) EnableItem(Menus[i].Mn,0);
                   1961:        DrawMenuBar();
                   1962: #endif
                   1963:        Keyonly = 0;
                   1964: }
                   1965: 
                   1966: static char *BufMPrint(b,i)
                   1967: Buffer *b;
                   1968: {
                   1969:        char *p;
                   1970:        char *nm = filename(b);
                   1971:        char t[35];
                   1972: 
                   1973:        if(strlen(nm) > 30) {
                   1974:                strcpy(t,"...");
                   1975:                strcat(t,nm + strlen(nm) - 30);
                   1976:        }
                   1977:        else strcpy(t,nm);
                   1978:        nm = t;
                   1979:        while(*nm) {
                   1980:                switch(*nm) {   /* ugh... these are metacharacter for Menus */
                   1981:                        case '/' : *nm = ':'; break;
                   1982:                        case '^' :
                   1983:                        case '!' :
                   1984:                        case '<' :
                   1985:                        case '(' :
                   1986:                        case ';' : *nm = '.'; break;    /* that will confuse everybody */
                   1987:                }
                   1988:                nm++;
                   1989:        }
                   1990:        p = sprint("%-2d %-11s \"%-s\"",i,b->b_name,t);
                   1991:        return(p);
                   1992: }
                   1993: 
                   1994: static void SetBufMenu()
                   1995: {
                   1996:        register Buffer *b;
                   1997:        data_obj *d;
                   1998:        int i,j,stop;
                   1999:        struct menu *M;
                   2000: 
                   2001:        Bufchange = 0;
                   2002:        for(i = 0; i < NMENUS && strcmp(Menus[i].Name,"Buffer"); i++);
                   2003:        if(i < NMENUS) {
                   2004:                M = &Menus[i];
                   2005:                for(j = 0; j < NMENUITEMS && (d = Menus[i].m[j]) && (d->Type & TYPEMASK) != BUFFER; j++);
                   2006:                if(j < NMENUITEMS) {
                   2007:                        for(i = j, b = world; i < NMENUITEMS && b != 0; i++, b = b->b_next) {
                   2008: 
                   2009:                                if(M->m[i] == 0)
                   2010:                                        AppendMenu(M->Mn,CtoPstr(BufMPrint(b,i-j+1)));  /* add the item */
                   2011:                                else
                   2012:                                        SetItem(M->Mn,i + 1,CtoPstr(BufMPrint(b,i-j+1)));       /* or change it */
                   2013:                                M->m[i] = (data_obj *) b;
                   2014:                        }
                   2015:                        stop = i;
                   2016:                          /* out of buffers? */
                   2017:                        for(;i < NMENUITEMS && M->m[i];i++) {
                   2018:                                DelMenuItem(M->Mn,stop + 1);    /* take off last item */
                   2019:                                M->m[i] = 0;
                   2020:                        }
                   2021:                }
                   2022:        }
                   2023:        return;
                   2024: }
                   2025: 
                   2026: static void MacSetVar(vp,mnu,itm)      /* Set a variable from the menu */
                   2027: struct variable *vp;   /* Liberally taken from SetVar() in extend.c */
                   2028: int mnu,itm;
                   2029: {
                   2030:        void MarkVar();
                   2031: 
                   2032:        char *prompt;
                   2033: 
                   2034:        prompt = sprint("Set %s: ", vp->Name);
                   2035:        switch (vp->v_flags & V_TYPEMASK) {
                   2036:        case V_BASE10:
                   2037:        case V_BASE8:
                   2038:            {
                   2039:                int     value;
                   2040: 
                   2041:                value = ask_int(prompt, ((vp->v_flags & V_TYPEMASK) == V_BASE10)
                   2042:                                          ? 10 : 8);
                   2043:                *(vp->v_value) = value;
                   2044:                break;
                   2045:            }
                   2046:        case V_BOOL:    /* toggle the value */
                   2047:                *(vp->v_value) = (*vp->v_value == ON ? OFF : ON);
                   2048:                MarkVar(vp,mnu,itm);
                   2049:                break;
                   2050:        case V_FILENAME:
                   2051:        case V_STRING:
                   2052:            {
                   2053:                char    *str;
                   2054: 
                   2055:                /* Do_ask() so you can set string to "" if you so desire. */
                   2056:                str = do_ask("\r\n", (int (*) proto((int))) 0, (char *) vp->v_value,
                   2057:                        prompt);
                   2058:                if (str == 0)
                   2059:                        str = NullStr;
                   2060:                strcpy((char *) vp->v_value, str);
                   2061:                /* ... and hope there is enough room. */
                   2062:                break;
                   2063:            }
                   2064:        case V_CHAR:
                   2065:                f_mess(prompt);
                   2066:                *(vp->v_value) = addgetc();
                   2067:                break;
                   2068:        }
                   2069: 
                   2070:        if (vp->v_flags & V_MODELINE)
                   2071:                UpdModLine = YES;
                   2072:        if (vp->v_flags & V_CLRSCREEN) ClAndRedraw();
                   2073:        if (vp->v_flags & V_TTY_RESET) tty_reset(); /* probably none on a Mac */
                   2074:        return;
                   2075: }
                   2076: 
                   2077: static void MarkModes()
                   2078: {
                   2079:        int mnu,itm,checked;
                   2080:        data_obj *d;
                   2081: 
                   2082:        Modechange = 0;
                   2083:        for(mnu = 0; mnu < NMENUS; mnu++)
                   2084:                for(itm = 0; itm < NMENUITEMS; itm++) {
                   2085:                        if((d = Menus[mnu].m[itm]) == 0) break;
                   2086:                        if((d->Type & (MAJOR_MODE | MINOR_MODE)) ||
                   2087:                                 ((d->Type & TYPEMASK) == BUFFER)){
                   2088:                                if(d->Type & (MAJOR_MODE))
                   2089:                                        checked = (curbuf->b_major == (d->Type >> 8)) ? 1 : 0;
                   2090:                                else if(d->Type & (MINOR_MODE))
                   2091:                                        checked = (curbuf->b_minor & (d->Type >> 8)) ? 1 : 0;
                   2092:                                else
                   2093:                                        checked = (d == (data_obj *) curbuf) ? 1 : 0;
                   2094:                                CheckItem(Menus[mnu].Mn, itm + 1, checked);
                   2095:                        }
                   2096:                }
                   2097: }
                   2098: 
                   2099: void MarkVar(vp,mnu,itm)       /* mark a boolean menu item */
                   2100: struct variable *vp;
                   2101: int mnu,itm;
                   2102: {
                   2103:        int checked;
                   2104:        if(mnu == -1) {         /* we don't know the item... slow */
                   2105:                int found;
                   2106:                for(mnu = 0, found = 0; (mnu < NMENUS) && !found; mnu++) {
                   2107:                        for(itm = 0; (itm < NMENUITEMS); itm++)
                   2108:                                if((struct variable *) (Menus[mnu].m[itm]) == vp) {
                   2109:                                        found++;
                   2110:                                        break;
                   2111:                                }
                   2112:                        if(found) break;
                   2113:                }
                   2114:                if(!found) return;
                   2115:        }
                   2116:        checked = (*(vp->v_value) == ON);
                   2117:        CheckItem(Menus[mnu].Mn, itm + 1, checked);
                   2118: }
                   2119: 
                   2120: static void MarkAllVar()       /* slow, but only do it once */
                   2121: {
                   2122:        int mnu,itm;
                   2123:        data_obj *d;
                   2124:        for(mnu = 0; mnu < NMENUS; mnu++)
                   2125:                for(itm = 0; itm < NMENUITEMS; itm++) {
                   2126:                        if((d = Menus[mnu].m[itm]) == 0) break;
                   2127:                        if((d->Type & TYPEMASK) == VARIABLE)
                   2128:                                MarkVar((struct variable *)Menus[mnu].m[itm],mnu,itm);
                   2129:                }
                   2130: }
                   2131: 
                   2132: 
                   2133: /* Screen routines and driver. The Macinitosh Text Edit routines are not utilized,
                   2134:    as they are slow and cumbersome for a terminal emulator. Instead, direct QuickDraw
                   2135:    calls are used. The fastest output is obtained writing a line at a time, rather
                   2136:    than on a character basis, so the major output routine is writechr(), which takes
                   2137:    a pascal-style string as an argument. See bufputc() in screen.c. */
                   2138: 
                   2139: void Placur(line,col)
                   2140: int line, col;
                   2141: {
                   2142:        CapCol = col;
                   2143:        CapLine = line;
                   2144:        putcurs(line,col,ON);
                   2145: }
                   2146: 
                   2147: void NPlacur(line,col)
                   2148: int line, col;
                   2149: {
                   2150:        CapCol = col;
                   2151:        CapLine = line;
                   2152:        putcurs(line,col,OFF);
                   2153: }
                   2154: 
                   2155: void i_lines(top, bottom, num)
                   2156: int top, bottom, num;
                   2157: {
                   2158:        Placur(bottom - num + 1, 0);
                   2159:        dellines(num,bottom);
                   2160:        Placur(top, 0);
                   2161:        inslines(num,bottom);
                   2162: }
                   2163: 
                   2164: void d_lines(top, bottom, num)
                   2165: int top, bottom, num;
                   2166: {
                   2167:        Placur(top, 0);
                   2168:        dellines(num,bottom);
                   2169:        Placur(bottom + 1 - num, 0);
                   2170:        inslines(num,bottom);
                   2171: }
                   2172: 
                   2173: /* (ORIGINALLY IN) tn.c   */
                   2174: /* window driver for MacIntosh using windows. */
                   2175: /* K. Mitchum 9/86 */
                   2176: 
                   2177: 
                   2178: /*#define VARFONT*/
                   2179: #ifdef VARFONT
                   2180: static height,width,theight,twidth,descent;
                   2181: #else
                   2182: #define height HEIGHT
                   2183: #define width WIDTH
                   2184: #define theight THEIGHT
                   2185: #define twidth TWIDTH
                   2186: #define descent DESCENT
                   2187: #endif
                   2188: 
                   2189: static trow,tcol, insert, tattr, cursor;
                   2190: static Rect cursor_rect;
                   2191: static char *p_scr, *p_curs;   /* physical screen and cursor */
                   2192: static int p_size;
                   2193: 
                   2194: static Rect  vRect;
                   2195: static WindowRecord myWindowRec;
                   2196: 
                   2197: #define active() SetPort(theScreen)
                   2198: #define maxadjust(r) OffsetRect((r),0,2);
                   2199: 
                   2200: char *conv_p_curs(row,col) 
                   2201: {
                   2202:        return(p_scr + (row * (CO)) + col);
                   2203: }
                   2204: 
                   2205: static void INSmode(new)
                   2206: int new;
                   2207: {
                   2208:        insert = new;
                   2209: }
                   2210: 
                   2211: static void HLmode(new)
                   2212: int new;
                   2213: {
                   2214:        if(new) tattr = 1;
                   2215:        else tattr = 0;
                   2216: }
                   2217: void SO_on()
                   2218: {
                   2219:        HLmode(1);
                   2220: }
                   2221: 
                   2222: void SO_off()
                   2223: {
                   2224:        HLmode(0);
                   2225: }
                   2226: 
                   2227: 
                   2228: static void tn_init()
                   2229: {
                   2230:        void INSmode(),
                   2231:        init_slate();
                   2232: 
                   2233:        HLmode(0);
                   2234:        INSmode(0);
                   2235:        init_slate();
                   2236:        ShowPen();
                   2237: }
                   2238: 
                   2239: void clr_page()        /* clear and home function */
                   2240: {
                   2241:        Rect r;
                   2242: 
                   2243:        setmem(p_scr,p_size,' ');
                   2244:        active();
                   2245:        SetRect(&r, 0,0,WINDWIDTH,WINDHEIGHT);
                   2246:        EraseRect(&r);
                   2247:        cursor = OFF;
                   2248:        putcurs(0,0);
                   2249:        drawfluff();
                   2250: }
                   2251: 
                   2252: static void putcurs(row,col,vis)
                   2253: unsigned row, col, vis;
                   2254: {
                   2255:        active();
                   2256:        curset(OFF);
                   2257:        trow = row;
                   2258:        tcol = col;
                   2259:        curset(vis);
                   2260: }
                   2261: 
                   2262: static void curset(desired)
                   2263: {
                   2264:        p_curs = conv_p_curs(trow,tcol);
                   2265:        if(trow == MAXROW)
                   2266:                MoveTo(tcol * width, (trow  +1) * height + 2 -descent );
                   2267:        else
                   2268:                MoveTo(tcol * width, (trow  +1) * height - descent);
                   2269: 
                   2270:        DrawChar(*p_curs);
                   2271: 
                   2272:        if(desired == ON) {
                   2273:                SetRect(&cursor_rect, tcol * width, (trow) * height , (tcol + 1) * width - 1, (trow +1) * height -1);
                   2274:                if(trow == MAXROW) maxadjust(&cursor_rect);
                   2275:                InvertRect(&cursor_rect);
                   2276:        }
                   2277:        if(trow == MAXROW)
                   2278:                MoveTo(tcol * width, (trow  +1) * height + 2 -descent );
                   2279:        else
                   2280:                MoveTo(tcol * width, (trow  +1) * height - descent);
                   2281: }
                   2282: 
                   2283: 
                   2284: void putp(p)                   /* put one character, advance cursor */
                   2285: int p;
                   2286: {
                   2287:        static Rect r;
                   2288:        static RgnHandle updateRgn;
                   2289: 
                   2290:        active();
                   2291:        curset(OFF);
                   2292:        if(insert) {
                   2293:                updateRgn = NewRgn();
                   2294:                SetRect(&r, tcol * width, trow * height, WINDWIDTH, (trow +1) * height -1);
                   2295:                if(trow == MAXROW) maxadjust(&r);
                   2296:                ScrollRect(&r, width, 0, updateRgn);
                   2297:                DisposeRgn(updateRgn);
                   2298:        }
                   2299:        if(p == '0') p = 0xAF;  /* slashed zero */
                   2300:        if(insert) BlockMove(p_curs, p_curs + 1, (long) (MAXCOL - tcol));
                   2301:        *p_curs = (char) p;
                   2302:        DrawChar(p);
                   2303:        if(tcol >= MAXCOL) putcurs(trow,MAXCOL);
                   2304:        else putcurs(trow,tcol +1);
                   2305: }
                   2306: 
                   2307: void clr_eoln()
                   2308: {
                   2309:                static Rect r;
                   2310: 
                   2311:                active();
                   2312:                cursor = OFF;
                   2313:                SetRect(&r, tcol * width, trow * height, WINDWIDTH, (trow +1) * height);
                   2314:                if(trow == MAXROW) maxadjust(&r);
                   2315:                EraseRect(&r);
                   2316:                setmem(p_curs,CO - tcol, ' ');
                   2317:                curset(ON);
                   2318: }
                   2319: 
                   2320: static void delchars()
                   2321: {
                   2322:                static Rect r;
                   2323:                static RgnHandle updateRgn;
                   2324: 
                   2325:        active();
                   2326:        curset(OFF);
                   2327:        updateRgn = NewRgn();
                   2328:        SetRect(&r, tcol * width, trow * height, twidth - width, (trow +1) * height);
                   2329:        if(trow == MAXROW) maxadjust(&r);
                   2330:        ScrollRect(&r, 0 - width, 0, updateRgn);
                   2331:        DisposeRgn(updateRgn);
                   2332:        BlockMove(p_curs + 1, p_curs, (long) (MAXCOL - tcol));
                   2333:        *(conv_p_curs(trow,MAXCOL)) = ' ';
                   2334:        curset(ON);
                   2335: }
                   2336: 
                   2337: static void dellines(n,bot)
                   2338: int n,bot;
                   2339: {
                   2340:        Rect r;
                   2341:        RgnHandle updateRgn;
                   2342:        long len;
                   2343: 
                   2344:        updateRgn = NewRgn();
                   2345:        active();
                   2346:        curset(OFF);
                   2347:        SetRect(&r, 0, ((trow) * height), WINDWIDTH, ((bot + 1) * height));
                   2348:        ScrollRect(&r, 0, 0 - (n * height), updateRgn);
                   2349:        DisposeRgn(updateRgn);
                   2350:        len = ((bot - trow - n + 1) * CO);
                   2351:        BlockMove(conv_p_curs((trow + n),0), conv_p_curs(trow,0), len);
                   2352:        setmem(conv_p_curs((bot - n + 1),0),(n * CO),' ');
                   2353:        putcurs(trow,0);
                   2354: }
                   2355: 
                   2356: static void inslines(n,bot)
                   2357: int n,bot;
                   2358: {
                   2359:        Rect r;
                   2360:        RgnHandle updateRgn;
                   2361:        long len;
                   2362: 
                   2363:        updateRgn = NewRgn();
                   2364:        active();
                   2365:        curset(OFF);
                   2366:        SetRect(&r, 0, trow * height, WINDWIDTH, (bot +1) * height);
                   2367:        ScrollRect(&r, 0, (n * height), updateRgn);
                   2368:        DisposeRgn(updateRgn);
                   2369:        len = ((bot - trow - n +1) * CO);
                   2370:        BlockMove(conv_p_curs(trow,0), conv_p_curs((trow + n),0), len);
                   2371:        setmem(conv_p_curs(trow,0),(n * CO),' ');
                   2372:        putcurs(trow,0);
                   2373: }
                   2374: 
                   2375: void writechr(start)
                   2376: char *start;   /* actually, a Str255 type string */
                   2377: {
                   2378:        static Rect r;
                   2379:        static RgnHandle updateRgn;
                   2380:        register len;
                   2381:        register char save;
                   2382: 
                   2383:        len = (int) start[0] & 0xff;            /* adjusted 6/86 K. M. in td.c*/
                   2384: 
                   2385:        active();
                   2386:        curset(OFF);
                   2387:        if(insert) {
                   2388:                updateRgn = NewRgn();
                   2389:                SetRect(&r, tcol * width, trow * height, twidth - width * len, (trow +1) * height -1);
                   2390:                if(trow == MAXROW) maxadjust(&r);
                   2391:                ScrollRect(&r, width * len, 0, updateRgn);
                   2392:                DisposeRgn(updateRgn);
                   2393:        }
                   2394:        DrawString(start);
                   2395:        if(insert) BlockMove(p_curs,p_curs + len, (long) (CO - tcol - len));
                   2396:        strncpy(p_curs,start + 1,len);
                   2397:        if(tcol >= MAXCOL) putcurs(trow,MAXCOL);
                   2398:        else putcurs(trow,tcol +len);
                   2399: }
                   2400: 
                   2401: static Rect myBoundsRect;
                   2402: static void init_slate()
                   2403: {
                   2404:        FontInfo f;
                   2405: 
                   2406:        char *Name = "Jove ";
                   2407:        char *Title;
                   2408: 
                   2409:        InitGraf(&thePort);
                   2410:        InitWindows();
                   2411:        InitCursor();
                   2412:        InitFonts ();
                   2413:        InitMenus ();
                   2414:        InitDialogs ((ProcPtr) 0);              /* no restart proc */
                   2415: 
                   2416:        /* figure limiting rectangle for window moves */
                   2417:        SetRect(&LimitRect,
                   2418:                screenBits.bounds.left + 3,
                   2419:                screenBits.bounds.top + 20,
                   2420:                screenBits.bounds.right - 3,
                   2421:                screenBits.bounds.bottom -3);
                   2422: 
                   2423:        Set_std();
                   2424:        SetBounds();
                   2425: 
                   2426:        /* initialize char array for updates */
                   2427:        p_scr = emalloc(p_size = wc_std.w_cols * wc_std.w_rows);        /* only once */
                   2428:        p_curs = p_scr;
                   2429:        
                   2430:        Title = sprint("%s%s",Name,version);
                   2431:        theScreen = NewWindow(&myWindowRec, &myBoundsRect,CtoPstr(Title),
                   2432:                1,8,(WindowPtr) -1, 1, (long) 0);
                   2433: 
                   2434:        /* figure an initial window configuration and adjust it */
                   2435:        wc = &wc_std;
                   2436:        wc_user = wc_std;       /* initially, only one configuration to toggle */
                   2437:        user_state(theScreen) = std_state(theScreen);
                   2438:        SetPort(theScreen);
                   2439: 
                   2440:        (theScreen)->txFont = FONT;
                   2441:        (theScreen)->txSize = TEXTSIZE;
                   2442: 
                   2443: #ifdef VARFONT
                   2444:        GetFontInfo(&f);
                   2445:                height = f.ascent+f.descent+f.leading;
                   2446:                width = f.widMax;
                   2447:                twidth = width * wc->w_cols;
                   2448:                theight = height * wc->w_rows;
                   2449:                descent = f.descent;
                   2450: #endif
                   2451: 
                   2452:        theScreen->txMode = patCopy;
                   2453:        theScreen->pnMode = patCopy;
                   2454:        PenNormal();
                   2455:        cursor = OFF;
                   2456: }
                   2457: 
                   2458: p_refresh()
                   2459: {
                   2460:        int lineno;
                   2461:        char *curs, *buf;
                   2462: 
                   2463:        buf = malloc(CO + 1);
                   2464:        for(lineno = 0; lineno < LI; lineno++) {
                   2465:                curs = conv_p_curs(lineno,0);
                   2466:                if(lineno == MAXROW)
                   2467:                        MoveTo(0, (lineno  +1) * height + 2 -descent );
                   2468:                else
                   2469:                        MoveTo(0, (lineno  +1) * height - descent);
                   2470:                strncpy(buf + 1, curs, CO);
                   2471:                buf[0] = (char) CO;
                   2472:                DrawString(buf);
                   2473:        }
                   2474:        putcurs(trow,tcol,0);
                   2475:        free(buf);
                   2476: }
                   2477: 
                   2478: 
                   2479: 
                   2480: 
                   2481: 
                   2482: wc_adjust(w,h,wcf,init)                /* adjust window config to look nice */
                   2483: struct wind_config *wcf;
                   2484: {
                   2485:        static int LIMIT_R, LIMIT_C;
                   2486:        int rows, cols;
                   2487: 
                   2488:        if(init) {
                   2489:                LIMIT_R = (h - 4) / HEIGHT;
                   2490:                LIMIT_C = (w - SCROLLWIDTH - 1) / WIDTH + 1;
                   2491:        }
                   2492:        if((w < WIDTH * 40) ||(h < HEIGHT * 10) /* too small */
                   2493:                || ((rows = (h - 4) / HEIGHT) > LIMIT_R)        /* too big */   
                   2494:                || ((cols = (w - SCROLLWIDTH - 1) / WIDTH + 1) > LIMIT_C)) return(0);
                   2495: 
                   2496:        wcf->w_rows = rows;
                   2497:        wcf->w_cols = cols;
                   2498:        wcf->w_width = wcf->w_cols * WIDTH + 1 + SCROLLWIDTH;
                   2499:        wcf->w_height = wcf->w_rows * HEIGHT + 4;
                   2500:        return(1);
                   2501: }
                   2502: 
                   2503: getCO()        /* so that jove knows params */
                   2504: {
                   2505:        return wc->w_cols;
                   2506: }
                   2507: 
                   2508: getLI()
                   2509: {
                   2510:        return wc->w_rows;
                   2511: }
                   2512: 
                   2513: static SetBounds()
                   2514: {
                   2515:        SetRect(&myBoundsRect,
                   2516:                screenBits.bounds.left + 3,
                   2517:                screenBits.bounds.top + 40,
                   2518:                screenBits.bounds.left + 3 + wc_std.w_width,    
                   2519:                screenBits.bounds.top + 40 + wc_std.w_height);
                   2520: }
                   2521: 
                   2522: static Set_std()
                   2523: {
                   2524:        wc_adjust(screenBits.bounds.right - screenBits.bounds.left - 6, 
                   2525:                screenBits.bounds.bottom - screenBits.bounds.top - 42,
                   2526:                &wc_std,1);
                   2527: }
                   2528: 
                   2529: static Reset_std()
                   2530: {
                   2531:        Set_std();
                   2532:        std_state(theScreen) = myBoundsRect;
                   2533: }
                   2534: #endif /* MAC */

unix.superglobalmegacorp.com

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