|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.