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