Annotation of 43BSDReno/contrib/jove/mac.c, revision 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.