diff --git a/README-Conversion to Pro 1 b/README-Conversion to Pro 1 new file mode 100755 index 0000000..8ae3794 --- /dev/null +++ b/README-Conversion to Pro 1 @@ -0,0 +1 @@ +======================================================================== Better Telnet Conversion Release Notes ======================================================================== Version: BetterTelnet 1.2.1/CodeWarrior Pro 1 Date: December 5, 1997 Author: Lawrence You ======================================================================== Conversion notes for conversion of BetterTelnet 1.2.1 (CW10) to CodeWarrior Pro 1. The BetterTelnet application was last built with CodeWarrior 10. These are the changes that were made to convert it to CodeWarrior Pro 1 (and later to CodeWarrior Pro 2). The new project builds with CodeWarrior Pro 1 as-is. See "Additional Notes" below, for the steps for conversion. ======================================================================== New Features in This Version ======================================================================== * Fat binaries * Multiple targets, single project; new vers resource * Metrowerks Standard Libraries (Runtime and ANSI C) ======================================================================== Bugs Fixed in This Version ======================================================================== * Precompiled headers ======================================================================== Known Bugs and Incompatibilities ======================================================================== * Compatible with Universal Headers using the "OLDROUTINENAMES" mode. (i.e., the program still compiles with old-style Mac headers with minor changes.) ======================================================================== Additional Notes ======================================================================== Following are the steps that were required to convert this application into a fat binary with CodeWarrior Pro 1. * Convert to Pro 1 with Project Converter. Drag the two CW10 projects onto the Metrowerks conversion program, "Project Converter 1.x" in the "Other Metrowerks Tools" folder. This will create a newly merged project file. * Remove old projects Delete the projects named projects named "telnet.68k." and "telnet.ppc.". * Open new project Open the new project with "CodeWarrior IDE 2.0" (or 2.1). * Fix access paths Various runtime libraries have been replaced with new versions in CodeWarrior Pro 1 based on the Metrowerks Standard Library (MSL). Click on the Target tab Double-click on the "telnet.68k" target. Select the Target:Access Paths panel. Add "{Compiler }Metrowerks Standard Library" to the System Paths. Click Save Do the same for the "telnet.ppc" target. * Use Metrowerks Standard Library for PowerPC Click on the Files tab. Command-click on an disclosure tab. Find the "Main" group" Select the "MWCRuntimeLib" file, establishing a selection where new libraries will be added. Choose "Add Files" from the Project menu. Add the file "Metrowerks CodeWarrior:MacOS Support:Libraries:Runtime: Runtime PPC:MSL RuntimePPC.Lib" Add it only to the "telnet.ppc" target when the dialog asks which target to use. Add the file "Metrowerks CodeWarrior:Metrowerks Standard Library: MSL C:Bin:MSL SIOUX.PPC.Lib" Add the file "Metrowerks CodeWarrior:Metrowerks Standard Library: MSL C:Bin:MSL C.PPC.Lib" Select "MWCRuntimeLib" Choose "Remove Selected Items" from the Project menu. * Use Metrowerks Standard Library for 68K Click on the Files tab. Command-click on an disclosure tab. Find the "Libraries" group" Select the "ANSI (2i) C.68K.Lib" file, establishing a selection where new libraries will be added. Choose "Add Files" from the Project menu. Add the file "Metrowerks CodeWarrior:MacOS Support:Libraries:Runtime: Runtime 68K:MSL Runtime68K.Lib" Add it only to the "telnet.68k" target when the dialog asks which target to use. Add the file "Metrowerks CodeWarrior:Metrowerks Standard Library: MSL C:Bin:MSL SIOUX.68K.Lib" Add the file "Metrowerks CodeWarrior:Metrowerks Standard Library: MSL C:Bin:MSL C.68K (2i).Lib" Select "ANSI (2i) C.68K.Lib" Choose "Remove Selected Items" from the Project menu. * Create a new target for fat binaries Choose "Create New Target" from the "Project" menu. Type in "telnet.fat", select "Empty Target" and click OK. Drag the target icons for "telnet.68k" and "telnet.ppc" as child (dependent) projects under "telnet.fat". Selecting this target (setting the black arrow) will cause both dependent projects to be built. Click the area under the chain icon, causing a black dot to appear to the right of the "telnet.fat" target. This indicates that the two dependent projects are linked in. * Fix precompiled headers Copy a version of MacHeaders.c (the file that includes all of the Mac headers) into the "telnet source :source:Headers:" directory. This will be used to create a slightly different version of the precompiled "MacHeaders" for this project. Edit the MacHeaders.c file just copied and change the define to be: #define OLDROUTINENAMES 1 This ensures that the project builds with the old-style (pre- Universal Headers 3.0) Macintosh API. If any changes are made to this precompiled header, make sure to delete the files named "TelnetHeader68K" and "TelnetHeaderPPC". Choose "Re-search for files" from the Project menu. * Update filenames Change the "BetterTelnet" application (68K only) to the PowerPC version: Click the Targets tab. Double-click "telnet.68k". Select "Target:68K Target" Change the File Name field from "BetterTelnet" to "BetterTelnet 68K" Click Save Close the window * Fix the fat application target Double-click "telnet.fat" Select "Linker:MacOS Merge" Check "Suppress Warnings" Change the creator to "rlfT" (same as for 68K and PPC versions). Click "Activate Browser" under Build Extras (you can do this for 68K and PPC projects also). Click Save Close the window * Fix 'vers' version resources Open up the telnet.68k.rsrc resource file. Change the version string to reflect the build is with CodeWarrior Pro 2. ======================================================================== Contacting Metrowerks ======================================================================== For bug reports, technical questions, and suggestions, please use the forms in the Release Notes folder on the CD, and send them to support@metrowerks.com See the CodeWarrior on the Nets document in the Release Notes folder for more contact information, including a list of Internet newsgroups, online services, and patch and update sites. ======================================================================== Lawrence You Metrowerks Corporation \ No newline at end of file diff --git a/README-Conversion to Pro 2 b/README-Conversion to Pro 2 new file mode 100755 index 0000000..e019745 --- /dev/null +++ b/README-Conversion to Pro 2 @@ -0,0 +1 @@ +======================================================================== Better Telnet Conversion Release Notes ======================================================================== Version: BetterTelnet 1.2.1/CodeWarrior Pro 2 Date: December 5, 1997 Author: Lawrence You ======================================================================== Conversion notes for conversion of BetterTelnet 1.2.1 (CW10) to CodeWarrior Pro 2. The BetterTelnet application was last built with CodeWarrior 10. These are the changes that were made to convert it to Pro 2 (see the release notes "README-Conversion to Pro 1" first). The new project builds with CodeWarrior Pro 2 as-is. See "Additional Notes" below, for the steps for conversion. ======================================================================== New Features in This Version ======================================================================== * N/A ======================================================================== Bugs Fixed in This Version ======================================================================== * Compatibility with Universal Headers 3.0.1 ======================================================================== Known Bugs and Incompatibilities ======================================================================== * Compatible with Universal Headers using the "OLDROUTINENAMES" mode. (i.e., the program still compiles with old-style Mac headers with minor changes.) ======================================================================== Additional Notes ======================================================================== Following are the steps that were required to convert this application for use with the CodeWarrior Pro 2 headers (Mac OS Support). * Minor changes Build the "telnet source (CWPro1)" project. Fix these errors: Change parameters to "Delay( ... , long*)" to use "Delay( ... , unsigned long*)" instead. The structure "WindowRecord" changed. Cast fields which are now "Handle" to "ControlHandle". Bracket declarations of the obsoleted struct, "AppFile" so that they are not declared as local variables in "init.c": #ifndef __powerpc__ AppFile theFile; #endif * Change 'vers' version resource Reflect change to source in all three telnet.xxx.rsrc files. ======================================================================== Contacting Metrowerks ======================================================================== For bug reports, technical questions, and suggestions, please use the forms in the Release Notes folder on the CD, and send them to support@metrowerks.com See the CodeWarrior on the Nets document in the Release Notes folder for more contact information, including a list of Internet newsgroups, online services, and patch and update sites. ======================================================================== Lawrence You Metrowerks Corporation \ No newline at end of file diff --git a/source/FTPserver/binsubs.c b/source/FTPserver/binsubs.c index 8fd5cbf..b3ca151 100755 --- a/source/FTPserver/binsubs.c +++ b/source/FTPserver/binsubs.c @@ -1 +1 @@ -// binsubs.c // MacBinary Subroutines. // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #ifdef MPW #pragma segment FTPServer #endif #include "maclook.proto.h" #include "bkgr.proto.h" #include "MacBinary.h" #include "telneterrors.h" #include "binsubs.proto.h" #include "translate.proto.h" #include "debug.h" #include "DlogUtils.proto.h" // For WriteZero static unsigned short CalculateCRC(unsigned char *ptr, short count, unsigned short crc); static void SetFileInfo(short volume, long dirID, StringPtr name, HFileParam *iop); static void MakeTextFile(short volume, long dirID, StringPtr name, HFileParam *iop); static short isMacBinary(MBHead *p); static OSErr bwrite( MBFile *out, char *buffer, long size); static void ProcessMBHead (MBFile *out, MBHead *header); extern MBFile /* BYU */ *mbfp; /* BYU */ #define BLOCKS(x) ((x+127)/128) /*#define lmove(f,t) memmove(f,t,(size_t) 4) /* BYU LSC */ MBHead *mbh; char buffer[128]; unsigned short CalculateCRC(unsigned char *ptr, short count, unsigned short crc) { unsigned short i; crc = 0; while (count -- > 0) { crc = crc ^ (unsigned short)*ptr++ << 8; for (i = 0; i < 8; i++) if (crc & 0x8000) crc = crc << 1 ^ 0x1021; else crc = crc << 1; } return crc; } void GetFileInfo(short volume, long dirID, StringPtr name, HFileParam *iop) { OSErr err; iop->ioNamePtr = name; iop->ioVRefNum = volume; iop->ioDirID = dirID; iop->ioFVersNum = 0; iop->ioFDirIndex = 0; err = PBHGetFInfo((HParmBlkPtr) iop, FALSE); } void SetFileInfo(short volume, long dirID, StringPtr name, HFileParam *iop) { OSErr err; iop->ioNamePtr = name; iop->ioVRefNum = volume; iop->ioDirID = dirID; iop->ioFVersNum = 0; iop->ioFDirIndex = 0; err = PBHSetFInfo((HParmBlkPtr) iop, FALSE); } void MakeTextFile(short volume, long dirID, StringPtr name, HFileParam *iop) { GetFileInfo(volume, dirID, name, iop); iop->ioFlFndrInfo.fdType = 'TEXT'; iop->ioFlFndrInfo.fdCreator = gFTPServerPrefs->TextCreator; SetFileInfo(volume, dirID, name, iop); } short isMacBinary(MBHead *p) { unsigned short crc; if ((p->nlen > 0) && (p->nlen < 65) && (p->zero1 == 0) && (p->zero2 == 0) && (p->zero3 == 0)) { // Assume MB I crc = CalculateCRC((unsigned char *)p, 124, 0); if (((short)p->crc == crc) && (p->mb2versnum > 128)) { // Check for MB II if (p->mb2minvers > 129) return(0); // If vers is greater than 129, leave it alone return (1); // Valid MB II file. } else { p->flags2 = 0; // So we can use same routines for MB I & II return (1); // Valid MB I file (we make it a II file on the fly.) } } return(0); // Not a Macbinary file } long MBsize( MBFile *mbfp) { long size = 0; OSErr ret; ret = GetEOF( mbfp->fd, &size ); /* length of file data fork */ if (ret != noErr) size = 0; return(size); } MBFile *MBopen(char *file, short vrefnum, long dirID, short mode) { MBFile *mbfp; OSErr err; int i; if ((mbfp = (MBFile *) myNewPtr(sizeof(MBFile))) == NULL) return(NULL); if (gFTPServerPrefs->DoISOtranslation) // MP: translation method trbuf_ftp_mac((unsigned char *)file, strlen(file)); BlockMove(file, mbfp->name, 32); if (strlen(file) > 31) mbfp->name[31] = 0; c2pstr((char *)mbfp->name); if (mbfp->name[1] == '.') mbfp->name[1] = '_'; //replace leading period with slash for (i = 1; i <= mbfp->name[0]; i++) // replace embedded slashes, colons, and CRs if (mbfp->name[i] == '/' || mbfp->name[i] == ':' || mbfp->name[i] == CR) mbfp->name[i] = ' '; if (gFTPServerPrefs->DoISOtranslation) trbuf_mac_ftp((unsigned char *)file, strlen(file)); // MP: translation method mbfp->vrefnum = vrefnum; mbfp->dirID = dirID; mbfp->mode = mode; if ((err = HOpenDF( vrefnum, dirID, mbfp->name, fsRdWrPerm, &mbfp->fd)) != noErr) { if ((err==-43) && (mode & MB_WRITE)) { err = HCreate( vrefnum, dirID, mbfp->name, gFTPServerPrefs->BinaryCreator, gFTPServerPrefs->BinaryType); if (mode & MB_ISASCII) { HFileParam blah; MakeTextFile(vrefnum, dirID, mbfp->name, &blah); } if (HOpenDF( vrefnum, dirID, mbfp->name, fsRdWrPerm, &mbfp->fd)) return( 0L); } else return(0L); } if (mode & MB_APPEND) SetFPos(mbfp->fd,fsFromLEOF,0); mbfp->binary=0; mbfp->sector1=1; mbfp->fork=0; return( mbfp); } OSErr bwrite( MBFile *out, char *buffer, long size) { long len = size; OSErr error = noErr; if (out->binary) { if (out->bytes > 0) { if (out->bytes < len) len = out->bytes; error= FSWrite( out->fd, &len, buffer); out->bytes -= len; buffer +=len; size -= len; } if (out->bytes <= 0) { if (!out->fork) { out->fork = 1; out->bytes = BLOCKS(out->rlen)*128; SetEOF( out->fd, (long) out->dlen); FSClose( out->fd); if (out->bytes) { HOpenRF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd); if (size) { len = (long) size; error= FSWrite( out->fd, &len, buffer); } } else out->fd = 0; } else SetEOF( out->fd, (long) out->rlen); } } else { error = FSWrite( out->fd, &len, buffer); } return (error); } void ProcessMBHead (MBFile *out, MBHead *header) { OSErr err; BlockMove(header, &out->header, sizeof(MBHead)); out->binary = 1; BlockMove(&header->dflen[0], &out->dlen, 4); BlockMove(&header->rflen[0], &out->rlen, 4); out->bytes = BLOCKS(out->dlen)*128; out->fork = 0; out->sector1 = 0; FSClose(out->fd); if (HDelete( out->vrefnum, out->dirID, out->name)) /* Error deleting Old File */ DoError (200 | RESOURCE_ERRORCLASS, LEVEL1, NULL); BlockMove(&out->header.nlen, out->name, 32); #if 0 /* BYU 2.4.17 */ MBstat( &out->header.nlen, 1, (long)(BLOCKS(out->dlen)+BLOCKS(out->rlen)) ); #endif /* BYU 2.4.17 */ if (out->bytes) { if ((err=HOpenDF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) != noErr) { if (err == -43) { long cre,typ; BlockMove(out->header.type, &typ, 4); BlockMove(out->header.creator, &cre, 4); HCreate( out->vrefnum, out->dirID, out->name, cre, typ); if (HOpenDF(out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) return; } else { return; } } } else { if ((err=HOpenRF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) != noErr) { if (err == -43) { long cre,typ; BlockMove(out->header.type, &typ, 4); BlockMove(out->header.creator, &cre, 4); HCreate( out->vrefnum, out->dirID, out->name, cre, typ); if (HOpenRF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) return; } else { return; } } out->fork = 1; out->bytes=BLOCKS(out->rlen)*128; } } long MBwrite( MBFile *out, void *buffer, /* BYU LSC */ long size ) { long rsize; if (size < 1) return(0); rsize=size; if (out->sector1 && (size >= sizeof(struct MBHead)) && (!(out->mode & MB_DISABLE))) { if (isMacBinary((MBHead *) buffer)) { // WARNING: isMacBinary modifies data ProcessMBHead( out, (MBHead *) buffer); buffer = (void *)((char *)buffer + 128); if ((size-=128) <1) return(rsize); } } if (bwrite( out,buffer,size)) return(-1); else return( rsize); } void MBclose( MBFile *out) { HFileParam finfo; long fpos; if (!out->fd) { if (out != NULL) DisposPtr((Ptr)out); return; } if (!(out->mode & MB_DISABLE) && (out->mode & MB_WRITE)) { if (out->fork) SetEOF( out->fd, (long) out->rlen); else SetEOF( out->fd, (long) out->dlen); FSClose( out->fd); GetFileInfo( out->vrefnum, out->dirID, out->name, &finfo); BlockMove(&out->header.type[0], &finfo.ioFlFndrInfo, sizeof(FInfo)); BlockMove(&out->header.cdate[0], &finfo.ioFlCrDat, 4); BlockMove(&out->header.mdate[0], &finfo.ioFlMdDat, 4); finfo.ioFlFndrInfo.fdFlags &= 0xfeff; finfo.ioFlFndrInfo.fdFlags |= (out->header.flags2 & 0x00FF); finfo.ioFlRLgLen=out->rlen; finfo.ioFlLgLen =out->dlen; SetFileInfo( out->vrefnum, out->dirID, out->name, &finfo); } else if (out->mode & MB_WRITE) { GetFPos( out->fd, &fpos); SetEOF( out->fd, fpos); FSClose( out->fd); } else FSClose( out->fd); DisposPtr((Ptr) out); /* JMB 2.6 -- Nice memory leak, no? */ } long MBread ( MBFile *in, void *buffer, long size ) { char *p; long rsize=size; unsigned short crc; if (in->fork<0) { return(-1); } p = buffer; if (in->sector1) { HFileParam finfo; // setmem( &in->header, sizeof(MBHead), 0); WriteZero((Ptr)&in->header, sizeof(MBHead)); BlockMove(in->name, &in->header.nlen, (Length(in->name) > 31) ? 32 : (Length(in->name)+1)); GetFileInfo( in->vrefnum, in->dirID, in->name, &finfo); BlockMove(&finfo.ioFlFndrInfo, &in->header.type[0], sizeof(FInfo) ); in->header.flags2 = finfo.ioFlFndrInfo.fdFlags & 0x00FF; in->header.protected = (in->header.zero2 & 0x40)?1:0; in->header.zero2 = 0; BlockMove(&finfo.ioFlLgLen, &in->header.dflen[0], 4); BlockMove(&finfo.ioFlRLgLen, &in->header.rflen[0], 4); BlockMove(&finfo.ioFlCrDat, &in->header.cdate[0], 4); BlockMove(&finfo.ioFlMdDat, &in->header.mdate[0], 4); in->header.mb2versnum = 129; in->header.mb2minvers = 129; crc = CalculateCRC((unsigned char *) &(in->header), 124, 0); BlockMove(&crc, &(in->header.crc), 2); in->dlen=finfo.ioFlLgLen; in->rlen=finfo.ioFlRLgLen; if (! (in->mode & MB_DISABLE) ) { if (size<128) return(-1); BlockMove(&in->header, p, 128); p +=128; size -= 128; in->bytes= BLOCKS(in->dlen)*128; in->binary=1; } else { in->bytes = in->dlen; in->rlen=0; in->binary=0; } in->sector1=0; #if 0 /* BYU 2.4.17 */ MBstat( &in->header.nlen, 1, (long) (BLOCKS(in->dlen)+BLOCKS(in->rlen)) ); #endif /* BYU 2.4.17 */ } if ( size >0) { long length = size; OSErr err; err = FSRead( in->fd, &length, p); size -= length; in->bytes -=length; p += length; if (err == -39 || (in->bytes<=0) ) { FSClose( in->fd ); if (in->bytes<0L) in->bytes=0L; // setmem(p, in->bytes, 0); // Make filler bytes zero WriteZero(p, in->bytes); size -= in->bytes; p += in->bytes; /* Make adjustments for necessary 128 byte term */ if (!in->fork ) { in->fork=1; in->bytes= BLOCKS(in->rlen)*128; if (in->bytes) { HOpenRF( in->vrefnum, in->dirID, in->name, fsRdWrPerm, &in->fd); #ifdef READ length=(long)size; if (length >0L) { err = FSRead( in->fd, &length, p); size -= length; in->bytes -=length; } #endif READ } else { in->fd=0; in->fork=-1; /* Time to close up shop */ } } else { in->fd=0; in->fork=-1; /* Time to close up shop */ } } } return( rsize-size); } void init_mb_files(void) { /* BYU */ mbfp->fd = 0; /* BYU */ } /* BYU */ /* BYU */ void close_mb_files(void) { /* BYU */ if (mbfp->fd != 0) MBclose( mbfp ); /* BYU - close input file */ } /* BYU */ \ No newline at end of file +// binsubs.c // MacBinary Subroutines. // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "maclook.proto.h" #include "bkgr.proto.h" #include "MacBinary.h" #include "telneterrors.h" #include "binsubs.proto.h" #include "translate.proto.h" #include "debug.h" #include "DlogUtils.proto.h" // For WriteZero static unsigned short CalculateCRC(unsigned char *ptr, short count, unsigned short crc); static void SetFileInfo(short volume, long dirID, StringPtr name, HFileParam *iop); static void MakeTextFile(short volume, long dirID, StringPtr name, HFileParam *iop); static short isMacBinary(MBHead *p); static OSErr bwrite( MBFile *out, char *buffer, long size); static void ProcessMBHead (MBFile *out, MBHead *header); extern MBFile /* BYU */ *mbfp; /* BYU */ #define BLOCKS(x) ((x+127)/128) /*#define lmove(f,t) memmove(f,t,(size_t) 4) /* BYU LSC */ MBHead *mbh; char buffer[128]; unsigned short CalculateCRC(unsigned char *ptr, short count, unsigned short crc) { unsigned short i; crc = 0; while (count -- > 0) { crc = crc ^ (unsigned short)*ptr++ << 8; for (i = 0; i < 8; i++) if (crc & 0x8000) crc = crc << 1 ^ 0x1021; else crc = crc << 1; } return crc; } void GetFileInfo(short volume, long dirID, StringPtr name, HFileParam *iop) { OSErr err; iop->ioNamePtr = name; iop->ioVRefNum = volume; iop->ioDirID = dirID; iop->ioFVersNum = 0; iop->ioFDirIndex = 0; err = PBHGetFInfoSync((HParmBlkPtr) iop); } void SetFileInfo(short volume, long dirID, StringPtr name, HFileParam *iop) { OSErr err; iop->ioNamePtr = name; iop->ioVRefNum = volume; iop->ioDirID = dirID; iop->ioFVersNum = 0; iop->ioFDirIndex = 0; err = PBHSetFInfoSync((HParmBlkPtr) iop); } void MakeTextFile(short volume, long dirID, StringPtr name, HFileParam *iop) { GetFileInfo(volume, dirID, name, iop); iop->ioFlFndrInfo.fdType = 'TEXT'; iop->ioFlFndrInfo.fdCreator = gFTPServerPrefs->TextCreator; SetFileInfo(volume, dirID, name, iop); } short isMacBinary(MBHead *p) { unsigned short crc; if ((p->nlen > 0) && (p->nlen < 65) && (p->zero1 == 0) && (p->zero2 == 0) && (p->zero3 == 0)) { // Assume MB I crc = CalculateCRC((unsigned char *)p, 124, 0); if (((short)p->crc == crc) && (p->mb2versnum > 128)) { // Check for MB II if (p->mb2minvers > 129) return(0); // If vers is greater than 129, leave it alone return (1); // Valid MB II file. } else { p->flags2 = 0; // So we can use same routines for MB I & II return (1); // Valid MB I file (we make it a II file on the fly.) } } return(0); // Not a Macbinary file } long MBsize( MBFile *mbfp) { long size = 0; OSErr ret; ret = GetEOF( mbfp->fd, &size ); /* length of file data fork */ if (ret != noErr) size = 0; return(size); } MBFile *MBopen(char *file, short vrefnum, long dirID, short mode) { MBFile *mbfp; OSErr err; int i; if ((mbfp = (MBFile *) myNewPtr(sizeof(MBFile))) == NULL) return(NULL); if (gFTPServerPrefs->DoISOtranslation) // MP: translation method trbuf_ftp_mac((unsigned char *)file, strlen(file)); BlockMove(file, mbfp->name, 32); if (strlen(file) > 31) mbfp->name[31] = 0; c2pstr((char *)mbfp->name); if (mbfp->name[1] == '.') mbfp->name[1] = '_'; //replace leading period with slash for (i = 1; i <= mbfp->name[0]; i++) // replace embedded slashes, colons, and CRs if (mbfp->name[i] == '/' || mbfp->name[i] == ':' || mbfp->name[i] == CR) mbfp->name[i] = ' '; if (gFTPServerPrefs->DoISOtranslation) trbuf_mac_ftp((unsigned char *)file, strlen(file)); // MP: translation method mbfp->vrefnum = vrefnum; mbfp->dirID = dirID; mbfp->mode = mode; if ((err = HOpenDF( vrefnum, dirID, mbfp->name, fsRdWrPerm, &mbfp->fd)) != noErr) { if ((err==-43) && (mode & MB_WRITE)) { err = HCreate( vrefnum, dirID, mbfp->name, gFTPServerPrefs->BinaryCreator, gFTPServerPrefs->BinaryType); if (mode & MB_ISASCII) { HFileParam blah; MakeTextFile(vrefnum, dirID, mbfp->name, &blah); } if (HOpenDF( vrefnum, dirID, mbfp->name, fsRdWrPerm, &mbfp->fd)) return( 0L); } else return(0L); } if (mode & MB_APPEND) SetFPos(mbfp->fd,fsFromLEOF,0); mbfp->binary=0; mbfp->sector1=1; mbfp->fork=0; return( mbfp); } OSErr bwrite( MBFile *out, char *buffer, long size) { long len = size; OSErr error = noErr; if (out->binary) { if (out->bytes > 0) { if (out->bytes < len) len = out->bytes; error= FSWrite( out->fd, &len, buffer); out->bytes -= len; buffer +=len; size -= len; } if (out->bytes <= 0) { if (!out->fork) { out->fork = 1; out->bytes = BLOCKS(out->rlen)*128; SetEOF( out->fd, (long) out->dlen); FSClose( out->fd); if (out->bytes) { HOpenRF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd); if (size) { len = (long) size; error= FSWrite( out->fd, &len, buffer); } } else out->fd = 0; } else SetEOF( out->fd, (long) out->rlen); } } else { error = FSWrite( out->fd, &len, buffer); } return (error); } void ProcessMBHead (MBFile *out, MBHead *header) { OSErr err; BlockMove(header, &out->header, sizeof(MBHead)); out->binary = 1; BlockMove(&header->dflen[0], &out->dlen, 4); BlockMove(&header->rflen[0], &out->rlen, 4); out->bytes = BLOCKS(out->dlen)*128; out->fork = 0; out->sector1 = 0; FSClose(out->fd); if (HDelete( out->vrefnum, out->dirID, out->name)) /* Error deleting Old File */ DoError (200 | RESOURCE_ERRORCLASS, LEVEL1, NULL); BlockMove(&out->header.nlen, out->name, 32); #if 0 /* BYU 2.4.17 */ MBstat( &out->header.nlen, 1, (long)(BLOCKS(out->dlen)+BLOCKS(out->rlen)) ); #endif /* BYU 2.4.17 */ if (out->bytes) { if ((err=HOpenDF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) != noErr) { if (err == -43) { long cre,typ; BlockMove(out->header.type, &typ, 4); BlockMove(out->header.creator, &cre, 4); HCreate( out->vrefnum, out->dirID, out->name, cre, typ); if (HOpenDF(out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) return; } else { return; } } } else { if ((err=HOpenRF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) != noErr) { if (err == -43) { long cre,typ; BlockMove(out->header.type, &typ, 4); BlockMove(out->header.creator, &cre, 4); HCreate( out->vrefnum, out->dirID, out->name, cre, typ); if (HOpenRF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) return; } else { return; } } out->fork = 1; out->bytes=BLOCKS(out->rlen)*128; } } long MBwrite( MBFile *out, void *buffer, /* BYU LSC */ long size ) { long rsize; if (size < 1) return(0); rsize=size; if (out->sector1 && (size >= sizeof(struct MBHead)) && (!(out->mode & MB_DISABLE))) { if (isMacBinary((MBHead *) buffer)) { // WARNING: isMacBinary modifies data ProcessMBHead( out, (MBHead *) buffer); buffer = (void *)((char *)buffer + 128); if ((size-=128) <1) return(rsize); } } if (bwrite( out,buffer,size)) return(-1); else return( rsize); } void MBclose( MBFile *out) { HFileParam finfo; long fpos; if (!out->fd) { if (out != NULL) DisposePtr((Ptr)out); return; } if (!(out->mode & MB_DISABLE) && (out->mode & MB_WRITE)) { if (out->fork) SetEOF( out->fd, (long) out->rlen); else SetEOF( out->fd, (long) out->dlen); FSClose( out->fd); GetFileInfo( out->vrefnum, out->dirID, out->name, &finfo); BlockMove(&out->header.type[0], &finfo.ioFlFndrInfo, sizeof(FInfo)); BlockMove(&out->header.cdate[0], &finfo.ioFlCrDat, 4); BlockMove(&out->header.mdate[0], &finfo.ioFlMdDat, 4); finfo.ioFlFndrInfo.fdFlags &= 0xfeff; finfo.ioFlFndrInfo.fdFlags |= (out->header.flags2 & 0x00FF); finfo.ioFlRLgLen=out->rlen; finfo.ioFlLgLen =out->dlen; SetFileInfo( out->vrefnum, out->dirID, out->name, &finfo); } else if (out->mode & MB_WRITE) { GetFPos( out->fd, &fpos); SetEOF( out->fd, fpos); FSClose( out->fd); } else FSClose( out->fd); DisposePtr((Ptr) out); /* JMB 2.6 -- Nice memory leak, no? */ } long MBread ( MBFile *in, void *buffer, long size ) { char *p; long rsize=size; unsigned short crc; if (in->fork<0) { return(-1); } p = buffer; if (in->sector1) { HFileParam finfo; // setmem( &in->header, sizeof(MBHead), 0); WriteZero((Ptr)&in->header, sizeof(MBHead)); BlockMove(in->name, &in->header.nlen, (StrLength(in->name) > 31) ? 32 : (StrLength(in->name)+1)); GetFileInfo( in->vrefnum, in->dirID, in->name, &finfo); BlockMove(&finfo.ioFlFndrInfo, &in->header.type[0], sizeof(FInfo) ); in->header.flags2 = finfo.ioFlFndrInfo.fdFlags & 0x00FF; in->header.protected = (in->header.zero2 & 0x40)?1:0; in->header.zero2 = 0; BlockMove(&finfo.ioFlLgLen, &in->header.dflen[0], 4); BlockMove(&finfo.ioFlRLgLen, &in->header.rflen[0], 4); BlockMove(&finfo.ioFlCrDat, &in->header.cdate[0], 4); BlockMove(&finfo.ioFlMdDat, &in->header.mdate[0], 4); in->header.mb2versnum = 129; in->header.mb2minvers = 129; crc = CalculateCRC((unsigned char *) &(in->header), 124, 0); BlockMove(&crc, &(in->header.crc), 2); in->dlen=finfo.ioFlLgLen; in->rlen=finfo.ioFlRLgLen; if (! (in->mode & MB_DISABLE) ) { if (size<128) return(-1); BlockMove(&in->header, p, 128); p +=128; size -= 128; in->bytes= BLOCKS(in->dlen)*128; in->binary=1; } else { in->bytes = in->dlen; in->rlen=0; in->binary=0; } in->sector1=0; #if 0 /* BYU 2.4.17 */ MBstat( &in->header.nlen, 1, (long) (BLOCKS(in->dlen)+BLOCKS(in->rlen)) ); #endif /* BYU 2.4.17 */ } if ( size >0) { long length = size; OSErr err; err = FSRead( in->fd, &length, p); size -= length; in->bytes -=length; p += length; if (err == -39 || (in->bytes<=0) ) { FSClose( in->fd ); if (in->bytes<0L) in->bytes=0L; // setmem(p, in->bytes, 0); // Make filler bytes zero WriteZero(p, in->bytes); size -= in->bytes; p += in->bytes; /* Make adjustments for necessary 128 byte term */ if (!in->fork ) { in->fork=1; in->bytes= BLOCKS(in->rlen)*128; if (in->bytes) { HOpenRF( in->vrefnum, in->dirID, in->name, fsRdWrPerm, &in->fd); #ifdef READ length=(long)size; if (length >0L) { err = FSRead( in->fd, &length, p); size -= length; in->bytes -=length; } #endif READ } else { in->fd=0; in->fork=-1; /* Time to close up shop */ } } else { in->fd=0; in->fork=-1; /* Time to close up shop */ } } } return( rsize-size); } void init_mb_files(void) { // 12/10/97, RJZ. Make sure ptr isn\'t // NULL before dereferencing. if (mbfp != NULL) mbfp->fd = 0; } /* BYU */ /* BYU */ void close_mb_files(void) { // 12/10/97, RJZ. Make sure ptr isn\'t // NULL before dereferencing. if (mbfp != NULL && mbfp->fd != 0) MBclose( mbfp ); } /* BYU */ \ No newline at end of file diff --git a/source/FTPserver/bkgr.c b/source/FTPserver/bkgr.c index 7b9c10b..def2d50 100755 --- a/source/FTPserver/bkgr.c +++ b/source/FTPserver/bkgr.c @@ -1 +1 @@ -// Background procedures for rcp and ftp // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* * NCSA Revisions: * 11/86 Tim Krauskopf * 7/92 Telnet 2.6: added global structures, cleaned up defines Scott Bulmahn * * */ #ifdef MPW #pragma segment FTPServer #endif #include "InternalEvents.h" #include "netevent.proto.h" #include "menuseg.proto.h" #include "network.proto.h" #include "mydnr.proto.h" #include "macutil.proto.h" #include "macbinary.h" #include "binsubs.proto.h" #include "maclook.proto.h" #include "bkgr.proto.h" #include "telneterrors.h" #include "wind.h" #include "mainseg.proto.h" #include "translate.proto.h" #include "DlogUtils.proto.h" // For WriteZero proto #include "vsdata.h" #include "vsinterf.proto.h" extern WindRec *ftplog; extern TelInfoRec *TelInfo; #define PFTP 1 #define PRCP 2 #define PDATA 3 #define HTELNET 23 #define HRSHD 514 #define HFTP 21 #define BUFFERS 8000 #define PATHLEN 256 #define MACBINARY #define RCPSEGSIZE 512 #define O_RAW O_RDONLY #define EOLCHAR 13 #define FASCII 0 #define FIMAGE O_RAW #define FAMODE 0 #define FIMODE 1 #define FMMODE 2 /* Mac Binary, when ready */ MBFile *mbfp=NULL; char *nextfile; static Handle mungbuf = 0; static short fcnt=0; static short ftpenable=0, /* is file transfer enabled? */ rcpenable=0, /* is rcp enabled? */ rsnum=-1, /* port number for incoming rshell */ rserr=-1; /* port number for rshd() stderr */ static unsigned char *xs=0L, /* buffer space for file transfer */ *pathname=0L, /* space to keep path names */ *newfile=0L, /* current file being received */ myuser[17], /* user name on my machine */ waitchar; /* character waiting for from net */ static short curstate = -1, /* state machine for background processes */ retstate = 200, /* to emulate a subroutine call */ ftpstate = 0, /* state of the ftp data transfer */ isdir=0, /* flag for rcp target pathname */ waitpos=0, /* marker for gathering strings from net */ cnt=0, /* number of characters from last netread() */ fh=0, /* file handle when transfer file is open */ ftpfh=0, /* file handle for ftp data */ rc=0, /* telnet flag */ xp=0, /* general pointer */ towrite=0, /* file transfer pointer */ len=0; /* file transfer length */ static long filelen=0L; /* length of current file for transfer */ short mainport[NPORTS]; /* BYU 2.4.16 - map FTP data port to main port */ short dataport[NPORTS]; /* BYU 2.4.16 - map FTP main port to data port */ short mainstate[NPORTS]; /* BYU 2.4.16 */ short datastate[NPORTS]; /* BYU 2.4.16 */ short retnstate[NPORTS]; ip_port fileport[NPORTS]; static char crfound=0; static short rfstate, ftptmode=FAMODE; /* how to transfer the file on net */ static ip_addr portaddr[NPORTS], hishostaddr; static ip_port portremoteport[NPORTS], portlocalport[NPORTS]; unsigned char messs[100]; /* BYU */ char ListingTemplate[256]; CInfoPBRec theDirectoryState; static void CRESP(short fnum, short msg_number); static short ftpgo( short fnum); void FTPServerUnload(void) {} void CRESP(short fnum, short msg_number) { GetIndString(messs,MSG_RESOURCE_ID,msg_number+1); netpush(fnum); netwrite(fnum, &messs[1], (short)messs[0]); } void ftpmess( char *cp) { short temp; temp=strlen(cp); if (temp>80 || temp < 1) return; VSwrite(ftplog->vs,cp,temp); } /***********************************************************************/ void StartUpFTP(void) { if (gFTPServerPrefs->ServerState != 0) setftp(); else unsetftp(); } void setftp( void) { short fnum,i1; /* BYU 2.4.16 */ short size = 1024; Mnetinit(); // RAB BetterTelnet 1.0fc4 /* set up to receive a telnet connection for ftp commands */ rfstate = 0; ftpstate = 0; /* Listen for FTP if we're not listening already */ for (i1 = 0; i1 < NPORTS; i1++) /* BYU 2.4.16 */ if (GetPortType(i1) == PFTP) break; /* BYU 2.4.16 */ if (i1 >= NPORTS) { /* BYU 2.4.16 - non-SLIP listen */ fnum = netlisten(HFTP); /* BYU 2.4.16 - MacTCP listen */ ftpenable = 1; /* BYU 2.4.16 */ if (fnum >= 0) { /* BYU 2.4.16 - signal that events should be caught */ SetPortType(fnum, PFTP); dataport[fnum] = -1; /* BYU 2.4.16 - no data needed yet */ mainstate[fnum] = 0; /* BYU 2.4.16 */ datastate[fnum] = 0; /* BYU 2.4.16*/ retnstate[fnum] = 200; /* BYU 2.4.16 */ } /* BYU 2.4.16 */ } /* BYU 2.4.16 */ strcpy((char *) myuser,"unknown"); /* BYU LSC - set unknown user name */ if (mungbuf == NULL) mungbuf = myNewHandle(size); } void unsetftp( void) { short i1; /* BYU 2.4.16 */ rfstate = 0; ftpstate = 0; for (i1 = 0; i1 < NPORTS; i1++) { /* BYU 2.4.16 */ if (GetPortType(i1) == PFTP) { /* BYU 2.4.16 */ netclose(i1); /* BYU 2.4.16 */ SetPortType(i1, NO_TYPE); /* BYU 2.4.16 */ mainstate[i1] = 0; /* BYU 2.4.16 */ datastate[i1] = 0; /* BYU 2.4.16*/ } /* BYU 2.4.16 */ } /* BYU 2.4.16 */ ftpenable = 0; if (mungbuf != NULL) DisposeHandle(mungbuf); } #if 0 /* BYU - Converted to STR# resource number 23227 */ /***********************************************************************/ /* * resident ftp server -- enables initiation of ftp without a username * and password, as long as this telnet is active at the same time * Now checks for the need of passwords. */ static char *messs[] = { "220 Macintosh Resident FTP server, ready \015\012", "451 Error in processing list command \015\012", "221 Goodbye \015\012", /*2*/ "200 This space intentionally left blank < > \015\012", "150 Opening connection \015\012", "226 Transfer complete \015\012", /*5*/ "200 Type set to A, ASCII transfer mode \015\012", "200 Type set to I, binary transfer mode \015\012", "500 Command not understood \015\012", /*8*/ "200 Okay \015\012", "230 User logged in \015\012", "550 File not found \015\012", /*11*/ "501 Directory not present or syntax error\015\012", "250 Chdir okay\015\012", "257 \"", "\" is the current directory \015\012", /*15*/ "501 File not found \015\012", "504 Parameter not accepted, not implemented\015\012", "200 Stru F, file structure\015\012", "200 Mode S, stream mode\015\012", /*19*/ "202 Allocate and Account not required for this server\015\012", "501 Cannot open file to write, check for valid name\015\012", "530 USER and PASS required to activate me\015\012", "331 Password required\015\012", /*23 */ "530 Login failed\015\012", "200 MacBinary Mode enabled\015\012", "200 MacBinary Mode disabled\015\012", /*26 */ "552 Disk write error, probably disk full\015\012", "214-NCSA Telnet FTP server, supported commands:\015\012", " USER PORT RETR ALLO PASS STOR CWD XCWD XPWD LIST NLST\015\012", " HELP QUIT MODE TYPE STRU ACCT NOOP MACB\015\012", /*30*/ " MACB is MacBinary and must be done with TYPE I\015\012", "214 Direct comments and bugs to telbug@ncsa.uiuc.edu\015\012", "200 Type set to I, binary transfer mode [MACBINARY ENABLED]\015\012", /* 33 */ "200 Type set to I, binary transfer mode [macbinary disabled]\015\012", ""}; #endif /* open the FTP data connection to the remote host */ short ftpgo( short fnum) { short ftpdata; netfromport(20); /* ftp data port */ ftpdata = netxopen(portaddr[fnum],fileport[fnum], 15); mainport[ftpdata] = fnum; dataport[fnum] = ftpdata; return(ftpdata); } void rftpd ( short code, /* BYU 2.4.16 */ short fnum /* BYU 2.4.16 */ ) { ip_port fdport; short ftpdata, i, append = 0; char tempp[256], theDir[256]; char updir[4]; /* JMB 2.6 */ if (!ftpenable) return; netpush(fnum); rfstate = mainstate[fnum]; /* BYU 2.4.16 */ ftpstate = datastate[fnum]; /* BYU 2.4.16 */ retstate = retnstate[fnum]; /* BYU 2.4.16 */ fdport = fileport[fnum]; /* BYU 2.4.16 */ switch (rfstate) { case 0: if (code != CONOPEN) break; ftptmode = FAMODE; netputevent(USERCLASS,FTPCOPEN,-1,0); if (!xs) xs=(unsigned char *)myNewPtr(BUFFERS+10); /* BYU LSC */ if (!pathname) pathname=(unsigned char *)myNewPtr(PATHLEN); if (!newfile) newfile=(unsigned char *)myNewPtr(PATHLEN); if (!xs || !pathname || !newfile) /* no memory for ftp names */ { DoError(114 | MEMORY_ERRORCLASS, LEVEL3, NULL); quit(); // Should we really quit? } rfstate = 1; /* drop through */ case 1: CRESP(fnum,0); /* BYU 2.4.16 */ netgetftp(fnum, &portaddr[fnum], &portlocalport[fnum], &portremoteport[fnum]); /* BYU 2.4.16 - get default ftp information */ hishostaddr = portaddr[fnum]; fdport = portremoteport[fnum]; waitpos = 0; waitchar = '\012'; rfstate = 50; /* note skips over */ if ((gFTPServerPrefs->ServerState == 2)) retstate = 3; /* check pass */ else retstate = 5; /* who needs one ? */ break; case 3: /* check for passwords */ case 4: waitpos = 0; waitchar = '\012'; rfstate = 50; if (!strncmp("USER",(char *) xs,4)) { /* BYU LSC */ if (strlen((char *) xs) < 6) /* BYU LSC - make sure blank name stays blank */ xs[5] = myuser[0] = 0; strncpy((char *) myuser,(char *) &xs[5],16); /* BYU LSC - keep user name */ FTPLogUserLoggingIn(); CRESP(fnum,23); /* BYU 2.4.16 */ retstate = 4; /* wait for password */ break; } if (!strncmp("PASS",(char *) xs,4)) { /* BYU LSC */ if (Scheckpass((char *) myuser,(char *) &xs[5])) { /* BYU LSC */ ftpmess("FTP password OK - logged in\015\012"); CRESP(fnum,10); /* BYU 2.4.16 */ retstate = 5; } else { ftpmess("FTP password failed - access denied\015\012"); CRESP(fnum,24); /* BYU 2.4.16 */ retstate = 3; } break; } if (!strncmp("QUIT",(char *) xs,4)) { /* BYU LSC */ CRESP(fnum,2); /* BYU 2.4.16 */ cnt = -1; } else { CRESP(fnum,22); /* BYU 2.4.16 */ } retstate = 3; /* must have password first */ break; /* interpret commands that are received from the other side */ case 5: /* set to a safe state to handle recursion, wait for another command line from client */ rfstate = 50; retstate = 5; waitchar = '\012'; waitpos = 0; if (!strncmp((char *) xs,"LIST",4) || !strncmp((char *) xs,"NLST",4)) { /* BYU LSC */ if ((strlen((char *) xs) < 6) || xs[5] == '.') /* BYU LSC */ strcpy((char *) xs,"LIST *"); /* BYU LSC */ strcpy(ListingTemplate, (char *) &xs[5]); theDirectoryState.hFileInfo.ioFDirIndex=1; theDirectoryState.hFileInfo.ioVRefNum = TelInfo->DefaultDirVRefNum; theDirectoryState.hFileInfo.ioDirID = TelInfo->DefaultDirDirID; nextfile = getFileName(ListingTemplate, &theDirectoryState); /* find first name */ if (nextfile == NULL) { CRESP(fnum,16); /* BYU 2.4.16 */ } else { Str255 tempstr; char tempstr2[256]; ftpdata = ftpgo(fnum); /* BYU 2.4.16 - open the connection */ fdport = portremoteport[fnum]; /* BYU 2.4.16 - reset to def */ if (ftpdata >= 0) SetPortType(ftpdata, PDATA); ftpstate = 40; /* ready to transmit */ CRESP(fnum,4); /* BYU 2.4.16 */ PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, tempstr); PtoCstr(tempstr); sprintf(tempstr2, "FTP Sending Directory %s\015\012", (char *)tempstr); ftpmess(tempstr2); } } else if (!strncmp((char *) xs,"CWD",3)) { /* BYU LSC */ if (ChangeDirectory(&(TelInfo->DefaultDirDirID), &(TelInfo->DefaultDirVRefNum), (char *) &xs[4])) { CRESP(fnum,12); /* BYU 2.4.16 */ } else { /* success */ CRESP(fnum,13); /* BYU 2.4.16 */ } } else if (!strncmp((char *) xs,"CDUP",4)) { /* JMB 2.6 */ strcpy(updir, ".."); /* JMB 2.6 */ if (ChangeDirectory(&(TelInfo->DefaultDirDirID), &(TelInfo->DefaultDirVRefNum), updir)) { /* JMB 2.6 */ CRESP(fnum,12); /* JMB 2.6 */ } /* JMB 2.6 */ else { /* JMB 2.6 */ CRESP(fnum,13); /* JMB 2.6 */ } /* JMB 2.6 */ } /* JMB 2.6 */ else if (!strncmp((char *) xs,"STOR",4) || !strncmp((char *) xs,"APPE", 4)) { short MBflag; if (!strncmp((char *) xs,"APPE", 4)) { if (ftptmode != FASCII) { CRESP(fnum, 35); break; } else append = 1; } /* had to simplify this, else MPW C 3.0/3.1 generates bad code! */ if ((!TelInfo->MacBinary) || (ftptmode == FAMODE)) MBflag = MB_DISABLE; else MBflag = 0; if (ftptmode == FAMODE) MBflag |= MB_ISASCII; if (append) MBflag |= MB_APPEND; append = 0; mbfp = MBopen((char *)&xs[5], TelInfo->DefaultDirVRefNum, TelInfo->DefaultDirDirID, (short)(MB_WRITE | MBflag)); if (mbfp == 0L) { CRESP(fnum,21); /* BYU 2.4.16 */ break; } else ftpfh = 12; ftpstate = 0; strncpy((char *) newfile,(char *) &xs[5],PATHLEN-1); /* BYU LSC */ ftpdata = ftpgo(fnum); /* BYU 2.4.16 - open connection */ fdport = portremoteport[fnum]; /* BYU 2.4.16 - reset to def */ if (ftpdata >= 0) SetPortType(ftpdata, PDATA); CRESP(fnum,4); /* BYU 2.4.16 */ ftpstate = 30; /* ready for data */ } else if (!strncmp((char *) xs,"RETR",4)) /* BYU LSC */ { /* had to simplify this, else MPW C 3.0/3.1 generates bad code! */ short MBflag; if ((!TelInfo->MacBinary) || (ftptmode == FAMODE)) MBflag = MB_DISABLE; else MBflag = 0; if (ftptmode == FAMODE) MBflag |= MB_ISASCII; mbfp = MBopen((char *) &xs[5], TelInfo->DefaultDirVRefNum, TelInfo->DefaultDirDirID, MB_READ | MBflag); if (mbfp == 0L) { CRESP(fnum,11); /* BYU 2.4.16 */ break; } ftpfh = 12; strncpy((char *) newfile,(char *) &xs[5],PATHLEN-1); /* BYU LSC */ PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, (StringPtr) theDir); PtoCstr((StringPtr) theDir); sprintf(tempp,"remote <-- %s/%s\015\012",theDir,newfile); ftpmess(tempp); ftpdata = ftpgo(fnum); /* BYU 2.4.16 - open connection */ fdport = portremoteport[fnum]; ftpstate = 20; /* ready for data */ if (ftpdata >= 0) SetPortType(ftpdata, PDATA); CRESP(fnum,4); /* BYU 2.4.16 */ } else if (!strncmp((char *) xs,"TYPE",4)) { /* BYU LSC */ if (toupper(xs[5]) == 'I') { ftptmode = FIMODE; if (TelInfo->MacBinary) { CRESP(fnum,33); /* BYU 2.4.16 - Binary on, MACB ON */ } else { CRESP(fnum,34); /* BYU 2.4.16 - Binary on, MACB off */ } } else if (toupper(xs[5]) == 'A') { ftptmode = FAMODE; CRESP(fnum,6); /* BYU 2.4.16 */ } else { CRESP(fnum,17); /* BYU 2.4.16 */ } } else if (!strncmp((char *) xs,"MACB",4)) { /* BYU LSC */ if (toupper(xs[5]) == 'E') { TelInfo->MacBinary = 1; CRESP(fnum,25); /* BYU 2.4.16 */ } else { TelInfo->MacBinary = 0; CRESP(fnum,26); /* BYU 2.4.16 */ } DisplayMacBinary(); /* post an event ? */ } else if (!strncmp((char *) xs,"PORT",4)) { /* get the requested port number from the command given */ ip_addrbytes tempaddr; unsigned char *stringPtr, *tempPtr, storage[10]; long numbers[6]; short index; for (tempPtr = stringPtr = &xs[5], index = 0; (*stringPtr != '\0') && (index < 6);index++) { while ((*tempPtr != '\0') && (*tempPtr != ',')) { tempPtr++; }; BlockMoveData(stringPtr, &(storage[1]), tempPtr-stringPtr); storage[0] = tempPtr-stringPtr; StringToNum(storage, &numbers[index]); tempPtr++; stringPtr = tempPtr; } tempaddr.a.byte[0] = (char) numbers[0]; tempaddr.a.byte[1] = (char) numbers[1]; tempaddr.a.byte[2] = (char) numbers[2]; tempaddr.a.byte[3] = (char) numbers[3]; portaddr[fnum] = tempaddr.a.addr; portlocalport[fnum] = numbers[4]*256 + numbers[5]; fdport = portlocalport[fnum]; CRESP(fnum,3); } else if (!strncmp((char *) xs,"QUIT",4)) { /* BYU LSC */ CRESP(fnum,2); /* BYU 2.4.16 */ rfstate = 60; netputuev(CONCLASS,CONDATA,fnum,0); /* post back to me */ } else if (!strncmp((char *) xs,"XPWD",4) || !strncmp((char *) xs,"PWD",3)) { /* BYU LSC */ CRESP(fnum,14); /* BYU 2.4.16 - start reply */ PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, (StringPtr) xs); PtoCstr((StringPtr) xs); netwrite(fnum,(char *) xs,strlen((char *) xs)); /* BYU LSC - write dir name */ CRESP(fnum,15); /* BYU 2.4.16 - finish reply */ } else if (!strncmp((char *) xs,"USER",4)) { /* BYU LSC */ if (strlen((char *) xs) < 6) /* BYU LSC - make sure blank name stays blank */ xs[5] = myuser[0] = 0; strncpy((char *) myuser,(char *) &xs[5],16); /* BYU LSC - keep user name */ FTPLogUserLoggingIn(); /* confirm log in without password */ CRESP(fnum,10); /* BYU 2.4.16 */ } else if (!strncmp((char *) xs,"STRU",4)) { /* BYU LSC - only one stru allowed */ if (xs[5] == 'F') { CRESP(fnum,18); } /* BYU 2.4.16 */ else { CRESP(fnum,17); } /* BYU 2.4.16 */ } else if (!strncmp((char *) xs,"MODE",4)) { /* BYU LSC - only one mode allowed */ if (xs[5] == 'S') { CRESP(fnum,19); } /* BYU 2.4.16 */ else { CRESP(fnum,17); } /* BYU 2.4.16 */ } else if (!strncmp((char *) xs,"ALLO",4) || !strncmp((char *) xs,"ACCT",4)) { /* BYU LSC */ CRESP(fnum,20); } /* BYU 2.4.16 */ else if (!strncmp((char *) xs,"HELP",4)) { /* BYU LSC */ for (i=28; i<33; i++) { CRESP(fnum,i); } /* BYU 2.4.16 */ } else if (!strncmp((char *) xs,"NOOP",4)) { /* BYU LSC */ CRESP(fnum,9); } /* BYU 2.4.16 */ else if (!strncmp((char *) xs,"SYST",4)) { // JMB 2.6 netpush(fnum); // JMB 2.6 netwrite(fnum, "225 MACOS System Version:\015\012", 27); // JMB 2.6 } // JMB 2.6 else { /* command not understood */ CRESP(fnum,8); /* BYU 2.4.16 */ } break; /* subroutine to wait for a particular character */ case 50: while (0 < (cnt = netread(fnum,&xs[waitpos],1))) { if (xs[waitpos] == waitchar) { rfstate = retstate; while (xs[waitpos] < 33) /* find end of string */ waitpos--; xs[++waitpos] = '\0'; /* put in terminator */ for (i=0; i<4; i++) /* want upper case */ xs[i] = toupper(xs[i]); break; } else waitpos += cnt; } break; case 60: /* wait for message to get through */ /* or connection is broken */ /* printf(" %d,%d",netpush(fnum),netest(fnum));*/ if (!netpush(fnum) || netest(fnum)) cnt = -1; else netputuev(CONCLASS,CONDATA,fnum,0); /* post back to me */ break; default: break; } if (cnt < 0) { if (mbfp) { MBclose( mbfp ); mbfp = NULL; } ftpdata = dataport[fnum]; /* BYU 2.4.16 */ if (ftpdata > 0) { netclose(ftpdata); netputevent(USERCLASS,FTPEND,-1,0); dataport[fnum] = -1; /* BYU 2.4.16 */ mainport[ftpdata] = -1; /* BYU 2.4.16 */ } rfstate = 100; ftpstate = 0; cnt = 0; netclose(fnum); SetPortType(fnum, NO_TYPE); netputevent(USERCLASS,FTPCLOSE,-1,0); #if 0 /* BYU 2.4.16 */ fnum = -1; ftpdata = -1; #endif /* BYU 2.4.16 */ setftp(); /* reset it */ } mainstate[fnum] = rfstate; /* BYU 2.4.16 */ datastate[fnum] = ftpstate; /* BYU 2.4.16 */ retnstate[fnum] = retstate; /* BYU 2.4.16 */ fileport[fnum] = fdport; /* BYU 2.4.16 */ } /* important note: for Sfread, nwant must be 256 bytes LARGER than the amount which will probably be read from the connection. Sfread will stop anywhere from 0 to 256 bytes short of filling nwant number of bytes. */ long Sfread( short pnum, char *buf, long nwant) { long i, ndone, lim; char *p, *q; if (nwant < 1024) return(-1); ndone = 0; HLock(mungbuf); while (ndone < nwant - 1024) { if (0 >= (lim = netread(pnum,*mungbuf,1024))) { if (ndone || !lim) /* if this read is valid, but no data */ return(ndone); else return(-1); /* if connection is closed for good */ } p = *mungbuf; q = (char *) buf + ndone; /* printf("\012 lim=%d done=%d want=%d",lim,ndone,nwant); n_row(); */ for (i=0; i < lim; i++) { if (crfound) { if (*p == 10) *q++ = EOLCHAR; else if (*p == 0) *q++ = 13; /* CR-NUL means CR */ crfound = 0; } else if (*p == 13) crfound = 1; else if (gFTPServerPrefs->DoISOtranslation) { *q++ = (char) ftp_iso_mac((unsigned char *)p); /* transform to mac */ } else *q++ = *p; /* copy the char */ p++; } ndone = q-buf; /* count chars ready */ } HUnlock(mungbuf); return(ndone); } /***************************************************************************/ /* Sfwrite * Write an EOL translated buffer into netwrite. * Returns the number of bytes which were processed from the incoming * buffer. Uses its own 1024 byte buffer for the translation (with Sfread). */ long Sfwrite( short pnum, void *buf, long nsrc) { long i,ndone,nout,lim; char *p,*q; ndone = 0; HLock (mungbuf); while (ndone < nsrc) { if (0 > ( i = netroom(pnum))) return(-1); if (i < 1024) /* not enough room to work with */ return(ndone); /* process up to 512 source bytes for output (could produce 1K bytes out) */ if (nsrc - ndone > 512) lim = 512; else lim = nsrc-ndone; p = (char *) buf + ndone; /* where to start this block */ q = *mungbuf; /* where munged stuff goes */ for (i=0; i < lim; i++) { if (*p == EOLCHAR) { *q++ = 13; *q++ = 10; p++; } else if (gFTPServerPrefs->DoISOtranslation) { *q++ = (char) ftp_mac_iso((unsigned char *)p); /* transform to ISO */ p++; } else *q++ = *p++; } ndone += lim; /* # of chars processed */ nout = q-*mungbuf; /* # of chars new */ if ( nout != netwrite(pnum,*mungbuf,nout) ) /* Some error in Sfwrite */ DoError (201 | RESOURCE_ERRORCLASS, LEVEL1, NULL); } HUnlock (mungbuf); return(ndone); } /* FTP receive and send file functions */ void ftpd ( short code, short ftpdata /* BYU 2.4.16 */ ) { short fnum = mainport[ftpdata]; /* BYU 2.4.16 */ short i,a; char tempp[256]; char theDir[256]; ftpstate = datastate[fnum]; /* BYU 2.4.16 */ switch (ftpstate) { default: break; case 40: /* list file names in current dir */ if (code == CONFAIL) /* something went wrong */ fcnt = -1; if (code != CONOPEN) /* waiting for connection to open */ break; ftpstate = 41; /* * send the "nextfile" string and then see if there is another file * name to send */ case 41: netputuev(SCLASS,FTPACT,ftpdata,0); netpush(ftpdata); strcpy(tempp,nextfile); /* BYU 2.4.13 */ strcat(tempp,"\015\012"); /* BYU 2.4.13 */ i = strlen(tempp); /* BYU 2.4.13 */ if (gFTPServerPrefs->DoISOtranslation) trbuf_mac_ftp((unsigned char *)tempp, i); /* transform to ISO */ //PETERL? if (i != netwrite(ftpdata,tempp,i)) { /* BYU 2.4.13 */ CRESP(fnum,1); /* BYU 2.4.16 */ fcnt = -1; break; } theDirectoryState.hFileInfo.ioFDirIndex++; if (NULL == (nextfile = getFileName(ListingTemplate, &theDirectoryState))) { /* normal end */ ftpstate = 22; /* push data through */ } break; case 30: if (code == CONFAIL) /* something went wrong */ fcnt = -1; if (code != CONOPEN) /* waiting for connection to open */ break; ftpstate = 31; crfound = 0; len = xp = 0; filelen = 0L; PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, (StringPtr) theDir); PtoCstr((StringPtr) theDir); sprintf(tempp,"remote --> %s/%s\015\012",theDir,newfile); ftpmess(tempp); netputevent(USERCLASS,FTPBEGIN,-2,0); case 31: /* * file has already been opened, take everything from the connection * and place into the open file: ftpfh */ do { /* wait until xs is full before writing to disk */ if (len <= 2000) { if (xp) { if (0 > MBwrite(mbfp, xs, xp)) { DoError (202 | RESOURCE_ERRORCLASS, LEVEL1, NULL); MBclose( mbfp); /* Close on Disk Full Error */ ftpstate=22; CRESP(fnum,27); /* BYU 2.4.16 */ ftpmess((char *) messs); /* BYU LSC */ if( (a = netclose(ftpdata)) !=0 ) DoError (108 | NET_ERRORCLASS, LEVEL1, NULL); fcnt = -1; mbfp=NULL; break; } xp = 0; } len = BUFFERS; /* expected or desired len to go */ } if (ftptmode == FAMODE) fcnt = Sfread(ftpdata,(char *) &xs[xp],len); /* BYU LSC */ else fcnt = netread(ftpdata,&xs[xp],len); if (fcnt >= 0) { len -= fcnt; xp += fcnt; filelen += fcnt; } if (fcnt < 0) { if (0 > MBwrite( mbfp, xs, xp)) { CRESP(fnum,27); /* BYU 2.4.16 */ MBclose( mbfp); /* Close file on error */ break; } MBclose( mbfp ); ftpfh = 0; CRESP(fnum,5); /* BYU 2.4.16 */ } } while (fcnt > 0); break; case 20: if (code == CONFAIL) /* something went wrong */ fcnt = -1; if (code != CONOPEN) /* waiting for connection to open */ break; ftpstate = 21; filelen = MBsize( mbfp ); towrite = 0; xp = 0; netputevent(USERCLASS,FTPBEGIN,-1,0); case 21: /* * transfer file(s) to the other host via ftp request * file is already open = ftpfh */ netputuev(SCLASS,FTPACT,ftpdata,0); if (towrite <= xp) { i = BUFFERS; towrite = MBread( mbfp, xs, i); xp = 0; } if (towrite <= 0 || netest(ftpdata)) { /* we are done */ ftpstate = 22; break; } if (ftptmode == FAMODE) i = Sfwrite(ftpdata,&xs[xp],towrite-xp); else i = netwrite(ftpdata,&xs[xp],towrite-xp); if (i > 0) { xp += i; filelen -= i; if (filelen < 0L) filelen = 0L; } break; case 22: /* wait for data to be accepted */ netputuev(SCLASS,FTPACT,ftpdata,0); fcnt = netpush(ftpdata); /* will go negative on err */ if (!fcnt || netest(ftpdata)) fcnt = -1; if (fcnt < 0) { CRESP(fnum,5); /* BYU 2.4.16 */ } break; case 0: break; } /* end of switch */ /* after reading from connection, if the connection is closed, reset up shop. */ if (fcnt < 0) { if (mbfp) { MBclose( mbfp ); mbfp = NULL; } ftpstate = 0; fcnt = 0; if (ftpdata >= 0) { netclose(ftpdata); netputevent(USERCLASS,FTPEND,-1,0); mainport[ftpdata] = -1; /* BYU 2.4.16 */ dataport[fnum] = -1; /* BYU 2.4.16 */ } } datastate[fnum] = ftpstate; /* BYU 2.4.16 */ } /* Sftpname and Sftpuser and Sftphost * record the name of the file being transferred, to use in the status * line updates */ void Sftpname(char *s) { strcpy(s, (char *) newfile); /* BYU LSC */ } ip_addr Sftphost(void) { return(hishostaddr); } void Sftpstat(long *byt) { *byt = filelen; } void FTPLogUserLoggingIn(void) { ftpmess("FTP user "); ftpmess((char *) myuser); ftpmess(" logging in\015\012"); } /****************************************************************************/ /* Sencompass - Compute the encrypted password */ void Sencompass(char *ps, char *en) { short i,ck; char *p,c; ck = 0; p = ps; while (*p) /* checksum the string */ ck += *p++; c = ck; for (i=0; i<10; i++) { *en = (((*ps ^ c) | 32) & 127); /* XOR with checksum */ if (*ps) ps++; else c++; /* to hide length */ en++; } *en = 0; } /* Sencompass */ /****************************************************************************/ /* Scompass - compute and check the encrypted password */ Boolean Scompass(char *ps, char *en) { short ck; char *p,c; ck = 0; p = ps; while (*p) /* checksum the string */ ck += *p++; c = ck; while (*en) { if ((((*ps ^ c) | 32) & 127) != *en) /* XOR with checksum */ return(FALSE); if (*ps) ps++; else c++; /* increment checksum to hide length */ en++; } return(TRUE); } /****************************************************************************/ /* Scheckpass - Check the password file for the user, password combination */ Boolean Scheckpass(char *us, char *ps) { FTPUser **FTPUhdl; Str255 scratchPstring; CInfoPBRec theInfo; strcpy((char *)scratchPstring, us); CtoPstr((char *)scratchPstring); UseResFile(TelInfo->SettingsFile); FTPUhdl = (FTPUser **)Get1NamedResource(FTPUSER, scratchPstring); if (ResError()) return(FALSE); // User not found HLock((Handle)FTPUhdl); BlockMove((**FTPUhdl).EncryptedPassword, scratchPstring, Length((**FTPUhdl).EncryptedPassword)+1); PtoCstr(scratchPstring); if (Scompass(ps, (char *)scratchPstring)) { // Password matches TelInfo->DefaultDirDirID = (**FTPUhdl).DefaultDirDirID; TelInfo->DefaultDirVRefNum = VolumeNameToRefNum((**FTPUhdl).DefaultDirVolName); WriteZero((Ptr)&theInfo, sizeof(CInfoPBRec)); theInfo.dirInfo.ioVRefNum = TelInfo->DefaultDirVRefNum; theInfo.dirInfo.ioDrDirID = TelInfo->DefaultDirDirID; theInfo.dirInfo.ioNamePtr = scratchPstring; theInfo.dirInfo.ioFDirIndex = -1; // Only give me the Directory Info if (PBGetCatInfoSync(&theInfo) != noErr) { TelInfo->DefaultDirDirID = 2; TelInfo->DefaultDirVRefNum = -1; } ReleaseResource((Handle)FTPUhdl); return(TRUE); } ReleaseResource((Handle)FTPUhdl); return(FALSE); // Password was no good } \ No newline at end of file +// Background procedures for rcp and ftp // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* * NCSA Revisions: * 11/86 Tim Krauskopf * 7/92 Telnet 2.6: added global structures, cleaned up defines Scott Bulmahn * * */ #include "InternalEvents.h" #include "netevent.proto.h" #include "menuseg.proto.h" #include "network.proto.h" #include "mydnr.proto.h" #include "macutil.proto.h" #include "macbinary.h" #include "binsubs.proto.h" #include "maclook.proto.h" #include "bkgr.proto.h" #include "telneterrors.h" #include "wind.h" #include "mainseg.proto.h" #include "translate.proto.h" #include "DlogUtils.proto.h" // For WriteZero proto #include "vsdata.h" #include "vsinterf.proto.h" extern WindRec *ftplog; extern TelInfoRec *TelInfo; #define PFTP 1 #define PRCP 2 #define PDATA 3 #define HTELNET 23 #define HRSHD 514 #define HFTP 21 #define BUFFERS 8000 #define PATHLEN 256 #define MACBINARY #define RCPSEGSIZE 512 #define O_RAW O_RDONLY #define EOLCHAR 13 #define FASCII 0 #define FIMAGE O_RAW #define FAMODE 0 #define FIMODE 1 #define FMMODE 2 /* Mac Binary, when ready */ MBFile *mbfp=NULL; char *nextfile; static Handle mungbuf = 0; static short fcnt=0; static short ftpenable=0, /* is file transfer enabled? */ rcpenable=0, /* is rcp enabled? */ rsnum=-1, /* port number for incoming rshell */ rserr=-1; /* port number for rshd() stderr */ static unsigned char *xs=0L, /* buffer space for file transfer */ *pathname=0L, /* space to keep path names */ *newfile=0L, /* current file being received */ myuser[17], /* user name on my machine */ waitchar; /* character waiting for from net */ static short curstate = -1, /* state machine for background processes */ retstate = 200, /* to emulate a subroutine call */ ftpstate = 0, /* state of the ftp data transfer */ isdir=0, /* flag for rcp target pathname */ waitpos=0, /* marker for gathering strings from net */ cnt=0, /* number of characters from last netread() */ fh=0, /* file handle when transfer file is open */ ftpfh=0, /* file handle for ftp data */ rc=0, /* telnet flag */ xp=0, /* general pointer */ towrite=0, /* file transfer pointer */ len=0; /* file transfer length */ static long filelen=0L; /* length of current file for transfer */ short mainport[NPORTS]; /* BYU 2.4.16 - map FTP data port to main port */ short dataport[NPORTS]; /* BYU 2.4.16 - map FTP main port to data port */ short mainstate[NPORTS]; /* BYU 2.4.16 */ short datastate[NPORTS]; /* BYU 2.4.16 */ short retnstate[NPORTS]; ip_port fileport[NPORTS]; static char crfound=0; static short rfstate, ftptmode=FAMODE; /* how to transfer the file on net */ static ip_addr portaddr[NPORTS], hishostaddr; static ip_port portremoteport[NPORTS], portlocalport[NPORTS]; unsigned char messs[100]; /* BYU */ char ListingTemplate[256]; CInfoPBRec theDirectoryState; static void CRESP(short fnum, short msg_number); static short ftpgo( short fnum); void FTPServerUnload(void) {} void CRESP(short fnum, short msg_number) { GetIndString(messs,MSG_RESOURCE_ID,msg_number+1); netpush(fnum); Rnetwrite(fnum, &messs[1], (short)messs[0]); } void ftpmess( char *cp) { short temp; temp=strlen(cp); if (temp>80 || temp < 1) return; VSwrite(ftplog->vs,cp,temp); } /***********************************************************************/ void StartUpFTP(void) { if (gFTPServerPrefs->ServerState != 0) setftp(); else unsetftp(); } void setftp( void) { short fnum,i1; /* BYU 2.4.16 */ short size = 1024; Mnetinit(); // RAB BetterTelnet 1.0fc4 /* set up to receive a telnet connection for ftp commands */ rfstate = 0; ftpstate = 0; /* Listen for FTP if we're not listening already */ for (i1 = 0; i1 < NPORTS; i1++) /* BYU 2.4.16 */ if (GetPortType(i1) == PFTP) break; /* BYU 2.4.16 */ if (i1 >= NPORTS) { /* BYU 2.4.16 - non-SLIP listen */ fnum = netlisten(HFTP); /* BYU 2.4.16 - MacTCP listen */ ftpenable = 1; /* BYU 2.4.16 */ if (fnum >= 0) { /* BYU 2.4.16 - signal that events should be caught */ SetPortType(fnum, PFTP); dataport[fnum] = -1; /* BYU 2.4.16 - no data needed yet */ mainstate[fnum] = 0; /* BYU 2.4.16 */ datastate[fnum] = 0; /* BYU 2.4.16*/ retnstate[fnum] = 200; /* BYU 2.4.16 */ } /* BYU 2.4.16 */ } /* BYU 2.4.16 */ strcpy((char *) myuser,"unknown"); /* BYU LSC - set unknown user name */ if (mungbuf == NULL) mungbuf = myNewHandle(size); } void unsetftp( void) { short i1; /* BYU 2.4.16 */ rfstate = 0; ftpstate = 0; for (i1 = 0; i1 < NPORTS; i1++) { /* BYU 2.4.16 */ if (GetPortType(i1) == PFTP) { /* BYU 2.4.16 */ netclose(i1); /* BYU 2.4.16 */ SetPortType(i1, NO_TYPE); /* BYU 2.4.16 */ mainstate[i1] = 0; /* BYU 2.4.16 */ datastate[i1] = 0; /* BYU 2.4.16*/ } /* BYU 2.4.16 */ } /* BYU 2.4.16 */ ftpenable = 0; if (mungbuf != NULL) DisposeHandle(mungbuf); } #if 0 /* BYU - Converted to STR# resource number 23227 */ /***********************************************************************/ /* * resident ftp server -- enables initiation of ftp without a username * and password, as long as this telnet is active at the same time * Now checks for the need of passwords. */ static char *messs[] = { "220 Macintosh Resident FTP server, ready \015\012", "451 Error in processing list command \015\012", "221 Goodbye \015\012", /*2*/ "200 This space intentionally left blank < > \015\012", "150 Opening connection \015\012", "226 Transfer complete \015\012", /*5*/ "200 Type set to A, ASCII transfer mode \015\012", "200 Type set to I, binary transfer mode \015\012", "500 Command not understood \015\012", /*8*/ "200 Okay \015\012", "230 User logged in \015\012", "550 File not found \015\012", /*11*/ "501 Directory not present or syntax error\015\012", "250 Chdir okay\015\012", "257 \"", "\" is the current directory \015\012", /*15*/ "501 File not found \015\012", "504 Parameter not accepted, not implemented\015\012", "200 Stru F, file structure\015\012", "200 Mode S, stream mode\015\012", /*19*/ "202 Allocate and Account not required for this server\015\012", "501 Cannot open file to write, check for valid name\015\012", "530 USER and PASS required to activate me\015\012", "331 Password required\015\012", /*23 */ "530 Login failed\015\012", "200 MacBinary Mode enabled\015\012", "200 MacBinary Mode disabled\015\012", /*26 */ "552 Disk write error, probably disk full\015\012", "214-NCSA Telnet FTP server, supported commands:\015\012", " USER PORT RETR ALLO PASS STOR CWD XCWD XPWD LIST NLST\015\012", " HELP QUIT MODE TYPE STRU ACCT NOOP MACB\015\012", /*30*/ " MACB is MacBinary and must be done with TYPE I\015\012", "214 Direct comments and bugs to telbug@ncsa.uiuc.edu\015\012", "200 Type set to I, binary transfer mode [MACBINARY ENABLED]\015\012", /* 33 */ "200 Type set to I, binary transfer mode [macbinary disabled]\015\012", ""}; #endif /* open the FTP data connection to the remote host */ short ftpgo( short fnum) { short ftpdata; netfromport(20); /* ftp data port */ ftpdata = netxopen(portaddr[fnum],fileport[fnum], 15); mainport[ftpdata] = fnum; dataport[fnum] = ftpdata; return(ftpdata); } void rftpd ( short code, /* BYU 2.4.16 */ short fnum /* BYU 2.4.16 */ ) { ip_port fdport; short ftpdata, i, append = 0; char tempp[256], theDir[256]; char updir[4]; /* JMB 2.6 */ if (!ftpenable) return; netpush(fnum); rfstate = mainstate[fnum]; /* BYU 2.4.16 */ ftpstate = datastate[fnum]; /* BYU 2.4.16 */ retstate = retnstate[fnum]; /* BYU 2.4.16 */ fdport = fileport[fnum]; /* BYU 2.4.16 */ switch (rfstate) { case 0: if (code != CONOPEN) break; ftptmode = FAMODE; netputevent(USERCLASS,FTPCOPEN,-1,0); if (!xs) xs=(unsigned char *)myNewPtr(BUFFERS+10); /* BYU LSC */ if (!pathname) pathname=(unsigned char *)myNewPtr(PATHLEN); if (!newfile) newfile=(unsigned char *)myNewPtr(PATHLEN); if (!xs || !pathname || !newfile) /* no memory for ftp names */ { DoError(114 | MEMORY_ERRORCLASS, LEVEL3, NULL); quit(); // Should we really quit? } rfstate = 1; /* drop through */ case 1: CRESP(fnum,0); /* BYU 2.4.16 */ netgetftp(fnum, &portaddr[fnum], &portlocalport[fnum], &portremoteport[fnum]); /* BYU 2.4.16 - get default ftp information */ hishostaddr = portaddr[fnum]; fdport = portremoteport[fnum]; waitpos = 0; waitchar = '\012'; rfstate = 50; /* note skips over */ if ((gFTPServerPrefs->ServerState == 2)) retstate = 3; /* check pass */ else retstate = 5; /* who needs one ? */ break; case 3: /* check for passwords */ case 4: waitpos = 0; waitchar = '\012'; rfstate = 50; if (!strncmp("USER",(char *) xs,4)) { /* BYU LSC */ if (strlen((char *) xs) < 6) /* BYU LSC - make sure blank name stays blank */ xs[5] = myuser[0] = 0; strncpy((char *) myuser,(char *) &xs[5],16); /* BYU LSC - keep user name */ FTPLogUserLoggingIn(); CRESP(fnum,23); /* BYU 2.4.16 */ retstate = 4; /* wait for password */ break; } if (!strncmp("PASS",(char *) xs,4)) { /* BYU LSC */ if (Scheckpass((char *) myuser,(char *) &xs[5])) { /* BYU LSC */ ftpmess("FTP password OK - logged in\015\012"); CRESP(fnum,10); /* BYU 2.4.16 */ retstate = 5; } else { ftpmess("FTP password failed - access denied\015\012"); CRESP(fnum,24); /* BYU 2.4.16 */ retstate = 3; } break; } if (!strncmp("QUIT",(char *) xs,4)) { /* BYU LSC */ CRESP(fnum,2); /* BYU 2.4.16 */ cnt = -1; } else { CRESP(fnum,22); /* BYU 2.4.16 */ } retstate = 3; /* must have password first */ break; /* interpret commands that are received from the other side */ case 5: /* set to a safe state to handle recursion, wait for another command line from client */ rfstate = 50; retstate = 5; waitchar = '\012'; waitpos = 0; if (!strncmp((char *) xs,"LIST",4) || !strncmp((char *) xs,"NLST",4)) { /* BYU LSC */ if ((strlen((char *) xs) < 6) || xs[5] == '.') /* BYU LSC */ strcpy((char *) xs,"LIST *"); /* BYU LSC */ strcpy(ListingTemplate, (char *) &xs[5]); theDirectoryState.hFileInfo.ioFDirIndex=1; theDirectoryState.hFileInfo.ioVRefNum = TelInfo->DefaultDirVRefNum; theDirectoryState.hFileInfo.ioDirID = TelInfo->DefaultDirDirID; nextfile = getFileName(ListingTemplate, &theDirectoryState); /* find first name */ if (nextfile == NULL) { CRESP(fnum,16); /* BYU 2.4.16 */ } else { Str255 tempstr; char tempstr2[256]; ftpdata = ftpgo(fnum); /* BYU 2.4.16 - open the connection */ fdport = portremoteport[fnum]; /* BYU 2.4.16 - reset to def */ if (ftpdata >= 0) SetPortType(ftpdata, PDATA); ftpstate = 40; /* ready to transmit */ CRESP(fnum,4); /* BYU 2.4.16 */ PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, tempstr); PtoCstr(tempstr); sprintf(tempstr2, "FTP Sending Directory %s\015\012", (char *)tempstr); ftpmess(tempstr2); } } else if (!strncmp((char *) xs,"CWD",3)) { /* BYU LSC */ if (ChangeDirectory(&(TelInfo->DefaultDirDirID), &(TelInfo->DefaultDirVRefNum), (char *) &xs[4])) { CRESP(fnum,12); /* BYU 2.4.16 */ } else { /* success */ CRESP(fnum,13); /* BYU 2.4.16 */ } } // KFG BetterTelnet 2.0fc1 - integrated KFG's patch for mkdir/rmdir else if (!strncmp((char *) xs,"MKD",3)) { /* KFG */ if (MakeDirectory(&(TelInfo->DefaultDirDirID), &(TelInfo->DefaultDirVRefNum), (char *) &xs[4])) { CRESP(fnum,37); } else { /* success */ CRESP(fnum,36); } } else if (!strncmp((char *) xs,"RMD",3)) { /* KFG */ if (RemoveDirectory(&(TelInfo->DefaultDirDirID), &(TelInfo->DefaultDirVRefNum), (char *) &xs[4])) { CRESP(fnum,39); } else { /* success */ CRESP(fnum,38); } } else if (!strncmp((char *) xs,"XMKD",4)) { /* KFG */ if (MakeDirectory(&(TelInfo->DefaultDirDirID), &(TelInfo->DefaultDirVRefNum), (char *) &xs[5])) { CRESP(fnum,37); } else { /* success */ CRESP(fnum,36); } } else if (!strncmp((char *) xs,"XRMD",4)) { /* KFG */ if (RemoveDirectory(&(TelInfo->DefaultDirDirID), &(TelInfo->DefaultDirVRefNum), (char *) &xs[5])) { CRESP(fnum,39); } else { /* success */ CRESP(fnum,38); } } else if (!strncmp((char *) xs,"CDUP",4)) { /* JMB 2.6 */ strcpy(updir, ".."); /* JMB 2.6 */ if (ChangeDirectory(&(TelInfo->DefaultDirDirID), &(TelInfo->DefaultDirVRefNum), updir)) { /* JMB 2.6 */ CRESP(fnum,12); /* JMB 2.6 */ } /* JMB 2.6 */ else { /* JMB 2.6 */ CRESP(fnum,13); /* JMB 2.6 */ } /* JMB 2.6 */ } /* JMB 2.6 */ else if (!strncmp((char *) xs,"STOR",4) || !strncmp((char *) xs,"APPE", 4)) { short MBflag; if (!strncmp((char *) xs,"APPE", 4)) { if (ftptmode != FASCII) { CRESP(fnum, 35); break; } else append = 1; } /* had to simplify this, else MPW C 3.0/3.1 generates bad code! */ if ((!TelInfo->MacBinary) || (ftptmode == FAMODE)) MBflag = MB_DISABLE; else MBflag = 0; if (ftptmode == FAMODE) MBflag |= MB_ISASCII; if (append) MBflag |= MB_APPEND; append = 0; mbfp = MBopen((char *)&xs[5], TelInfo->DefaultDirVRefNum, TelInfo->DefaultDirDirID, (short)(MB_WRITE | MBflag)); if (mbfp == 0L) { CRESP(fnum,21); /* BYU 2.4.16 */ break; } else ftpfh = 12; ftpstate = 0; strncpy((char *) newfile,(char *) &xs[5],PATHLEN-1); /* BYU LSC */ ftpdata = ftpgo(fnum); /* BYU 2.4.16 - open connection */ fdport = portremoteport[fnum]; /* BYU 2.4.16 - reset to def */ if (ftpdata >= 0) SetPortType(ftpdata, PDATA); CRESP(fnum,4); /* BYU 2.4.16 */ ftpstate = 30; /* ready for data */ } else if (!strncmp((char *) xs,"RETR",4)) /* BYU LSC */ { /* had to simplify this, else MPW C 3.0/3.1 generates bad code! */ short MBflag; if ((!TelInfo->MacBinary) || (ftptmode == FAMODE)) MBflag = MB_DISABLE; else MBflag = 0; if (ftptmode == FAMODE) MBflag |= MB_ISASCII; mbfp = MBopen((char *) &xs[5], TelInfo->DefaultDirVRefNum, TelInfo->DefaultDirDirID, MB_READ | MBflag); if (mbfp == 0L) { CRESP(fnum,11); /* BYU 2.4.16 */ break; } ftpfh = 12; strncpy((char *) newfile,(char *) &xs[5],PATHLEN-1); /* BYU LSC */ PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, (StringPtr) theDir); PtoCstr((StringPtr) theDir); sprintf(tempp,"remote <-- %s/%s\015\012",theDir,newfile); ftpmess(tempp); ftpdata = ftpgo(fnum); /* BYU 2.4.16 - open connection */ fdport = portremoteport[fnum]; ftpstate = 20; /* ready for data */ if (ftpdata >= 0) SetPortType(ftpdata, PDATA); CRESP(fnum,4); /* BYU 2.4.16 */ } else if (!strncmp((char *) xs,"TYPE",4)) { /* BYU LSC */ if (toupper(xs[5]) == 'I') { ftptmode = FIMODE; if (TelInfo->MacBinary) { CRESP(fnum,33); /* BYU 2.4.16 - Binary on, MACB ON */ } else { CRESP(fnum,34); /* BYU 2.4.16 - Binary on, MACB off */ } } else if (toupper(xs[5]) == 'A') { ftptmode = FAMODE; CRESP(fnum,6); /* BYU 2.4.16 */ } else { CRESP(fnum,17); /* BYU 2.4.16 */ } } else if (!strncmp((char *) xs,"MACB",4)) { /* BYU LSC */ if (toupper(xs[5]) == 'E') { TelInfo->MacBinary = 1; CRESP(fnum,25); /* BYU 2.4.16 */ } else { TelInfo->MacBinary = 0; CRESP(fnum,26); /* BYU 2.4.16 */ } DisplayMacBinary(); /* post an event ? */ } else if (!strncmp((char *) xs,"PORT",4)) { /* get the requested port number from the command given */ ip_addrbytes tempaddr; unsigned char *stringPtr, *tempPtr, storage[10]; long numbers[6]; short index; for (tempPtr = stringPtr = &xs[5], index = 0; (*stringPtr != '\0') && (index < 6);index++) { while ((*tempPtr != '\0') && (*tempPtr != ',')) { tempPtr++; }; BlockMoveData(stringPtr, &(storage[1]), tempPtr-stringPtr); storage[0] = tempPtr-stringPtr; StringToNum(storage, &numbers[index]); tempPtr++; stringPtr = tempPtr; } tempaddr.a.byte[0] = (char) numbers[0]; tempaddr.a.byte[1] = (char) numbers[1]; tempaddr.a.byte[2] = (char) numbers[2]; tempaddr.a.byte[3] = (char) numbers[3]; portaddr[fnum] = tempaddr.a.addr; portlocalport[fnum] = numbers[4]*256 + numbers[5]; fdport = portlocalport[fnum]; CRESP(fnum,3); } else if (!strncmp((char *) xs,"QUIT",4)) { /* BYU LSC */ CRESP(fnum,2); /* BYU 2.4.16 */ rfstate = 60; netputuev(CONCLASS,CONDATA,fnum,0); /* post back to me */ } else if (!strncmp((char *) xs,"XPWD",4) || !strncmp((char *) xs,"PWD",3)) { /* BYU LSC */ CRESP(fnum,14); /* BYU 2.4.16 - start reply */ PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, (StringPtr) xs); PtoCstr((StringPtr) xs); Rnetwrite(fnum,(char *) xs,strlen((char *) xs)); /* BYU LSC - write dir name */ CRESP(fnum,15); /* BYU 2.4.16 - finish reply */ } else if (!strncmp((char *) xs,"USER",4)) { /* BYU LSC */ if (strlen((char *) xs) < 6) /* BYU LSC - make sure blank name stays blank */ xs[5] = myuser[0] = 0; strncpy((char *) myuser,(char *) &xs[5],16); /* BYU LSC - keep user name */ FTPLogUserLoggingIn(); /* confirm log in without password */ CRESP(fnum,10); /* BYU 2.4.16 */ } else if (!strncmp((char *) xs,"STRU",4)) { /* BYU LSC - only one stru allowed */ if (xs[5] == 'F') { CRESP(fnum,18); } /* BYU 2.4.16 */ else { CRESP(fnum,17); } /* BYU 2.4.16 */ } else if (!strncmp((char *) xs,"MODE",4)) { /* BYU LSC - only one mode allowed */ if (xs[5] == 'S') { CRESP(fnum,19); } /* BYU 2.4.16 */ else { CRESP(fnum,17); } /* BYU 2.4.16 */ } else if (!strncmp((char *) xs,"ALLO",4) || !strncmp((char *) xs,"ACCT",4)) { /* BYU LSC */ CRESP(fnum,20); } /* BYU 2.4.16 */ else if (!strncmp((char *) xs,"HELP",4)) { /* BYU LSC */ for (i=28; i<33; i++) { CRESP(fnum,i); } /* BYU 2.4.16 */ } else if (!strncmp((char *) xs,"NOOP",4)) { /* BYU LSC */ CRESP(fnum,9); } /* BYU 2.4.16 */ else if (!strncmp((char *) xs,"SYST",4)) { // JMB 2.6 netpush(fnum); // JMB 2.6 Rnetwrite(fnum, "225 MACOS System Version:\015\012", 27); // JMB 2.6 } // JMB 2.6 else { /* command not understood */ CRESP(fnum,8); /* BYU 2.4.16 */ } break; /* subroutine to wait for a particular character */ case 50: while (0 < (cnt = netread(fnum,&xs[waitpos],1))) { if (xs[waitpos] == waitchar) { rfstate = retstate; while (xs[waitpos] < 33) /* find end of string */ waitpos--; xs[++waitpos] = '\0'; /* put in terminator */ for (i=0; i<4; i++) /* want upper case */ xs[i] = toupper(xs[i]); break; } else waitpos += cnt; } break; case 60: /* wait for message to get through */ /* or connection is broken */ /* printf(" %d,%d",netpush(fnum),netest(fnum));*/ if (!netpush(fnum) || netest(fnum)) cnt = -1; else netputuev(CONCLASS,CONDATA,fnum,0); /* post back to me */ break; default: break; } if (cnt < 0) { if (mbfp) { MBclose( mbfp ); mbfp = NULL; } ftpdata = dataport[fnum]; /* BYU 2.4.16 */ if (ftpdata > 0) { netclose(ftpdata); netputevent(USERCLASS,FTPEND,-1,0); dataport[fnum] = -1; /* BYU 2.4.16 */ mainport[ftpdata] = -1; /* BYU 2.4.16 */ } rfstate = 100; ftpstate = 0; cnt = 0; netclose(fnum); SetPortType(fnum, NO_TYPE); netputevent(USERCLASS,FTPCLOSE,-1,0); #if 0 /* BYU 2.4.16 */ fnum = -1; ftpdata = -1; #endif /* BYU 2.4.16 */ setftp(); /* reset it */ } mainstate[fnum] = rfstate; /* BYU 2.4.16 */ datastate[fnum] = ftpstate; /* BYU 2.4.16 */ retnstate[fnum] = retstate; /* BYU 2.4.16 */ fileport[fnum] = fdport; /* BYU 2.4.16 */ } /* important note: for Sfread, nwant must be 256 bytes LARGER than the amount which will probably be read from the connection. Sfread will stop anywhere from 0 to 256 bytes short of filling nwant number of bytes. */ long Sfread( short pnum, char *buf, long nwant) { long i, ndone, lim; char *p, *q; if (nwant < 1024) return(-1); ndone = 0; HLock(mungbuf); while (ndone < nwant - 1024) { if (0 >= (lim = netread(pnum,*mungbuf,1024))) { if (ndone || !lim) /* if this read is valid, but no data */ return(ndone); else return(-1); /* if connection is closed for good */ } p = *mungbuf; q = (char *) buf + ndone; /* printf("\012 lim=%d done=%d want=%d",lim,ndone,nwant); n_row(); */ for (i=0; i < lim; i++) { if (crfound) { if (*p == 10) *q++ = EOLCHAR; else if (*p == 0) *q++ = 13; /* CR-NUL means CR */ crfound = 0; } else if (*p == 13) crfound = 1; else if (gFTPServerPrefs->DoISOtranslation) { *q++ = (char) ftp_iso_mac((unsigned char *)p); /* transform to mac */ } else *q++ = *p; /* copy the char */ p++; } ndone = q-buf; /* count chars ready */ } HUnlock(mungbuf); return(ndone); } /***************************************************************************/ /* Sfwrite * Write an EOL translated buffer into Rnetwrite. * Returns the number of bytes which were processed from the incoming * buffer. Uses its own 1024 byte buffer for the translation (with Sfread). */ long Sfwrite( short pnum, void *buf, long nsrc) { long i,ndone,nout,lim; char *p,*q; ndone = 0; HLock (mungbuf); while (ndone < nsrc) { if (0 > ( i = netroom(pnum))) return(-1); if (i < 1024) /* not enough room to work with */ return(ndone); /* process up to 512 source bytes for output (could produce 1K bytes out) */ if (nsrc - ndone > 512) lim = 512; else lim = nsrc-ndone; p = (char *) buf + ndone; /* where to start this block */ q = *mungbuf; /* where munged stuff goes */ for (i=0; i < lim; i++) { if (*p == EOLCHAR) { *q++ = 13; *q++ = 10; p++; } else if (gFTPServerPrefs->DoISOtranslation) { *q++ = (char) ftp_mac_iso((unsigned char *)p); /* transform to ISO */ p++; } else *q++ = *p++; } ndone += lim; /* # of chars processed */ nout = q-*mungbuf; /* # of chars new */ if ( nout != Rnetwrite(pnum,*mungbuf,nout) ) /* Some error in Sfwrite */ DoError (201 | RESOURCE_ERRORCLASS, LEVEL1, NULL); } HUnlock (mungbuf); return(ndone); } /* FTP receive and send file functions */ void ftpd ( short code, short ftpdata /* BYU 2.4.16 */ ) { short fnum = mainport[ftpdata]; /* BYU 2.4.16 */ short i,a; char tempp[256]; char theDir[256]; ftpstate = datastate[fnum]; /* BYU 2.4.16 */ switch (ftpstate) { default: break; case 40: /* list file names in current dir */ if (code == CONFAIL) /* something went wrong */ fcnt = -1; if (code != CONOPEN) /* waiting for connection to open */ break; ftpstate = 41; /* * send the "nextfile" string and then see if there is another file * name to send */ case 41: netputuev(SCLASS,FTPACT,ftpdata,0); netpush(ftpdata); strcpy(tempp,nextfile); /* BYU 2.4.13 */ strcat(tempp,"\015\012"); /* BYU 2.4.13 */ i = strlen(tempp); /* BYU 2.4.13 */ if (gFTPServerPrefs->DoISOtranslation) trbuf_mac_ftp((unsigned char *)tempp, i); /* transform to ISO */ //PETERL? if (i != Rnetwrite(ftpdata,tempp,i)) { /* BYU 2.4.13 */ CRESP(fnum,1); /* BYU 2.4.16 */ fcnt = -1; break; } theDirectoryState.hFileInfo.ioFDirIndex++; if (NULL == (nextfile = getFileName(ListingTemplate, &theDirectoryState))) { /* normal end */ ftpstate = 22; /* push data through */ } break; case 30: if (code == CONFAIL) /* something went wrong */ fcnt = -1; if (code != CONOPEN) /* waiting for connection to open */ break; ftpstate = 31; crfound = 0; len = xp = 0; filelen = 0L; PathNameFromDirID(TelInfo->DefaultDirDirID, TelInfo->DefaultDirVRefNum, (StringPtr) theDir); PtoCstr((StringPtr) theDir); sprintf(tempp,"remote --> %s/%s\015\012",theDir,newfile); ftpmess(tempp); netputevent(USERCLASS,FTPBEGIN,-2,0); case 31: /* * file has already been opened, take everything from the connection * and place into the open file: ftpfh */ do { /* wait until xs is full before writing to disk */ if (len <= 2000) { if (xp) { if (0 > MBwrite(mbfp, xs, xp)) { DoError (202 | RESOURCE_ERRORCLASS, LEVEL1, NULL); MBclose( mbfp); /* Close on Disk Full Error */ ftpstate=22; CRESP(fnum,27); /* BYU 2.4.16 */ ftpmess((char *) messs); /* BYU LSC */ if( (a = netclose(ftpdata)) !=0 ) DoError (108 | NET_ERRORCLASS, LEVEL1, NULL); fcnt = -1; mbfp=NULL; break; } xp = 0; } len = BUFFERS; /* expected or desired len to go */ } if (ftptmode == FAMODE) fcnt = Sfread(ftpdata,(char *) &xs[xp],len); /* BYU LSC */ else fcnt = netread(ftpdata,&xs[xp],len); if (fcnt >= 0) { len -= fcnt; xp += fcnt; filelen += fcnt; } if (fcnt < 0) { if (0 > MBwrite( mbfp, xs, xp)) { CRESP(fnum,27); /* BYU 2.4.16 */ MBclose( mbfp); /* Close file on error */ break; } MBclose( mbfp ); ftpfh = 0; CRESP(fnum,5); /* BYU 2.4.16 */ } } while (fcnt > 0); break; case 20: if (code == CONFAIL) /* something went wrong */ fcnt = -1; if (code != CONOPEN) /* waiting for connection to open */ break; ftpstate = 21; filelen = MBsize( mbfp ); towrite = 0; xp = 0; netputevent(USERCLASS,FTPBEGIN,-1,0); case 21: /* * transfer file(s) to the other host via ftp request * file is already open = ftpfh */ netputuev(SCLASS,FTPACT,ftpdata,0); if (towrite <= xp) { i = BUFFERS; towrite = MBread( mbfp, xs, i); xp = 0; } if (towrite <= 0 || netest(ftpdata)) { /* we are done */ ftpstate = 22; break; } if (ftptmode == FAMODE) i = Sfwrite(ftpdata,&xs[xp],towrite-xp); else i = Rnetwrite(ftpdata,&xs[xp],towrite-xp); if (i > 0) { xp += i; filelen -= i; if (filelen < 0L) filelen = 0L; } break; case 22: /* wait for data to be accepted */ netputuev(SCLASS,FTPACT,ftpdata,0); fcnt = netpush(ftpdata); /* will go negative on err */ if (!fcnt || netest(ftpdata)) fcnt = -1; if (fcnt < 0) { CRESP(fnum,5); /* BYU 2.4.16 */ } break; case 0: break; } /* end of switch */ /* after reading from connection, if the connection is closed, reset up shop. */ if (fcnt < 0) { if (mbfp) { MBclose( mbfp ); mbfp = NULL; } ftpstate = 0; fcnt = 0; if (ftpdata >= 0) { netclose(ftpdata); netputevent(USERCLASS,FTPEND,-1,0); mainport[ftpdata] = -1; /* BYU 2.4.16 */ dataport[fnum] = -1; /* BYU 2.4.16 */ } } datastate[fnum] = ftpstate; /* BYU 2.4.16 */ } /* Sftpname and Sftpuser and Sftphost * record the name of the file being transferred, to use in the status * line updates */ void Sftpname(char *s) { strcpy(s, (char *) newfile); /* BYU LSC */ } ip_addr Sftphost(void) { return(hishostaddr); } void Sftpstat(long *byt) { *byt = filelen; } void FTPLogUserLoggingIn(void) { ftpmess("FTP user "); ftpmess((char *) myuser); ftpmess(" logging in\015\012"); } /****************************************************************************/ /* Sencompass - Compute the encrypted password */ void Sencompass(char *ps, char *en) { short i,ck; char *p,c; ck = 0; p = ps; while (*p) /* checksum the string */ ck += *p++; c = ck; for (i=0; i<10; i++) { *en = (((*ps ^ c) | 32) & 127); /* XOR with checksum */ if (*ps) ps++; else c++; /* to hide length */ en++; } *en = 0; } /* Sencompass */ /****************************************************************************/ /* Scompass - compute and check the encrypted password */ Boolean Scompass(char *ps, char *en) { short ck; char *p,c; ck = 0; p = ps; while (*p) /* checksum the string */ ck += *p++; c = ck; while (*en) { if ((((*ps ^ c) | 32) & 127) != *en) /* XOR with checksum */ return(FALSE); if (*ps) ps++; else c++; /* increment checksum to hide length */ en++; } return(TRUE); } /****************************************************************************/ /* Scheckpass - Check the password file for the user, password combination */ Boolean Scheckpass(char *us, char *ps) { FTPUser **FTPUhdl; Str255 scratchPstring; CInfoPBRec theInfo; strcpy((char *)scratchPstring, us); CtoPstr((char *)scratchPstring); UseResFile(TelInfo->SettingsFile); FTPUhdl = (FTPUser **)Get1NamedResource(FTPUSER, scratchPstring); if (ResError()) return(FALSE); // User not found HLock((Handle)FTPUhdl); BlockMove((**FTPUhdl).EncryptedPassword, scratchPstring, StrLength((**FTPUhdl).EncryptedPassword)+1); PtoCstr(scratchPstring); if (Scompass(ps, (char *)scratchPstring)) { // Password matches TelInfo->DefaultDirDirID = (**FTPUhdl).DefaultDirDirID; TelInfo->DefaultDirVRefNum = VolumeNameToRefNum((**FTPUhdl).DefaultDirVolName); WriteZero((Ptr)&theInfo, sizeof(CInfoPBRec)); theInfo.dirInfo.ioVRefNum = TelInfo->DefaultDirVRefNum; theInfo.dirInfo.ioDrDirID = TelInfo->DefaultDirDirID; theInfo.dirInfo.ioNamePtr = scratchPstring; theInfo.dirInfo.ioFDirIndex = -1; // Only give me the Directory Info if (PBGetCatInfoSync(&theInfo) != noErr) { TelInfo->DefaultDirDirID = 2; TelInfo->DefaultDirVRefNum = -1; } ReleaseResource((Handle)FTPUhdl); return(TRUE); } ReleaseResource((Handle)FTPUhdl); return(FALSE); // Password was no good } \ No newline at end of file diff --git a/source/FTPserver/macutil.c b/source/FTPserver/macutil.c index 07da18c..f51fa93 100755 --- a/source/FTPserver/macutil.c +++ b/source/FTPserver/macutil.c @@ -1 +1 @@ -// macutil.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // April, 1993 Entirely rewritten by Jim Browne to use HFS. #ifdef MPW #pragma segment FTPServer #endif #include "maclook.proto.h" #include "telneterrors.h" #include "DlogUtils.proto.h" #include "macutil.proto.h" /* Some globals for file lookup */ char FileName[256]; // Get the name of the directory identified by vRefNum & dirID // (works for volumes too... [dirID = 2]) void GetDirectoryName(short vRefNum, long dirID, Str32 name) { CInfoPBRec theInfo; WriteZero((Ptr)&theInfo, sizeof(CInfoPBRec)); theInfo.dirInfo.ioVRefNum = vRefNum; theInfo.dirInfo.ioDrDirID = dirID; theInfo.dirInfo.ioNamePtr = name; theInfo.dirInfo.ioFDirIndex = -1; // Only give me the Directory Info PBGetCatInfoSync(&theInfo); } // Convert the given volume name to a reference number. Returns the default vRefNum // if the volume specified is not found. short VolumeNameToRefNum(Str32 volumeName) { short retval; if (SetVol(volumeName, 0) != noErr) return(-1); GetVol(NULL, &retval); return(retval); } void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName) { CInfoPBRec block; Str255 directoryName; OSErr err; fullPathName[0] = '\0'; block.dirInfo.ioDrParID = dirID; block.dirInfo.ioNamePtr = directoryName; do { block.dirInfo.ioVRefNum = vRefNum; block.dirInfo.ioFDirIndex = -1; block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID; if ((err = PBGetCatInfoSync(&block)) != noErr) return; pstrcat(directoryName, (StringPtr)"\p/"); pstrinsert(fullPathName, directoryName); } while (block.dirInfo.ioDrDirID != 2); pstrinsert(fullPathName, "\p/"); } // ChangeDirectory will change the directory relative from the provided dirID and // vRefNum. It handles preceding ".." modifiers as well as absolute pathnames. short ChangeDirectory(long *dirID, short *vRefNum,char *pathname) { CInfoPBRec theDirInfo; char tempst[256], *nSlash, *start; short NumberOfLevelsToGoUp = 0, temp, localvRefNum; long junk1, junk2, localdirID; OSErr err; start = pathname; localvRefNum = *vRefNum; localdirID = *dirID; while ( (nSlash = strchr(pathname,'/') ) !=0L) { if (( (nSlash - pathname) == 2) && (*pathname=='.') && (*(pathname+1) =='.') ) { pathname += 3L; start = pathname; NumberOfLevelsToGoUp++; } else { *nSlash=':'; pathname=nSlash + 1L; } } if ( strcmp("..",pathname)==0) { start[0]=0; NumberOfLevelsToGoUp++; } // Now start points to the beginning of a relative pathname devoid of ".."'s, and colons // for seperators rather than slashes. if ( *start==':') { // This is a fully qualified pathname if (NumberOfLevelsToGoUp) return(1); // Someone did a "../..//blah"... nSlash = strchr(start+1L, ':'); // Seperate out volume name if (strlen(start) == 1) // Someone did a "cd /" localdirID = 2; // Use top level directory else { if (nSlash != NULL) *nSlash = 0; strcpy(tempst, start+1); // Remove leading colon strcat(tempst, ":"); // Add trailing colon CtoPstr(tempst); SetVol((StringPtr)tempst, 0); GetVol(NULL, &temp); GetWDInfo(temp, &localvRefNum, &junk1, &junk2); localdirID = 2; if (nSlash != NULL) { // There's more than a volume name *nSlash = ':'; // Restore the leading slash strcpy( tempst, nSlash); CtoPstr(tempst); // tempst now contains relative pathname WriteZero((Ptr)&theDirInfo, (long)sizeof(CInfoPBRec)); theDirInfo.dirInfo.ioVRefNum = localvRefNum; // Now find the directory on the volume theDirInfo.dirInfo.ioDrDirID = localdirID; theDirInfo.dirInfo.ioNamePtr = (StringPtr)tempst; theDirInfo.dirInfo.ioFDirIndex = 0; if ((err = PBGetCatInfo(&theDirInfo, FALSE)) != noErr) return(1); localdirID = theDirInfo.dirInfo.ioDrDirID; } } } else { // This is a relative pathname, start by taking care of any ".."s... WriteZero((Ptr)&theDirInfo, (long)sizeof(CInfoPBRec)); while (NumberOfLevelsToGoUp && (localdirID != 2)) { theDirInfo.dirInfo.ioVRefNum = localvRefNum; theDirInfo.dirInfo.ioDrDirID = localdirID; theDirInfo.dirInfo.ioNamePtr = 0; theDirInfo.dirInfo.ioFDirIndex = -1; if ((err = PBGetCatInfo(&theDirInfo, FALSE)) != noErr) return(1); localdirID = theDirInfo.dirInfo.ioDrParID; NumberOfLevelsToGoUp--; } // Now use the relative pathname to find out the actual directory ID // Relative pathnames must begin with a colon, so put on on the beginning if(start[0]) { strcpy(tempst+1, start); tempst[0] = ':'; CtoPstr(tempst); WriteZero((Ptr)&theDirInfo, (long)sizeof(CInfoPBRec)); theDirInfo.dirInfo.ioVRefNum = localvRefNum; theDirInfo.dirInfo.ioDrDirID = localdirID; theDirInfo.dirInfo.ioNamePtr = (StringPtr)tempst; theDirInfo.dirInfo.ioFDirIndex = 0; if ((err = PBGetCatInfo(&theDirInfo, FALSE)) != noErr) return(1); localdirID = theDirInfo.dirInfo.ioDrDirID; } } *dirID = localdirID; // Everything went ok, change the dirID and vRefNum *vRefNum = localvRefNum; return(0); } short wccheck(char *file, char *template) /* BYU - routine now returns (short) for recursion. */ { while(*template) { if (*template=='*') { template++; if (*template) { while((*file) && !wccheck(file,template)) file++; /* BYU */ if ((*file)==0) return(0); } else return(1); continue; } else if ((*template!='?') && (*template!=*file)) return(0); template++;file++; } if (*file) /* BYU */ return(0); /* BYU */ else /* BYU */ return(1); /* BYU */ } /* getFileName * find the name in the given directory which matches the wildcard * specification */ char *getFileName(char *spec, CInfoPBRec *finfo) { CInfoPBRec *localfinfo; Boolean done = FALSE; localfinfo = (CInfoPBRec *) myNewPtr(sizeof(CInfoPBRec)); finfo->hFileInfo.ioNamePtr=(StringPtr) FileName; while (!done) { BlockMove(finfo, localfinfo, sizeof(CInfoPBRec)); if (PBGetCatInfo(localfinfo,FALSE)!=0) { DisposePtr((Ptr)localfinfo); return(0L); } FileName[FileName[0]+1]=0; if ((!wccheck(&FileName[1],spec))|| //it doesnt match (((localfinfo->hFileInfo.ioFlAttrib & 0x10)&& //its an invisible directory (localfinfo->dirInfo.ioDrUsrWds.frFlags & (fInvisible | 0x1000)))|| (!(localfinfo->hFileInfo.ioFlAttrib & 0x10)&&//its an invisible file (localfinfo->hFileInfo.ioFlFndrInfo.fdFlags)&(fInvisible | 0x1000)))) finfo->hFileInfo.ioFDirIndex++; //go to next one else done = TRUE; } if (localfinfo->hFileInfo.ioFlAttrib & 0x10) //its a directory { FileName[++FileName[0]]='/'; FileName[FileName[0]+1]=0; } DisposePtr((Ptr)localfinfo); return(&FileName[1]); } \ No newline at end of file +// macutil.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // April, 1993 Entirely rewritten by Jim Browne to use HFS. #include "maclook.proto.h" #include "telneterrors.h" #include "DlogUtils.proto.h" #include "macutil.proto.h" /* Some globals for file lookup */ char FileName[256]; // Get the name of the directory identified by vRefNum & dirID // (works for volumes too... [dirID = 2]) void GetDirectoryName(short vRefNum, long dirID, Str32 name) { CInfoPBRec theInfo; WriteZero((Ptr)&theInfo, sizeof(CInfoPBRec)); theInfo.dirInfo.ioVRefNum = vRefNum; theInfo.dirInfo.ioDrDirID = dirID; theInfo.dirInfo.ioNamePtr = name; theInfo.dirInfo.ioFDirIndex = -1; // Only give me the Directory Info PBGetCatInfoSync(&theInfo); } // Convert the given volume name to a reference number. Returns the default vRefNum // if the volume specified is not found. short VolumeNameToRefNum(Str32 volumeName) { short retval; if (SetVol(volumeName, 0) != noErr) return(-1); GetVol(NULL, &retval); return(retval); } void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName) { CInfoPBRec block; Str255 directoryName; OSErr err; fullPathName[0] = '\0'; block.dirInfo.ioDrParID = dirID; block.dirInfo.ioNamePtr = directoryName; do { block.dirInfo.ioVRefNum = vRefNum; block.dirInfo.ioFDirIndex = -1; block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID; if ((err = PBGetCatInfoSync(&block)) != noErr) return; pstrcat(directoryName, (StringPtr)"\p/"); pstrinsert(fullPathName, directoryName); } while (block.dirInfo.ioDrDirID != 2); pstrinsert(fullPathName, "\p/"); } // ChangeDirectory will change the directory relative from the provided dirID and // vRefNum. It handles preceding ".." modifiers as well as absolute pathnames. short ChangeDirectory(long *dirID, short *vRefNum,char *pathname) { CInfoPBRec theDirInfo; char tempst[256], *nSlash, *start; short NumberOfLevelsToGoUp = 0, temp, localvRefNum; long junk1, junk2, localdirID; OSErr err; start = pathname; localvRefNum = *vRefNum; localdirID = *dirID; while ( (nSlash = strchr(pathname,'/') ) !=0L) { if (( (nSlash - pathname) == 2) && (*pathname=='.') && (*(pathname+1) =='.') ) { pathname += 3L; start = pathname; NumberOfLevelsToGoUp++; } else { *nSlash=':'; pathname=nSlash + 1L; } } if ( strcmp("..",pathname)==0) { start[0]=0; NumberOfLevelsToGoUp++; } // Now start points to the beginning of a relative pathname devoid of ".."'s, and colons // for seperators rather than slashes. if ( *start==':') { // This is a fully qualified pathname if (NumberOfLevelsToGoUp) return(1); // Someone did a "../..//blah"... nSlash = strchr(start+1L, ':'); // Seperate out volume name if (strlen(start) == 1) // Someone did a "cd /" localdirID = 2; // Use top level directory else { if (nSlash != NULL) *nSlash = 0; strcpy(tempst, start+1); // Remove leading colon strcat(tempst, ":"); // Add trailing colon CtoPstr(tempst); SetVol((StringPtr)tempst, 0); GetVol(NULL, &temp); GetWDInfo(temp, &localvRefNum, &junk1, &junk2); localdirID = 2; if (nSlash != NULL) { // There's more than a volume name *nSlash = ':'; // Restore the leading slash strcpy( tempst, nSlash); CtoPstr(tempst); // tempst now contains relative pathname WriteZero((Ptr)&theDirInfo, (long)sizeof(CInfoPBRec)); theDirInfo.dirInfo.ioVRefNum = localvRefNum; // Now find the directory on the volume theDirInfo.dirInfo.ioDrDirID = localdirID; theDirInfo.dirInfo.ioNamePtr = (StringPtr)tempst; theDirInfo.dirInfo.ioFDirIndex = 0; if ((err = PBGetCatInfoSync(&theDirInfo)) != noErr) return(1); localdirID = theDirInfo.dirInfo.ioDrDirID; } } } else { // This is a relative pathname, start by taking care of any ".."s... WriteZero((Ptr)&theDirInfo, (long)sizeof(CInfoPBRec)); while (NumberOfLevelsToGoUp && (localdirID != 2)) { theDirInfo.dirInfo.ioVRefNum = localvRefNum; theDirInfo.dirInfo.ioDrDirID = localdirID; theDirInfo.dirInfo.ioNamePtr = 0; theDirInfo.dirInfo.ioFDirIndex = -1; if ((err = PBGetCatInfoSync(&theDirInfo)) != noErr) return(1); localdirID = theDirInfo.dirInfo.ioDrParID; NumberOfLevelsToGoUp--; } // Now use the relative pathname to find out the actual directory ID // Relative pathnames must begin with a colon, so put on on the beginning if(start[0]) { strcpy(tempst+1, start); tempst[0] = ':'; CtoPstr(tempst); WriteZero((Ptr)&theDirInfo, (long)sizeof(CInfoPBRec)); theDirInfo.dirInfo.ioVRefNum = localvRefNum; theDirInfo.dirInfo.ioDrDirID = localdirID; theDirInfo.dirInfo.ioNamePtr = (StringPtr)tempst; theDirInfo.dirInfo.ioFDirIndex = 0; if ((err = PBGetCatInfoSync(&theDirInfo)) != noErr) return(1); localdirID = theDirInfo.dirInfo.ioDrDirID; } } *dirID = localdirID; // Everything went ok, change the dirID and vRefNum *vRefNum = localvRefNum; return(0); } short wccheck(char *file, char *template) /* BYU - routine now returns (short) for recursion. */ { while(*template) { if (*template=='*') { template++; if (*template) { while((*file) && !wccheck(file,template)) file++; /* BYU */ if ((*file)==0) return(0); } else return(1); continue; } else if ((*template!='?') && (*template!=*file)) return(0); template++;file++; } if (*file) /* BYU */ return(0); /* BYU */ else /* BYU */ return(1); /* BYU */ } /* getFileName * find the name in the given directory which matches the wildcard * specification */ char *getFileName(char *spec, CInfoPBRec *finfo) { CInfoPBRec *localfinfo; Boolean done = FALSE; localfinfo = (CInfoPBRec *) myNewPtr(sizeof(CInfoPBRec)); finfo->hFileInfo.ioNamePtr=(StringPtr) FileName; while (!done) { BlockMove(finfo, localfinfo, sizeof(CInfoPBRec)); if (PBGetCatInfoSync(localfinfo)!=0) { DisposePtr((Ptr)localfinfo); return(0L); } FileName[FileName[0]+1]=0; if ((!wccheck(&FileName[1],spec))|| //it doesnt match (((localfinfo->hFileInfo.ioFlAttrib & 0x10)&& //its an invisible directory (localfinfo->dirInfo.ioDrUsrWds.frFlags & (fInvisible | 0x1000)))|| (!(localfinfo->hFileInfo.ioFlAttrib & 0x10)&&//its an invisible file (localfinfo->hFileInfo.ioFlFndrInfo.fdFlags)&(fInvisible | 0x1000)))) finfo->hFileInfo.ioFDirIndex++; //go to next one else done = TRUE; } if (localfinfo->hFileInfo.ioFlAttrib & 0x10) //its a directory { FileName[++FileName[0]]='/'; FileName[FileName[0]+1]=0; } DisposePtr((Ptr)localfinfo); return(&FileName[1]); } // MakeDirectory will add a new directory relative from the provided dirID and // vRefNum. It handles preceding ".." modifiers as well as absolute pathnames. short MakeDirectory(long *dirID, short *vRefNum,char *pathname) // KFG { OSErr oserr; char tstr[256]; Str255 pstr; FSSpec fsspec; long newDirID; int n, o; if (pathname[0] == '/') BlockMove(&pathname[1], tstr, strlen(pathname)); else { tstr[0] = ':'; BlockMove(pathname, &tstr[1], strlen(pathname) + 1); } for (n = 0, o = strlen(tstr); n < o; n++) if (tstr[n] == '/') tstr[n] = ':'; BlockMove(tstr, &pstr[1], (*pstr = (Byte) strlen(tstr))); if (tstr[0] != ':') oserr = FSMakeFSSpec(0x8000, 0, pstr, &fsspec); else oserr = FSMakeFSSpec(*vRefNum, *dirID, pstr, &fsspec); if (oserr != -43) return 1; return FSpDirCreate(&fsspec, 0, &newDirID); } // RemoveDirectory will remove an existing directory relative from the provided dirID and // vRefNum. It handles preceding ".." modifiers as well as absolute pathnames. short RemoveDirectory(long *dirID, short *vRefNum,char *pathname) // KFG { OSErr oserr; char tstr[256]; Str255 pstr; FSSpec fsspec; int n, o; if (pathname[0] == '/') BlockMove(&pathname[1], tstr, strlen(pathname)); else { tstr[0] = ':'; BlockMove(pathname, &tstr[1], strlen(pathname) + 1); } for (n = 0, o = strlen(tstr); n < o; n++) if (tstr[n] == '/') tstr[n] = ':'; BlockMove(tstr, &pstr[1], (*pstr = (Byte) strlen(tstr))); if (tstr[0] != ':') oserr = FSMakeFSSpec(0x8000, 0, pstr, &fsspec); else oserr = FSMakeFSSpec(*vRefNum, *dirID, pstr, &fsspec); if (! oserr) oserr = FSpDelete(&fsspec); return oserr; } \ No newline at end of file diff --git a/source/FTPserver/macutil.proto.h b/source/FTPserver/macutil.proto.h index 183867a..5fbfa73 100755 --- a/source/FTPserver/macutil.proto.h +++ b/source/FTPserver/macutil.proto.h @@ -1 +1 @@ -void GetDirectoryName(short vRefNum, long dirID, Str32 name); short VolumeNameToRefNum(Str32 volumeName); void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName); short ChangeDirectory(long *dirID, short *vRefNum,char *pathname); short wccheck(char *file, char *template); char *getFileName(char *spec, CInfoPBRec *finfo); \ No newline at end of file +void GetDirectoryName(short vRefNum, long dirID, Str32 name); short VolumeNameToRefNum(Str32 volumeName); void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName); short ChangeDirectory(long *dirID, short *vRefNum,char *pathname); short wccheck(char *file, char *template); char *getFileName(char *spec, CInfoPBRec *finfo); short MakeDirectory(long *dirID, short *vRefNum,char *pathname); short RemoveDirectory(long *dirID, short *vRefNum,char *pathname); \ No newline at end of file diff --git a/source/Headers/Preferences.h b/source/Headers/Preferences.h index 2d757d3..9ca057f 100755 --- a/source/Headers/Preferences.h +++ b/source/Headers/Preferences.h @@ -1 +1 @@ -#define PREFERENCES_FILE_NAME_STR_ID 1991 // STR resource containing "BetterTelnet // Prefs2" or translated name #define OUR_PREFS_VERSION_NUMBER 2 #define NO_TIMEOUTS_VERSION 1 // Name of each instance is the resource name. Resource type TeR2 typedef struct { short version; // Version of this structure RGBColor nfcolor, // Normal foreground RGB nbcolor, // Normal background RGB bfcolor, // Blinking foreground RGB bbcolor, // Blinking background RGB reserved1, // Reserved by JMB - NCSA reserved2; // Reserved by JMB - NCSA short vtemulation, // 0 = VT100, 1 = VT220 (supposedly) vtwidth, // Width of the terminal screen in characters vtheight, // Height of the terminal screen in characters fontsize, // Size of DisplayFont to use to display text numbkscroll; // Number of lines to save in scroll buffer Boolean ANSIgraphics, // Recognize ANSI color sequences Xtermsequences, // Recognize Xterm sequences vtwrap, // Use VT wrap mode emacsmetakey, // 0 = off, 1 = cmd-control, 2 = option emacsarrows, // Arrow keys and mouse position are EMACS flavor MATmappings, // Map PageUp, PageDown, Home, End. (MAT == Mark Tamsky) eightbit, // Don't strip the high bit clearsave; // Save cleared lines Str63 DisplayFont; // Font to use to display text Str32 AnswerBackMessage; // Response to send when asked what terminal we are Boolean remapKeypad; //remap keypad (2.7 CCP) short remapCtrlD, // remap Del to ^D (RAB BetterTelnet 1.0fc4) allowBold, // allow boldface font (RAB BetterTelnet 1.0fc4) colorBold; // use color for boldface (RAB BetterTelnet 1.0fc4) Str63 BoldFont; short boldFontSize, boldFontStyle, realbold, oldScrollback; short padding[98]; // So I'm generous.... } TerminalPrefs; #define TERMINALPREFS_RESTYPE 'TeR2' #define TERMINALPREFS_APPID 1991 // The "" terminal seed copy // Name of each instance is the resource name. Resource type SeSn typedef struct { short version; // Version of this structure short port, // Port to connect to tektype, // -1 = inhibit, 0 = 4014, 1 = 4105 pastemethod, // 0 = quick, 1 = block pasteblocksize; // Size of blocks to paste if using block mode unsigned long ip_address; // IP address of the host Boolean forcesave, // crmap, // Strange Bezerkley 4.3 CR mode needed linemode, // Allow linemode to be used showlowlevelerrors, // Not Used anymore tekclear, // Clear TEK window vs. create new one halfdup; // Half duplex required char bksp, // 0 DELETE = BKSP, 1 DELETE = DELETE ckey, skey, qkey; Str32 TerminalEmulation, // Name of terminal emulator to use TranslationTable; // Name of translation table to use by default Str63 hostname; // The DNS name of the host Boolean authenticate, // Kerberos authentication encrypt, // Encrypted session localecho, // Force local echo on? reserved1; // Reserved by JMB - NCSA short NetBlockSize, // Size of read buffer (2.7 CCP) portNegative, // Port number is negative (force use of initial Telnet codes) // (RAB BetterTelnet 1.0fc4) alwaysBSD, // always use BSD 4.3 CR mode, even on non-port-23 // (RAB BetterTelnet 1.0fc4) ignoreBeeps, // Ignore Beeps (RAB BetterTelnet 1.0fc7) ignoreff, // Ignore Form Feeds (RAB BetterTelnet 1.0fc8) otpauto, // Automatic OTP - RAB BetterTelnet 1.2 otpmulti, // RAB BetterTelnet 1.2 otpnoprompt, // RAB BetterTelnet 1.2 otphex; // RAB BetterTelnet 1.2 char otppassword[64]; // RAB BetterTelnet 1.2 short otpsavepass; // RAB BetterTelnet 1.2.1 short padding[56]; // Disk space is cheap.... (used to be [98]) } SessionPrefs; #define SESSIONPREFS_RESTYPE 'SeSn' #define SESSIONPREFS_APPID 1991 // The "" session seed copy // Only one instance of this resource type. Resource type PrEf typedef struct { short version; // Version of this resource short CursorType, // 0 = block, 1 = underscore, 2 = vertical line CopyTableThresh; // Copy table threshold long TimeSlice; // Timeslice passed to WaitNextEvent ResType CaptureFileCreator; // Creator signature for session capture files Boolean WindowsDontGoAway, // Connection's windows remain open after connection close StaggerWindows, // Stagger connection windows CommandKeys, // Use command key shortcuts for menus RemapTilde, // Remap ~ to escape BlinkCursor, // Blink the cursor KeyPadAndFuncMenus; // Show Keypad and Function key menus short OpenTimeout, // Time to Open Connections in seconds (CCP 2.7) SendTimeout, // Time to Send Data (and receive ACK) (CCP 2.7) StaggerWindowsOffset, // Allow user to specify how much windows are staggered NotifyUser, destroyKTickets, //destroy kerberos tickets when window closes autoOpenDialog, dontWarnOnQuit, autoOpenDefault, parseAliases, monospacedOut, clipTrailingSpaces, defaultBoldColor, globalSavePass; short padding[88]; // Memory is getting cheap too.... (used to be [96]) } ApplicationPrefs; #define APPLICATIONPREFS_RESTYPE 'PrEf' #define APPLICATIONPREFS_ID 1991 #define APPLICATIONPREFS_APPID 1990 extern ApplicationPrefs *gApplicationPrefs; // Only one instance of this structure. Resource FTPs typedef struct { short version; // Version of this resource short ServerState; // 0 = off, 1 = no protection, 2 = password protection OSType BinaryCreator, // Default creator for files transferred in binary mode BinaryType, // Default type for files transferred in binary mode TextCreator; // Default creator for file transferred in ASCII mode Boolean ShowFTPlog, // FTP log defaults to visible DNSlookupconnections, // Translate IP of connecting hosts to DNS names for log UseMacBinaryII, // Allow MacBinary II unused1, // Unused unused2, // Unused ResetMacBinary, // Reset MacBinary after each transfer DoISOtranslation; // Use ISO translation short padding[100]; } FTPServerPrefs; #define FTPSERVERPREFS_RESTYPE 'FTPs' #define FTPSERVERPREFS_ID 1991 #define FTPSERVERPREFS_APPID 1990 extern FTPServerPrefs *gFTPServerPrefs; // Username is the resource name. Resource type FTPu typedef struct { short version; // Version of this resource Str32 EncryptedPassword, // Encrypted form of user's password DefaultDirVolName; // Name of the volume containing user's default directory long DefaultDirDirID; // DirID of the user's default directory Boolean UserCanCWD; // User is allowed to change directories short padding[20]; // Some padding for the future } FTPUser; #define FTPUSER 'FTPu' // >>>> FTP Client Prefs? <<< typedef struct { TerminalPrefs **terminal; SessionPrefs **session; Str255 WindowName; short ftpstate; Rect WindowLocation; } ConnInitParams; \ No newline at end of file +#define PREFERENCES_FILE_NAME_STR_ID 1991 // STR resource containing "BetterTelnet // Prefs2" or translated name #define OUR_PREFS_VERSION_NUMBER 2 #define NO_TIMEOUTS_VERSION 1 /* HEY! READ THIS BEFORE YOU EVEN _THINK_ ABOUT CHANGING THE PREFS FILE FORMAT... BetterTelnet 2.0b2 changes the way the prefs work. It used to be that we had a certain amount of padding which had to be reduced each time we added a prefs option. Once we were out of padding, too bad, tough noogies, we had to scrap the whole prefs file and make a new one with a longer resource of that particular type. This happened once during the BetterTelnet 1.0 beta cycle, and thus the file is named "BetterTelnet Prefs2" and the terminals resource is 'TeR2' and not 'TeRm'. But no more. So, here are the guidelines for modifying the NEW prefs system: 1. Padding stays at 100 words, or 200 bytes. This is only for backward compatibility, but DO NOT reduce the padding when adding new options, because we WANT the resource to expand, and BetterTelnet 2.0b2 and later will take care of enlarging it for us. 2. Change the size of the master resource in the application to match this. 3. Don't worry about backwards compatibility. All versions of BetterTelnet prior to 2.0b1 did all memory copies to and from the prefs resources using the size of their prefs definition and not the actual size of the resource. Thus, they'll simply ignore the larger resource size, no problem. 4. Don't worry about forwards compatibility, either. 2.0b2 and later will automatically enlarge the resource if needed to fix their prefs definition but will never shrink it. Since all memory copies are done with the size of the prefs definition, there's still no problem. 5. 2.0b1 may crash with the 2.0b2 resource format, due to a bug. Tell users not to use 2.0b1 anymore and there won't be a problem. Just use 2.0b2, or later. 6. When adding a prefs option, remember that ALL ZEROES are the default for new options. DON'T assume that what you put in the master resource will automatically be loaded into the user's resources, because it won't unless the user deletes his/her prefs file. So, structure your prefs code so that all zeroes in a field will always invoke the default option. 7. This applies to all prefs resources except those for the FTP server. 8. And remember, always add new prefs at the end of the old ones, before the padding but after everything else. */ // Name of each instance is the resource name. Resource type TeR2 typedef struct { short version; // Version of this structure RGBColor nfcolor, // Normal foreground RGB nbcolor, // Normal background RGB bfcolor, // Blinking foreground RGB bbcolor, // Blinking background RGB reserved1, // Reserved by JMB - NCSA reserved2; // Reserved by JMB - NCSA short vtemulation, // 0 = VT100, 1 = VT220 (supposedly) vtwidth, // Width of the terminal screen in characters vtheight, // Height of the terminal screen in characters fontsize, // Size of DisplayFont to use to display text numbkscroll; // Number of lines to save in scroll buffer Boolean ANSIgraphics, // Recognize ANSI color sequences Xtermsequences, // Recognize Xterm sequences vtwrap, // Use VT wrap mode emacsmetakey, // 0 = off, 1 = cmd-control, 2 = option emacsarrows, // Arrow keys and mouse position are EMACS flavor MATmappings, // Map PageUp, PageDown, Home, End. (MAT == Mark Tamsky) eightbit, // Don't strip the high bit clearsave; // Save cleared lines Str63 DisplayFont; // Font to use to display text Str32 AnswerBackMessage; // Response to send when asked what terminal we are Boolean remapKeypad; //remap keypad (2.7 CCP) short remapCtrlD, // remap Del to ^D (RAB BetterTelnet 1.0fc4) allowBold, // allow boldface font (RAB BetterTelnet 1.0fc4) colorBold; // use color for boldface (RAB BetterTelnet 1.0fc4) Str63 BoldFont; short boldFontSize, boldFontStyle, realbold, oldScrollback, jumpScroll, realBlink; short padding[100]; // So I'm generous.... } TerminalPrefs; #define TERMINALPREFS_RESTYPE 'TeR2' #define TERMINALPREFS_APPID 1991 // The "" terminal seed copy // Name of each instance is the resource name. Resource type SeSn typedef struct { short version; // Version of this structure short port, // Port to connect to tektype, // -1 = inhibit, 0 = 4014, 1 = 4105 pastemethod, // 0 = quick, 1 = block pasteblocksize; // Size of blocks to paste if using block mode unsigned long ip_address; // IP address of the host Boolean forcesave, // crmap, // Strange Bezerkley 4.3 CR mode needed linemode, // Allow linemode to be used showlowlevelerrors, // Not Used anymore tekclear, // Clear TEK window vs. create new one halfdup; // Half duplex required char bksp, // 0 DELETE = BKSP, 1 DELETE = DELETE ckey, skey, qkey; Str32 TerminalEmulation, // Name of terminal emulator to use TranslationTable; // Name of translation table to use by default Str63 hostname; // The DNS name of the host Boolean authenticate, // Kerberos authentication encrypt, // Encrypted session localecho, // Force local echo on? reserved1; // Reserved by JMB - NCSA short NetBlockSize, // Size of read buffer (2.7 CCP) portNegative, // Port number is negative (force use of initial Telnet codes) // (RAB BetterTelnet 1.0fc4) alwaysBSD, // always use BSD 4.3 CR mode, even on non-port-23 // (RAB BetterTelnet 1.0fc4) ignoreBeeps, // Ignore Beeps (RAB BetterTelnet 1.0fc7) ignoreff, // Ignore Form Feeds (RAB BetterTelnet 1.0fc8) otpauto, // Automatic OTP - RAB BetterTelnet 1.2 otpmulti, // RAB BetterTelnet 1.2 otpnoprompt, // RAB BetterTelnet 1.2 otphex; // RAB BetterTelnet 1.2 char otppassword[64]; // RAB BetterTelnet 1.2 short otpsavepass; // RAB BetterTelnet 1.2.1 // Now we bring you a whole bunch of NEW stuff for BetterTelnet 2.0b2... (RAB) char username[256], password[256], clientuser[256], command[256]; short protocol; // Telnet = 0, rlogin = 1, rsh = 2, rexec = 3, ssh = 4, raw TCP = 5 short encryption; // for SSH: 3DES = 0, DES = 1, Blowfish = 2, IDEA = 3, none = 4 // and now for BetterTelnet 2.0fc1 (SOCKS stuff)... short usesocks, // boolean - do we use SOCKS 4 for firewalling connections? socks4a, // boolean - do we use SOCKS 4a for firewalling DNS lookups? socksport; // the socks port (what else?) - default of 0 = actually 1080 char socksusername[256], // and now more gratuitous disk wastage for strings :P sockshost[256]; short padding[100]; // Disk space is cheap.... (used to be [98]) } SessionPrefs; #define SESSIONPREFS_RESTYPE 'SeSn' #define SESSIONPREFS_APPID 1991 // The "" session seed copy // Only one instance of this resource type. Resource type PrEf typedef struct { short version; // Version of this resource short CursorType, // 0 = block, 1 = underscore, 2 = vertical line CopyTableThresh; // Copy table threshold long TimeSlice; // Timeslice passed to WaitNextEvent ResType CaptureFileCreator; // Creator signature for session capture files Boolean WindowsDontGoAway, // Connection's windows remain open after connection close StaggerWindows, // Stagger connection windows CommandKeys, // Use command key shortcuts for menus RemapTilde, // Remap ~ to escape BlinkCursor, // Blink the cursor KeyPadAndFuncMenus; // Show Keypad and Function key menus short OpenTimeout, // Time to Open Connections in seconds (CCP 2.7) SendTimeout, // Time to Send Data (and receive ACK) (CCP 2.7) StaggerWindowsOffset, // Allow user to specify how much windows are staggered NotifyUser, destroyKTickets, //destroy kerberos tickets when window closes autoOpenDialog, dontWarnOnQuit, autoOpenDefault, parseAliases, monospacedOut, clipTrailingSpaces, defaultBoldColor, globalSavePass, noLiveScrolling; short padding[100]; // Memory is getting cheap too.... (used to be [96]) } ApplicationPrefs; #define APPLICATIONPREFS_RESTYPE 'PrEf' #define APPLICATIONPREFS_ID 1991 #define APPLICATIONPREFS_APPID 1990 extern ApplicationPrefs *gApplicationPrefs; // Only one instance of this structure. Resource FTPs typedef struct { short version; // Version of this resource short ServerState; // 0 = off, 1 = no protection, 2 = password protection OSType BinaryCreator, // Default creator for files transferred in binary mode BinaryType, // Default type for files transferred in binary mode TextCreator; // Default creator for file transferred in ASCII mode Boolean ShowFTPlog, // FTP log defaults to visible DNSlookupconnections, // Translate IP of connecting hosts to DNS names for log UseMacBinaryII, // Allow MacBinary II unused1, // Unused unused2, // Unused ResetMacBinary, // Reset MacBinary after each transfer DoISOtranslation; // Use ISO translation short padding[100]; } FTPServerPrefs; #define FTPSERVERPREFS_RESTYPE 'FTPs' #define FTPSERVERPREFS_ID 1991 #define FTPSERVERPREFS_APPID 1990 extern FTPServerPrefs *gFTPServerPrefs; // Username is the resource name. Resource type FTPu typedef struct { short version; // Version of this resource Str32 EncryptedPassword, // Encrypted form of user's password DefaultDirVolName; // Name of the volume containing user's default directory long DefaultDirDirID; // DirID of the user's default directory Boolean UserCanCWD; // User is allowed to change directories short padding[20]; // Some padding for the future } FTPUser; #define FTPUSER 'FTPu' // >>>> FTP Client Prefs? <<< typedef struct { TerminalPrefs **terminal; SessionPrefs **session; Str255 WindowName; short ftpstate; Rect WindowLocation; NewMacroInfo sessmacros; } ConnInitParams; \ No newline at end of file diff --git a/source/Headers/TelnetHeader.pch b/source/Headers/TelnetHeader.pch index ee0da7f..77a84f9 100755 --- a/source/Headers/TelnetHeader.pch +++ b/source/Headers/TelnetHeader.pch @@ -1 +1 @@ -/*TelnetHeader.pch*/ #ifdef __cplusplus #ifdef powerc #pragma precompile_target "TelnetHeaderPPC++" #else #pragma precompile_target "TelnetHeader68K++" #endif #else #ifdef powerc #pragma precompile_target "TelnetHeaderPPC" #else #pragma precompile_target "TelnetHeader68K" #endif #endif #include "MacHeaders.c" #include "Palettes.h" #include "TelnetHeader.h" #include "dialog_resrcdefs.h" #include "general_resrcdefs.h" #include "menu_resrcdefs.h" #include "string_resrcdefs.h" #include "debug.h" #include "memory.proto.h" #include #include #include #include \ No newline at end of file +// BetterTelnet // BEFORE YOU COMPILE... // If you are using CW10 or CW11, don't change a thing. It will compile right out of the box. // If you are using CWPro1, you will only need to change the libraries. (see below) // NOTICE: As of BetterTelnet 2.0fc1, OLDROUTINENAMES is now globally #defined as 0. // This means that you MUST use the new routine names. // If you are using CWPro2, CWPro3 or later, uncomment the line below //#define BT_CWPRO2 1 // If you are using CWPro(1|2|3) or later, you will have to remove the ANSI library from the // Libraries segment and add the MSL (Metrowerks Standard Library) instead. See the // conversion notes for extra info. // If you are using a CodeWarrior version PRIOR to CW10, compilation is not guaranteed, // but it might work. You may need to roll your own project file to do this. // If you are using MPW or (God forbid) Symantec C++, major changes may be needed. You can // ask me (Rolf) for compile help, but I can't guarantee that I'll be able to provide you // with any. If you are using the latest MPW, I'd advise #defining BT_CWPRO2 1 since that // makes BT do what the newer Universal Headers expect. // That's it. Report compile errors to the author. #ifdef __cplusplus #ifdef powerc #pragma precompile_target "TelnetHeaderPPC++" #else #pragma precompile_target "TelnetHeader68K++" #endif #else #ifdef powerc #pragma precompile_target "TelnetHeaderPPC" #else #pragma precompile_target "TelnetHeader68K" #endif #endif #include #ifdef OLDROUTINENAMES #undef OLDROUTINENAMES #endif #define OLDROUTINENAMES 0 #ifdef BT_CWPRO2 #define DELAYLONG unsigned long #else #define DELAYLONG long #endif #include "MacHeaders.c" #include "Palettes.h" #include "TelnetHeader.h" #include "dialog_resrcdefs.h" #include "general_resrcdefs.h" #include "menu_resrcdefs.h" #include "string_resrcdefs.h" #include "debug.h" #include "memory.proto.h" #include #include #include #include enum { inLabel = 1, inMenu = 2, inTriangle = 4, inButton = 10, inCheckBox = 11, inUpButton = 20, inDownButton = 21, inPageUp = 22, inPageDown = 23, inThumb = 129 }; \ No newline at end of file diff --git a/source/Headers/globaldefs.h b/source/Headers/globaldefs.h index 2e1a6ad..468dc51 100755 --- a/source/Headers/globaldefs.h +++ b/source/Headers/globaldefs.h @@ -1 +1 @@ -/* * globaldefs.h * Defines we only want to define once... * ***************************************************************************** * NCSA Telnet for the Macintosh * * * * National Center for Supercomputing Applications * * 152 Computing Applications Building * * 605 E. Springfield Ave. * * Champaign, IL 61820 * * * * Copyright (c) 1992, Board of Trustees of the University of Illinois * * * ***************************************************************************** * Revisions: * 7/92 Telnet 2.6: Initial version. Jim Browne */ /* Operation Governing Defines: */ #define MaxSess 20 /* The maximum number of sessions */ #define MaxGraph 30 /* Maximum number of graphics */ #define NPORTS 30 #define MAXVG 20 /* maximum number of VG windows */ #define NEVENTS 50 /* The two TEK devices (window and picture) */ #define TEK_DEVICE_WINDOW 0 #define TEK_DEVICE_PICTURE 1 /* Possible values for windowKind */ #define WIN_MODELESS userKind+1 // Modeless windows #define WIN_CONSOLE userKind+2 // Console window #define WIN_LOG userKind+3 // FTP log window #define WIN_CNXN userKind+4 // Connections #define WIN_TEK userKind+5 // TEK windows #define WIN_ICRG userKind+6 // Interactive Color Raster Graphics windows /* Emulation type defines */ #define VTEKTYPE 1 #define TEKTYPE 2 #define DUMBTYPE 3 #define RASTYPE 4 /* Font Height and width constants */ #define DefFONT 4 #define DefSIZE 9 /* ASCII character set defines */ #define ESC 0x1b /* the escape character */ #define BS 0x08 /* the backspace character */ #define DEL 0x7f /* the delete character */ #define CR 0x0d /* the carriage return character */ #define LF 0x0a /* the line feed character */ /* Now for some event stuff */ #define BScode 51 /* This is the Keycode for Backspace */ #define KPlowest 65 /* This is the last code before the KP */ #define switchEvt 1 /* Switching event (suspend/resume ) for app4evt */ /* These next three keep track of the screen windows */ #define NO_WINDOW 0 #define DEC_WINDOW 1 #define TEK_WINDOW 2 #define NUMCURS 7 #define gincurs 0 #define xfercurs 1 #define normcurs 2 #define textcurs 3 #define poscurs 4 #define watchcurs 5 #define graphcurs 6 #define kInFront (WindowPtr) -1 /* ===================================================================================*/ struct TelInfoRec { short setdir, SettingsFile, /* The Resource Reference Number of the Settings file */ ApplicationFile, // The Resource Reference Number of the Application file MacBinary, // Alternate instance that can allow us to change MB state w/o // changing the actual preference value ScrlLock, /* Are we in network suspend mode */ ftplogon, /* Is ftp log visible (default no) */ done, /* Are we done yet 0=not */ numwindows, /* Number of active window structures (note: not windows ) */ ginon, /* True if we are in GIN mode */ xferon, /* Is a transfer in progress */ graphs, /* How many detached graphs do we have */ debug, /* Flag for debugging 1=active */ myfronttype, /* what kinda window is the front one */ suspended, //are we backgrounded isQuerty, //do we have a querty layout gotDocument, startedTCP, lastPanelSession, lastPanelTerminal; DialogPtr macrosModeless, // RAB BetterTelnet 1.2 - modeless Set Macros dialog ipModeless; // RAB BetterTelnet 1.2 - modeless Show IP Address box char otpword[64]; short CONFstate, /* ...for parsing config files */ CONFactive, position, /* the next three are state variables for config.tel parsing */ inquote, lineno; /* state vars */ long oldgraph[MaxGraph], /* Storage for old Graph numbers */ myfrontvs, /* what is the VS # of the window */ blinktime; Rect screenRect, /* The whole screen */ dragRect; /* Where it is legal to drag ourselves */ RgnHandle greyRegion; //all monitors together WindowPeek myfrontwindow; /* window pointer for changing the pointer */ RgnHandle myfrontRgn; /* Handle to the region of the window to scope for stuff */ Cursor *lastCursor; FSSpec ApFolder, SysFolder, PrefFolder; short DefaultDirVRefNum, FTPClientVRefNum; long DefaultDirDirID, FTPClientDirID; PaletteHandle AnsiColors; //The Global ANSI Color palette Boolean haveColorQuickDraw; }; typedef struct TelInfoRec TelInfoRec; #ifndef GLOBALMASTER extern TelInfoRec *TelInfo; /* all the globals related to Telnet internals */ #endif \ No newline at end of file +/* * globaldefs.h * Defines we only want to define once... * ***************************************************************************** * NCSA Telnet for the Macintosh * * * * National Center for Supercomputing Applications * * 152 Computing Applications Building * * 605 E. Springfield Ave. * * Champaign, IL 61820 * * * * Copyright (c) 1992, Board of Trustees of the University of Illinois * * * ***************************************************************************** * Revisions: * 7/92 Telnet 2.6: Initial version. Jim Browne */ /* Operation Governing Defines: */ #define MaxSess 20 /* The maximum number of sessions */ #define MaxGraph 30 /* Maximum number of graphics */ #define NPORTS 30 #define MAXVG 20 /* maximum number of VG windows */ #define NEVENTS 50 /* The two TEK devices (window and picture) */ #define TEK_DEVICE_WINDOW 0 #define TEK_DEVICE_PICTURE 1 /* Possible values for windowKind */ #define WIN_MODELESS userKind+1 // Modeless windows #define WIN_CONSOLE userKind+2 // Console window #define WIN_LOG userKind+3 // FTP log window #define WIN_CNXN userKind+4 // Connections #define WIN_TEK userKind+5 // TEK windows #define WIN_ICRG userKind+6 // Interactive Color Raster Graphics windows /* Emulation type defines */ #define VTEKTYPE 1 #define TEKTYPE 2 #define DUMBTYPE 3 #define RASTYPE 4 /* Font Height and width constants */ #define DefFONT 4 #define DefSIZE 9 /* ASCII character set defines */ #define ESC 0x1b /* the escape character */ #define BS 0x08 /* the backspace character */ #define DEL 0x7f /* the delete character */ #define CR 0x0d /* the carriage return character */ #define LF 0x0a /* the line feed character */ /* Now for some event stuff */ #define BScode 51 /* This is the Keycode for Backspace */ #define KPlowest 65 /* This is the last code before the KP */ #define switchEvt 1 /* Switching event (suspend/resume ) for app4evt */ /* These next three keep track of the screen windows */ #define NO_WINDOW 0 #define DEC_WINDOW 1 #define TEK_WINDOW 2 #define NUMCURS 7 #define gincurs 0 #define xfercurs 1 #define normcurs 2 #define textcurs 3 #define poscurs 4 #define watchcurs 5 #define graphcurs 6 #define kInFront (WindowPtr) -1 typedef struct NewMacroInfo { short index[110]; char *macros, **handle; } NewMacroInfo; /* ===================================================================================*/ struct TelInfoRec { short setdir, SettingsFile, /* The Resource Reference Number of the Settings file */ ApplicationFile, // The Resource Reference Number of the Application file MacBinary, // Alternate instance that can allow us to change MB state w/o // changing the actual preference value ScrlLock, /* Are we in network suspend mode */ ftplogon, /* Is ftp log visible (default no) */ done, /* Are we done yet 0=not */ numwindows, /* Number of active window structures (note: not windows ) */ ginon, /* True if we are in GIN mode */ xferon, /* Is a transfer in progress */ graphs, /* How many detached graphs do we have */ debug, /* Flag for debugging 1=active */ myfronttype, /* what kinda window is the front one */ suspended, //are we backgrounded isQuerty, //do we have a querty layout gotDocument, startedTCP, lastPanelSession, lastPanelTerminal; DialogPtr macrosModeless, // RAB BetterTelnet 1.2 - modeless Set Macros dialog ipModeless; // RAB BetterTelnet 1.2 - modeless Show IP Address box char otpword[64]; short CONFstate, /* ...for parsing config files */ CONFactive, position, /* the next three are state variables for config.tel parsing */ inquote, lineno; /* state vars */ short checkedFontNum, checkedBoldFontNum; long oldgraph[MaxGraph], /* Storage for old Graph numbers */ myfrontvs, /* what is the VS # of the window */ blinktime; Rect screenRect, /* The whole screen */ dragRect; /* Where it is legal to drag ourselves */ RgnHandle greyRegion; //all monitors together WindowPeek myfrontwindow; /* window pointer for changing the pointer */ RgnHandle myfrontRgn; /* Handle to the region of the window to scope for stuff */ Cursor *lastCursor; FSSpec ApFolder, SysFolder, PrefFolder; short DefaultDirVRefNum, FTPClientVRefNum; long DefaultDirDirID, FTPClientDirID; PaletteHandle AnsiColors; //The Global ANSI Color palette Boolean haveColorQuickDraw; NewMacroInfo newMacros; }; typedef struct TelInfoRec TelInfoRec; #ifndef GLOBALMASTER extern TelInfoRec *TelInfo; /* all the globals related to Telnet internals */ #endif \ No newline at end of file diff --git a/source/Headers/menu_resrcdefs.h b/source/Headers/menu_resrcdefs.h index 1768665..0950016 100755 --- a/source/Headers/menu_resrcdefs.h +++ b/source/Headers/menu_resrcdefs.h @@ -1 +1 @@ -/*================================================================================*/ /* Defines for the Menu related resources */ #define NMENUS 14 /* We have NMENUS menus right now */ #define appleMenu 1 /* Apple Menu ID */ #define NfileMenu 512 /* File Menu Resource ID */ #define NeditMenu 513 /* Edit Menu Resource ID */ #define NtermMenu 514 /* Emulation Menu Resource ID */ #define NconnMenu 515 /* Connection Menu Resource ID */ #define NnetMenu 516 /* Network Menu Resource ID */ #define fileMenu 256 /* File Menu ID */ #define editMenu 257 /* Edit Menu ID */ #define termMenu 258 /* Emulation Menu ID */ #define connMenu 259 /* Connection Menu ID */ #define netMenu 260 /* Network Menu Resource ID */ #define fontMenu 128 /* Font Menu Resource ID */ #define sizeMenu 129 /* Size Menu Resource ID */ #define opspecMenu 130 /* Open Special Sub-Menu Resource ID */ #define prefsMenu 131 /* Preferences Sub-Menu Resource ID */ #define transMenu 132 /* Translation Sub-Menu Resource ID */ #define fontMenu2 133 // Bold Font Sub-Menu: RAB BetterTelnet 1.0.1 #define keyMenu 1000 /* Baylor -- Keypad menu */ #define funcMenu 1002 /* Baylor -- Function key menu */ #define Fil 1 /* File Menu's Position */ #define Edit 2 /* Edit Menu's Position */ #define Emul 3 /* Emulation Menu's position */ #define Net 4 /* Network Menu's position */ #define Conn 5 /* Connection Menu's position */ #define Font 6 /* Font Menu's position */ #define Sizem 7 /* Size Menu's position */ #define OpSpec 8 /* Open Special Sub-Menu's position */ #define PrefsSub 9 /* Preferences Sub-Menu position */ #define National 10 /* Translation Sub-Menu's postition */ #define Keypad 11 /* Baylor -- Keypad menu's position */ #define Function 12 /* Baylor -- Function menu's position */ #define FontOther 13 // RAB BetterTelnet 1.0.1 - the bold font submenu /* ----------------- The File Menu ---------------------- */ #define FLopen 1 /* File Menu: Open Connection */ #define FLopenspec 2 /* File Menu: Open Special */ #define FLclose 3 /* File Menu: Close Connection */ #define FLload 5 /* File Menu: Load Set */ #define FLsave 6 /* File Menu: Save Set */ #define FLsavem 7 /* File Menu: Save Set with Macros */ #define FLbin 9 /* File Menu: MacBinary on */ #define FLlog 11 /* File Menu: ftp log on */ #define FLotp 12 // RAB BetterTelnet 1.2 - OTP #define FLprint 14 /* File Menu: Print Selection */ #define FLpset 15 /* File Menu: Page Setup */ #define FLselect 16 // RAB BetterTelnet 1.0fc9 - Save Selection to File #define FLupload 17 // RAB BetterTelnet 1.0fc9 - Upload File #define FLquit 19 /* File Menu: Quit */ /* ----------------- The Edit Menu ---------------------- */ #define EDundo 1 #define EDcut 3 #define EDcopy 4 /* Edit Menu: Copy */ #define EDpaste 5 /* Edit Menu: Paste */ #define EDclear 6 /* Edit Menu: Clear */ #define EDcopyt 7 /* Edit Menu: Copy Table */ #define EDretype 8 // RAB BetterTelnet 1.0fc6: retype selection #define EDmacros 10 /* Edit Menu: Macros */ #define EDprefs 11 /* Edit Menu: Preferences */ /* ----------------- The Session Menu ---------------------- */ #define EMbs 1 /* Emulation Menu: backspace */ #define EMdel 2 /* Emulation Menu: delete */ #define EMscreensize 4 /* NCSA: SB - new screen dimensions dialog */ #define EMsetup 6 /* BYU 2.4.8 - Emulation Menu: Setup keys */ #define EMfont 7 /* BYU 2.4.8 - Emulation Menu: Font */ #define EMfont2 8 // RAB BetterTelnet 1.0.1 - Bold Font submenu #define EMsize 9 /* BYU 2.4.8 - Emulation Menu: Size */ #define EMcolor 10 /* BYU 2.4.8 - Emulation Menu: Color */ #define EMAnsiColor 11 #define EMcapture 13 /* BYU 2.4.18 - Emulation Menu: Capture to file */ #define EMqprint 14 // RAB BetterTelnet 1.0fc3 - Emulation Menu: Queue Print Jobs #define EMff 15 // RAB BetterTelnet 1.0fc8 - Emulation Menu: Ignore FF #define EMecho 17 /* Emulation Menu: echo */ #define EMwrap 18 /* Emulation Menu: Wrap mode on/off */ #define EMcrmap 19 /* RAB BetterTelnet 1.0b2c2 - Emulation Menu: BSD 4.3 CR Mode */ #define EMansi 20 /* RAB BetterTelnet - Emulation Menu: ANSI color */ #define EMxterm 21 /* RAB BetterTelnet - Emulation Menu: Xterm */ #define EMeightbit 22 /* RAB BetterTelnet - Emulation Menu: 8-bit */ #define EMmapkeypad 23 /* RAB BetterTelnet - Emulation Menu: remap keypad */ #define EMarrowmap 24 /* JMB - Emulation Menu: Turn EMACS mapping off/on */ #define EMpgupdwn 25 /* JMB - Emulation Menu: Turn local PgUp/PgDwn/etc. on/off */ #define EMnational 26 /* LU */ #define EMscroll 27 /* Emulation Menu: Clear Screen Saves Lines */ #define EMreset 28 /* Emulation Menu: Reset Terminal */ #define EMjump 29 /* Emulation Menu: Jump Scroll */ #define EMpage 30 /* Emulation Menu: TEK Page command */ #define EMclear 31 /* BYU 2.4.8 - Emulation Menu: TEK Page clears screen */ #define EMmapd 32 // RAB BetterTelnet 1.0fc4: map Del to ^D #define EMbold 33 // RAB BetterTelnet 1.0fc6: allow boldfacing #define EMboldcolor 34 // RAB BetterTelnet 1.0fc6: allow color for boldfacing #define EMinverse 35 // RAB BetterTelnet 1.0fc9: use inverse for bold #define EMbeep 36 // RAB BetterTelnet 1.0fc8: ignore beeps /* ----------------- The Network Menu ---------------------- */ /* #define NEcommand 19 Emulation Menu: Command Keys */ #define NEftp 1 /* Emulation Menu: Send ftp command */ #define NEip 2 /* Emulation Menu: Send IP # */ #define NEayt 4 /* Emulation Menu: Send "Are You There" */ #define NEao 5 /* Emulation Menu: Send "Abort Output" */ #define NEinter 6 /* Emulation Menu: Send "Interrupt Process" */ #define NEec 7 /* Emulation Menu: Send "Erase Character" */ #define NEel 8 /* Emulation Menu: Send "Erase Line" */ #define NEsync 9 /* Network Menu: Send SYNC (Urgent) */ #define NEbrk 10 /* Network Menu: Send BRK (Break) */ #define NEipsync 11 // RAB BetterTelnet 1.0fc9 - IP + SYNC (RFC compliant) #define NEscroll 13 /* Network Menu: Scroll Lock */ #define NEnet 15 /* Network Menu: Show Net #'s */ /* ----------------- The Connection Menu ---------------------- */ #define COnext 1 /* Connection Menu: Next Session... */ #define COtitle 2 /* Change window title */ #define FIRST_CNXN_ITEM 4 /* The first slot for connections in the menu */ /* ----------------- The Preferences Menu --------------------- */ #define prfGlobal 1 #define prfTerm 2 #define prfSess 3 #define prfFTP 4 #define prfFTPUser 5 /* Baylor ----------------- The Keypad Menu --------------------- */ #define KPFind 1 /* Baylor -- Edit Key "Find" */ #define KPInsertHere 2 /* Baylor -- Edit Key "Insert here" */ #define KPRemove 3 /* Baylor -- Edit Key "Remove" */ #define KPSelect 4 /* Baylor -- Edit Key "Select" */ #define KPPrevScreen 5 /* Baylor -- Edit Key "Prev Screen" */ #define KPNextScreen 6 /* Baylor -- Edit Key "Next Screen" */ #define KPUp 7 /* Baylor -- Edit Key "Up arrow" */ #define KPLeft 8 /* Baylor -- Edit Key "Left arrow" */ #define KPDown 9 /* Baylor -- Edit Key "Down arrow" */ #define KPRight 10 /* Baylor -- Edit Key "Right arrow" */ #define KPPF1 11 /* Baylor -- Keypad "PF1" */ #define KPPF2 12 /* Baylor -- Keypad "PF2" */ #define KPPF3 13 /* Baylor -- Keypad "PF3" */ #define KPPF4 14 /* Baylor -- Keypad "PF4" */ #define KPKP7 15 /* Baylor -- Keypad "7" */ #define KPKP8 16 /* Baylor -- Keypad "8" */ #define KPKP9 17 /* Baylor -- Keypad "9" */ #define KPKPMinus 18 /* Baylor -- Keypad "Minus" */ #define KPKP4 19 /* Baylor -- Keypad "4" */ #define KPKP5 20 /* Baylor -- Keypad "5" */ #define KPKP6 21 /* Baylor -- Keypad "6" */ #define KPKPComma 22 /* Baylor -- Keypad "Comma" */ #define KPKP1 23 /* Baylor -- Keypad "1" */ #define KPKP2 24 /* Baylor -- Keypad "2" */ #define KPKP3 25 /* Baylor -- Keypad "3" */ #define KPKEnter 26 /* Baylor -- Keypad "Enter" */ #define KPKP0 27 /* Baylor -- Keypad "0" */ #define KPKPPeriod 28 /* Baylor -- Keypad "Period" */ /* Baylor ----------------- The Keypad Menu --------------------- */ #define FKF6 1 /* Baylor -- Function Key "F6" */ #define FKF7 2 /* Baylor -- Function Key "F7" */ #define FKF8 3 /* Baylor -- Function Key "F8" */ #define FKF9 4 /* Baylor -- Function Key "F9" */ #define FKF10 5 /* Baylor -- Function Key "F10" */ #define FKF11 6 /* Baylor -- Function Key "F11" */ #define FKF12 7 /* Baylor -- Function Key "F12" */ #define FKF13 8 /* Baylor -- Function Key "F13" */ #define FKF14 9 /* Baylor -- Function Key "F14" */ #define FKHelp 10 /* Baylor -- Function Key "Help" */ #define FKDo 11 /* Baylor -- Function Key "Do" */ #define FKF17 12 /* Baylor -- Function Key "F17" */ #define FKF18 13 /* Baylor -- Function Key "F18" */ #define FKF19 14 /* Baylor -- Function Key "F19" */ #define FKF20 15 /* Baylor -- Function Key "F20" */ \ No newline at end of file +/*================================================================================*/ /* Defines for the Menu related resources */ #define NMENUS 14 /* We have NMENUS menus right now */ #define appleMenu 1 /* Apple Menu ID */ #define NfileMenu 512 /* File Menu Resource ID */ #define NeditMenu 513 /* Edit Menu Resource ID */ #define NtermMenu 514 /* Emulation Menu Resource ID */ #define NconnMenu 515 /* Connection Menu Resource ID */ #define NnetMenu 516 /* Network Menu Resource ID */ #define fileMenu 256 /* File Menu ID */ #define editMenu 257 /* Edit Menu ID */ #define termMenu 258 /* Emulation Menu ID */ #define connMenu 259 /* Connection Menu ID */ #define netMenu 260 /* Network Menu Resource ID */ #define fontMenu 128 /* Font Menu Resource ID */ #define sizeMenu 129 /* Size Menu Resource ID */ #define opspecMenu 130 /* Open Special Sub-Menu Resource ID */ #define prefsMenu 131 /* Preferences Sub-Menu Resource ID */ #define transMenu 132 /* Translation Sub-Menu Resource ID */ #define fontMenu2 133 // Bold Font Sub-Menu: RAB BetterTelnet 1.0.1 #define keyMenu 1000 /* Baylor -- Keypad menu */ #define funcMenu 1002 /* Baylor -- Function key menu */ #define Fil 1 /* File Menu's Position */ #define Edit 2 /* Edit Menu's Position */ #define Emul 3 /* Emulation Menu's position */ #define Net 4 /* Network Menu's position */ #define Conn 5 /* Connection Menu's position */ #define Font 6 /* Font Menu's position */ #define Sizem 7 /* Size Menu's position */ #define OpSpec 8 /* Open Special Sub-Menu's position */ #define PrefsSub 9 /* Preferences Sub-Menu position */ #define National 10 /* Translation Sub-Menu's postition */ #define Keypad 11 /* Baylor -- Keypad menu's position */ #define Function 12 /* Baylor -- Function menu's position */ #define FontOther 13 // RAB BetterTelnet 1.0.1 - the bold font submenu /* ----------------- The File Menu ---------------------- */ #define FLopen 1 /* File Menu: Open Connection */ #define FLopenspec 2 /* File Menu: Open Special */ #define FLclose 3 /* File Menu: Close Connection */ #define FLload 5 /* File Menu: Load Set */ #define FLsave 6 /* File Menu: Save Set */ #define FLsavem 7 /* File Menu: Save Set with Macros */ #define FLbin 9 /* File Menu: MacBinary on */ #define FLlog 11 /* File Menu: ftp log on */ #define FLotp 12 // RAB BetterTelnet 1.2 - OTP #define FLprint 14 /* File Menu: Print Selection */ #define FLpset 15 /* File Menu: Page Setup */ #define FLselect 16 // RAB BetterTelnet 1.0fc9 - Save Selection to File #define FLupload 17 // RAB BetterTelnet 1.0fc9 - Upload File #define FLquit 19 /* File Menu: Quit */ /* ----------------- The Edit Menu ---------------------- */ #define EDundo 1 #define EDcut 3 #define EDcopy 4 /* Edit Menu: Copy */ #define EDpaste 5 /* Edit Menu: Paste */ #define EDclear 6 /* Edit Menu: Clear */ #define EDcopyt 7 /* Edit Menu: Copy Table */ #define EDretype 8 // RAB BetterTelnet 1.0fc6: retype selection #define EDmacros 10 /* Edit Menu: Macros */ #define EDprefs 11 /* Edit Menu: Preferences */ /* ----------------- The Session Menu ---------------------- */ #define EMbs 1 /* Emulation Menu: backspace */ #define EMdel 2 /* Emulation Menu: delete */ #define EMscreensize 4 /* NCSA: SB - new screen dimensions dialog */ #define EMsetup 6 /* BYU 2.4.8 - Emulation Menu: Setup keys */ #define EMfont 7 /* BYU 2.4.8 - Emulation Menu: Font */ #define EMfont2 8 // RAB BetterTelnet 1.0.1 - Bold Font submenu #define EMsize 9 /* BYU 2.4.8 - Emulation Menu: Size */ #define EMcolor 10 /* BYU 2.4.8 - Emulation Menu: Color */ #define EMAnsiColor 11 #define EMcapture 13 /* BYU 2.4.18 - Emulation Menu: Capture to file */ #define EMqprint 14 // RAB BetterTelnet 1.0fc3 - Emulation Menu: Queue Print Jobs #define EMff 15 // RAB BetterTelnet 1.0fc8 - Emulation Menu: Ignore FF #define EMsuspend 16 // RAB BetterTelnet 2.0b1 - Suspend Session #define EMclrlines 17 // RAB BetterTelnet 2.0b4 - clear saved lines #define EMecho 19 /* Emulation Menu: echo */ #define EMwrap 20 /* Emulation Menu: Wrap mode on/off */ #define EMcrmap 21 /* RAB BetterTelnet 1.0b2c2 - Emulation Menu: BSD 4.3 CR Mode */ #define EMansi 22 /* RAB BetterTelnet - Emulation Menu: ANSI color */ #define EMxterm 23 /* RAB BetterTelnet - Emulation Menu: Xterm */ #define EMeightbit 24 /* RAB BetterTelnet - Emulation Menu: 8-bit */ #define EMmapkeypad 25 /* RAB BetterTelnet - Emulation Menu: remap keypad */ #define EMarrowmap 26 /* JMB - Emulation Menu: Turn EMACS mapping off/on */ #define EMpgupdwn 27 /* JMB - Emulation Menu: Turn local PgUp/PgDwn/etc. on/off */ #define EMnational 28 /* LU */ #define EMscroll 29 /* Emulation Menu: Clear Screen Saves Lines */ #define EMreset 30 /* Emulation Menu: Reset Terminal */ #define EMjump 31 /* Emulation Menu: Jump Scroll */ #define EMpage 32 /* Emulation Menu: TEK Page command */ #define EMclear 33 /* BYU 2.4.8 - Emulation Menu: TEK Page clears screen */ #define EMmapd 34 // RAB BetterTelnet 1.0fc4: map Del to ^D #define EMbold 35 // RAB BetterTelnet 1.0fc6: allow boldfacing #define EMboldcolor 36 // RAB BetterTelnet 1.0fc6: allow color for boldfacing #define EMinverse 37 // RAB BetterTelnet 1.0fc9: use inverse for bold #define EMbeep 38 // RAB BetterTelnet 1.0fc8: ignore beeps /* ----------------- The Network Menu ---------------------- */ /* #define NEcommand 19 Emulation Menu: Command Keys */ #define NEftp 1 /* Emulation Menu: Send ftp command */ #define NEip 2 /* Emulation Menu: Send IP # */ #define NEayt 4 /* Emulation Menu: Send "Are You There" */ #define NEao 5 /* Emulation Menu: Send "Abort Output" */ #define NEinter 6 /* Emulation Menu: Send "Interrupt Process" */ #define NEec 7 /* Emulation Menu: Send "Erase Character" */ #define NEel 8 /* Emulation Menu: Send "Erase Line" */ #define NEsync 9 /* Network Menu: Send SYNC (Urgent) */ #define NEbrk 10 /* Network Menu: Send BRK (Break) */ #define NEipsync 11 // RAB BetterTelnet 1.0fc9 - IP + SYNC (RFC compliant) #define NEeof 12 // RAB BetterTelnet 2.0b1 - End of File #define NEsusp 13 // RAB BetterTelnet 2.0b1 - SUSPend Process #define NEabort 14 // RAB BetterTelnet 2.0b1 - Abort #define NEscroll 16 /* Network Menu: Scroll Lock */ #define NEnet 18 /* Network Menu: Show Net #'s */ /* ----------------- The Connection Menu ---------------------- */ #define COnext 1 /* Connection Menu: Next Session... */ #define COtitle 2 /* Change window title */ #define FIRST_CNXN_ITEM 4 /* The first slot for connections in the menu */ /* ----------------- The Preferences Menu --------------------- */ #define prfGlobal 1 #define prfTerm 2 #define prfSess 3 #define prfFTP 4 #define prfFTPUser 5 /* Baylor ----------------- The Keypad Menu --------------------- */ #define KPFind 1 /* Baylor -- Edit Key "Find" */ #define KPInsertHere 2 /* Baylor -- Edit Key "Insert here" */ #define KPRemove 3 /* Baylor -- Edit Key "Remove" */ #define KPSelect 4 /* Baylor -- Edit Key "Select" */ #define KPPrevScreen 5 /* Baylor -- Edit Key "Prev Screen" */ #define KPNextScreen 6 /* Baylor -- Edit Key "Next Screen" */ #define KPUp 7 /* Baylor -- Edit Key "Up arrow" */ #define KPLeft 8 /* Baylor -- Edit Key "Left arrow" */ #define KPDown 9 /* Baylor -- Edit Key "Down arrow" */ #define KPRight 10 /* Baylor -- Edit Key "Right arrow" */ #define KPPF1 11 /* Baylor -- Keypad "PF1" */ #define KPPF2 12 /* Baylor -- Keypad "PF2" */ #define KPPF3 13 /* Baylor -- Keypad "PF3" */ #define KPPF4 14 /* Baylor -- Keypad "PF4" */ #define KPKP7 15 /* Baylor -- Keypad "7" */ #define KPKP8 16 /* Baylor -- Keypad "8" */ #define KPKP9 17 /* Baylor -- Keypad "9" */ #define KPKPMinus 18 /* Baylor -- Keypad "Minus" */ #define KPKP4 19 /* Baylor -- Keypad "4" */ #define KPKP5 20 /* Baylor -- Keypad "5" */ #define KPKP6 21 /* Baylor -- Keypad "6" */ #define KPKPComma 22 /* Baylor -- Keypad "Comma" */ #define KPKP1 23 /* Baylor -- Keypad "1" */ #define KPKP2 24 /* Baylor -- Keypad "2" */ #define KPKP3 25 /* Baylor -- Keypad "3" */ #define KPKEnter 26 /* Baylor -- Keypad "Enter" */ #define KPKP0 27 /* Baylor -- Keypad "0" */ #define KPKPPeriod 28 /* Baylor -- Keypad "Period" */ /* Baylor ----------------- The Keypad Menu --------------------- */ #define FKF6 1 /* Baylor -- Function Key "F6" */ #define FKF7 2 /* Baylor -- Function Key "F7" */ #define FKF8 3 /* Baylor -- Function Key "F8" */ #define FKF9 4 /* Baylor -- Function Key "F9" */ #define FKF10 5 /* Baylor -- Function Key "F10" */ #define FKF11 6 /* Baylor -- Function Key "F11" */ #define FKF12 7 /* Baylor -- Function Key "F12" */ #define FKF13 8 /* Baylor -- Function Key "F13" */ #define FKF14 9 /* Baylor -- Function Key "F14" */ #define FKHelp 10 /* Baylor -- Function Key "Help" */ #define FKDo 11 /* Baylor -- Function Key "Do" */ #define FKF17 12 /* Baylor -- Function Key "F17" */ #define FKF18 13 /* Baylor -- Function Key "F18" */ #define FKF19 14 /* Baylor -- Function Key "F19" */ #define FKF20 15 /* Baylor -- Function Key "F20" */ \ No newline at end of file diff --git a/source/ICR/vdevice.c b/source/ICR/vdevice.c index adc926a..39c60ff 100755 --- a/source/ICR/vdevice.c +++ b/source/ICR/vdevice.c @@ -1 +1 @@ -// vdevice.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "vdevice.h" #include "vdevice.proto.h" #define PIXEL_DEPTH 8 CGrafPtr origPort; GDHandle origDev; int InitVDevice (VDevicePtr whichDevice, PaletteHandle initalPalette) { PixMapHandle thePixMap; OSErr err; CTabHandle theNewColorTable; GetGWorld(&origPort,&origDev); //save old settings //first, copy the initalPalette into a color table handle theNewColorTable = (CTabHandle) myNewHandle(sizeof(ColorTable)); if (!theNewColorTable) return -1; Palette2CTab(initalPalette,theNewColorTable); //init the GWorld err = NewGWorld(&whichDevice->whichWorld,PIXEL_DEPTH,whichDevice->bounds, theNewColorTable,NULL,0); if ((!whichDevice->whichWorld)||(err != noErr)) { if (whichDevice->whichWorld) DisposeGWorld(whichDevice->whichWorld); DisposeHandle((Handle)theNewColorTable); return -1; } SetGWorld(whichDevice->whichWorld,NULL); thePixMap = GetGWorldPixMap(whichDevice->whichWorld); EraseRect(&(whichDevice->whichWorld->portRect)); SetGWorld(origPort,origDev); return (0); } void ColorVDevice ( VDevicePtr vdev, PaletteHandle pal ) { CTabHandle ct; ct = (*vdev->whichWorld->portPixMap)->pmTable; /* handle from vdevice */ if (!ct) return; Palette2CTab( pal, ct ); (*ct)->ctSeed = GetCTSeed(); /* give it a unique seed */ (*ct)->ctFlags = 0x8000; //MakeITable( ct, (vdev->whichWorld->gdITable, 3 ); /* 3-bit inverse table */ } /*******************************************************************************/ /* SetVDevice * Set the gdevice and port to our off-screen space. * Save the old values for unset. */ SetVDevice(VDevicePtr vdev) { GetGWorld(&origPort,&origDev); //save old settings if (!vdev->whichWorld) return(-1); SetGWorld(vdev->whichWorld,NULL); return(0); } /*******************************************************************************/ /* UnsetVDevice * Set the vdevice back to the saved values. */ void UnsetVDevice(void) { SetGWorld(origPort,origDev); } /*******************************************************************************/ /* TrashVDevice * Get rid of the devices that we created with InitVDevice. */ void TrashVDevice(VDevicePtr vdev) { if (vdev->whichWorld) DisposeGWorld(vdev->whichWorld); return; } \ No newline at end of file +// vdevice.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "vdevice.h" #include "vdevice.proto.h" #define PIXEL_DEPTH 8 CGrafPtr origPort; GDHandle origDev; int InitVDevice (VDevicePtr whichDevice, PaletteHandle initalPalette) { PixMapHandle thePixMap; OSErr err; CTabHandle theNewColorTable; GetGWorld(&origPort,&origDev); //save old settings //first, copy the initalPalette into a color table handle theNewColorTable = (CTabHandle) myNewHandle(sizeof(ColorTable)); if (!theNewColorTable) return -1; Palette2CTab(initalPalette,theNewColorTable); //init the GWorld err = NewGWorld(&whichDevice->whichWorld,PIXEL_DEPTH,whichDevice->bounds, theNewColorTable,NULL,0); if ((!whichDevice->whichWorld)||(err != noErr)) { if (whichDevice->whichWorld) DisposeGWorld(whichDevice->whichWorld); DisposeHandle((Handle)theNewColorTable); return -1; } SetGWorld(whichDevice->whichWorld,NULL); thePixMap = GetGWorldPixMap(whichDevice->whichWorld); EraseRect(&(whichDevice->whichWorld->portRect)); SetGWorld(origPort,origDev); return (0); } void ColorVDevice ( VDevicePtr vdev, PaletteHandle pal ) { CTabHandle ct; ct = (*vdev->whichWorld->portPixMap)->pmTable; /* handle from vdevice */ if (!ct) return; Palette2CTab( pal, ct ); (*ct)->ctSeed = GetCTSeed(); /* give it a unique seed */ (*ct)->ctFlags = 0x8000; //MakeITable( ct, (vdev->whichWorld->gdITable, 3 ); /* 3-bit inverse table */ } /*******************************************************************************/ /* SetVDevice * Set the gdevice and port to our off-screen space. * Save the old values for unset. */ SetVDevice(VDevicePtr vdev) { GetGWorld(&origPort,&origDev); //save old settings if (!vdev->whichWorld) return(-1); SetGWorld(vdev->whichWorld,NULL); return(0); } /*******************************************************************************/ /* UnsetVDevice * Set the vdevice back to the saved values. */ void UnsetVDevice(void) { SetGWorld(origPort,origDev); } /*******************************************************************************/ /* TrashVDevice * Get rid of the devices that we created with InitVDevice. */ void TrashVDevice(VDevicePtr vdev) { if (vdev->whichWorld) DisposeGWorld(vdev->whichWorld); return; } \ No newline at end of file diff --git a/source/ICR/vr.c b/source/ICR/vr.c index c864cfd..199b196 100755 --- a/source/ICR/vr.c +++ b/source/ICR/vr.c @@ -1 +1 @@ -/* ** Raster Virtual Kernel (vr.c) */ // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #ifdef MPW #pragma segment ICR #endif #define MASTERDEF #include "vr.h" #include "vr.proto.h" #include "vrrgmac.proto.h" /* defines for raster states and variables */ /* states */ #define DONE 0 /* we've been called */ #define ESCFOUND 1 /* found escape */ #define WANTCMD 2 /* want a command char */ #define WANTDEL 3 /* want that first delimiter */ #define IARG 4 /* looking for integer arg */ #define SARG 5 /* looking for string arg */ #define CARG 6 /* looking for count arg */ #define DATA 7 /* all args parsed, found ^ */ /* commands */ #define ESC 0x1b /* start of a sequence */ #define ESCCMD ' ' /* escape to next level of commands */ #define DELIM ';' /* argument delimiter */ #define CMDTRM '^' /* terminator, but also prefix w/ ESC */ #define WINCMD 'W' /* create a window */ #define DESCMD 'D' /* destroy a window */ #define MAPCMD 'M' /* change color map entries */ #define RLECMD 'R' /* run-length encoded data */ #define PIXCMD 'P' /* standard pixel data */ #define IMPCMD 'I' /* IMCOMP compressed data */ #define FILCMD 'F' /* save to file command */ #define CLKCMD 'C' /* click the slide camera */ #define SAVCMD 'S' /* save a color map to a file */ /* command parameter types*/ #define MAXARGS 7 /* maximum args to a command */ #define INT 1 /* integer argument */ #define STRING 2 /* string (character) argument */ #define COUNT 3 /* data count argument */ #define LINEMAX 1024 /* longest width for window */ /* ** flag values */ #define FL_NORMAL 1 /* command needs no data */ #define FL_DATA 2 /* command takes data */ /* ** structure of command table */ struct cmd { char c_name; short c_flags; short (*c_func)(union arg av[], char *); short c_args[MAXARGS]; }; static struct cmd cmdtab[] = { WINCMD, FL_NORMAL, VRwindow, {INT, INT, INT, INT, INT, STRING, 0}, DESCMD, FL_NORMAL, VRdestroy, {STRING, 0, 0, 0, 0, 0, 0}, MAPCMD, FL_DATA, VRmap, {INT, INT, COUNT, STRING, 0, 0, 0}, FILCMD, FL_NORMAL, VRfile, {INT, INT, INT, INT, INT, STRING, STRING}, PIXCMD, FL_DATA, VRpixel, {INT, INT, INT, COUNT, STRING, 0, 0}, RLECMD, FL_DATA, VRrle, {INT, INT, INT, COUNT, STRING, 0, 0}, IMPCMD, FL_DATA, VRimp, {INT, INT, INT, COUNT, STRING, 0, 0}, CLKCMD, FL_NORMAL, VRclick, {STRING, 0, 0, 0, 0, 0, 0}, SAVCMD, FL_NORMAL, VRmsave, {STRING, STRING, 0, 0, 0, 0, 0} }; #define NCMDS (sizeof(cmdtab) / sizeof(struct cmd)) /* ** global vars */ static short VRstate = DONE; /* current state */ static short VRcmdnum = -1; /* current command */ static short VRargcount = 0; /* number of args for command */ static short VRdatalen = 0; /* length of expected data */ static short VRbufpos = 0; /* current pointer in tempdata */ static union arg VRargs[MAXARGS]; /* argument vector */ static char VRtempdata[256]; /* temporary storage while parsing */ static char *VRspace; /* storage for incoming data */ static char *VRsp2; /* storage for pixel expansion */ static char *VRptr; /* pointer for data buffer */ static char *VRptr2; /* copy of above */ /***********************************************************************/ /* decode0 and decode1 * start and continue the decoding. * * Returns real characters, 0 if in the middle of an escape sequence. */ #define FRSKIP 0 #define FRIN 1 #define FRSPECIAL 2 #define FROVER 3 #define FRDONE 4 void ICRunload(void) {} static short VRnextargstate(short ac, short c); /* ** VRinit -- initialize the VR system ** ** Arguments: ** ** None. ** ** Returns: ** ** short -- status, 1 == succsessful, 0 == failed */ short VRinit( void) { VRhead.w_next = NULL; VRsp2 = (char *)myNewPtr(4*LINEMAX+10); VRspace = (char *)myNewPtr(LINEMAX+10); if (VRspace) return 1; else return 0; } /* ** VRwrite -- parse a string of VR commands ** ** Arguments: ** ** char *b; -- buffer pointer ** short len; -- buffer length ** ** Returns: ** ** short -- Number of characters processed. 0 tells ** -- the upper level to switch out of raster mode; ** -- usually on error, but also at completion of ** -- command processing. ** */ short VRwrite( char *b, short len) { short count = 0; char *p = b; char c; short i; /* loop 'til no more chars */ while (count < len) { c = *p; switch (VRstate) { case DONE: if (c == ESC) VRstate = ESCFOUND; else return count; break; case ESCFOUND: if (c == CMDTRM) VRstate = WANTCMD; else { VRstate = DONE; return count; } break; /* looking for a valid command char */ case WANTCMD: for (i = 0; i < NCMDS; i++) { if (cmdtab[i].c_name == c) break; } VRcmdnum = i; if (VRcmdnum == NCMDS) { VRstate = DONE; return 0; } /* set up for this command */ VRargcount = 0; VRbufpos = 0; VRstate = WANTDEL; break; /* look for that first ; */ case WANTDEL: if (c == DELIM) VRstate = VRnextargstate(VRargcount, VRcmdnum); else VRstate = DONE; break; /* looking for an integer arg */ case IARG: switch (c) { /* we've found the end of the argument, so try to put into the vector for later use */ case DELIM: case CMDTRM: VRtempdata[VRbufpos] = '\0'; /* copy into argument union */ (void)sscanf(VRtempdata,"%d",&VRargs[VRargcount].a_num); VRbufpos = 0; VRargcount++; if (c == DELIM) VRstate = VRnextargstate(VRargcount, VRcmdnum); else if (cmdtab[VRcmdnum].c_flags & FL_DATA) VRstate = DATA; else { /* run the command */ (*cmdtab[VRcmdnum].c_func)(VRargs, (char *)0L); VRstate = DONE; } break; /* copy over characters for later */ default: VRtempdata[VRbufpos++] = c; } break; /* looking for string arg */ case SARG: switch (c) { /* put string into argument vector */ case DELIM: case CMDTRM: VRtempdata[VRbufpos] = '\0'; /* VRargs[VRargcount].a_ptr = myNewPtr((unsigned)VRbufpos+1); if (VRargs[VRargcount].a_ptr == (char *)0L) { VRstate = DONE; break; } */ (void)strcpy(VRargs[VRargcount].a_ptr, VRtempdata); VRbufpos = 0; VRargcount++; if (c == DELIM) VRstate = VRnextargstate(VRargcount, VRcmdnum); else if (cmdtab[VRcmdnum].c_flags & FL_DATA) VRstate = DATA; else { /* run the command */ (*cmdtab[VRcmdnum].c_func)(VRargs, (char *)0L); VRstate = DONE; } break; /* save string for later */ default: VRtempdata[VRbufpos++] = c; } break; /* looking for a count argument */ case CARG: switch (c) { /* we've found the end of the argument, so try to put into the vector for later use */ case DELIM: case CMDTRM: VRtempdata[VRbufpos] = '\0'; /* copy into argument union */ (void)sscanf(VRtempdata,"%d",&VRdatalen); (void)sscanf(VRtempdata,"%d",&VRargs[VRargcount].a_num); if (VRdatalen > LINEMAX) VRdatalen = LINEMAX; VRargcount++; VRbufpos = 0; if (c == DELIM) VRstate = VRnextargstate(VRargcount, VRcmdnum); else if (cmdtab[VRcmdnum].c_flags & FL_DATA) VRstate = DATA; else { /* run the command */ (*cmdtab[VRcmdnum].c_func)(VRargs, (char *)0L); VRstate = DONE; } /* allocate storage for data */ VRptr = VRspace; if (VRptr == (char *)0L) { VRstate = DONE; return 0; } VRptr2 = VRptr; decode0(); /* reset decoder */ break; /* copy over characters for later */ default: VRtempdata[VRbufpos++] = c; } break; /* retrieve a line of data */ case DATA: /* store bytes until done */ if (0 <= (i = decode1(c))) { *VRptr2++ = i; --VRdatalen; } if (!VRdatalen) { /* we've got all of the data */ (*cmdtab[VRcmdnum].c_func)(VRargs, VRptr); VRstate = DONE; } break; } /* end switch(VRstate)*/ p++; count++; } /* end while loop */ return count; } /* ** VRnextargstate -- return the next state based on where we're ** -- at already. ** ** Arguments: ** ** short ac -- current argument count ** short state -- current state ** short c -- current command ** ** Returns: ** ** short -- next state to move to ** */ static short VRnextargstate(short ac, short c) { switch (cmdtab[c].c_args[ac]) { case INT: return IARG; case STRING: return SARG; case COUNT: return CARG; case 0: return DATA; /* in case of error*/ default: return DONE; } } /* ** VRwindow -- create a new raster window ** ** Arguments: ** ** union arg av[]; -- the argument vector ** ** short av[0, 1]; -- upper left; ** short av[2, 3]; -- width, height ** short av[4]; -- window hardware display number ** char *av[5]; -- title ** ** Returns: ** ** None. No provision has been made for error returns in any of ** these routines because I don't know what to do if an error ** occurs. Perhaps a better man than I can figure out how to ** deal with this. ** N.B -- these functions are declared as short, in the event ** that an error return is added. */ short VRwindow(union arg av[], char *unused) { UNUSED_ARG(unused) VRW *w = VRhead.w_next; short ret; /* search list, and if needed, myNewPtr some space for a new window thing */ while (w) { if (!strcmp(w->w_name,av[5].a_ptr) && w->w_width == av[2].a_num && w->w_height == av[3].a_num) /* don't re-allocate win */ return(1); if (!strcmp(w->w_name,av[5].a_ptr)) /* duplicate, different size */ w->w_used = 1; w = w->w_next; } w = (VRW *)myNewPtr(sizeof(VRW)); /* new element for list */ if (!w) return(-1); w->w_next = VRhead.w_next; /* set next equal to current head */ VRhead.w_next = w; /* set head of list equal to me */ /* ** fill in the new window area */ w->w_left = av[0].a_num; w->w_top = av[1].a_num; w->w_width = av[2].a_num; w->w_height = av[3].a_num; w->w_display = av[4].a_num; w->w_used = 0; strncpy(w->w_name,av[5].a_ptr,100); if (w->w_width > LINEMAX) /* have to be SOME limits */ w->w_width = LINEMAX; if (0 <= (ret = MacRGnewwindow( w->w_name, w->w_left, w->w_top, w->w_left+w->w_width, w->w_top+w->w_height ))) MacRGsetwindow( ret); w->w_rr.wn = ret; return(ret); } /* ** VRdestroy -- destroy a window by name ** ** Arguments: ** ** union arg av[]; -- the argument vector ** ** char *av[0] -- the name of the window ** ** Returns: ** ** None. ** */ short VRdestroy(union arg av[], char *unused) { UNUSED_ARG(unused) VRW *w,*ow; ow = &VRhead; w = ow->w_next; while (w) { if (!strcmp(w->w_name, av[0].a_ptr) ) { MacRGremove( w->w_rr.wn); ow->w_next = w->w_next; DisposPtr((char *)w); } else ow = ow->w_next; w = ow->w_next; } return 0; } void VRdestroybyName(char *name) { union arg blah; strncpy(blah.a_ptr, name, 100); VRdestroy(&blah, NULL); } /* ** VRmap -- take a color map command and set the palette ** ** Arguments: ** ** union arg av[]; -- the argument vector ** ** short av[0, 1]; -- start & length of map segment ** short av[2]; -- count of data needed (info only) ** char *av[3]; -- window name ** char *data; -- pointer to the data ** ** Returns: ** ** None. ** */ short VRmap(union arg av[], char *data) { VRW *w; w = VRlookup(av[3].a_ptr); if (!w) return 0; return MacRGmap(av[0].a_num, av[1].a_num, data); } /* ** VRpixel -- display a line of pixel data ** ** Arugments: ** ** union arg av[]; -- the argument vector ** ** short av[0]; -- x coordinate ** short av[1]; -- y coordinate ** short av[2]; -- pixel expansion factor ** short av[3]; -- length of data ** char *av[4]; -- window name ** char *data; -- pointer to data ** ** Returns: ** ** None. ** */ short VRpixel(union arg av[], char *data) { VRW *w; short i,lim; char *p,*q; /* find the right window */ w = VRlookup(av[4].a_ptr); if (w == (VRW *)0L) return 0; lim = av[3].a_num*av[2].a_num; /* total number of expanded pixels */ if (lim > w->w_width) lim = w->w_width; if (av[2].a_num > 1) { p = data; q = VRsp2; for (i=0; i < lim; i++) { *q++ = *p; if (!((i+1) % av[2].a_num)) p++; } for (i=0; iw_width); /* BYU LSC - decompress it */ /* gives four lines in the VRsp2 buffer, now pixel expand */ i = av[3].a_num; lim = i*av[2].a_num; /* total number of expanded pixels on a line*/ if (lim > w->w_width) lim = w->w_width; if (i > w->w_width) i = w->w_width; p = VRsp2; /* from this buffer */ for (j=0; j<4; j++) { if (av[2].a_num > 1) { q = VRspace; /* to here */ for (i=0; i < lim; i++) { *q++ = *p; if (!((i+1) % av[2].a_num)) p++; } p++; for (i=0; i> (3 - i)*4; for (j=x; j<(x+4); j++) { if ((temp & 8) == 8) out[i*xdim+j] = hi_color; else out[i*xdim+j] = lo_color; temp = temp << 1; } } } /* end of for x */ } /* end of unimcomp */ /* unrleit - Decompress run length encoding. */ short unrleit(unsigned char *buf, unsigned char *bufto, short inlen, short outlen) { register short cnt; register unsigned char *p,*q; unsigned char *endp,*endq; p = buf; endp = buf + inlen; q = bufto; endq = bufto + outlen; while (p < endp && q < endq) { /* go 'til p or q hits end */ cnt = *p++; /* count field */ if (!(cnt & 128)) { /* is set of uniques */ while (cnt-- && q < endq) *q++ = *p++; /* copy unmodified */ } else { cnt &= 127; /* strip high bit */ while (cnt-- && q < endq) *q++ = *p; /* copy same character */ p++; /* skip that character */ } } /* while */ return((short)(q-bufto)); } /***************************************************************************/ /* ** VRrle -- display a line of run-length encoded data ** ** Arugments: ** ** union arg av[]; -- the argument vector ** ** short av[0]; -- x coordinate ** short av[1]; -- y coordinate ** short av[2]; -- pixel expansion ** short av[3]; -- length of data ** char *av[4]; -- window name ** char *data; -- pointer to data ** ** Returns: ** ** None. ** */ short VRrle(union arg av[], char *data) { VRW *w; short i,lim; char *p,*q; /* find the right window */ w = VRlookup(av[4].a_ptr); if (w == (VRW *)0L) return 0; i = unrleit((unsigned char *) data,(unsigned char *) VRsp2,av[3].a_num,w->w_width); /* BYU LSC - decompress it */ lim = i*av[2].a_num; /* total number of expanded pixels */ if (lim > w->w_width) lim = w->w_width; if (av[2].a_num > 1) { p = VRsp2; /* from this buffer */ q = VRspace; /* to here */ for (i=0; i < lim; i++) { *q++ = *p; if (!((i+1) % av[2].a_num)) p++; } for (i=0; iw_name, name) && !w->w_used) { /* same name, not old dup */ if (w->w_rr.wn < 0) /* maybe window don't work */ return(NULL); MacRGsetwindow(w->w_rr.wn); return(w); } w = w->w_next; } return(NULL); } /* ** VRcleanup -- remove all windows from the screen ** ** Arguments: ** ** None. ** ** Returns: ** ** short; 1 -- always successful, or there's nothing you can do ** -- about it anyways... ** */ short VRcleanup(void) { VRW *w = VRhead.w_next; VRW *x; while (w != (VRW *)0L) { x = w->w_next; MacRGremove( w->w_rr.wn); w = x; } return 1; } /************************************************************************/ /* decoding * handle the special ASCII printable character encoding of data bytes. */ /***********************************************************************/ /* * 123 precedes #'s 0-63 * 124 precedes #'s 64-127 * 125 precedes #'s 128-191 * 126 precedes #'s 192-255 * overall: realchar = (specialchar - 123)*64 + (char-32) * specialchar = r div 64 + 123 * char = r mod 64 + 32 */ /***********************************************************************/ static short dstate=FRSKIP,dspec=0; /* set up receive */ void decode0(void) { dstate = FRIN; } short decode1(char c) { switch (dstate) { case FRSKIP: return(-1); case FRIN: /* decoding */ if (c > 31 && c < 123) return(c); else { dspec = c; /* save special character */ dstate = FRSPECIAL; /* doing special character */ } return(-1); case FRSPECIAL: switch (dspec) { case 123: case 124: case 125: case 126: /* encoded character */ dstate = FRIN; return(((dspec - 123)<< 6) - 32 + c); default: /* mistaken character in stream */ dstate = FRIN; /* assume not special */ return(decode1(c)); /* check for sure */ break; } break; } // switch (dstate) } \ No newline at end of file +/* ** Raster Virtual Kernel (vr.c) */ // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #define MASTERDEF #include "vr.h" #include "vr.proto.h" #include "vrrgmac.proto.h" /* defines for raster states and variables */ /* states */ #define DONE 0 /* we've been called */ #define ESCFOUND 1 /* found escape */ #define WANTCMD 2 /* want a command char */ #define WANTDEL 3 /* want that first delimiter */ #define IARG 4 /* looking for integer arg */ #define SARG 5 /* looking for string arg */ #define CARG 6 /* looking for count arg */ #define DATA 7 /* all args parsed, found ^ */ /* commands */ #define ESC 0x1b /* start of a sequence */ #define ESCCMD ' ' /* escape to next level of commands */ #define DELIM ';' /* argument delimiter */ #define CMDTRM '^' /* terminator, but also prefix w/ ESC */ #define WINCMD 'W' /* create a window */ #define DESCMD 'D' /* destroy a window */ #define MAPCMD 'M' /* change color map entries */ #define RLECMD 'R' /* run-length encoded data */ #define PIXCMD 'P' /* standard pixel data */ #define IMPCMD 'I' /* IMCOMP compressed data */ #define FILCMD 'F' /* save to file command */ #define CLKCMD 'C' /* click the slide camera */ #define SAVCMD 'S' /* save a color map to a file */ /* command parameter types*/ #define MAXARGS 7 /* maximum args to a command */ #define INT 1 /* integer argument */ #define STRING 2 /* string (character) argument */ #define COUNT 3 /* data count argument */ #define LINEMAX 1024 /* longest width for window */ /* ** flag values */ #define FL_NORMAL 1 /* command needs no data */ #define FL_DATA 2 /* command takes data */ /* ** structure of command table */ struct cmd { char c_name; short c_flags; short (*c_func)(union arg av[], char *); short c_args[MAXARGS]; }; static struct cmd cmdtab[] = { WINCMD, FL_NORMAL, VRwindow, {INT, INT, INT, INT, INT, STRING, 0}, DESCMD, FL_NORMAL, VRdestroy, {STRING, 0, 0, 0, 0, 0, 0}, MAPCMD, FL_DATA, VRmap, {INT, INT, COUNT, STRING, 0, 0, 0}, FILCMD, FL_NORMAL, VRfile, {INT, INT, INT, INT, INT, STRING, STRING}, PIXCMD, FL_DATA, VRpixel, {INT, INT, INT, COUNT, STRING, 0, 0}, RLECMD, FL_DATA, VRrle, {INT, INT, INT, COUNT, STRING, 0, 0}, IMPCMD, FL_DATA, VRimp, {INT, INT, INT, COUNT, STRING, 0, 0}, CLKCMD, FL_NORMAL, VRclick, {STRING, 0, 0, 0, 0, 0, 0}, SAVCMD, FL_NORMAL, VRmsave, {STRING, STRING, 0, 0, 0, 0, 0} }; #define NCMDS (sizeof(cmdtab) / sizeof(struct cmd)) /* ** global vars */ static short VRstate = DONE; /* current state */ static short VRcmdnum = -1; /* current command */ static short VRargcount = 0; /* number of args for command */ static short VRdatalen = 0; /* length of expected data */ static short VRbufpos = 0; /* current pointer in tempdata */ static union arg VRargs[MAXARGS]; /* argument vector */ static char VRtempdata[256]; /* temporary storage while parsing */ static char *VRspace; /* storage for incoming data */ static char *VRsp2; /* storage for pixel expansion */ static char *VRptr; /* pointer for data buffer */ static char *VRptr2; /* copy of above */ /***********************************************************************/ /* decode0 and decode1 * start and continue the decoding. * * Returns real characters, 0 if in the middle of an escape sequence. */ #define FRSKIP 0 #define FRIN 1 #define FRSPECIAL 2 #define FROVER 3 #define FRDONE 4 void ICRunload(void) {} static short VRnextargstate(short ac, short c); /* ** VRinit -- initialize the VR system ** ** Arguments: ** ** None. ** ** Returns: ** ** short -- status, 1 == succsessful, 0 == failed */ short VRinit( void) { VRhead.w_next = NULL; VRsp2 = (char *)myNewPtr(4*LINEMAX+10); VRspace = (char *)myNewPtr(LINEMAX+10); if (VRspace) return 1; else return 0; } /* ** VRwrite -- parse a string of VR commands ** ** Arguments: ** ** char *b; -- buffer pointer ** short len; -- buffer length ** ** Returns: ** ** short -- Number of characters processed. 0 tells ** -- the upper level to switch out of raster mode; ** -- usually on error, but also at completion of ** -- command processing. ** */ short VRwrite( char *b, short len) { short count = 0; char *p = b; char c; short i; /* loop 'til no more chars */ while (count < len) { c = *p; switch (VRstate) { case DONE: if (c == ESC) VRstate = ESCFOUND; else return count; break; case ESCFOUND: if (c == CMDTRM) VRstate = WANTCMD; else { VRstate = DONE; return count; } break; /* looking for a valid command char */ case WANTCMD: for (i = 0; i < NCMDS; i++) { if (cmdtab[i].c_name == c) break; } VRcmdnum = i; if (VRcmdnum == NCMDS) { VRstate = DONE; return 0; } /* set up for this command */ VRargcount = 0; VRbufpos = 0; VRstate = WANTDEL; break; /* look for that first ; */ case WANTDEL: if (c == DELIM) VRstate = VRnextargstate(VRargcount, VRcmdnum); else VRstate = DONE; break; /* looking for an integer arg */ case IARG: switch (c) { /* we've found the end of the argument, so try to put into the vector for later use */ case DELIM: case CMDTRM: VRtempdata[VRbufpos] = '\0'; /* copy into argument union */ (void)sscanf(VRtempdata,"%d",&VRargs[VRargcount].a_num); VRbufpos = 0; VRargcount++; if (c == DELIM) VRstate = VRnextargstate(VRargcount, VRcmdnum); else if (cmdtab[VRcmdnum].c_flags & FL_DATA) VRstate = DATA; else { /* run the command */ (*cmdtab[VRcmdnum].c_func)(VRargs, (char *)0L); VRstate = DONE; } break; /* copy over characters for later */ default: VRtempdata[VRbufpos++] = c; } break; /* looking for string arg */ case SARG: switch (c) { /* put string into argument vector */ case DELIM: case CMDTRM: VRtempdata[VRbufpos] = '\0'; /* VRargs[VRargcount].a_ptr = myNewPtr((unsigned)VRbufpos+1); if (VRargs[VRargcount].a_ptr == (char *)0L) { VRstate = DONE; break; } */ (void)strcpy(VRargs[VRargcount].a_ptr, VRtempdata); VRbufpos = 0; VRargcount++; if (c == DELIM) VRstate = VRnextargstate(VRargcount, VRcmdnum); else if (cmdtab[VRcmdnum].c_flags & FL_DATA) VRstate = DATA; else { /* run the command */ (*cmdtab[VRcmdnum].c_func)(VRargs, (char *)0L); VRstate = DONE; } break; /* save string for later */ default: VRtempdata[VRbufpos++] = c; } break; /* looking for a count argument */ case CARG: switch (c) { /* we've found the end of the argument, so try to put into the vector for later use */ case DELIM: case CMDTRM: VRtempdata[VRbufpos] = '\0'; /* copy into argument union */ (void)sscanf(VRtempdata,"%d",&VRdatalen); (void)sscanf(VRtempdata,"%d",&VRargs[VRargcount].a_num); if (VRdatalen > LINEMAX) VRdatalen = LINEMAX; VRargcount++; VRbufpos = 0; if (c == DELIM) VRstate = VRnextargstate(VRargcount, VRcmdnum); else if (cmdtab[VRcmdnum].c_flags & FL_DATA) VRstate = DATA; else { /* run the command */ (*cmdtab[VRcmdnum].c_func)(VRargs, (char *)0L); VRstate = DONE; } /* allocate storage for data */ VRptr = VRspace; if (VRptr == (char *)0L) { VRstate = DONE; return 0; } VRptr2 = VRptr; decode0(); /* reset decoder */ break; /* copy over characters for later */ default: VRtempdata[VRbufpos++] = c; } break; /* retrieve a line of data */ case DATA: /* store bytes until done */ if (0 <= (i = decode1(c))) { *VRptr2++ = i; --VRdatalen; } if (!VRdatalen) { /* we've got all of the data */ (*cmdtab[VRcmdnum].c_func)(VRargs, VRptr); VRstate = DONE; } break; } /* end switch(VRstate)*/ p++; count++; } /* end while loop */ return count; } /* ** VRnextargstate -- return the next state based on where we're ** -- at already. ** ** Arguments: ** ** short ac -- current argument count ** short state -- current state ** short c -- current command ** ** Returns: ** ** short -- next state to move to ** */ static short VRnextargstate(short ac, short c) { switch (cmdtab[c].c_args[ac]) { case INT: return IARG; case STRING: return SARG; case COUNT: return CARG; case 0: return DATA; /* in case of error*/ default: return DONE; } } /* ** VRwindow -- create a new raster window ** ** Arguments: ** ** union arg av[]; -- the argument vector ** ** short av[0, 1]; -- upper left; ** short av[2, 3]; -- width, height ** short av[4]; -- window hardware display number ** char *av[5]; -- title ** ** Returns: ** ** None. No provision has been made for error returns in any of ** these routines because I don't know what to do if an error ** occurs. Perhaps a better man than I can figure out how to ** deal with this. ** N.B -- these functions are declared as short, in the event ** that an error return is added. */ short VRwindow(union arg av[], char *unused) { UNUSED_ARG(unused) VRW *w = VRhead.w_next; short ret; /* search list, and if needed, myNewPtr some space for a new window thing */ while (w) { if (!strcmp(w->w_name,av[5].a_ptr) && w->w_width == av[2].a_num && w->w_height == av[3].a_num) /* don't re-allocate win */ return(1); if (!strcmp(w->w_name,av[5].a_ptr)) /* duplicate, different size */ w->w_used = 1; w = w->w_next; } w = (VRW *)myNewPtr(sizeof(VRW)); /* new element for list */ if (!w) return(-1); w->w_next = VRhead.w_next; /* set next equal to current head */ VRhead.w_next = w; /* set head of list equal to me */ /* ** fill in the new window area */ w->w_left = av[0].a_num; w->w_top = av[1].a_num; w->w_width = av[2].a_num; w->w_height = av[3].a_num; w->w_display = av[4].a_num; w->w_used = 0; strncpy(w->w_name,av[5].a_ptr,100); if (w->w_width > LINEMAX) /* have to be SOME limits */ w->w_width = LINEMAX; if (0 <= (ret = MacRGnewwindow( w->w_name, w->w_left, w->w_top, w->w_left+w->w_width, w->w_top+w->w_height ))) MacRGsetwindow( ret); w->w_rr.wn = ret; return(ret); } /* ** VRdestroy -- destroy a window by name ** ** Arguments: ** ** union arg av[]; -- the argument vector ** ** char *av[0] -- the name of the window ** ** Returns: ** ** None. ** */ short VRdestroy(union arg av[], char *unused) { UNUSED_ARG(unused) VRW *w,*ow; ow = &VRhead; w = ow->w_next; while (w) { if (!strcmp(w->w_name, av[0].a_ptr) ) { MacRGremove( w->w_rr.wn); ow->w_next = w->w_next; DisposePtr((char *)w); } else ow = ow->w_next; w = ow->w_next; } return 0; } void VRdestroybyName(char *name) { union arg blah; strncpy(blah.a_ptr, name, 100); VRdestroy(&blah, NULL); } /* ** VRmap -- take a color map command and set the palette ** ** Arguments: ** ** union arg av[]; -- the argument vector ** ** short av[0, 1]; -- start & length of map segment ** short av[2]; -- count of data needed (info only) ** char *av[3]; -- window name ** char *data; -- pointer to the data ** ** Returns: ** ** None. ** */ short VRmap(union arg av[], char *data) { VRW *w; w = VRlookup(av[3].a_ptr); if (!w) return 0; return MacRGmap(av[0].a_num, av[1].a_num, data); } /* ** VRpixel -- display a line of pixel data ** ** Arugments: ** ** union arg av[]; -- the argument vector ** ** short av[0]; -- x coordinate ** short av[1]; -- y coordinate ** short av[2]; -- pixel expansion factor ** short av[3]; -- length of data ** char *av[4]; -- window name ** char *data; -- pointer to data ** ** Returns: ** ** None. ** */ short VRpixel(union arg av[], char *data) { VRW *w; short i,lim; char *p,*q; /* find the right window */ w = VRlookup(av[4].a_ptr); if (w == (VRW *)0L) return 0; lim = av[3].a_num*av[2].a_num; /* total number of expanded pixels */ if (lim > w->w_width) lim = w->w_width; if (av[2].a_num > 1) { p = data; q = VRsp2; for (i=0; i < lim; i++) { *q++ = *p; if (!((i+1) % av[2].a_num)) p++; } for (i=0; iw_width); /* BYU LSC - decompress it */ /* gives four lines in the VRsp2 buffer, now pixel expand */ i = av[3].a_num; lim = i*av[2].a_num; /* total number of expanded pixels on a line*/ if (lim > w->w_width) lim = w->w_width; if (i > w->w_width) i = w->w_width; p = VRsp2; /* from this buffer */ for (j=0; j<4; j++) { if (av[2].a_num > 1) { q = VRspace; /* to here */ for (i=0; i < lim; i++) { *q++ = *p; if (!((i+1) % av[2].a_num)) p++; } p++; for (i=0; i> (3 - i)*4; for (j=x; j<(x+4); j++) { if ((temp & 8) == 8) out[i*xdim+j] = hi_color; else out[i*xdim+j] = lo_color; temp = temp << 1; } } } /* end of for x */ } /* end of unimcomp */ /* unrleit - Decompress run length encoding. */ short unrleit(unsigned char *buf, unsigned char *bufto, short inlen, short outlen) { register short cnt; register unsigned char *p,*q; unsigned char *endp,*endq; p = buf; endp = buf + inlen; q = bufto; endq = bufto + outlen; while (p < endp && q < endq) { /* go 'til p or q hits end */ cnt = *p++; /* count field */ if (!(cnt & 128)) { /* is set of uniques */ while (cnt-- && q < endq) *q++ = *p++; /* copy unmodified */ } else { cnt &= 127; /* strip high bit */ while (cnt-- && q < endq) *q++ = *p; /* copy same character */ p++; /* skip that character */ } } /* while */ return((short)(q-bufto)); } /***************************************************************************/ /* ** VRrle -- display a line of run-length encoded data ** ** Arugments: ** ** union arg av[]; -- the argument vector ** ** short av[0]; -- x coordinate ** short av[1]; -- y coordinate ** short av[2]; -- pixel expansion ** short av[3]; -- length of data ** char *av[4]; -- window name ** char *data; -- pointer to data ** ** Returns: ** ** None. ** */ short VRrle(union arg av[], char *data) { VRW *w; short i,lim; char *p,*q; /* find the right window */ w = VRlookup(av[4].a_ptr); if (w == (VRW *)0L) return 0; i = unrleit((unsigned char *) data,(unsigned char *) VRsp2,av[3].a_num,w->w_width); /* BYU LSC - decompress it */ lim = i*av[2].a_num; /* total number of expanded pixels */ if (lim > w->w_width) lim = w->w_width; if (av[2].a_num > 1) { p = VRsp2; /* from this buffer */ q = VRspace; /* to here */ for (i=0; i < lim; i++) { *q++ = *p; if (!((i+1) % av[2].a_num)) p++; } for (i=0; iw_name, name) && !w->w_used) { /* same name, not old dup */ if (w->w_rr.wn < 0) /* maybe window don't work */ return(NULL); MacRGsetwindow(w->w_rr.wn); return(w); } w = w->w_next; } return(NULL); } /* ** VRcleanup -- remove all windows from the screen ** ** Arguments: ** ** None. ** ** Returns: ** ** short; 1 -- always successful, or there's nothing you can do ** -- about it anyways... ** */ short VRcleanup(void) { VRW *w = VRhead.w_next; VRW *x; while (w != (VRW *)0L) { x = w->w_next; MacRGremove( w->w_rr.wn); w = x; } return 1; } /************************************************************************/ /* decoding * handle the special ASCII printable character encoding of data bytes. */ /***********************************************************************/ /* * 123 precedes #'s 0-63 * 124 precedes #'s 64-127 * 125 precedes #'s 128-191 * 126 precedes #'s 192-255 * overall: realchar = (specialchar - 123)*64 + (char-32) * specialchar = r div 64 + 123 * char = r mod 64 + 32 */ /***********************************************************************/ static short dstate=FRSKIP,dspec=0; /* set up receive */ void decode0(void) { dstate = FRIN; } short decode1(char c) { switch (dstate) { case FRSKIP: return(-1); case FRIN: /* decoding */ if (c > 31 && c < 123) return(c); else { dspec = c; /* save special character */ dstate = FRSPECIAL; /* doing special character */ } return(-1); case FRSPECIAL: switch (dspec) { case 123: case 124: case 125: case 126: /* encoded character */ dstate = FRIN; return(((dspec - 123)<< 6) - 32 + c); default: /* mistaken character in stream */ dstate = FRIN; /* assume not special */ return(decode1(c)); /* check for sure */ break; } break; } // switch (dstate) } \ No newline at end of file diff --git a/source/ICR/vrrgmac.c b/source/ICR/vrrgmac.c index 94a75fb..1ba9ac9 100755 --- a/source/ICR/vrrgmac.c +++ b/source/ICR/vrrgmac.c @@ -1 +1 @@ -// BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* * * Virtual Graphics Kernel Macintosh Real Graphics Interface * (vrrgmac.c) * * National Center for Supercomputing Applications * by Gaige B. Paulsen * * This file contains the macintosh real screen calls for the NCSA * Virtual Graphics Kernel. * * Following are the Per Device calls: * * MacRGraster( p,x1,y1,x2,y2,wid)- Plot raster in rect @(x1,y1,x2,y2) with wid @ p * MacRGcopy( x1,y1,x2,y2,x3,y3,x4,y4)- * MacRGmap( offset,count,data) - * * * WARNING, WARNING! * Gaige has this cute idea about how to do "subwindows" of real windows by shifting * the window number by 4 bits (MAC_WINDOW_SHIFT). Then, the remainder is the * sub-window number. It will probably work, but you MUST keep the shifted and * non-shifted numbers straight. For example, MacRGdestroy() and MacRGremove() take * different uses of the window number right now. * * * Macintosh only Routines: * * Version Date Notes * ------- ------ --------------------------------------------------- * 0.5 880912 Initial Coding -GBP * 1.0 890216 Minor fixes for 1.0 - TKK */ #ifdef MPW #pragma segment ICR #endif #define __ALLNU__ #include "maclook.proto.h" #include "vdevice.h" #include "vdevice.proto.h" #include "vr.h" #include "InternalEvents.h" #define MAX_MAC_RGS 8 #define MAX_MAC_SUB 16 #define MAC_WINDOW_SHIFT 4 /* Bits shifted */ #define MAC_SUB_MASK 0xf /* Bits maksed */ #include "vrrgmac.proto.h" #include "errors.proto.h" #include "telneterrors.h" typedef struct MacWindow { VDevice vdev; /* virtual device to draw in, has its own colors */ WindowPtr window; /* My Window (0L if not in use ) */ PaletteHandle palette; /* My Palette */ char title[256]; /* Title string */ Point size; /* My height and width */ Rect subs[MAX_MAC_SUB];/* Rectangles of my subwindows [0,0,0,0] if not in use */ } MacWindow; MacWindow *MacRGs; short RGwn=0; /* Window number in use */ short RGsub=0; /* Sub-Window Number in use */ void MacRGinit(void) { short i; MacRGs= (MacWindow *)myNewPtr( MAX_MAC_RGS * sizeof(MacWindow)); for (i=0;i= MAX_MAC_RGS) return( -1); if ((x2 - x1) & 1) /* odd width, must be even */ x2++; SetRect( &wDims, x1+40, y1+40, x2+40, y2+40); strcpy( MacRGs[w].title, name); /* Copy of the name */ if (!TelInfo->haveColorQuickDraw) /* Borrow from RS */ return(-1); else { short i; Str255 scratchPstring; strcpy((char *)scratchPstring, name); CtoPstr((char *)scratchPstring); MacRGs[w].window=NewCWindow(NULL, &wDims, scratchPstring, TRUE, noGrowDocProc, kInFront, /* BYU LSC */ TRUE, (long) w); if (!MacRGs[w].window) { DoError(108 | MEMORY_ERRORCLASS, LEVEL2, NULL); return(-1); } MacRGs[w].vdev.bounds = &MacRGs[w].window->portRect; MacRGs[w].palette = NewPalette( 256, NULL, pmTolerant, 0); if (!MacRGs[w].palette) { DisposeWindow(MacRGs[w].window); DoError(108 | MEMORY_ERRORCLASS, LEVEL2, NULL); return(-1); } for (i=0; i<256; i++) { /* load with grey-scale */ curcol.red = i<<8; curcol.green = i<<8; curcol.blue = i<<8; SetEntryColor( MacRGs[w].palette, i, &curcol); } if (InitVDevice(&MacRGs[w].vdev,MacRGs[w].palette)) /* get vdevice going */ { DisposePalette(MacRGs[w].palette); DisposeWindow(MacRGs[w].window); DoError(108 | MEMORY_ERRORCLASS, LEVEL2, NULL); return(-1); } } ((WindowPeek)MacRGs[w].window)->windowKind = WIN_ICRG; MacRGs[w].size.h = x2-x1; MacRGs[w].size.v = y2-y1; for (i=0; i> MAC_WINDOW_SHIFT; if (!MacRGs[w].window) return; SetPort( MacRGs[w].window); RGwn = w; RGsub= wn & MAC_SUB_MASK; /* Optionally set the clip region */ } /**************************************** * MacRGdestroy(wn) - * * destroy window wn * ****************************************/ void MacRGdestroy(short wn) { // sprintf((char *) tempspot,"destroy: %d", wn); putln((char *) tempspot); /* BYU LSC */ if (!MacRGs[wn].window) return; VRdestroybyName((char *) &MacRGs[wn].title); } /**************************************** * MacRGremove(wn) - * * destroy window wn * ****************************************/ void MacRGremove ( short wn ) { CGrafPtr cgp; short w = wn>> MAC_WINDOW_SHIFT; if (!MacRGs[w].window) return; TrashVDevice(&MacRGs[w].vdev); cgp = (CGrafPtr) MacRGs[w].window; /* unseed window color table */ (*(*(cgp->portPixMap))->pmTable)->ctSeed = GetCTSeed(); DisposeWindow( MacRGs[w].window); /* Get rid of the actual window */ if (MacRGs[w].palette) DisposePalette( MacRGs[w].palette); MacRGs[w].palette = NULL; MacRGs[w].window = NULL; // sprintf((char *) tempspot,"take away: %d", w); putln((char *) tempspot); /* BYU LSC */ } short MacRGfindwind(WindowPtr wind) { short i=0; if (!wind) return(-2); while (iportPixMap; copyfrom = *MacRGs[wn].vdev.bounds; SetPort(wind); copysize = copyfrom; /* boundary of drawing area */ picture= OpenPicture(©size); ClipRect(©size); /* RGBBackColor(&icrwhite); RGBForeColor(&icrblack); */ ForeColor( blackColor); BackColor( whiteColor); LockPixels(hidep); CopyBits((BitMap *) (*hidep), &wind->portBits, ©from, ©size, srcCopy, NULL); UnlockPixels(hidep); ClosePicture(); /* put the PICT into the scrap manager */ len = GetHandleSize((Handle) picture); HLock((Handle) picture); ZeroScrap(); PutScrap( len, 'PICT', (Ptr) *picture); HUnlock((Handle) picture); KillPicture(picture); } short MacRGupdate( WindowPtr wind) { short wn; GWorldPtr theWorld; if (( wn= MacRGfindwind( wind)) <0) return(-1); /* Couldn't do it */ theWorld = MacRGs[wn].vdev.whichWorld; SetPort(wind); ForeColor( blackColor); BackColor( whiteColor); BeginUpdate(wind); LockPixels(theWorld->portPixMap); CopyBits(&((GrafPtr)theWorld)->portBits,&wind->portBits,&theWorld->portRect, &wind->portRect, srcCopy, NULL); UnlockPixels(theWorld->portPixMap); EndUpdate( wind); return(0); } /**************************** Hereafter lie the graphics routines ************************/ short MacRGraster(char *data, short x1, short y1, short x2, short y2, short rowbytes) { Rect tr; char *p,*baseOfThisRun; short i; PixMapHandle pix; CGrafPtr origPort; GDHandle origDev; GWorldPtr theOffscreenWorld; long temp; if (!MacRGs[RGwn].window) return(-1); theOffscreenWorld = MacRGs[RGwn].vdev.whichWorld; GetGWorld(&origPort,&origDev); //save old settings SetGWorld(theOffscreenWorld,NULL); pix = GetGWorldPixMap(MacRGs[RGwn].vdev.whichWorld); LockPixels(pix); baseOfThisRun = (char *)GetPixBaseAddr(pix); temp = (long)((*pix)->rowBytes & 0x3fff); baseOfThisRun += temp*y1 + x1; p = baseOfThisRun; for (i=0; i= MAX_MAC_RGS) return( -1); if ((x2 - x1) & 1) /* odd width, must be even */ x2++; SetRect( &wDims, x1+40, y1+40, x2+40, y2+40); strcpy( MacRGs[w].title, name); /* Copy of the name */ if (!TelInfo->haveColorQuickDraw) /* Borrow from RS */ return(-1); else { short i; Str255 scratchPstring; strcpy((char *)scratchPstring, name); CtoPstr((char *)scratchPstring); MacRGs[w].window=NewCWindow(NULL, &wDims, scratchPstring, TRUE, noGrowDocProc, kInFront, /* BYU LSC */ TRUE, (long) w); if (!MacRGs[w].window) { DoError(108 | MEMORY_ERRORCLASS, LEVEL2, NULL); return(-1); } MacRGs[w].vdev.bounds = &MacRGs[w].window->portRect; MacRGs[w].palette = NewPalette( 256, NULL, pmTolerant, 0); if (!MacRGs[w].palette) { DisposeWindow(MacRGs[w].window); DoError(108 | MEMORY_ERRORCLASS, LEVEL2, NULL); return(-1); } for (i=0; i<256; i++) { /* load with grey-scale */ curcol.red = i<<8; curcol.green = i<<8; curcol.blue = i<<8; SetEntryColor( MacRGs[w].palette, i, &curcol); } if (InitVDevice(&MacRGs[w].vdev,MacRGs[w].palette)) /* get vdevice going */ { DisposePalette(MacRGs[w].palette); DisposeWindow(MacRGs[w].window); DoError(108 | MEMORY_ERRORCLASS, LEVEL2, NULL); return(-1); } } ((WindowPeek)MacRGs[w].window)->windowKind = WIN_ICRG; MacRGs[w].size.h = x2-x1; MacRGs[w].size.v = y2-y1; for (i=0; i> MAC_WINDOW_SHIFT; if (!MacRGs[w].window) return; SetPort( MacRGs[w].window); RGwn = w; RGsub= wn & MAC_SUB_MASK; /* Optionally set the clip region */ } /**************************************** * MacRGdestroy(wn) - * * destroy window wn * ****************************************/ void MacRGdestroy(short wn) { // sprintf((char *) tempspot,"destroy: %d", wn); putln((char *) tempspot); /* BYU LSC */ if (!MacRGs[wn].window) return; VRdestroybyName((char *) &MacRGs[wn].title); } /**************************************** * MacRGremove(wn) - * * destroy window wn * ****************************************/ void MacRGremove ( short wn ) { CGrafPtr cgp; short w = wn>> MAC_WINDOW_SHIFT; if (!MacRGs[w].window) return; TrashVDevice(&MacRGs[w].vdev); cgp = (CGrafPtr) MacRGs[w].window; /* unseed window color table */ (*(*(cgp->portPixMap))->pmTable)->ctSeed = GetCTSeed(); DisposeWindow( MacRGs[w].window); /* Get rid of the actual window */ if (MacRGs[w].palette) DisposePalette( MacRGs[w].palette); MacRGs[w].palette = NULL; MacRGs[w].window = NULL; // sprintf((char *) tempspot,"take away: %d", w); putln((char *) tempspot); /* BYU LSC */ } short MacRGfindwind(WindowPtr wind) { short i=0; if (!wind) return(-2); while (iportPixMap; copyfrom = *MacRGs[wn].vdev.bounds; SetPort(wind); copysize = copyfrom; /* boundary of drawing area */ picture= OpenPicture(©size); ClipRect(©size); /* RGBBackColor(&icrwhite); RGBForeColor(&icrblack); */ ForeColor( blackColor); BackColor( whiteColor); LockPixels(hidep); CopyBits((BitMap *) (*hidep), &wind->portBits, ©from, ©size, srcCopy, NULL); UnlockPixels(hidep); ClosePicture(); /* put the PICT into the scrap manager */ len = GetHandleSize((Handle) picture); HLock((Handle) picture); ZeroScrap(); PutScrap( len, 'PICT', (Ptr) *picture); HUnlock((Handle) picture); KillPicture(picture); } short MacRGupdate( WindowPtr wind) { short wn; GWorldPtr theWorld; if (( wn= MacRGfindwind( wind)) <0) return(-1); /* Couldn't do it */ theWorld = MacRGs[wn].vdev.whichWorld; SetPort(wind); ForeColor( blackColor); BackColor( whiteColor); BeginUpdate(wind); LockPixels(theWorld->portPixMap); CopyBits(&((GrafPtr)theWorld)->portBits,&wind->portBits,&theWorld->portRect, &wind->portRect, srcCopy, NULL); UnlockPixels(theWorld->portPixMap); EndUpdate( wind); return(0); } /**************************** Hereafter lie the graphics routines ************************/ short MacRGraster(char *data, short x1, short y1, short x2, short y2, short rowbytes) { Rect tr; char *p,*baseOfThisRun; short i; PixMapHandle pix; CGrafPtr origPort; GDHandle origDev; GWorldPtr theOffscreenWorld; long temp; if (!MacRGs[RGwn].window) return(-1); theOffscreenWorld = MacRGs[RGwn].vdev.whichWorld; GetGWorld(&origPort,&origDev); //save old settings SetGWorld(theOffscreenWorld,NULL); pix = GetGWorldPixMap(MacRGs[RGwn].vdev.whichWorld); LockPixels(pix); baseOfThisRun = (char *)GetPixBaseAddr(pix); temp = (long)((*pix)->rowBytes & 0x3fff); baseOfThisRun += temp*y1 + x1; p = baseOfThisRun; for (i=0; i #endif #ifndef __TYPES__ #include #endif #ifndef __WINDOWS__ #include #endif #ifndef __DIALOGS__ #include #endif #ifndef __FILES__ #include #endif #ifndef __ICONS__ #include #endif #ifndef __CONTROLS__ #include #endif #ifndef __TEXTEDIT__ #include #endif #ifndef __QDOFFSCREEN__ #include #endif #ifdef __cplusplus extern "C" { #endif #if PRAGMA_IMPORT_SUPPORTED #pragma import on #endif #if PRAGMA_ALIGN_SUPPORTED #pragma options align=mac68k #endif typedef UInt32 TextEncoding; /**/ /* Appearance Manager constants, etc. */ /**/ enum { /* Appearance Trap Number */ _AppearanceDispatch = 0xAA74 }; /* Gestalt selector and values for the Appearance Manager */ enum { gestaltAppearanceAttr = 'appr', gestaltAppearanceExists = 0, gestaltAppearanceCompatMode = 1 }; /* Appearance Manager Error Codes */ enum { appearanceBadBrushIndexErr = -30560, /* pattern index invalid */ appearanceProcessRegisteredErr = -30561, appearanceProcessNotRegisteredErr = -30562, appearanceBadTextColorIndexErr = -30563 }; enum { kThemeActiveDialogBackgroundBrush = 1, /* Dialogs */ kThemeInactiveDialogBackgroundBrush = 2, /* Dialogs */ kThemeActiveAlertBackgroundBrush = 3, kThemeInactiveAlertBackgroundBrush = 4, kThemeActiveModelessDialogBackgroundBrush = 5, kThemeInactiveModelessDialogBackgroundBrush = 6, kThemeActiveUtilityWindowBackgroundBrush = 7, /* Miscellaneous */ kThemeInactiveUtilityWindowBackgroundBrush = 8, /* Miscellaneous */ kThemeListViewSortColumnBackgroundBrush = 9, /* Finder */ kThemeListViewBackgroundBrush = 10, kThemeIconLabelBackgroundBrush = 11, kThemeListViewSeparatorBrush = 12, kThemeChasingArrowsBrush = 13, kThemeDragHiliteBrush = 14, kThemeDocumentWindowBackgroundBrush = 15, kThemeFinderWindowBackgroundBrush = 16 }; typedef SInt16 ThemeBrush; enum { kThemeActiveDialogTextColor = 1, /* Dialogs */ kThemeInactiveDialogTextColor = 2, kThemeActiveAlertTextColor = 3, kThemeInactiveAlertTextColor = 4, kThemeActiveModelessDialogTextColor = 5, kThemeInactiveModelessDialogTextColor = 6, kThemeActiveWindowHeaderTextColor = 7, /* Primitives */ kThemeInactiveWindowHeaderTextColor = 8, kThemeActivePlacardTextColor = 9, /* Primitives */ kThemeInactivePlacardTextColor = 10, kThemePressedPlacardTextColor = 11, kThemeActivePushButtonTextColor = 12, /* Primitives */ kThemeInactivePushButtonTextColor = 13, kThemePressedPushButtonTextColor = 14, kThemeActiveBevelButtonTextColor = 15, /* Primitives */ kThemeInactiveBevelButtonTextColor = 16, kThemePressedBevelButtonTextColor = 17, kThemeActivePopupButtonTextColor = 18, /* Primitives */ kThemeInactivePopupButtonTextColor = 19, kThemePressedPopupButtonTextColor = 20, kThemeIconLabelTextColor = 21, /* Finder */ kThemeListViewTextColor = 22 }; typedef SInt16 ThemeTextColor; /* States to draw primitives: disabled, active, and pressed (hilited) */ enum { kThemeStateDisabled = 0, kThemeStateActive = 1, kThemeStatePressed = 2 }; typedef UInt32 ThemeDrawState; /**/ /* Window Manager constants, etc. */ /**/ enum { /* Resource IDs for new window defprocs */ kWindowDocumentDefProcResID = 64, kWindowDialogDefProcResID = 65, kWindowUtilityDefProcResID = 66, kWindowUtilitySideTitleDefProcResID = 67 }; enum { /* Proc IDs for theme-savvy windows */ kWindowDocumentProc = 1024, kWindowGrowDocumentProc = 1025, kWindowVertZoomDocumentProc = 1026, kWindowVertZoomGrowDocumentProc = 1027, kWindowHorizZoomDocumentProc = 1028, kWindowHorizZoomGrowDocumentProc = 1029, kWindowFullZoomDocumentProc = 1030, kWindowFullZoomGrowDocumentProc = 1031 }; enum { /* Proc IDs for theme-savvy dialogs */ kWindowPlainDialogProc = 1040, kWindowShadowDialogProc = 1041, kWindowModalDialogProc = 1042, kWindowMovableModalDialogProc = 1043, kWindowAlertProc = 1044, kWindowMovableAlertProc = 1045 }; enum { /* Proc IDs for top title bar theme-savvy floating windows */ kWindowFloatProc = 1057, kWindowFloatGrowProc = 1059, kWindowFloatVertZoomProc = 1061, kWindowFloatVertZoomGrowProc = 1063, kWindowFloatHorizZoomProc = 1065, kWindowFloatHorizZoomGrowProc = 1067, kWindowFloatFullZoomProc = 1069, kWindowFloatFullZoomGrowProc = 1071 }; enum { /* Proc IDs for side title bar theme-savvy floating windows */ kWindowFloatSideProcID = 1073, kWindowFloatSideGrowProcID = 1075, kWindowFloatSideVertZoomProcID = 1077, kWindowFloatSideVertZoomGrowProcID = 1079, kWindowFloatSideHorizZoomProcID = 1081, kWindowFloatSideHorizZoomGrowProcID = 1083, kWindowFloatSideFullZoomProcID = 1085, kWindowFloatSideFullZoomGrowProcID = 1087 }; enum { /* Region values to pass into GetWindowRegion */ kWindowTitleBarRgn = 0, kWindowTitleTextRgn = 1, kWindowCloseBoxRgn = 2, kWindowZoomBoxRgn = 3, kWindowDragRgn = 5, kWindowGrowRgn = 6, kWindowCollapseBoxRgn = 7, kWindowStructureRgn = 32, kWindowContentRgn = 33 }; typedef UInt16 WindowRegionCode; enum { /* Window Features returned by GetWindowFeatures */ kWindowCanGrow = (1 << 0), kWindowCanZoom = (1 << 1), kWindowCanCollapse = (1 << 2), kWindowIsModal = (1 << 3), kWindowCanGetWindowRegion = (1 << 4), kWindowIsAlert = (1 << 5), kWindowHasTitleBar = (1 << 6) }; enum { /* New window messages */ kWindowMsgGetFeatures = 7, kWindowMsgGetRegion = 8 }; enum { /* New Window part codes */ inCollapseBox = 11 }; enum { /* Window Definition hit test result codes ("WindowPart")*/ wInCollapseBox = 9 }; /* Window positioning constants */ enum { kWindowDefaultPosition = 0x0000, kWindowCenterMainScreen = 0x280A, kWindowAlertPositionMainScreen = 0x300A, kWindowStaggerMainScreen = 0x380A, kWindowCenterParentWindow = 0xA80A, kWindowAlertPositionParentWindow = 0xB00A, kWindowStaggerParentWindow = 0xB80A, kWindowCenterParentWindowScreen = 0x680A, kWindowAlertPositionParentWindowScreen = 0x700A, kWindowStaggerParentWindowScreen = 0x780A }; /* GetWindowRegionRec - used for WDEF calls with kWindowMsgGetRegion */ struct GetWindowRegionRec { RgnHandle winRgn; WindowRegionCode regionCode; }; typedef struct GetWindowRegionRec GetWindowRegionRec; typedef GetWindowRegionRec *GetWindowRegionPtr; /**/ /* Dialog Manager constants, etc. */ /**/ enum { /* Alert types to pass into StandardAlert */ kAlertStopAlert = 0, kAlertNoteAlert = 1, kAlertCautionAlert = 2, kAlertPlainAlert = 3 }; typedef SInt16 AlertType; enum { kAlertDefaultOKText = -1, /* "OK"*/ kAlertDefaultCancelText = -1, /* "Cancel"*/ kAlertDefaultOtherText = -1 /* "Don't Save"*/ }; /* StandardAlert alert button numbers */ enum { kAlertStdAlertOKButton = 1, kAlertStdAlertCancelButton = 2, kAlertStdAlertOtherButton = 3, kAlertStdAlertHelpButton = 4 }; enum { /* Dialog Flags for use in NewFeaturesDialog or dlgx resource */ kDialogFlagsUseThemeBackground = (1 << 0), kDialogFlagsUseControlHierarchy = (1 << 1), kDialogFlagsHandleMovableModal = (1 << 2), kDialogFlagsUseThemeControls = (1 << 3) }; enum { /* Alert Flags for use in alrx resource */ kAlertFlagsUseThemeBackground = (1 << 0), kAlertFlagsUseControlHierarchy = (1 << 1), kAlertFlagsAlertIsMovable = (1 << 2), kAlertFlagsUseThemeControls = (1 << 3) }; /* For dftb resource */ enum { kDialogFontNoFontStyle = 0, kDialogFontUseFontMask = 0x0001, kDialogFontUseFaceMask = 0x0002, kDialogFontUseSizeMask = 0x0004, kDialogFontUseForeColorMask = 0x0008, kDialogFontUseBackColorMask = 0x0010, kDialogFontUseModeMask = 0x0020, kDialogFontUseJustMask = 0x0040, kDialogFontUseAllMask = 0x00FF, kDialogFontAddFontSizeMask = 0x0100, kDialogFontUseFontMaskMask = 0x0200 }; struct AlertStdAlertParamRec { Boolean movable; /* Make alert movable modal */ Boolean helpButton; /* Is there a help button? */ ModalFilterUPP filterProc; /* Event filter */ StringPtr defaultText; /* Text for button in OK position */ StringPtr cancelText; /* Text for button in cancel position */ StringPtr otherText; /* Text for button in left position */ SInt16 defaultButton; /* Which button behaves as the default */ SInt16 cancelButton; /* Which one behaves as cancel (can be 0) */ UInt16 position; /* Position (kWindowDefaultPosition in this case */ /* equals kWindowAlertPositionParentWindowScreen) */ }; typedef struct AlertStdAlertParamRec AlertStdAlertParamRec; typedef AlertStdAlertParamRec *AlertStdAlertParamPtr; /**/ /* Control Manager constants, etc. */ /**/ enum { _ControlDispatch = 0xAA73 }; enum { /* resource types for new controls */ kControlTabListResType = 'tab#', /* used for tab control only*/ kControlListDescResType = 'ldes' /* used for list box control only*/ }; enum { /* new part codes for new controls */ kControlEditTextPart = 5, kControlPicturePart = 6, kControlIconPart = 7, kControlClockPart = 8, kControlListBoxPart = 24, kControlListBoxDoubleClickPart = 25 }; enum { kControlSupportsNewMessages = ' ok ' /* CDEF should return as result of kControlMsgTestNewMsgSupport*/ }; /* focusing part codes */ enum { kControlFocusNoPart = 0, /* tells control to clear its focus*/ kControlFocusNextPart = -1, /* tells control to focus on the next part*/ kControlFocusPrevPart = -2 /* tells control to focus on the previous part*/ }; typedef SInt16 ControlFocusPart; /* Key Filter result codes */ /* */ /* Certain controls can have a keyfilter attached to them. The filter proc should */ /* return one of the two constants below. If kKeyFilterBlockKey is returned, the */ /* key is blocked and never makes it to the control. If kKeyFilterPassKey is */ /* returned, the control receives the keystroke. */ enum { kControlKeyFilterBlockKey = 0, kControlKeyFilterPassKey = 1 }; typedef SInt16 ControlKeyFilterResult; /**/ /* SPECIAL FONT USAGE NOTES: You can specify the font to use for many control types. The constants below are meta-font numbers which you can use to set a particular control's font usage. There are essentially two modes you can use: 1) default, which is essentially the same as it always has been, i.e. it uses the system font, unless directed to use the window font via a control variant. 2) you can specify to use the big or small system font in a generic manner. The Big system font is the font used in menus, etc. Chicago has filled that role for some time now. Small system font is currently Geneva 10. The meta-font number implies the size and style. NOTE: Not all font attributes are used by all controls. Most, in fact, ignore the fore and back color (Static Text is the only one that does, for backwards compatibility). Also size, face, and addFontSize are ignored when using the meta-font numbering. */ /**/ enum { /* Meta-font numbering - see not above */ kControlFontBigSystemFont = -1, /* force to big system font*/ kControlFontSmallSystemFont = -2, /* force to small system font*/ kControlFontSmallBoldSystemFont = -3 /* force to small bold system font*/ }; /* Add these masks together to set the flags field of a ControlFontStyleRec */ /* They specify which fields to apply to the text. It is important to make */ /* sure that you specify only the fields that you wish to set. */ enum { kControlUseFontMask = 0x0001, kControlUseFaceMask = 0x0002, kControlUseSizeMask = 0x0004, kControlUseForeColorMask = 0x0008, kControlUseBackColorMask = 0x0010, kControlUseModeMask = 0x0020, kControlUseJustMask = 0x0040, kControlUseAllMask = 0x00FF, kControlAddFontSizeMask = 0x0100 }; struct ControlFontStyleRec { SInt16 flags; SInt16 font; SInt16 size; SInt16 style; SInt16 mode; SInt16 just; RGBColor foreColor; RGBColor backColor; }; typedef struct ControlFontStyleRec ControlFontStyleRec; typedef ControlFontStyleRec *ControlFontStylePtr; /**/ /* Common data tags for Get/SetControlData */ /**/ enum { kControlFontStyleTag = 'font', kControlKeyFilterTag = 'fltr' }; /**/ /* Errors are in the range -30580 .. -30599 */ /**/ enum { errMessageNotSupported = -30580, errDataNotSupported = -30581, errControlDoesntSupportFocus = -30582, errWindowDoesntSupportFocus = -30583, errUnknownControl = -30584, errCouldntSetFocus = -30585, errNoRootControl = -30586, errRootAlreadyExists = -30587, errInvalidPartCode = -30588, errControlsAlreadyExist = -30589, errControlIsNotEmbedder = -30590, errDataSizeMismatch = -30591, errControlHiddenOrDisabled = -30592, errWindowRegionCodeInvalid = -30593, errCantEmbedIntoSelf = -30594, errCantEmbedRoot = -30595, errItemNotControl = -30596 }; enum { /* Control feature bits - returned by GetControlFeatures */ kControlSupportsGhosting = 1 << 0, kControlSupportsEmbedding = 1 << 1, kControlSupportsFocus = 1 << 2, kControlWantsIdle = 1 << 3, kControlWantsActivate = 1 << 4, kControlHandlesTracking = 1 << 5, kControlSupportsDataAccess = 1 << 6, kControlHasSpecialBackground = 1 << 7, kControlGetsFocusOnClick = 1 << 8, kControlSupportsCalcBestRect = 1 << 9, kControlSupportsLiveFeedback = 1 << 10 }; enum { /* Control Messages */ kControlMsgDrawGhost = 13, kControlMsgCalcBestRect = 14, /* Calculate best fitting rectangle for control*/ kControlMsgHandleTracking = 15, kControlMsgFocus = 16, /* param indicates action.*/ kControlMsgKeyDown = 17, kControlMsgIdle = 18, kControlMsgGetFeatures = 19, kControlMsgSetData = 20, kControlMsgGetData = 21, kControlMsgActivate = 22, kControlMsgSetUpBackground = 23, kControlMsgCalcValue = 24, kControlMsgSubControlHit = 25, kControlMsgCalcValueFromPos = 26, kControlMsgTestNewMsgSupport = 27 /* See if this control supports new messaging*/ }; /**/ /* This structure is passed into a CDEF when called with the kControlMsgHandleTracking */ /* message */ /**/ struct ControlTrackingRec { Point startPt; SInt16 modifiers; ControlActionUPP action; }; typedef struct ControlTrackingRec ControlTrackingRec; typedef ControlTrackingRec *ControlTrackingPtr; /**/ /* This structure is passed into a CDEF when called with the kControlMsgKeyDown message */ /**/ struct ControlKeyDownRec { SInt16 modifiers; SInt16 keyCode; SInt16 charCode; }; typedef struct ControlKeyDownRec ControlKeyDownRec; typedef ControlKeyDownRec *ControlKeyDownPtr; /**/ /* This structure is passed into a CDEF when called with the kControlMsgGetData or */ /* kControlMsgSetData message */ /**/ struct ControlDataAccessRec { ResType tag; ResType part; Size size; Ptr dataPtr; }; typedef struct ControlDataAccessRec ControlDataAccessRec; typedef ControlDataAccessRec *ControlDataAccessPtr; /**/ /* This structure is passed into a CDEF when called with the kControlCalcBestRect msg */ /**/ struct ControlCalcSizeRec { SInt16 height; SInt16 width; SInt16 baseLine; }; typedef struct ControlCalcSizeRec ControlCalcSizeRec; typedef ControlCalcSizeRec *ControlCalcSizePtr; /**/ /* This structure is passed into a CDEF when called with the kControlMsgSetUpBackground */ /* message is sent */ /**/ struct ControlBackgroundRec { SInt16 depth; Boolean colorDevice; }; typedef struct ControlBackgroundRec ControlBackgroundRec; typedef ControlBackgroundRec *ControlBackgroundPtr; /**/ /* Key Filter */ /* */ /* Definition of a key filter for intercepting and possibly changing keystrokes */ /* which are destined for a control */ /**/ typedef pascal ControlKeyFilterResult (*ControlKeyFilterProcPtr)(ControlHandle theControl, SInt16 *keyCode, SInt16 *charCode, SInt16 *modifiers); #if GENERATINGCFM typedef UniversalProcPtr ControlKeyFilterUPP; #else typedef ControlKeyFilterProcPtr ControlKeyFilterUPP; #endif enum { uppControlKeyFilterProcInfo = kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(ControlKeyFilterResult))) | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ControlHandle))) | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(SInt16 *))) | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(SInt16 *))) | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(SInt16 *))) }; #if GENERATINGCFM #define NewControlKeyFilterProc(userRoutine) \ (ControlKeyFilterUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppControlKeyFilterProcInfo, GetCurrentArchitecture()) #else #define NewControlKeyFilterProc(userRoutine) \ ((ControlKeyFilterUPP) (userRoutine)) #endif #if GENERATINGCFM #define CallControlKeyFilterProc(userRoutine, theControl, keyCode, charCode, modifiers) \ CallUniversalProc((UniversalProcPtr)(userRoutine), uppControlKeyFilterProcInfo, (theControl), (keyCode), (charCode), (modifiers)) #else #define CallControlKeyFilterProc(userRoutine, theControl, keyCode, charCode, modifiers) \ (*(userRoutine))((theControl), (keyCode), (charCode), (modifiers)) #endif /**/ /* BEVEL BUTTON INTERFACE (CDEF 2) */ /**/ /* Bevel buttons allow you to control the content type (pict/icon/etc.), the behavior */ /* (pushbutton/toggle/sticky), and the bevel size. You also have the option of */ /* attaching a menu to it. When a menu is present, you can specify which way the */ /* popup arrow is facing (down or right). */ /* */ /* This is all made possible by overloading the Min, Max, and Value parameters for the */ /* control, as well as adjusting the variant. Here's the breakdown of what goes where: */ /* */ /* Parameter What Goes Here */ /* */ /* Min Hi Byte = Behavior, Lo Byte = content type. */ /* Max ResID for resource-based content types. */ /* Value MenuID to attach, 0 = no menu, please. */ /* */ /* The variant is broken down into two halfs. The low 2 bits control the bevel type. */ /* Bit 2 controls the popup arrow direction (if a menu is present) and bit 3 controls */ /* whether or not to use the control's owning window's font. */ /* */ /* Constants for all you need to put this together are below. The values for behaviors */ /* are set up so that you can simply add them to the content type and pass them into */ /* the Min parameter of NewControl. */ /* */ /* An example call: */ /* */ /* control = NewControl( window, &bounds, "\p", true, 0, kContentIconSuiteRes + */ /* kBehaviorToggles, myIconSuiteID, bevelButtonSmallBevelProc, */ /* 0L ); */ /* */ /* Attaching a menu: */ /* */ /* control = NewControl( window, &bounds, "\p", true, kMyMenuID, kContentIconSuiteRes, */ /* myIconSuiteID, bevelButtonSmallBevelProc + kBevelButtonMenuOnRight, 0L ); */ /* */ /* This will attach menu ID kMyMenuID to the button, with the popup arrow facing right.*/ /* This also puts the menu up to the right of the button. You can also specify that a */ /* menu can have multiple items checked at once by adding kBehaviorMultiValueMenus */ /* into the Min parameter. If you do use multivalue menus, the GetBevelButtonMenuValue */ /* helper function will return the last item chosen from the menu, whether or not it */ /* was checked. */ /* */ /* NOTE: Bevel buttons with menus actually have *two* values. The value of the */ /* button (on/off), and the value of the menu. The menu value can be gotten */ /* with the GetBevelButtonMenuValue helper function. */ /* */ /* Handle-based Content */ /* */ /* You can create your control and then set the content to an existing handle to an */ /* icon suite, etc. using the macros below. Please keep in mind that resource-based */ /* content is owned by the control, handle-based content is owned by you. The CDEF will*/ /* not try to dispose of handle-based content. If you are changing the content type of */ /* the button on the fly, you must make sure that if you are replacing a handle- */ /* based content with a resource-based content to properly dispose of the handle, */ /* else a memory leak will ensue. */ /* */ enum { /* Bevel Button Proc IDs */ kControlBevelButtonSmallBevelProc = 32, kControlBevelButtonNormalBevelProc = 33, kControlBevelButtonLargeBevelProc = 34 }; enum { /* Bevel button graphic alignment values */ kControlBevelButtonAlignSysDirection = -1, /* only left or right*/ kControlBevelButtonAlignCenter = 0, kControlBevelButtonAlignLeft = 1, kControlBevelButtonAlignRight = 2, kControlBevelButtonAlignTop = 3, kControlBevelButtonAlignBottom = 4, kControlBevelButtonAlignTopLeft = 5, kControlBevelButtonAlignBottomLeft = 6, kControlBevelButtonAlignTopRight = 7, kControlBevelButtonAlignBottomRight = 8 }; typedef SInt16 ControlButtonGraphicAlignment; enum { /* Bevel button text alignment values */ kControlBevelButtonAlignTextSysDirection = teFlushDefault, kControlBevelButtonAlignTextCenter = teCenter, kControlBevelButtonAlignTextFlushRight = teFlushRight, kControlBevelButtonAlignTextFlushLeft = teFlushLeft }; typedef SInt16 ControlButtonTextAlignment; enum { /* Bevel button text placement values */ kControlBevelButtonPlaceSysDirection = -1, /* if graphic on right, then on left*/ kControlBevelButtonPlaceNormally = 0, kControlBevelButtonPlaceToRightOfGraphic = 1, kControlBevelButtonPlaceToLeftOfGraphic = 2, kControlBevelButtonPlaceBelowGraphic = 3, kControlBevelButtonPlaceAboveGraphic = 4 }; typedef SInt16 ControlButtonTextPlacement; /* Add these variant codes to kBevelButtonSmallBevelProc to change the type of button */ enum { kControlBevelButtonSmallBevelVariant = 0, kControlBevelButtonNormalBevelVariant = (1 << 0), kControlBevelButtonLargeBevelVariant = (1 << 1), kControlBevelButtonMenuOnRight = (1 << 2) }; /* Behaviors of bevel buttons. These are set up so you can add them together with the content types. */ enum { kControlBehaviorPushbutton = 0, kControlBehaviorToggles = 0x0100, kControlBehaviorSticky = 0x0200, kControlBehaviorMultiValueMenu = 0x4000, /* only makes sense when a menu is attached.*/ kControlBehaviorOffsetContents = 0x8000 }; /* Content types supported by bevel buttons *and* image wells*/ enum { kControlContentTextOnly = 0, kControlContentIconSuiteRes = 1, kControlContentCIconRes = 2, kControlContentPictRes = 3, kControlContentIconSuiteHandle = 129, kControlContentCIconHandle = 130, kControlContentPictHandle = 131, kControlContentIconRef = 132 }; typedef SInt16 ControlContentType; /* Data tags supported by the bevel button controls */ enum { kControlBevelButtonContentTag = 'cont', /* ButtonContentInfo*/ kControlBevelButtonTransformTag = 'tran', /* IconTransformType*/ kControlBevelButtonTextAlignTag = 'tali', /* ButtonTextAlignment*/ kControlBevelButtonTextOffsetTag = 'toff', /* SInt16*/ kControlBevelButtonGraphicAlignTag = 'gali', /* ButtonGraphicAlignment*/ kControlBevelButtonGraphicOffsetTag = 'goff', /* Point*/ kControlBevelButtonTextPlaceTag = 'tplc', /* ButtonTextPlacement*/ kControlBevelButtonMenuValueTag = 'mval', /* SInt16*/ kControlBevelButtonMenuHandleTag = 'mhnd' /* MenuHandle*/ }; /* Structure to pass into bevel buttons and image wells to set/get content type */ struct ControlButtonContentInfo { ControlContentType contentType; union { SInt16 resID; CIconHandle cIconHandle; Handle iconSuite; Handle iconRef; PicHandle picture; } u; }; typedef struct ControlButtonContentInfo ControlButtonContentInfo; typedef ControlButtonContentInfo *ControlButtonContentInfoPtr; /**/ /* SLIDER (CDEF 3) */ /**/ /* There are several variants that control the behavior of the slider control. Any */ /* combination of the following three constants can be added to the basic CDEF ID */ /* (kSliderProc). */ /* */ /* Variants: */ /* */ /* kSliderLiveFeedback Slider does not use "ghosted" indicator when tracking. */ /* ActionProc is called (set via SetControlAction) as the */ /* indicator is dragged. The value is updated so that the */ /* actionproc can adjust some other property based on the */ /* value each time the action proc is called. If no action */ /* proc is installed, it reverts to the ghost indicator. */ /* */ /* kSliderHasTickMarks Slider is drawn with 'tick marks'. The control */ /* rectangle must be large enough to accomidate the tick */ /* marks. */ /*|* kSliderReverseDirection Slider thumb points in opposite direction than normal. */ /* If the slider is vertical, the thumb will point to the */ /* left, if the slider is horizontal, the thumb will point */ /* upwards. */ /* */ /* kSliderNonDirectional This option overrides the kSliderReverseDirection and */ /* kSliderHasTickMarks variants. It creates an indicator */ /* which is rectangular and doesn't point in any direction */ /* like the normal indicator does. */ enum { /* Slider proc IDs */ kControlSliderProc = 48, kControlSliderLiveFeedback = (1 << 0), kControlSliderHasTickMarks = (1 << 1), kControlSliderReverseDirection = (1 << 2), kControlSliderNonDirectional = (1 << 3) }; /**/ /* DISCLOSURE TRIANGLE (CDEF 4) */ /**/ /* This control can be used as either left or right facing. It can also handle its own */ /* tracking if you wish. This means that when the 'autotoggle' variant is used, if the */ /* user clicks the control, it's state will change automatically from open to closed */ /* and vice-versa depending on its initial state. After a successful call to Track- */ /* Control, you can just check the current value to see what state it was switched to. */ enum { /* Triangle proc IDs */ kControlTriangleProc = 64, kControlTriangleLeftFacingProc = 65, kControlTriangleAutoToggleProc = 66, kControlTriangleLeftFacingAutoToggleProc = 67 }; enum { /* Tagged data supported by disclosure triangles */ kControlTriangleLastValueTag = 'last' /* SInt16*/ }; /**/ /* PROGRESS INDICATOR (CDEF 5) */ /**/ /* This CDEF implements both determinate and indeterminate progress bars. To switch, */ /* just use SetControlData to set the indeterminate flag to make it indeterminate call */ /* IdleControls to step thru the animation. IdleControls should be called at least */ /* once during your event loop. */ /* */ enum { /* Progress Bar proc IDs */ kControlProgressBarProc = 80 }; enum { /* Tagged data supported by progress bars */ kControlProgressBarIndeterminateTag = 'inde' /* Boolean*/ }; /**/ /* LITTLE ARROWS (CDEF 6) */ /**/ /* This control implements the little up and down arrows you'd see in the Memory */ /* control panel for adjusting the cache size. */ enum { /* Little Arrows proc IDs */ kControlLittleArrowsProc = 96 }; /**/ /* CHASING ARROWS (CDEF 7) */ /**/ /* To animate this control, make sure to call IdleControls repeatedly. */ /* */ enum { /* Chasing Arrows proc IDs */ kControlChasingArrowsProc = 112 }; /**/ /* TABS (CDEF 8) */ /**/ /* Tabs use an auxiliary resource (tab#) to hold tab information such as the tab name */ /* and an icon suite ID for each tab. */ /* */ /* The ID of the tab# resource that you wish to associate with a tab control should */ /* be passed in as the Value parameter of the control. If you are using GetNewControl, */ /* then the Value slot in the CNTL resource should have the ID of the 'tab#' resource */ /* on creation. */ /* */ enum { /* Tabs proc IDs */ kControlTabLargeProc = 128, /* Large tab size */ kControlTabSmallProc = 129 /* Small tab size */ }; enum { /* Tagged data supported by progress bars */ kControlTabContentRectTag = 'rect', /* Rect*/ kControlTabEnabledFlagTag = 'enab', /* Boolean*/ kControlTabFontStyleTag = kControlFontStyleTag /* ControlFontStyleRec*/ }; /**/ /* VISUAL SEPARATOR (CDEF 9) */ /**/ /* Separator lines determine their orientation (horizontal or vertical) automatically */ /* based on the relative height and width of their contrlRect. */ enum { /* Visual separator proc IDs */ kControlSeparatorLineProc = 144 }; /**/ /* GROUP BOX (CDEF 10) */ /**/ /* The group box CDEF can be use in several ways. It can have no title, a text title, */ /* a check box as the title, or a popup button as a title. There are two versions of */ /* group boxes, primary and secondary, which look slightly different. */ enum { /* Group Box proc IDs */ kControlGroupBoxTextTitleProc = 160, kControlGroupBoxCheckBoxProc = 161, kControlGroupBoxPopupButtonProc = 162, kControlGroupBoxSecondaryTextTitleProc = 164, kControlGroupBoxSecondaryCheckBoxProc = 165, kControlGroupBoxSecondaryPopupButtonProc = 166 }; enum { /* Tagged data supported by group box */ kControlGroupBoxMenuHandleTag = 'mhan', /* MenuHandle (popup title only)*/ kControlGroupBoxFontStyleTag = kControlFontStyleTag /* ControlFontStyleRec*/ }; /**/ /* IMAGE WELL (CDEF 11) */ /**/ /* Image Wells allow you to control the content type (pict/icon/etc.) shown in the */ /* well. */ /* */ /* This is made possible by overloading the Min and Value parameters for the control. */ /* */ /* Parameter What Goes Here */ /* */ /* Min content type (see constants for bevel buttons) */ /* Value Resource ID of content type, if resource-based. */ /* */ /* */ /* Checked State */ /* */ /* The checked state is enabled by setting the value of the control to 1, just like a */ /* check box. */ /* */ /* Handle-based Content */ /* */ /* You can create your control and then set the content to an existing handle to an */ /* icon suite, etc. using the macros below. Please keep in mind that resource-based */ /* content is owned by the control, handle-based content is owned by you. The CDEF will*/ /* not try to dispose of handle-based content. If you are changing the content type of */ /* the button on the fly, you must make sure that if you are replacing a handle- */ /* based content with a resource-based content to properly dispose of the handle, */ /* else a memory leak will ensue. */ /* */ /* */ /* AutoTracking */ /* */ /* Image Wells are capable of autotracking. The current autotracking feature sets the */ /* value itself, so that the control remains hilited. It behaves as a sort of palette */ /* type object where clicking selects it, it cannot be delected by clicking it again, */ /* clicking on another object should cause the focus to change (as in Get Info windows)*/ /* and the application should then set the value to 0 to take away the checked border. */ /* */ enum { /* Image Well proc IDs */ kControlImageWellProc = 176, kControlImageWellAutoTrackProc = 177 }; enum { /* Tagged data supported by image wells */ kControlImageWellContentTag = 'cont', /* ButtonContentInfo*/ kControlImageWellTransformTag = 'tran' /* IconTransformType*/ }; /**/ /* POPUP ARROW (CDEF 12) */ /**/ /* The popup arrow CDEF is used to draw the small arrow normally associated with a */ /* popup control. The arrow can point in four directions, and a small or large version */ /* can be used. This control is provided to allow clients to draw the arrow in a */ /* normalized fashion which will take advantage of themes automatically. */ /* */ enum { /* Popup Arrow proc IDs */ kControlPopupArrowEastProc = 192, kControlPopupArrowWestProc = 193, kControlPopupArrowNorthProc = 194, kControlPopupArrowSouthProc = 195, kControlPopupArrowSmallEastProc = 196, kControlPopupArrowSmallWestProc = 197, kControlPopupArrowSmallNorthProc = 198, kControlPopupArrowSmallSouthProc = 199 }; /**/ /* PLACARD (CDEF 14) */ /**/ enum { /* Placard proc IDs */ kControlPlacardProc = 224 }; /**/ /* CLOCK (CDEF 15) */ /**/ /* NOTE: You can specify more options in the Value paramter when creating the clock. */ /* See below. */ enum { /* Clock proc IDs */ kControlClockTimeProc = 240, kControlClockTimeSecondsProc = 241, kControlClockDateProc = 242, kControlClockMonthYearProc = 243 }; /**/ /* These flags can be passed into 'value' field on creation of the control. */ /* Value is set to 0 after control is created. */ /* */ /* The kClockIsLive value tells the clock to automatically update on idle (clock will */ /* have the current time). This flag is only valid when the kClockIsDisplayOnly flag */ /* is set. */ /**/ enum { kControlClockNoFlags = 0, kControlClockIsDisplayOnly = 1, kControlClockIsLive = 2 }; enum { /* Tagged data supported by clocks */ kControlClockLongDateTag = 'date', /* LongDateRec*/ kControlClockFontStyleTag = kControlFontStyleTag /* ControlFontStyleRec*/ }; /**/ /* USER PANE (CDEF 16) */ /**/ enum { /* User Pane proc IDs */ kControlUserPaneProc = 256 }; /* Tagged data supported by user panes */ /* Currently, they are all proc ptrs for doing things like drawing and hit testing, etc. */ enum { kControlUserItemDrawProcTag = 'uidp', /* UserItemUPP*/ kControlUserPaneDrawProcTag = 'draw', /* ControlUserPaneDrawingUPP*/ kControlUserPaneHitTestProcTag = 'hitt', /* ControlUserPaneHitTestUPP*/ kControlUserPaneTrackingProcTag = 'trak', /* ControlUserPaneTrackingUPP*/ kControlUserPaneIdleProcTag = 'idle', /* ControlUserPaneIdleUPP*/ kControlUserPaneKeyDownProcTag = 'keyd', /* ControlUserPaneKeyDownUPP*/ kControlUserPaneActivateProcTag = 'acti', /* ControlUserPaneActivateUPP*/ kControlUserPaneFocusProcTag = 'foci', /* ControlUserPaneFocusUPP*/ kControlUserPaneBackgroundProcTag = 'back' /* ControlUserPaneBackgroundUPP*/ }; typedef pascal void (*ControlUserPaneDrawProcPtr)(ControlHandle control, SInt16 part); typedef pascal ControlPartCode (*ControlUserPaneHitTestProcPtr)(ControlHandle control, Point where); typedef pascal ControlPartCode (*ControlUserPaneTrackingProcPtr)(ControlHandle control, Point startPt, ControlActionUPP actionProc); typedef pascal void (*ControlUserPaneIdleProcPtr)(ControlHandle control); typedef pascal ControlPartCode (*ControlUserPaneKeyDownProcPtr)(ControlHandle control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers); typedef pascal void (*ControlUserPaneActivateProcPtr)(ControlHandle control, Boolean activating); typedef pascal ControlPartCode (*ControlUserPaneFocusProcPtr)(ControlHandle control, ControlFocusPart action); typedef pascal void (*ControlUserPaneBackgroundProcPtr)(ControlHandle control, ControlBackgroundPtr info); #if GENERATINGCFM typedef UniversalProcPtr ControlUserPaneDrawUPP; typedef UniversalProcPtr ControlUserPaneHitTestUPP; typedef UniversalProcPtr ControlUserPaneTrackingUPP; typedef UniversalProcPtr ControlUserPaneIdleUPP; typedef UniversalProcPtr ControlUserPaneKeyDownUPP; typedef UniversalProcPtr ControlUserPaneActivateUPP; typedef UniversalProcPtr ControlUserPaneFocusUPP; typedef UniversalProcPtr ControlUserPaneBackgroundUPP; #else typedef ControlUserPaneDrawProcPtr ControlUserPaneDrawUPP; typedef ControlUserPaneHitTestProcPtr ControlUserPaneHitTestUPP; typedef ControlUserPaneTrackingProcPtr ControlUserPaneTrackingUPP; typedef ControlUserPaneIdleProcPtr ControlUserPaneIdleUPP; typedef ControlUserPaneKeyDownProcPtr ControlUserPaneKeyDownUPP; typedef ControlUserPaneActivateProcPtr ControlUserPaneActivateUPP; typedef ControlUserPaneFocusProcPtr ControlUserPaneFocusUPP; typedef ControlUserPaneBackgroundProcPtr ControlUserPaneBackgroundUPP; #endif enum { uppControlUserPaneDrawProcInfo = kPascalStackBased | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ControlHandle))) | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(SInt16))), uppControlUserPaneHitTestProcInfo = kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(ControlPartCode))) | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ControlHandle))) | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Point))), uppControlUserPaneTrackingProcInfo = kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(ControlPartCode))) | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ControlHandle))) | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Point))) | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(ControlActionUPP))), uppControlUserPaneIdleProcInfo = kPascalStackBased | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ControlHandle))), uppControlUserPaneKeyDownProcInfo = kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(ControlPartCode))) | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ControlHandle))) | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(SInt16))) | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(SInt16))) | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(SInt16))), uppControlUserPaneActivateProcInfo = kPascalStackBased | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ControlHandle))) | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Boolean))), uppControlUserPaneFocusProcInfo = kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(ControlPartCode))) | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ControlHandle))) | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ControlFocusPart))), uppControlUserPaneBackgroundProcInfo = kPascalStackBased | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ControlHandle))) | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(ControlBackgroundPtr))) }; #if GENERATINGCFM #define NewControlUserPaneDrawProc(userRoutine) \ (ControlUserPaneDrawUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppControlUserPaneDrawProcInfo, GetCurrentArchitecture()) #define NewControlUserPaneHitTestProc(userRoutine) \ (ControlUserPaneHitTestUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppControlUserPaneHitTestProcInfo, GetCurrentArchitecture()) #define NewControlUserPaneTrackingProc(userRoutine) \ (ControlUserPaneTrackingUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppControlUserPaneTrackingProcInfo, GetCurrentArchitecture()) #define NewControlUserPaneIdleProc(userRoutine) \ (ControlUserPaneIdleUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppControlUserPaneIdleProcInfo, GetCurrentArchitecture()) #define NewControlUserPaneKeyDownProc(userRoutine) \ (ControlUserPaneKeyDownUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppControlUserPaneKeyDownProcInfo, GetCurrentArchitecture()) #define NewControlUserPaneActivateProc(userRoutine) \ (ControlUserPaneActivateUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppControlUserPaneActivateProcInfo, GetCurrentArchitecture()) #define NewControlUserPaneFocusProc(userRoutine) \ (ControlUserPaneFocusUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppControlUserPaneFocusProcInfo, GetCurrentArchitecture()) #define NewControlUserPaneBackgroundProc(userRoutine) \ (ControlUserPaneBackgroundUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppControlUserPaneBackgroundProcInfo, GetCurrentArchitecture()) #else #define NewControlUserPaneDrawProc(userRoutine) \ ((ControlUserPaneDrawUPP) (userRoutine)) #define NewControlUserPaneHitTestProc(userRoutine) \ ((ControlUserPaneHitTestUPP) (userRoutine)) #define NewControlUserPaneTrackingProc(userRoutine) \ ((ControlUserPaneTrackingUPP) (userRoutine)) #define NewControlUserPaneIdleProc(userRoutine) \ ((ControlUserPaneIdleUPP) (userRoutine)) #define NewControlUserPaneKeyDownProc(userRoutine) \ ((ControlUserPaneKeyDownUPP) (userRoutine)) #define NewControlUserPaneActivateProc(userRoutine) \ ((ControlUserPaneActivateUPP) (userRoutine)) #define NewControlUserPaneFocusProc(userRoutine) \ ((ControlUserPaneFocusUPP) (userRoutine)) #define NewControlUserPaneBackgroundProc(userRoutine) \ ((ControlUserPaneBackgroundUPP) (userRoutine)) #endif #if GENERATINGCFM #define CallControlUserPaneDrawProc(userRoutine, control, part) \ CallUniversalProc((UniversalProcPtr)(userRoutine), uppControlUserPaneDrawProcInfo, (control), (part)) #define CallControlUserPaneHitTestProc(userRoutine, control, where) \ CallUniversalProc((UniversalProcPtr)(userRoutine), uppControlUserPaneHitTestProcInfo, (control), (where)) #define CallControlUserPaneTrackingProc(userRoutine, control, startPt, actionProc) \ CallUniversalProc((UniversalProcPtr)(userRoutine), uppControlUserPaneTrackingProcInfo, (control), (startPt), (actionProc)) #define CallControlUserPaneIdleProc(userRoutine, control) \ CallUniversalProc((UniversalProcPtr)(userRoutine), uppControlUserPaneIdleProcInfo, (control)) #define CallControlUserPaneKeyDownProc(userRoutine, control, keyCode, charCode, modifiers) \ CallUniversalProc((UniversalProcPtr)(userRoutine), uppControlUserPaneKeyDownProcInfo, (control), (keyCode), (charCode), (modifiers)) #define CallControlUserPaneActivateProc(userRoutine, control, activating) \ CallUniversalProc((UniversalProcPtr)(userRoutine), uppControlUserPaneActivateProcInfo, (control), (activating)) #define CallControlUserPaneFocusProc(userRoutine, control, action) \ CallUniversalProc((UniversalProcPtr)(userRoutine), uppControlUserPaneFocusProcInfo, (control), (action)) #define CallControlUserPaneBackgroundProc(userRoutine, control, info) \ CallUniversalProc((UniversalProcPtr)(userRoutine), uppControlUserPaneBackgroundProcInfo, (control), (info)) #else #define CallControlUserPaneDrawProc(userRoutine, control, part) \ (*(userRoutine))((control), (part)) #define CallControlUserPaneHitTestProc(userRoutine, control, where) \ (*(userRoutine))((control), (where)) #define CallControlUserPaneTrackingProc(userRoutine, control, startPt, actionProc) \ (*(userRoutine))((control), (startPt), (actionProc)) #define CallControlUserPaneIdleProc(userRoutine, control) \ (*(userRoutine))((control)) #define CallControlUserPaneKeyDownProc(userRoutine, control, keyCode, charCode, modifiers) \ (*(userRoutine))((control), (keyCode), (charCode), (modifiers)) #define CallControlUserPaneActivateProc(userRoutine, control, activating) \ (*(userRoutine))((control), (activating)) #define CallControlUserPaneFocusProc(userRoutine, control, action) \ (*(userRoutine))((control), (action)) #define CallControlUserPaneBackgroundProc(userRoutine, control, info) \ (*(userRoutine))((control), (info)) #endif /* EDIT TEXT (CDEF 17) */ enum { /* Edit Text proc IDs */ kControlEditTextProc = 272, kControlEditTextDialogProc = 273, kControlEditTextPasswordProc = 274 }; enum { /* Tagged data supported by edit text */ kControlEditTextStyleTag = kControlFontStyleTag, /* ControlFontStyleRec*/ kControlEditTextTextTag = 'text', /* Buffer of chars - you supply the buffer*/ kControlEditTextTEHandleTag = 'than', /* The TEHandle of the text edit record*/ kControlEditTextKeyFilterTag = kControlKeyFilterTag, kControlEditTextSelectionTag = 'sele', /* EditTextSelectionRec*/ kControlEditTextPasswordTag = 'pass' /* The clear text password text*/ }; struct ControlEditTextSelectionRec { /* Structure for getting the edit text selection */ SInt16 selStart; SInt16 selEnd; }; typedef struct ControlEditTextSelectionRec ControlEditTextSelectionRec; typedef ControlEditTextSelectionRec *ControlEditTextSelectionPtr; /**/ /* STATIC TEXT (CDEF 18) */ /**/ /* Static Text proc IDs */ enum { kControlStaticTextProc = 288 }; /* Tagged data supported by static text */ enum { kControlStaticTextStyleTag = kControlFontStyleTag, /* ControlFontStyleRec*/ kControlStaticTextTextTag = 'text', /* Copy of text*/ kControlStaticTextTextHeightTag = 'thei' /* SInt16*/ }; /**/ /* PICTURE CONTROL (CDEF 19) */ /**/ /* Value parameter should contain the ID of the picture you wish to display when */ /* creating controls of this type. If you don't want the control tracked at all, use */ /* the 'no track' variant. */ enum { /* Picture control proc IDs */ kControlPictureProc = 304, kControlPictureNoTrackProc = 305 /* immediately returns kControlPicturePart*/ }; /**/ /* ICON CONTROL (CDEF 20) */ /**/ /* Value parameter should contain the ID of the ICON or cicn you wish to display when */ /* creating controls of this type. If you don't want the control tracked at all, use */ /* the 'no track' variant. */ /* Icon control proc IDs */ enum { kControlIconProc = 320, kControlIconNoTrackProc = 321, /* immediately returns kControlIconPart*/ kControlIconSuiteProc = 322, kControlIconSuiteNoTrackProc = 323 /* immediately returns kControlIconPart*/ }; /* Tagged data supported by icon controls */ enum { kControlIconTransformTag = 'trfm', /* IconTransformType*/ kControlIconAlignmentTag = 'algn' /* IconAlignmentType*/ }; /**/ /* WINDOW HEADER (CDEF 21) */ /**/ enum { /* Window Header proc IDs */ kControlWindowHeaderProc = 336, /* normal header*/ kControlWindowListViewHeaderProc = 337 /* variant for list views - no bottom line*/ }; /**/ /* LIST BOX (CDEF 22) */ /**/ /* Lists use an auxiliary resource to define their format. The resource type used is */ /* 'ldes' and a definition for it can be found in Appearance.r. The resource ID for */ /* the ldes is passed in the 'value' parameter when creating the control. */ enum { /* List Box proc IDs */ kControlListBoxProc = 352, kControlListBoxAutoSizeProc = 353 }; enum { /* Tagged data supported by list box */ kControlListBoxListHandleTag = 'lhan', /* ListHandle*/ kControlListBoxKeyFilterTag = kControlKeyFilterTag, /* ControlKeyFilterUPP*/ kControlListBoxFontStyleTag = kControlFontStyleTag /* ControlFontStyleRec*/ }; /**/ /* PUSH BUTTON (CDEF 23) */ /**/ /* The new standard checkbox and radio button controls support a "mixed" value that */ /* indicates that the current setting contains a mixed set of on and off values. The */ /* control value used to display this indication is defined in Controls.h: */ /* */ /* kControlCheckBoxMixedValue = 2 */ /* */ /* Two new variants of the standard pushbutton have been added to the standard control */ /* suite that draw a color icon next to the control title. One variant draws the icon */ /* on the left side, the other draws it on the right side (when the system justifica- */ /* tion is right to left, these are reversed). */ /* */ /* When either of the icon pushbuttons are created, the contrlMax field of the control */ /* record is used to determine the ID of the 'cicn' resource drawn in the pushbutton. */ /* */ /* In addition, a push button can now be told to draw with a default outline using the */ /* SetControlData routine with the kPushButtonDefaultTag below. */ /* */ enum { /* Theme Push Button/Check Box/Radio Button proc IDs */ kControlPushButtonProc = 368, kControlCheckBoxProc = 369, kControlRadioButtonProc = 370, kControlPushButLeftIconProc = 374, /* Standard pushbutton with left-side icon*/ kControlPushButRightIconProc = 375 /* Standard pushbutton with right-side icon*/ }; enum { /* Tagged data supported by standard buttons */ kControlPushButtonDefaultTag = 'dflt' /* default ring flag*/ }; /**/ /* SCROLL BAR (CDEF 24) */ /**/ /* This is the new Appearance scroll bar. */ /* */ enum { /* Theme Scroll Bar proc IDs */ kControlScrollBarProc = 384, /* normal scroll bar*/ kControlScrollBarLiveProc = 386 /* live scrolling variant*/ }; /**/ /* POPUP BUTTON (CDEF 25) */ /**/ /* This is the new Appearance Popup Button. It takes the same variants and does the */ /* same overloading as the previous popup menu control. There are some differences: */ /* */ /* Passing in a menu ID of -12345 causes the popup not to try and get the menu from a */ /* resource. Instead, you can build the menu and later stuff the menuhandle field in */ /* the popup data information. */ /* */ /* You can pass -1 in the Max parameter to have the control calculate the width of the */ /* title on its own instead of guessing and then tweaking to get it right. It adds the */ /* appropriate amount of space between the title and the popup. */ /* */ enum { /* Theme Popup Button proc IDs */ kControlPopupButtonProc = 400, kControlPopupFixedWidthVariant = 1 << 0, kControlPopupVariableWidthVariant = 1 << 1, kControlPopupUseAddResMenuVariant = 1 << 2, kControlPopupUseWFontVariant = kControlUsesOwningWindowsFontVariant }; /**/ /* Menu Manager constants, etc. */ /**/ enum { kMenuStdMenuProc = 63, kMenuStdMenuBarProc = 63 }; enum { kMenuNoModifiers = 0, /* Mask for no modifiers*/ kMenuShiftModifier = (1 << 0), /* Mask for shift key modifier*/ kMenuOptionModifier = (1 << 1), /* Mask for option key modifier*/ kMenuControlModifier = (1 << 2), /* Mask for control key modifier*/ kMenuNoCommandModifier = (1 << 3) /* Mask for no command key modifier*/ }; enum { kMenuNoIcon = 0, /* No icon*/ kMenuIconType = 1, /* Type for ICON*/ kMenuShrinkIconType = 2, /* Type for ICON plotted 16 x 16*/ kMenuSmallIconType = 3, /* Type for SICN*/ kMenuColorIconType = 4, /* Type for cicn*/ kMenuIconSuiteType = 5, /* Type for Icon Suite*/ kMenuIconRefType = 6 /* Type for Icon Ref*/ }; /**/ /* Appearance Manager APIs */ /**/ /* Registering Appearance-Savvy Applications */ extern pascal OSStatus RegisterAppearanceClient(void) THREEWORDINLINE(0x303C, 0x0015, 0xAA74); extern pascal OSStatus UnregisterAppearanceClient(void) THREEWORDINLINE(0x303C, 0x0016, 0xAA74); /* **************************************************************************** NOTES ON THEME BRUSHES Theme brushes can be either colors or patterns, depending on the theme. Because of this, you should be prepared to handle the case where a brush is a pattern and save and restore the pnPixPat and bkPixPat fields of your GrafPorts when saving the fore and back colors. Also, since patterns in bkPixPat override the background color of the window, you should use BackPat to set your background pattern to a normal white pattern. This will ensure that you can use RGBBackColor to set your back color to white, call EraseRect and get the expected results. **************************************************************************** */ extern pascal OSStatus SetThemePen(ThemeBrush brush, SInt16 depth, Boolean colorDevice) THREEWORDINLINE(0x303C, 0x0001, 0xAA74); extern pascal OSStatus SetThemeBackground(ThemeBrush brush, SInt16 depth, Boolean colorDevice) THREEWORDINLINE(0x303C, 0x0002, 0xAA74); extern pascal OSStatus SetThemeTextColor(ThemeTextColor color, SInt16 depth, Boolean colorDevice) THREEWORDINLINE(0x303C, 0x0003, 0xAA74); extern pascal OSStatus SetThemeWindowBackground(WindowPtr window, ThemeBrush brush, Boolean update) THREEWORDINLINE(0x303C, 0x0004, 0xAA74); /* Window Placards, Headers and Frames */ extern pascal OSStatus DrawThemeWindowHeader(const Rect *rect, ThemeDrawState state) THREEWORDINLINE(0x303C, 0x0005, 0xAA74); extern pascal OSStatus DrawThemeWindowListViewHeader(const Rect *rect, ThemeDrawState state) THREEWORDINLINE(0x303C, 0x0006, 0xAA74); extern pascal OSStatus DrawThemePlacard(const Rect *rect, ThemeDrawState state) THREEWORDINLINE(0x303C, 0x0007, 0xAA74); extern pascal OSStatus DrawThemeEditTextFrame(const Rect *rect, ThemeDrawState state) THREEWORDINLINE(0x303C, 0x0009, 0xAA74); extern pascal OSStatus DrawThemeListBoxFrame(const Rect *rect, ThemeDrawState state) THREEWORDINLINE(0x303C, 0x000A, 0xAA74); /* Keyboard Focus Drawing */ extern pascal OSStatus DrawThemeFocusRect(const Rect *rect, Boolean hasFocus) THREEWORDINLINE(0x303C, 0x000B, 0xAA74); /* Dialog Group Boxes and Separators */ extern pascal OSStatus DrawThemePrimaryGroup(const Rect *rect, ThemeDrawState state) THREEWORDINLINE(0x303C, 0x000C, 0xAA74); extern pascal OSStatus DrawThemeSecondaryGroup(const Rect *rect, ThemeDrawState state) THREEWORDINLINE(0x303C, 0x000D, 0xAA74); extern pascal OSStatus DrawThemeSeparator(const Rect *rect, ThemeDrawState state) THREEWORDINLINE(0x303C, 0x000E, 0xAA74); /**/ /* Window Manager APIs */ /**/ extern pascal OSStatus GetWindowFeatures(WindowPtr window, UInt32 *features) THREEWORDINLINE(0x303C, 0x0013, 0xAA74); extern pascal Boolean IsWindowCollapsable(WindowPtr window) THREEWORDINLINE(0x303C, 0x000F, 0xAA74); extern pascal Boolean IsWindowCollapsed(WindowPtr window) THREEWORDINLINE(0x303C, 0x0010, 0xAA74); extern pascal OSStatus CollapseWindow(WindowPtr window, Boolean collapseIt) THREEWORDINLINE(0x303C, 0x0011, 0xAA74); extern pascal OSStatus CollapseAllWindows(Boolean collapseEm) THREEWORDINLINE(0x303C, 0x0012, 0xAA74); extern pascal OSStatus GetWindowRegion(WindowPtr window, WindowRegionCode regionCode, RgnHandle winRgn) THREEWORDINLINE(0x303C, 0x0014, 0xAA74); /**/ /* Dialog Manager APIs */ /**/ extern pascal DialogPtr NewFeaturesDialog(void *wStorage, const Rect *boundsRect, ConstStr255Param title, Boolean visible, SInt16 procID, WindowPtr behind, Boolean goAwayFlag, SInt32 refCon, Handle itmLstHndl, UInt32 flags) THREEWORDINLINE(0x303C, 0x110C, 0xAA68); extern pascal OSErr AutoSizeDialog(DialogPtr dialog) THREEWORDINLINE(0x303C, 0x020D, 0xAA68); extern pascal OSErr StandardAlert(AlertType alertType, StringPtr error, StringPtr explanation, AlertStdAlertParamPtr alertParam, SInt16 *itemHit) THREEWORDINLINE(0x303C, 0x090E, 0xAA68); extern pascal OSErr GetDialogItemAsControl(DialogPtr dialog, SInt16 itemNo, ControlHandle *control) THREEWORDINLINE(0x303C, 0x050F, 0xAA68); extern pascal OSErr MoveDialogItem(DialogPtr dialog, SInt16 itemNo, SInt16 horiz, SInt16 vert) THREEWORDINLINE(0x303C, 0x0510, 0xAA68); extern pascal OSErr SizeDialogItem(DialogPtr dialog, SInt16 itemNo, SInt16 height, SInt16 width) THREEWORDINLINE(0x303C, 0x0511, 0xAA68); /**/ /* Control Manager APIs */ /**/ /* These routines are available only thru the shared library/glue Bevel button routines */ extern pascal OSErr GetBevelButtonMenuValue(ControlHandle button, SInt16 *value); extern pascal OSErr SetBevelButtonMenuValue(ControlHandle button, SInt16 value); extern pascal OSErr GetBevelButtonMenuHandle(ControlHandle button, MenuHandle *handle); extern pascal OSErr GetBevelButtonContentInfo(ControlHandle button, ControlButtonContentInfoPtr content); extern pascal OSErr SetBevelButtonContentInfo(ControlHandle button, ControlButtonContentInfoPtr content); extern pascal OSErr SetBevelButtonTransform(ControlHandle button, IconTransformType transform); extern pascal OSErr SetBevelButtonGraphicAlignment(ControlHandle button, ControlButtonGraphicAlignment align, SInt16 hOffset, SInt16 vOffset); extern pascal OSErr SetBevelButtonTextAlignment(ControlHandle button, ControlButtonTextAlignment align, SInt16 hOffset); extern pascal OSErr SetBevelButtonTextPlacement(ControlHandle button, ControlButtonTextPlacement where); /* Image well routines*/ extern pascal OSErr GetImageWellContentInfo(ControlHandle button, ControlButtonContentInfoPtr content); extern pascal OSErr SetImageWellContentInfo(ControlHandle button, ControlButtonContentInfoPtr content); extern pascal OSErr SetImageWellTransform(ControlHandle button, IconTransformType transform); /* Tab routines*/ extern pascal OSErr GetTabContentRect(ControlHandle tabControl, Rect *contentRect); extern pascal OSErr SetTabEnabled(ControlHandle tabControl, SInt16 tabToHilite, Boolean enabled); /* Disclosure triangles*/ extern pascal OSErr SetDisclosureTriangleLastValue(ControlHandle tabControl, SInt16 value); /* Trap-based routines*/ extern pascal SInt32 SendControlMessage(ControlHandle theControl, SInt16 message, SInt32 param) THREEWORDINLINE(0x303C, 0xFFFE, 0xAA73); extern pascal OSErr DumpControlHierarchy(WindowPtr window, const FSSpec *outFile) THREEWORDINLINE(0x303C, 0xFFFF, 0xAA73); extern pascal OSErr CreateRootControl(WindowPtr window, ControlHandle *control) THREEWORDINLINE(0x303C, 0x0001, 0xAA73); extern pascal OSErr GetRootControl(WindowPtr window, ControlHandle *control) THREEWORDINLINE(0x303C, 0x0002, 0xAA73); extern pascal OSErr EmbedControl(ControlHandle control, ControlHandle container) THREEWORDINLINE(0x303C, 0x0003, 0xAA73); extern pascal OSErr AutoEmbedControl(ControlHandle control, WindowPtr window) THREEWORDINLINE(0x303C, 0x0004, 0xAA73); extern pascal Boolean IsControlActive(ControlHandle control) THREEWORDINLINE(0x303C, 0x0005, 0xAA73); extern pascal Boolean IsControlVisible(ControlHandle control) THREEWORDINLINE(0x303C, 0x0006, 0xAA73); extern pascal OSErr ActivateControl(ControlHandle control) THREEWORDINLINE(0x303C, 0x0007, 0xAA73); extern pascal OSErr DeactivateControl(ControlHandle control) THREEWORDINLINE(0x303C, 0x0008, 0xAA73); extern pascal ControlHandle FindControlUnderMouse(Point where, WindowPtr window, SInt16 *part) THREEWORDINLINE(0x303C, 0x0009, 0xAA73); extern pascal SInt16 HandleControlClick(ControlHandle control, Point where, SInt16 modifiers, ControlActionUPP action) THREEWORDINLINE(0x303C, 0x000A, 0xAA73); extern pascal SInt16 HandleControlKey(ControlHandle control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers) THREEWORDINLINE(0x303C, 0x000B, 0xAA73); extern pascal void IdleControls(WindowPtr window) THREEWORDINLINE(0x303C, 0x000C, 0xAA73); extern pascal OSErr GetKeyboardFocus(WindowPtr window, ControlHandle *control) THREEWORDINLINE(0x303C, 0x000D, 0xAA73); extern pascal OSErr SetKeyboardFocus(WindowPtr window, ControlHandle control, ControlFocusPart part) THREEWORDINLINE(0x303C, 0x000E, 0xAA73); extern pascal OSErr AdvanceKeyboardFocus(WindowPtr window) THREEWORDINLINE(0x303C, 0x000F, 0xAA73); extern pascal OSErr ReverseKeyboardFocus(WindowPtr window) THREEWORDINLINE(0x303C, 0x0010, 0xAA73); extern pascal OSErr GetControlFeatures(ControlHandle control, UInt32 *features) THREEWORDINLINE(0x303C, 0x0011, 0xAA73); extern pascal OSErr SetControlData(ControlHandle control, ControlPartCode part, ResType tagName, Size size, Ptr data) THREEWORDINLINE(0x303C, 0x0012, 0xAA73); extern pascal OSErr GetControlData(ControlHandle control, ControlPartCode part, ResType tagName, Size bufferSize, Ptr buffer, Size *actualSize) THREEWORDINLINE(0x303C, 0x0013, 0xAA73); extern pascal OSErr GetControlDataSize(ControlHandle control, ControlPartCode part, ResType tagName, Size *maxSize) THREEWORDINLINE(0x303C, 0x0014, 0xAA73); extern pascal OSErr GetSuperControl(ControlHandle control, ControlHandle *parent) THREEWORDINLINE(0x303C, 0x0015, 0xAA73); extern pascal OSErr CountSubControls(ControlHandle control, SInt16 *numChildren) THREEWORDINLINE(0x303C, 0x0016, 0xAA73); extern pascal OSErr GetIndexedSubControl(ControlHandle control, SInt16 index, ControlHandle *subControl) THREEWORDINLINE(0x303C, 0x0017, 0xAA73); extern pascal void DrawControlInCurrentPort(ControlHandle theControl) THREEWORDINLINE(0x303C, 0x0018, 0xAA73); extern pascal OSErr ClearKeyboardFocus(WindowPtr window) THREEWORDINLINE(0x303C, 0x0019, 0xAA73); extern pascal OSErr SetControlSupervisor(ControlHandle control, ControlHandle boss) THREEWORDINLINE(0x303C, 0x001A, 0xAA73); extern pascal OSErr GetBestControlRect(ControlHandle control, Rect *rect, SInt16 *baseLineOffset) THREEWORDINLINE(0x303C, 0x001B, 0xAA73); extern pascal OSErr SetControlFontStyle(ControlHandle control, ControlFontStyleRec *style) THREEWORDINLINE(0x303C, 0x001C, 0xAA73); extern pascal OSErr SetUpControlBackground(ControlHandle control, SInt16 depth, Boolean colorDevice) THREEWORDINLINE(0x303C, 0x001D, 0xAA73); extern pascal OSErr SetControlVisibility(ControlHandle control, Boolean isVisible, Boolean draw) THREEWORDINLINE(0x303C, 0x001E, 0xAA73); /**/ /* Menu Manager APIs */ /**/ extern pascal UInt32 MenuEvent(const EventRecord *event) THREEWORDINLINE(0x303C, 0x020C, 0xA825); extern pascal OSErr SetMenuItemCommandID(MenuHandle menu, SInt16 item, UInt32 commandID) THREEWORDINLINE(0x303C, 0x0502, 0xA825); extern pascal OSErr GetMenuItemCommandID(MenuHandle menu, SInt16 item, UInt32 *commandID) THREEWORDINLINE(0x303C, 0x0503, 0xA825); extern pascal OSErr SetMenuItemModifiers(MenuHandle menu, SInt16 item, UInt8 modifiers) THREEWORDINLINE(0x303C, 0x0404, 0xA825); extern pascal OSErr GetMenuItemModifiers(MenuHandle menu, SInt16 item, UInt8 *modifiers) THREEWORDINLINE(0x303C, 0x0505, 0xA825); extern pascal OSErr SetMenuItemIconHandle(MenuHandle menu, SInt16 item, UInt8 iconType, Handle icon) THREEWORDINLINE(0x303C, 0x0606, 0xA825); extern pascal OSErr GetMenuItemIconHandle(MenuHandle menu, SInt16 item, UInt8 *iconType, Handle *icon) THREEWORDINLINE(0x303C, 0x0707, 0xA825); extern pascal OSErr SetMenuItemTextEncoding(MenuHandle menu, SInt16 item, TextEncoding scriptID) THREEWORDINLINE(0x303C, 0x0408, 0xA825); extern pascal OSErr GetMenuItemTextEncoding(MenuHandle menu, SInt16 item, TextEncoding *scriptID) THREEWORDINLINE(0x303C, 0x0509, 0xA825); extern pascal OSErr SetMenuItemHierarchicalID(MenuHandle menu, SInt16 item, SInt16 hierID) THREEWORDINLINE(0x303C, 0x040D, 0xA825); extern pascal OSErr GetMenuItemHierarchicalID(MenuHandle menu, SInt16 item, SInt16 *hierID) THREEWORDINLINE(0x303C, 0x050E, 0xA825); extern pascal OSErr SetMenuItemFontID(MenuHandle menu, SInt16 item, SInt16 fontID) THREEWORDINLINE(0x303C, 0x040F, 0xA825); extern pascal OSErr GetMenuItemFontID(MenuHandle menu, SInt16 item, SInt16 *fontID) THREEWORDINLINE(0x303C, 0x0510, 0xA825); extern pascal OSErr SetMenuItemRefCon(MenuHandle menu, SInt16 item, UInt32 refCon) THREEWORDINLINE(0x303C, 0x050A, 0xA825); extern pascal OSErr GetMenuItemRefCon(MenuHandle menu, SInt16 item, UInt32 *refCon) THREEWORDINLINE(0x303C, 0x050B, 0xA825); extern pascal OSErr SetMenuItemRefCon2(MenuHandle menu, SInt16 item, UInt32 refCon2) THREEWORDINLINE(0x303C, 0x0511, 0xA825); extern pascal OSErr GetMenuItemRefCon2(MenuHandle menu, SInt16 item, UInt32 *refCon2) THREEWORDINLINE(0x303C, 0x0512, 0xA825); extern pascal OSErr SetMenuItemKeyGlyph(MenuHandle menu, SInt16 item, SInt16 glyph) THREEWORDINLINE(0x303C, 0x0513, 0xA825); extern pascal OSErr GetMenuItemKeyGlyph(MenuHandle menu, SInt16 item, SInt16 *glyph) THREEWORDINLINE(0x303C, 0x0514, 0xA825); #if PRAGMA_ALIGN_SUPPORTED #pragma options align=reset #endif #if PRAGMA_IMPORT_SUPPORTED #pragma import off #endif #ifdef __cplusplus } #endif #endif /* __APPEARANCE__ */ \ No newline at end of file diff --git a/source/Libraries/AppearanceLib.bin b/source/Libraries/AppearanceLib.bin new file mode 100644 index 0000000..3430ded Binary files /dev/null and b/source/Libraries/AppearanceLib.bin differ diff --git a/source/Libraries/ICGlue.o b/source/Libraries/ICGlue.o index 707589b..0c74830 100755 Binary files a/source/Libraries/ICGlue.o and b/source/Libraries/ICGlue.o differ diff --git a/source/Libraries/ICGluePPC.lib b/source/Libraries/ICGlueCFM-PPC.lib similarity index 54% rename from source/Libraries/ICGluePPC.lib rename to source/Libraries/ICGlueCFM-PPC.lib index e388c30..1826da6 100755 Binary files a/source/Libraries/ICGluePPC.lib and b/source/Libraries/ICGlueCFM-PPC.lib differ diff --git a/source/Libraries/gmp.h b/source/Libraries/gmp.h new file mode 100755 index 0000000..b8181f1 --- /dev/null +++ b/source/Libraries/gmp.h @@ -0,0 +1,637 @@ +/* gmp.h -- Definitions for GNU multiple precision functions. + +Copyright (C) 1991, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#ifndef __GMP_H__ + +#ifndef __GNU_MP__ +#define __GNU_MP__ 2 +#define __need_size_t +#include +#undef __need_size_t + +//#if defined (__mips) && defined (_ABIN32) +/* Force the use of 64-bit limbs for all 64-bit MIPS CPUs if ABI permits. */ +//#define _LONG_LONG_LIMB +//#endif + +#if defined (__STDC__) || defined (__cplusplus) +#define __gmp_const const +#else +#define __gmp_const +#endif + +#if defined (__GNUC__) +#define __gmp_inline __inline__ +#else +#define __gmp_inline +#endif + +#ifndef _EXTERN_INLINE +#ifdef __GNUC__ +#define _EXTERN_INLINE extern __inline__ +#else +#define _EXTERN_INLINE static +#endif +#endif + +#ifdef _SHORT_LIMB +typedef unsigned int mp_limb_t; +typedef int mp_limb_signed_t; +#else +#ifdef _LONG_LONG_LIMB +typedef unsigned long long int mp_limb_t; +typedef long long int mp_limb_signed_t; +#else +typedef unsigned long int mp_limb_t; +typedef long int mp_limb_signed_t; +#endif +#endif + +typedef mp_limb_t * mp_ptr; +typedef __gmp_const mp_limb_t * mp_srcptr; +typedef long int mp_size_t; +typedef long int mp_exp_t; + +#ifndef __MP_SMALL__ +typedef struct +{ + int _mp_alloc; /* Number of *limbs* allocated and pointed + to by the D field. */ + int _mp_size; /* abs(SIZE) is the number of limbs + the last field points to. If SIZE + is negative this is a negative + number. */ + mp_limb_t *_mp_d; /* Pointer to the limbs. */ +} __mpz_struct; +#else +typedef struct +{ + short int _mp_alloc; /* Number of *limbs* allocated and pointed + to by the D field. */ + short int _mp_size; /* abs(SIZE) is the number of limbs + the last field points to. If SIZE + is negative this is a negative + number. */ + mp_limb_t *_mp_d; /* Pointer to the limbs. */ +} __mpz_struct; +#endif +#endif /* __GNU_MP__ */ + +/* User-visible types. */ +typedef __mpz_struct MP_INT; +typedef __mpz_struct mpz_t[1]; + +/* Structure for rational numbers. Zero is represented as 0/any, i.e. + the denominator is ignored. Negative numbers have the sign in + the numerator. */ +typedef struct +{ + __mpz_struct _mp_num; + __mpz_struct _mp_den; +#if 0 + int _mp_num_alloc; /* Number of limbs allocated + for the numerator. */ + int _mp_num_size; /* The absolute value of this field is the + length of the numerator; the sign is the + sign of the entire rational number. */ + mp_ptr _mp_num; /* Pointer to the numerator limbs. */ + int _mp_den_alloc; /* Number of limbs allocated + for the denominator. */ + int _mp_den_size; /* Length of the denominator. (This field + should always be positive.) */ + mp_ptr _mp_den; /* Pointer to the denominator limbs. */ +#endif +} __mpq_struct; + +typedef __mpq_struct MP_RAT; +typedef __mpq_struct mpq_t[1]; + +typedef struct +{ + int _mp_prec; /* Max precision, in number of `mp_limb_t's. + Set by mpf_init and modified by + mpf_set_prec. The area pointed to + by the `d' field contains `prec' + 1 + limbs. */ + int _mp_size; /* abs(SIZE) is the number of limbs + the last field points to. If SIZE + is negative this is a negative + number. */ + mp_exp_t _mp_exp; /* Exponent, in the base of `mp_limb_t'. */ + mp_limb_t *_mp_d; /* Pointer to the limbs. */ +} __mpf_struct; + +/* typedef __mpf_struct MP_FLOAT; */ +typedef __mpf_struct mpf_t[1]; + +/* Types for function declarations in gmp files. */ +/* ??? Should not pollute user name space with these ??? */ +typedef __gmp_const __mpz_struct *mpz_srcptr; +typedef __mpz_struct *mpz_ptr; +typedef __gmp_const __mpf_struct *mpf_srcptr; +typedef __mpf_struct *mpf_ptr; +typedef __gmp_const __mpq_struct *mpq_srcptr; +typedef __mpq_struct *mpq_ptr; + +#ifndef _PROTO +#if defined (__STDC__) || defined (__cplusplus) +#define _PROTO(x) x +#else +#define _PROTO(x) () +#endif +#endif + +#ifndef __MPN +#if defined (__STDC__) || defined (__cplusplus) +#define __MPN(x) __mpn_##x +#else +#define __MPN(x) __mpn_/**/x +#endif +#endif + +#if defined (FILE) || defined (H_STDIO) || defined (_H_STDIO) \ + || defined (_STDIO_H) || defined (_STDIO_H_) || defined (__STDIO_H__) \ + || defined (_STDIO_INCLUDED) +#define _GMP_H_HAVE_FILE 1 +#endif + +void mp_set_memory_functions _PROTO ((void *(*) (size_t), + void *(*) (void *, size_t, size_t), + void (*) (void *, size_t))); +extern __gmp_const int mp_bits_per_limb; + +/**************** Integer (i.e. Z) routines. ****************/ + +#if defined (__cplusplus) +extern "C" { +#endif +void *_mpz_realloc _PROTO ((mpz_ptr, mp_size_t)); + +void mpz_abs _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_add _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_add_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_and _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_array_init _PROTO ((mpz_ptr, mp_size_t, mp_size_t)); +void mpz_cdiv_q _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +unsigned long int mpz_cdiv_q_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_cdiv_qr _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr)); +unsigned long int mpz_cdiv_qr_ui _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_cdiv_r _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +unsigned long int mpz_cdiv_r_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +unsigned long int mpz_cdiv_ui _PROTO ((mpz_srcptr, unsigned long int)); +void mpz_clear _PROTO ((mpz_ptr)); +void mpz_clrbit _PROTO ((mpz_ptr, unsigned long int)); +int mpz_cmp _PROTO ((mpz_srcptr, mpz_srcptr)); +int mpz_cmp_si _PROTO ((mpz_srcptr, signed long int)); +int mpz_cmp_ui _PROTO ((mpz_srcptr, unsigned long int)); +void mpz_com _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_divexact _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_fac_ui _PROTO ((mpz_ptr, unsigned long int)); +void mpz_fdiv_q _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_fdiv_q_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +unsigned long int mpz_fdiv_q_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_fdiv_qr _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr)); +unsigned long int mpz_fdiv_qr_ui _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_fdiv_r _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_fdiv_r_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +unsigned long int mpz_fdiv_r_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +unsigned long int mpz_fdiv_ui _PROTO ((mpz_srcptr, unsigned long int)); +void mpz_gcd _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +unsigned long int mpz_gcd_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_gcdext _PROTO ((mpz_ptr, mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr)); +double mpz_get_d _PROTO ((mpz_srcptr)); +/* signed */ long int mpz_get_si _PROTO ((mpz_srcptr)); +char *mpz_get_str _PROTO ((char *, int, mpz_srcptr)); +unsigned long int mpz_get_ui _PROTO ((mpz_srcptr)); +mp_limb_t mpz_getlimbn _PROTO ((mpz_srcptr, mp_size_t)); +unsigned long int mpz_hamdist _PROTO ((mpz_srcptr, mpz_srcptr)); +void mpz_init _PROTO ((mpz_ptr)); +#ifdef _GMP_H_HAVE_FILE +size_t mpz_inp_binary _PROTO ((mpz_ptr, FILE *)); +size_t mpz_inp_raw _PROTO ((mpz_ptr, FILE *)); +size_t mpz_inp_str _PROTO ((mpz_ptr, FILE *, int)); +#endif +void mpz_init_set _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_init_set_d _PROTO ((mpz_ptr, double)); +void mpz_init_set_si _PROTO ((mpz_ptr, signed long int)); +int mpz_init_set_str _PROTO ((mpz_ptr, const char *, int)); +void mpz_init_set_ui _PROTO ((mpz_ptr, unsigned long int)); +int mpz_invert _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_ior _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +int mpz_jacobi _PROTO ((mpz_srcptr, mpz_srcptr)); +int mpz_legendre _PROTO ((mpz_srcptr, mpz_srcptr)); +void mpz_mod _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_mul _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_mul_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_mul_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_neg _PROTO ((mpz_ptr, mpz_srcptr)); +#ifdef _GMP_H_HAVE_FILE +size_t mpz_out_binary _PROTO ((FILE *, mpz_srcptr)); +size_t mpz_out_raw _PROTO ((FILE *, mpz_srcptr)); +size_t mpz_out_str _PROTO ((FILE *, int, mpz_srcptr)); +#endif +int mpz_perfect_square_p _PROTO ((mpz_srcptr)); +unsigned long int mpz_popcount _PROTO ((mpz_srcptr)); +void mpz_pow_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_powm _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr, mpz_srcptr)); +void mpz_powm_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int, mpz_srcptr)); +int mpz_probab_prime_p _PROTO ((mpz_srcptr, int)); +void mpz_random _PROTO ((mpz_ptr, mp_size_t)); +void mpz_random2 _PROTO ((mpz_ptr, mp_size_t)); +unsigned long int mpz_scan0 _PROTO ((mpz_srcptr, unsigned long int)); +unsigned long int mpz_scan1 _PROTO ((mpz_srcptr, unsigned long int)); +void mpz_set _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_set_d _PROTO ((mpz_ptr, double)); +void mpz_set_f _PROTO ((mpz_ptr, mpf_srcptr)); +void mpz_set_q _PROTO ((mpz_ptr, mpq_srcptr)); +void mpz_set_si _PROTO ((mpz_ptr, signed long int)); +int mpz_set_str _PROTO ((mpz_ptr, const char *, int)); +void mpz_set_ui _PROTO ((mpz_ptr, unsigned long int)); +void mpz_setbit _PROTO ((mpz_ptr, unsigned long int)); +size_t mpz_size _PROTO ((mpz_srcptr)); +size_t mpz_sizeinbase _PROTO ((mpz_srcptr, int)); +void mpz_sqrt _PROTO ((mpz_ptr, mpz_srcptr)); +void mpz_sqrtrem _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr)); +void mpz_sub _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_sub_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_tdiv_q _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_tdiv_q_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_tdiv_q_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_tdiv_qr _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_tdiv_qr_ui _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_tdiv_r _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); +void mpz_tdiv_r_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_tdiv_r_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int)); +void mpz_ui_pow_ui _PROTO ((mpz_ptr, unsigned long int, unsigned long int)); + +/**************** Rational (i.e. Q) routines. ****************/ + +void mpq_init _PROTO ((mpq_ptr)); +void mpq_clear _PROTO ((mpq_ptr)); +void mpq_set _PROTO ((mpq_ptr, mpq_srcptr)); +void mpq_set_ui _PROTO ((mpq_ptr, unsigned long int, unsigned long int)); +void mpq_set_si _PROTO ((mpq_ptr, signed long int, unsigned long int)); +void mpq_set_z _PROTO ((mpq_ptr, mpz_srcptr)); +void mpq_add _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr)); +void mpq_sub _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr)); +void mpq_mul _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr)); +void mpq_div _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr)); +void mpq_neg _PROTO ((mpq_ptr, mpq_srcptr)); +int mpq_cmp _PROTO ((mpq_srcptr, mpq_srcptr)); +int mpq_cmp_ui _PROTO ((mpq_srcptr, unsigned long int, unsigned long int)); +int mpq_equal _PROTO ((mpq_srcptr, mpq_srcptr)); +void mpq_inv _PROTO ((mpq_ptr, mpq_srcptr)); +void mpq_set_num _PROTO ((mpq_ptr, mpz_srcptr)); +void mpq_set_den _PROTO ((mpq_ptr, mpz_srcptr)); +void mpq_get_num _PROTO ((mpz_ptr, mpq_srcptr)); +void mpq_get_den _PROTO ((mpz_ptr, mpq_srcptr)); +double mpq_get_d _PROTO ((mpq_srcptr)); +void mpq_canonicalize _PROTO ((mpq_ptr)); + +/**************** Float (i.e. F) routines. ****************/ + +void mpf_abs _PROTO ((mpf_ptr, mpf_srcptr)); +void mpf_add _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr)); +void mpf_add_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_clear _PROTO ((mpf_ptr)); +int mpf_cmp _PROTO ((mpf_srcptr, mpf_srcptr)); +int mpf_cmp_si _PROTO ((mpf_srcptr, signed long int)); +int mpf_cmp_ui _PROTO ((mpf_srcptr, unsigned long int)); +void mpf_div _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr)); +void mpf_div_2exp _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_div_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_dump _PROTO ((mpf_srcptr)); +int mpf_eq _PROTO ((mpf_srcptr, mpf_srcptr, unsigned long int)); +double mpf_get_d _PROTO ((mpf_srcptr)); +unsigned long int mpf_get_prec _PROTO ((mpf_srcptr)); +char *mpf_get_str _PROTO ((char *, mp_exp_t *, int, size_t, mpf_srcptr)); +void mpf_init _PROTO ((mpf_ptr)); +void mpf_init2 _PROTO ((mpf_ptr, unsigned long int)); +#ifdef _GMP_H_HAVE_FILE +size_t mpf_inp_str _PROTO ((mpf_ptr, FILE *, int)); +#endif +void mpf_init_set _PROTO ((mpf_ptr, mpf_srcptr)); +void mpf_init_set_d _PROTO ((mpf_ptr, double)); +void mpf_init_set_si _PROTO ((mpf_ptr, signed long int)); +int mpf_init_set_str _PROTO ((mpf_ptr, const char *, int)); +void mpf_init_set_ui _PROTO ((mpf_ptr, unsigned long int)); +void mpf_mul _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr)); +void mpf_mul_2exp _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_mul_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_neg _PROTO ((mpf_ptr, mpf_srcptr)); +#ifdef _GMP_H_HAVE_FILE +size_t mpf_out_str _PROTO ((FILE *, int, size_t, mpf_srcptr)); +#endif +void mpf_random2 _PROTO ((mpf_ptr, mp_size_t, mp_exp_t)); +void mpf_reldiff _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr)); +void mpf_set _PROTO ((mpf_ptr, mpf_srcptr)); +void mpf_set_d _PROTO ((mpf_ptr, double)); +void mpf_set_default_prec _PROTO ((unsigned long int)); +void mpf_set_prec _PROTO ((mpf_ptr, unsigned long int)); +void mpf_set_prec_raw _PROTO ((mpf_ptr, unsigned long int)); +void mpf_set_q _PROTO ((mpf_ptr, mpq_srcptr)); +void mpf_set_si _PROTO ((mpf_ptr, signed long int)); +int mpf_set_str _PROTO ((mpf_ptr, const char *, int)); +void mpf_set_ui _PROTO ((mpf_ptr, unsigned long int)); +void mpf_set_z _PROTO ((mpf_ptr, mpz_srcptr)); +size_t mpf_size _PROTO ((mpf_srcptr)); +void mpf_sqrt _PROTO ((mpf_ptr, mpf_srcptr)); +void mpf_sqrt_ui _PROTO ((mpf_ptr, unsigned long int)); +void mpf_sub _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr)); +void mpf_sub_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int)); +void mpf_ui_div _PROTO ((mpf_ptr, unsigned long int, mpf_srcptr)); +void mpf_ui_sub _PROTO ((mpf_ptr, unsigned long int, mpf_srcptr)); +#if defined (__cplusplus) +} +#endif +/************ Low level positive-integer (i.e. N) routines. ************/ + +/* This is ugly, but we need to make usr calls reach the prefixed function. */ +#define mpn_add __MPN(add) +#define mpn_add_1 __MPN(add_1) +#define mpn_add_n __MPN(add_n) +#define mpn_addmul_1 __MPN(addmul_1) +#define mpn_bdivmod __MPN(bdivmod) +#define mpn_cmp __MPN(cmp) +#define mpn_divmod_1 __MPN(divmod_1) +#define mpn_divrem __MPN(divrem) +#define mpn_divrem_1 __MPN(divrem_1) +#define mpn_dump __MPN(dump) +#define mpn_gcd __MPN(gcd) +#define mpn_gcd_1 __MPN(gcd_1) +#define mpn_gcdext __MPN(gcdext) +#define mpn_get_str __MPN(get_str) +#define mpn_hamdist __MPN(hamdist) +#define mpn_lshift __MPN(lshift) +#define mpn_mod_1 __MPN(mod_1) +#define mpn_mul __MPN(mul) +#define mpn_mul_1 __MPN(mul_1) +#define mpn_mul_n __MPN(mul_n) +#define mpn_perfect_square_p __MPN(perfect_square_p) +#define mpn_popcount __MPN(popcount) +#define mpn_preinv_mod_1 __MPN(preinv_mod_1) +#define mpn_random2 __MPN(random2) +#define mpn_rshift __MPN(rshift) +#define mpn_scan0 __MPN(scan0) +#define mpn_scan1 __MPN(scan1) +#define mpn_set_str __MPN(set_str) +#define mpn_sqrtrem __MPN(sqrtrem) +#define mpn_sub __MPN(sub) +#define mpn_sub_1 __MPN(sub_1) +#define mpn_sub_n __MPN(sub_n) +#define mpn_submul_1 __MPN(submul_1) +#define mpn_udiv_w_sdiv __MPN(udiv_w_sdiv) + +#if defined (__cplusplus) +extern "C" { +#endif +mp_limb_t mpn_add _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr,mp_size_t)); +mp_limb_t mpn_add_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)); +mp_limb_t mpn_add_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)); +mp_limb_t mpn_addmul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)); +mp_limb_t mpn_bdivmod _PROTO ((mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, unsigned long int)); +int mpn_cmp _PROTO ((mp_srcptr, mp_srcptr, mp_size_t)); +mp_limb_t mpn_divmod_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)); +mp_limb_t mpn_divrem _PROTO ((mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr, mp_size_t)); +mp_limb_t mpn_divrem_1 _PROTO ((mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t)); +void mpn_dump _PROTO ((mp_srcptr, mp_size_t)); +mp_size_t mpn_gcd _PROTO ((mp_ptr, mp_ptr, mp_size_t, mp_ptr, mp_size_t)); +mp_limb_t mpn_gcd_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb_t)); +mp_size_t mpn_gcdext _PROTO ((mp_ptr, mp_ptr, mp_ptr, mp_size_t, mp_ptr, mp_size_t)); +size_t mpn_get_str _PROTO ((unsigned char *, int, mp_ptr, mp_size_t)); +unsigned long int mpn_hamdist _PROTO ((mp_srcptr, mp_srcptr, mp_size_t)); +mp_limb_t mpn_lshift _PROTO ((mp_ptr, mp_srcptr, mp_size_t, unsigned int)); +mp_limb_t mpn_mod_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb_t)); +mp_limb_t mpn_mul _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t)); +mp_limb_t mpn_mul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)); +void mpn_mul_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)); +int mpn_perfect_square_p _PROTO ((mp_srcptr, mp_size_t)); +unsigned long int mpn_popcount _PROTO ((mp_srcptr, mp_size_t)); +mp_limb_t mpn_preinv_mod_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t)); +void mpn_random2 _PROTO ((mp_ptr, mp_size_t)); +mp_limb_t mpn_rshift _PROTO ((mp_ptr, mp_srcptr, mp_size_t, unsigned int)); +unsigned long int mpn_scan0 _PROTO ((mp_srcptr, unsigned long int)); +unsigned long int mpn_scan1 _PROTO ((mp_srcptr, unsigned long int)); +mp_size_t mpn_set_str _PROTO ((mp_ptr, const unsigned char *, size_t, int)); +mp_size_t mpn_sqrtrem _PROTO ((mp_ptr, mp_ptr, mp_srcptr, mp_size_t)); +mp_limb_t mpn_sub _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr,mp_size_t)); +mp_limb_t mpn_sub_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)); +mp_limb_t mpn_sub_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)); +mp_limb_t mpn_submul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)); +#if defined (__cplusplus) +} +#endif + +#if defined (__GNUC__) || defined (_FORCE_INLINES) +_EXTERN_INLINE mp_limb_t +#if defined (__STDC__) || defined (__cplusplus) +mpn_add_1 (register mp_ptr res_ptr, + register mp_srcptr s1_ptr, + register mp_size_t s1_size, + register mp_limb_t s2_limb) +#else +mpn_add_1 (res_ptr, s1_ptr, s1_size, s2_limb) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_size_t s1_size; + register mp_limb_t s2_limb; +#endif +{ + register mp_limb_t x; + + x = *s1_ptr++; + s2_limb = x + s2_limb; + *res_ptr++ = s2_limb; + if (s2_limb < x) + { + while (--s1_size != 0) + { + x = *s1_ptr++ + 1; + *res_ptr++ = x; + if (x != 0) + goto fin; + } + + return 1; + } + + fin: + if (res_ptr != s1_ptr) + { + mp_size_t i; + for (i = 0; i < s1_size - 1; i++) + res_ptr[i] = s1_ptr[i]; + } + return 0; +} + +_EXTERN_INLINE mp_limb_t +#if defined (__STDC__) || defined (__cplusplus) +mpn_add (register mp_ptr res_ptr, + register mp_srcptr s1_ptr, + register mp_size_t s1_size, + register mp_srcptr s2_ptr, + register mp_size_t s2_size) +#else +mpn_add (res_ptr, s1_ptr, s1_size, s2_ptr, s2_size) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_size_t s1_size; + register mp_srcptr s2_ptr; + register mp_size_t s2_size; +#endif +{ + mp_limb_t cy_limb = 0; + + if (s2_size != 0) + cy_limb = mpn_add_n (res_ptr, s1_ptr, s2_ptr, s2_size); + + if (s1_size - s2_size != 0) + cy_limb = mpn_add_1 (res_ptr + s2_size, + s1_ptr + s2_size, + s1_size - s2_size, + cy_limb); + return cy_limb; +} + +_EXTERN_INLINE mp_limb_t +#if defined (__STDC__) || defined (__cplusplus) +mpn_sub_1 (register mp_ptr res_ptr, + register mp_srcptr s1_ptr, + register mp_size_t s1_size, + register mp_limb_t s2_limb) +#else +mpn_sub_1 (res_ptr, s1_ptr, s1_size, s2_limb) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_size_t s1_size; + register mp_limb_t s2_limb; +#endif +{ + register mp_limb_t x; + + x = *s1_ptr++; + s2_limb = x - s2_limb; + *res_ptr++ = s2_limb; + if (s2_limb > x) + { + while (--s1_size != 0) + { + x = *s1_ptr++; + *res_ptr++ = x - 1; + if (x != 0) + goto fin; + } + + return 1; + } + + fin: + if (res_ptr != s1_ptr) + { + mp_size_t i; + for (i = 0; i < s1_size - 1; i++) + res_ptr[i] = s1_ptr[i]; + } + return 0; +} + +_EXTERN_INLINE mp_limb_t +#if defined (__STDC__) || defined (__cplusplus) +mpn_sub (register mp_ptr res_ptr, + register mp_srcptr s1_ptr, + register mp_size_t s1_size, + register mp_srcptr s2_ptr, + register mp_size_t s2_size) +#else +mpn_sub (res_ptr, s1_ptr, s1_size, s2_ptr, s2_size) + register mp_ptr res_ptr; + register mp_srcptr s1_ptr; + register mp_size_t s1_size; + register mp_srcptr s2_ptr; + register mp_size_t s2_size; +#endif +{ + mp_limb_t cy_limb = 0; + + if (s2_size != 0) + cy_limb = mpn_sub_n (res_ptr, s1_ptr, s2_ptr, s2_size); + + if (s1_size - s2_size != 0) + cy_limb = mpn_sub_1 (res_ptr + s2_size, + s1_ptr + s2_size, + s1_size - s2_size, + cy_limb); + return cy_limb; +} +#endif /* __GNUC__ */ + +/* Allow faster testing for negative, zero, and positive. */ +#define mpz_sgn(Z) ((Z)->_mp_size < 0 ? -1 : (Z)->_mp_size > 0) +#define mpf_sgn(F) ((F)->_mp_size < 0 ? -1 : (F)->_mp_size > 0) +#define mpq_sgn(Q) ((Q)->_mp_num._mp_size < 0 ? -1 : (Q)->_mp_num._mp_size > 0) + +/* Allow direct user access to numerator and denominator of a mpq_t object. */ +#define mpq_numref(Q) (&((Q)->_mp_num)) +#define mpq_denref(Q) (&((Q)->_mp_den)) + +/* When using GCC, optimize certain common comparisons. */ +#if defined (__GNUC__) +#define mpz_cmp_ui(Z,UI) \ + (__builtin_constant_p (UI) && (UI) == 0 \ + ? mpz_sgn (Z) : mpz_cmp_ui (Z,UI)) +#define mpz_cmp_si(Z,UI) \ + (__builtin_constant_p (UI) && (UI) == 0 ? mpz_sgn (Z) \ + : __builtin_constant_p (UI) && (UI) > 0 ? mpz_cmp_ui (Z,UI) \ + : mpz_cmp_si (Z,UI)) +#define mpq_cmp_ui(Q,NUI,DUI) \ + (__builtin_constant_p (NUI) && (NUI) == 0 \ + ? mpq_sgn (Q) : mpq_cmp_ui (Q,NUI,DUI)) +#endif + +#define mpn_divmod(qp,np,nsize,dp,dsize) mpn_divrem (qp,0,np,nsize,dp,dsize) +#if 0 +#define mpn_divmod_1(qp,np,nsize,dlimb) mpn_divrem_1 (qp,0,np,nsize,dlimb) +#endif + +/* Compatibility with GMP 1. */ +#define mpz_mdiv mpz_fdiv_q +#define mpz_mdivmod mpz_fdiv_qr +#define mpz_mmod mpz_fdiv_r +#define mpz_mdiv_ui mpz_fdiv_q_ui +#define mpz_mdivmod_ui(q,r,n,d) \ + ((r == 0) ? mpz_fdiv_q_ui (q,n,d) : mpz_fdiv_qr_ui (q,r,n,d)) +#define mpz_mmod_ui(r,n,d) \ + ((r == 0) ? mpz_fdiv_ui (n,d) : mpz_fdiv_r_ui (r,n,d)) + +/* Useful synonyms, but not quite compatible with GMP 1. */ +#define mpz_div mpz_fdiv_q +#define mpz_divmod mpz_fdiv_qr +#define mpz_div_ui mpz_fdiv_q_ui +#define mpz_divmod_ui mpz_fdiv_qr_ui +#define mpz_mod_ui mpz_fdiv_r_ui +#define mpz_div_2exp mpz_fdiv_q_2exp +#define mpz_mod_2exp mpz_fdiv_r_2exp + +#define __GNU_MP_VERSION 2 +#define __GNU_MP_VERSION_MINOR 0 +#define __GMP_H__ +#endif /* __GMP_H__ */ diff --git a/source/Linemode/linemode.c b/source/Linemode/linemode.c index f02f99d..046b809 100755 --- a/source/Linemode/linemode.c +++ b/source/Linemode/linemode.c @@ -1 +1 @@ -// linemode.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "wind.h" #include "parse.h" #include "linemode.proto.h" #include "network.proto.h" #include "parse.proto.h" #include "vsdata.h" #include "vsinterf.proto.h" #ifdef MPW #pragma segment Parse #endif //#define OPTS_DEBUG #ifdef OPTS_DEBUG extern char *telstates[]; extern char *teloptions[]; extern char *LMoptions[]; extern char *LMflags[]; extern char *LMmodes[]; extern char *LMmodeBits[]; #define opts_debug_print(x) putln(x) #else #define opts_debug_print(x) #endif static void DemangleLineMode(char *s, short mode); static void setForwardMask(struct WindRec *tw); //set the keys on which we forward on static void negotiateSLC(struct WindRec *tw); static void respondSLC(short optionNumber,short *alreadySentSB,struct WindRec *tw, Boolean AWK); static unsigned char str_lm[] = { TEL_IAC, TEL_SB, N_LINEMODE, 0, 0, TEL_IAC, TEL_SE }; static unsigned char str_lm_mode[] = { TEL_IAC, TEL_SB, N_LINEMODE, L_MODE, 0, TEL_IAC, TEL_SE }; static unsigned char default_slc[] = { 255, 255, 255, DEFAULT_SLC_IP,DEFAULT_SLC_AO,0,0,DEFAULT_SLC_ABORT,DEFAULT_SLC_EOF, DEFAULT_SLC_SUSP,DEFAULT_SLC_EC,DEFAULT_SLC_EL,DEFAULT_SLC_EW,DEFAULT_SLC_RP, DEFAULT_SLC_LNEXT,DEFAULT_SLC_XON,DEFAULT_SLC_XOFF,DEFAULT_SLC_FORW1,DEFAULT_SLC_FORW2,255,255,255,255,255,255,255,255,255,255,255,255 }; #ifdef OPTS_DEBUG static char munger[255]; #endif void LinemodeUnload(void) {} void initLinemode(struct WindRec *tw) { short temp; for (temp=0; temp<= SLC_MAX; temp++) { tw->slc[temp] = default_slc[temp]; if (default_slc[temp] == 255) tw->slcLevel[temp] = SLC_NOSUPPORT; else tw->slcLevel[temp] = SLC_VALUE; } tw->lmodeBits = 0; tw->litNext = 0; tw->lmode = 0; } void process_key(unsigned char ascii,struct WindRec *tw) { if (tw->litNext) //do no processing on next key { tw->litNext = FALSE; if (tw->kblen < (MAXKB -1)) /* Add to buffer if not full */ tw->kbbuf[tw->kblen++] = ascii; else { netpush(tw->port); netwrite( tw->port, tw->kbbuf, tw->kblen); /* if full send buffer */ tw->kbbuf[0]=ascii; tw->kblen=1; } if (tw->echo) { if (ascii>31 && ascii <127) /* add these chars to buffer */ { parse(tw, &ascii, 1); return; } else return; } } if (tw->lmodeBits & 2) // TRAPSIG mode active { unsigned char toSend[2] = {IAC,0}; short whichSignal = 0; if (ascii == tw->slc[SLC_IP]) { whichSignal = SLC_IP; toSend[1] = TEL_SUSP; } else if (ascii == tw->slc[SLC_ABORT]) { whichSignal = SLC_ABORT; toSend[1] = TEL_ABORT; } if (toSend[1]) //if we have a signal to catch { if (tw->echo) parse(tw, &ascii, 1); // echo if we should tw->kblen=0; //zero out the buffer netpush(tw->port); netwrite(tw->port,toSend,2); //send IAC whatever if (tw->slcLevel[whichSignal] & SLC_FLUSHIN) { unsigned char dm[2] = {IAC,TEL_DM}; netpush(tw->port); netUrgent();//send next as urgent data netwrite(tw->port,dm,2);//send IAC DM } if (tw->slcLevel[whichSignal] & SLC_FLUSHOUT) { unsigned char tm[3] = {IAC,TEL_DOTEL,N_TIMING}; tw->timing = 1; //tell ourselves to wait for WILL TIMING netpush(tw->port); netwrite(tw->port,tm,3);//send DO TIMING } return; } } if ((tw->lmodeBits & L_SOFT_TAB)&&(ascii == 0x09)) // SOFT_TAB mode active; expand tab into spaces { short numSpaces = VSIgetNextTabDistance(); while (numSpaces > 0) { while ((numSpaces > 0)&&(tw->kblen < (MAXKB -1))) { tw->kbbuf[tw->kblen++] = 0x20; //space numSpaces--; } if (tw->kblen == (MAXKB -1)) { netpush(tw->port); netwrite( tw->port, tw->kbbuf, tw->kblen); /* if full send buffer */ tw->kblen=0; } } if (tw->echo) parse(tw, &ascii, 1); return; } if (tw->lmodeBits & L_EDIT) //handle editing functions { if (ascii == '\015') //CR { //since we are in edit, send the buffer and CR-LF if (tw->kblen > 0) netwrite(tw->port, tw->kbbuf, tw->kblen); netpush(tw->port); netwrite(tw->port,"\015\012",2); tw->kblen = 0; if (tw->echo) parse(tw,(unsigned char *) "\012\015",2); return; } if (ascii == tw->slc[SLC_EC]) //kill the character { if (tw->echo) parse(tw,(unsigned char *) "\010 \010",3); tw->kblen--; return; } else if (ascii == tw->slc[SLC_AO]) //kill the line { while (tw->kblen >0) { if (tw->echo) parse(tw,(unsigned char *) "\010 \010",3); tw->kblen--; } return; } else if (ascii == tw->slc[SLC_EL]) //kill the line { while (tw->kblen >0) { if (tw->echo) parse(tw,(unsigned char *) "\010 \010",3); tw->kblen--; } return; } else if (ascii == tw->slc[SLC_EOF]) { //push the buffer, send IAC EOF char eofString[2] = { IAC, TEL_EOF }; if (tw->kblen > 0) netwrite(tw->port, tw->kbbuf, tw->kblen); tw->kbbuf[0]=ascii; tw->kblen=1; netpush(tw->port); netwrite(tw->port,eofString, 2); return; } else if (ascii == tw->slc[SLC_SUSP]) { char eofString[2] = { IAC, TEL_SUSP }; if (tw->kblen > 0) netwrite(tw->port, tw->kbbuf, tw->kblen); tw->kblen = 0; netpush(tw->port); netwrite(tw->port,eofString, 2); return; } else if (ascii == tw->slc[SLC_EW]) { while ((tw->kbbuf[tw->kblen-1] != 0x20)&&(tw->kblen >= 0)) //while its not a space { if (tw->echo) parse(tw,(unsigned char *)"\010 \010",3); tw->kblen--; } } else if (ascii == tw->slc[SLC_RP]) { VSredrawLine(tw->vs); return; } else if (ascii == tw->slc[SLC_LNEXT]) { tw->litNext = TRUE; return; } else if (ascii == tw->slc[SLC_XON]) { if (tw->allow_flow) //remote flow control can turn this off tw->enabled = 0; return; } else if (ascii == tw->slc[SLC_XOFF]) { if (tw->allow_flow) //remote flow control can turn this off tw->enabled = 0; return; } else if ((ascii == tw->slc[SLC_FORW1])||(ascii == tw->slc[SLC_FORW1])) { if (tw->kblen > 0) netwrite(tw->port, tw->kbbuf, tw->kblen); netpush(tw->port); netwrite(tw->port,&ascii,1); tw->kblen = 0; return; } //ok, at this point, we are past all local editing functions. Now, add the character to the buffer. else { if (tw->kblen < (MAXKB -1)) // Add to buffer if not full tw->kbbuf[tw->kblen++] = ascii; else { netpush(tw->port); netwrite( tw->port, tw->kbbuf, tw->kblen); // if full send buffer tw->kbbuf[0]=ascii; tw->kblen=1; } } } else if (ascii == '\015') //CR; map this to CR-LF { unsigned char toSend[2] = {0x0D,0x00}; netpush(tw->port); netwrite(tw->port,toSend,2); if (tw->echo) parse(tw,(unsigned char *) "\012\015",2); return; } else //not editing; send it { netpush(tw->port); netwrite( tw->port, &ascii, 1); // if full send buffer } if (tw->echo) /* Handle local ECHOs */ { if (ascii>31 && ascii <127) /* add these chars to buffer */ parse(tw, &ascii, 1); else /* not printable char */ { if (!(tw->lmodeBits & L_LIT_ECHO)) //don't echo if this is set { ascii='@'+ascii; parse(tw,(unsigned char *) "^",1); parse(tw, &ascii, 1); } } } } void linemode_suboption(struct WindRec *tw) { switch(tw->parsedat[1]) { char s[80]; case L_MODE: /* change mode */ #ifdef OPTS_DEBUG strcpy(s, "RECV: SB LINEMODE MODE => "); DemangleLineModeShort(s, tw->parsedat[2]); opts_debug_print(s); #endif if (tw->lineAllow) { // First make sure we allowed linemode in the first place. // RFC 1184 says client should ignore MODE negotiations with the MODE_ACK bit set, and should not // generate a response if the negotiated MODE matches the current MODE if (!((tw->parsedat[2] & L_MODE_ACK) || ((tw->parsedat[2] & L_MODE_MASK) == tw->lmodeBits))) { tw->lmodeBits = tw->parsedat[2]; // Accept the mode tw->parsedat[2] |= L_MODE_ACK; // Set the MODE_ACK bit sprintf(s,"%c%c%c%c",IAC,TEL_SB,N_LINEMODE,L_MODE); netwrite(tw->port,s,4); sprintf(s,"%c%c%c",tw->parsedat[2],IAC,TEL_SE); netwrite(tw->port,s,3); #ifdef OPTS_DEBUG opts_debug_print("SENT: IAC SB"); strcpy(s, "SENT: LM MODE = "); DemangleLineModeShort(s, tw->parsedat[2]); opts_debug_print(s); opts_debug_print("SENT: IAC SE"); #endif } #ifdef OPTS_DEBUG else { strcpy(s, "LINEMODE MODE = "); DemangleLineModeShort(s, tw->parsedat[2]); opts_debug_print(s); if (tw->parsedat[2] & L_MODE_ACK) opts_debug_print("\tignored because MODE_ACK was set."); else opts_debug_print("\tIgnored because we are already at that mode."); strcpy(s, "Curr Linemode = "); DemangleLineModeShort(s, tw->lmodeBits); opts_debug_print(s); } #endif } break; case TEL_DOTEL: #ifdef OPTS_DEBUG sprintf(munger,"RECV: SB LINEMODE DO %c", tw->parsedat[2]); opts_debug_print(munger); #endif tw->forwardMask = TRUE; setForwardMask(tw); str_lm[3] = TEL_WILLTEL; str_lm[4] = L_FORWARDMASK; netpush(tw->port); netwrite(tw->port, str_lm, sizeof(str_lm)); #ifdef OPTS_DEBUG sprintf(munger,"SENT: IAC SB LINEMODE WILL %c IAC SE", tw->parsedat[2]); opts_debug_print(munger); #endif break; case TEL_DONTTEL: #ifdef OPTS_DEBUG sprintf(munger,"RECV: SB LINEMODE DO %c", tw->parsedat[2]); opts_debug_print(munger); #endif tw->forwardMask = FALSE; str_lm[3] = TEL_WONTTEL; str_lm[4] = L_FORWARDMASK; netpush(tw->port); netwrite(tw->port, str_lm, sizeof(str_lm)); #ifdef OPTS_DEBUG sprintf(munger,"SENT: IAC SB LINEMODE WONT %c IAC SE", tw->parsedat[2]); opts_debug_print(munger); #endif break; case L_SLC: /* set local chars */ negotiateSLC(tw); break; default: #ifdef OPTS_DEBUG sprintf(munger, "RECV: SB LINEMODE ?? (?? = %c)", tw->parsedat[1]); opts_debug_print(munger); #endif break; }//switch parsedat } void setForwardMask(struct WindRec *tw) //set the keys on which we forward on { short j, i = 3; Boolean anotherByte = TRUE; tw->numForwardKeys = 1; while((tw->parsedat[i] != 0)&&(i < 35)) { if (tw->parsedat[i] == 255) { i++; //could be doubled IAC if(tw->parsedat[i+1] == TEL_SE) { anotherByte = FALSE; //but its not i--; } } if (anotherByte) for(j = 0; j < 8; j++) { if (tw->parsedat[i] & (j*2)) { tw->forwardKeys[tw->numForwardKeys-1] = (i-3)*8 + j; tw->numForwardKeys++; } } else break; i++;//next byte } for (i = tw->numForwardKeys; i < 32; i++) //zero the rest of the array tw->forwardKeys[i] = 0; } void respondSLC(short optionNumber,short *alreadySentSB,struct WindRec *tw, Boolean AWK) { unsigned char stuffToSend[3]; unsigned char subBeginSeq[4] = {IAC,TEL_SB,N_LINEMODE,L_SLC}; stuffToSend[0] = optionNumber; stuffToSend[1] = tw->slcLevel[optionNumber]; if (AWK) stuffToSend[1] |= SLC_AWK; stuffToSend[2] = tw->slc[optionNumber]; if (!(*alreadySentSB)) { *alreadySentSB = TRUE; netwrite(tw->port, subBeginSeq, 4); opts_debug_print("SENT: IAC SB LINEMODE SLC"); } if (stuffToSend[2] == IAC) { netwrite(tw->port, stuffToSend,2); netwrite(tw->port, subBeginSeq,1); //double the IAC netwrite(tw->port, subBeginSeq,1); } else netwrite(tw->port, stuffToSend, 3); #ifdef OPTS_DEBUG if (AWK) { if ((tw->slcLevel[optionNumber] & (SLC_FLUSHIN | SLC_FLUSHOUT)) == (SLC_FLUSHIN | SLC_FLUSHOUT)) sprintf(munger,"\t %s %s | AWK | FLUSHIN | FLUSHOUT %d",LMoptions[optionNumber],LMflags[SLC_LEVELBITS & tw->slcLevel[optionNumber]],tw->slc[optionNumber]); else if (tw->slcLevel[optionNumber] & SLC_FLUSHIN) sprintf(munger,"\t %s %s | AWK | FLUSHIN %d",LMoptions[optionNumber],LMflags[SLC_LEVELBITS & tw->slcLevel[optionNumber]],tw->slc[optionNumber]); else if (tw->slcLevel[optionNumber] & SLC_FLUSHOUT) sprintf(munger,"\t %s %s | AWK | FLUSHOUT %d",LMoptions[optionNumber],LMflags[SLC_LEVELBITS & tw->slcLevel[optionNumber]],tw->slc[optionNumber]); else sprintf(munger,"\t %s %s | AWK %d",LMoptions[optionNumber],LMflags[tw->slcLevel[optionNumber]],tw->slc[optionNumber]); } else { if ((tw->slcLevel[optionNumber] & (SLC_FLUSHIN | SLC_FLUSHOUT)) == (SLC_FLUSHIN | SLC_FLUSHOUT)) sprintf(munger,"\t %s %s | AWK | FLUSHIN | FLUSHOUT %d",LMoptions[optionNumber],LMflags[SLC_LEVELBITS & tw->slcLevel[optionNumber]],tw->slc[optionNumber]); else if (tw->slcLevel[optionNumber] & SLC_FLUSHIN) sprintf(munger,"\t %s %s | FLUSHIN %d",LMoptions[optionNumber],LMflags[SLC_LEVELBITS & tw->slcLevel[optionNumber]],tw->slc[optionNumber]); else if (tw->slcLevel[optionNumber] & SLC_FLUSHOUT) sprintf(munger,"\t %s %s | FLUSHOUT %d",LMoptions[optionNumber],LMflags[SLC_LEVELBITS & tw->slcLevel[optionNumber]],tw->slc[optionNumber]); else sprintf(munger,"\t %s %s %d",LMoptions[optionNumber],LMflags[tw->slcLevel[optionNumber]],tw->slc[optionNumber]); } opts_debug_print(munger); #endif } void negotiateSLC(struct WindRec *tw) { short lmslcflag = 0; unsigned char *ourValues = tw->slc; unsigned char *ourLevels = tw->slcLevel; short i; #ifdef OPTS_DEBUG sprintf(munger,"RECV: IAC SB LINEMODE SLC"); opts_debug_print(munger); for(i=2;i <= tw->parseIndex - 3; i+=3) { if (tw->parsedat[i] > 30) DebugStr("\pAck! Bad option number"); if(tw->parsedat[i+1] & SLC_AWK) sprintf(munger," %s %s|AWK %d",LMoptions[tw->parsedat[i]],LMflags[tw->parsedat[i+1] & SLC_LEVELBITS],tw->parsedat[i+2]); else sprintf(munger," %s %s %d",LMoptions[tw->parsedat[i]],LMflags[tw->parsedat[i+1] & SLC_LEVELBITS],tw->parsedat[i+2]); opts_debug_print(munger); } sprintf(munger,"RECV: IAC SE"); opts_debug_print(munger); #endif for (i=2, lmslcflag=0; i <= tw->parseIndex - 3; i+=3) { short optionNumber = tw->parsedat[i]; Boolean awked = (tw->parsedat[i+1] & SLC_AWK); unsigned char requestedValue = tw->parsedat[i+2]; unsigned char requestedLevel = tw->parsedat[i+1] & SLC_LEVELBITS; Boolean flushin = tw->parsedat[i+1] & SLC_FLUSHIN; Boolean flushout = tw->parsedat[i+1] & SLC_FLUSHOUT; if ((ourValues[optionNumber] != requestedValue)||(ourLevels[optionNumber] != tw->parsedat[i+1])) //if we are sent what we already have, ignore it { if (requestedLevel == SLC_NOSUPPORT) { if (ourLevels[optionNumber] & SLC_LEVELBITS != SLC_NOSUPPORT) { ourValues[optionNumber] = 255; ourLevels[optionNumber] = SLC_NOSUPPORT;//ok, we wont support this if (!awked) respondSLC(optionNumber,&lmslcflag, tw, TRUE);//awk only if he didnt awk #ifdef OPTS_DEBUG else { sprintf(munger,"\t %s %s %d accepted; no response sent because it was AWKED", LMoptions[optionNumber],LMflags[requestedLevel],requestedValue); opts_debug_print(munger); } #endif } #ifdef OPTS_DEBUG else { sprintf(munger, "\t %s %s %d Ignored because we are already at nosupport", LMoptions[optionNumber],LMflags[requestedLevel],ourValues[optionNumber]); opts_debug_print(munger); } #endif } else if (requestedLevel == SLC_DEFAULT) { ourValues[optionNumber] = default_slc[optionNumber]; //get our default if (ourValues[optionNumber] == 255) ourLevels[optionNumber] = SLC_NOSUPPORT; else ourLevels[optionNumber] = SLC_VALUE; respondSLC(optionNumber, &lmslcflag, tw, FALSE); //tell him about our choice } else if (requestedLevel > ourLevels[optionNumber]) respondSLC(optionNumber, &lmslcflag, tw, FALSE); //keep lower setting else { ourValues[optionNumber] = requestedValue; ourLevels[optionNumber] = requestedLevel; if (flushin) ourLevels[optionNumber] |= SLC_FLUSHIN; if (flushout) ourLevels[optionNumber] |= SLC_FLUSHOUT; if (!awked) respondSLC(optionNumber, &lmslcflag, tw, TRUE); //agree to his new setting } } #ifdef OPTS_DEBUG else { sprintf(munger, "\t %s %s Ignored because %d is already the current value", LMoptions[optionNumber],LMflags[requestedLevel],ourValues[optionNumber]); opts_debug_print(munger); } #endif }//end for on parseindex if (lmslcflag) { unsigned char toSend[2] = {IAC,TEL_SE}; netpush(tw->port); netwrite(tw->port,toSend,2); opts_debug_print("SENT: IAC SE"); } } void doLinemode(struct WindRec *tw) { short i; unsigned char subBeginSeq[4] = {IAC,TEL_SB,N_LINEMODE,L_SLC}; unsigned char subEndSeq[2] = {IAC,TEL_SE}; unsigned char toSend[3]; tw->lmodeBits = 0; tw->lmode = TRUE; tw->litNext = FALSE; netwrite(tw->port,subBeginSeq,4); opts_debug_print("SENT: IAC SB LINEMODE SLC"); for (i=1; i<= SLC_MAX; i++) { if (tw->slc[i]==255) { toSend[0] = i; toSend[1] = SLC_NOSUPPORT; toSend[2] = 0; #ifdef OPTS_DEBUG sprintf(munger," %s NO_SUPPORT 0",LMoptions[i]); #endif } else { toSend[0] = i; toSend[1] = SLC_VALUE; toSend[2] = tw->slc[i]; #ifdef OPTS_DEBUG sprintf(munger," %s VALUE %d",LMoptions[i],(short)tw->slc[i]); #endif } opts_debug_print(munger); netwrite(tw->port,toSend,3); } opts_debug_print("SENT: IAC SE"); netpush(tw->port); netwrite(tw->port,subEndSeq,2); } static void DemangleLineMode(char *s, short mode) { #ifdef OPTS_DEBUG short i; for (i=0; i<5; i++) { if (mode & (1 << i)) strcat(s, LMmodes[i]); } #endif } void DemangleLineModeShort(char *s, short mode) { #ifdef OPTS_DEBUG short i; for (i=0; i<5; i++) { if (mode & (1 << i)) strcat(s, LMmodeBits[i]); else strcat(s," "); } #endif } \ No newline at end of file +// linemode.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "wind.h" #include "parse.h" #include "linemode.proto.h" #include "network.proto.h" #include "parse.proto.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "menuseg.proto.h" //#define OPTS_DEBUG #ifdef OPTS_DEBUG extern char *telstates[]; extern char *teloptions[]; extern char *LMoptions[]; extern char *LMflags[]; extern char *LMmodes[]; extern char *LMmodeBits[]; #define opts_debug_print(x) putln(x) #else #define opts_debug_print(x) #endif extern short scrn; static void DemangleLineMode(char *s, short mode); static void setForwardMask(struct WindRec *tw); //set the keys on which we forward on static void negotiateSLC(struct WindRec *tw); static void respondSLC(short optionNumber,short *alreadySentSB,struct WindRec *tw, Boolean AWK); static unsigned char str_lm[] = { TEL_IAC, TEL_SB, N_LINEMODE, 0, 0, TEL_IAC, TEL_SE }; static unsigned char str_lm_mode[] = { TEL_IAC, TEL_SB, N_LINEMODE, L_MODE, 0, TEL_IAC, TEL_SE }; static unsigned char default_slc[] = { 255, 255, DEFAULT_SLC_BRK, DEFAULT_SLC_IP,DEFAULT_SLC_AO,0,0,DEFAULT_SLC_ABORT,DEFAULT_SLC_EOF, DEFAULT_SLC_SUSP,DEFAULT_SLC_EC,DEFAULT_SLC_EL,DEFAULT_SLC_EW,DEFAULT_SLC_RP, DEFAULT_SLC_LNEXT,DEFAULT_SLC_XON,DEFAULT_SLC_XOFF,DEFAULT_SLC_FORW1,DEFAULT_SLC_FORW2,255,255,255,255,255,255,255,255,255,255,255,255 }; #ifdef OPTS_DEBUG static char munger[255]; #endif void LinemodeUnload(void) {} void initLinemode(struct WindRec *tw) { short temp; for (temp=0; temp<= SLC_MAX; temp++) { tw->slc[temp] = default_slc[temp]; if (default_slc[temp] == 255) tw->slcLevel[temp] = SLC_NOSUPPORT; else tw->slcLevel[temp] = SLC_VALUE; } tw->lmodeBits = 0; tw->litNext = 0; tw->lmode = 0; } void process_key(unsigned char ascii,struct WindRec *tw) { if (tw->litNext) //do no processing on next key { tw->litNext = FALSE; if (tw->kblen < (MAXKB -1)) /* Add to buffer if not full */ tw->kbbuf[tw->kblen++] = ascii; else { netpush(tw->port); netwrite( tw->port, tw->kbbuf, tw->kblen); /* if full send buffer */ tw->kbbuf[0]=ascii; tw->kblen=1; } if (tw->echo) { if (ascii>31 && ascii <127) /* add these chars to buffer */ { parse(tw, &ascii, 1); return; } else return; } } if (tw->lmodeBits & 2) // TRAPSIG mode active { unsigned char toSend[2] = {IAC,0}; short whichSignal = 0; if (ascii == tw->slc[SLC_IP]) { whichSignal = SLC_IP; toSend[1] = TEL_IP; // RAB BetterTelnet 2.0b1 } else if (ascii == tw->slc[SLC_SUSP]) // RAB BetterTelnet 2.0b1 { whichSignal = SLC_SUSP; toSend[1] = TEL_SUSP; } // RAB BetterTelnet 2.0b1 // The defaults in parse.h are to send ABORT on ^\ which is usually correct, but // feel free to hack this (in parse.h, not here) if BRK is better in your configuration. else if (ascii == tw->slc[SLC_ABORT]) { whichSignal = SLC_ABORT; toSend[1] = TEL_ABORT; } else if (ascii == tw->slc[SLC_BRK]) // RAB BetterTelnet 2.0b1 { whichSignal = SLC_BRK; toSend[1] = TEL_BREAK; } if (toSend[1]) //if we have a signal to catch { // if (tw->echo) // parse(tw, &ascii, 1); // echo if we should tw->kblen=0; //zero out the buffer netpush(tw->port); netwrite(tw->port,toSend,2); //send IAC whatever if (tw->slcLevel[whichSignal] & SLC_FLUSHIN) { unsigned char dm[2] = {IAC,TEL_DM}; netpush(tw->port); netUrgent();//send next as urgent data netwrite(tw->port,dm,2);//send IAC DM } if (tw->slcLevel[whichSignal] & SLC_FLUSHOUT) { unsigned char tm[3] = {IAC,TEL_DOTEL,N_TIMING}; tw->timing = 1; //tell ourselves to wait for WILL TIMING netpush(tw->port); netwrite(tw->port,tm,3);//send DO TIMING } return; } } if ((tw->lmodeBits & L_SOFT_TAB)&&(ascii == 0x09)) // SOFT_TAB mode active; expand tab into spaces { short numSpaces = VSIgetNextTabDistance(); while (numSpaces > 0) { while ((numSpaces > 0)&&(tw->kblen < (MAXKB -1))) { tw->kbbuf[tw->kblen++] = 0x20; //space numSpaces--; } if (tw->kblen == (MAXKB -1)) { netpush(tw->port); netwrite( tw->port, tw->kbbuf, tw->kblen); /* if full send buffer */ tw->kblen=0; } } if (tw->echo) parse(tw, &ascii, 1); return; } if (tw->lmodeBits & L_EDIT) //handle editing functions { if (ascii == '\015') //CR { //since we are in edit, send the buffer and CR-LF if (tw->kblen > 0) netwrite(tw->port, tw->kbbuf, tw->kblen); netpush(tw->port); netwrite(tw->port,"\015\012",2); tw->kblen = 0; if (tw->echo) parse(tw,(unsigned char *) "\012\015",2); return; } if (ascii == tw->slc[SLC_EC]) //kill the character { if (tw->echo) parse(tw,(unsigned char *) "\010 \010",3); tw->kblen--; return; } else if (ascii == tw->slc[SLC_AO]) //kill the line { while (tw->kblen >0) { if (tw->echo) parse(tw,(unsigned char *) "\010 \010",3); tw->kblen--; } return; } else if (ascii == tw->slc[SLC_EL]) //kill the line { while (tw->kblen >0) { if (tw->echo) parse(tw,(unsigned char *) "\010 \010",3); tw->kblen--; } return; } else if ((ascii == tw->slc[SLC_EOF]) && (tw->lmodeBits & 2)) { //push the buffer, send IAC EOF (RAB BetterTelnet 2.0b1 - only under TRAPSIG) char eofString[2] = { IAC, TEL_EOF }; if (tw->kblen > 0) netwrite(tw->port, tw->kbbuf, tw->kblen); // RAB BetterTelnet 2.0b1 - BAD! BAD! BAD! // Fix for *BSD (and probably others): // Putting ^D into Telnet's key buffer after sending an EOF could make it pop up later, so // hitting some keys (arrows seemed to do the trick) that flushed Telnet's key buffer // after a cat command which terminated with ^D caused a logout. Yuck. // tw->kbbuf[0]=ascii; // tw->kblen=1; tw->kblen = 0; netpush(tw->port); netwrite(tw->port,eofString, 2); return; } // RAB BetterTelnet 2.0b1 // We don't need to do this down here if we're already handling TRAPSIG mode // separately. The SUSP (usually ^Z) char is part of TRAPSIG, not EDIT. // else if (ascii == tw->slc[SLC_SUSP]) // { // char eofString[2] = { IAC, TEL_SUSP }; // if (tw->kblen > 0) // netwrite(tw->port, tw->kbbuf, tw->kblen); // tw->kblen = 0; // netpush(tw->port); // netwrite(tw->port,eofString, 2); // return; // } else if (ascii == tw->slc[SLC_EW]) { while ((tw->kbbuf[tw->kblen-1] != 0x20)&&(tw->kblen >= 0)) //while its not a space { if (tw->echo) parse(tw,(unsigned char *)"\010 \010",3); tw->kblen--; } } else if (ascii == tw->slc[SLC_RP]) { VSredrawLine(tw->vs); return; } else if (ascii == tw->slc[SLC_LNEXT]) { tw->litNext = TRUE; return; } else if (ascii == tw->slc[SLC_XON]) { if (tw->allow_flow) { //remote flow control can turn this off tw->enabled = 1; // oops small bug (RAB BetterTelnet 2.0b1) changeport(scrn, scrn); } return; } else if (ascii == tw->slc[SLC_XOFF]) { if (tw->allow_flow) { //remote flow control can turn this off tw->enabled = 0; changeport(scrn, scrn); } return; } else if ((ascii == tw->slc[SLC_FORW1])||(ascii == tw->slc[SLC_FORW1])) { if (tw->kblen > 0) netwrite(tw->port, tw->kbbuf, tw->kblen); netpush(tw->port); netwrite(tw->port,&ascii,1); tw->kblen = 0; return; } //ok, at this point, we are past all local editing functions. Now, add the character to the buffer. else { if (tw->kblen < (MAXKB -1)) // Add to buffer if not full tw->kbbuf[tw->kblen++] = ascii; else { netpush(tw->port); netwrite( tw->port, tw->kbbuf, tw->kblen); // if full send buffer tw->kbbuf[0]=ascii; tw->kblen=1; } } } else if (ascii == '\015') //CR; map this to CR-LF { unsigned char toSend[2] = {0x0D,0x00}; netpush(tw->port); netwrite(tw->port,toSend,2); if (tw->echo) parse(tw,(unsigned char *) "\012\015",2); return; } else //not editing; send it { netpush(tw->port); netwrite( tw->port, &ascii, 1); // if full send buffer } if (tw->echo) /* Handle local ECHOs */ { if (ascii>31 && ascii <127) /* add these chars to buffer */ parse(tw, &ascii, 1); else /* not printable char */ { if (!(tw->lmodeBits & L_LIT_ECHO)) //don't echo if this is set { ascii='@'+ascii; parse(tw,(unsigned char *) "^",1); parse(tw, &ascii, 1); } } } } void linemode_suboption(struct WindRec *tw) { switch(tw->parsedat[1]) { char s[80]; case L_MODE: /* change mode */ #ifdef OPTS_DEBUG strcpy(s, "RECV: SB LINEMODE MODE => "); DemangleLineModeShort(s, tw->parsedat[2]); opts_debug_print(s); #endif if (tw->lineAllow) { // First make sure we allowed linemode in the first place. // RFC 1184 says client should ignore MODE negotiations with the MODE_ACK bit set, and should not // generate a response if the negotiated MODE matches the current MODE if (!((tw->parsedat[2] & L_MODE_ACK) || ((tw->parsedat[2] & L_MODE_MASK) == tw->lmodeBits))) { tw->lmodeBits = tw->parsedat[2]; // Accept the mode tw->parsedat[2] |= L_MODE_ACK; // Set the MODE_ACK bit sprintf(s,"%c%c%c%c",IAC,TEL_SB,N_LINEMODE,L_MODE); netwrite(tw->port,s,4); sprintf(s,"%c%c%c",tw->parsedat[2],IAC,TEL_SE); netwrite(tw->port,s,3); #ifdef OPTS_DEBUG opts_debug_print("SENT: IAC SB"); strcpy(s, "SENT: LM MODE = "); DemangleLineModeShort(s, tw->parsedat[2]); opts_debug_print(s); opts_debug_print("SENT: IAC SE"); #endif } #ifdef OPTS_DEBUG else { strcpy(s, "LINEMODE MODE = "); DemangleLineModeShort(s, tw->parsedat[2]); opts_debug_print(s); if (tw->parsedat[2] & L_MODE_ACK) opts_debug_print("\tignored because MODE_ACK was set."); else opts_debug_print("\tIgnored because we are already at that mode."); strcpy(s, "Curr Linemode = "); DemangleLineModeShort(s, tw->lmodeBits); opts_debug_print(s); } #endif } break; case TEL_DOTEL: #ifdef OPTS_DEBUG sprintf(munger,"RECV: SB LINEMODE DO %c", tw->parsedat[2]); opts_debug_print(munger); #endif tw->forwardMask = TRUE; setForwardMask(tw); str_lm[3] = TEL_WILLTEL; str_lm[4] = L_FORWARDMASK; netpush(tw->port); netwrite(tw->port, str_lm, sizeof(str_lm)); #ifdef OPTS_DEBUG sprintf(munger,"SENT: IAC SB LINEMODE WILL %c IAC SE", tw->parsedat[2]); opts_debug_print(munger); #endif break; case TEL_DONTTEL: #ifdef OPTS_DEBUG sprintf(munger,"RECV: SB LINEMODE DO %c", tw->parsedat[2]); opts_debug_print(munger); #endif tw->forwardMask = FALSE; str_lm[3] = TEL_WONTTEL; str_lm[4] = L_FORWARDMASK; netpush(tw->port); netwrite(tw->port, str_lm, sizeof(str_lm)); #ifdef OPTS_DEBUG sprintf(munger,"SENT: IAC SB LINEMODE WONT %c IAC SE", tw->parsedat[2]); opts_debug_print(munger); #endif break; case L_SLC: /* set local chars */ negotiateSLC(tw); break; default: #ifdef OPTS_DEBUG sprintf(munger, "RECV: SB LINEMODE ?? (?? = %c)", tw->parsedat[1]); opts_debug_print(munger); #endif break; }//switch parsedat } void setForwardMask(struct WindRec *tw) //set the keys on which we forward on { short j, i = 3; Boolean anotherByte = TRUE; tw->numForwardKeys = 1; while((tw->parsedat[i] != 0)&&(i < 35)) { if (tw->parsedat[i] == 255) { i++; //could be doubled IAC if(tw->parsedat[i+1] == TEL_SE) { anotherByte = FALSE; //but its not i--; } } if (anotherByte) for(j = 0; j < 8; j++) { if (tw->parsedat[i] & (j*2)) { tw->forwardKeys[tw->numForwardKeys-1] = (i-3)*8 + j; tw->numForwardKeys++; } } else break; i++;//next byte } for (i = tw->numForwardKeys; i < 32; i++) //zero the rest of the array tw->forwardKeys[i] = 0; } void respondSLC(short optionNumber,short *alreadySentSB,struct WindRec *tw, Boolean AWK) { unsigned char stuffToSend[3]; unsigned char subBeginSeq[4] = {IAC,TEL_SB,N_LINEMODE,L_SLC}; stuffToSend[0] = optionNumber; stuffToSend[1] = tw->slcLevel[optionNumber]; if (AWK) stuffToSend[1] |= SLC_AWK; stuffToSend[2] = tw->slc[optionNumber]; if (!(*alreadySentSB)) { *alreadySentSB = TRUE; netwrite(tw->port, subBeginSeq, 4); opts_debug_print("SENT: IAC SB LINEMODE SLC"); } if (stuffToSend[2] == IAC) { netwrite(tw->port, stuffToSend,2); netwrite(tw->port, subBeginSeq,1); //double the IAC netwrite(tw->port, subBeginSeq,1); } else netwrite(tw->port, stuffToSend, 3); #ifdef OPTS_DEBUG if (AWK) { if ((tw->slcLevel[optionNumber] & (SLC_FLUSHIN | SLC_FLUSHOUT)) == (SLC_FLUSHIN | SLC_FLUSHOUT)) sprintf(munger,"\t %s %s | AWK | FLUSHIN | FLUSHOUT %d",LMoptions[optionNumber],LMflags[SLC_LEVELBITS & tw->slcLevel[optionNumber]],tw->slc[optionNumber]); else if (tw->slcLevel[optionNumber] & SLC_FLUSHIN) sprintf(munger,"\t %s %s | AWK | FLUSHIN %d",LMoptions[optionNumber],LMflags[SLC_LEVELBITS & tw->slcLevel[optionNumber]],tw->slc[optionNumber]); else if (tw->slcLevel[optionNumber] & SLC_FLUSHOUT) sprintf(munger,"\t %s %s | AWK | FLUSHOUT %d",LMoptions[optionNumber],LMflags[SLC_LEVELBITS & tw->slcLevel[optionNumber]],tw->slc[optionNumber]); else sprintf(munger,"\t %s %s | AWK %d",LMoptions[optionNumber],LMflags[tw->slcLevel[optionNumber]],tw->slc[optionNumber]); } else { if ((tw->slcLevel[optionNumber] & (SLC_FLUSHIN | SLC_FLUSHOUT)) == (SLC_FLUSHIN | SLC_FLUSHOUT)) sprintf(munger,"\t %s %s | AWK | FLUSHIN | FLUSHOUT %d",LMoptions[optionNumber],LMflags[SLC_LEVELBITS & tw->slcLevel[optionNumber]],tw->slc[optionNumber]); else if (tw->slcLevel[optionNumber] & SLC_FLUSHIN) sprintf(munger,"\t %s %s | FLUSHIN %d",LMoptions[optionNumber],LMflags[SLC_LEVELBITS & tw->slcLevel[optionNumber]],tw->slc[optionNumber]); else if (tw->slcLevel[optionNumber] & SLC_FLUSHOUT) sprintf(munger,"\t %s %s | FLUSHOUT %d",LMoptions[optionNumber],LMflags[SLC_LEVELBITS & tw->slcLevel[optionNumber]],tw->slc[optionNumber]); else sprintf(munger,"\t %s %s %d",LMoptions[optionNumber],LMflags[tw->slcLevel[optionNumber]],tw->slc[optionNumber]); } opts_debug_print(munger); #endif } void negotiateSLC(struct WindRec *tw) { short lmslcflag = 0; unsigned char *ourValues = tw->slc; unsigned char *ourLevels = tw->slcLevel; short i; #ifdef OPTS_DEBUG sprintf(munger,"RECV: IAC SB LINEMODE SLC"); opts_debug_print(munger); for(i=2;i <= tw->parseIndex - 3; i+=3) { if (tw->parsedat[i] > 30) break; // RAB BetterTelnet 2.0b3 // we shouldn't panic on bad data // if (tw->parsedat[i] > 30) // DebugStr("\pAck! Bad option number"); if(tw->parsedat[i+1] & SLC_AWK) sprintf(munger," %s %s|AWK %d",LMoptions[tw->parsedat[i]],LMflags[tw->parsedat[i+1] & SLC_LEVELBITS],tw->parsedat[i+2]); else sprintf(munger," %s %s %d",LMoptions[tw->parsedat[i]],LMflags[tw->parsedat[i+1] & SLC_LEVELBITS],tw->parsedat[i+2]); opts_debug_print(munger); } sprintf(munger,"RECV: IAC SE"); opts_debug_print(munger); #endif for (i=2, lmslcflag=0; i <= tw->parseIndex - 3; i+=3) { short optionNumber = tw->parsedat[i]; Boolean awked = (tw->parsedat[i+1] & SLC_AWK); unsigned char requestedValue = tw->parsedat[i+2]; unsigned char requestedLevel = tw->parsedat[i+1] & SLC_LEVELBITS; Boolean flushin = tw->parsedat[i+1] & SLC_FLUSHIN; Boolean flushout = tw->parsedat[i+1] & SLC_FLUSHOUT; if ((ourValues[optionNumber] != requestedValue)||(ourLevels[optionNumber] != tw->parsedat[i+1])) //if we are sent what we already have, ignore it { if (requestedLevel == SLC_NOSUPPORT) { if (ourLevels[optionNumber] & SLC_LEVELBITS != SLC_NOSUPPORT) { ourValues[optionNumber] = 255; ourLevels[optionNumber] = SLC_NOSUPPORT;//ok, we wont support this if (!awked) respondSLC(optionNumber,&lmslcflag, tw, TRUE);//awk only if he didnt awk #ifdef OPTS_DEBUG else { sprintf(munger,"\t %s %s %d accepted; no response sent because it was AWKED", LMoptions[optionNumber],LMflags[requestedLevel],requestedValue); opts_debug_print(munger); } #endif } #ifdef OPTS_DEBUG else { sprintf(munger, "\t %s %s %d Ignored because we are already at nosupport", LMoptions[optionNumber],LMflags[requestedLevel],ourValues[optionNumber]); opts_debug_print(munger); } #endif } else if (requestedLevel == SLC_DEFAULT) { ourValues[optionNumber] = default_slc[optionNumber]; //get our default if (ourValues[optionNumber] == 255) ourLevels[optionNumber] = SLC_NOSUPPORT; else ourLevels[optionNumber] = SLC_VALUE; respondSLC(optionNumber, &lmslcflag, tw, FALSE); //tell him about our choice } else if (requestedLevel > ourLevels[optionNumber]) respondSLC(optionNumber, &lmslcflag, tw, FALSE); //keep lower setting else { ourValues[optionNumber] = requestedValue; ourLevels[optionNumber] = requestedLevel; if (flushin) ourLevels[optionNumber] |= SLC_FLUSHIN; if (flushout) ourLevels[optionNumber] |= SLC_FLUSHOUT; if (!awked) respondSLC(optionNumber, &lmslcflag, tw, TRUE); //agree to his new setting } } #ifdef OPTS_DEBUG else { sprintf(munger, "\t %s %s Ignored because %d is already the current value", LMoptions[optionNumber],LMflags[requestedLevel],ourValues[optionNumber]); opts_debug_print(munger); } #endif }//end for on parseindex if (lmslcflag) { unsigned char toSend[2] = {IAC,TEL_SE}; netpush(tw->port); netwrite(tw->port,toSend,2); opts_debug_print("SENT: IAC SE"); } } void doLinemode(struct WindRec *tw) { short i; unsigned char subBeginSeq[4] = {IAC,TEL_SB,N_LINEMODE,L_SLC}; unsigned char subEndSeq[2] = {IAC,TEL_SE}; unsigned char toSend[3]; tw->lmodeBits = 0; tw->lmode = TRUE; tw->litNext = FALSE; netwrite(tw->port,subBeginSeq,4); opts_debug_print("SENT: IAC SB LINEMODE SLC"); for (i=1; i<= SLC_MAX; i++) { if (tw->slc[i]==255) { toSend[0] = i; toSend[1] = SLC_NOSUPPORT; toSend[2] = 0; #ifdef OPTS_DEBUG sprintf(munger," %s NO_SUPPORT 0",LMoptions[i]); #endif } else { toSend[0] = i; toSend[1] = SLC_VALUE; toSend[2] = tw->slc[i]; #ifdef OPTS_DEBUG sprintf(munger," %s VALUE %d",LMoptions[i],(short)tw->slc[i]); #endif } opts_debug_print(munger); netwrite(tw->port,toSend,3); } opts_debug_print("SENT: IAC SE"); netpush(tw->port); netwrite(tw->port,subEndSeq,2); } static void DemangleLineMode(char *s, short mode) { #ifdef OPTS_DEBUG short i; for (i=0; i<5; i++) { if (mode & (1 << i)) strcat(s, LMmodes[i]); } #endif } void DemangleLineModeShort(char *s, short mode) { #ifdef OPTS_DEBUG short i; for (i=0; i<5; i++) { if (mode & (1 << i)) strcat(s, LMmodeBits[i]); else strcat(s," "); } #endif } \ No newline at end of file diff --git a/source/Preferences/prefs.c b/source/Preferences/prefs.c index aaabaec..c670be1 100755 --- a/source/Preferences/prefs.c +++ b/source/Preferences/prefs.c @@ -1 +1 @@ -// prefs.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* NCSA Revisions: * 5/93 Telnet 2.6: Rewritten entirely -- Jim Browne */ #ifdef MPW #pragma segment Configure #endif #include "prefs.proto.h" #include "mainseg.proto.h" // For quit proto #include "errors.proto.h" FTPServerPrefs* gFTPServerPrefs=NULL; ApplicationPrefs* gApplicationPrefs=NULL; void PREFSUnload(void) { } OSErr OpenPreferencesFile( void) { Str255 **PreferencesFileNameHdl; OSErr err; PreferencesFileNameHdl = (Str255**)GetString(PREFERENCES_FILE_NAME_STR_ID); if (PreferencesFileNameHdl == NULL) { DebugStr("\pSomeone has deleted the prefs file name resource!"); forcequit(); } HLock((Handle)PreferencesFileNameHdl); /* look for an existing settings file. */ /* first, try the application folder */ TelInfo->SettingsFile=HOpenResFile(TelInfo->ApFolder.vRefNum, TelInfo->ApFolder.parID, (StringPtr)*PreferencesFileNameHdl,fsRdWrShPerm); if (TelInfo->SettingsFile == -1) /* Look in System Folder */ { TelInfo->SettingsFile = HOpenResFile(TelInfo->SysFolder.vRefNum, TelInfo->SysFolder.parID, (StringPtr)*PreferencesFileNameHdl, fsRdWrShPerm); } if (TelInfo->SettingsFile == -1) /* Look in Preferences Folder */ { TelInfo->SettingsFile = HOpenResFile(TelInfo->PrefFolder.vRefNum, TelInfo->PrefFolder.parID, (StringPtr)*PreferencesFileNameHdl, fsRdWrShPerm); } if (TelInfo->SettingsFile == -1) { if ((err = HCreate(TelInfo->PrefFolder.vRefNum, TelInfo->PrefFolder.parID, (StringPtr)*PreferencesFileNameHdl, 'rlfT', 'pref')) != noErr) FatalAlert(CANT_CREATE_PREFS, 120, err); HCreateResFile(TelInfo->PrefFolder.vRefNum, TelInfo->PrefFolder.parID, (StringPtr)*PreferencesFileNameHdl); if (ResError() != noErr) FatalAlert(CANT_CREATE_PREFS, 120, ResError()); TelInfo->SettingsFile = HOpenResFile(TelInfo->PrefFolder.vRefNum, TelInfo->PrefFolder.parID, (StringPtr)*PreferencesFileNameHdl, fsRdWrShPerm); if (TelInfo->SettingsFile == -1) FatalAlert(CANT_CREATE_PREFS, 120, ResError()); // Give up if ((err = NewPreferences()) != noErr) return(err); } UseResFile(TelInfo->SettingsFile); ReleaseResource((Handle)PreferencesFileNameHdl); return noErr; } OSErr NewPreferences(void) { ApplicationPrefs **AppPrefsHdl; FTPServerPrefs **FTPPrefsHdl; SessionPrefs **DefaultSessionPrefs; TerminalPrefs **DefaultTerminalPrefs; // Get the master copies from the application's resource fork AppPrefsHdl = (ApplicationPrefs **)GetResource(APPLICATIONPREFS_RESTYPE, APPLICATIONPREFS_APPID); if ((ResError() != noErr) || (AppPrefsHdl == NULL)) return(ResError()); DetachResource((Handle)AppPrefsHdl); FTPPrefsHdl = (FTPServerPrefs **)GetResource(FTPSERVERPREFS_RESTYPE, FTPSERVERPREFS_APPID); if ((ResError() != noErr) || (FTPPrefsHdl == NULL)) return(ResError()); DetachResource((Handle)FTPPrefsHdl); DefaultSessionPrefs = (SessionPrefs **)GetResource(SESSIONPREFS_RESTYPE, SESSIONPREFS_APPID); if ((ResError() != noErr) || (DefaultSessionPrefs == NULL)) return(ResError()); DetachResource((Handle)DefaultSessionPrefs); DefaultTerminalPrefs = (TerminalPrefs **)GetResource(TERMINALPREFS_RESTYPE, TERMINALPREFS_APPID); if ((ResError() != noErr) || (DefaultTerminalPrefs == NULL)) return(ResError()); DetachResource((Handle)DefaultTerminalPrefs); // Add them to the Preferences file UseResFile(TelInfo->SettingsFile); if (ResError() != noErr) return(ResError()); AddResource((Handle)AppPrefsHdl, APPLICATIONPREFS_RESTYPE, APPLICATIONPREFS_ID, "\p"); if (ResError() != noErr) return(ResError()); AddResource((Handle)FTPPrefsHdl,FTPSERVERPREFS_RESTYPE, FTPSERVERPREFS_ID, "\p"); if (ResError() != noErr) return(ResError()); AddResource((Handle)DefaultSessionPrefs,SESSIONPREFS_RESTYPE, SESSIONPREFS_APPID, "\p"); if (ResError() != noErr) return(ResError()); AddResource((Handle)DefaultTerminalPrefs,TERMINALPREFS_RESTYPE, TERMINALPREFS_APPID, "\p"); if (ResError() != noErr) return(ResError()); // Update the preferences file and release the resources UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)AppPrefsHdl); ReleaseResource((Handle)FTPPrefsHdl); ReleaseResource((Handle)DefaultSessionPrefs); ReleaseResource((Handle)DefaultTerminalPrefs); return(ResError()); } OSErr LoadPreferences(void) { ApplicationPrefs **AppPrefsHdl; FTPServerPrefs **FTPPrefsHdl; UseResFile(TelInfo->SettingsFile); if (ResError() != noErr) return(ResError()); AppPrefsHdl = (ApplicationPrefs **)GetResource(APPLICATIONPREFS_RESTYPE, APPLICATIONPREFS_ID); if ((ResError() != noErr) || (AppPrefsHdl == NULL)) return(ResError()); HLock((Handle) AppPrefsHdl); BlockMove(*AppPrefsHdl, gApplicationPrefs, sizeof(ApplicationPrefs)); ReleaseResource((Handle) AppPrefsHdl); FTPPrefsHdl = (FTPServerPrefs **)GetResource(FTPSERVERPREFS_RESTYPE, FTPSERVERPREFS_ID); if ((ResError() != noErr) || (FTPPrefsHdl == NULL)) return(ResError()); HLock((Handle) FTPPrefsHdl); BlockMove(*FTPPrefsHdl, gFTPServerPrefs, sizeof(FTPServerPrefs)); ReleaseResource((Handle) FTPPrefsHdl); if (TelInfo->haveColorQuickDraw) { UseResFile(TelInfo->SettingsFile); TelInfo->AnsiColors = GetNewPalette(10001); if (TelInfo->AnsiColors == NULL) //get the Application's copy instead { UseResFile(TelInfo->ApplicationFile); TelInfo->AnsiColors = GetNewPalette(9999); DetachResource((Handle)TelInfo->AnsiColors); UseResFile(TelInfo->SettingsFile); AddResource((Handle)TelInfo->AnsiColors, 'pltt', 10001, "\pANSI Colors");//make the new resource UpdateResFile(TelInfo->SettingsFile); } DetachResource((Handle)TelInfo->AnsiColors); } CheckPrefsVersion(); return(noErr); } OSErr SaveAppPreferences(void) { ApplicationPrefs **AppPrefsHdl; Boolean UserHasBeenAlerted = FALSE, UserResponse; UseResFile(TelInfo->SettingsFile); if (ResError() != noErr) return(ResError()); AppPrefsHdl = (ApplicationPrefs **)GetResource(APPLICATIONPREFS_RESTYPE, APPLICATIONPREFS_ID); if ((ResError() != noErr) || (AppPrefsHdl == NULL)) return(ResError()); HLock((Handle) AppPrefsHdl); if (gApplicationPrefs->version < (*AppPrefsHdl)->version) { UserResponse = AskUserAlert(PREFS_ARE_NEWER_ID, TRUE); // Cancel is default if (UserResponse == TRUE) return(noErr); // User doesn't want to destroy prefs UserHasBeenAlerted = TRUE; // Don't ask the user twice! } BlockMove(gApplicationPrefs, *AppPrefsHdl, sizeof(ApplicationPrefs)); ChangedResource((Handle) AppPrefsHdl); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle) AppPrefsHdl); return(noErr); } OSErr SaveFTPPreferences(void) { FTPServerPrefs **FTPPrefsHdl; Boolean UserHasBeenAlerted = FALSE, UserResponse; UseResFile(TelInfo->SettingsFile); if (ResError() != noErr) return(ResError()); FTPPrefsHdl = (FTPServerPrefs **)GetResource(FTPSERVERPREFS_RESTYPE, FTPSERVERPREFS_ID); if ((ResError() != noErr) || (FTPPrefsHdl == NULL)) return(ResError()); HLock((Handle) FTPPrefsHdl); if ((gFTPServerPrefs->version < (*FTPPrefsHdl)->version) && (!UserHasBeenAlerted)) { UserResponse = AskUserAlert(PREFS_ARE_NEWER_ID, TRUE); // Cancel is default if (UserResponse == TRUE) return(noErr); // User doesn't want to destroy prefs } BlockMove(gFTPServerPrefs, *FTPPrefsHdl, sizeof(FTPServerPrefs)); ChangedResource((Handle) FTPPrefsHdl); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle) FTPPrefsHdl); return(noErr); } TerminalPrefs **GetDefaultTerminal(void) { TerminalPrefs **theTerminalHdl; short scratchshort; UseResFile(TelInfo->SettingsFile); theTerminalHdl = (TerminalPrefs **)Get1NamedResource(TERMINALPREFS_RESTYPE, "\p"); // If there is an error here, we put up a dialog box about the prefs // being messed up and then we restore the default from the master copy // in the application's resource fork. if (theTerminalHdl == NULL) { FatalCancelAlert(PREFERENCES_PROBLEM, "\pRepair", 110, ResError()); UseResFile(TelInfo->ApplicationFile); theTerminalHdl = (TerminalPrefs **)Get1NamedResource(TERMINALPREFS_RESTYPE, "\p"); // If the master copy is not there, it's a fatal error! if (theTerminalHdl == NULL) FatalAlert(RESOURCE_PROBLEM, 111, ResError()); // Doesn't return DetachResource((Handle)theTerminalHdl); UseResFile(TelInfo->SettingsFile); scratchshort = Unique1ID(TERMINALPREFS_RESTYPE); AddResource((Handle)theTerminalHdl, TERMINALPREFS_RESTYPE, scratchshort, "\p"); // If an error ocurred fixing the prefs file, it's a fatal error! if (ResError() != noErr) FatalAlert(NUKED_PREFS, 112, ResError()); // Doesn't return UpdateResFile(TelInfo->SettingsFile); } DetachResource((Handle)theTerminalHdl); return(theTerminalHdl); } SessionPrefs **GetDefaultSession(void) { SessionPrefs **theSessionHdl; short scratchshort; UseResFile(TelInfo->SettingsFile); theSessionHdl = (SessionPrefs **)Get1NamedResource(SESSIONPREFS_RESTYPE, "\p"); // If there is an error here, we put up a dialog box about the prefs // being messed up and then we restore the default from the master copy // in the application's resource fork. if (theSessionHdl == NULL) { FatalCancelAlert(PREFERENCES_PROBLEM, "\pRepair", 100, ResError()); UseResFile(TelInfo->ApplicationFile); theSessionHdl = (SessionPrefs **)Get1NamedResource(SESSIONPREFS_RESTYPE, "\p"); // If the master copy is not there, it's a fatal error! if (theSessionHdl == NULL) FatalAlert(RESOURCE_PROBLEM, 101, ResError()); // Doesn't return DetachResource((Handle)theSessionHdl); UseResFile(TelInfo->SettingsFile); scratchshort = Unique1ID(SESSIONPREFS_RESTYPE); AddResource((Handle)theSessionHdl, SESSIONPREFS_RESTYPE, scratchshort, "\p"); // If an error ocurred fixing the prefs file, it's a fatal error! if (ResError() != noErr) FatalAlert(NUKED_PREFS, 102, ResError()); // Doesn't return UpdateResFile(TelInfo->SettingsFile); } DetachResource((Handle)theSessionHdl); return(theSessionHdl); } void GetHostNameFromSession(StringPtr string) { SessionPrefs **sessHdl; UseResFile(TelInfo->SettingsFile); sessHdl = (SessionPrefs **)Get1NamedResource(SESSIONPREFS_RESTYPE, string); HLock((Handle)sessHdl); BlockMove((**sessHdl).hostname, string, Length((**sessHdl).hostname)+1); ReleaseResource((Handle)sessHdl); } Boolean ProcessHostnameString(StringPtr HostnameString, short *port, short *portNegative) { Str255 MungeString; short scratchshort; long portRequested; StringPtr xxxxptr, yyyyptr; Boolean foundPort = FALSE; short portNeg = 0; // Copy the whole damn thing over BlockMove(HostnameString, MungeString, 255); // Remove leading spaces scratchshort = 1; while((scratchshort <= Length(MungeString)) && (MungeString[scratchshort] == ' ')) scratchshort++; if (scratchshort > Length(MungeString)) { HostnameString[0] = 0; return(FALSE); } xxxxptr = &MungeString[scratchshort-1]; // Now look for a port number... while((scratchshort <= Length(MungeString)) && (MungeString[scratchshort] != ' ')) scratchshort++; yyyyptr = &MungeString[scratchshort]; if (scratchshort < Length(MungeString)) { if (MungeString[scratchshort + 1] == '-') { scratchshort++; portNeg = 1; } MungeString[scratchshort] = Length(MungeString) - scratchshort; StringToNum(&MungeString[scratchshort], &portRequested); if ((portRequested > 0) && (portRequested < 65535)) foundPort = TRUE; } xxxxptr[0] = yyyyptr - xxxxptr - 1; // Copy parsed hostname string back BlockMove(xxxxptr, HostnameString, Length(xxxxptr)+1); *port = (short)portRequested; *portNegative = portNeg; return(foundPort); } void CheckPrefsVersion(void) { if (gApplicationPrefs->version != OUR_PREFS_VERSION_NUMBER) //need to correctly set new values { if (gApplicationPrefs->version < NO_TIMEOUTS_VERSION) { gApplicationPrefs->SendTimeout = 15; //before d5, we need to set these gApplicationPrefs->OpenTimeout = 15; } gApplicationPrefs->StaggerWindowsOffset = 10;//before b1, we need to set this gApplicationPrefs->version = OUR_PREFS_VERSION_NUMBER; SaveAppPreferences(); } } \ No newline at end of file +// prefs.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* NCSA Revisions: * 5/93 Telnet 2.6: Rewritten entirely -- Jim Browne */ #include "prefs.proto.h" #include "mainseg.proto.h" // For quit proto #include "errors.proto.h" FTPServerPrefs* gFTPServerPrefs=NULL; ApplicationPrefs* gApplicationPrefs=NULL; ResType taggedSessTypes[] = { 'uMac' }; #define NUM_TAGGED_SESS_TYPES 1 void PREFSUnload(void) { } OSErr OpenPreferencesFile( void) { Str255 **PreferencesFileNameHdl; OSErr err; PreferencesFileNameHdl = (Str255**)GetString(PREFERENCES_FILE_NAME_STR_ID); if (PreferencesFileNameHdl == NULL) { DebugStr("\pSomeone has deleted the prefs file name resource!"); forcequit(); } HLock((Handle)PreferencesFileNameHdl); /* look for an existing settings file. */ /* first, try the application folder */ TelInfo->SettingsFile=HOpenResFile(TelInfo->ApFolder.vRefNum, TelInfo->ApFolder.parID, (StringPtr)*PreferencesFileNameHdl,fsRdWrShPerm); if (TelInfo->SettingsFile == -1) /* Look in System Folder */ { TelInfo->SettingsFile = HOpenResFile(TelInfo->SysFolder.vRefNum, TelInfo->SysFolder.parID, (StringPtr)*PreferencesFileNameHdl, fsRdWrShPerm); } if (TelInfo->SettingsFile == -1) /* Look in Preferences Folder */ { TelInfo->SettingsFile = HOpenResFile(TelInfo->PrefFolder.vRefNum, TelInfo->PrefFolder.parID, (StringPtr)*PreferencesFileNameHdl, fsRdWrShPerm); } if (TelInfo->SettingsFile == -1) { if ((err = HCreate(TelInfo->PrefFolder.vRefNum, TelInfo->PrefFolder.parID, (StringPtr)*PreferencesFileNameHdl, 'rlfT', 'pref')) != noErr) FatalAlert(CANT_CREATE_PREFS, 120, err); HCreateResFile(TelInfo->PrefFolder.vRefNum, TelInfo->PrefFolder.parID, (StringPtr)*PreferencesFileNameHdl); if (ResError() != noErr) FatalAlert(CANT_CREATE_PREFS, 120, ResError()); TelInfo->SettingsFile = HOpenResFile(TelInfo->PrefFolder.vRefNum, TelInfo->PrefFolder.parID, (StringPtr)*PreferencesFileNameHdl, fsRdWrShPerm); if (TelInfo->SettingsFile == -1) FatalAlert(CANT_CREATE_PREFS, 120, ResError()); // Give up if ((err = NewPreferences()) != noErr) return(err); } UseResFile(TelInfo->SettingsFile); ReleaseResource((Handle)PreferencesFileNameHdl); return noErr; } OSErr NewPreferences(void) { ApplicationPrefs **AppPrefsHdl; FTPServerPrefs **FTPPrefsHdl; SessionPrefs **DefaultSessionPrefs; TerminalPrefs **DefaultTerminalPrefs; // Get the master copies from the application's resource fork AppPrefsHdl = (ApplicationPrefs **)GetResource(APPLICATIONPREFS_RESTYPE, APPLICATIONPREFS_APPID); if ((ResError() != noErr) || (AppPrefsHdl == NULL)) return(ResError()); DetachResource((Handle)AppPrefsHdl); FTPPrefsHdl = (FTPServerPrefs **)GetResource(FTPSERVERPREFS_RESTYPE, FTPSERVERPREFS_APPID); if ((ResError() != noErr) || (FTPPrefsHdl == NULL)) return(ResError()); DetachResource((Handle)FTPPrefsHdl); DefaultSessionPrefs = (SessionPrefs **)GetResource(SESSIONPREFS_RESTYPE, SESSIONPREFS_APPID); if ((ResError() != noErr) || (DefaultSessionPrefs == NULL)) return(ResError()); DetachResource((Handle)DefaultSessionPrefs); DefaultTerminalPrefs = (TerminalPrefs **)GetResource(TERMINALPREFS_RESTYPE, TERMINALPREFS_APPID); if ((ResError() != noErr) || (DefaultTerminalPrefs == NULL)) return(ResError()); DetachResource((Handle)DefaultTerminalPrefs); // Add them to the Preferences file UseResFile(TelInfo->SettingsFile); if (ResError() != noErr) return(ResError()); AddResource((Handle)AppPrefsHdl, APPLICATIONPREFS_RESTYPE, APPLICATIONPREFS_ID, "\p"); if (ResError() != noErr) return(ResError()); AddResource((Handle)FTPPrefsHdl,FTPSERVERPREFS_RESTYPE, FTPSERVERPREFS_ID, "\p"); if (ResError() != noErr) return(ResError()); AddResource((Handle)DefaultSessionPrefs,SESSIONPREFS_RESTYPE, SESSIONPREFS_APPID, "\p"); if (ResError() != noErr) return(ResError()); AddResource((Handle)DefaultTerminalPrefs,TERMINALPREFS_RESTYPE, TERMINALPREFS_APPID, "\p"); if (ResError() != noErr) return(ResError()); // Update the preferences file and release the resources UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)AppPrefsHdl); ReleaseResource((Handle)FTPPrefsHdl); ReleaseResource((Handle)DefaultSessionPrefs); ReleaseResource((Handle)DefaultTerminalPrefs); return(ResError()); } OSErr LoadPreferences(void) { ApplicationPrefs **AppPrefsHdl; FTPServerPrefs **FTPPrefsHdl; UseResFile(TelInfo->SettingsFile); if (ResError() != noErr) return(ResError()); AppPrefsHdl = (ApplicationPrefs **)GetResource(APPLICATIONPREFS_RESTYPE, APPLICATIONPREFS_ID); if ((ResError() != noErr) || (AppPrefsHdl == NULL)) return(ResError()); HLock((Handle) AppPrefsHdl); CheckPrefsHandleSize((Handle) AppPrefsHdl, sizeof(ApplicationPrefs)); BlockMove(*AppPrefsHdl, gApplicationPrefs, sizeof(ApplicationPrefs)); ReleaseResource((Handle) AppPrefsHdl); FTPPrefsHdl = (FTPServerPrefs **)GetResource(FTPSERVERPREFS_RESTYPE, FTPSERVERPREFS_ID); if ((ResError() != noErr) || (FTPPrefsHdl == NULL)) return(ResError()); HLock((Handle) FTPPrefsHdl); BlockMove(*FTPPrefsHdl, gFTPServerPrefs, sizeof(FTPServerPrefs)); ReleaseResource((Handle) FTPPrefsHdl); if (TelInfo->haveColorQuickDraw) { UseResFile(TelInfo->SettingsFile); TelInfo->AnsiColors = GetNewPalette(10001); if (TelInfo->AnsiColors == NULL) //get the Application's copy instead { UseResFile(TelInfo->ApplicationFile); TelInfo->AnsiColors = GetNewPalette(9999); DetachResource((Handle)TelInfo->AnsiColors); UseResFile(TelInfo->SettingsFile); AddResource((Handle)TelInfo->AnsiColors, 'pltt', 10001, "\pANSI Colors");//make the new resource UpdateResFile(TelInfo->SettingsFile); } DetachResource((Handle)TelInfo->AnsiColors); } CheckPrefsVersion(); return(noErr); } OSErr SaveAppPreferences(void) { ApplicationPrefs **AppPrefsHdl; Boolean UserHasBeenAlerted = FALSE, UserResponse; UseResFile(TelInfo->SettingsFile); if (ResError() != noErr) return(ResError()); AppPrefsHdl = (ApplicationPrefs **)GetResource(APPLICATIONPREFS_RESTYPE, APPLICATIONPREFS_ID); if ((ResError() != noErr) || (AppPrefsHdl == NULL)) return(ResError()); HLock((Handle) AppPrefsHdl); CheckPrefsHandleSize((Handle) AppPrefsHdl, sizeof(ApplicationPrefs)); if (gApplicationPrefs->version < (*AppPrefsHdl)->version) { UserResponse = AskUserAlert(PREFS_ARE_NEWER_ID, TRUE); // Cancel is default if (UserResponse == TRUE) return(noErr); // User doesn't want to destroy prefs UserHasBeenAlerted = TRUE; // Don't ask the user twice! } BlockMove(gApplicationPrefs, *AppPrefsHdl, sizeof(ApplicationPrefs)); ChangedResource((Handle) AppPrefsHdl); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle) AppPrefsHdl); return(noErr); } OSErr SaveFTPPreferences(void) { FTPServerPrefs **FTPPrefsHdl; Boolean UserHasBeenAlerted = FALSE, UserResponse; UseResFile(TelInfo->SettingsFile); if (ResError() != noErr) return(ResError()); FTPPrefsHdl = (FTPServerPrefs **)GetResource(FTPSERVERPREFS_RESTYPE, FTPSERVERPREFS_ID); if ((ResError() != noErr) || (FTPPrefsHdl == NULL)) return(ResError()); HLock((Handle) FTPPrefsHdl); if ((gFTPServerPrefs->version < (*FTPPrefsHdl)->version) && (!UserHasBeenAlerted)) { UserResponse = AskUserAlert(PREFS_ARE_NEWER_ID, TRUE); // Cancel is default if (UserResponse == TRUE) return(noErr); // User doesn't want to destroy prefs } BlockMove(gFTPServerPrefs, *FTPPrefsHdl, sizeof(FTPServerPrefs)); ChangedResource((Handle) FTPPrefsHdl); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle) FTPPrefsHdl); return(noErr); } TerminalPrefs **GetDefaultTerminal(void) { TerminalPrefs **theTerminalHdl; short scratchshort; UseResFile(TelInfo->SettingsFile); theTerminalHdl = (TerminalPrefs **)Get1NamedSizedResource(TERMINALPREFS_RESTYPE, "\p", sizeof(TerminalPrefs)); // If there is an error here, we put up a dialog box about the prefs // being messed up and then we restore the default from the master copy // in the application's resource fork. if (theTerminalHdl == NULL) { FatalCancelAlert(PREFERENCES_PROBLEM, "\pRepair", 110, ResError()); UseResFile(TelInfo->ApplicationFile); theTerminalHdl = (TerminalPrefs **)Get1NamedSizedResource(TERMINALPREFS_RESTYPE, "\p", sizeof(TerminalPrefs)); // If the master copy is not there, it's a fatal error! if (theTerminalHdl == NULL) FatalAlert(RESOURCE_PROBLEM, 111, ResError()); // Doesn't return DetachResource((Handle)theTerminalHdl); UseResFile(TelInfo->SettingsFile); scratchshort = Unique1ID(TERMINALPREFS_RESTYPE); AddResource((Handle)theTerminalHdl, TERMINALPREFS_RESTYPE, scratchshort, "\p"); // If an error ocurred fixing the prefs file, it's a fatal error! if (ResError() != noErr) FatalAlert(NUKED_PREFS, 112, ResError()); // Doesn't return UpdateResFile(TelInfo->SettingsFile); } DetachResource((Handle)theTerminalHdl); return(theTerminalHdl); } SessionPrefs **GetDefaultSession(void) { SessionPrefs **theSessionHdl; short scratchshort; UseResFile(TelInfo->SettingsFile); theSessionHdl = (SessionPrefs **)Get1NamedSizedResource(SESSIONPREFS_RESTYPE, "\p", sizeof(SessionPrefs)); // If there is an error here, we put up a dialog box about the prefs // being messed up and then we restore the default from the master copy // in the application's resource fork. if (theSessionHdl == NULL) { FatalCancelAlert(PREFERENCES_PROBLEM, "\pRepair", 100, ResError()); UseResFile(TelInfo->ApplicationFile); theSessionHdl = (SessionPrefs **)Get1NamedSizedResource(SESSIONPREFS_RESTYPE, "\p", sizeof(SessionPrefs)); // If the master copy is not there, it's a fatal error! if (theSessionHdl == NULL) FatalAlert(RESOURCE_PROBLEM, 101, ResError()); // Doesn't return DetachResource((Handle)theSessionHdl); UseResFile(TelInfo->SettingsFile); scratchshort = Unique1ID(SESSIONPREFS_RESTYPE); AddResource((Handle)theSessionHdl, SESSIONPREFS_RESTYPE, scratchshort, "\p"); // If an error ocurred fixing the prefs file, it's a fatal error! if (ResError() != noErr) FatalAlert(NUKED_PREFS, 102, ResError()); // Doesn't return UpdateResFile(TelInfo->SettingsFile); } DetachResource((Handle)theSessionHdl); return(theSessionHdl); } void GetHostNameFromSession(StringPtr string) { SessionPrefs **sessHdl; UseResFile(TelInfo->SettingsFile); sessHdl = (SessionPrefs **)Get1NamedSizedResource(SESSIONPREFS_RESTYPE, string, sizeof(SessionPrefs)); HLock((Handle)sessHdl); BlockMove((**sessHdl).hostname, string, StrLength((**sessHdl).hostname)+1); ReleaseResource((Handle)sessHdl); } Boolean ProcessHostnameString(StringPtr HostnameString, short *port, short *portNegative) { Str255 MungeString; short scratchshort; long portRequested; StringPtr xxxxptr, yyyyptr; Boolean foundPort = FALSE; short portNeg = 0; // Copy the whole damn thing over BlockMove(HostnameString, MungeString, 255); // Remove leading spaces scratchshort = 1; while((scratchshort <= StrLength(MungeString)) && (MungeString[scratchshort] == ' ')) scratchshort++; if (scratchshort > StrLength(MungeString)) { HostnameString[0] = 0; return(FALSE); } xxxxptr = &MungeString[scratchshort-1]; // Now look for a port number... while((scratchshort <= StrLength(MungeString)) && (MungeString[scratchshort] != ' ')) scratchshort++; yyyyptr = &MungeString[scratchshort]; if (scratchshort < StrLength(MungeString)) { if (MungeString[scratchshort + 1] == '-') { scratchshort++; portNeg = 1; } MungeString[scratchshort] = StrLength(MungeString) - scratchshort; StringToNum(&MungeString[scratchshort], &portRequested); if ((portRequested > 0) && (portRequested < 65535)) foundPort = TRUE; } xxxxptr[0] = yyyyptr - xxxxptr - 1; // Copy parsed hostname string back BlockMove(xxxxptr, HostnameString, StrLength(xxxxptr)+1); *port = (short)portRequested; *portNegative = portNeg; return(foundPort); } void CheckPrefsVersion(void) { if (gApplicationPrefs->version != OUR_PREFS_VERSION_NUMBER) //need to correctly set new values { if (gApplicationPrefs->version < NO_TIMEOUTS_VERSION) { gApplicationPrefs->SendTimeout = 15; //before d5, we need to set these gApplicationPrefs->OpenTimeout = 15; } gApplicationPrefs->StaggerWindowsOffset = 10;//before b1, we need to set this gApplicationPrefs->version = OUR_PREFS_VERSION_NUMBER; SaveAppPreferences(); } } void CheckPrefsHandleSize(Handle h, long requestedSize) { long oldsize, i; char *myPointer; oldsize = GetHandleSize(h); if (requestedSize > oldsize) { HUnlock(h); SetHandleSize(h, requestedSize); HLock(h); myPointer = (char *) *h; for (i = oldsize; i < requestedSize; i++) *(myPointer + i) = 0; } } Handle Get1NamedSizedResource(ResType theType, StringPtr theName, long requestedSize) { Handle h; h = Get1NamedResource(theType, theName); CheckPrefsHandleSize(h, requestedSize); return h; } void RemoveTaggedResource(Handle resHandle, ResType theType, StringPtr theName) { short i; Handle h; RemoveResource(resHandle); UseResFile(TelInfo->SettingsFile); switch (theType) { case 'SeSn': for (i = 0; i < NUM_TAGGED_SESS_TYPES; i++) { h = Get1NamedResource(taggedSessTypes[i], theName); if (h) RemoveResource(h); } break; } } void SetTaggedSesResInfo(Handle resHandle, short resID, StringPtr oldName, StringPtr newName) { short i; short id; ResType rt; Handle h; static Str255 tmpname; SetResInfo(resHandle, resID, newName); UseResFile(TelInfo->SettingsFile); for (i = 0; i < NUM_TAGGED_SESS_TYPES; i++) { h = Get1NamedResource(taggedSessTypes[i], oldName); if (h) { GetResInfo(h, &id, &rt, tmpname); SetResInfo(h, id, newName); ReleaseResource(h); } } } \ No newline at end of file diff --git a/source/Preferences/prefs.proto.h b/source/Preferences/prefs.proto.h index d0f3ce6..31bd783 100755 --- a/source/Preferences/prefs.proto.h +++ b/source/Preferences/prefs.proto.h @@ -1 +1 @@ -OSErr OpenPreferencesFile(void); OSErr NewPreferences(void); OSErr LoadPreferences(void); OSErr SaveFTPPreferences(void); OSErr SaveAppPreferences(void); TerminalPrefs **GetDefaultTerminal(void); SessionPrefs **GetDefaultSession(void); void GetHostNameFromSession(StringPtr string); Boolean ProcessHostnameString(StringPtr, short*, short*); void CheckPrefsVersion(void); void PREFSUnload(void); \ No newline at end of file +OSErr OpenPreferencesFile(void); OSErr NewPreferences(void); OSErr LoadPreferences(void); OSErr SaveFTPPreferences(void); OSErr SaveAppPreferences(void); TerminalPrefs **GetDefaultTerminal(void); SessionPrefs **GetDefaultSession(void); void GetHostNameFromSession(StringPtr string); Boolean ProcessHostnameString(StringPtr, short*, short*); void CheckPrefsVersion(void); void PREFSUnload(void); void CheckPrefsHandleSize(Handle, long); Handle Get1NamedSizedResource(ResType, Str255, long); void RemoveTaggedResource(Handle, ResType, Str255); void SetTaggedSesResInfo(Handle, short, Str255, Str255); \ No newline at end of file diff --git a/source/Screens/rsinterf.c b/source/Screens/rsinterf.c index 4979811..f3fe6a4 100755 --- a/source/Screens/rsinterf.c +++ b/source/Screens/rsinterf.c @@ -1 +1 @@ -/* rsinterf.c */ /* A split of RSmac.c to facilitate keeping my sanity --CCP */ #include "rsdefs.h" #include "vsdata.h" #include "wind.h" #include "rsmac.proto.h" #include "vsinterf.proto.h" #include "vsintern.proto.h" #include "rsinterf.proto.h" #include "menuseg.proto.h" #include "maclook.proto.h" #include "wdefpatch.proto.h" /* 931112, ragge, NADA, KTH */ #include "parse.proto.h" #include "network.proto.h" #include "DlogUtils.proto.h" #include "url.proto.h" #include "drag.proto.h" #include "configure.proto.h" #include "errors.proto.h" static void calculateWindowPosition(WindRec *theScreen,Rect *whereAt, short colsHigh, short colsWide); extern WindRec *screens; extern short MaxRS; extern RSdata *RSlocal, *RScurrent; extern Rect noConst; extern short RSw, /* last window used */ RSa; /* last attrib used */ extern short **topLeftCorners; extern short NumberOfColorBoxes; extern short BoxColorItems[8]; extern RGBColor BoxColorData[8]; long RScolors[8] = //these are the old quickdraw constants, { //only used if Telinfo->hasColorQuickDraw is false blackColor, redColor, greenColor, yellowColor, blueColor, magentaColor, cyanColor, whiteColor }; SIMPLE_UPP(ScrollProc,ControlAction); static void HandleDoubleClick(short w, short modifiers); void RSunload(void) {} /*------------------------------------------------------------------------------*/ /* RSselect */ /* Handle the mouse down in the session window. All we know so far is that it */ /* is somewhere in the content window, and it is NOT an option - click. */ /* Double clicking now works -- SMB */ // And I fixed it so it works correctly. Grrrr... - JMB // WARNING: Make sure RSlocal[w].selected is 1 when doing selections. If it is // zero, the autoscrolling routines will seriously hose the selection drawing. // Heed this advice, it took me two hours to find the cause of this bug! - JMB /* called on a mouse-down in the text display area of the active window. Creates or extends the highlighted selection within that window, autoscrolling as appropriate if the user drags outside the currently visible part of the display. */ void RSselect( short w, Point pt, EventRecord theEvent) { static long lastClick = 0; static Point lastClickLoc = {0,0}; GrafPtr tempwndo; Point curr, temp; long clickTime; short shift = (theEvent.modifiers & shiftKey); RSsetConst(w); tempwndo = RSlocal[w].window; curr = normalize(pt, w, TRUE); clickTime = TickCount(); if ( ( EqualPt(RSlocal[w].anchor, curr) || EqualPt(RSlocal[w].anchor, RSlocal[w].last) ) && ((clickTime - lastClick) <= GetDblTime()) && EqualPt(curr, lastClickLoc)) { /* NCSA: SB - check to see if this is a special click */ /* NCSA: SB - It has to be in the right time interval, and in the same spot */ curr = RSlocal[w].anchor = RSlocal[w].last = normalize(pt, w,TRUE); HandleDoubleClick(w, theEvent.modifiers); RSlocal[w].selected = 1; lastClick = clickTime; lastClickLoc = curr; } else if (theEvent.modifiers & cmdKey) { // a command click means we should look for a url if ((RSlocal[w].selected)&(PointInSelection(curr, w))) //we have a selection already HandleURL(w); else { // we need to find the url around this pnt if (FindURLAroundPoint(curr, w)) HandleURL(w); else SysBeep(1); } } else { lastClick = clickTime; lastClickLoc = curr; if (RSlocal[w].selected) { if (!shift) { /* unhighlight current selection */ RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst); /* start new selection */ curr = RSlocal[w].last = RSlocal[w].anchor = normalize(pt, w,TRUE); } else { RSsortAnchors(w); if ((curr.v < RSlocal[w].anchor.v) || ((curr.v == RSlocal[w].anchor.v) && (curr.h < RSlocal[w].anchor.h))) { temp = RSlocal[w].anchor; RSlocal[w].anchor = RSlocal[w].last; RSlocal[w].last = temp; } } } else { /* start new selection */ curr = RSlocal[w].anchor = RSlocal[w].last = normalize(pt, w,TRUE); RSlocal[w].selected = 1; } while (StillDown()) { /* wait for mouse position to change */ do { curr = normalize(getlocalmouse(tempwndo), w,TRUE); } while (EqualPt(curr, RSlocal[w].last) && StillDown()); /* toggle highlight state of text between current and last mouse positions */ RSinvText(w, curr, RSlocal[w].last, &noConst); RSlocal[w].last = curr; } /* while */ } if (EqualPt(RSlocal[w].anchor, RSlocal[w].last)) RSlocal[w].selected = 0; else RSlocal[w].selected = 1; SetMenusForSelection((short)RSlocal[w].selected); } /* RSselect */ void FlashSelection(short w) { short i; long finalTick; for (i = 0; i < 2; i++) { Delay(5, &finalTick); RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst); Delay(5, &finalTick); RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst); } } Boolean PointInSelection(Point curr, short w) { long beg_offset, end_offset, current_offset; short columns; columns = VSgetcols(w); beg_offset = columns*RSlocal[w].anchor.v + RSlocal[w].anchor.h; end_offset = columns*RSlocal[w].last.v + RSlocal[w].last.h; if (beg_offset == end_offset) return FALSE; current_offset = columns*curr.v + curr.h; if ((current_offset >= beg_offset)&&(current_offset <= end_offset)) return TRUE; else return FALSE; } void RSzoom ( GrafPtr window, /* window to zoom */ short code, /* inZoomIn or inZoomOut */ short shifted /* bring to front or not */ ) /* called after a click in the zoom box, to zoom a terminal window. */ { WStateData **WSDhdl; short w; short h, v, x1, x2, y1, y2; short width, lines; // For setting Standard State before zooming short top, left; // Ditto SetPort(window); w = RSfindvwind(window); /* which window is it, anyway */ width = VSmaxwidth(w) + 1; lines = VSgetlines(w); WSDhdl = (WStateData **)((WindowPeek)window)->dataHandle; top = (**WSDhdl).userState.top; left = (**WSDhdl).userState.left; HLock((Handle)WSDhdl); SetRect(&((*WSDhdl)->stdState), left, top, RMAXWINDOWWIDTH + left, RMAXWINDOWHEIGHT + top); HUnlock((Handle)WSDhdl); /* EraseRect(&window->portRect); */ ZoomWindow(window, code, shifted); EraseRect(&window->portRect); /* BYU 2.4.15 */ /* get new window size */ h = window->portRect.right - window->portRect.left; v = window->portRect.bottom - window->portRect.top; RSsetsize(w, v, h); /* save new size settings and update scroll bars */ /* update the visible region of the virtual screen */ VSgetrgn(w, &x1, &y1, &x2, &y2); VSsetrgn(w, x1, y1, (x1 + (h - 16 + CHO) / FWidth -1), (y1 + (v - 16 + CVO) / FHeight - 1)); VSgetrgn(w, &x1, &y1, &x2, &y2); /* Get new region */ /* refresh the part which has been revealed, if any */ VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); /* window contents are now completely valid */ ValidRect(&window->portRect); } /* RSzoom */ Boolean RSisInFront(short w) { if (((WindowPtr)RSlocal[w].window) == FrontWindow()) return TRUE; else return FALSE; } short RSupdate ( GrafPtr wind ) /* does updating for the specified window, if it's one of mine. Returns zero iff it is. */ { short w, x1, x2, y1, y2; w = RSfindvwind(wind); if (RSsetwind(w) < 0) return(-1); /* not one of mine */ BeginUpdate(wind); RSregnconv /* find bounds of text area needing updating */ ( wind->visRgn, &x1, &y1, &x2, &y2, RScurrent->fheight, RScurrent->fwidth ); if (x2 > x1) { VSredraw(w, x1, y1, x2, y2); /* draw that text */ /* We must reset, less we risk looking UGLY as sin... */ BackPat(PATTERN(qd.white)); PenPat(PATTERN(qd.black)); if (TelInfo->haveColorQuickDraw) { PmForeColor(0); PmBackColor(1); } else { if (!RSlocal->flipped) { ForeColor(RScolors[0]); /* normal foreground */ BackColor(RScolors[7]); /* normal Background */ } else { ForeColor(RScolors[7]); /* normal foreground */ BackColor(RScolors[0]); /* normal Background */ } } /* if */ //now get that annoying strip on the right (CCP) RSa = -1; PenMode(patOr); DrawGrowIcon(wind); PenMode(patCopy); //DrawControls(wind); UpdtControl(wind, wind->visRgn); } EndUpdate(wind); return(0); } /* RSupdate */ short RSTextSelected(short w) { /* BYU 2.4.11 */ return(RSlocal[w].selected); /* BYU 2.4.11 */ } /* BYU 2.4.11 */ void RSskip ( short w, Boolean on ) /* sets the "skip" flag for the specified window (whether ignore screen updates until further notice). */ { RSlocal[w].skip = on; } /* RSskip */ /* * This routine is called when the user presses the grow icon, or when the size of * the window needs to be adjusted (where==NULL, modifiers==0). * It limits the size of the window to a legal range. */ short RSsize (GrafPtr window, long *where, long modifiers) { Rect SizRect; long size; short w, width, lines; short tw, h, v, x1, x2, y1, y2, th; Boolean changeVSSize = false; short screenIndex = 0; Boolean screenIndexValid = false; short err = noErr; if ((w = RSfindvwind(window)) < 0) /* Not found */ return (0); if (modifiers & cmdKey) return (0); screenIndexValid = (screenIndex = findbyVS(w)) != -1; changeVSSize = (modifiers & optionKey) == optionKey; #define DONT_DEFAULT_CHANGE_VS_IF_NAWS // JMB // 931112, ragge, NADA, KTH // I think this is the way it should work, if there is naws available it // should be used by default, and option toggles behaviour. // Maybe it should be user configurable? #ifndef DONT_DEFAULT_CHANGE_VS_IF_NAWS if(screenIndexValid && screens[screenIndex].naws) { changeVSSize = (modifiers & optionKey) != optionKey; } #endif SetPort(window); width = VSmaxwidth(w) + 1; //VSmaxwidth returns one less than number of columns lines = VSgetlines(w); if (changeVSSize) { th = INFINITY; tw = INFINITY-1; } else { tw = RMAXWINDOWWIDTH; th = RMAXWINDOWHEIGHT + 1; } SetRect(&SizRect, 48, 48, tw + 1, th); if (where) /* grow icon actions */ { if (changeVSSize) { /* 931112, ragge, NADA, KTH */ setupForGrow(window, 1 - CHO, 1 - CVO, FWidth, FHeight); } size = GrowWindow(window, *(Point *) where, &SizRect); /* BYU LSC */ if (changeVSSize) { /* 931112, ragge, NADA, KTH */ cleanupForGrow(window); } if (size != 0L) { SizeWindow(window, size & 0xffff, (size >> 16) & 0xffff, FALSE); h = window->portRect.right - window->portRect.left; v = window->portRect.bottom - window->portRect.top; } else return(0); /* user skipped growing */ } else { /* just resize the window */ h = window->portRect.right - window->portRect.left; /* same width */ v = (FHeight) * (VSgetlines(w)); /* new height */ SizeWindow(window, h, v, FALSE); /* change it */ } RSsetsize(w, v, h); /* save new size settings and update scroll bars */ /* update the visible region of the virtual screen */ VSgetrgn(w, &x1, &y1, &x2, &y2); VSsetrgn(w, x1, y1, (short)((x1 + (h - 16 + CHO) / FWidth - 1)), (short)((y1 + (v - 16) / FHeight - 1))); VSgetrgn(w, &x1, &y1, &x2, &y2); /* Get new region */ if (changeVSSize) { switch (VSsetlines(w,y2 -y1 +1)) { case (-4000): //can't even get enough memory to put VS back to original size /* signal this to main program */ return(-4); break; case (-3000): //no resize: unkown problems, but we put the VS back to original size return(0); break; case (-2000): //no resize: Memory problems, but we put the VS back to original size return(-2); break; default: //Ok, we can resize; tell host if ((x2 - x1 + 1) <= 132) { // bug fix from RAB 6/5/97 RScalcwsize(w,x2 - x1 +1); if (screenIndexValid && screens[screenIndex].naws) SendNAWSinfo(&screens[screenIndex], (x2-x1+1), (y2-y1+1)); } else { // RAB 6/5/97 RScalcwsize(w, 132); if (screenIndexValid && screens[screenIndex].naws) SendNAWSinfo(&screens[screenIndex], 132, (y2-y1+1)); } // RAB 6/5/97 return (0); break; } } VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); /* refresh the part which has been revealed, if any */ ValidRect(&window->portRect); /* window contents are now completely valid */ return (0); } /* RSsize */ void RSshow( short w) /* reveals a hidden terminal window. */ { VSscrn *theVS; if (RSsetwind(w) < 0) return; theVS = VSwhereis(w); RSa = -1; VSredraw(w, 0, 0, theVS->maxwidth, theVS->lines); ShowWindow(RScurrent->window); } Boolean RSsetcolor ( short w, /* window number */ short n, /* color entry number */ RGBColor Color ) /* sets a new value for the specified color entry of a terminal window. */ { if ( !(TelInfo->haveColorQuickDraw) || (RSsetwind(w) < 0) || (n > 15) || (n < 0)) return(FALSE); SetEntryColor(RScurrent->pal, n, &Color); SetPort(RScurrent->window); InvalRect(&RScurrent->window->portRect); return(TRUE); } /* RSsetcolor */ void RSsendstring ( short w, /* which terminal window */ char *ptr, /* pointer to data */ short len /* length of data */ ) /* sends some data to the host along the connection associated with the specified window. */ { short temp; temp = findbyVS(w); if (temp < 0) return; netpush(screens[temp].port); /* BYU 2.4.18 - for Diab systems? */ netwrite(screens[temp].port, ptr, len); } /* RSsendstring */ short RSnewwindow ( RectPtr wDims, short scrollback, /* number of lines to save off top */ short width, /* number of characters per text line (80 or 132) */ short lines, /* number of text lines */ StringPtr name, /* window name */ short wrapon, /* autowrap on by default */ short fnum, /* ID of font to use initially */ short fsiz, /* size of font to use initially */ short showit, /* window initially visible or not */ short goaway, /* NCSA 2.5 */ short forcesave, /* NCSA 2.5: force screen save */ short screenNumber, short allowBold, short colorBold, short ignoreBeeps, short bfnum, short bfsiz, short bfstyle, short realbold, short oldScrollback ) /* creates a virtual screen and a window to display it in. */ { GrafPort gp; /* temp port for getting text parameters */ short w; Rect pRect; short wheight, wwidth; WStateData *wstate; WindowPeek wpeek; CTabHandle ourColorTableHdl; /* create the virtual screen */ w = VSnewscreen(scrollback, (scrollback != 0), /* NCSA 2.5 */ lines, width, forcesave, ignoreBeeps, oldScrollback); /* NCSA 2.5 */ if (w < 0) { /* problems opening the virtual screen -- tell us about it */ return(-1); } RScurrent = RSlocal + w; RScurrent->fnum = fnum; RScurrent->fsiz = fsiz; RScurrent->bfnum = bfnum; RScurrent->bfsiz = bfsiz; RScurrent->bfstyle = bfstyle; OpenPort(&gp); RScurrent->allowBold = allowBold; RScurrent->colorBold = colorBold; RScurrent->realbold = realbold; RSTextFont(fnum,fsiz,0); /* BYU */ TextSize(fsiz); RSfontmetrics(); ClosePort(&gp); if (wDims->bottom == 0) calculateWindowPosition(&screens[screenNumber],wDims,lines,width); if ((wDims->right - wDims->left) > RMAXWINDOWWIDTH) wDims->right = wDims->left + RMAXWINDOWWIDTH; if ((wDims->bottom - wDims->top) > RMAXWINDOWHEIGHT) wDims->bottom = wDims->top + RMAXWINDOWHEIGHT; wwidth = wDims->right - wDims->left; wheight = wDims->bottom - wDims->top; if (!RectInRgn(wDims,TelInfo->greyRegion)) //window would be offscreen calculateWindowPosition(&screens[screenNumber],wDims,lines,width); /* create the window */ if (!TelInfo->haveColorQuickDraw) { RScurrent->window = NewWindow(0L, wDims, name, showit, 8,kInFront, goaway, (long)w); RScurrent->pal = NULL; if (RScurrent->window == NULL) { VSdestroy(w); return(-2); } } else { short i; RGBColor scratchRGB; RScurrent->window = NewCWindow(0L, wDims, name, showit, (short)8,kInFront, goaway, (long)w); if (RScurrent->window == NULL) { VSdestroy(w); return(-2); } //note: the ANSI colors are in the top 8 of the palette. The four telnet colors (settable //in telnet) are in the lower 4 of the palette. These 4 are set later by a call from //CreateConnectionFromParams to RSsetColor (ick, but I am not going to add 4 more params to //this ungodly function call (CCP 2.7) ourColorTableHdl = (CTabHandle) myNewHandle((long) (sizeof(ColorTable) + PALSIZE * sizeof(CSpecArray))); if (ourColorTableHdl == NULL) { DisposeWindow(RScurrent->window); VSdestroy(w); return(-2); } HLock((Handle) ourColorTableHdl); (*ourColorTableHdl)->ctSize = PALSIZE-1; // Number of entries minus 1 (*ourColorTableHdl)->ctFlags = 0; for (i=0; i <4; i++) //set the ctTable.value field to zero for our four (*ourColorTableHdl)->ctTable[i].value = 0; if (TelInfo->AnsiColors==NULL) return(-2); //BUGG CHANGE THIS ONCE WE ARE WORKING for (i=0; i < MAXATTR*2; i++) //get the ANSI colors from the palette { GetEntryColor(TelInfo->AnsiColors, i, &scratchRGB); (*ourColorTableHdl)->ctTable[i+4].rgb = scratchRGB; (*ourColorTableHdl)->ctTable[i+4].value = 0; } RScurrent->pal = NewPalette(PALSIZE, ourColorTableHdl, pmCourteous, 0); DisposeHandle((Handle) ourColorTableHdl); if (RScurrent->pal == NULL) { DisposeWindow(RScurrent->window); VSdestroy(w); return(-2); } SetPalette(RScurrent->window, RScurrent->pal, TRUE); //copy the palette to the window } SetPort(RScurrent->window); SetOrigin(CHO, CVO); /* Cheap way to correct left margin problem */ wpeek = (WindowPeek) RScurrent->window; HLock(wpeek->dataHandle); wstate = (WStateData *) *wpeek->dataHandle; BlockMove(&wstate->userState, wDims, 8); pRect.top = wDims->top; pRect.left = wDims->left; pRect.right = pRect.left + RMAXWINDOWWIDTH; if (pRect.right > TelInfo->screenRect.right) pRect.right = TelInfo->screenRect.right; pRect.bottom = pRect.top + RMAXWINDOWHEIGHT; BlockMove(&wstate->stdState, &pRect, 8); /* create scroll bars for window */ pRect.top = -1 + CVO; pRect.bottom = wheight - 14 + CVO; pRect.left = wwidth - 15 + CHO; pRect.right = wwidth + CHO; RScurrent->scroll = NewControl(RScurrent->window, &pRect, "\p", FALSE, /* BYU LSC */ 0, 0, 0, 16, 1L); if (RScurrent->scroll == 0L) return(-3); pRect.top = wheight - 15 + CVO; pRect.bottom = wheight + CVO; pRect.left = -1 + CHO; pRect.right = wwidth - 14 + CHO; RScurrent->left = NewControl(RScurrent->window, &pRect, "\p", FALSE, /* BYU LSC */ 0, 0, 0, 16, 1L); if (RScurrent->left == 0L) return(-3); RScurrent->skip = 0; /* not skipping output initially */ RScurrent->max = 0; /* scroll bar settings will be properly initialized by subsequent call to VSsetrgn */ RScurrent->min = 0; RScurrent->current = 0; RScurrent->lmax = 0; RScurrent->lmin = 0; RScurrent->lcurrent = 0; RScurrent->selected = 0; /* no selection initially */ RScurrent->cursorstate = 0; /* BYU 2.4.11 - cursor off initially */ RScurrent->flipped = 0; /* Initially, the color entries are not flipped */ RSsetsize(w, wheight, wwidth); RSTextFont(RScurrent->fnum,RScurrent->fsiz,0); /* BYU LSC */ TextSize(RScurrent->fsiz); /* 9 point*/ if (!TelInfo->haveColorQuickDraw) TextMode(srcXor); /* Xor mode*/ else TextMode(srcCopy); if (wrapon) /* turn on autowrap */ VSwrite(w, "\033[?7h",5); return(w); } /* RSnewwindow */ short RSmouseintext /* Point is in global coords */ ( short w, Point myPoint ) /* is myPoint within the text-display area of the specified window. */ { return PtInRect(myPoint, &RSlocal[w].textrect); /* BYU LSC */ } /* RSmouseintext */ void RSkillwindow ( short w ) /* closes a terminal window. */ { WindRecPtr tw; RSdata *temp = RSlocal + w; tw = &screens[findbyVS(w)]; --((*topLeftCorners)[tw->positionIndex]); //one less window at this position if (temp->pal != NULL) { DisposePalette(temp->pal); temp->pal = NULL; } VSdestroy(w); /* destroy the virtual screen */ KillControls(RSlocal[w].window); /* Get rid of those little slidy things */ DisposeWindow(RSlocal[w].window); /* Get rid of the actual window */ RSlocal[w].window = 0L; RSw = -1; } RGBColor RSgetcolor ( short w, /* window number */ short n /* color entry number */ ) /* gets the current value for the specified color entry of a terminal window. */ { RGBColor theColor; GetEntryColor(RSlocal[w].pal,n,&theColor); return theColor; } /* RSgetcolor */ void RShide( short w) /* hides a terminal window. */ { if (RSsetwind(w) < 0) return; HideWindow(RScurrent->window); } GrafPtr RSgetwindow ( short w ) /* returns a pointer to the Mac window structure for the specified terminal window. */ { return(RSlocal[w].window); } /* RSgetwindow */ char **RSGetTextSel ( short w, /* window to look at */ short table /* nonzero for "table" mode, i e replace this many (or more) spaces with a single tab. */ ) /* returns the contents of the current selection as a handle, or nil if there is no selection. */ { char **charh, *charp; short maxwid; long realsiz; Point Anchor,Last; if (!RSlocal[w].selected) return(0L); /* No Selection */ maxwid = VSmaxwidth(w); Anchor = RSlocal[w].anchor; Last = RSlocal[w].last; realsiz = Anchor.v - Last.v; if (realsiz < 0) realsiz = - realsiz; realsiz ++; /* lines 2,3 selected can be 2 lines */ realsiz *= (maxwid + 2); charh = myNewHandle(realsiz); if (charh == 0L) return((char **) -1L); /* Boo Boo return */ HLock((Handle)charh); charp = *charh; realsiz = VSgettext(w, Anchor.h, Anchor.v, Last.h, Last.v, charp, realsiz, "\015", table); HUnlock((Handle)charh); mySetHandleSize((Handle)charh, realsiz); return(charh); } /* RSGetTextSel */ RgnHandle RSGetTextSelRgn(short w) { Rect temp, temp2; Point lb, ub; Point curr; Point last; RgnHandle rgnH, tempRgn; rgnH = NewRgn(); if (rgnH == nil) { return nil; } tempRgn = NewRgn(); if (tempRgn == nil) { DisposeRgn(rgnH); return nil; } RSsetwind(w); curr = RSlocal[w].anchor; last = RSlocal[w].last; /* normalize coordinates with respect to visible area of virtual screen */ curr.v -= RScurrent->topline; curr.h -= RScurrent->leftmarg; last.v -= RScurrent->topline; last.h -= RScurrent->leftmarg; if (curr.v == last.v) { /* highlighted text all on one line */ if (curr.h < last.h) /* get bounds the right way round */ { ub = curr; lb = last; } else { ub = last; lb = curr; } /* if */ MYSETRECT /* set up rectangle bounding area to be highlighted */ ( temp, (ub.h + 1) * RScurrent->fwidth, ub.v * RScurrent->fheight, (lb.h + 1) * RScurrent->fwidth, (lb.v + 1) * RScurrent->fheight ); SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */ RectRgn(rgnH, &temp2); } else { /* highlighting across more than one line */ if (curr.v < last.v) ub = curr; else ub = last; if (curr.v > last.v) lb = curr; else lb = last; MYSETRECT /* bounds of first (possibly partial) line to be highlighted */ ( temp, (ub.h + 1) * RScurrent->fwidth, ub.v * RScurrent->fheight, RScurrent->width, (ub.v + 1) * RScurrent->fheight ); SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */ RectRgn(rgnH, &temp2); MYSETRECT /* bounds of last (possibly partial) line to be highlighted */ ( temp, 0, lb.v * RScurrent->fheight, (lb.h + 1) * RScurrent->fwidth, (lb.v + 1) * RScurrent->fheight ); SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */ RectRgn(tempRgn, &temp2); UnionRgn(tempRgn, rgnH, rgnH); if (lb.v - ub.v > 1) /* highlight extends across more than two lines */ { /* highlight complete in-between lines */ SetRect ( &temp, 0, (ub.v + 1) * RScurrent->fheight, RScurrent->width, lb.v * RScurrent->fheight ); SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */ RectRgn(tempRgn, &temp2); UnionRgn(tempRgn, rgnH, rgnH); } /* if */ } /* if */ DisposeRgn(tempRgn); return rgnH; } short RSfindvwind ( GrafPtr wind ) /* returns the number of the virtual screen associated with the specified window, or -4 if not found. */ { short i = 0; while ((RSlocal[i].window != wind) && (i < MaxRS)) i++; if ((RSlocal[i].window == 0L) || (i >= MaxRS)) return(-4); else return(i); } /* RSfindvwind */ void RSdeactivate ( short w ) /* handles a deactivate event for the specified window. */ { GrafPtr port; GetPort(&port); SetPort(RSlocal[w].window); RSsetConst(w); /* update the appearance of the grow icon */ DrawGrowIcon(RSlocal[w].window); /* and deactivate the scroll bars */ BackColor(whiteColor); if (RSlocal[w].scroll != 0L) HideControl(RSlocal[w].scroll); if (RSlocal[w].left != 0L) HideControl(RSlocal[w].left); if (TelInfo->haveColorQuickDraw) PmBackColor(1); else BackColor(blackColor); SetPort(port); } /* RSdeactivate */ void RScursblink( short w) /* Blinks the cursor */ { GrafPtr oldwindow; long now = TickCount(); if (now > TelInfo->blinktime) { if (VSvalids(w) != 0) /* BYU 2.4.12 */ return; /* BYU 2.4.12 */ if (!VSIcursorvisible()) /* BYU 2.4.12 */ return; /* BYU 2.4.12 - cursor isn't visible */ GetPort(&oldwindow); /* BYU 2.4.11 */ TelInfo->blinktime = now + 40; /* BYU 2.4.11 */ RSlocal[w].cursorstate ^= 1; /* BYU 2.4.11 */ SetPort(RSlocal[w].window); /* BYU 2.4.11 */ InvertRect(&RSlocal[w].cursor); /* BYU 2.4.11 */ SetPort(oldwindow); /* BYU 2.4.11 */ } } /* RScursblink */ void RScursblinkon /* BYU 2.4.18 */ ( /* BYU 2.4.18 */ short w /* BYU 2.4.18 */ ) /* BYU 2.4.18 */ /* Blinks the cursor */ /* BYU 2.4.18 */ { /* BYU 2.4.18 */ if (!VSIcursorvisible()) return; /* Bri 970610 */ if (!RSlocal[w].cursorstate) { /* BYU 2.4.18 */ GrafPtr oldwindow; /* BYU 2.4.18 */ GetPort(&oldwindow); /* BYU 2.4.18 */ RSlocal[w].cursorstate = 1; /* BYU 2.4.18 */ SetPort(RSlocal[w].window); /* BYU 2.4.18 */ InvertRect(&RSlocal[w].cursor); /* BYU 2.4.18 */ SetPort(oldwindow); /* BYU 2.4.18 */ } /* BYU 2.4.18 */ } /* RScursblink */ /* BYU 2.4.18 */ void RScursblinkoff /* BYU 2.4.11 */ ( /* BYU 2.4.11 */ short w /* BYU 2.4.11 */ ) /* BYU 2.4.11 */ /* Blinks the cursor */ /* BYU 2.4.11 */ { /* BYU 2.4.11 */ if (RSlocal[w].cursorstate) { /* BYU 2.4.11 */ GrafPtr oldwindow; /* BYU 2.4.11 */ GetPort(&oldwindow); /* BYU 2.4.11 */ RSlocal[w].cursorstate = 0; /* BYU 2.4.11 */ SetPort(RSlocal[w].window); /* BYU 2.4.11 */ InvertRect(&RSlocal[w].cursor); /* BYU 2.4.11 */ SetPort(oldwindow); /* BYU 2.4.11 */ } /* BYU 2.4.11 */ } /* RScursblink */ /* BYU 2.4.11 */ void RScprompt(short w) /* puts up the dialog that lets the user examine and change the color settings for the specified window. */ { short scratchshort, ditem; Point ColorBoxPoint; DialogPtr dptr; Boolean UserLikesNewColor; RGBColor scratchRGBcolor; dptr = GetNewMySmallDialog(ColorDLOG, NULL, kInFront, (void *)ThirdCenterDialog); for (scratchshort = 0, NumberOfColorBoxes = 4; scratchshort < NumberOfColorBoxes; scratchshort++) { RGBColor tempColor; tempColor = RSgetcolor(w,scratchshort); BoxColorItems[scratchshort] = ColorNF + scratchshort; BlockMove(&tempColor,&BoxColorData[scratchshort], sizeof(RGBColor)); UItemAssign( dptr, ColorNF + scratchshort, ColorBoxItemProcUPP); } ColorBoxPoint.h = 0; // Have the color picker center the box on the main ColorBoxPoint.v = 0; // screen ditem = 3; while (ditem > 2) { ModalDialog(ColorBoxModalProcUPP, &ditem); switch (ditem) { case ColorNF: case ColorNB: case ColorBF: case ColorBB: if (TelInfo->haveColorQuickDraw) { Str255 askColorString; GetIndString(askColorString,MISC_STRINGS,PICK_NEW_COLOR_STRING); UserLikesNewColor = GetColor(ColorBoxPoint, askColorString, &BoxColorData[ditem-ColorNF], &scratchRGBcolor); if (UserLikesNewColor) BoxColorData[ditem-ColorNF] = scratchRGBcolor; } break; default: break; } // switch } // while if (ditem == DLOGCancel) { DisposeDialog(dptr); return; } for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) RSsetcolor(w,scratchshort,BoxColorData[scratchshort]); /* force redrawing of entire window contents */ SetPort(RSlocal[w].window); InvalRect(&RSlocal[w].window->portRect); DisposeDialog(dptr); } /* RScprompt */ /*------------------------------------------------------------------------------*/ /* NCSA: SB - RScalcwsize */ /* This routine is used to switch between 80 and 132 column mode. All that */ /* is passed in is the RS window, and the new width. This calculates the */ /* new window width, resizes the window, and updates everything. - SMB */ /*------------------------------------------------------------------------------*/ void RScalcwsize(short w, short width) { short x1,x2,y1,y2; short lines; short resizeWidth, resizeHeight; Rect ourContent; RSsetwind(w); RScursoff(w); VSsetcols(w,(short)(width-1)); VSgetrgn(w, &x1, &y1, &x2, &y2); /*get current visible region */ x2= width-1; lines = VSgetlines(w); /* NCSA: SB - trust me, you need this... */ RScurrent->rwidth = RScurrent->width = (x2 - x1 + 1) * RScurrent->fwidth - CHO; RScurrent->rheight = RScurrent->height= (y2 - y1 + 1) * RScurrent->fheight; if (RScurrent->rwidth > RMAXWINDOWWIDTH - 16 - CHO) RScurrent->rwidth = RMAXWINDOWWIDTH - 16 - CHO; if (RScurrent->rheight > RMAXWINDOWHEIGHT - 16) RScurrent->rheight = RMAXWINDOWHEIGHT - 16; ourContent = (*((WindowPeek)(RScurrent->window))->contRgn)->rgnBBox; RScheckmaxwind(&ourContent,RScurrent->rwidth +16, RScurrent->rheight + 16, &resizeWidth, &resizeHeight); RScurrent->rwidth = resizeWidth - 16; RScurrent->rheight = resizeHeight - 16; SizeWindow ( RScurrent->window, RScurrent->rwidth + 16, RScurrent->rheight+16, FALSE ); RSsetsize(w, RScurrent->rheight + 16, RScurrent->rwidth + 16); VSgetrgn(w, &x1, &y1, &x2, &y2); VSsetrgn(w, x1, y1, (short) (x1 + (RScurrent->rwidth ) / RScurrent->fwidth - 1), (short) (y1 + (RScurrent->rheight) / RScurrent->fheight - 1)); VSgetrgn(w, &x1, &y1, &x2, &y2); /* Get new region */ DrawGrowIcon(RScurrent->window); VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); /* redraw newly-revealed area, if any */ ValidRect(&RScurrent->window->portRect); /* no need to do it again */ DrawControls(RScurrent->window); RScursoff(w); } /* handles a click in a terminal window. */ short RSclick( GrafPtr window, EventRecord theEvent) { ControlHandle ctrlh; short w, part, part2, x1, x2, y1, y2; Point where = theEvent.where; short shifted = (theEvent.modifiers & shiftKey); short optioned = (theEvent.modifiers & optionKey); w = 0; while ((RSlocal[w].window != window) && (w < MaxRS)) //find VS w++; if ((RSlocal[w].window == 0L) || (w >= MaxRS)) return(-1); /* what the heck is going on here?? */ SetPort(window); GlobalToLocal((Point *) &where); part = FindControl(where, window, &ctrlh); /* BYU LSC */ if (part != 0) switch (part) { case inThumb: part2 = TrackControl(ctrlh, where, 0L); /* BYU LSC */ if (part2 == inThumb) { part = GetCtlValue(ctrlh); if (ctrlh == RSlocal[w].scroll) { /* scroll visible region vertically */ VSgetrgn(w, &x1, &y1, &x2, &y2); VSsetrgn(w, x1, part, x2, part + (y2 - y1)); } else { /* ctrlh must be .left */ /* scroll visible region horizontally */ VSgetrgn(w, &x1, &y1, &x2, &y2); VSsetrgn(w, part, y1, part + (x2 - x1), y2); } /* if */ } /* if */ break; case inUpButton: case inDownButton: case inPageUp: case inPageDown: part2 = TrackControl(ctrlh, where, ScrollProcUPP); /* BYU LSC */ /* InvalRect(&(**RSlocal->scroll).contrlRect); */ /* cheap fix */ break; default: break; } /* switch */ else { if ((where.h <= RSlocal[w].width)&&(where.v <= RSlocal[w].height)) {//CCP 2.7 added the above check so that we dont do things when we are in an inactive scrollbar if (optioned) { /* send host the appropriate sequences to move the cursor to the specified position */ Point x; x = normalize(where, w,FALSE); VSpossend(w, x.h, x.v, screens[scrn].echo); /* MAT--we can check here if we want to use normal */ /* MAT--or EMACS movement. */ } else if (ClickInContent(where,w)) /* NCSA: SB - prevent BUS error */ { Boolean dragged; (void) DragText(&theEvent, where, w, &dragged); if (!dragged) RSselect(w, where, theEvent); } } } /* if */ return 0; } /* RSclick */ void RSactivate ( short w ) /* handles an activate event for the specified window. */ { RSsetConst(w); /* display the grow icon */ DrawGrowIcon(RSlocal[w].window); /* and activate the scroll bars */ if (RSlocal[w].scroll != 0L) ShowControl(RSlocal[w].scroll); if (RSlocal[w].left != 0L) ShowControl(RSlocal[w].left); } /* RSactivate */ /*--------------------------------------------------------------------------*/ /* HandleDoubleClick */ /* This is the routine that does the real dirty work. Since it is not a */ /* true TextEdit window, we have to kinda "fake" the double clicking. By */ /* this time, we already know that a double click has taken place, so check */ /* the chars to the left and right of our location, and select all chars */ /* that are appropriate -- SMB */ /*--------------------------------------------------------------------------*/ static void HandleDoubleClick(short w, short modifiers) { Point leftLoc, rightLoc, curr, oldcurr; long mySize; char theChar[5]; short mode = -1, newmode, foundEnd=0; RSsetConst(w); /* get window dims */ leftLoc = RSlocal[w].anchor; /* these two should be the same */ rightLoc = RSlocal[w].last; while(!foundEnd) /* scan to the right first */ { mySize = VSgettext(w,rightLoc.h, rightLoc.v, rightLoc.h+1, rightLoc.v, theChar,(long)1,"\015",0); if(mySize ==0 || isspace(*theChar)) /* stop if not a letter */ foundEnd =1; else rightLoc.h++; } foundEnd =0; while(!foundEnd) /* ...and then scan to the left */ { mySize = VSgettext(w,leftLoc.h-1, leftLoc.v, leftLoc.h, leftLoc.v, theChar,(long)1,"\015",0); if(mySize ==0 || isspace(*theChar)) /* STOP! */ foundEnd =1; else leftLoc.h--; } if (leftLoc.h != rightLoc.h) { /* we selected something */ RSlocal[w].anchor = leftLoc; /* new left bound */ RSlocal[w].last = rightLoc; /* and a matching new right bound */ RSlocal[w].selected = 1; /* give me credit for the selection I just made */ RSinvText(w, RSlocal[w].anchor, /* time to show it off */ RSlocal[w].last, &noConst); if (modifiers & cmdKey) // Possible URL selection HandleURL(w); else { curr.h = 0; curr.v = 0; while (StillDown()) { /* wait for mouse position to change */ do { oldcurr = curr; curr = normalize(getlocalmouse(RSlocal[w].window), w,TRUE); } while (EqualPt(curr, oldcurr) && StillDown()); if ((curr.v < leftLoc.v) || ((curr.v == leftLoc.v) && (curr.h < leftLoc.h))) { newmode = 1; // up } else if ((curr.v > leftLoc.v) || ((curr.v == leftLoc.v) && (curr.h > rightLoc.h))) { newmode = 2; // down } else newmode = -1; // inside dbl-clicked word /* toggle highlight state of text between current and last mouse positions */ if (mode == -1) { if (newmode == 2) { RSlocal[w].anchor = leftLoc; RSinvText(w, curr, rightLoc, &noConst); RSlocal[w].last = curr; } if (newmode == 1) { RSlocal[w].anchor = rightLoc; RSinvText(w, curr, leftLoc, &noConst); RSlocal[w].last = curr; } } if (mode == 1) { if (newmode == 2) { RSlocal[w].anchor = leftLoc; RSinvText(w, oldcurr, leftLoc, &noConst); RSinvText(w, rightLoc, curr, &noConst); RSlocal[w].last = curr; } if (newmode == -1) { RSlocal[w].anchor = leftLoc; RSinvText(w, oldcurr, leftLoc, &noConst); RSlocal[w].last = rightLoc; } if (newmode == mode) { RSinvText(w, oldcurr, curr, &noConst); RSlocal[w].last = curr; } } if (mode == 2) { if (newmode == 1) { RSlocal[w].anchor = rightLoc; RSinvText(w, oldcurr, rightLoc, &noConst); RSinvText(w, leftLoc, curr, &noConst); RSlocal[w].last = curr; } if (newmode == -1) { RSlocal[w].anchor = leftLoc; RSinvText(w, oldcurr, rightLoc, &noConst); RSlocal[w].last = rightLoc; } if (newmode == mode) { RSinvText(w, oldcurr, curr, &noConst); RSlocal[w].last = curr; } } mode = newmode; } /* while */ } } } Point getlocalmouse(GrafPtr wind) /* returns the current mouse position in coordinates local to the specified window. Leaves the current grafPort set to that window. */ { Point temp; SetPort(wind); GetMouse(&temp); return(temp); } /* getlocalmouse */ /*--------------------------------------------------------------------------*/ /* NCSA: SB - ClickInContent */ /* This procedure is a quick check to see if the mouse click is in the */ /* content region of the window. Normalize the point to be a VS location */ /* and then see if that is larger than what it should be... */ /* Used by RSClick to see if the click is in the scroll bars, or content.. */ /*--------------------------------------------------------------------------*/ short ClickInContent(Point where,short w) /* NCSA: SB */ { /* NCSA: SB */ Point x; /* NCSA: SB */ x = normalize(where, w,FALSE); /* NCSA: SB */ if (x.v >= VSgetlines(w)) return 0; /* NCSA: SB */ else return 1; /* NCSA: SB */ } /* NCSA: SB */ void RSchangefont(short w, short fnum,long fsiz) /* Set (w) to font fnum, size fsiz; resize window */ { Rect pRect; short x1, x2, y1, y2, width, lines; short srw,srh; WStateData *wstate; WindowPeek wpeek; short resizeWidth, resizeHeight; /* NCSA: SB */ RSsetwind(w); srw = RScurrent->rwidth; srh = RScurrent->rheight; if (fnum != -1) { RSTextFont(fnum,fsiz,0); /* BYU */ RScurrent->fnum = fnum; } /* if */ if (fsiz) { TextSize(fsiz); RScurrent->fsiz = fsiz; } /* if */ RSfontmetrics(); width = VSmaxwidth(w) + 1; lines = VSgetlines(w); /* resize window to preserve its dimensions in character cell units */ VSgetrgn(w, &x1, &y1, &x2, &y2); /* get visible region */ RScurrent->rwidth = RScurrent->width = (x2 - x1 + 1) * RScurrent->fwidth - CHO; RScurrent->rheight = RScurrent->height= (y2 - y1 + 1) * RScurrent->fheight; if (RScurrent->rwidth > RMAXWINDOWWIDTH - 16 - CHO) RScurrent->rwidth = RMAXWINDOWWIDTH - 16 - CHO; if (RScurrent->rheight > RMAXWINDOWHEIGHT - 16) RScurrent->rheight = RMAXWINDOWHEIGHT - 16; RScheckmaxwind(&RScurrent->window->portRect,RScurrent->rwidth +16, /* NCSA: SB */ RScurrent->rheight + 16, &resizeWidth, &resizeHeight); /* NCSA: SB */ SizeWindow ( RScurrent->window, RScurrent->rwidth + 16, RScurrent->rheight+16, FALSE ); /* TRUE if done right */ RSsetsize(w, RScurrent->rheight + 16, RScurrent->rwidth + 16); wpeek = (WindowPeek) RScurrent->window; HLock(wpeek->dataHandle); wstate = (WStateData *) *wpeek->dataHandle; BlockMove(&pRect, &wstate->stdState, 8); pRect.right = pRect.left + RMAXWINDOWWIDTH; if (pRect.right > TelInfo->screenRect.right) pRect.right = TelInfo->screenRect.right; pRect.bottom = pRect.top + RMAXWINDOWHEIGHT; BlockMove(&wstate->stdState, &pRect, 8); VSgetrgn(w, &x1, &y1, &x2, &y2); VSsetrgn(w, x1, y1, (short) (x1 + (RScurrent->rwidth ) / RScurrent->fwidth - 1), (short) (y1 + (RScurrent->rheight) / RScurrent->fheight - 1)); VSgetrgn(w, &x1, &y1, &x2, &y2); /* Get new region */ DrawGrowIcon(RScurrent->window); VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); /* redraw newly-revealed area, if any */ ValidRect(&RScurrent->window->portRect); /* no need to do it again */ DrawControls(RScurrent->window); } /* RSchangefont */ void RSchangebold ( short w, short allowBold, short colorBold, short inversebold ) { RSsetwind(w); RScurrent->allowBold = allowBold; RScurrent->colorBold = colorBold; RScurrent->bfstyle = inversebold; VSredraw(screens[scrn].vs,0,0,VSmaxwidth(screens[scrn].vs),VSgetlines(screens[scrn].vs)-1); } short RSgetfont ( short w, /* which window */ short *pfnum, /* where to return font ID */ short *pfsiz /* where to return font size */ ) /* returns the current font ID and size setting for the specified window. */ { if (0 > RSsetwind(w)) return -1; *pfnum = RScurrent->fnum; *pfsiz = RScurrent->fsiz; return(0); } /* RSgetfont */ void RSfontmetrics ( void ) /* calculates various metrics for drawing text with selected font and size in current grafport into *RScurrent. */ { FontInfo finforec; GrafPtr myGP; GetPort(&myGP); GetFontInfo(&finforec); RScurrent->fascent = finforec.ascent; RScurrent->fheight = finforec.ascent + finforec.descent + finforec.leading /* +1 */; RScurrent->monospaced = (CharWidth('W') == CharWidth('i')); RScurrent->fwidth = CharWidth('W'); } pascal void ScrollProc(ControlHandle control, short part) /* scroll-tracking routine which does continuous scrolling of visible region. */ { short w, kind, x1, y2, x2, y1; kind = RSfindscroll(control, &w); VSgetrgn(w, &x1, &y1, &x2, &y2); if (kind == 2) { /* horizontal scroll bar */ switch (part) { case inUpButton: /* Up is left */ VSscrolleft(w, 1); break; case inDownButton: /* Down is right */ VSscrolright(w, 1); break; case inPageUp: VSscrolleft(w, x2 - x1); /* scroll a whole windowful */ break; case inPageDown: VSscrolright(w, x2 - x1); /* scroll a whole windowful */ break; default: break; } /* switch */ } else if (kind == 1) { /* vertical scroll bar */ switch (part) { case inUpButton: VSscrolback(w, 1); break; case inDownButton: VSscrolforward(w, 1); break; case inPageUp: VSscrolback(w, y2 - y1); /* scroll a whole windowful */ break; case inPageDown: VSscrolforward(w, y2 - y1); /* scroll a whole windowful */ break; default: break; } /* switch */ } /* if */ } /* ScrollProc */ void UnHiliteSelection(short w) { RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst); RSlocal[w].selected = FALSE; } void HiliteThis(short w, Point begin, Point end) { if (RSlocal[w].selected) UnHiliteSelection(w); RSlocal[w].anchor.v = begin.v; RSlocal[w].anchor.h = begin.h; RSlocal[w].last.v = end.v; RSlocal[w].last.h = end.h; RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst); RSlocal[w].selected = TRUE; } void calculateWindowPosition(WindRec *theScreen,Rect *whereAt, short colsHigh, short colsWide) { short offset, currentCount = 0, lastIndex = 0; Boolean done = FALSE, tooFarRight = FALSE; short w = theScreen->vs; Boolean wideCount = 0; theScreen->positionIndex = 0; while (!done) { while (((*topLeftCorners)[theScreen->positionIndex] > currentCount)&& //find an empty spot (theScreen->positionIndex < MaxSess - 1)) theScreen->positionIndex++; offset = ((gApplicationPrefs->StaggerWindows == TRUE) ? gApplicationPrefs->StaggerWindowsOffset : 1) * (theScreen->positionIndex); whereAt->top = GetMBarHeight() + 25 + offset; whereAt->left = 10 + offset; if (!tooFarRight) whereAt->left += (currentCount-wideCount)*gApplicationPrefs->StaggerWindowsOffset; else wideCount += currentCount - 1; whereAt->bottom= 30000 + offset; whereAt->right = 30000 + offset; tooFarRight = (whereAt->left + (colsWide + 1)*RScurrent->fwidth + 16 - CHO > TelInfo->screenRect.right); if (tooFarRight || (whereAt->top + (colsHigh + 1)*RScurrent->fwidth + 16 - CHO > TelInfo->screenRect.bottom)) { // we are off screen if (theScreen->positionIndex == 0) return; //the window is bigger than the screensize; return; currentCount++; // go through again, pick spot with least number already at it lastIndex = theScreen->positionIndex; theScreen->positionIndex = 0; } else done = TRUE; } ((*topLeftCorners)[theScreen->positionIndex])++; //add our window to the number at this spot } void RSUpdatePalette(void) //called when ANSI colors have changed, and we need to update each { //windows palette GrafPtr oldPort; int screenIndex; GetPort(&oldPort); for (screenIndex = 0; screenIndex < TelInfo->numwindows; screenIndex++) { if ((screens[screenIndex].active == CNXN_ACTIVE)|| (screens[screenIndex].active == CNXN_OPENING)) { if (screens[screenIndex].ANSIgraphics) { if (RSsetwind(screens[screenIndex].vs) >= 0) { int i; for (i = 0; i < 16; i++) { RGBColor tempColor; GetEntryColor(TelInfo->AnsiColors, i, &tempColor); SetEntryColor(RScurrent->pal,i+4, &tempColor); //set the new color SetPort(screens[screenIndex].wind); InvalRect(&(RScurrent->window->portRect));//force a redraw } } } } } SetPort(oldPort); } void RSchangeboldfont(short w, short fnum) { RSsetwind(w); RScurrent->bfnum = fnum; VSredraw(screens[scrn].vs,0,0,VSmaxwidth(screens[scrn].vs),VSgetlines(screens[scrn].vs)-1); } /* RSchangeboldfont */ short RSgetboldfont ( short w, /* which window */ short *pfnum /* where to return font ID */ ) /* returns the current font ID and size setting for the specified window. */ { if (0 > RSsetwind(w)) return -1; *pfnum = RScurrent->bfnum; return(0); } /* RSgetboldfont */ \ No newline at end of file +// BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // #pragma profile on /* rsinterf.c */ /* A split of RSmac.c to facilitate keeping my sanity --CCP */ #include "rsdefs.h" #include "vsdata.h" #include "wind.h" #include "rsmac.proto.h" #include "vsinterf.proto.h" #include "vsintern.proto.h" #include "rsinterf.proto.h" #include "menuseg.proto.h" #include "maclook.proto.h" #include "wdefpatch.proto.h" /* 931112, ragge, NADA, KTH */ #include "parse.proto.h" #include "network.proto.h" #include "DlogUtils.proto.h" #include "url.proto.h" #include "drag.proto.h" #include "configure.proto.h" #include "errors.proto.h" #include "SmartTrackControl.h" static void calculateWindowPosition(WindRec *theScreen,Rect *whereAt, short colsHigh, short colsWide); extern WindRec *screens; extern short MaxRS; extern RSdata *RSlocal, *RScurrent; extern Rect noConst; extern short RSw, /* last window used */ RSa; /* last attrib used */ extern short **topLeftCorners; extern short NumberOfColorBoxes; extern short BoxColorItems[8]; extern RGBColor BoxColorData[8]; long RScolors[8] = //these are the old quickdraw constants, { //only used if Telinfo->hasColorQuickDraw is false blackColor, redColor, greenColor, yellowColor, blueColor, magentaColor, cyanColor, whiteColor }; SIMPLE_UPP(ScrollProc,ControlAction); SIMPLE_UPP(ActiveScrollProc,ControlAction); static void HandleDoubleClick(short w, short modifiers); void RSunload(void) {} /*------------------------------------------------------------------------------*/ /* RSselect */ /* Handle the mouse down in the session window. All we know so far is that it */ /* is somewhere in the content window, and it is NOT an option - click. */ /* Double clicking now works -- SMB */ // And I fixed it so it works correctly. Grrrr... - JMB // WARNING: Make sure RSlocal[w].selected is 1 when doing selections. If it is // zero, the autoscrolling routines will seriously hose the selection drawing. // Heed this advice, it took me two hours to find the cause of this bug! - JMB /* called on a mouse-down in the text display area of the active window. Creates or extends the highlighted selection within that window, autoscrolling as appropriate if the user drags outside the currently visible part of the display. */ void RSselect( short w, Point pt, EventRecord theEvent) { static long lastClick = 0; static Point lastClickLoc = {0,0}; GrafPtr tempwndo; Point curr, temp; long clickTime; short shift = (theEvent.modifiers & shiftKey); RSsetConst(w); tempwndo = RSlocal[w].window; curr = normalize(pt, w, TRUE); clickTime = TickCount(); if ( ( EqualPt(RSlocal[w].anchor, curr) || EqualPt(RSlocal[w].anchor, RSlocal[w].last) ) && ((clickTime - lastClick) <= GetDblTime()) && EqualPt(curr, lastClickLoc)) { /* NCSA: SB - check to see if this is a special click */ /* NCSA: SB - It has to be in the right time interval, and in the same spot */ curr = RSlocal[w].anchor = RSlocal[w].last = normalize(pt, w,TRUE); HandleDoubleClick(w, theEvent.modifiers); RSlocal[w].selected = 1; lastClick = clickTime; lastClickLoc = curr; } else if (theEvent.modifiers & cmdKey) { // a command click means we should look for a url if ((RSlocal[w].selected)&(PointInSelection(curr, w))) //we have a selection already HandleURL(w); else { // we need to find the url around this pnt if (FindURLAroundPoint(curr, w)) HandleURL(w); else SysBeep(1); } } else { lastClick = clickTime; lastClickLoc = curr; if (RSlocal[w].selected) { if (!shift) { /* unhighlight current selection */ RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst); /* start new selection */ curr = RSlocal[w].last = RSlocal[w].anchor = normalize(pt, w,TRUE); } else { RSsortAnchors(w); if ((curr.v < RSlocal[w].anchor.v) || ((curr.v == RSlocal[w].anchor.v) && (curr.h < RSlocal[w].anchor.h))) { temp = RSlocal[w].anchor; RSlocal[w].anchor = RSlocal[w].last; RSlocal[w].last = temp; } } } else { /* start new selection */ curr = RSlocal[w].anchor = RSlocal[w].last = normalize(pt, w,TRUE); RSlocal[w].selected = 1; } while (StillDown()) { /* wait for mouse position to change */ do { curr = normalize(getlocalmouse(tempwndo), w,TRUE); } while (EqualPt(curr, RSlocal[w].last) && StillDown()); /* toggle highlight state of text between current and last mouse positions */ RSinvText(w, curr, RSlocal[w].last, &noConst); RSlocal[w].last = curr; } /* while */ } if (EqualPt(RSlocal[w].anchor, RSlocal[w].last)) RSlocal[w].selected = 0; else RSlocal[w].selected = 1; SetMenusForSelection((short)RSlocal[w].selected); } /* RSselect */ void FlashSelection(short w) { short i; DELAYLONG finalTick; for (i = 0; i < 2; i++) { Delay(5, &finalTick); RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst); Delay(5, &finalTick); RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst); } } Boolean PointInSelection(Point curr, short w) { long beg_offset, end_offset, current_offset; short columns; columns = VSgetcols(w); beg_offset = columns*RSlocal[w].anchor.v + RSlocal[w].anchor.h; end_offset = columns*RSlocal[w].last.v + RSlocal[w].last.h; if (beg_offset == end_offset) return FALSE; current_offset = columns*curr.v + curr.h; if ((current_offset >= beg_offset)&&(current_offset <= end_offset)) return TRUE; else return FALSE; } void RSzoom ( GrafPtr window, /* window to zoom */ short code, /* inZoomIn or inZoomOut */ short shifted /* bring to front or not */ ) /* called after a click in the zoom box, to zoom a terminal window. */ { WStateData **WSDhdl; short w; short h, v, x1, x2, y1, y2; short width, lines; // For setting Standard State before zooming short top, left; // Ditto SetPort(window); w = RSfindvwind(window); /* which window is it, anyway */ width = VSmaxwidth(w) + 1; lines = VSgetlines(w); WSDhdl = (WStateData **)((WindowPeek)window)->dataHandle; top = (**WSDhdl).userState.top; left = (**WSDhdl).userState.left; HLock((Handle)WSDhdl); SetRect(&((*WSDhdl)->stdState), left, top, RMAXWINDOWWIDTH + left, RMAXWINDOWHEIGHT + top); HUnlock((Handle)WSDhdl); /* EraseRect(&window->portRect); */ ZoomWindow(window, code, shifted); EraseRect(&window->portRect); /* BYU 2.4.15 */ /* get new window size */ h = window->portRect.right - window->portRect.left; v = window->portRect.bottom - window->portRect.top; RSsetsize(w, v, h); /* save new size settings and update scroll bars */ /* update the visible region of the virtual screen */ VSgetrgn(w, &x1, &y1, &x2, &y2); VSsetrgn(w, x1, y1, (x1 + (h - 16 + CHO) / FWidth -1), (y1 + (v - 16 + CVO) / FHeight - 1)); VSgetrgn(w, &x1, &y1, &x2, &y2); /* Get new region */ /* refresh the part which has been revealed, if any */ VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); /* window contents are now completely valid */ ValidRect(&window->portRect); } /* RSzoom */ Boolean RSisInFront(short w) { if (((WindowPtr)RSlocal[w].window) == FrontWindow()) return TRUE; else return FALSE; } short RSupdate ( GrafPtr wind ) /* does updating for the specified window, if it's one of mine. Returns zero iff it is. */ { short w, x1, x2, y1, y2; w = RSfindvwind(wind); if (RSsetwind(w) < 0) return(-1); /* not one of mine */ BeginUpdate(wind); RSregnconv /* find bounds of text area needing updating */ ( wind->visRgn, &x1, &y1, &x2, &y2, RScurrent->fheight, RScurrent->fwidth ); if (x2 > x1) { VSredraw(w, x1, y1, x2, y2); /* draw that text */ /* We must reset, less we risk looking UGLY as sin... */ BackPat(PATTERN(qd.white)); PenPat(PATTERN(qd.black)); if (TelInfo->haveColorQuickDraw) { PmForeColor(0); PmBackColor(1); } else { if (!RSlocal->flipped) { ForeColor(RScolors[0]); /* normal foreground */ BackColor(RScolors[7]); /* normal Background */ } else { ForeColor(RScolors[7]); /* normal foreground */ BackColor(RScolors[0]); /* normal Background */ } } /* if */ //now get that annoying strip on the right (CCP) RSa = -1; PenMode(patOr); DrawGrowIcon(wind); PenMode(patCopy); //DrawControls(wind); UpdateControls(wind, wind->visRgn); } EndUpdate(wind); return(0); } /* RSupdate */ short RSTextSelected(short w) { /* BYU 2.4.11 */ return(RSlocal[w].selected); /* BYU 2.4.11 */ } /* BYU 2.4.11 */ void RSskip ( short w, Boolean on ) /* sets the "skip" flag for the specified window (whether ignore screen updates until further notice). */ { RSlocal[w].skip = on; } /* RSskip */ /* * This routine is called when the user presses the grow icon, or when the size of * the window needs to be adjusted (where==NULL, modifiers==0). * It limits the size of the window to a legal range. */ short RSsize (GrafPtr window, long *where, long modifiers) { Rect SizRect; long size; short w, width, lines; short tw, h, v, x1, x2, y1, y2, th; Boolean changeVSSize = false; short screenIndex = 0; Boolean screenIndexValid = false; short err = noErr; if ((w = RSfindvwind(window)) < 0) /* Not found */ return (0); if (modifiers & cmdKey) return (0); screenIndexValid = (screenIndex = findbyVS(w)) != -1; changeVSSize = (modifiers & optionKey) == optionKey; #define DONT_DEFAULT_CHANGE_VS_IF_NAWS // JMB // 931112, ragge, NADA, KTH // I think this is the way it should work, if there is naws available it // should be used by default, and option toggles behaviour. // Maybe it should be user configurable? #ifndef DONT_DEFAULT_CHANGE_VS_IF_NAWS if(screenIndexValid && screens[screenIndex].naws) { changeVSSize = (modifiers & optionKey) != optionKey; } #endif SetPort(window); width = VSmaxwidth(w) + 1; //VSmaxwidth returns one less than number of columns lines = VSgetlines(w); if (changeVSSize) { th = INFINITY; tw = INFINITY-1; } else { tw = RMAXWINDOWWIDTH; th = RMAXWINDOWHEIGHT + 1; } SetRect(&SizRect, 48, 48, tw + 1, th); if (where) /* grow icon actions */ { if (changeVSSize) { /* 931112, ragge, NADA, KTH */ setupForGrow(window, 1 - CHO, 1 - CVO, FWidth, FHeight); } size = GrowWindow(window, *(Point *) where, &SizRect); /* BYU LSC */ if (changeVSSize) { /* 931112, ragge, NADA, KTH */ cleanupForGrow(window); } if (size != 0L) { SizeWindow(window, size & 0xffff, (size >> 16) & 0xffff, FALSE); h = window->portRect.right - window->portRect.left; v = window->portRect.bottom - window->portRect.top; } else return(0); /* user skipped growing */ } else { /* just resize the window */ h = window->portRect.right - window->portRect.left; /* same width */ v = (FHeight) * (VSgetlines(w)); /* new height */ SizeWindow(window, h, v, FALSE); /* change it */ } RSsetsize(w, v, h); /* save new size settings and update scroll bars */ /* update the visible region of the virtual screen */ VSgetrgn(w, &x1, &y1, &x2, &y2); VSsetrgn(w, x1, y1, (short)((x1 + (h - 16 + CHO) / FWidth - 1)), (short)((y1 + (v - 16) / FHeight - 1))); VSgetrgn(w, &x1, &y1, &x2, &y2); /* Get new region */ DrawControls(window); if (changeVSSize) { switch (VSsetlines(w,y2 -y1 +1)) { case (-4000): //can't even get enough memory to put VS back to original size /* signal this to main program */ return(-4); break; case (-3000): //no resize: unkown problems, but we put the VS back to original size return(0); break; case (-2000): //no resize: Memory problems, but we put the VS back to original size return(-2); break; default: //Ok, we can resize; tell host if ((x2 - x1 + 1) <= 132) { // bug fix from RAB 6/5/97 RScalcwsize(w,x2 - x1 +1); if (screenIndexValid && screens[screenIndex].naws) SendNAWSinfo(&screens[screenIndex], (x2-x1+1), (y2-y1+1)); } else { // RAB 6/5/97 RScalcwsize(w, 132); if (screenIndexValid && screens[screenIndex].naws) SendNAWSinfo(&screens[screenIndex], 132, (y2-y1+1)); } // RAB 6/5/97 return (0); break; } } VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); /* refresh the part which has been revealed, if any */ ValidRect(&window->portRect); /* window contents are now completely valid */ return (0); } /* RSsize */ void RSshow( short w) /* reveals a hidden terminal window. */ { VSscrn *theVS; if (RSsetwind(w) < 0) return; theVS = VSwhereis(w); RSa = -1; VSredraw(w, 0, 0, theVS->maxwidth, theVS->lines); ShowWindow(RScurrent->window); } Boolean RSsetcolor ( short w, /* window number */ short n, /* color entry number */ RGBColor Color ) /* sets a new value for the specified color entry of a terminal window. */ { if ( !(TelInfo->haveColorQuickDraw) || (RSsetwind(w) < 0) || (n > 15) || (n < 0)) return(FALSE); SetEntryColor(RScurrent->pal, n, &Color); SetPort(RScurrent->window); InvalRect(&RScurrent->window->portRect); return(TRUE); } /* RSsetcolor */ void RSsendstring ( short w, /* which terminal window */ char *ptr, /* pointer to data */ short len /* length of data */ ) /* sends some data to the host along the connection associated with the specified window. */ { short temp; temp = findbyVS(w); if (temp < 0) return; netpush(screens[temp].port); /* BYU 2.4.18 - for Diab systems? */ netwrite(screens[temp].port, ptr, len); } /* RSsendstring */ short RSnewwindow ( RectPtr wDims, short scrollback, /* number of lines to save off top */ short width, /* number of characters per text line (80 or 132) */ short lines, /* number of text lines */ StringPtr name, /* window name */ short wrapon, /* autowrap on by default */ short fnum, /* ID of font to use initially */ short fsiz, /* size of font to use initially */ short showit, /* window initially visible or not */ short goaway, /* NCSA 2.5 */ short forcesave, /* NCSA 2.5: force screen save */ short screenNumber, short allowBold, short colorBold, short ignoreBeeps, short bfnum, short bfsiz, short bfstyle, short realbold, short oldScrollback, short jump, short realBlink ) /* creates a virtual screen and a window to display it in. */ { GrafPort gp; /* temp port for getting text parameters */ short w; Rect pRect; short wheight, wwidth; WStateData *wstate; WindowPeek wpeek; CTabHandle ourColorTableHdl; /* create the virtual screen */ w = VSnewscreen(scrollback, (scrollback != 0), /* NCSA 2.5 */ lines, width, forcesave, ignoreBeeps, oldScrollback, jump, realBlink); /* NCSA 2.5 */ if (w < 0) { /* problems opening the virtual screen -- tell us about it */ return(-1); } RScurrent = RSlocal + w; RScurrent->fnum = fnum; RScurrent->fsiz = fsiz; RScurrent->bfnum = bfnum; RScurrent->bfsiz = bfsiz; RScurrent->bfstyle = bfstyle; OpenPort(&gp); RScurrent->allowBold = allowBold; RScurrent->colorBold = colorBold; RScurrent->realbold = realbold; RSTextFont(fnum,fsiz,0); /* BYU */ TextSize(fsiz); RSfontmetrics(); ClosePort(&gp); if (wDims->bottom == 0) calculateWindowPosition(&screens[screenNumber],wDims,lines,width); if ((wDims->right - wDims->left) > RMAXWINDOWWIDTH) wDims->right = wDims->left + RMAXWINDOWWIDTH; if ((wDims->bottom - wDims->top) > RMAXWINDOWHEIGHT) wDims->bottom = wDims->top + RMAXWINDOWHEIGHT; wwidth = wDims->right - wDims->left; wheight = wDims->bottom - wDims->top; if (!RectInRgn(wDims,TelInfo->greyRegion)) //window would be offscreen calculateWindowPosition(&screens[screenNumber],wDims,lines,width); /* create the window */ if (!TelInfo->haveColorQuickDraw) { RScurrent->window = NewWindow(0L, wDims, name, showit, 8,kInFront, goaway, (long)w); RScurrent->pal = NULL; if (RScurrent->window == NULL) { VSdestroy(w); return(-2); } } else { short i; RGBColor scratchRGB; RScurrent->window = NewCWindow(0L, wDims, name, showit, (short)8,kInFront, goaway, (long)w); if (RScurrent->window == NULL) { VSdestroy(w); return(-2); } //note: the ANSI colors are in the top 8 of the palette. The four telnet colors (settable //in telnet) are in the lower 4 of the palette. These 4 are set later by a call from //CreateConnectionFromParams to RSsetColor (ick, but I am not going to add 4 more params to //this ungodly function call (CCP 2.7) ourColorTableHdl = (CTabHandle) myNewHandle((long) (sizeof(ColorTable) + PALSIZE * sizeof(CSpecArray))); if (ourColorTableHdl == NULL) { DisposeWindow(RScurrent->window); VSdestroy(w); return(-2); } HLock((Handle) ourColorTableHdl); (*ourColorTableHdl)->ctSize = PALSIZE-1; // Number of entries minus 1 (*ourColorTableHdl)->ctFlags = 0; for (i=0; i <4; i++) //set the ctTable.value field to zero for our four (*ourColorTableHdl)->ctTable[i].value = 0; if (TelInfo->AnsiColors==NULL) return(-2); //BUGG CHANGE THIS ONCE WE ARE WORKING for (i=0; i < MAXATTR*2; i++) //get the ANSI colors from the palette { GetEntryColor(TelInfo->AnsiColors, i, &scratchRGB); (*ourColorTableHdl)->ctTable[i+4].rgb = scratchRGB; (*ourColorTableHdl)->ctTable[i+4].value = 0; } RScurrent->pal = NewPalette(PALSIZE, ourColorTableHdl, pmCourteous, 0); DisposeHandle((Handle) ourColorTableHdl); if (RScurrent->pal == NULL) { DisposeWindow(RScurrent->window); VSdestroy(w); return(-2); } SetPalette(RScurrent->window, RScurrent->pal, TRUE); //copy the palette to the window } SetPort(RScurrent->window); SetOrigin(CHO, CVO); /* Cheap way to correct left margin problem */ wpeek = (WindowPeek) RScurrent->window; HLock(wpeek->dataHandle); wstate = (WStateData *) *wpeek->dataHandle; BlockMove(&wstate->userState, wDims, 8); pRect.top = wDims->top; pRect.left = wDims->left; pRect.right = pRect.left + RMAXWINDOWWIDTH; if (pRect.right > TelInfo->screenRect.right) pRect.right = TelInfo->screenRect.right; pRect.bottom = pRect.top + RMAXWINDOWHEIGHT; BlockMove(&wstate->stdState, &pRect, 8); /* create scroll bars for window */ pRect.top = -1 + CVO; pRect.bottom = wheight - 14 + CVO; pRect.left = wwidth - 15 + CHO; pRect.right = wwidth + CHO; RScurrent->scroll = NewControl(RScurrent->window, &pRect, "\p", FALSE, /* BYU LSC */ 0, 0, 0, 16, 1L); if (RScurrent->scroll == 0L) return(-3); pRect.top = wheight - 15 + CVO; pRect.bottom = wheight + CVO; pRect.left = -1 + CHO; pRect.right = wwidth - 14 + CHO; RScurrent->left = NewControl(RScurrent->window, &pRect, "\p", FALSE, /* BYU LSC */ 0, 0, 0, 16, 1L); if (RScurrent->left == 0L) return(-3); RScurrent->skip = 0; /* not skipping output initially */ RScurrent->max = 0; /* scroll bar settings will be properly initialized by subsequent call to VSsetrgn */ RScurrent->min = 0; RScurrent->current = 0; RScurrent->lmax = 0; RScurrent->lmin = 0; RScurrent->lcurrent = 0; RScurrent->selected = 0; /* no selection initially */ RScurrent->cursorstate = 0; /* BYU 2.4.11 - cursor off initially */ RScurrent->flipped = 0; /* Initially, the color entries are not flipped */ RSsetsize(w, wheight, wwidth); RSTextFont(RScurrent->fnum,RScurrent->fsiz,0); /* BYU LSC */ TextSize(RScurrent->fsiz); /* 9 point*/ if (!TelInfo->haveColorQuickDraw) TextMode(srcXor); /* Xor mode*/ else TextMode(srcCopy); if (wrapon) /* turn on autowrap */ VSwrite(w, "\033[?7h",5); return(w); } /* RSnewwindow */ short RSmouseintext /* Point is in global coords */ ( short w, Point myPoint ) /* is myPoint within the text-display area of the specified window. */ { return PtInRect(myPoint, &RSlocal[w].textrect); /* BYU LSC */ } /* RSmouseintext */ void RSkillwindow ( short w ) /* closes a terminal window. */ { WindRecPtr tw; RSdata *temp = RSlocal + w; tw = &screens[findbyVS(w)]; --((*topLeftCorners)[tw->positionIndex]); //one less window at this position if (temp->pal != NULL) { DisposePalette(temp->pal); temp->pal = NULL; } VSdestroy(w); /* destroy the virtual screen */ KillControls(RSlocal[w].window); /* Get rid of those little slidy things */ DisposeWindow(RSlocal[w].window); /* Get rid of the actual window */ RSlocal[w].window = 0L; RSw = -1; } RGBColor RSgetcolor ( short w, /* window number */ short n /* color entry number */ ) /* gets the current value for the specified color entry of a terminal window. */ { RGBColor theColor; GetEntryColor(RSlocal[w].pal,n,&theColor); return theColor; } /* RSgetcolor */ void RShide( short w) /* hides a terminal window. */ { if (RSsetwind(w) < 0) return; HideWindow(RScurrent->window); } GrafPtr RSgetwindow ( short w ) /* returns a pointer to the Mac window structure for the specified terminal window. */ { return(RSlocal[w].window); } /* RSgetwindow */ char **RSGetTextSel ( short w, /* window to look at */ short table /* nonzero for "table" mode, i e replace this many (or more) spaces with a single tab. */ ) /* returns the contents of the current selection as a handle, or nil if there is no selection. */ { char **charh, *charp; short maxwid; long realsiz; Point Anchor,Last; if (!RSlocal[w].selected) return(0L); /* No Selection */ maxwid = VSmaxwidth(w); Anchor = RSlocal[w].anchor; Last = RSlocal[w].last; realsiz = Anchor.v - Last.v; if (realsiz < 0) realsiz = - realsiz; realsiz ++; /* lines 2,3 selected can be 2 lines */ realsiz *= (maxwid + 2); charh = myNewHandle(realsiz); if (charh == 0L) return((char **) -1L); /* Boo Boo return */ HLock((Handle)charh); charp = *charh; realsiz = VSgettext(w, Anchor.h, Anchor.v, Last.h, Last.v, charp, realsiz, "\015", table); HUnlock((Handle)charh); mySetHandleSize((Handle)charh, realsiz); return(charh); } /* RSGetTextSel */ RgnHandle RSGetTextSelRgn(short w) { Rect temp, temp2; Point lb, ub; Point curr; Point last; RgnHandle rgnH, tempRgn; rgnH = NewRgn(); if (rgnH == nil) { return nil; } tempRgn = NewRgn(); if (tempRgn == nil) { DisposeRgn(rgnH); return nil; } RSsetwind(w); curr = RSlocal[w].anchor; last = RSlocal[w].last; /* normalize coordinates with respect to visible area of virtual screen */ curr.v -= RScurrent->topline; curr.h -= RScurrent->leftmarg; last.v -= RScurrent->topline; last.h -= RScurrent->leftmarg; if (curr.v == last.v) { /* highlighted text all on one line */ if (curr.h < last.h) /* get bounds the right way round */ { ub = curr; lb = last; } else { ub = last; lb = curr; } /* if */ MYSETRECT /* set up rectangle bounding area to be highlighted */ ( temp, (ub.h + 1) * RScurrent->fwidth, ub.v * RScurrent->fheight, (lb.h + 1) * RScurrent->fwidth, (lb.v + 1) * RScurrent->fheight ); SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */ RectRgn(rgnH, &temp2); } else { /* highlighting across more than one line */ if (curr.v < last.v) ub = curr; else ub = last; if (curr.v > last.v) lb = curr; else lb = last; MYSETRECT /* bounds of first (possibly partial) line to be highlighted */ ( temp, (ub.h + 1) * RScurrent->fwidth, ub.v * RScurrent->fheight, RScurrent->width, (ub.v + 1) * RScurrent->fheight ); SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */ RectRgn(rgnH, &temp2); MYSETRECT /* bounds of last (possibly partial) line to be highlighted */ ( temp, 0, lb.v * RScurrent->fheight, (lb.h + 1) * RScurrent->fwidth, (lb.v + 1) * RScurrent->fheight ); SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */ RectRgn(tempRgn, &temp2); UnionRgn(tempRgn, rgnH, rgnH); if (lb.v - ub.v > 1) /* highlight extends across more than two lines */ { /* highlight complete in-between lines */ SetRect ( &temp, 0, (ub.v + 1) * RScurrent->fheight, RScurrent->width, lb.v * RScurrent->fheight ); SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */ RectRgn(tempRgn, &temp2); UnionRgn(tempRgn, rgnH, rgnH); } /* if */ } /* if */ DisposeRgn(tempRgn); return rgnH; } short RSfindvwind ( GrafPtr wind ) /* returns the number of the virtual screen associated with the specified window, or -4 if not found. */ { short i = 0; while ((RSlocal[i].window != wind) && (i < MaxRS)) i++; if ((RSlocal[i].window == 0L) || (i >= MaxRS)) return(-4); else return(i); } /* RSfindvwind */ void RSdeactivate ( short w ) /* handles a deactivate event for the specified window. */ { GrafPtr port; GetPort(&port); SetPort(RSlocal[w].window); RSsetConst(w); /* update the appearance of the grow icon */ DrawGrowIcon(RSlocal[w].window); /* and deactivate the scroll bars */ BackColor(whiteColor); if (RSlocal[w].scroll != 0L) HideControl(RSlocal[w].scroll); if (RSlocal[w].left != 0L) HideControl(RSlocal[w].left); if (TelInfo->haveColorQuickDraw) PmBackColor(1); else BackColor(blackColor); SetPort(port); } /* RSdeactivate */ void RScursblink( short w) /* Blinks the cursor */ { GrafPtr oldwindow; long now = TickCount(); if (now > TelInfo->blinktime) { if (VSvalids(w) != 0) /* BYU 2.4.12 */ return; /* BYU 2.4.12 */ if (!VSIcursorvisible()) /* BYU 2.4.12 */ return; /* BYU 2.4.12 - cursor isn't visible */ GetPort(&oldwindow); /* BYU 2.4.11 */ TelInfo->blinktime = now + 40; /* BYU 2.4.11 */ RSlocal[w].cursorstate ^= 1; /* BYU 2.4.11 */ SetPort(RSlocal[w].window); /* BYU 2.4.11 */ InvertRect(&RSlocal[w].cursor); /* BYU 2.4.11 */ SetPort(oldwindow); /* BYU 2.4.11 */ } } /* RScursblink */ void RScursblinkon /* BYU 2.4.18 */ ( /* BYU 2.4.18 */ short w /* BYU 2.4.18 */ ) /* BYU 2.4.18 */ /* Blinks the cursor */ /* BYU 2.4.18 */ { /* BYU 2.4.18 */ if (VSvalids(w) != 0) /* BYU 2.4.12 */ return; /* BYU 2.4.12 */ if (!VSIcursorvisible()) return; /* Bri 970610 */ if (!RSlocal[w].cursorstate) { /* BYU 2.4.18 */ GrafPtr oldwindow; /* BYU 2.4.18 */ GetPort(&oldwindow); /* BYU 2.4.18 */ RSlocal[w].cursorstate = 1; /* BYU 2.4.18 */ SetPort(RSlocal[w].window); /* BYU 2.4.18 */ InvertRect(&RSlocal[w].cursor); /* BYU 2.4.18 */ SetPort(oldwindow); /* BYU 2.4.18 */ } /* BYU 2.4.18 */ } /* RScursblink */ /* BYU 2.4.18 */ void RScursblinkoff /* BYU 2.4.11 */ ( /* BYU 2.4.11 */ short w /* BYU 2.4.11 */ ) /* BYU 2.4.11 */ /* Blinks the cursor */ /* BYU 2.4.11 */ { /* BYU 2.4.11 */ if (VSvalids(w) != 0) /* BYU 2.4.12 */ return; /* BYU 2.4.12 */ if (RSlocal[w].cursorstate) { /* BYU 2.4.11 */ GrafPtr oldwindow; /* BYU 2.4.11 */ GetPort(&oldwindow); /* BYU 2.4.11 */ RSlocal[w].cursorstate = 0; /* BYU 2.4.11 */ SetPort(RSlocal[w].window); /* BYU 2.4.11 */ InvertRect(&RSlocal[w].cursor); /* BYU 2.4.11 */ SetPort(oldwindow); /* BYU 2.4.11 */ } /* BYU 2.4.11 */ } /* RScursblink */ /* BYU 2.4.11 */ void RScprompt(short w) /* puts up the dialog that lets the user examine and change the color settings for the specified window. */ { short scratchshort, ditem; Point ColorBoxPoint; DialogPtr dptr; Boolean UserLikesNewColor; RGBColor scratchRGBcolor; dptr = GetNewMySmallDialog(ColorDLOG, NULL, kInFront, (void *)ThirdCenterDialog); for (scratchshort = 0, NumberOfColorBoxes = 4; scratchshort < NumberOfColorBoxes; scratchshort++) { RGBColor tempColor; tempColor = RSgetcolor(w,scratchshort); BoxColorItems[scratchshort] = ColorNF + scratchshort; BlockMove(&tempColor,&BoxColorData[scratchshort], sizeof(RGBColor)); UItemAssign( dptr, ColorNF + scratchshort, ColorBoxItemProcUPP); } ColorBoxPoint.h = 0; // Have the color picker center the box on the main ColorBoxPoint.v = 0; // screen ditem = 3; while (ditem > 2) { ModalDialog(ColorBoxModalProcUPP, &ditem); switch (ditem) { case ColorNF: case ColorNB: case ColorBF: case ColorBB: if (TelInfo->haveColorQuickDraw) { Str255 askColorString; GetIndString(askColorString,MISC_STRINGS,PICK_NEW_COLOR_STRING); UserLikesNewColor = GetColor(ColorBoxPoint, askColorString, &BoxColorData[ditem-ColorNF], &scratchRGBcolor); if (UserLikesNewColor) BoxColorData[ditem-ColorNF] = scratchRGBcolor; } break; default: break; } // switch } // while if (ditem == DLOGCancel) { DisposeDialog(dptr); return; } for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) RSsetcolor(w,scratchshort,BoxColorData[scratchshort]); /* force redrawing of entire window contents */ SetPort(RSlocal[w].window); InvalRect(&RSlocal[w].window->portRect); DisposeDialog(dptr); } /* RScprompt */ /*------------------------------------------------------------------------------*/ /* NCSA: SB - RScalcwsize */ /* This routine is used to switch between 80 and 132 column mode. All that */ /* is passed in is the RS window, and the new width. This calculates the */ /* new window width, resizes the window, and updates everything. - SMB */ /*------------------------------------------------------------------------------*/ void RScalcwsize(short w, short width) { short x1,x2,y1,y2; short lines; short resizeWidth, resizeHeight; Rect ourContent; RSsetwind(w); RScursoff(w); VSsetcols(w,(short)(width-1)); VSgetrgn(w, &x1, &y1, &x2, &y2); /*get current visible region */ x2= width-1; lines = VSgetlines(w); /* NCSA: SB - trust me, you need this... */ RScurrent->rwidth = RScurrent->width = (x2 - x1 + 1) * RScurrent->fwidth - CHO; RScurrent->rheight = RScurrent->height= (y2 - y1 + 1) * RScurrent->fheight; if (RScurrent->rwidth > RMAXWINDOWWIDTH - 16 - CHO) RScurrent->rwidth = RMAXWINDOWWIDTH - 16 - CHO; if (RScurrent->rheight > RMAXWINDOWHEIGHT - 16) RScurrent->rheight = RMAXWINDOWHEIGHT - 16; ourContent = (*((WindowPeek)(RScurrent->window))->contRgn)->rgnBBox; RScheckmaxwind(&ourContent,RScurrent->rwidth +16, RScurrent->rheight + 16, &resizeWidth, &resizeHeight); RScurrent->rwidth = resizeWidth - 16; RScurrent->rheight = resizeHeight - 16; SizeWindow ( RScurrent->window, RScurrent->rwidth + 16, RScurrent->rheight+16, FALSE ); RSsetsize(w, RScurrent->rheight + 16, RScurrent->rwidth + 16); VSgetrgn(w, &x1, &y1, &x2, &y2); VSsetrgn(w, x1, y1, (short) (x1 + (RScurrent->rwidth ) / RScurrent->fwidth - 1), (short) (y1 + (RScurrent->rheight) / RScurrent->fheight - 1)); VSgetrgn(w, &x1, &y1, &x2, &y2); /* Get new region */ DrawGrowIcon(RScurrent->window); VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); /* redraw newly-revealed area, if any */ ValidRect(&RScurrent->window->portRect); /* no need to do it again */ DrawControls(RScurrent->window); RScursoff(w); } /* handles a click in a terminal window. */ short RSclick( GrafPtr window, EventRecord theEvent) { ControlHandle ctrlh; short w, part, part2, x1, x2, y1, y2; Point where = theEvent.where; short shifted = (theEvent.modifiers & shiftKey); short optioned = (theEvent.modifiers & optionKey); w = 0; while ((RSlocal[w].window != window) && (w < MaxRS)) //find VS w++; if ((RSlocal[w].window == 0L) || (w >= MaxRS)) return(-1); /* what the heck is going on here?? */ SetPort(window); GlobalToLocal((Point *) &where); part = FindControl(where, window, &ctrlh); /* BYU LSC */ if (part != 0) switch (part) { case inThumb: if (gApplicationPrefs->noLiveScrolling) // RAB BetterTelnet 2.0b2 part2 = TrackControl(ctrlh, where, 0L); else part2 = SmartTrackControl(ctrlh, where, ActiveScrollProcUPP); /* BYU LSC */ if (part2 == inThumb) { part = GetControlValue(ctrlh); if (ctrlh == RSlocal[w].scroll) { /* scroll visible region vertically */ VSgetrgn(w, &x1, &y1, &x2, &y2); VSsetrgn(w, x1, part, x2, part + (y2 - y1)); } else { /* ctrlh must be .left */ /* scroll visible region horizontally */ VSgetrgn(w, &x1, &y1, &x2, &y2); VSsetrgn(w, part, y1, part + (x2 - x1), y2); } /* if */ } /* if */ break; case inUpButton: case inDownButton: case inPageUp: case inPageDown: part2 = TrackControl(ctrlh, where, ScrollProcUPP); /* BYU LSC */ /* InvalRect(&(**RSlocal->scroll).contrlRect); */ /* cheap fix */ break; default: break; } /* switch */ else { if ((where.h <= RSlocal[w].width)&&(where.v <= RSlocal[w].height)) {//CCP 2.7 added the above check so that we dont do things when we are in an inactive scrollbar if (optioned) { /* send host the appropriate sequences to move the cursor to the specified position */ Point x; x = normalize(where, w,FALSE); VSpossend(w, x.h, x.v, screens[scrn].echo); /* MAT--we can check here if we want to use normal */ /* MAT--or EMACS movement. */ } else if (ClickInContent(where,w)) /* NCSA: SB - prevent BUS error */ { Boolean dragged; (void) DragText(&theEvent, where, w, &dragged); if (!dragged) RSselect(w, where, theEvent); } } } /* if */ return 0; } /* RSclick */ void RSactivate ( short w ) /* handles an activate event for the specified window. */ { RSsetConst(w); /* display the grow icon */ DrawGrowIcon(RSlocal[w].window); /* and activate the scroll bars */ if (RSlocal[w].scroll != 0L) ShowControl(RSlocal[w].scroll); if (RSlocal[w].left != 0L) ShowControl(RSlocal[w].left); } /* RSactivate */ /*--------------------------------------------------------------------------*/ /* HandleDoubleClick */ /* This is the routine that does the real dirty work. Since it is not a */ /* true TextEdit window, we have to kinda "fake" the double clicking. By */ /* this time, we already know that a double click has taken place, so check */ /* the chars to the left and right of our location, and select all chars */ /* that are appropriate -- SMB */ /*--------------------------------------------------------------------------*/ static void HandleDoubleClick(short w, short modifiers) { Point leftLoc, rightLoc, curr, oldcurr; long mySize; char theChar[5]; short mode = -1, newmode, foundEnd=0; RSsetConst(w); /* get window dims */ leftLoc = RSlocal[w].anchor; /* these two should be the same */ rightLoc = RSlocal[w].last; while(!foundEnd) /* scan to the right first */ { mySize = VSgettext(w,rightLoc.h, rightLoc.v, rightLoc.h+1, rightLoc.v, theChar,(long)1,"\015",0); if(mySize ==0 || isspace(*theChar)) /* stop if not a letter */ foundEnd =1; else rightLoc.h++; } foundEnd =0; while(!foundEnd) /* ...and then scan to the left */ { mySize = VSgettext(w,leftLoc.h-1, leftLoc.v, leftLoc.h, leftLoc.v, theChar,(long)1,"\015",0); if(mySize ==0 || isspace(*theChar)) /* STOP! */ foundEnd =1; else leftLoc.h--; } if (leftLoc.h != rightLoc.h) { /* we selected something */ RSlocal[w].anchor = leftLoc; /* new left bound */ RSlocal[w].last = rightLoc; /* and a matching new right bound */ RSlocal[w].selected = 1; /* give me credit for the selection I just made */ RSinvText(w, RSlocal[w].anchor, /* time to show it off */ RSlocal[w].last, &noConst); if (modifiers & cmdKey) // Possible URL selection HandleURL(w); else { curr.h = 0; curr.v = 0; while (StillDown()) { /* wait for mouse position to change */ do { oldcurr = curr; curr = normalize(getlocalmouse(RSlocal[w].window), w,TRUE); } while (EqualPt(curr, oldcurr) && StillDown()); if ((curr.v < leftLoc.v) || ((curr.v == leftLoc.v) && (curr.h < leftLoc.h))) { newmode = 1; // up } else if ((curr.v > leftLoc.v) || ((curr.v == leftLoc.v) && (curr.h > rightLoc.h))) { newmode = 2; // down } else newmode = -1; // inside dbl-clicked word /* toggle highlight state of text between current and last mouse positions */ if (mode == -1) { if (newmode == 2) { RSlocal[w].anchor = leftLoc; RSinvText(w, curr, rightLoc, &noConst); RSlocal[w].last = curr; } if (newmode == 1) { RSlocal[w].anchor = rightLoc; RSinvText(w, curr, leftLoc, &noConst); RSlocal[w].last = curr; } } if (mode == 1) { if (newmode == 2) { RSlocal[w].anchor = leftLoc; RSinvText(w, oldcurr, leftLoc, &noConst); RSinvText(w, rightLoc, curr, &noConst); RSlocal[w].last = curr; } if (newmode == -1) { RSlocal[w].anchor = leftLoc; RSinvText(w, oldcurr, leftLoc, &noConst); RSlocal[w].last = rightLoc; } if (newmode == mode) { RSinvText(w, oldcurr, curr, &noConst); RSlocal[w].last = curr; } } if (mode == 2) { if (newmode == 1) { RSlocal[w].anchor = rightLoc; RSinvText(w, oldcurr, rightLoc, &noConst); RSinvText(w, leftLoc, curr, &noConst); RSlocal[w].last = curr; } if (newmode == -1) { RSlocal[w].anchor = leftLoc; RSinvText(w, oldcurr, rightLoc, &noConst); RSlocal[w].last = rightLoc; } if (newmode == mode) { RSinvText(w, oldcurr, curr, &noConst); RSlocal[w].last = curr; } } mode = newmode; } /* while */ } } } Point getlocalmouse(GrafPtr wind) /* returns the current mouse position in coordinates local to the specified window. Leaves the current grafPort set to that window. */ { Point temp; SetPort(wind); GetMouse(&temp); return(temp); } /* getlocalmouse */ /*--------------------------------------------------------------------------*/ /* NCSA: SB - ClickInContent */ /* This procedure is a quick check to see if the mouse click is in the */ /* content region of the window. Normalize the point to be a VS location */ /* and then see if that is larger than what it should be... */ /* Used by RSClick to see if the click is in the scroll bars, or content.. */ /*--------------------------------------------------------------------------*/ short ClickInContent(Point where,short w) /* NCSA: SB */ { /* NCSA: SB */ Point x; /* NCSA: SB */ x = normalize(where, w,FALSE); /* NCSA: SB */ if (x.v >= VSgetlines(w)) return 0; /* NCSA: SB */ else return 1; /* NCSA: SB */ } /* NCSA: SB */ void RSchangefont(short w, short fnum,long fsiz) /* Set (w) to font fnum, size fsiz; resize window */ { Rect pRect; short x1, x2, y1, y2, width, lines; short srw,srh; WStateData *wstate; WindowPeek wpeek; short resizeWidth, resizeHeight; /* NCSA: SB */ RSsetwind(w); srw = RScurrent->rwidth; srh = RScurrent->rheight; if (fnum != -1) { RSTextFont(fnum,fsiz,0); /* BYU */ RScurrent->fnum = fnum; } /* if */ if (fsiz) { TextSize(fsiz); RScurrent->fsiz = fsiz; } /* if */ RSfontmetrics(); width = VSmaxwidth(w) + 1; lines = VSgetlines(w); /* resize window to preserve its dimensions in character cell units */ VSgetrgn(w, &x1, &y1, &x2, &y2); /* get visible region */ RScurrent->rwidth = RScurrent->width = (x2 - x1 + 1) * RScurrent->fwidth - CHO; RScurrent->rheight = RScurrent->height= (y2 - y1 + 1) * RScurrent->fheight; if (RScurrent->rwidth > RMAXWINDOWWIDTH - 16 - CHO) RScurrent->rwidth = RMAXWINDOWWIDTH - 16 - CHO; if (RScurrent->rheight > RMAXWINDOWHEIGHT - 16) RScurrent->rheight = RMAXWINDOWHEIGHT - 16; RScheckmaxwind(&RScurrent->window->portRect,RScurrent->rwidth +16, /* NCSA: SB */ RScurrent->rheight + 16, &resizeWidth, &resizeHeight); /* NCSA: SB */ SizeWindow ( RScurrent->window, RScurrent->rwidth + 16, RScurrent->rheight+16, FALSE ); /* TRUE if done right */ RSsetsize(w, RScurrent->rheight + 16, RScurrent->rwidth + 16); wpeek = (WindowPeek) RScurrent->window; HLock(wpeek->dataHandle); wstate = (WStateData *) *wpeek->dataHandle; BlockMove(&pRect, &wstate->stdState, 8); pRect.right = pRect.left + RMAXWINDOWWIDTH; if (pRect.right > TelInfo->screenRect.right) pRect.right = TelInfo->screenRect.right; pRect.bottom = pRect.top + RMAXWINDOWHEIGHT; BlockMove(&wstate->stdState, &pRect, 8); VSgetrgn(w, &x1, &y1, &x2, &y2); VSsetrgn(w, x1, y1, (short) (x1 + (RScurrent->rwidth ) / RScurrent->fwidth - 1), (short) (y1 + (RScurrent->rheight) / RScurrent->fheight - 1)); VSgetrgn(w, &x1, &y1, &x2, &y2); /* Get new region */ DrawGrowIcon(RScurrent->window); VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); /* redraw newly-revealed area, if any */ ValidRect(&RScurrent->window->portRect); /* no need to do it again */ DrawControls(RScurrent->window); } /* RSchangefont */ void RSchangebold ( short w, short allowBold, short colorBold, short inversebold ) { RSsetwind(w); RScurrent->allowBold = allowBold; RScurrent->colorBold = colorBold; RScurrent->bfstyle = inversebold; VSredraw(screens[scrn].vs,0,0,VSmaxwidth(screens[scrn].vs),VSgetlines(screens[scrn].vs)-1); } short RSgetfont ( short w, /* which window */ short *pfnum, /* where to return font ID */ short *pfsiz /* where to return font size */ ) /* returns the current font ID and size setting for the specified window. */ { if (0 > RSsetwind(w)) return -1; *pfnum = RScurrent->fnum; *pfsiz = RScurrent->fsiz; return(0); } /* RSgetfont */ void RSfontmetrics ( void ) /* calculates various metrics for drawing text with selected font and size in current grafport into *RScurrent. */ { FontInfo finforec; GrafPtr myGP; GetPort(&myGP); GetFontInfo(&finforec); RScurrent->fascent = finforec.ascent; RScurrent->fheight = finforec.ascent + finforec.descent + finforec.leading /* +1 */; RScurrent->monospaced = (CharWidth('W') == CharWidth('i')); RScurrent->fwidth = CharWidth('W'); } pascal void ScrollProc(ControlHandle control, short part) /* scroll-tracking routine which does continuous scrolling of visible region. */ { short w, kind, x1, y2, x2, y1, value; kind = RSfindscroll(control, &w); VSgetrgn(w, &x1, &y1, &x2, &y2); if (kind == 2) { /* horizontal scroll bar */ switch (part) { case inUpButton: /* Up is left */ VSscrolleft(w, 1); break; case inDownButton: /* Down is right */ VSscrolright(w, 1); break; case inPageUp: VSscrolleft(w, x2 - x1); /* scroll a whole windowful */ break; case inPageDown: VSscrolright(w, x2 - x1); /* scroll a whole windowful */ break; default: break; } /* switch */ } else if (kind == 1) { /* vertical scroll bar */ switch (part) { case inUpButton: VSscrolback(w, 1); break; case inDownButton: VSscrolforward(w, 1); break; case inPageUp: VSscrolback(w, y2 - y1); /* scroll a whole windowful */ break; case inPageDown: VSscrolforward(w, y2 - y1); /* scroll a whole windowful */ break; default: break; } /* switch */ } /* if */ } /* ScrollProc */ pascal void ActiveScrollProc(ControlHandle control, short part) /* scroll-tracking routine which does continuous scrolling of visible region. */ { short w, kind, x1, y2, x2, y1, value; kind = RSfindscroll(control, &w); VSgetrgn(w, &x1, &y1, &x2, &y2); if (kind == 2) { /* horizontal scroll bar */ switch (part) { case inThumb: value = GetControlValue(control); /* scroll visible region horizontally */ VSsetrgn(w, value, y1, value + (x2 - x1), y2); break; default: break; } /* switch */ } else if (kind == 1) { /* vertical scroll bar */ switch (part) { case inThumb: value = GetControlValue(control); /* scroll visible region vertically */ VSsetrgn(w, x1, value, x2, value + (y2 - y1)); break; default: break; } /* switch */ } /* if */ } /* ActiveScrollProc */ void UnHiliteSelection(short w) { RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst); RSlocal[w].selected = FALSE; } void HiliteThis(short w, Point begin, Point end) { if (RSlocal[w].selected) UnHiliteSelection(w); RSlocal[w].anchor.v = begin.v; RSlocal[w].anchor.h = begin.h; RSlocal[w].last.v = end.v; RSlocal[w].last.h = end.h; RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst); RSlocal[w].selected = TRUE; } void calculateWindowPosition(WindRec *theScreen,Rect *whereAt, short colsHigh, short colsWide) { short offset, currentCount = 0, lastIndex = 0; Boolean done = FALSE, tooFarRight = FALSE; short w = theScreen->vs; Boolean wideCount = 0; theScreen->positionIndex = 0; while (!done) { while (((*topLeftCorners)[theScreen->positionIndex] > currentCount)&& //find an empty spot (theScreen->positionIndex < MaxSess - 1)) theScreen->positionIndex++; offset = ((gApplicationPrefs->StaggerWindows == TRUE) ? gApplicationPrefs->StaggerWindowsOffset : 1) * (theScreen->positionIndex); whereAt->top = GetMBarHeight() + 25 + offset; whereAt->left = 10 + offset; if (!tooFarRight) whereAt->left += (currentCount-wideCount)*gApplicationPrefs->StaggerWindowsOffset; else wideCount += currentCount - 1; whereAt->bottom= 30000 + offset; whereAt->right = 30000 + offset; tooFarRight = (whereAt->left + (colsWide + 1)*RScurrent->fwidth + 16 - CHO > TelInfo->screenRect.right); if (tooFarRight || (whereAt->top + (colsHigh + 1)*RScurrent->fwidth + 16 - CHO > TelInfo->screenRect.bottom)) { // we are off screen if (theScreen->positionIndex == 0) return; //the window is bigger than the screensize; return; currentCount++; // go through again, pick spot with least number already at it lastIndex = theScreen->positionIndex; theScreen->positionIndex = 0; } else done = TRUE; } ((*topLeftCorners)[theScreen->positionIndex])++; //add our window to the number at this spot } void RSUpdatePalette(void) //called when ANSI colors have changed, and we need to update each { //windows palette GrafPtr oldPort; int screenIndex; GetPort(&oldPort); for (screenIndex = 0; screenIndex < TelInfo->numwindows; screenIndex++) { if ((screens[screenIndex].active == CNXN_ACTIVE)|| (screens[screenIndex].active == CNXN_OPENING)) { if (screens[screenIndex].ANSIgraphics) { if (RSsetwind(screens[screenIndex].vs) >= 0) { int i; for (i = 0; i < 16; i++) { RGBColor tempColor; GetEntryColor(TelInfo->AnsiColors, i, &tempColor); SetEntryColor(RScurrent->pal,i+4, &tempColor); //set the new color SetPort(screens[screenIndex].wind); InvalRect(&(RScurrent->window->portRect));//force a redraw } } } } } SetPort(oldPort); } void RSchangeboldfont(short w, short fnum) { RSsetwind(w); RScurrent->bfnum = fnum; VSredraw(screens[scrn].vs,0,0,VSmaxwidth(screens[scrn].vs),VSgetlines(screens[scrn].vs)-1); } /* RSchangeboldfont */ short RSgetboldfont ( short w, /* which window */ short *pfnum /* where to return font ID */ ) /* returns the current font ID and size setting for the specified window. */ { if (0 > RSsetwind(w)) return -1; *pfnum = RScurrent->bfnum; return(0); } /* RSgetboldfont */ \ No newline at end of file diff --git a/source/Screens/rsinterf.proto.h b/source/Screens/rsinterf.proto.h index 0195191..cdaccf0 100755 --- a/source/Screens/rsinterf.proto.h +++ b/source/Screens/rsinterf.proto.h @@ -1 +1 @@ -/* rsinterf.proto.h */ void RSunload(void); void RSselect(short w, Point pt, EventRecord theEvent); void RSzoom(GrafPtr window, short code, short shifted); short RSupdate(GrafPtr wind); short RSTextSelected(short w); void RSskip(short w, Boolean on); short RSsize(GrafPtr window, long *where, long modifiers); void RSshow(short w); Boolean RSsetcolor(short w, short n, RGBColor Color); void RSsendstring(short w, char *ptr, short len); short RSnewwindow(RectPtr wDims,short scrollback, short width, short lines, StringPtr name, short wrapon, short fnum, short fsiz, short showit, short goaway, short forcesave, short screenNumber, short allowBold, short colorBold, short ignoreBeeps, short bfnum, short bfsiz, short bfstyle, short realbold, short oldScrollback); short RSmouseintext(short w, Point myPoint); void RSkillwindow(short w); RGBColor RSgetcolor(short w, short n); void RShide(short w); GrafPtr RSgetwindow(short w); char **RSGetTextSel(short w, short table); RgnHandle RSGetTextSelRgn(short w); short RSfindvwind(GrafPtr wind); void RSdeactivate(short w); void RScursblink(short w); void RScursblinkon(short w); void RScursblinkoff(short w); void RScprompt(short w); void RScalcwsize(short w, short width); short RSclick(GrafPtr window, EventRecord theEvent); void RSactivate(short w); short ClickInContent(Point where, short w); Point getlocalmouse(GrafPtr wind); void RSchangefont(short w, short fnum, long fsiz); void RSchangeboldfont(short w, short fnum); void RSchangebold(short, short, short, short); short RSgetfont(short w, short *pfnum, short *pfsiz); short RSgetboldfont(short w, short *pfnum); void RSfontmetrics(void); pascal void ScrollProc(ControlHandle control, short part); void FlashSelection(short w); Boolean PointInSelection(Point curr, short w); void UnHiliteSelection(short w); void HiliteThis(short w, Point begin, Point end); void RSUpdatePalette(void); Boolean RSisInFront(short w); \ No newline at end of file +/* rsinterf.proto.h */ void RSunload(void); void RSselect(short w, Point pt, EventRecord theEvent); void RSzoom(GrafPtr window, short code, short shifted); short RSupdate(GrafPtr wind); short RSTextSelected(short w); void RSskip(short w, Boolean on); short RSsize(GrafPtr window, long *where, long modifiers); void RSshow(short w); Boolean RSsetcolor(short w, short n, RGBColor Color); void RSsendstring(short w, char *ptr, short len); short RSnewwindow(RectPtr wDims,short scrollback, short width, short lines, StringPtr name, short wrapon, short fnum, short fsiz, short showit, short goaway, short forcesave, short screenNumber, short allowBold, short colorBold, short ignoreBeeps, short bfnum, short bfsiz, short bfstyle, short realbold, short oldScrollback, short jump, short); short RSmouseintext(short w, Point myPoint); void RSkillwindow(short w); RGBColor RSgetcolor(short w, short n); void RShide(short w); GrafPtr RSgetwindow(short w); char **RSGetTextSel(short w, short table); RgnHandle RSGetTextSelRgn(short w); short RSfindvwind(GrafPtr wind); void RSdeactivate(short w); void RScursblink(short w); void RScursblinkon(short w); void RScursblinkoff(short w); void RScprompt(short w); void RScalcwsize(short w, short width); short RSclick(GrafPtr window, EventRecord theEvent); void RSactivate(short w); short ClickInContent(Point where, short w); Point getlocalmouse(GrafPtr wind); void RSchangefont(short w, short fnum, long fsiz); void RSchangeboldfont(short w, short fnum); void RSchangebold(short, short, short, short); short RSgetfont(short w, short *pfnum, short *pfsiz); short RSgetboldfont(short w, short *pfnum); void RSfontmetrics(void); pascal void ScrollProc(ControlHandle control, short part); pascal void ActiveScrollProc(ControlHandle control, short part); void FlashSelection(short w); Boolean PointInSelection(Point curr, short w); void UnHiliteSelection(short w); void HiliteThis(short w, Point begin, Point end); void RSUpdatePalette(void); Boolean RSisInFront(short w); \ No newline at end of file diff --git a/source/Screens/rsmac.c b/source/Screens/rsmac.c index c41237c..da24426 100755 --- a/source/Screens/rsmac.c +++ b/source/Screens/rsmac.c @@ -1 +1 @@ -/* * * Virtual Screen Kernel Macintosh Real Screen Interface * (rsmac.c) * * National Center for Supercomputing Applications * by Gaige B. Paulsen * * This file contains the macintosh real screen calls for the NCSA * Virtual Screen Kernel. * * RSbell(w) - Ring window w's bell * RScursoff(w) - Turn the cursor off in w * RScurson(w,x,y) - Turn the cursor on in w at x,y * RSdraw(w,x,y,a,len,ptr) - Draw @x,y in w string@ptr for length len * RSdelchars(w,x,y,n) - Delete n chars in w from x,y * RSdellines(w,t,b,n) - Delete n lines in region t->b in w * RSerase(w,x1,y1,x2,y2) - Erase from x1,y1 to x2,y2 in w * RSinitall() - Initialize the world if necessary * RSinslines(w,t,b,n) - Insert n lines in region t->b in w * RSinsstring(w,x,y,a,len,ptr)- Insert len chars @x,y in w attrib a * RSsendstring(w,ptr,len) - Send string @ptr length len from window w * RSbufinfo( w, total,current)- Tells you the total/current lines in buffer * RSmargininfo( w, total, current) - Tells you total/current columns in VS * * * Macintosh only Routines: * NI RSregnconv( *) - Convert region to rect coords * NI RSsetwind(w) - Set the port and vars to window w * NI RSsetattr(a) - Set font/text style to a * NI RSsetConst(w) * ML RSattach(w,wind) - Attach the RS (w) to window wind * ML RSdetach(w) - Ready window for go-away * ML RSselect(w,pt,shift) - Handle selection RS (w) point (pt) and (shift) if held down * ML RSzoom(window,code,shifted) - Zoom Box handling * ML RSsize( window, where) - Resize handling * IN RSgetwindow(w) - Get the WindowPtr for RS (w) * IN RSfindvwind(wind) - Find the (RS/VS) # of wind * IN RSfindscroll( control, n) - Find which VS the control is in and which control it is * RSupdate(wind) - Handle updates on WIND, return 0 if not an RS * RSactivate(w) - Handle activate events * RSdeactivate(w) - Handle deactivate events * RSGetTextSel(w,table) - Returns handle to text selection of window w, table->tabs * RSnewwindow( wDims, sb, wid, lines * name,wrap,fnum,fsiz, * showit, goaway) - Returns VS # of newly created text window - * wDims (dimension),sb(scrollback),wid(width 80/132), * lines (# of lines, 24 <> 66), * name(window), wrap(0/1),fnum,fsiz, showit(vis),goaway(0,1) * RSkillwindow( w) - Destroys, deallocates, kills window (w) * RSclick(window, eventRecord)- Handle clicks in window (returns false if not RS window) * RShide(w) - Hide RS (w) * RSshow(w) - Show RS (w) * RScprompt(w, FilterProc) - Prompt for colors...FilterProc is for Modal Dialog * RSsetcolor(w,n,r,g,b) - Set one of the 4 colors of RS (w) to R,G,B * RSgetcolor(w,n,r,g,b) - Get one of the 4 colors of RS (w) into R,G,B * RSmouseintext(w,myPoint) - Returns true if Mouse is in text part of current RS window * RSskip(w,on) - Activate/deactivate drawing in an RS * * IN - Informational * ML - Mid Level * NI - Necessary Internal * - Suggested calls * * Version Date Notes * ------- ------ --------------------------------------------------- * 0.01 861102 Initial coding -GBP * 0.25 861106 Added code from screen.c -GBP * 0.50 861113 First compiled edition -GBP * 2.1 871130 NCSA Telnet 2.1 -GBP * 2.2 880715 NCSA Telnet 2.2 -GBP * 2.6 7/92 put globals into struct, cursors into array, and cleaned up * some of the font typedefs Scott Bulmahn * 2.6b4 12/92 Cleaned up the code, and added double clicking -- Scott Bulmahn * */ #ifdef MPW #pragma segment RS #endif #define __ALLNU__ #include "DlogUtils.proto.h" #include "configure.proto.h" // For colorboxmodalproc and colorboxproc #include "maclook.proto.h" #include "network.proto.h" #include "menuseg.proto.h" #include "vskeys.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "vsintern.proto.h" #include "wind.h" #include "rsdefs.h" #include "parse.proto.h" // For SendNAWSinfo proto #include "wdefpatch.proto.h" /* 931112, ragge, NADA, KTH */ #include "drag.proto.h" #include "rsinterf.proto.h" #include "event.proto.h" //notify user proto #define NFDEF {0,0,0} #define NBDEF {65535,65535,65535} #define BFDEF {0,61183,11060} #define BBDEF {61183,2079,4938} #define UFDEF {1,0,0} #define UBDEF {0,0,0} extern WindRec *screens; #include "rsmac.proto.h" short MaxRS; RSdata *RSlocal, *RScurrent; Rect noConst, RScur; /* cursor rectangle */ RgnHandle RSuRgn; /* update region */ short RSw=-1, /* last window used */ RSa=0; /* last attrib used */ extern long RScolors[]; // initializes handling of terminal windows void RSinitall(short max) //max windows to allow { short i; MaxRS = max; RSlocal = (RSdata *) myNewPtr(MaxRS * sizeof(RSdata)); for (i = 0; i < MaxRS; RSlocal[i++].window = 0L) { RScurrent = RSlocal + i; RScurrent->id = 'RSDA'; RScurrent->cursor.top = 0; RScurrent->cursor.bottom = 0; RScurrent->cursor.left = 0; RScurrent->cursor.right = 0; } RSuRgn = NewRgn(); RScur.left = 0; RScur.top = 0; RScur.bottom = 0; RScur.right = 0; if (!TelInfo->haveColorQuickDraw) DisposeHandle((Handle)TelInfo->AnsiColors); } // RSinitall void RSsetConst ( short w ) /* sets "noConst" global to a zero-based rectangle equal in size to the specified terminal window. */ { noConst.left = 0; noConst.top = 0; noConst.right = RSlocal[w].width; noConst.bottom = RSlocal[w].height; } /* RSsetConst */ /****************************************************************************/ /* Given a window record number, do a SetPort() to the window associated with * that window record. */ short RSsetwind ( short w ) { if ((w < 0) || (w > MaxRS)) return(-3); if (RSw != w) /* if last window used is different */ { if (RSlocal[w].window == 0L) return(-4); RScurrent = RSlocal + w; RSw = w; RSa = -1; /* attributes will need setting */ SetPort(RScurrent->window); return(1); } SetPort(RScurrent->window); return(0); } /* RSsetwind */ void RSvalidateRect(short w) { ValidRect(&((RSlocal[w].window)->portRect)); } void RSbell ( short w ) /* gives an audible signal associated with the specified window. */ { RSsetwind(w); if (FrontWindow() != RScurrent->window) { /* beep and temporarily invert the window contents, so the user sees which window is beeping */ InvertRect(&RScurrent->window->portRect); SysBeep(8); InvertRect(&RScurrent->window->portRect); } else /* window is frontmost--just beep */ SysBeep(8); NotifyUser(); } /* RSbell */ void RScursoff ( short w ) /* hides the text cursor for the specified window. Assumes it is currently being shown. */ { if (RSlocal[w].skip || !RSlocal[w].cursorstate) /* BYU 2.4.11 */ return; RSsetwind(w); RScurrent->cursorstate = 0; /* BYU 2.4.11 */ InvertRect(&RScurrent->cursor); } /* RScursoff */ void RScurson ( short w, short x, short y ) /* displays the text cursor for the specified window, at the specified position. Assumes it isn't currently being shown. */ { if (RSlocal[w].skip || RSlocal[w].cursorstate) /* BYU 2.4.11 */ return; RSsetwind(w); RScurrent->cursor.left = x * RScurrent->fwidth; /* BYU 2.4.11 */ RScurrent->cursor.top = y * RScurrent->fheight; /* BYU 2.4.11 */ switch (gApplicationPrefs->CursorType) { /* BYU 2.4.11 */ case UNDERSCORECURSOR: /* BYU 2.4.11 */ RScurrent->cursor.top += RScurrent->fheight; /* BYU 2.4.11 */ RScurrent->cursor.right = RScurrent->cursor.left + RScurrent->fwidth; /* BYU 2.4.11 */ RScurrent->cursor.bottom = RScurrent->cursor.top + 1; /* BYU 2.4.11 */ break; case VERTICALCURSOR: /* BYU 2.4.11 */ RScurrent->cursor.left += 2; /* BYU 2.4.11 */ RScurrent->cursor.right = RScurrent->cursor.left + 1; /* BYU 2.4.11 */ RScurrent->cursor.bottom = RScurrent->cursor.top + RScurrent->fheight; /* BYU 2.4.11 */ break; case BLOCKCURSOR: /* BYU 2.4.11 */ default: /* BYU 2.4.11 */ RScurrent->cursor.right = RScurrent->cursor.left + RScurrent->fwidth; /* BYU 2.4.11 */ RScurrent->cursor.bottom = RScurrent->cursor.top + RScurrent->fheight; /* BYU 2.4.11 */ break; } if (!gApplicationPrefs->BlinkCursor) { /* BYU 2.4.11 */ RScurrent->cursorstate = 1; /* BYU 2.4.11 */ InvertRect(&RScurrent->cursor); /* BYU 2.4.11 */ } /* BYU 2.4.11 */ } /* RScurson */ void RSsetattr(short a) { short fg, bg, tempFontID; // RAB BetterTelnet 1.0fc4 static GrafPtr lastPort; if (RSa!=-1 && RSa==a && qd.thePort==lastPort) return; lastPort = qd.thePort; RSa = a; if (VSisgrph(a)) { GetFNum("\p%NCSA VT", &tempFontID); // RAB BetterTelnet 1.0fc4 TextFont(tempFontID); /* use "NCSA VT" (74) font for special graphics */ } else RSTextFont(RScurrent->fnum,RScurrent->fsiz,((a & bold) && RScurrent->allowBold)); /* BYU - use user-selected text font */ TextSize(RScurrent->fsiz); /* BYU - bold system fonts don't work (they overwrite the scroll bars), but NCSA's 9 point Monaco bold works okay. */ if (VSisbold(a) && RScurrent->realbold) TextFace(((a & outline) >> 1) + 1); else TextFace((a & outline) >> 1); /* BYU - do outline as underline setting */ if (VSisansifg(a)) { fg = 4 +((a>>8)&0x7); if (RScurrent->colorBold && VSisbold(a)) fg += 8; } else if (RScurrent->colorBold && VSisbold(a)) fg = gApplicationPrefs->defaultBoldColor + 4; else fg = 0; if (VSisansibg(a)) bg = 4+ ((a>>12)&0x7); else bg = 1; // set up text modes if (TelInfo->haveColorQuickDraw) { if (VSisrev(a) || ((a & bold) && RScurrent->bfstyle)) TextMode(notSrcCopy); else TextMode(srcCopy); } else { if (VSisrev(a) || ((a & bold) && RScurrent->bfstyle)) { BackPat(PATTERN(qd.black)); /* Reverses current attributes regard */ PenPat(PATTERN(qd.white)); /* less of the color, etc.... */ } else { BackPat(PATTERN(qd.white)); /* Reverses current attributes regard */ PenPat(PATTERN(qd.black)); /* less of the color, etc.... */ } } //set up colors if (TelInfo->haveColorQuickDraw) { if (VSisblnk(a)) { PmForeColor(2); //use colors for blink PmBackColor(3); } else { PmForeColor(fg); PmBackColor(bg); } } else { if (VSisblnk(a)) { ForeColor(RScolors[7]); //use colors for blink BackColor(RScolors[0]); } else { ForeColor(RScolors[0]); BackColor(RScolors[7]); } } } /* RSsetattr */ void RSTextFont(short myfnum, short myfsiz, short myface) /* BYU */ { /* BYU */ short tempFontID; // RAB BetterTelnet 1.0fc4 // RAB BetterTelnet 1.0fc4: For one thing, we use font *names* now. Also, we use NCSA VT Bold // when the user wants, not when it's Monaco 9. if (// (myfnum == monaco) && /* BYU - If Monaco, size 9, and bold, then */ // (myfsiz == 9) && /* BYU */ (myface & bold)) { /* BYU */ // GetFNum("\p%NCSA VT Bold", &tempFontID); // TextFont(tempFontID); /* BYU - use NCSA's Monaco. (75) */ TextFont(RScurrent->bfnum); // RAB BetterTelnet 1.0fc9 } else { /* BYU */ TextFont(myfnum); /* BYU */ } /* BYU */ } /* BYU */ #ifdef NO_UNIVERSAL #define LMGetHiliteMode() (* (unsigned char *) 0x0938) #define LMSetHiliteMode(HiliteModeValue) ((* (unsigned char *) 0x0938) = (HiliteModeValue)) #endif void DoHiliteMode(void) /* BYU LSC */ /* enables use of highlighting in place of simple color inversion for next QuickDraw operation. */ { LMSetHiliteMode(LMGetHiliteMode() & 0x7F); // char *p = (char *) 0x938; /* pointer to HiliteMode low-memory global */ // *p = *p & 0x7f; /* clear the HiliteBit */ } /* HiliteMode */ void RSinvText ( short w, Point curr, Point last, RectPtr constrain /* don't highlight anything outside this rectangle */ ) /* highlights the text from curr to last inclusive. */ { Rect temp, temp2; Point lb, ub; RSsetwind(w); /* normalize coordinates with respect to visible area of virtual screen */ curr.v -= RScurrent->topline; curr.h -= RScurrent->leftmarg; last.v -= RScurrent->topline; last.h -= RScurrent->leftmarg; if (curr.v == last.v) { /* highlighted text all on one line */ if (curr.h < last.h) /* get bounds the right way round */ { ub = curr; lb = last; } else { ub = last; lb = curr; } /* if */ MYSETRECT /* set up rectangle bounding area to be highlighted */ ( temp, (ub.h + 1) * RScurrent->fwidth, ub.v * RScurrent->fheight, (lb.h + 1) * RScurrent->fwidth, (lb.v + 1) * RScurrent->fheight ); SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */ DoHiliteMode(); /* BYU LSC */ InvertRect(&temp2); } else { /* highlighting across more than one line */ if (curr.v < last.v) ub = curr; else ub = last; if (curr.v > last.v) lb = curr; else lb = last; MYSETRECT /* bounds of first (possibly partial) line to be highlighted */ ( temp, (ub.h + 1) * RScurrent->fwidth, ub.v * RScurrent->fheight, RScurrent->width, (ub.v + 1) * RScurrent->fheight ); SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */ DoHiliteMode(); /* BYU LSC */ InvertRect(&temp2); MYSETRECT /* bounds of last (possibly partial) line to be highlighted */ ( temp, 0, lb.v * RScurrent->fheight, (lb.h + 1) * RScurrent->fwidth, (lb.v + 1) * RScurrent->fheight ); SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */ DoHiliteMode(); /* BYU LSC */ InvertRect(&temp2); if (lb.v - ub.v > 1) /* highlight extends across more than two lines */ { /* highlight complete in-between lines */ SetRect ( &temp, 0, (ub.v + 1) * RScurrent->fheight, RScurrent->width, lb.v * RScurrent->fheight ); SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */ DoHiliteMode(); /* BYU LSC */ InvertRect(&temp2); } /* if */ } /* if */ } /* RSinvText */ void RSdraw ( short w, /* window number */ short x, /* starting column */ short y, /* line on which to draw */ short a, /* text attributes */ short len, /* length of text to draw */ char *ptr /* pointer to text */ ) /* draws a piece of text (assumed to fit on a single line) in a window, using the specified attributes. If any part of the text falls within the current selection, it will be highlighted. */ { Rect rect; short ys; if (RSlocal[w].skip) return; RSsetwind(w); // RSsetattr(0); JMB 2.6.1d4 ys = y * RScurrent->fheight; MYSETRECT /* set up rectangle bounding text being drawn */ ( rect, x * RScurrent->fwidth, ys, (x + len) * RScurrent->fwidth, ys + RScurrent->fheight ); RSsetattr(a); if (x <= 0) /* BYU 2.4.12 - Without this, 1 pixel column of reverse */ rect.left = -3; /* BYU 2.4.12 - video text does not clear at left margin */ if (rect.bottom == RScurrent->rheight) rect.bottom += 1; //CCP take care of updating problems while scrolling EraseRect(&rect); if (x <= 0) /* BYU 2.4.12 - Okay, just putting it back the way it was */ rect.left = 0; /* BYU 2.4.12 */ MoveTo(x * RScurrent->fwidth, ys + RScurrent->fascent); DrawText(ptr, 0, len); if (RScurrent->selected) RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect); ValidRect(&rect); } /* RSdraw */ void RSdelcols ( short w, short n /* number of columns to scroll */ ) /* scrolls the entire visible display of a virtual screen the specified number of columns to the left, blanking out the newly-revealed area. */ { Rect rect; if (RSlocal[w].skip) return; RSsetwind(w); MYSETRECT /* bounds of entire text area, for scrolling */ ( rect, 0, 0, RScurrent->width, RScurrent->height ); ScrollRect(&rect, -n * RScurrent->fwidth, 0, RSuRgn); InvalRgn(RSuRgn); ValidRect(&rect); /* any necessary redrawing in newly-revealed area will be done by caller */ MYSETRECT /* bounds of newly-revealed area */ ( rect, RScurrent->width - (n * RScurrent->fwidth), 0, RScurrent->width, RScurrent->height ); if (RScurrent->selected) /* highlight any newly-revealed part of the current selection */ RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect); } /* RSdelcols */ void RSdelchars ( short w, /* affected window */ short x, /* column to delete from */ short y, /* line on which to do deletion */ short n /* number of characters to delete */ ) /* deletes the specified number of characters from the specified position to the right, moving the remainder of the line to the left. */ { Rect rect; if (RSlocal[w].skip) return; RSsetwind(w); RSsetattr(0); /* avoid funny pen modes */ MYSETRECT /* bounds of area from starting column to end of line */ ( rect, x * RScurrent->fwidth, y * RScurrent->fheight, RScurrent->width, (y + 1) * RScurrent->fheight ); if ((x + n) * RScurrent->fwidth > RScurrent->width) /* deleting to end of line */ EraseRect(&rect); else { /* scroll remainder of line to the left */ ScrollRect(&rect, - RScurrent->fwidth * n, 0, RSuRgn); InvalRgn(RSuRgn); ValidRect(&rect); /* leave newly-revealed area blank */ if (RScurrent->selected) { /* highlight any part of selection which lies in newly-blanked area */ HLock((Handle) RSuRgn); RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &((*RSuRgn)->rgnBBox)); HUnlock((Handle) RSuRgn); } /* if */ } /* if */ } /* RSdelchars */ void RSdellines ( short w, /* affected window */ short t, /* top line of affected region */ short b, /* bottom line of affected region */ short n, /* number of lines to delete */ short scrolled /* -ve => cancel current selection, if any; +ve => selection has moved up one line; 0 => don't touch selection */ ) /* deletes lines at the top of the specified region of a window, inserting new blank lines at the bottom, and scrolling up the stuff in between. */ { Rect rect; short RSfheightTimesn, RSfheightTimesbplus1; if (RSlocal[w].skip) return; RSsetwind(w); RSsetConst(w); RSsetattr(0); /* avoid funny pen modes */ if (scrolled) { if (RScurrent->selected && scrolled < 0) { /* unhighlight and cancel current selection */ RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &noConst); RScurrent->selected = 0; } else { RScurrent->last.v -= 1; /* Subtract one from each of the */ RScurrent->anchor.v -= 1; /* vertical Selection components */ } /* if */ } /* if */ rect.left = -1; /* BYU 2.4.12 - necessary */ rect.right = RScurrent->width; rect.top = t * RScurrent->fheight; RSfheightTimesbplus1 = (b + 1) * RScurrent->fheight; rect.bottom = RSfheightTimesbplus1; /* adjust the update region to track the scrolled window contents */ RSfheightTimesn = RScurrent->fheight * n; OffsetRgn(((WindowPeek) RScurrent->window)->updateRgn, 0, -RSfheightTimesn); ScrollRect(&rect, 0, -RSfheightTimesn , RSuRgn); RSsetattr(VSIw->attrib); /* restore mode for text drawing */ InvalRgn(RSuRgn); /* validate the area containing the newly-inserted blank lines. */ /* any necessary redrawing in newly-revealed area will be done by caller */ MYSETRECT ( rect, 0, (b - n + 1) * RScurrent->fheight - 1, RScurrent->width, RSfheightTimesbplus1 + 1 ); ValidRect(&rect); } /* RSdellines */ void RSerase ( short w, /* affected window */ short x1, /* left column */ short y1, /* top line */ short x2, /* right column */ short y2 /* bottom line */ ) /* erases a rectangular portion of the screen display, preserving the selection highlight. */ { Rect rect; if (RSlocal[w].skip) return; RSsetwind(w); RSsetattr(0); /* avoid funny pen modes */ SetRect ( &rect, x1 * RScurrent->fwidth , y1 * RScurrent->fheight, (x2 + 1) * RScurrent->fwidth - 1, (y2 + 1) * RScurrent->fheight + 1 ); if (rect.left <= 0) /* little buffer strip on left */ rect.left = CHO; if (rect.right >= RScurrent->width - 1) rect.right = RScurrent->rwidth - 2; /* clear to edge of window, including edge strip */ if (rect.bottom >= RScurrent->height - 2) rect.bottom = RScurrent->rheight + 1; /* clear to bottom edge also */ EraseRect(&rect); if (RScurrent->selected) /* highlight any part of the selection within the cleared area */ RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect); } /* RSerase */ void RSinslines ( short w, /* affected window */ short t, /* where to insert blank lines */ short b, /* bottom of area to scroll */ short n, /* number of lines to insert */ short scrolled /* -ve <=> cancel current selection, if any */ ) /* inserts blank lines at the top of the given area of the display, scrolling the rest of it down. */ { Rect rect; if (RSlocal[w].skip) return; RSsetwind(w); RSsetConst(w); RSsetattr(0); /* avoid funny pen modes */ if (RScurrent->selected && (scrolled < 0)) { /* unhighlight and cancel selection */ RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &noConst); RScurrent->selected = 0; } /* if */ rect.left = -1; /* BYU 2.4.12 - necessary */ rect.right = RScurrent->width; rect.top = t * RScurrent->fheight; rect.bottom = (b + 1) * RScurrent->fheight; /* adjust the update region to track the scrolled window contents */ OffsetRgn(((WindowPeek) RScurrent->window)->updateRgn, 0, RScurrent->fheight * n); ScrollRect(&rect, 0, RScurrent->fheight * n, RSuRgn); InvalRgn(RSuRgn); /* newly-inserted area is already blank -- validate it to avoid redrawing. */ /* any necessary redrawing will be done by caller */ SetRect(&rect, 0, t * RScurrent->fheight - 1, RScurrent->width, (t + n) * RScurrent->fheight + 1); ValidRect(&rect); } /* RSinslines */ void RSinscols ( short w, short n /* number of columns to insert */ ) /* inserts blank columns at the left side of the text display in the specified window, scrolling its current contents to the right. Maintains the selection highlight, but doesn't move the selection. Doesn't even unhighlight text which moves out of the selection area. */ { Rect rect; if (RSlocal[w].skip) return; RSsetwind(w); SetRect /* bounds of entire text area */ ( &rect, 0, 0, RScurrent->width, RScurrent->height ); ScrollRect(&rect, n * RScurrent->fwidth, 0, RSuRgn); InvalRgn(RSuRgn); ValidRect(&rect); /* any necessary redrawing in newly-revealed area will be done by caller */ SetRect /* bounds of newly-inserted blank area */ ( &rect, 0, 0, (n + 1) * RScurrent->fwidth - 1, RScurrent->height ); if (RScurrent->selected) /* highlight any part of the selection in the newly-blanked area */ RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect); } /* RSinscols */ void RSinsstring ( short w, /* affected window */ short x, /* starting column at which to insert */ short y, /* line on which to insert */ short a, /* attributes for inserted text */ short len, /* length of inserted text */ char *ptr /* pointer to inserted text */ ) /* inserts a string of characters at the specified position, scrolling the rest of the line to the right. Highlights any part of the newly- inserted text lying within the current selection. */ { Rect rect; if (RSlocal[w].skip) return; RSsetwind(w); SetRect /* bounds of part of line from specified position to end of line */ ( &rect, x * RScurrent->fwidth, y * RScurrent->fheight, RScurrent->width, (y + 1) * RScurrent->fheight ); ScrollRect(&rect, len * RScurrent->fwidth, 0, RSuRgn); /* scroll remainder of line to the right */ if (RSa != a) RSsetattr(a); InvalRgn(RSuRgn); ValidRect(&rect); /* any necessary redrawing in newly-revealed area will be done by caller */ SetRect /* bounds area to contain inserted string */ ( &rect, x * RScurrent->fwidth, y * RScurrent->fheight, (x + len) * RScurrent->fwidth, (y + 1) * RScurrent->fheight ); EraseRect(&rect); /* erase area to appropriate background */ MoveTo ( x * RScurrent->fwidth, y * RScurrent->fheight + RScurrent->fascent ); DrawText(ptr, 0, len); if (RScurrent->selected) /* highlight any part of selection covering the newly-inserted text */ RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect); } /* RSinsstring */ void RSmargininfo ( short w, short total, /* number of invisible character positions (screen width less visible width) */ short current /* leftmost visible character position */ ) /* updates the horizontal scroll bar and associated variables to reflect the current view of the virtual screen within the specified window. */ { RSlocal[w].leftmarg = current; /* Adjust local vars */ if (RSlocal[w].lcurrent != current) SetCtlValue(RSlocal[w].left, (RSlocal[w].lcurrent = current)); if (RSlocal[w].lmax != total) SetCtlMax(RSlocal[w].left, (RSlocal[w].lmax = total)); } /* RSmargininfo */ void RSbufinfo ( short w, /* affected window */ short total, /* number of lines of scrollback */ short current, /* current topmost visible line */ short bottom /* current bottommost visible line */ ) /* readjusts the vertical scroll bar and associated variables to reflect the current view of the virtual screen within the specified window. */ { RSdata *RSthis; short newmax; RSthis = RSlocal + w; newmax = (VSgetlines(w) - 1) - (bottom - current); RSthis->topline = current; /* Adjust local vars */ if (RSthis->min != -total) { if (RSthis->min == 0) //need to activate scrollbars SetCtlMin(RSthis->scroll, (RSthis->min = -total)); (**RSthis->scroll).contrlMin = (RSthis->min = -total); // JMB 2.6.1d4 } /* if */ if (RSthis->current != current) SetCtlValue(RSthis->scroll, (RSthis->current = current)); if (RSthis->max != newmax) (**RSthis->scroll).contrlMax = (RSthis->max = newmax); // JMB 2.6.1d4 } /* RSbufinfo */ short RSfindscroll /* Find screen index by control*/ ( ControlHandle control, short *n ) /* finds the window to which the given scroll bar belongs. Returns the window number in *n if found, and a function result of 1 for a vertical scroll bar, 2 for a horizontal one, or -1 if the window wasn't found. */ { /* look for a vertical scroll bar */ *n = 0; while ((*n < MaxRS) && (control != RSlocal[*n].scroll)) (*n)++; if (*n < MaxRS) return (1); /* found it */ /* look for a horizontal scroll bar */ *n = 0; while ((*n < MaxRS) && (control != RSlocal[*n].left)) (*n)++; if (*n < MaxRS) return (2); /* found it */ return(-1); /* not found */ } /* RSfindscroll */ void RSregnconv ( RgnHandle regn, short *x1, /* left (output) */ short *y1, /* top (output) */ short *x2, /* right (output) */ short *y2, /* bottom (output) */ short fh, /* font character height */ short fw /* font character width */ ) /* converts the bounding box of the specified QuickDraw region into units of character positions (using the specified character height and width) and returns the results in *x1, *y1, *x2 and *y2. */ { HLock((Handle) regn); *y1 = ((*regn)->rgnBBox.top) / fh; *y2 = (((*regn)->rgnBBox.bottom) + fh - 1) / fh; *x1 = ((*regn)->rgnBBox.left) / fw; *x2 = (((*regn)->rgnBBox.right) + fw - 1) / fw; HUnlock((Handle) regn); if (*x1 < 0) *x1 = 0; if (*y1 < 0) *y1 = 0; if (*x2 < 0) *x2 = 0; if (*y2 < 0) *y2 = 0; } /* RSregnconv */ #define Fwidthhalf FWidth/2 Point normalize(Point in, short w, Boolean autoScroll) /* converts in from a pixel position in local coordinates to a character cell position within the virtual screen corresponding to the specified window. Constrains the position to lie within the currently-visible region of the screen, autoscrolling the screen if necessary (and if autoScroll = TRUE). */ { if (in.v <0) { in.v = 0; if (autoScroll) VSscrolback(w, 1); } /* if */ if (in.v > RSlocal[w].height) { in.v = RSlocal[w].height; if (autoScroll) VSscrolforward(w, 1); } /* if */ in.v = in.v / FHeight; if (in.h < 0) { in.h = -1; if (autoScroll) VSscrolleft(w, 1); } /* if */ if (in.h > RSlocal[w].width) { in.h = RSlocal[w].width; if (autoScroll) VSscrolright(w, 1); } /* if */ /* in.h = (in.h + Fwidthhalf) / FWidth - 1; */ /* the MPW C 3.0 compiler has a bug in its register allocation */ /* which keeps the above line from working. So, replace it with this: */ in.h = in.h + Fwidthhalf; in.h = in.h / FWidth - 1; /* note the bug has been fixed in the 3.1 compiler. */ /* convert to virtual screen coordinates */ in.v += RSlocal[w].topline; in.h += RSlocal[w].leftmarg; return(in); } /* normalize */ void RSsortAnchors(short w) { Point temp; if (RSlocal[w].anchor.v > RSlocal[w].last.v) { temp = RSlocal[w].anchor; RSlocal[w].anchor = RSlocal[w].last; RSlocal[w].last = temp; } if ((RSlocal[w].anchor.v == RSlocal[w].last.v) && (RSlocal[w].anchor.h > RSlocal[w].last.h)) { temp = RSlocal[w].anchor; RSlocal[w].anchor = RSlocal[w].last; RSlocal[w].last = temp; } } void RSsetsize( short w, short v, short h) /* saves the new size settings for a window, and repositions the scroll bars accordingly. */ { RSlocal[w].height = ((v - 16 + CVO) / FHeight) * FHeight; RSlocal[w].width = ((h - 16 + CHO) / FWidth) * FWidth; RSlocal[w].rheight = v - 16; RSlocal[w].rwidth = h - 16; /* * Get rid of the scroll bars which were in the old size. * Hiding them causes the region to be updated later. */ if (RSlocal[w].scroll != NULL ) HideControl(RSlocal[w].scroll); if (RSlocal[w].left != NULL ) HideControl(RSlocal[w].left); DrawGrowIcon(RSlocal[w].window); /* Draw in the necessary bugger */ /* move the scroll bars to their new positions and sizes, and redisplay them */ SetCtlValue(RSlocal[w].scroll, RSlocal[w].current); //because we dont always have this if (RSlocal[w].scroll != NULL ) { SizeControl(RSlocal[w].scroll, 16, (v - 13)); MoveControl(RSlocal[w].scroll, (h - 15) + CHO, -1 + CVO); ShowControl(RSlocal[w].scroll); } if (RSlocal[w].left != NULL ) { SizeControl(RSlocal[w].left, (h - 13), 16); MoveControl(RSlocal[w].left, -1 + CHO, (v - 15) + CVO); ShowControl(RSlocal[w].left); } SetRect(&RSlocal[w].textrect, 0, 0, RSlocal[w].rwidth, RSlocal[w].rheight); } /* RSsetsize */ /*--------------------------------------------------------------------------*/ /* NCSA: SB - RSbackground */ /* This procedure allows Telnet to switch from dark background to light */ /* background. Save the current state into the RSdata struct, so that */ /* we know our background state next time we want to do anything. */ /* Make sure the screen contents (and palette) is updated NOW. */ /*--------------------------------------------------------------------------*/ void RSbackground(short w, short value) { RGBColor temp1,temp2; RSsetwind(w); if ((value && !RSlocal[w].flipped) || (!value && RSlocal[w].flipped)) { RSlocal[w].flipped = !RSlocal[w].flipped; if (TelInfo->haveColorQuickDraw) //flip the background and foreground color positions { GetEntryColor(RSlocal[w].pal,0,&temp1); GetEntryColor(RSlocal[w].pal,1,&temp2); SetEntryColor(RSlocal[w].pal,0,&temp2); SetEntryColor(RSlocal[w].pal,1,&temp1); } SetPort(RSlocal[w].window); InvalRect(&RSlocal[w].window->portRect); } } void RScheckmaxwind(Rect *origRect,short origW, short origH, short *endW, short *endH) { Rect *grayRect; *endW = origW; *endH = origH; grayRect = &((*TelInfo->greyRegion)->rgnBBox); if (origW > (grayRect->right - origRect->left)) *endW = grayRect->right - origRect->left; if (origH > (grayRect->bottom - origRect->top -15 )) *endH = grayRect->bottom - origRect->top; } \ No newline at end of file +// BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // #pragma profile on /* * * Virtual Screen Kernel Macintosh Real Screen Interface * (rsmac.c) * * National Center for Supercomputing Applications * by Gaige B. Paulsen * * This file contains the macintosh real screen calls for the NCSA * Virtual Screen Kernel. * * RSbell(w) - Ring window w's bell * RScursoff(w) - Turn the cursor off in w * RScurson(w,x,y) - Turn the cursor on in w at x,y * RSdraw(w,x,y,a,len,ptr) - Draw @x,y in w string@ptr for length len * RSdelchars(w,x,y,n) - Delete n chars in w from x,y * RSdellines(w,t,b,n) - Delete n lines in region t->b in w * RSerase(w,x1,y1,x2,y2) - Erase from x1,y1 to x2,y2 in w * RSinitall() - Initialize the world if necessary * RSinslines(w,t,b,n) - Insert n lines in region t->b in w * RSinsstring(w,x,y,a,len,ptr)- Insert len chars @x,y in w attrib a * RSsendstring(w,ptr,len) - Send string @ptr length len from window w * RSbufinfo( w, total,current)- Tells you the total/current lines in buffer * RSmargininfo( w, total, current) - Tells you total/current columns in VS * * * Macintosh only Routines: * NI RSregnconv( *) - Convert region to rect coords * NI RSsetwind(w) - Set the port and vars to window w * NI RSsetattr(a) - Set font/text style to a * NI RSsetConst(w) * ML RSattach(w,wind) - Attach the RS (w) to window wind * ML RSdetach(w) - Ready window for go-away * ML RSselect(w,pt,shift) - Handle selection RS (w) point (pt) and (shift) if held down * ML RSzoom(window,code,shifted) - Zoom Box handling * ML RSsize( window, where) - Resize handling * IN RSgetwindow(w) - Get the WindowPtr for RS (w) * IN RSfindvwind(wind) - Find the (RS/VS) # of wind * IN RSfindscroll( control, n) - Find which VS the control is in and which control it is * RSupdate(wind) - Handle updates on WIND, return 0 if not an RS * RSactivate(w) - Handle activate events * RSdeactivate(w) - Handle deactivate events * RSGetTextSel(w,table) - Returns handle to text selection of window w, table->tabs * RSnewwindow( wDims, sb, wid, lines * name,wrap,fnum,fsiz, * showit, goaway) - Returns VS # of newly created text window - * wDims (dimension),sb(scrollback),wid(width 80/132), * lines (# of lines, 24 <> 66), * name(window), wrap(0/1),fnum,fsiz, showit(vis),goaway(0,1) * RSkillwindow( w) - Destroys, deallocates, kills window (w) * RSclick(window, eventRecord)- Handle clicks in window (returns false if not RS window) * RShide(w) - Hide RS (w) * RSshow(w) - Show RS (w) * RScprompt(w, FilterProc) - Prompt for colors...FilterProc is for Modal Dialog * RSsetcolor(w,n,r,g,b) - Set one of the 4 colors of RS (w) to R,G,B * RSgetcolor(w,n,r,g,b) - Get one of the 4 colors of RS (w) into R,G,B * RSmouseintext(w,myPoint) - Returns true if Mouse is in text part of current RS window * RSskip(w,on) - Activate/deactivate drawing in an RS * * IN - Informational * ML - Mid Level * NI - Necessary Internal * - Suggested calls * * Version Date Notes * ------- ------ --------------------------------------------------- * 0.01 861102 Initial coding -GBP * 0.25 861106 Added code from screen.c -GBP * 0.50 861113 First compiled edition -GBP * 2.1 871130 NCSA Telnet 2.1 -GBP * 2.2 880715 NCSA Telnet 2.2 -GBP * 2.6 7/92 put globals into struct, cursors into array, and cleaned up * some of the font typedefs Scott Bulmahn * 2.6b4 12/92 Cleaned up the code, and added double clicking -- Scott Bulmahn * */ #define __ALLNU__ #include "DlogUtils.proto.h" #include "configure.proto.h" // For colorboxmodalproc and colorboxproc #include "maclook.proto.h" #include "network.proto.h" #include "menuseg.proto.h" #include "vskeys.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "vsintern.proto.h" #include "wind.h" #include "rsdefs.h" #include "parse.proto.h" // For SendNAWSinfo proto #include "wdefpatch.proto.h" /* 931112, ragge, NADA, KTH */ #include "drag.proto.h" #include "rsinterf.proto.h" #include "event.proto.h" //notify user proto #define NFDEF {0,0,0} #define NBDEF {65535,65535,65535} #define BFDEF {0,61183,11060} #define BBDEF {61183,2079,4938} #define UFDEF {1,0,0} #define UBDEF {0,0,0} extern short gBlink; extern WindRec *screens; #include "rsmac.proto.h" short MaxRS; RSdata *RSlocal, *RScurrent; Rect noConst, RScur; /* cursor rectangle */ RgnHandle RSuRgn; /* update region */ short RSw=-1, /* last window used */ RSa=0; /* last attrib used */ extern long RScolors[]; // initializes handling of terminal windows void RSinitall(short max) //max windows to allow { short i; MaxRS = max; RSlocal = (RSdata *) myNewPtr(MaxRS * sizeof(RSdata)); for (i = 0; i < MaxRS; RSlocal[i++].window = 0L) { RScurrent = RSlocal + i; RScurrent->id = 'RSDA'; RScurrent->cursor.top = 0; RScurrent->cursor.bottom = 0; RScurrent->cursor.left = 0; RScurrent->cursor.right = 0; } RSuRgn = NewRgn(); RScur.left = 0; RScur.top = 0; RScur.bottom = 0; RScur.right = 0; if (!TelInfo->haveColorQuickDraw) DisposeHandle((Handle)TelInfo->AnsiColors); } // RSinitall void RSsetConst ( short w ) /* sets "noConst" global to a zero-based rectangle equal in size to the specified terminal window. */ { noConst.left = 0; noConst.top = 0; noConst.right = RSlocal[w].width; noConst.bottom = RSlocal[w].height; } /* RSsetConst */ /****************************************************************************/ /* Given a window record number, do a SetPort() to the window associated with * that window record. */ short RSsetwind ( short w ) { if ((w < 0) || (w > MaxRS)) return(-3); if (RSw != w) /* if last window used is different */ { if (RSlocal[w].window == 0L) return(-4); RScurrent = RSlocal + w; RSw = w; RSa = -1; /* attributes will need setting */ SetPort(RScurrent->window); return(1); } SetPort(RScurrent->window); return(0); } /* RSsetwind */ void RSvalidateRect(short w) { ValidRect(&((RSlocal[w].window)->portRect)); } void RSbell ( short w ) /* gives an audible signal associated with the specified window. */ { RSsetwind(w); if (FrontWindow() != RScurrent->window) { /* beep and temporarily invert the window contents, so the user sees which window is beeping */ InvertRect(&RScurrent->window->portRect); SysBeep(8); InvertRect(&RScurrent->window->portRect); } else /* window is frontmost--just beep */ SysBeep(8); NotifyUser(); } /* RSbell */ void RScursoff ( short w ) /* hides the text cursor for the specified window. Assumes it is currently being shown. */ { if (RSlocal[w].skip || !RSlocal[w].cursorstate) /* BYU 2.4.11 */ return; RSsetwind(w); RScurrent->cursorstate = 0; /* BYU 2.4.11 */ InvertRect(&RScurrent->cursor); } /* RScursoff */ void RScurson ( short w, short x, short y ) /* displays the text cursor for the specified window, at the specified position. Assumes it isn't currently being shown. */ { if (RSlocal[w].skip || RSlocal[w].cursorstate) /* BYU 2.4.11 */ return; RSsetwind(w); RScurrent->cursor.left = x * RScurrent->fwidth; /* BYU 2.4.11 */ RScurrent->cursor.top = y * RScurrent->fheight; /* BYU 2.4.11 */ switch (gApplicationPrefs->CursorType) { /* BYU 2.4.11 */ case UNDERSCORECURSOR: /* BYU 2.4.11 */ RScurrent->cursor.top += RScurrent->fheight; /* BYU 2.4.11 */ RScurrent->cursor.right = RScurrent->cursor.left + RScurrent->fwidth; /* BYU 2.4.11 */ RScurrent->cursor.bottom = RScurrent->cursor.top + 1; /* BYU 2.4.11 */ break; case VERTICALCURSOR: /* BYU 2.4.11 */ RScurrent->cursor.left += 2; /* BYU 2.4.11 */ RScurrent->cursor.right = RScurrent->cursor.left + 1; /* BYU 2.4.11 */ RScurrent->cursor.bottom = RScurrent->cursor.top + RScurrent->fheight; /* BYU 2.4.11 */ break; case BLOCKCURSOR: /* BYU 2.4.11 */ default: /* BYU 2.4.11 */ RScurrent->cursor.right = RScurrent->cursor.left + RScurrent->fwidth; /* BYU 2.4.11 */ RScurrent->cursor.bottom = RScurrent->cursor.top + RScurrent->fheight; /* BYU 2.4.11 */ break; } if (!gApplicationPrefs->BlinkCursor) { /* BYU 2.4.11 */ RScurrent->cursorstate = 1; /* BYU 2.4.11 */ InvertRect(&RScurrent->cursor); /* BYU 2.4.11 */ } /* BYU 2.4.11 */ } /* RScurson */ void RSsetattr(short a) { short fg, bg, tempFontID; // RAB BetterTelnet 1.0fc4 static GrafPtr lastPort; if (RSa!=-1 && RSa==a && qd.thePort==lastPort) return; lastPort = qd.thePort; RSa = a; if (VSisgrph(a)) { GetFNum("\p%NCSA VT", &tempFontID); // RAB BetterTelnet 1.0fc4 TextFont(tempFontID); /* use "NCSA VT" (74) font for special graphics */ } else RSTextFont(RScurrent->fnum,RScurrent->fsiz,((a & bold) && RScurrent->allowBold)); /* BYU - use user-selected text font */ TextSize(RScurrent->fsiz); /* BYU - bold system fonts don't work (they overwrite the scroll bars), but NCSA's 9 point Monaco bold works okay. */ if (VSisbold(a) && RScurrent->realbold) TextFace(((a & outline) >> 1) + 1); else TextFace((a & outline) >> 1); /* BYU - do outline as underline setting */ if (VSisansifg(a)) { fg = 4 +((a>>8)&0x7); if (RScurrent->colorBold && VSisbold(a)) fg += 8; } else if (RScurrent->colorBold && VSisbold(a)) fg = gApplicationPrefs->defaultBoldColor + 4; else fg = 0; if (VSisansibg(a)) bg = 4+ ((a>>12)&0x7); else bg = 1; // set up text modes if (TelInfo->haveColorQuickDraw) { if (VSisrev(a) || ((a & bold) && RScurrent->bfstyle)) TextMode(notSrcCopy); else TextMode(srcCopy); } else { if (VSisrev(a) || ((a & bold) && RScurrent->bfstyle)) { BackPat(PATTERN(qd.black)); /* Reverses current attributes regard */ PenPat(PATTERN(qd.white)); /* less of the color, etc.... */ } else { BackPat(PATTERN(qd.white)); /* Reverses current attributes regard */ PenPat(PATTERN(qd.black)); /* less of the color, etc.... */ } } //set up colors if (TelInfo->haveColorQuickDraw) { if (VSisblnk(a) && (!gBlink || !VSIgetblinkflag())) { PmForeColor(2); //use colors for blink PmBackColor(3); } else { PmForeColor(fg); PmBackColor(bg); } } else { if (VSisblnk(a)) { ForeColor(RScolors[7]); //use colors for blink BackColor(RScolors[0]); } else { ForeColor(RScolors[0]); BackColor(RScolors[7]); } } } /* RSsetattr */ void RSTextFont(short myfnum, short myfsiz, short myface) /* BYU */ { /* BYU */ short tempFontID; // RAB BetterTelnet 1.0fc4 // RAB BetterTelnet 1.0fc4: For one thing, we use font *names* now. Also, we use NCSA VT Bold // when the user wants, not when it's Monaco 9. if (// (myfnum == monaco) && /* BYU - If Monaco, size 9, and bold, then */ // (myfsiz == 9) && /* BYU */ (myface & bold)) { /* BYU */ // GetFNum("\p%NCSA VT Bold", &tempFontID); // TextFont(tempFontID); /* BYU - use NCSA's Monaco. (75) */ TextFont(RScurrent->bfnum); // RAB BetterTelnet 1.0fc9 } else { /* BYU */ TextFont(myfnum); /* BYU */ } /* BYU */ } /* BYU */ #ifdef NO_UNIVERSAL #define LMGetHiliteMode() (* (unsigned char *) 0x0938) #define LMSetHiliteMode(HiliteModeValue) ((* (unsigned char *) 0x0938) = (HiliteModeValue)) #endif void DoHiliteMode(void) /* BYU LSC */ /* enables use of highlighting in place of simple color inversion for next QuickDraw operation. */ { LMSetHiliteMode(LMGetHiliteMode() & 0x7F); // char *p = (char *) 0x938; /* pointer to HiliteMode low-memory global */ // *p = *p & 0x7f; /* clear the HiliteBit */ } /* HiliteMode */ void RSinvText ( short w, Point curr, Point last, RectPtr constrain /* don't highlight anything outside this rectangle */ ) /* highlights the text from curr to last inclusive. */ { Rect temp, temp2; Point lb, ub; RSsetwind(w); /* normalize coordinates with respect to visible area of virtual screen */ curr.v -= RScurrent->topline; curr.h -= RScurrent->leftmarg; last.v -= RScurrent->topline; last.h -= RScurrent->leftmarg; if (curr.v == last.v) { /* highlighted text all on one line */ if (curr.h < last.h) /* get bounds the right way round */ { ub = curr; lb = last; } else { ub = last; lb = curr; } /* if */ MYSETRECT /* set up rectangle bounding area to be highlighted */ ( temp, (ub.h + 1) * RScurrent->fwidth, ub.v * RScurrent->fheight, (lb.h + 1) * RScurrent->fwidth, (lb.v + 1) * RScurrent->fheight ); SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */ DoHiliteMode(); /* BYU LSC */ InvertRect(&temp2); } else { /* highlighting across more than one line */ if (curr.v < last.v) ub = curr; else ub = last; if (curr.v > last.v) lb = curr; else lb = last; MYSETRECT /* bounds of first (possibly partial) line to be highlighted */ ( temp, (ub.h + 1) * RScurrent->fwidth, ub.v * RScurrent->fheight, RScurrent->width, (ub.v + 1) * RScurrent->fheight ); SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */ DoHiliteMode(); /* BYU LSC */ InvertRect(&temp2); MYSETRECT /* bounds of last (possibly partial) line to be highlighted */ ( temp, 0, lb.v * RScurrent->fheight, (lb.h + 1) * RScurrent->fwidth, (lb.v + 1) * RScurrent->fheight ); SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */ DoHiliteMode(); /* BYU LSC */ InvertRect(&temp2); if (lb.v - ub.v > 1) /* highlight extends across more than two lines */ { /* highlight complete in-between lines */ SetRect ( &temp, 0, (ub.v + 1) * RScurrent->fheight, RScurrent->width, lb.v * RScurrent->fheight ); SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */ DoHiliteMode(); /* BYU LSC */ InvertRect(&temp2); } /* if */ } /* if */ } /* RSinvText */ void RSdraw ( short w, /* window number */ short x, /* starting column */ short y, /* line on which to draw */ short a, /* text attributes */ short len, /* length of text to draw */ char *ptr /* pointer to text */ ) /* draws a piece of text (assumed to fit on a single line) in a window, using the specified attributes. If any part of the text falls within the current selection, it will be highlighted. */ { Rect rect; short ys; if (RSlocal[w].skip) return; RSsetwind(w); // RSsetattr(0); JMB 2.6.1d4 ys = y * RScurrent->fheight; MYSETRECT /* set up rectangle bounding text being drawn */ ( rect, x * RScurrent->fwidth, ys, (x + len) * RScurrent->fwidth, ys + RScurrent->fheight ); RSsetattr(a); if (x <= 0) /* BYU 2.4.12 - Without this, 1 pixel column of reverse */ rect.left = -3; /* BYU 2.4.12 - video text does not clear at left margin */ if (rect.bottom == RScurrent->rheight) rect.bottom += 1; //CCP take care of updating problems while scrolling EraseRect(&rect); if (x <= 0) /* BYU 2.4.12 - Okay, just putting it back the way it was */ rect.left = 0; /* BYU 2.4.12 */ MoveTo(x * RScurrent->fwidth, ys + RScurrent->fascent); DrawText(ptr, 0, len); if (RScurrent->selected) RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect); ValidRect(&rect); } /* RSdraw */ void RSdelcols ( short w, short n /* number of columns to scroll */ ) /* scrolls the entire visible display of a virtual screen the specified number of columns to the left, blanking out the newly-revealed area. */ { Rect rect; if (RSlocal[w].skip) return; RSsetwind(w); MYSETRECT /* bounds of entire text area, for scrolling */ ( rect, 0, 0, RScurrent->width, RScurrent->height ); ScrollRect(&rect, -n * RScurrent->fwidth, 0, RSuRgn); InvalRgn(RSuRgn); ValidRect(&rect); /* any necessary redrawing in newly-revealed area will be done by caller */ MYSETRECT /* bounds of newly-revealed area */ ( rect, RScurrent->width - (n * RScurrent->fwidth), 0, RScurrent->width, RScurrent->height ); if (RScurrent->selected) /* highlight any newly-revealed part of the current selection */ RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect); } /* RSdelcols */ void RSdelchars ( short w, /* affected window */ short x, /* column to delete from */ short y, /* line on which to do deletion */ short n /* number of characters to delete */ ) /* deletes the specified number of characters from the specified position to the right, moving the remainder of the line to the left. */ { Rect rect; if (RSlocal[w].skip) return; RSsetwind(w); RSsetattr(0); /* avoid funny pen modes */ MYSETRECT /* bounds of area from starting column to end of line */ ( rect, x * RScurrent->fwidth, y * RScurrent->fheight, RScurrent->width, (y + 1) * RScurrent->fheight ); if ((x + n) * RScurrent->fwidth > RScurrent->width) /* deleting to end of line */ EraseRect(&rect); else { /* scroll remainder of line to the left */ ScrollRect(&rect, - RScurrent->fwidth * n, 0, RSuRgn); InvalRgn(RSuRgn); ValidRect(&rect); /* leave newly-revealed area blank */ if (RScurrent->selected) { /* highlight any part of selection which lies in newly-blanked area */ HLock((Handle) RSuRgn); RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &((*RSuRgn)->rgnBBox)); HUnlock((Handle) RSuRgn); } /* if */ } /* if */ } /* RSdelchars */ void RSdellines ( short w, /* affected window */ short t, /* top line of affected region */ short b, /* bottom line of affected region */ short n, /* number of lines to delete */ short scrolled /* -ve => cancel current selection, if any; +ve => selection has moved up one line; 0 => don't touch selection */ ) /* deletes lines at the top of the specified region of a window, inserting new blank lines at the bottom, and scrolling up the stuff in between. */ { Rect rect; short RSfheightTimesn, RSfheightTimesbplus1; if (RSlocal[w].skip) return; RSsetwind(w); RSsetConst(w); RSsetattr(0); /* avoid funny pen modes */ if (scrolled) { if (RScurrent->selected && scrolled < 0) { /* unhighlight and cancel current selection */ RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &noConst); RScurrent->selected = 0; } else { RScurrent->last.v -= 1; /* Subtract one from each of the */ RScurrent->anchor.v -= 1; /* vertical Selection components */ } /* if */ } /* if */ rect.left = -1; /* BYU 2.4.12 - necessary */ rect.right = RScurrent->width; rect.top = t * RScurrent->fheight; RSfheightTimesbplus1 = (b + 1) * RScurrent->fheight; rect.bottom = RSfheightTimesbplus1; /* adjust the update region to track the scrolled window contents */ RSfheightTimesn = RScurrent->fheight * n; OffsetRgn(((WindowPeek) RScurrent->window)->updateRgn, 0, -RSfheightTimesn); ScrollRect(&rect, 0, -RSfheightTimesn, RSuRgn); RSsetattr(VSIw->attrib); /* restore mode for text drawing */ InvalRgn(RSuRgn); /* validate the area containing the newly-inserted blank lines. */ /* any necessary redrawing in newly-revealed area will be done by caller */ MYSETRECT ( rect, 0, (b - n + 1) * RScurrent->fheight - 1, RScurrent->width, RSfheightTimesbplus1 + 1 ); ValidRect(&rect); } /* RSdellines */ void RSerase ( short w, /* affected window */ short x1, /* left column */ short y1, /* top line */ short x2, /* right column */ short y2 /* bottom line */ ) /* erases a rectangular portion of the screen display, preserving the selection highlight. */ { Rect rect; if (RSlocal[w].skip) return; RSsetwind(w); RSsetattr(0); /* avoid funny pen modes */ SetRect ( &rect, x1 * RScurrent->fwidth , y1 * RScurrent->fheight, (x2 + 1) * RScurrent->fwidth - 1, (y2 + 1) * RScurrent->fheight + 1 ); if (rect.left <= 0) /* little buffer strip on left */ rect.left = CHO; if (rect.right >= RScurrent->width - 1) rect.right = RScurrent->rwidth - 2; /* clear to edge of window, including edge strip */ if (rect.bottom >= RScurrent->height - 2) rect.bottom = RScurrent->rheight + 1; /* clear to bottom edge also */ EraseRect(&rect); if (RScurrent->selected) /* highlight any part of the selection within the cleared area */ RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect); } /* RSerase */ void RSinslines ( short w, /* affected window */ short t, /* where to insert blank lines */ short b, /* bottom of area to scroll */ short n, /* number of lines to insert */ short scrolled /* -ve <=> cancel current selection, if any */ ) /* inserts blank lines at the top of the given area of the display, scrolling the rest of it down. */ { Rect rect; if (RSlocal[w].skip) return; RSsetwind(w); RSsetConst(w); RSsetattr(0); /* avoid funny pen modes */ if (RScurrent->selected && (scrolled < 0)) { /* unhighlight and cancel selection */ RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &noConst); RScurrent->selected = 0; } /* if */ rect.left = -1; /* BYU 2.4.12 - necessary */ rect.right = RScurrent->width; rect.top = t * RScurrent->fheight; rect.bottom = (b + 1) * RScurrent->fheight; /* adjust the update region to track the scrolled window contents */ OffsetRgn(((WindowPeek) RScurrent->window)->updateRgn, 0, RScurrent->fheight * n); ScrollRect(&rect, 0, RScurrent->fheight * n, RSuRgn); InvalRgn(RSuRgn); /* newly-inserted area is already blank -- validate it to avoid redrawing. */ /* any necessary redrawing will be done by caller */ SetRect(&rect, 0, t * RScurrent->fheight - 1, RScurrent->width, (t + n) * RScurrent->fheight + 1); ValidRect(&rect); } /* RSinslines */ void RSinscols ( short w, short n /* number of columns to insert */ ) /* inserts blank columns at the left side of the text display in the specified window, scrolling its current contents to the right. Maintains the selection highlight, but doesn't move the selection. Doesn't even unhighlight text which moves out of the selection area. */ { Rect rect; if (RSlocal[w].skip) return; RSsetwind(w); SetRect /* bounds of entire text area */ ( &rect, 0, 0, RScurrent->width, RScurrent->height ); ScrollRect(&rect, n * RScurrent->fwidth, 0, RSuRgn); InvalRgn(RSuRgn); ValidRect(&rect); /* any necessary redrawing in newly-revealed area will be done by caller */ SetRect /* bounds of newly-inserted blank area */ ( &rect, 0, 0, (n + 1) * RScurrent->fwidth - 1, RScurrent->height ); if (RScurrent->selected) /* highlight any part of the selection in the newly-blanked area */ RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect); } /* RSinscols */ void RSinsstring ( short w, /* affected window */ short x, /* starting column at which to insert */ short y, /* line on which to insert */ short a, /* attributes for inserted text */ short len, /* length of inserted text */ char *ptr /* pointer to inserted text */ ) /* inserts a string of characters at the specified position, scrolling the rest of the line to the right. Highlights any part of the newly- inserted text lying within the current selection. */ { Rect rect; if (RSlocal[w].skip) return; RSsetwind(w); SetRect /* bounds of part of line from specified position to end of line */ ( &rect, x * RScurrent->fwidth, y * RScurrent->fheight, RScurrent->width, (y + 1) * RScurrent->fheight ); ScrollRect(&rect, len * RScurrent->fwidth, 0, RSuRgn); /* scroll remainder of line to the right */ if (RSa != a) RSsetattr(a); InvalRgn(RSuRgn); ValidRect(&rect); /* any necessary redrawing in newly-revealed area will be done by caller */ SetRect /* bounds area to contain inserted string */ ( &rect, x * RScurrent->fwidth, y * RScurrent->fheight, (x + len) * RScurrent->fwidth, (y + 1) * RScurrent->fheight ); EraseRect(&rect); /* erase area to appropriate background */ MoveTo ( x * RScurrent->fwidth, y * RScurrent->fheight + RScurrent->fascent ); DrawText(ptr, 0, len); if (RScurrent->selected) /* highlight any part of selection covering the newly-inserted text */ RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect); } /* RSinsstring */ void RSmargininfo ( short w, short total, /* number of invisible character positions (screen width less visible width) */ short current /* leftmost visible character position */ ) /* updates the horizontal scroll bar and associated variables to reflect the current view of the virtual screen within the specified window. */ { RSlocal[w].leftmarg = current; /* Adjust local vars */ if (RSlocal[w].lcurrent != current) SetControlValue(RSlocal[w].left, (RSlocal[w].lcurrent = current)); if (RSlocal[w].lmax != total) SetControlMaximum(RSlocal[w].left, (RSlocal[w].lmax = total)); } /* RSmargininfo */ void RSbufinfo ( short w, /* affected window */ short total, /* number of lines of scrollback */ short current, /* current topmost visible line */ short bottom /* current bottommost visible line */ ) /* readjusts the vertical scroll bar and associated variables to reflect the current view of the virtual screen within the specified window. */ { RSdata *RSthis; short newmax; RSthis = RSlocal + w; newmax = (VSgetlines(w) - 1) - (bottom - current); RSthis->topline = current; /* Adjust local vars */ if (RSthis->min != -total) { if (RSthis->min == 0) //need to activate scrollbars SetControlMinimum(RSthis->scroll, (RSthis->min = -total)); (**RSthis->scroll).contrlMin = (RSthis->min = -total); // JMB 2.6.1d4 } /* if */ if (RSthis->current != current) SetControlValue(RSthis->scroll, (RSthis->current = current)); if (RSthis->max != newmax) (**RSthis->scroll).contrlMax = (RSthis->max = newmax); // JMB 2.6.1d4 } /* RSbufinfo */ short RSfindscroll /* Find screen index by control*/ ( ControlHandle control, short *n ) /* finds the window to which the given scroll bar belongs. Returns the window number in *n if found, and a function result of 1 for a vertical scroll bar, 2 for a horizontal one, or -1 if the window wasn't found. */ { /* look for a vertical scroll bar */ *n = 0; while ((*n < MaxRS) && (control != RSlocal[*n].scroll)) (*n)++; if (*n < MaxRS) return (1); /* found it */ /* look for a horizontal scroll bar */ *n = 0; while ((*n < MaxRS) && (control != RSlocal[*n].left)) (*n)++; if (*n < MaxRS) return (2); /* found it */ return(-1); /* not found */ } /* RSfindscroll */ void RSregnconv ( RgnHandle regn, short *x1, /* left (output) */ short *y1, /* top (output) */ short *x2, /* right (output) */ short *y2, /* bottom (output) */ short fh, /* font character height */ short fw /* font character width */ ) /* converts the bounding box of the specified QuickDraw region into units of character positions (using the specified character height and width) and returns the results in *x1, *y1, *x2 and *y2. */ { HLock((Handle) regn); *y1 = ((*regn)->rgnBBox.top) / fh; *y2 = (((*regn)->rgnBBox.bottom) + fh - 1) / fh; *x1 = ((*regn)->rgnBBox.left) / fw; *x2 = (((*regn)->rgnBBox.right) + fw - 1) / fw; HUnlock((Handle) regn); if (*x1 < 0) *x1 = 0; if (*y1 < 0) *y1 = 0; if (*x2 < 0) *x2 = 0; if (*y2 < 0) *y2 = 0; } /* RSregnconv */ #define Fwidthhalf FWidth/2 Point normalize(Point in, short w, Boolean autoScroll) /* converts in from a pixel position in local coordinates to a character cell position within the virtual screen corresponding to the specified window. Constrains the position to lie within the currently-visible region of the screen, autoscrolling the screen if necessary (and if autoScroll = TRUE). */ { if (in.v <0) { in.v = 0; if (autoScroll) VSscrolback(w, 1); } /* if */ if (in.v > RSlocal[w].height) { in.v = RSlocal[w].height; if (autoScroll) VSscrolforward(w, 1); } /* if */ in.v = in.v / FHeight; if (in.h < 0) { in.h = -1; if (autoScroll) VSscrolleft(w, 1); } /* if */ if (in.h > RSlocal[w].width) { in.h = RSlocal[w].width; if (autoScroll) VSscrolright(w, 1); } /* if */ /* in.h = (in.h + Fwidthhalf) / FWidth - 1; */ /* the MPW C 3.0 compiler has a bug in its register allocation */ /* which keeps the above line from working. So, replace it with this: */ in.h = in.h + Fwidthhalf; in.h = in.h / FWidth - 1; /* note the bug has been fixed in the 3.1 compiler. */ /* convert to virtual screen coordinates */ in.v += RSlocal[w].topline; in.h += RSlocal[w].leftmarg; return(in); } /* normalize */ void RSsortAnchors(short w) { Point temp; if (RSlocal[w].anchor.v > RSlocal[w].last.v) { temp = RSlocal[w].anchor; RSlocal[w].anchor = RSlocal[w].last; RSlocal[w].last = temp; } if ((RSlocal[w].anchor.v == RSlocal[w].last.v) && (RSlocal[w].anchor.h > RSlocal[w].last.h)) { temp = RSlocal[w].anchor; RSlocal[w].anchor = RSlocal[w].last; RSlocal[w].last = temp; } } void RSsetsize( short w, short v, short h) /* saves the new size settings for a window, and repositions the scroll bars accordingly. */ { RSlocal[w].height = ((v - 16 + CVO) / FHeight) * FHeight; RSlocal[w].width = ((h - 16 + CHO) / FWidth) * FWidth; RSlocal[w].rheight = v - 16; RSlocal[w].rwidth = h - 16; /* * Get rid of the scroll bars which were in the old size. * Hiding them causes the region to be updated later. */ if (RSlocal[w].scroll != NULL ) HideControl(RSlocal[w].scroll); if (RSlocal[w].left != NULL ) HideControl(RSlocal[w].left); DrawGrowIcon(RSlocal[w].window); /* Draw in the necessary bugger */ /* move the scroll bars to their new positions and sizes, and redisplay them */ SetControlValue(RSlocal[w].scroll, RSlocal[w].current); //because we dont always have this if (RSlocal[w].scroll != NULL ) { SizeControl(RSlocal[w].scroll, 16, (v - 13)); MoveControl(RSlocal[w].scroll, (h - 15) + CHO, -1 + CVO); ShowControl(RSlocal[w].scroll); } if (RSlocal[w].left != NULL ) { SizeControl(RSlocal[w].left, (h - 13), 16); MoveControl(RSlocal[w].left, -1 + CHO, (v - 15) + CVO); ShowControl(RSlocal[w].left); } SetRect(&RSlocal[w].textrect, 0, 0, RSlocal[w].rwidth, RSlocal[w].rheight); } /* RSsetsize */ /*--------------------------------------------------------------------------*/ /* NCSA: SB - RSbackground */ /* This procedure allows Telnet to switch from dark background to light */ /* background. Save the current state into the RSdata struct, so that */ /* we know our background state next time we want to do anything. */ /* Make sure the screen contents (and palette) is updated NOW. */ /*--------------------------------------------------------------------------*/ void RSbackground(short w, short value) { RGBColor temp1,temp2; RSsetwind(w); if ((value && !RSlocal[w].flipped) || (!value && RSlocal[w].flipped)) { RSlocal[w].flipped = !RSlocal[w].flipped; if (TelInfo->haveColorQuickDraw) //flip the background and foreground color positions { GetEntryColor(RSlocal[w].pal,0,&temp1); GetEntryColor(RSlocal[w].pal,1,&temp2); SetEntryColor(RSlocal[w].pal,0,&temp2); SetEntryColor(RSlocal[w].pal,1,&temp1); } SetPort(RSlocal[w].window); InvalRect(&RSlocal[w].window->portRect); } } void RScheckmaxwind(Rect *origRect,short origW, short origH, short *endW, short *endH) { Rect *grayRect; *endW = origW; *endH = origH; grayRect = &((*TelInfo->greyRegion)->rgnBBox); if (origW > (grayRect->right - origRect->left)) *endW = grayRect->right - origRect->left; if (origH > (grayRect->bottom - origRect->top -15 )) *endH = grayRect->bottom - origRect->top; } \ No newline at end of file diff --git a/source/Screens/vsdata.h b/source/Screens/vsdata.h index 3c57d11..6ff28ae 100755 --- a/source/Screens/vsdata.h +++ b/source/Screens/vsdata.h @@ -1 +1 @@ -/* * Virtual Screen Kernel Data/Structure Definitions * (vsdata.h) * * National Center for Supercomputing Applications * by Gaige B. Paulsen * * This file contains the control and interface calls for the NCSA * Virtual Screen Kernel. * * Version Date Notes * ------- ------ --------------------------------------------------- * 0.01 861102 Initial coding -GBP * 2.1 871130 NCSA Telnet 2.1 -GBP * 2.2 880715 NCSA Telnet 2.2 -GBP * */ #ifndef __VSDATA__ #define __VSDATA__ #define MAXWID 132 /* The absolute maximum number of chars/line */ typedef struct VSline { struct VSline /* doubly-linked list of lines */ *next, /* Pointer to next line */ *prev; /* Pointer to previous line */ char // Text for the line -- may be part of a block *text; /* of memory containing more than one line */ unsigned short *attr; /* 16 bit attribute; 8 for normal, 8 for ansi color */ short /* flag for memory allocation coordination */ mem; /* nonzero for first line in memory block */ } VSline,*VSlinePtr,**VSlineArray; // RAB BetterTelnet 1.2.1 - added this again for the old scrollback code typedef struct VSattrline //CCP 2.7 ANSI needs shorts { struct VSattrline /* doubly-linked list of lines */ *next, /* Pointer to next line */ *prev; /* Pointer to previous line */ unsigned short // macblue, now use 16 bit attribute; 8 for normal, 8 for ansi color *text; /* of memory containing more than one line */ char *dummy; // keep the pointer lists the same length - RAB BetterTelnet 1.2.1 short /* flag for memory allocation coordination */ mem; /* nonzero for first line in memory block */ } VSattrline, *VSattrlinePtr, **VSattrlineArray; #define maxparms 16 struct VSscrn { OSType id; // VSCR VSlinePtr scrntop, /* topmost line of the current screen (= linest[0]) */ buftop, /* top (i e oldest line) of scrollback buffer */ vistop; /* topmost line within visible region (may be in screen or scrollback area) */ VSlineArray linest; /* pointer to array of screen text lines */ VSattrlineArray attrst; // RAB BetterTelnet 1.2.1 - added this again, too short lines, /* How many lines are in the screen arrays */ maxlines, /* maximum number of lines to save off top */ numlines, /* number of lines currently saved off top */ allwidth, /* allocated width of screen lines */ maxwidth, /* current screen width setting (<= allwidth) */ savelines, /* save lines off top? 0=no */ forcesave, /* NCSA 2.5: always force lines to be saved off top */ possibleForce, //we have receive a "move to 0,0"; if next is EEOl, forcesave ESscroll, /* Scroll screen when ES received */ attrib, /* current character writing attributes */ x,y, /* current cursor positon */ Px,Py,Pattrib, /* saved cursor position and writing attributes */ DECAWM, /* Auto Wrap Mode 0=off */ DECCKM, /* Cursor Key Mode */ DECPAM, /* keyPad Application Mode */ DECORG, /* origin mode */ DECCM, /* Bri 970610: cursor mode (1=visible, 0=invisible) */ G0,G1, /* Character set identifiers */ charset, /* Character set mode */ IRM, /* Insert/Replace Mode */ escflg, /* Current Escape level */ top, bottom, /* Vertical bounds of scrolling region */ Rtop,Rbottom, /* Vertical bounds of visible region */ Rleft,Rright, /* Horizontal bounds of visible region */ parmptr, /* LU - index of current parm */ prredirect, /* LU - printer redirection or not */ qprint, // RAB BetterTelnet 1.0fc3: queue print requests printqueued, // RAB BetterTelnet 1.0fc3: print queue in progress ignoreBeeps, // RAB BetterTelnet 1.0fc7: ignore beeps oldScrollback; // RAB BetterTelnet 1.2.1 - use old scrollback code // (no attribute saving) long prbuf; /* LU - last four chars */ char prbuf2; // RAB BetterTelnet 1.2: and another char short refNum; /* LU - temporary file for printer redirection */ char fname[40]; /* LU - file name for temporary file */ short parms[maxparms]; /* Ansi Parameters */ char *tabs; /* pointer to array for tab settings */ /* contains 'x' at each tab position, blanks elsewhere */ }; typedef struct VSscrn VSscrn; struct VSscrndata { VSscrn *loc; /* Location of the Screen record for this scrn */ short captureRN, /* capture file's RefNum */ /* BYU 2.4.18 */ stat; /* status of this screen (0=Uninitialized, */ /* BYU 2.4.18 */ /* 1=In Use */ /* BYU 2.4.18 */ /* 2=Initialized, but not IU */ /* BYU 2.4.18 */ }; typedef struct VSscrndata VSscrndata; #ifdef VSMASTER VSscrn *VSIw; short VSIwn; #else extern VSscrn *VSIw; extern short VSIwn; #endif #define VSPBOTTOM (VSIw->lines) #endif // __VSDATA__ \ No newline at end of file +/* * Virtual Screen Kernel Data/Structure Definitions * (vsdata.h) * * National Center for Supercomputing Applications * by Gaige B. Paulsen * * This file contains the control and interface calls for the NCSA * Virtual Screen Kernel. * * Version Date Notes * ------- ------ --------------------------------------------------- * 0.01 861102 Initial coding -GBP * 2.1 871130 NCSA Telnet 2.1 -GBP * 2.2 880715 NCSA Telnet 2.2 -GBP * */ #ifndef __VSDATA__ #define __VSDATA__ #define MAXWID 132 /* The absolute maximum number of chars/line */ typedef struct VSline { struct VSline /* doubly-linked list of lines */ *next, /* Pointer to next line */ *prev; /* Pointer to previous line */ char // Text for the line -- may be part of a block *text; /* of memory containing more than one line */ unsigned short *attr; /* 16 bit attribute; 8 for normal, 8 for ansi color */ short /* flag for memory allocation coordination */ mem; /* nonzero for first line in memory block */ } VSline,*VSlinePtr,**VSlineArray; // RAB BetterTelnet 1.2.1 - added this again for the old scrollback code typedef struct VSattrline //CCP 2.7 ANSI needs shorts { struct VSattrline /* doubly-linked list of lines */ *next, /* Pointer to next line */ *prev; /* Pointer to previous line */ unsigned short // macblue, now use 16 bit attribute; 8 for normal, 8 for ansi color *text; /* of memory containing more than one line */ char *dummy; // keep the pointer lists the same length - RAB BetterTelnet 1.2.1 short /* flag for memory allocation coordination */ mem; /* nonzero for first line in memory block */ } VSattrline, *VSattrlinePtr, **VSattrlineArray; #define maxparms 16 #define DEBUG_CAPTURE struct VSscrn { OSType id; // VSCR VSlinePtr scrntop, /* topmost line of the current screen (= linest[0]) */ buftop, /* top (i e oldest line) of scrollback buffer */ vistop; /* topmost line within visible region (may be in screen or scrollback area) */ VSlineArray linest; /* pointer to array of screen text lines */ VSattrlineArray attrst; // RAB BetterTelnet 1.2.1 - added this again, too short lines, /* How many lines are in the screen arrays */ maxlines, /* maximum number of lines to save off top */ numlines, /* number of lines currently saved off top */ allwidth, /* allocated width of screen lines */ maxwidth, /* current screen width setting (<= allwidth) */ savelines, /* save lines off top? 0=no */ forcesave, /* NCSA 2.5: always force lines to be saved off top */ possibleForce, //we have receive a "move to 0,0"; if next is EEOl, forcesave ESscroll, /* Scroll screen when ES received */ attrib, /* current character writing attributes */ x,y, /* current cursor positon */ Px,Py,Pattrib, /* saved cursor position and writing attributes */ DECAWM, /* Auto Wrap Mode 0=off */ DECCKM, /* Cursor Key Mode */ DECPAM, /* keyPad Application Mode */ DECORG, /* origin mode */ DECCM, /* Bri 970610: cursor mode (1=visible, 0=invisible) */ G0,G1, /* Character set identifiers */ charset, /* Character set mode */ IRM, /* Insert/Replace Mode */ escflg, /* Current Escape level */ top, bottom, /* Vertical bounds of scrolling region */ Rtop,Rbottom, /* Vertical bounds of visible region */ Rleft,Rright, /* Horizontal bounds of visible region */ parmptr, /* LU - index of current parm */ prredirect, /* LU - printer redirection or not */ qprint, // RAB BetterTelnet 1.0fc3: queue print requests printqueued, // RAB BetterTelnet 1.0fc3: print queue in progress ignoreBeeps, // RAB BetterTelnet 1.0fc7: ignore beeps oldScrollback, // RAB BetterTelnet 1.2.1 - use old scrollback code // (no attribute saving) linesjumped, // RAB BetterTelnet 2.0b3 - number of jump scrolled lines jumpScroll, disableCursor, // RAB BetterTelnet 2.0b4 - cursor disabled to avoid screen glitch realBlink; // RAB BetterTelnet 2.0fc1 - real blinking text long prbuf; /* LU - last four chars */ char prbuf2; // RAB BetterTelnet 1.2: and another char short refNum; /* LU - temporary file for printer redirection */ char fname[40]; /* LU - file name for temporary file */ short parms[maxparms]; /* Ansi Parameters */ char *tabs; /* pointer to array for tab settings */ /* contains 'x' at each tab position, blanks elsewhere */ }; typedef struct VSscrn VSscrn; struct VSscrndata { VSscrn *loc; /* Location of the Screen record for this scrn */ short captureRN, /* capture file's RefNum */ /* BYU 2.4.18 */ stat; /* status of this screen (0=Uninitialized, */ /* BYU 2.4.18 */ /* 1=In Use */ /* BYU 2.4.18 */ /* 2=Initialized, but not IU */ /* BYU 2.4.18 */ }; typedef struct VSscrndata VSscrndata; #ifdef VSMASTER VSscrn *VSIw; short VSIwn; #else extern VSscrn *VSIw; extern short VSIwn; #endif #define VSPBOTTOM (VSIw->lines) #endif // __VSDATA__ \ No newline at end of file diff --git a/source/Screens/vsinterf.c b/source/Screens/vsinterf.c index 48a1cd4..07e9408 100755 --- a/source/Screens/vsinterf.c +++ b/source/Screens/vsinterf.c @@ -1 +1 @@ -/* * * Virtual Screen Kernel Interface * (vsinterf.c) * * by Gaige B. Paulsen * * This file contains the control and interface calls for the NCSA * Virtual Screen Kernal. * * VSinit(maxwidth) - Initialize the VSK * VSnewscreen(maxlines,scrnsave) - Initialize a new screen. * VSdetach(w) - Detach screen w * VSredraw(w,x1,y1,x2,y2) - redraw region for window w * VSwrite(w,ptr,len) - write text @ptr, length len * VSclear(w) - clear w's real screen * VSkbsend(w,k,echo) - send keycode k's rep. out window w (w/echo if req.) * VSclearall(w) - clear w's real and saved screen * VSreset(w) - reset w's emulator (as per TERM) * VSgetline(w,y) - get a ptr to w's line y * VSsetrgn(w,x1,y1,x2,y2) - set local display region * VSscrolback(w,n) - scrolls window w back n lines * VSscrolforward(w,n) - scrolls window w forward n lines * VSscrolleft(w,n) - scrolls window w left n columns * VSscrolright(w,n) - scrolls window w right n columns * VSscrolcontrol(w,scrlon,offtop) - sets scroll vars for w * VSgetrgn(w,&x1,&y1,&x2,&y2) - returns set region * VSsnapshot(w) - takes a snapshot of w * VSgetlines(w) - Returns current # of lines * VSsetlines(w, lines) - Sets the current # of lines to lines * * Version Date Notes * ------- ------ --------------------------------------------------- * 0.01 861102 Initial coding -GBP * 0.10 861113 Added some actual program to this file -GBP * 0.15 861114 Initiated Kludge Operation-GBP * 0.50 8611VSPBOTTOM Parameters added to VSnewscreen -GBP * 0.90 870203 Added the kbsend routine -GBP * 2.1 871130 NCSA Telnet 2.1 -GBP * 2.2 880715 NCSA Telnet 2.2 -GBP * */ #ifdef MPW #pragma segment VS #endif #define VSMASTER #include "rsinterf.proto.h" #include "rsmac.proto.h" #include "vsem.proto.h" #include "vsdata.h" #include "vskeys.h" #include "vsinit.h" #include "vsintern.proto.h" #include "Wind.h" #include "DlogUtils.proto.h" #include "maclook.proto.h" #include "errors.proto.h" #define DEBUGMAC #include "vsinterf.proto.h" extern TelInfoRec *TelInfo; extern WindRec *screens; extern long TempItemsDirID; extern short TempItemsVRefNum; short /* Internal variables for use in managing windows */ VSmax = 0, /* max nr screens allowed */ VSinuse = 0; /* nr screens actually in existence */ VSscrndata *VSscreens; short VSinit ( short max /* max nr screens to allow */ ) /* initializes virtual screen and window handling. */ { short i; RSinitall(max); VSmax = max; VSIwn = 0; if ((VSscreens = (VSscrndata *) myNewPtr(max * sizeof(VSscrndata))) == 0L) return(-2); for (i = 0; i < max; i++) { VSscreens[i].loc = 0L; VSscreens[i].stat = 0; } /* for */ return(0); } /* VSinit */ short VSiscapturing(short w) { /* BYU 2.4.18 */ return(VSscreens[w].captureRN); /* BYU 2.4.18 */ } /* BYU 2.4.18 */ Boolean VSopencapture(short scrn_num, short w) { UNUSED_ARG(scrn_num) static short captNumber = 1; short VRefNum; long DirID; Str255 filename, tempString; Str32 numstring; Point where = {100,100}; SFReply sfr; long junk = 0; OSErr err; NumToString(captNumber++, numstring); GetIndString(filename, MISC_STRINGS, CAPTFILENAME); filename[++(filename[0])] = ' '; pstrcat(filename, numstring); GetIndString(tempString,MISC_STRINGS,SAVE_CAPTURED_TEXT_STRING); SFPutFile(where,tempString, filename, NULL, &sfr); if (sfr.good) { (void) GetWDInfo(sfr.vRefNum, &VRefNum, &DirID, &junk); err = HCreate(VRefNum, DirID, sfr.fName, gApplicationPrefs->CaptureFileCreator, 'TEXT'); if (err == dupFNErr) { HDelete(VRefNum, DirID, sfr.fName); err = HCreate(VRefNum, DirID, sfr.fName, gApplicationPrefs->CaptureFileCreator, 'TEXT'); } if (err != noErr) OperationFailedAlert(CANT_CREATE_FILE, 500, err); else { err = HOpenDF(VRefNum, DirID, sfr.fName, fsRdWrPerm, &VSscreens[w].captureRN); if (err != noErr) OperationFailedAlert(CANT_OPEN_FILE, 501, err); else { SetEOF(VSscreens[w].captureRN, (long) 0); return(TRUE); } } } return(FALSE); } void VSclosecapture(short w) { /* BYU 2.4.18 */ FSClose(VSscreens[w].captureRN); /* BYU 2.4.18 */ VSscreens[w].captureRN = 0; /* BYU 2.4.18 */ } /* BYU 2.4.18 */ void VScapture(unsigned char *ptr, short len) { /* BYU 2.4.18 */ long ln = len; /* BYU 2.4.18 */ if (VSscreens[VSIwn].captureRN) { /* BYU 2.4.18 */ unsigned char captbuf[512]; /* BYU 2.4.18 */ unsigned char *ptr2,*ptr3; /* BYU 2.4.18 */ ptr2 = ptr; /* BYU 2.4.18 */ ptr3 = &captbuf[0]; /* BYU 2.4.18 */ for (len = 0; len < ln; len++) { /* BYU 2.4.18 */ if (*ptr2 >= 32 || /* BYU 2.4.18 */ *ptr2 == 13 || /* BYU 2.4.18 */ *ptr2 == 9) /* BYU 2.4.18 */ *(ptr3++) = *(ptr2++); /* BYU 2.4.18 */ else { /* BYU 2.4.18 */ ptr2++; /* BYU 2.4.18 */ ln--; /* BYU 2.4.18 */ } /* BYU 2.4.18 */ } /* BYU 2.4.18 */ if (ln > 0) { /* BYU 2.4.18 */ if (FSWrite(VSscreens[VSIwn].captureRN, &ln, captbuf)) { /* BYU 2.4.18 */ FSClose(VSscreens[VSIwn].captureRN); /* BYU 2.4.18 */ VSscreens[VSIwn].captureRN = 0; /* BYU 2.4.18 */ } /* BYU 2.4.18 */ } /* BYU 2.4.18 */ } /* BYU 2.4.18 */ } /* BYU 2.4.18 */ short VSisprinting(short w) { if ((VSscreens[w].loc)->qprint) // RAB BetterTelnet 1.0fc4 return ((VSscreens[w].loc)->printqueued); // RAB BetterTelnet 1.0fc4 return ((VSscreens[w].loc)->prredirect); } void ClosePrintingFile(short w) { OSErr sts; char tmp[80]; putln("Attempting to remove print file"); if ((sts=FSClose ((VSscreens[w].loc)->refNum)) != noErr) { SysBeep(1); sprintf(tmp,"FSClose: ERROR %d",sts); putln(tmp); } if ((sts=HDelete(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname)) != noErr) { SysBeep(1); sprintf(tmp,"HDelete: ERROR %d",sts); putln(tmp); } } short VSvalids ( short w ) /* validates a virtual screen number and sets it as the current screen for subsequent operations if success. Returns 0 iff success. */ { if (VSinuse == 0) return(-5); /* -5=no ports in use */ if (VSIwn == w) return(0); /* Currently set to that window */ if ((w > VSmax) || (w < 0)) return(-6); /* blown out the top of the stuff */ VSIwn = w; if (VSscreens[w].stat != 1) return(-3);/* not currently active */ VSIw = VSscreens[w].loc; if (VSIw == 0L) return(-3); /* no space allocated */ return(0); } /* VSvalids */ VSscrn *VSwhereis(short i) /* screen number */ /* returns a pointer to the structure for the specified screen. */ { VSvalids(i); return(VSIw); } /* VSwhereis */ void VSIclrbuf ( void ) /* clears out the text and attribute buffers for the current screen. All text characters are set to blanks, and all attribute bytes are set to zero. Doesn't update the display. */ { register short j, i; register char *tx; register unsigned short *ta; for (i = 0; i <= VSIw->lines; i++) { if (VSIw->oldScrollback) ta = &VSIw->attrst[i]->text[0]; else ta = &VSIw->linest[i]->attr[0]; tx = &VSIw->linest[i]->text[0]; for (j = 0; j <= VSIw->allwidth; j++) { *ta++ = 0; *tx++ = ' '; } /* for */ } /* for */ } /* VSIclrbuf */ short VSnewscreen ( short maxlines, /* max lines to save in scrollback buffer */ short screensave, /* whether to have a scrollback buffer */ short numLines, //numLines initially on screen (CCP 2.7) short maxwid, /* number of columns on screen */ short forcesave, /* NCSA 2.5: force lines to be saved */ short ignoreBeeps, short oldScrollback ) /* creates a new virtual screen, and returns its number. */ { if (maxlines < VSDEFLINES) maxlines = VSDEFLINES; if (VSinuse >= VSmax) /* too many screens in existence */ return(-1); VSIwn = 0; while ((VSIwn < VSmax) && (VSscreens[VSIwn].stat == 1)) VSIwn++; if (VSIwn >= VSmax) /* shouldn't occur? */ return(-1); numLines -= 1; //correct for internal use /* * Fill initial scrollback buffer and screen storage space. * * Memory allocation rules: * line->mem == 0 if not a memory allocation, line->mem == 1 if it is the first * VSline in a block (indeterminate size, may be size == 1) * * attributes array is ALWAYS allocated as one block. Internally represented and * manipulated as a linked list of lines, but only one of the lines will have * line->mem == 1. This list is always supposed to be circular (it is never * extended, as attributes are never scrolled back). * * scrollback and screen line buffer space is allocated in large blocks. Each * block will have line->mem == 1 if the pointer to that VSline is "free"able. * This list will either be circular (which means it has reached its full size), * or it will have a NULL next field at the end. During scrolling, the end may * be augmented until VSIw->numlines > VSIw->maxlines or we run out of memory. * Typically allocate memory 100 lines at a time in two blocks, one is the VSline * list, the other is the mem for the character storage. * */ /* All memory allocation for this function is done at once, to help damage control in low memory situations */ if ((VSscreens[VSIwn].loc = VSIw = (VSscrn *) myNewPtr(sizeof(VSscrn))) == 0L) return(-2); VSIw->oldScrollback = oldScrollback; VSIw->lines = numLines; //VSIw->lines = 23; CCP 2.7 set this from the start VSIw->linest = VSInewlinearray(VSIw->lines + 1); if (VSIw->linest == NULL) { DisposePtr((Ptr)VSIw); VSscreens[VSIwn].loc = VSIw = NULL; return (-2); } if (VSIw->oldScrollback) { VSIw->attrst = (VSattrlinePtr *) VSInewlinearray(VSIw->lines + 1); if (VSIw->attrst == NULL) { DisposePtr((Ptr)VSIw->linest); DisposePtr((Ptr)VSIw); VSscreens[VSIwn].loc = VSIw = NULL; return (-2); } } VSIw->tabs = (char *) myNewPtr(132); /* NCSA: SB - allow 132 column mode */ if (VSIw->tabs == NULL) /* CCP: Hey? Why not check if we got it?! */ { DisposePtr((Ptr)VSIw->linest); DisposePtr((Ptr)VSIw); VSscreens[VSIwn].loc = VSIw = NULL; return (-2); } VSIw->allwidth = 131; /* NCSA: SB - always allocate max lines */ if (!VSIw->oldScrollback) { if (screensave) VSIw->buftop = VSInewlines(VSIw->lines + 1 + VSDEFLINES); /* screen lines plus some initial preallocated scrollback space */ else VSIw->buftop = VSInewlines(VSIw->lines + 1); /* screen lines, no scrollback */ if (VSIw->buftop == NULL) { DisposePtr((Ptr)VSIw->tabs); DisposePtr((Ptr)VSIw->linest); DisposePtr((Ptr)VSIw); VSscreens[VSIwn].loc = VSIw = NULL; return(-2); } VSIw->linest[0] = VSIw->buftop; } else { if (screensave) VSIw->buftop = VSOnewlines(VSIw->lines + 1 + VSDEFLINES,1); /* screen lines plus some initial preallocated scrollback space */ else VSIw->buftop = VSOnewlines(VSIw->lines + 1,1); /* screen lines, no scrollback */ if (VSIw->buftop == NULL) { DisposePtr((Ptr)VSIw->tabs); DisposePtr((Ptr)VSIw->attrst); DisposePtr((Ptr)VSIw->linest); DisposePtr((Ptr)VSIw); VSscreens[VSIwn].loc = VSIw = NULL; return(-2); } VSIw->linest[0] = VSIw->buftop; VSIw->attrst[0] = (VSattrlinePtr)VSOnewlines(VSIw->lines + 1,2); /* new space for attributes (these are never scrolled back) */ if (VSIw->attrst[0] == NULL) { VSIfreelinelist(VSIw->buftop); DisposePtr((Ptr)VSIw->tabs); DisposePtr((Ptr)VSIw->attrst); DisposePtr((Ptr)VSIw->linest); DisposePtr((Ptr)VSIw); VSscreens[VSIwn].loc = VSIw = NULL; return(-2); } } VSIw->vistop = VSIw->scrntop = VSIw->buftop; /* initial view = screen */ if (VSIw->oldScrollback) { VSOlistndx(VSIw->scrntop, VSIw->attrst[0]); VSIw->attrst[0]->prev = VSIw->attrst[VSIw->lines]; /* make attribute list circular, since it is never extended */ VSIw->attrst[VSIw->lines]->next = VSIw->attrst[0]; } else VSIlistndx(VSIw->scrntop); /* Set up screen arrays */ if (!screensave) { /* make text line list circular to indicate no extensions */ VSIw->linest[0]->prev = VSIw->linest[VSIw->lines]; VSIw->linest[VSIw->lines]->next = VSIw->linest[0]; } /* if */ VSIw->maxlines = maxlines; VSIw->numlines = 0; VSscreens[VSIwn].captureRN = 0; /* BYU 2.4.18 - capture file's RefNum */ VSIw->id = 'VSCR'; VSIw->maxwidth = maxwid - 1; VSIw->savelines = screensave; VSIw->forcesave = forcesave; /* NCSA 2.5 */ VSIw->attrib = 0; VSIw->Pattrib = -1; /* initially no saved attribute */ VSIw->x = 0; VSIw->y = 0; VSIw->charset = 0; VSIw->G0 = 0; VSIw->G1 = 1; VSIw->DECAWM = 0; VSIw->DECCKM = 0; VSIw->DECPAM = 0; VSIw->DECORG = 0; VSIw->DECCM = 1; /* Bri 970610 */ VSIw->IRM = 0; VSIw->escflg = 0; VSIw->top = 0; VSIw->bottom = numLines; VSIw->parmptr = 0; VSIw->Rtop = 0; VSIw->Rleft = 0; VSIw->Rright = maxwid - 1; VSIw->Rbottom = numLines; VSIw->ESscroll = 1; VSIw->prredirect = 0; /* LU */ VSIw->qprint = 0; VSIw->ignoreBeeps = ignoreBeeps; VSIw->prbuf = 0; /* LU */ VSIw->refNum = -1; /* LU */ VSIw->possibleForce = 0; VSIclrbuf(); VSItabinit(); VSscreens[VSIwn].stat = 1; VSinuse++; return(VSIwn); } /* VSnewscreen */ short VSdestroy(short w) /* screen number */ /* gets rid of a virtual screen. */ { if (VSvalids(w) != 0) return(-3); VSIfreelines(); if (VSIw->oldScrollback) { VSIfreelinelist((VSlinePtr)VSIw->attrst[0]); if (VSIw->attrst) DisposPtr((Ptr) VSIw->attrst); } if(VSIw->linest) DisposPtr((Ptr) VSIw->linest); if(VSIw->tabs) DisposPtr(VSIw->tabs); if(VSIw) DisposPtr((Ptr) VSIw); VSscreens[w].stat = 0; VSIwn = -1; VSinuse--; /* SCA '87 */ return(0); } /* VSdestroy */ void VSredrawLine(short w) //redraws current line { if (VSvalids(w) != 0) return; VSredraw(w, 0, VSIw->y,VSIw->maxwidth, VSIw->y); VSIcuroff(w); } short VSredraw ( short w, // window to redraw */ short x1, short y1, short x2, short y2 ) /* redisplays the specified portion of a virtual screen. */ { VSlinePtr ypt; short y; short tx1, tx2, ty1, ty2, tn, offset; if (VSvalids(w) != 0) return(-3); if (VSIw->oldScrollback) return VSOredraw(w, x1, y1, x2, y2); x1 += VSIw->Rleft; // Make local coords global again x2 += VSIw->Rleft; y1 += VSIw->Rtop; y2 += VSIw->Rtop; if (x1 < 0) x1 = 0; else if (x1 > VSIw->maxwidth) x1 = VSIw->maxwidth; if (x2 < 0) x2 = 0; else if (x2 > VSIw->maxwidth) x2 = VSIw->maxwidth; if (y1 < -VSIw->numlines) y1 = -VSIw->numlines; else if (y1 > VSIw->lines) y1 = VSIw->lines; if (y2 < -VSIw->numlines) y2 = -VSIw->numlines; /* limit to amount of scrollback */ else if (y2 > VSIw->lines) y2 = VSIw->lines; tx1 = x1; // Set up to clip redraw area to visible area tx2 = x2; ty1 = y1; ty2 = y2; tn = -1; // so we include more than 1 line if (VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)!=0) return 0; // test clip region VSIcuroff(w); // temporarily hide cursor RSerase(w, tx1, ty1, tx2, ty2); // Erase the offending area // draw visible part of scrollback buffer if (y1 < 0) { tx1 = x1; // Set up to clip redraw area to visible area of scrollback buffer tx2 = x2; ty1 = y1; ty2 = (y2>=0) ? -1 : y2; tn = -1; if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { ypt = VSIw->vistop; for(y=VSIw->Rtop; ynext; // Get pointer to top line we need for (y=ty1; y<=ty2; y++) { char *pt; unsigned short *pa; unsigned short lasta; short x, lastx; pt = ypt->text + VSIw->Rleft; pa = ypt->attr + VSIw->Rleft; lastx = tx1; lasta = pa[tx1]; for(x=tx1+1; x<=tx2; x++) { if (pa[x]!=lasta) { RSdraw(w, lastx, y, lasta, x-lastx, pt + lastx); lastx = x; lasta = pa[x]; } } if (lastx<=tx2) RSdraw(w, lastx, y, lasta, tx2-lastx+1, pt + lastx); ypt = ypt->next; } } y1 = 0; // continue with on-screen buffer, if any } // draw visible part of on-screen buffer, taking account of attributes if (y2 >= 0) { tx1 = x1; // Set up to clip redraw area to visible area of on-screen buffer tx2 = x2; ty1 = y1; ty2 = y2; tn = -1; if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { ypt = VSIw->linest[VSIw->Rtop+ty1]; for (y=ty1; y<=ty2; y++) { char *pt; unsigned short *pa; unsigned short lasta; short x, lastx; pt = ypt->text + VSIw->Rleft; pa = ypt->attr + VSIw->Rleft; lastx = tx1; lasta = pa[tx1]; for(x=tx1+1; x<=tx2; x++) { if (pa[x]!=lasta) { RSdraw(w, lastx, y, lasta, x-lastx, pt + lastx); lastx = x; lasta = pa[x]; } } if (lastx<=tx2) RSdraw(w, lastx, y, lasta, tx2-lastx+1, pt + lastx); ypt = ypt->next; } } } VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ tx1 = ty1 = 0; tn = 132; return(0); } /* VSredraw */ short VSOredraw ( short w, // window to redraw */ short x1, short y1, short x2, short y2 ) /* redisplays the specified portion of a virtual screen. */ { VSlinePtr ypt; VSattrlinePtr ypa; short y; short tx1, tx2, ty1, ty2, tn, offset; if (VSvalids(w) != 0) return(-3); x1 += VSIw->Rleft; // Make local coords global again x2 += VSIw->Rleft; y1 += VSIw->Rtop; y2 += VSIw->Rtop; if (x1 < 0) x1 = 0; else if (x1 > VSIw->maxwidth) x1 = VSIw->maxwidth; if (x2 < 0) x2 = 0; else if (x2 > VSIw->maxwidth) x2 = VSIw->maxwidth; if (y1 < -VSIw->numlines) y1 = -VSIw->numlines; else if (y1 > VSIw->lines) y1 = VSIw->lines; if (y2 < -VSIw->numlines) y2 = -VSIw->numlines; /* limit to amount of scrollback */ else if (y2 > VSIw->lines) y2 = VSIw->lines; tx1 = x1; // Set up to clip redraw area to visible area tx2 = x2; ty1 = y1; ty2 = y2; tn = -1; // so we include more than 1 line if (VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)!=0) return 0; // test clip region VSIcuroff(w); // temporarily hide cursor RSerase(w, tx1, ty1, tx2, ty2); // Erase the offending area // draw visible part of scrollback buffer if (y1 < 0) { tx1 = x1; // Set up to clip redraw area to visible area of scrollback buffer tx2 = x2; ty1 = y1; ty2 = (y2>=0) ? -1 : y2; tn = -1; if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { ypt = VSIw->vistop; for(y=VSIw->Rtop; ynext; // Get pointer to top line we need for (y=ty1; y<=ty2; y++) { RSdraw(w, tx1, y, 0, tn, ypt->text + VSIw->Rleft +tx1); ypt = ypt->next; } } y1 = 0; // continue with on-screen buffer, if any } // draw visible part of on-screen buffer, taking account of attributes if (y2 >= 0) { tx1 = x1; // Set up to clip redraw area to visible area of on-screen buffer tx2 = x2; ty1 = y1; ty2 = y2; tn = -1; if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { ypt = VSIw->linest[VSIw->Rtop+ty1]; ypa = VSIw->attrst[VSIw->Rtop+ty1]; for (y=ty1; y<=ty2; y++) { char *pt; unsigned short *pa; unsigned short lasta; short x, lastx; pt = ypt->text + VSIw->Rleft; pa = ypa->text + VSIw->Rleft; lastx = tx1; lasta = pa[tx1]; for(x=tx1+1; x<=tx2; x++) { if (pa[x]!=lasta) { RSdraw(w, lastx, y, lasta, x-lastx, pt + lastx); lastx = x; lasta = pa[x]; } } if (lastx<=tx2) RSdraw(w, lastx, y, lasta, tx2-lastx+1, pt + lastx); ypt = ypt->next; ypa = ypa->next; } } } VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ tx1 = ty1 = 0; tn = 132; return(0); } /* VSOredraw */ short VSwrite ( short w, /* screen to draw into */ char *ptr, /* pointer to text string */ short len /* length of text string */ ) /* sends a stream of characters to the specified window. */ { // _profile = 1; if (len == 0) return 0; if (VSvalids(w) != 0) return(-3); VSIcuroff(w); /* hide cursor momentarily */ VSem((unsigned char *) ptr, len); /* BYU LSC - interpret the character stream */ VSIcurson(w, VSIw->x, VSIw->y, 1); /* restore cursor, force it to be visible. */ // _profile = 0; return(0); } /* VSwrite */ // Utility routine: BetterTelnet 1.0fc3 (RAB) void VSsetprintmode(short w, short printMode) { if (VSvalids(w) != 0) return; VSIw->qprint = printMode; if (!printMode) { VSIw->prredirect = VSIw->printqueued; VSprOFF(); } VSIw->printqueued = 0; } short VSIgetNextTabDistance(void) { short current; if (VSIw->x >= VSIw->maxwidth) return(0); current = VSIw->x + 1; while ((VSIw->tabs[current] != 'x')&&(current < VSIw->maxwidth)) current++; return (current - VSIw->x); } // MAT--We need to define how big the Queue is // MAT--for sending the cursor characters. // MAT--Since MacTCP doesn't like 30+ individual #define MATSbufSize 254 // MAT--SendChar requests. void VSpossendEM // MAT--we can change this to support EMACS ( // MAT--style movement commands. short w, /* affected screen */ // MAT-- short x, /* column to move to */ // MAT-- short y, /* line to move to */ // MAT-- short echo /* local echo flag */ // MAT-- ) // MAT-- /* sends a stream of VT100 cursor-movement sequences to move the // MAT-- cursor on the specified screen to the specified position. */ // MAT-- { // MAT-- UNUSED_ARG(echo) static char // MAT-- tt[MATSbufSize] = ""; // MAT-- char curschar; // MAT-- short localCount; // MAT-- // MAT-- // MAT-- if (x < 0 || y < 0 || x > VSIw->maxwidth || y > VSIw->lines) // MAT-- return; // MAT-- /* convert x and y to relative distance to move */ // MAT-- x -= VSIw->x; // MAT-- y -= VSIw->y; // MAT-- // MAT-- curschar = '\002'; /* EMACS cursor left */ // MAT-- localCount=0; while (x < 0 && localCount < MATSbufSize) // MAT-- { // MAT-- tt[localCount] = curschar; // MAT-- x++; localCount++; // MAT-- } /* while */ // MAT-- if(localCount) RSsendstring(w, tt, localCount); // MAT-- curschar = '\016'; /* EMACS cursor down */ // MAT-- localCount=0; while (y > 0 && localCount < MATSbufSize) // MAT-- why we check to see if localCount is < MATSbufSize { // MAT-- I dont know. But If they had a window > 254 columns tt[localCount] = curschar; // MAT-- maybe it's a good idea. y--; localCount++; // MAT-- but it never hurts to be safe. } /* while */ // MAT-- if(localCount) RSsendstring(w, tt, localCount); // MAT-- curschar = '\020'; /* EMACS cursor up */ // MAT-- localCount=0; while (y < 0 && localCount < MATSbufSize) // MAT-- { // MAT-- tt[localCount] = curschar; // MAT-- y++; localCount++; // MAT-- } /* while */ // MAT-- if(localCount) RSsendstring(w, tt, localCount); // MAT-- curschar = '\006'; /* EMACS cursor right */ // MAT-- localCount=0; while (x > 0 && localCount < MATSbufSize) // MAT-- { // MAT-- tt[localCount] = curschar; // MAT-- x--; localCount++; // MAT-- } /* while */ // MAT-- if(localCount) RSsendstring(w, tt, localCount); // MAT-- // MAT-- if (0) //(note: supposed to look for "echo" here) // MAT-- { // MAT-- VSIcuroff(w); // MAT-- VSIw->x = x; // MAT-- VSIw->y = y; // MAT-- VSIcurson(w, VSIw->x, VSIw->y, 1); /* Force Move */ // MAT-- } /* if */ // MAT-- } /* VSpossendEM */ // changed comment // MAT-- void VSpossend ( short w, /* affected screen */ short x, /* column to move to */ short y, /* line to move to */ short echo /* local echo flag */ ) /* sends a stream of VT100 cursor-movement sequences to move the cursor on the specified screen to the specified position. */ { static char VSkbax[] = "\033O ", /* prefix for auxiliary code */ VSkban[] = "\033[ "; /* prefix for arrows normal */ char *vskptr; if (VSvalids(w) != 0) return; /* NCSA: SB - This would bomb before. You need to get the screens # from the translation routine before you access the record! */ if (screens[findbyVS(w)].arrowmap) { /* NCSA: SB - get the CORRECT screens # */ VSpossendEM(w,x,y,echo); // MAT-- call our cursor movement routine return; // MAT-- then exit } if (VSIw->DECPAM && VSIw->DECCKM) vskptr = VSkbax; else vskptr = VSkban; if (x < 0 || y < 0 || x > VSIw->maxwidth || y > VSIw->lines) return; /* convert x and y to relative distance to move */ x -= VSIw->x; y -= VSIw->y; vskptr[2] = 'D'; /* cursor left */ while (x < 0) { x++; RSsendstring(w, vskptr, 3); } /* while */ vskptr[2] = 'B'; /* cursor down */ while (y > 0) { y--; RSsendstring(w, vskptr, 3); } /* while */ vskptr[2] = 'A'; /* cursor up */ while (y < 0) { y++; RSsendstring(w, vskptr, 3); } /* while */ vskptr[2] = 'C'; /* cursor right */ while (x > 0) { x--; RSsendstring(w, vskptr, 3); } /* while */ if (echo) { VSIcuroff(w); VSIw->x = x; VSIw->y = y; VSIcurson(w, VSIw->x, VSIw->y, 1); /* Force Move */ } /* if */ } /* VSpossend */ char VSkbsend ( short w, /* active window */ unsigned char k, /* special key code if > 128, else ascii code */ short echo /* local echo flag */ ) /* sends the appropriate sequence for the specified key, taking due account of terminal mode settings. */ { static char VSkbkn[] = "\033O ", /* prefix for keypad normal */ VSkbax[] = "\033O ", /* prefix for auxiliary code*/ VSkban[] = "\033[ ", /* prefix for arrows normal */ VSkbfn[] = "\033O ", /* prefix for function keys */ /* BYU 2.4.12 */ VSk220[] = "\033[ ~"; /* prefix for vt220 keys */ /* BYU 2.4.12 */ char *vskptr; short vskplen; if (VSvalids(w) != 0) return(-3); if ( screens[findbyVS(w)].arrowmap && (k <= VSLT) && (k >= VSUP) ) // MAT-- // MAT-- important...we need to check this first before { // MAT-- the next if() statement gets its hands on the string. switch (k) { // MAT-- do the mapping from arrowkeys -> EMACS ctrl keys. case VSLT: // MAT-- k = 0x02; // MAT-- ^B Question: Is there a way to find out if the option break; // MAT-- key was held down with this character? case VSRT: // MAT-- I didn't want to declare myEvent an extern k = 0x06; // MAT-- ^F (I didn't know if that was a no-no) break; // MAT-- If I can.....let me know, I want to make case VSUP: // MAT-- option-arrowkey's do useful things too k = 0x10; // MAT-- ^P break; // MAT-- checking the keymap would be a kludge here. case VSDN: // MAT-- k = 0x0e; // MAT-- ^N break; // MAT-- } /* switch k */ // MAT-- RSsendstring(w,(char *)&k,1); // MAT-- send the character return(0); // MAT-- } // MAT-- if (k < VSF10) /* BYU 2.4.12 */ /* 7-bit ascii code -- send as is */ RSsendstring(w,(char *) &k, 1); /* BYU LSC */ /* Keypad (Not Application Mode): 0-9 , - . Enter */ if ((k > VSLT) && (k < VSF1) && (!VSIw->DECPAM)) { RSsendstring(w, &VSIkpxlate[0][k - VSUP], 1); if (echo) VSwrite(w, &VSIkpxlate[0][k - VSUP], 1); if (k == VSKE) RSsendstring(w, "\012", 1); return(0); } /* if */ if (VSIw->DECPAM && VSIw->DECCKM) { /* aux kp mode */ vskptr = VSkbax; vskplen = 3; vskptr[2] = VSIkpxlate[1][k - VSUP]; /* BYU 2.4.12 */ } else if (k < VSUP) { /* BYU 2.4.12 */ vskptr = VSk220; /* BYU 2.4.12 */ vskplen = VSIkplen[k - VSF10]; /* BYU 2.4.12 */ vskptr[2] = VSIkpxlate2[k - VSF10]; /* BYU 2.4.12 */ vskptr[3] = VSIkpxlate3[k - VSF10]; /* BYU 2.4.12 */ } else { /* BYU 2.4.12 */ vskplen = 3; /* BYU 2.4.12 */ if (k < VSK0) { /* BYU 2.4.13 - arrow keys */ vskptr = VSkban; /* BYU 2.4.12 */ if (VSIw->DECCKM) /* BYU 2.4.13 */ vskptr[1] = 79; /* BYU 2.4.13 */ else /* BYU 2.4.13 */ vskptr[1] = 91; /* BYU 2.4.13 */ } /* BYU 2.4.13 */ else if (k < VSF1) /* BYU 2.4.12 */ vskptr = VSkbkn; /* BYU 2.4.12 */ else /* BYU 2.4.12 */ vskptr = VSkbfn; /* BYU 2.4.12 */ /* BYU 2.4.12 */ vskptr[2] = VSIkpxlate[1][k - VSUP]; /* BYU 2.4.12 */ } /* BYU 2.4.12 */ RSsendstring(w, vskptr, vskplen); if (echo) VSwrite(w, vskptr, vskplen); return(0); } /* VSkbsend */ short VSreset ( short w ) /* resets virtual terminal settings to default state, clears screen and homes cursor. */ { if (VSvalids(w) != 0) return(-3); VSIcuroff(w); /* NCSA: SB -- get rid of extraneous cursor BS */ VSIreset(); /* causes cursor to disappear */ VSIcurson(w, VSIw->x, VSIw->y, 1); /* redisplay cursor at home position */ return(0); } /* VSreset */ void VSscrolright ( short w, short n /* number of columns to scroll */ ) /* moves the view of the virtual screen within its window the specified number of columns to the right. */ { short sn, lmmax; if (VSvalids(w) != 0) return; /* limit scroll amount against number of invisible columns */ lmmax = VSIw->maxwidth - (VSIw->Rright - VSIw->Rleft); if (VSIw->Rleft + n > lmmax) n = lmmax - VSIw->Rleft; /* can't scroll any further right than this */ if (n == 0) return; /* Do nothing if appropriate */ VSIcuroff(w); /* temporarily hide cursor */ VSIw->Rleft += n; /* update visible region */ VSIw->Rright += n; sn = VSIw->Rbottom - VSIw->Rtop; RSmargininfo(w, lmmax, VSIw->Rleft); /* update horizontal scroll bar */ RSdelcols(w, n); /* scroll the window contents */ VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ /* redraw newly-revealed portion of screen */ VSredraw(w, (VSIw->Rright - VSIw->Rleft) - n, 0, (VSIw->Rright - VSIw->Rleft), sn); } /* VSscrolright */ void VSscrolleft ( short w, short n /* number of columns to scroll */ ) /* moves the view of the virtual screen within its window the specified number of columns to the left. */ { short sn, lmmax; if (VSvalids(w) != 0) return; lmmax = VSIw->maxwidth - (VSIw->Rright - VSIw->Rleft); /* number of invisible columns */ if (n > VSIw->Rleft) n = VSIw->Rleft; /* can't scroll any further left than this */ if (n == 0) return; /* Do nothing if appropriate */ VSIcuroff(w); /* temporarily hide cursor */ VSIw->Rleft -= n; /* update visible region */ VSIw->Rright -= n; sn = VSIw->Rbottom - VSIw->Rtop; RSmargininfo(w, lmmax, VSIw->Rleft); /* update horizontal scroll bar */ RSinscols(w, n); /* scroll the window contents */ VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ VSredraw(w, 0, 0, n, sn); /* redraw newly-revealed portion of screen */ } /* VSscrolleft */ short VSscroltop( short w /* which window */) /* JMB 2.6 */ { /* JMB 2.6 */ if (VSvalids(w) != 0) /* JMB 2.6 */ return(-3); /* JMB 2.6 */ /* JMB 2.6 */ return(VSscrolback(w, VSIw->Rtop + VSIw->numlines)); /* can't scroll back any further than this */ } /* JMB 2.6 */ short VSscrolback ( short w, /* which window */ short in /* number of lines to scroll */ ) /* moves the view of the virtual screen within its window the specified number of lines upwards. */ { short sn, n; n = in; if (VSvalids(w) != 0) return(-3); if (VSIw->numlines < (n - VSIw->Rtop)) n = VSIw->Rtop + VSIw->numlines; /* can't scroll back any further than this */ if (n <= 0) return(0); /* Dont be scrollin' no lines.... */ VSIcuroff(w); /* temporarily hide cursor */ VSIw->Rtop = VSIw->Rtop - n; /* adjust the visible region */ VSIw->Rbottom = VSIw->Rbottom - n; /* find the line list element for the new topmost visible line */ sn = n; while (sn-- > 0) { #ifdef DEBUGMAC if (VSIw->vistop->prev == 0L) DebugStr("\pVSscrolback -- something wrong with linked list structure"); #endif DEBUGMAC VSIw->vistop = VSIw->vistop->prev; } /* while */ sn = VSIw->Rbottom - VSIw->Rtop; /* update vertical scroll bar */ RSbufinfo(w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); if (n <= VSIw->lines) { RSinslines(w, 0, sn, n, 0); /* scroll, preserving current selection */ VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ VSredraw(w, 0, 0, VSIw->maxwidth, n - 1); /* redraw newly-revealed portion */ } else { /* currently-visible contents scrolled completely off the screen-- just redraw everything */ VSredraw(w, 0, 0, VSIw->maxwidth, sn); } return(0); } /* VSscrolback */ short VSscrolforward ( short w, /* which window */ short n /* number of lines to scroll */ ) /* moves the view of the virtual screen within its window the specified number of lines downwards. */ { short sn; if (VSvalids(w) != 0) return(-3); if (n > VSIw->lines - VSIw->Rbottom) n = VSIw->lines - VSIw->Rbottom; /* can't scroll any further forward than this */ if (n <= 0) return(0); /* Dont be scrollin' no lines.... */ VSIcuroff(w); /* temporarily hide cursor */ VSIw->Rtop = n + VSIw->Rtop; /* adjust the visible region */ VSIw->Rbottom = n + VSIw->Rbottom; /* find the line list element for the new topmost visible line */ sn = n; while (sn-- > 0) { #ifdef DEBUGMAC if (VSIw->vistop->next == nil) DebugStr("\pVSscrolforward -- something wrong with linked list structure"); #endif DEBUGMAC VSIw->vistop = VSIw->vistop->next; } /* while */ sn = VSIw->Rbottom - VSIw->Rtop; /* update vertical scroll bar */ RSbufinfo(w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); if (n <= VSIw->lines) { RSdellines(w, 0, sn, n, 0); /* scroll, preserving current selection */ VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ VSredraw(w, 0, (sn + 1) - n, VSIw->maxwidth, sn); /* redraw newly-revealed portion */ } /* if */ else { /* currently-visible contents scrolled completely off the screen-- just redraw everything */ VSredraw(w, 0, 0, VSIw->maxwidth, sn); } return(0); } /* VSscrolforward */ short VSsetrgn ( short w, short x1, /* leftmost column */ short y1, /* uppermost line */ short x2, /* rightmost column */ short y2 /* bottommost line */ ) /* sets the visible region for the specified virtual screen in its window, scrolling its contents as appropriate. Assumes that either the vertical bounds or the height of the region has changed, but not both, and similarly that the horizontal bounds or the width has changed, but not both. */ { short n; if (VSvalids(w) != 0) return(-3); VSIw->Rbottom = VSIw->Rtop + (y2 - y1); /* make change in height of visible region first */ if (x2 > VSIw->maxwidth) { /* trying to make columns visible which aren't there-- adjust the left and right boundaries to avoid this */ n = x2 - VSIw->maxwidth; /* how far to adjust to the left */ if (n > x1) n = x1; /* but I'd rather have unused columns on the right than on the left */ x1 -= n; /* Adjust left */ x2 -= n; /* Adjust right */ } /* if */ if (VSIw->Rleft != x1) { /* left margin changed -- scroll horizontally */ /* (assume width of region hasn't also changed) */ n = x1 - VSIw->Rleft; if (n > 0) VSscrolright(w, n); else VSscrolleft(w, -n); } else /* just update horizontal scroll bar limits for new width of visible region */ RSmargininfo(w, VSIw->maxwidth - (x2 - x1), x1); VSIw->Rleft = x1; VSIw->Rright = x2; if (VSIw->Rbottom > VSIw->lines) /* don't scroll off the bottom of the screen */ n = VSIw->Rbottom - VSIw->lines; else /* scroll to new topmost line as specified */ n = VSIw->Rtop - y1; if (n != 0) /* scroll vertically (assume height of region hasn't also changed) */ if (n > 0) VSscrolback(w, n); else VSscrolforward(w, -n); else /* update vertical scroll bar limits for new height of visible region */ RSbufinfo(w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); return(0); } /* VSsetrgn */ short VSscrolcontrol ( short w, short scrolon, /* whether to save lines off top */ short offtop /* whether to save lines on clearing entire screen */ ) /* changes scrollback flag settings for a virtual screen. */ { if (VSvalids(w) != 0) return(-3); if (scrolon > -1) VSIw->savelines = scrolon; if (offtop > -1) VSIw->ESscroll = offtop; return(0); } /* VSscrolcontrol */ // RAB BetterTelnet 1.2 - set "ignore beeps" void VSbeepcontrol ( short w, short beep ) { if (VSvalids(w) != 0) return; VSIw->ignoreBeeps = beep; } short VSgetrgn ( short w, short *x1, short *y1, short *x2, short *y2 ) /* returns the current visible region for a virtual screen. */ { if (VSvalids(w) != 0) return(-3); *x1 = VSIw->Rleft; *y1 = VSIw->Rtop; *x2 = VSIw->Rright; *y2 = VSIw->Rbottom; return(0); } /* VSgetrgn */ short VSmaxwidth ( short w ) /* returns one less than the number of columns on a virtual screen. */ { if (VSvalids(w) != 0) return(-3); return(VSIw->maxwidth); } /* VSmaxwidth */ VSlinePtr VSIGetLineStart(short w, short y1) /* returns a pointer to the specified text line (number may be negative for a line in the scrollback buffer). */ { VSlinePtr ptr; short n; if (VSvalids(w) != 0) return((VSlinePtr) -3); if (y1 >= 0) return(VSIw->linest[y1]); n = y1 - VSIw->Rtop; /* Number of lines from VISTOP to scroll forward */ ptr = VSIw->vistop; while (n > 0) { n--; ptr = ptr->next; } /* while */ while (n < 0) { n++; ptr = ptr->prev; } /* while */ return(ptr); } /* VSIGetLineStart */ char *VSIstrcopy(char *src, short len, char *dest, short table, short noClip) /* copies characters from *src (length len) to *dest, dropping trailing blanks. If table is nonzero, then this number (or more) of consecutive embedded blanks will be replaced with a tab. Returns a pointer to the position one past the last character copied to the *dest buffer. */ { char *p, *tempp; short tblck; p = src + len - 1; /* skip trailing blanks, but only if !noClip */ if ((!noClip) || table || gApplicationPrefs->clipTrailingSpaces) // RAB BetterTelnet 1.0fc7, 1.1 while ((*p == ' ') && (p >= src)) p--; if (p < src) return(dest); if (!table) /* straight character copy */ while (src <= p) *dest++ = *src++; else /* tab-replacement copy */ while (src <= p) { while ((src <= p) && (*src != ' ')) *dest++ = *src++; if (src < p) { tempp = dest; /* remember start of run of spaces */ tblck = 0; /* length of run */ while ((src <= p) && (*src == ' ')) { *dest++ = *src++; tblck++; } /* while */ if (tblck >= table) { *tempp++ = '\011'; /* replace first space with a tab */ dest = tempp; /* drop remaining spaces */ } /* if */ } /* if */ } /* while */ return(dest); } /* VSIstrcopy */ long VSgettext(short w, short x1, short y1, short x2, short y2, char *charp, long max, char *EOLS, short table) /* copies a portion of text from the specified virtual screen into the *charp buffer. table, if nonzero, is the minimum length of runs of spaces to be replaced with single tabs. Returns the length of the copied text. max is supposed to be the maximum length to copy, but this is currently ignored! EOLS is the end-of-line sequence to insert at line boundaries. This is currently assumed to be exactly one character long. */ { UNUSED_ARG(max) /* !! */ short EOLlen; short lx,ly, /* Upper bounds of selection */ ux,uy; /* Lower bounds of selection */ short maxwid; char *origcp; VSlinePtr t; if (VSvalids(w) != 0) return(-3); EOLlen = strlen(EOLS); maxwid = VSIw->maxwidth; origcp = charp; if (y1 < -VSIw->numlines) { y1 = -VSIw->numlines; x1 = -1; } /* if */ if (y1 == y2) { /* copying no more than a single line */ t = VSIGetLineStart(w, y1); if (x1 < x2) /* Order the lower and upper bounds */ { ux = x1; uy = y1; lx = x2; ly = y2; } else { ux = x2; uy = y2; lx = x1; ly = y1; } /* if */ if ((long)(lx-ux) < max) charp=VSIstrcopy(&t->text[ux+1], lx-ux, charp, table, 1); else charp=VSIstrcopy(&t->text[ux+1], (short)(max - (long)(charp-origcp)), charp, table, 1); if (lx == maxwid) *charp++ = *EOLS; /* assumes it's only one character! */ } else { /* copying more than one line */ if (y1 < y2) /* Order the lower and upper bounds */ { ux = x1; uy = y1; lx = x2; ly = y2; } else { ux = x2; uy = y2; lx = x1; ly = y1; } /* if */ t = VSIGetLineStart(w, uy); if (((long) (maxwid-ux) < max)) charp=VSIstrcopy(&t->text[ux+1],maxwid-ux,charp,table, 0); else charp=VSIstrcopy(&t->text[ux+1],(short) (max-(long)(charp-origcp)),charp,table, 0); *charp++ = *EOLS; /* assumes it's only one character! */ uy++; t = t->next; while (uy < ly && uy < VSIw->lines) { if ((long)(maxwid+1) < max) charp=VSIstrcopy(t->text,maxwid+1,charp, table, 0); else charp=VSIstrcopy(t->text,(short)(max - (long) (charp-origcp)),charp, table, 0); *charp++=*EOLS; t=t->next; uy++; } /* while */ if (ly > VSIw->lines) lx = maxwid; if ((long) (lx+1) < max) charp=VSIstrcopy(t->text,lx+1,charp,table, 0); else charp=VSIstrcopy(t->text,(short)(max - (long)(charp-origcp)),charp,table, 0); if (lx >= maxwid) *charp++ = *EOLS; /* assumes it's only one character! */ } /* if */ return(charp - origcp); } /* VSgettext */ short VSgetlines ( short w ) /* returns the number of lines in a virtual screen. */ { if (VSvalids(w) != 0) return(-2); return(VSIw->lines + 1); } /* VSgetlines */ short VSsetlines ( short w, /* window number */ short lines /* new number of lines */ ) /* sets the number of lines in a virtual screen, reallocating text and attribute arrays accordingly. Returns the new number of lines on success, or an error otherwise */ { VSlineArray linest; /* For storage of old ones */ VSlinePtr line; /* pointer to a line */ short i, j, oldlines; char *temp; unsigned short *tempa; if (VSvalids(w) != 0) return(-3000); if (VSIw->oldScrollback) return VSOsetlines(w, lines); lines -= 1; /* Correct for internal use */ oldlines = VSIw->lines; if (lines == oldlines) /* no change */ return(0); VSIw->x = 0; VSIw->y = 0; VSIcurson(w, VSIw->x, VSIw->y, 1); /* keeps cursor from pointing outside of window */ VSIw->vistop = VSIw->scrntop; /* Force view to the top of the screen */ linest = VSIw->linest; VSIw->linest = VSInewlinearray(lines + 1); /* allocate new screen buffers */ if (!VSIw->linest) { VSIw->linest = linest; /* mem problems */ return (-2000); } VSIw->lines = lines; /* set new number of screen lines */ VSIw->linest[0] = VSInewlines(lines + 1); /* allocate new text and attribute lines */ if (VSIw->linest[0]) { /* mem is there */ VSIlistndx(VSIw->linest[0]); /* build the new screen arrays */ if (VSIw->savelines) { /* save previous screen contents in scrollback buffer */ line = linest[oldlines]->next; /* save continuation */ linest[oldlines]->next = VSIw->linest[0]; VSIw->linest[lines]->next = line; /* restore continuation */ VSIw->linest[0]->prev = linest[oldlines]; /* backpointer */ if (line) /* if there was a follower */ line->prev = VSIw->linest[lines]; /* new prev for it */ VSIw->numlines += oldlines; /* we made more scrollback */ } else { /* get rid of previous screen contents */ VSIfreelinelist(linest[0]); DisposPtr((Ptr) linest); } } else { /* need more mem - emergency */ if (VSIw->linest[0]) /*if 1/2 of push for memory died, kill the other */ VSIfreelinelist(VSIw->linest[0]); /* Here we should ask if we want to lose the screen buffer!! CCP */ VSIfreelines(); /* release scrollback buffer */ VSIfreelinelist(linest[0]); /* release current visible lines */ DisposPtr((Ptr) linest); VSIw->linest[0] = VSInewlines(lines + 1); /* allocate new screen arrays */ if (!VSIw->linest[0]) { /* still not enough memory; Try to allocate just enough to go back to original size */ if (VSIw->linest[0]) /* this gets rid of useless */ VSIfreelinelist(VSIw->linest[0]); /* memory, since we are giving up */ VSIw->linest[0] = VSInewlines(oldlines + 1); /* try original size */ if (!VSIw->linest[0]) /* damage control: */ { /* Nope. Give up, and signal that */ if (VSIw->linest[0]) /* caller should kill this screen */ VSIfreelinelist(VSIw->linest[0]); /* dont destroy everything, as this will screw up VSdestroy later */ return(-4000); } else { lines = oldlines; VSIw->lines = lines; } } VSIw->buftop = VSIw->linest[0]; VSIw->numlines = 0; /* nothing in scrollback */ } /* if */ VSIw->scrntop = VSIw->linest[0]; /* new top of screen */ VSIw->vistop = VSIw->scrntop; /* Force a scroll to the top of the screen */ VSIlistndx(VSIw->scrntop); /* rebuild screen arrays */ if (!VSIw->savelines) { /* make text line list circular to indicate no extensions */ VSIw->linest[lines]->next = VSIw->linest[0]; VSIw->linest[0]->prev = VSIw->linest[lines]; } /* if */ /* initialize the new screen lines to blank text and no attributes */ for (i = 0; i <= lines; i++) { tempa = VSIw->linest[i]->attr; temp = VSIw->linest[i]->text; for (j = 0; j <= VSIw->allwidth; j++) { *temp++ = ' '; *tempa++ = 0; } /* for */ } /* for */ /* reset scrolling region */ VSIw->top = 0; VSIw->bottom = lines; /* reset visible region */ VSIw->Rtop = 0; VSIw->Rbottom = lines; VSredraw(w, 0, 0, VSIw->maxwidth, lines); /* draw new blank screen */ RSbufinfo(w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* adjust vertical scroll bar */ return(VSIw->lines); } /* VSsetlines */ short VSOsetlines ( short w, /* window number */ short lines /* new number of lines */ ) /* sets the number of lines in a virtual screen, reallocating text and attribute arrays accordingly. Returns the new number of lines on success, or an error otherwise */ { VSlineArray linest; /* For storage of old ones */ VSattrlineArray attrst; VSlinePtr line; /* pointer to a line */ short i, j, oldlines; char *temp; unsigned short *tempa; if (VSvalids(w) != 0) return(-3000); lines -= 1; /* Correct for internal use */ oldlines = VSIw->lines; if (lines == oldlines) /* no change */ return(0); VSIw->x = 0; VSIw->y = 0; VSIcurson(w, VSIw->x, VSIw->y, 1); /* keeps cursor from pointing outside of window */ VSIw->vistop = VSIw->scrntop; /* Force view to the top of the screen */ attrst = VSIw->attrst; /* save old screen arrays */ linest = VSIw->linest; VSIw->linest = VSInewlinearray(lines + 1); /* allocate new screen buffers */ if (!VSIw->linest) { VSIw->linest = linest; /* mem problems */ return (-2000); } VSIw->attrst = (VSattrlinePtr *)VSInewlinearray(lines + 1); if (!VSIw->attrst) { /* mem problems */ DisposPtr((Ptr) VSIw->linest); VSIw->linest = linest; VSIw->attrst = attrst; return (-2000); } VSIw->lines = lines; /* set new number of screen lines */ VSIw->linest[0] = VSOnewlines(lines + 1,1); /* allocate new text and attribute lines */ VSIw->attrst[0] = (VSattrlinePtr)VSOnewlines(lines + 1,2); if (VSIw->linest[0] && VSIw->attrst[0]) { /* mem is there */ /* dispose of old attribute lines */ VSIfreelinelist((VSlinePtr)attrst[0]); DisposPtr((Ptr) attrst); VSOlistndx(VSIw->linest[0],VSIw->attrst[0]); /* build the new screen arrays */ if (VSIw->savelines) { /* save previous screen contents in scrollback buffer */ line = linest[oldlines]->next; /* save continuation */ linest[oldlines]->next = VSIw->linest[0]; VSIw->linest[lines]->next = line; /* restore continuation */ VSIw->linest[0]->prev = linest[oldlines]; /* backpointer */ if (line) /* if there was a follower */ line->prev = VSIw->linest[lines]; /* new prev for it */ VSIw->numlines += oldlines; /* we made more scrollback */ } else { /* get rid of previous screen contents */ VSIfreelinelist(linest[0]); DisposPtr((Ptr) linest); } } else { /* need more mem - emergency */ if (VSIw->linest[0]) /*if 1/2 of push for memory died, kill the other */ VSIfreelinelist(VSIw->linest[0]); if (VSIw->attrst[0]) VSIfreelinelist((VSlinePtr)VSIw->attrst[0]); /* Here we should ask if we want to lose the screen buffer!! CCP */ VSIfreelines(); /* release scrollback buffer */ VSIfreelinelist(linest[0]); /* release current visible lines */ DisposPtr((Ptr) linest); VSIfreelinelist((VSlinePtr)attrst[0]); /* release current visible attrib */ DisposPtr((Ptr) attrst); VSIw->linest[0] = VSOnewlines(lines + 1,1); /* allocate new screen arrays */ VSIw->attrst[0] = (VSattrlinePtr)VSOnewlines(lines + 1,2); if (!VSIw->linest[0] || !VSIw->attrst[0]) { /* still not enough memory; Try to allocate just enough to go back to original size */ if (VSIw->linest[0]) /* this gets rid of useless */ VSIfreelinelist(VSIw->linest[0]); /* memory, since we are giving up */ if (VSIw->attrst[0]) VSIfreelinelist((VSlinePtr)VSIw->attrst[0]); VSIw->linest[0] = VSOnewlines(oldlines + 1,1); /* try original size */ VSIw->attrst[0] = (VSattrlinePtr)VSOnewlines(oldlines + 1,2); if (!VSIw->linest[0] || !VSIw->attrst[0]) /* damage control: */ { /* Nope. Give up, and signal that */ if (VSIw->linest[0]) /* caller should kill this screen */ VSIfreelinelist(VSIw->linest[0]); if (VSIw->attrst[0]) VSIfreelinelist((VSlinePtr)VSIw->attrst[0]); /* dont destroy everything, as this will screw up VSdestroy later */ return(-4000); } else { lines = oldlines; VSIw->lines = lines; } } VSIw->buftop = VSIw->linest[0]; VSIw->numlines = 0; /* nothing in scrollback */ } /* if */ VSIw->scrntop = VSIw->linest[0]; /* new top of screen */ VSIw->vistop = VSIw->scrntop; /* Force a scroll to the top of the screen */ VSOlistndx(VSIw->scrntop, VSIw->attrst[0]); /* rebuild screen arrays */ VSIw->attrst[0]->prev = VSIw->attrst[lines]; /* Make attribute list circular */ VSIw->attrst[lines]->next = VSIw->attrst[0]; if (!VSIw->savelines) { /* make text line list circular to indicate no extensions */ VSIw->linest[lines]->next = VSIw->linest[0]; VSIw->linest[0]->prev = VSIw->linest[lines]; } /* if */ /* initialize the new screen lines to blank text and no attributes */ for (i = 0; i <= lines; i++) { tempa = VSIw->attrst[i]->text; temp = VSIw->linest[i]->text; for (j = 0; j <= VSIw->allwidth; j++) { *temp++ = ' '; *tempa++ = 0; } /* for */ } /* for */ /* reset scrolling region */ VSIw->top = 0; VSIw->bottom = lines; /* reset visible region */ VSIw->Rtop = 0; VSIw->Rbottom = lines; VSOredraw(w, 0, 0, VSIw->maxwidth, lines); /* draw new blank screen */ RSbufinfo(w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* adjust vertical scroll bar */ return(VSIw->lines); } /* VSOsetlines */ /*--------------------------------------------------------------------------*/ /* NCSA: SB - VSsetcols */ /* This allows external procedures to set the column width. Used by */ /* routines in main, to allow ARBITRARY column widths */ /*--------------------------------------------------------------------------*/ short VSsetcols(short w, short myWidth) /* NCSA: SB */ { /* NCSA: SB */ if (VSvalids(w) != 0) /* NCSA: SB */ return(-1); /* NCSA: SB */ VSIw->maxwidth = myWidth; /* NCSA: SB */ return 0; } /* NCSA: SB */ /*--------------------------------------------------------------------------*/ /* NCSA: SB - VSgetcols */ /* This returns the column width. Used by SetScreenDimensions, when */ /* the procedure needs to know the initial column width */ /*--------------------------------------------------------------------------*/ short VSgetcols(short w) /* NCSA: SB */ { /* NCSA: SB */ if (VSvalids(w) != 0) /* NCSA: SB */ return(-1); /* NCSA: SB */ return VSIw->maxwidth; /* NCSA: SB */ } /* NCSA: SB */ \ No newline at end of file +// BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // #pragma profile on /* * * Virtual Screen Kernel Interface * (vsinterf.c) * * by Gaige B. Paulsen * * This file contains the control and interface calls for the NCSA * Virtual Screen Kernal. * * VSinit(maxwidth) - Initialize the VSK * VSnewscreen(maxlines,scrnsave) - Initialize a new screen. * VSdetach(w) - Detach screen w * VSredraw(w,x1,y1,x2,y2) - redraw region for window w * VSwrite(w,ptr,len) - write text @ptr, length len * VSclear(w) - clear w's real screen * VSkbsend(w,k,echo) - send keycode k's rep. out window w (w/echo if req.) * VSclearall(w) - clear w's real and saved screen * VSreset(w) - reset w's emulator (as per TERM) * VSgetline(w,y) - get a ptr to w's line y * VSsetrgn(w,x1,y1,x2,y2) - set local display region * VSscrolback(w,n) - scrolls window w back n lines * VSscrolforward(w,n) - scrolls window w forward n lines * VSscrolleft(w,n) - scrolls window w left n columns * VSscrolright(w,n) - scrolls window w right n columns * VSscrolcontrol(w,scrlon,offtop) - sets scroll vars for w * VSgetrgn(w,&x1,&y1,&x2,&y2) - returns set region * VSsnapshot(w) - takes a snapshot of w * VSgetlines(w) - Returns current # of lines * VSsetlines(w, lines) - Sets the current # of lines to lines * * Version Date Notes * ------- ------ --------------------------------------------------- * 0.01 861102 Initial coding -GBP * 0.10 861113 Added some actual program to this file -GBP * 0.15 861114 Initiated Kludge Operation-GBP * 0.50 8611VSPBOTTOM Parameters added to VSnewscreen -GBP * 0.90 870203 Added the kbsend routine -GBP * 2.1 871130 NCSA Telnet 2.1 -GBP * 2.2 880715 NCSA Telnet 2.2 -GBP * */ #define VSMASTER #include "rsinterf.proto.h" #include "rsmac.proto.h" #include "vsem.proto.h" #include "vsdata.h" #include "vskeys.h" #include "vsinit.h" #include "vsintern.proto.h" #include "Wind.h" #include "DlogUtils.proto.h" #include "maclook.proto.h" #include "errors.proto.h" #include "Macros.proto.h" #define DEBUGMAC #include "vsinterf.proto.h" extern TelInfoRec *TelInfo; extern WindRec *screens; extern long TempItemsDirID; extern short TempItemsVRefNum; extern short RSa; short /* Internal variables for use in managing windows */ VSmax = 0, /* max nr screens allowed */ VSinuse = 0; /* nr screens actually in existence */ VSscrndata *VSscreens; short VSinit ( short max /* max nr screens to allow */ ) /* initializes virtual screen and window handling. */ { short i; RSinitall(max); VSmax = max; VSIwn = 0; if ((VSscreens = (VSscrndata *) myNewPtr(max * sizeof(VSscrndata))) == 0L) return(-2); for (i = 0; i < max; i++) { VSscreens[i].loc = 0L; VSscreens[i].stat = 0; } /* for */ return(0); } /* VSinit */ short VSiscapturing(short w) { /* BYU 2.4.18 */ return(VSscreens[w].captureRN); /* BYU 2.4.18 */ } /* BYU 2.4.18 */ Boolean VSopencapture(short scrn_num, short w) { UNUSED_ARG(scrn_num) static short captNumber = 1; short VRefNum; long DirID; Str255 filename, tempString; Str32 numstring; Point where = {100,100}; SFReply sfr; long junk = 0; OSErr err; NumToString(captNumber++, numstring); GetIndString(filename, MISC_STRINGS, CAPTFILENAME); filename[++(filename[0])] = ' '; pstrcat(filename, numstring); GetIndString(tempString,MISC_STRINGS,SAVE_CAPTURED_TEXT_STRING); SFPutFile(where,tempString, filename, NULL, &sfr); if (sfr.good) { (void) GetWDInfo(sfr.vRefNum, &VRefNum, &DirID, &junk); err = HCreate(VRefNum, DirID, sfr.fName, gApplicationPrefs->CaptureFileCreator, 'TEXT'); if (err == dupFNErr) { HDelete(VRefNum, DirID, sfr.fName); err = HCreate(VRefNum, DirID, sfr.fName, gApplicationPrefs->CaptureFileCreator, 'TEXT'); } if (err != noErr) OperationFailedAlert(CANT_CREATE_FILE, 500, err); else { err = HOpenDF(VRefNum, DirID, sfr.fName, fsRdWrPerm, &VSscreens[w].captureRN); if (err != noErr) OperationFailedAlert(CANT_OPEN_FILE, 501, err); else { SetEOF(VSscreens[w].captureRN, (long) 0); return(TRUE); } } } return(FALSE); } void VSclosecapture(short w) { /* BYU 2.4.18 */ FSClose(VSscreens[w].captureRN); /* BYU 2.4.18 */ VSscreens[w].captureRN = 0; /* BYU 2.4.18 */ } /* BYU 2.4.18 */ void VScapture(unsigned char *ptr, short len) { /* BYU 2.4.18 */ long ln = len; /* BYU 2.4.18 */ if (VSscreens[VSIwn].captureRN) { /* BYU 2.4.18 */ unsigned char captbuf[512]; /* BYU 2.4.18 */ unsigned char *ptr2,*ptr3; /* BYU 2.4.18 */ ptr2 = ptr; /* BYU 2.4.18 */ ptr3 = &captbuf[0]; /* BYU 2.4.18 */ #ifdef DEBUG_CAPTURE // RAB BetterTelnet 2.0b1 - debug capture captures ALL control codes if (TelInfo->debug) { for (len = 0; len < ln; len++) *(ptr3++) = *(ptr2++); } else { #endif for (len = 0; len < ln; len++) { /* BYU 2.4.18 */ if (*ptr2 >= 32 || /* BYU 2.4.18 */ *ptr2 == 13 || /* BYU 2.4.18 */ *ptr2 == 9) /* BYU 2.4.18 */ *(ptr3++) = *(ptr2++); /* BYU 2.4.18 */ else { /* BYU 2.4.18 */ ptr2++; /* BYU 2.4.18 */ ln--; /* BYU 2.4.18 */ } /* BYU 2.4.18 */ } /* BYU 2.4.18 */ #ifdef DEBUG_CAPTURE } #endif if (ln > 0) { /* BYU 2.4.18 */ if (FSWrite(VSscreens[VSIwn].captureRN, &ln, captbuf)) { /* BYU 2.4.18 */ FSClose(VSscreens[VSIwn].captureRN); /* BYU 2.4.18 */ VSscreens[VSIwn].captureRN = 0; /* BYU 2.4.18 */ } /* BYU 2.4.18 */ } /* BYU 2.4.18 */ } /* BYU 2.4.18 */ } /* BYU 2.4.18 */ short VSisprinting(short w) { if ((VSscreens[w].loc)->qprint) // RAB BetterTelnet 1.0fc4 return ((VSscreens[w].loc)->printqueued); // RAB BetterTelnet 1.0fc4 return ((VSscreens[w].loc)->prredirect); } void ClosePrintingFile(short w) { OSErr sts; char tmp[80]; putln("Attempting to remove print file"); if ((sts=FSClose ((VSscreens[w].loc)->refNum)) != noErr) { SysBeep(1); sprintf(tmp,"FSClose: ERROR %d",sts); putln(tmp); } if ((sts=HDelete(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname)) != noErr) { SysBeep(1); sprintf(tmp,"HDelete: ERROR %d",sts); putln(tmp); } } short VSvalids ( short w ) /* validates a virtual screen number and sets it as the current screen for subsequent operations if success. Returns 0 iff success. */ { if (VSinuse == 0) return(-5); /* -5=no ports in use */ if (VSIwn == w) return(0); /* Currently set to that window */ if ((w > VSmax) || (w < 0)) return(-6); /* blown out the top of the stuff */ VSIwn = w; if (VSscreens[w].stat != 1) return(-3);/* not currently active */ VSIw = VSscreens[w].loc; if (VSIw == 0L) return(-3); /* no space allocated */ return(0); } /* VSvalids */ VSscrn *VSwhereis(short i) /* screen number */ /* returns a pointer to the structure for the specified screen. */ { VSvalids(i); return(VSIw); } /* VSwhereis */ void VSIclrbuf ( void ) /* clears out the text and attribute buffers for the current screen. All text characters are set to blanks, and all attribute bytes are set to zero. Doesn't update the display. */ { register short j, i; register char *tx; register unsigned short *ta; for (i = 0; i <= VSIw->lines; i++) { if (VSIw->oldScrollback) ta = &VSIw->attrst[i]->text[0]; else ta = &VSIw->linest[i]->attr[0]; tx = &VSIw->linest[i]->text[0]; for (j = 0; j <= VSIw->allwidth; j++) { *ta++ = 0; *tx++ = ' '; } /* for */ } /* for */ } /* VSIclrbuf */ short VSnewscreen ( short maxlines, /* max lines to save in scrollback buffer */ short screensave, /* whether to have a scrollback buffer */ short numLines, //numLines initially on screen (CCP 2.7) short maxwid, /* number of columns on screen */ short forcesave, /* NCSA 2.5: force lines to be saved */ short ignoreBeeps, short oldScrollback, short jump, short realBlink ) /* creates a new virtual screen, and returns its number. */ { if (maxlines < VSDEFLINES) maxlines = VSDEFLINES; if (VSinuse >= VSmax) /* too many screens in existence */ return(-1); VSIwn = 0; while ((VSIwn < VSmax) && (VSscreens[VSIwn].stat == 1)) VSIwn++; if (VSIwn >= VSmax) /* shouldn't occur? */ return(-1); numLines -= 1; //correct for internal use /* * Fill initial scrollback buffer and screen storage space. * * Memory allocation rules: * line->mem == 0 if not a memory allocation, line->mem == 1 if it is the first * VSline in a block (indeterminate size, may be size == 1) * * attributes array is ALWAYS allocated as one block. Internally represented and * manipulated as a linked list of lines, but only one of the lines will have * line->mem == 1. This list is always supposed to be circular (it is never * extended, as attributes are never scrolled back). * * scrollback and screen line buffer space is allocated in large blocks. Each * block will have line->mem == 1 if the pointer to that VSline is "free"able. * This list will either be circular (which means it has reached its full size), * or it will have a NULL next field at the end. During scrolling, the end may * be augmented until VSIw->numlines > VSIw->maxlines or we run out of memory. * Typically allocate memory 100 lines at a time in two blocks, one is the VSline * list, the other is the mem for the character storage. * */ /* All memory allocation for this function is done at once, to help damage control in low memory situations */ if ((VSscreens[VSIwn].loc = VSIw = (VSscrn *) myNewPtr(sizeof(VSscrn))) == 0L) return(-2); VSIw->oldScrollback = oldScrollback; VSIw->lines = numLines; //VSIw->lines = 23; CCP 2.7 set this from the start VSIw->linest = VSInewlinearray(VSIw->lines + 1); if (VSIw->linest == NULL) { DisposePtr((Ptr)VSIw); VSscreens[VSIwn].loc = VSIw = NULL; return (-2); } if (VSIw->oldScrollback) { VSIw->attrst = (VSattrlinePtr *) VSInewlinearray(VSIw->lines + 1); if (VSIw->attrst == NULL) { DisposePtr((Ptr)VSIw->linest); DisposePtr((Ptr)VSIw); VSscreens[VSIwn].loc = VSIw = NULL; return (-2); } } VSIw->tabs = (char *) myNewPtr(132); /* NCSA: SB - allow 132 column mode */ if (VSIw->tabs == NULL) /* CCP: Hey? Why not check if we got it?! */ { DisposePtr((Ptr)VSIw->linest); DisposePtr((Ptr)VSIw); VSscreens[VSIwn].loc = VSIw = NULL; return (-2); } VSIw->allwidth = 131; /* NCSA: SB - always allocate max lines */ if (!VSIw->oldScrollback) { if (screensave) VSIw->buftop = VSInewlines(VSIw->lines + 1 + VSDEFLINES); /* screen lines plus some initial preallocated scrollback space */ else VSIw->buftop = VSInewlines(VSIw->lines + 1); /* screen lines, no scrollback */ if (VSIw->buftop == NULL) { DisposePtr((Ptr)VSIw->tabs); DisposePtr((Ptr)VSIw->linest); DisposePtr((Ptr)VSIw); VSscreens[VSIwn].loc = VSIw = NULL; return(-2); } VSIw->linest[0] = VSIw->buftop; } else { if (screensave) VSIw->buftop = VSOnewlines(VSIw->lines + 1 + VSDEFLINES,1); /* screen lines plus some initial preallocated scrollback space */ else VSIw->buftop = VSOnewlines(VSIw->lines + 1,1); /* screen lines, no scrollback */ if (VSIw->buftop == NULL) { DisposePtr((Ptr)VSIw->tabs); DisposePtr((Ptr)VSIw->attrst); DisposePtr((Ptr)VSIw->linest); DisposePtr((Ptr)VSIw); VSscreens[VSIwn].loc = VSIw = NULL; return(-2); } VSIw->linest[0] = VSIw->buftop; VSIw->attrst[0] = (VSattrlinePtr)VSOnewlines(VSIw->lines + 1,2); /* new space for attributes (these are never scrolled back) */ if (VSIw->attrst[0] == NULL) { VSIfreelinelist(VSIw->buftop); DisposePtr((Ptr)VSIw->tabs); DisposePtr((Ptr)VSIw->attrst); DisposePtr((Ptr)VSIw->linest); DisposePtr((Ptr)VSIw); VSscreens[VSIwn].loc = VSIw = NULL; return(-2); } } VSIw->vistop = VSIw->scrntop = VSIw->buftop; /* initial view = screen */ if (VSIw->oldScrollback) { VSOlistndx(VSIw->scrntop, VSIw->attrst[0]); VSIw->attrst[0]->prev = VSIw->attrst[VSIw->lines]; /* make attribute list circular, since it is never extended */ VSIw->attrst[VSIw->lines]->next = VSIw->attrst[0]; } else VSIlistndx(VSIw->scrntop); /* Set up screen arrays */ if (!screensave) { /* make text line list circular to indicate no extensions */ VSIw->linest[0]->prev = VSIw->linest[VSIw->lines]; VSIw->linest[VSIw->lines]->next = VSIw->linest[0]; } /* if */ VSIw->disableCursor = 0; // cursor may be visible (RAB BetterTelnet 2.0b4) VSIw->linesjumped = 0; // reset the jump scrolling (RAB BetterTelnet 2.0b3) VSIw->jumpScroll = jump; VSIw->maxlines = maxlines; VSIw->numlines = 0; VSscreens[VSIwn].captureRN = 0; /* BYU 2.4.18 - capture file's RefNum */ VSIw->id = 'VSCR'; VSIw->maxwidth = maxwid - 1; VSIw->savelines = screensave; VSIw->forcesave = forcesave; /* NCSA 2.5 */ VSIw->attrib = 0; VSIw->Pattrib = -1; /* initially no saved attribute */ VSIw->x = 0; VSIw->y = 0; VSIw->charset = 0; VSIw->G0 = 0; VSIw->G1 = 1; VSIw->DECAWM = 0; VSIw->DECCKM = 0; VSIw->DECPAM = 0; VSIw->DECORG = 0; VSIw->DECCM = 1; /* Bri 970610 */ VSIw->IRM = 0; VSIw->escflg = 0; VSIw->top = 0; VSIw->bottom = numLines; VSIw->parmptr = 0; VSIw->Rtop = 0; VSIw->Rleft = 0; VSIw->Rright = maxwid - 1; VSIw->Rbottom = numLines; VSIw->ESscroll = 1; VSIw->prredirect = 0; /* LU */ VSIw->qprint = 0; VSIw->ignoreBeeps = ignoreBeeps; VSIw->prbuf = 0; /* LU */ VSIw->refNum = -1; /* LU */ VSIw->possibleForce = 0; VSIw->realBlink = realBlink; VSIclrbuf(); VSItabinit(); VSscreens[VSIwn].stat = 1; VSinuse++; return(VSIwn); } /* VSnewscreen */ short VSdestroy(short w) /* screen number */ /* gets rid of a virtual screen. */ { if (VSvalids(w) != 0) return(-3); VSIfreelines(); if (VSIw->oldScrollback) { VSIfreelinelist((VSlinePtr)VSIw->attrst[0]); if (VSIw->attrst) DisposePtr((Ptr) VSIw->attrst); } if(VSIw->linest) DisposePtr((Ptr) VSIw->linest); if(VSIw->tabs) DisposePtr(VSIw->tabs); if(VSIw) DisposePtr((Ptr) VSIw); VSscreens[w].stat = 0; VSIwn = -1; VSinuse--; /* SCA '87 */ return(0); } /* VSdestroy */ // RAB BetterTelnet 2.0b4 // reallocates a virtual screen, keeping screen contents but nuking the scrollback buffer void VSrealloc(short w) { short i; VSlinePtr savedTextBlock, savedTextPtr; if (VSvalids(w) != 0) return; // save the current screen savedTextBlock = VSInewlines(VSIw->lines + 1 + VSDEFLINES); savedTextPtr = savedTextBlock; for (i = 0; i <= VSIw->lines; i++) { BlockMoveData(VSIw->linest[i]->text, savedTextPtr->text, VSIw->allwidth + 1); if (savedTextPtr->next) savedTextPtr = savedTextPtr->next; } savedTextPtr = savedTextBlock; for (i = 0; i <= VSIw->lines; i++) { if (VSIw->oldScrollback) BlockMoveData(VSIw->attrst[i]->text, savedTextPtr->attr, (VSIw->allwidth + 1) * 2); else BlockMoveData(VSIw->linest[i]->attr, savedTextPtr->attr, (VSIw->allwidth + 1) * 2); if (savedTextPtr->next) savedTextPtr = savedTextPtr->next; } // nuke the current line structures VSIfreelines(); // note: this always frees the text, but only frees the attributes if we're using // the "new" scrollback if (!VSIw->oldScrollback) { VSIw->buftop = savedTextBlock; // hey, we have a block with the right stuff anyway... VSIw->linest[0] = VSIw->buftop; VSIlistndx(VSIw->buftop); } else { VSIw->buftop = VSOnewlines(VSIw->lines + 1 + VSDEFLINES,1); /* screen lines plus some initial preallocated scrollback space */ /* if (VSIw->buftop == NULL) { DisposePtr((Ptr)VSIw->tabs); DisposePtr((Ptr)VSIw->attrst); DisposePtr((Ptr)VSIw->linest); DisposePtr((Ptr)VSIw); VSscreens[VSIwn].loc = VSIw = NULL; return(-2); } */ // we really should check for errors here, but what do we do if we find one? VSIw->linest[0] = VSIw->buftop; VSOlistndx(VSIw->buftop, VSIw->attrst[0]); VSIw->attrst[0]->prev = VSIw->attrst[VSIw->lines]; /* make attribute list circular, since it is never extended */ VSIw->attrst[VSIw->lines]->next = VSIw->attrst[0]; // we don't allocate attrst here because we already have it // we do, however, need to copy in the screen text savedTextPtr = savedTextBlock; for (i = 0; i <= VSIw->lines; i++) { BlockMoveData(savedTextPtr->text, VSIw->linest[i]->text, VSIw->allwidth + 1); if (savedTextPtr->next) savedTextPtr = savedTextPtr->next; } DisposePtr((Ptr) savedTextBlock); // VSIfreelinelist adds un-needed overhead here } VSIw->vistop = VSIw->scrntop = VSIw->buftop; VSIw->Rbottom -= VSIw->Rtop; VSIw->Rtop = 0; VSIw->numlines = 0; } void VSredrawLine(short w) //redraws current line { if (VSvalids(w) != 0) return; VSredraw(w, 0, VSIw->y,VSIw->maxwidth, VSIw->y); VSIcuroff(w); } short VSredraw ( short w, // window to redraw */ short x1, short y1, short x2, short y2 ) /* redisplays the specified portion of a virtual screen. */ { VSlinePtr ypt; short y; short tx1, tx2, ty1, ty2, tn, offset; if (VSvalids(w) != 0) return(-3); if (VSIw->oldScrollback) return VSOredraw(w, x1, y1, x2, y2); x1 += VSIw->Rleft; // Make local coords global again x2 += VSIw->Rleft; y1 += VSIw->Rtop; y2 += VSIw->Rtop; if (x1 < 0) x1 = 0; else if (x1 > VSIw->maxwidth) x1 = VSIw->maxwidth; if (x2 < 0) x2 = 0; else if (x2 > VSIw->maxwidth) x2 = VSIw->maxwidth; if (y1 < -VSIw->numlines) y1 = -VSIw->numlines; else if (y1 > VSIw->lines) y1 = VSIw->lines; if (y2 < -VSIw->numlines) y2 = -VSIw->numlines; /* limit to amount of scrollback */ else if (y2 > VSIw->lines) y2 = VSIw->lines; tx1 = x1; // Set up to clip redraw area to visible area tx2 = x2; ty1 = y1; ty2 = y2; tn = -1; // so we include more than 1 line if (VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)!=0) return 0; // test clip region VSIcuroff(w); // temporarily hide cursor RSerase(w, tx1, ty1, tx2, ty2); // Erase the offending area // draw visible part of scrollback buffer if (y1 < 0) { tx1 = x1; // Set up to clip redraw area to visible area of scrollback buffer tx2 = x2; ty1 = y1; ty2 = (y2>=0) ? -1 : y2; tn = -1; if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { ypt = VSIw->vistop; for(y=VSIw->Rtop; ynext; // Get pointer to top line we need for (y=ty1; y<=ty2; y++) { char *pt; unsigned short *pa; unsigned short lasta; short x, lastx; pt = ypt->text + VSIw->Rleft; pa = ypt->attr + VSIw->Rleft; lastx = tx1; lasta = pa[tx1]; for(x=tx1+1; x<=tx2; x++) { if (pa[x]!=lasta) { RSdraw(w, lastx, y, lasta, x-lastx, pt + lastx); lastx = x; lasta = pa[x]; } } if (lastx<=tx2) RSdraw(w, lastx, y, lasta, tx2-lastx+1, pt + lastx); ypt = ypt->next; } } y1 = 0; // continue with on-screen buffer, if any } // draw visible part of on-screen buffer, taking account of attributes if (y2 >= 0) { tx1 = x1; // Set up to clip redraw area to visible area of on-screen buffer tx2 = x2; ty1 = y1; ty2 = y2; tn = -1; if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { ypt = VSIw->linest[VSIw->Rtop+ty1]; for (y=ty1; y<=ty2; y++) { char *pt; unsigned short *pa; unsigned short lasta; short x, lastx; pt = ypt->text + VSIw->Rleft; pa = ypt->attr + VSIw->Rleft; lastx = tx1; lasta = pa[tx1]; for(x=tx1+1; x<=tx2; x++) { if (pa[x]!=lasta) { RSdraw(w, lastx, y, lasta, x-lastx, pt + lastx); lastx = x; lasta = pa[x]; } } if (lastx<=tx2) RSdraw(w, lastx, y, lasta, tx2-lastx+1, pt + lastx); ypt = ypt->next; } } } VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ tx1 = ty1 = 0; tn = 132; return(0); } /* VSredraw */ short VSOredraw ( short w, // window to redraw */ short x1, short y1, short x2, short y2 ) /* redisplays the specified portion of a virtual screen. */ { VSlinePtr ypt; VSattrlinePtr ypa; short y; short tx1, tx2, ty1, ty2, tn, offset; if (VSvalids(w) != 0) return(-3); x1 += VSIw->Rleft; // Make local coords global again x2 += VSIw->Rleft; y1 += VSIw->Rtop; y2 += VSIw->Rtop; if (x1 < 0) x1 = 0; else if (x1 > VSIw->maxwidth) x1 = VSIw->maxwidth; if (x2 < 0) x2 = 0; else if (x2 > VSIw->maxwidth) x2 = VSIw->maxwidth; if (y1 < -VSIw->numlines) y1 = -VSIw->numlines; else if (y1 > VSIw->lines) y1 = VSIw->lines; if (y2 < -VSIw->numlines) y2 = -VSIw->numlines; /* limit to amount of scrollback */ else if (y2 > VSIw->lines) y2 = VSIw->lines; tx1 = x1; // Set up to clip redraw area to visible area tx2 = x2; ty1 = y1; ty2 = y2; tn = -1; // so we include more than 1 line if (VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)!=0) return 0; // test clip region VSIcuroff(w); // temporarily hide cursor RSerase(w, tx1, ty1, tx2, ty2); // Erase the offending area // draw visible part of scrollback buffer if (y1 < 0) { tx1 = x1; // Set up to clip redraw area to visible area of scrollback buffer tx2 = x2; ty1 = y1; ty2 = (y2>=0) ? -1 : y2; tn = -1; if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { ypt = VSIw->vistop; for(y=VSIw->Rtop; ynext; // Get pointer to top line we need for (y=ty1; y<=ty2; y++) { RSdraw(w, tx1, y, 0, tn, ypt->text + VSIw->Rleft +tx1); ypt = ypt->next; } } y1 = 0; // continue with on-screen buffer, if any } // draw visible part of on-screen buffer, taking account of attributes if (y2 >= 0) { tx1 = x1; // Set up to clip redraw area to visible area of on-screen buffer tx2 = x2; ty1 = y1; ty2 = y2; tn = -1; if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { ypt = VSIw->linest[VSIw->Rtop+ty1]; ypa = VSIw->attrst[VSIw->Rtop+ty1]; for (y=ty1; y<=ty2; y++) { char *pt; unsigned short *pa; unsigned short lasta; short x, lastx; pt = ypt->text + VSIw->Rleft; pa = ypa->text + VSIw->Rleft; lastx = tx1; lasta = pa[tx1]; for(x=tx1+1; x<=tx2; x++) { if (pa[x]!=lasta) { RSdraw(w, lastx, y, lasta, x-lastx, pt + lastx); lastx = x; lasta = pa[x]; } } if (lastx<=tx2) RSdraw(w, lastx, y, lasta, tx2-lastx+1, pt + lastx); ypt = ypt->next; ypa = ypa->next; } } } VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ tx1 = ty1 = 0; tn = 132; return(0); } /* VSOredraw */ short VSwrite ( short w, /* screen to draw into */ char *ptr, /* pointer to text string */ short len /* length of text string */ ) /* sends a stream of characters to the specified window. */ { // _profile = 1; if (len == 0) return 0; if (VSvalids(w) != 0) return(-3); VSIcuroff(w); /* hide cursor momentarily */ VSIcursdisable(); // RAB BetterTelnet 2.0b4 VSem((unsigned char *) ptr, len); /* BYU LSC - interpret the character stream */ VSIflush(); // RAB BetterTelnet 2.0b3 VSIcursenable(); VSIcurson(w, VSIw->x, VSIw->y, 1); /* restore cursor, force it to be visible. */ // _profile = 0; return(0); } /* VSwrite */ // RAB BetterTelnet 2.0b3 // The same VSwrite you know and love, except it doesn't flush. // This is for parse() to use so it doesn't flush every time it hits an escape. short VSwritefast ( short w, /* screen to draw into */ char *ptr, /* pointer to text string */ short len /* length of text string */ ) /* sends a stream of characters to the specified window. */ { // _profile = 1; if (len == 0) return 0; if (VSvalids(w) != 0) return(-3); VSIcuroff(w); /* hide cursor momentarily */ VSIcursdisable(); VSem((unsigned char *) ptr, len); /* BYU LSC - interpret the character stream */ // We don't show the cursor again here because it interferes with the screen refresh. // Anything that calls VSfastwrite() is supposed to call VSflushwrite() anyway once it's done. // _profile = 0; return(0); } /* VSwrite */ // RAB BetterTelnet 2.0b3 - interface to VSIflush() which shows the cursor once // the screen has been flushed void VSflushwrite(short w) { if (VSvalids(w) != 0) return; VSIflush(); VSIcursenable(); VSIcurson(w, VSIw->x, VSIw->y, 1); } // Utility routine: BetterTelnet 1.0fc3 (RAB) void VSsetprintmode(short w, short printMode) { if (VSvalids(w) != 0) return; VSIw->qprint = printMode; if (!printMode) { VSIw->prredirect = VSIw->printqueued; VSprOFF(); } VSIw->printqueued = 0; } short VSIgetNextTabDistance(void) { short current; if (VSIw->x >= VSIw->maxwidth) return(0); current = VSIw->x + 1; while ((VSIw->tabs[current] != 'x')&&(current < VSIw->maxwidth)) current++; return (current - VSIw->x); } // MAT--We need to define how big the Queue is // MAT--for sending the cursor characters. // MAT--Since MacTCP doesn't like 30+ individual #define MATSbufSize 254 // MAT--SendChar requests. void VSpossendEM // MAT--we can change this to support EMACS ( // MAT--style movement commands. short w, /* affected screen */ // MAT-- short x, /* column to move to */ // MAT-- short y, /* line to move to */ // MAT-- short echo /* local echo flag */ // MAT-- ) // MAT-- /* sends a stream of VT100 cursor-movement sequences to move the // MAT-- cursor on the specified screen to the specified position. */ // MAT-- { // MAT-- UNUSED_ARG(echo) static char // MAT-- tt[MATSbufSize] = ""; // MAT-- char curschar; // MAT-- short localCount; // MAT-- // MAT-- // MAT-- if (x < 0 || y < 0 || x > VSIw->maxwidth || y > VSIw->lines) // MAT-- return; // MAT-- /* convert x and y to relative distance to move */ // MAT-- x -= VSIw->x; // MAT-- y -= VSIw->y; // MAT-- // MAT-- curschar = '\002'; /* EMACS cursor left */ // MAT-- localCount=0; while (x < 0 && localCount < MATSbufSize) // MAT-- { // MAT-- tt[localCount] = curschar; // MAT-- x++; localCount++; // MAT-- } /* while */ // MAT-- if(localCount) RSsendstring(w, tt, localCount); // MAT-- curschar = '\016'; /* EMACS cursor down */ // MAT-- localCount=0; while (y > 0 && localCount < MATSbufSize) // MAT-- why we check to see if localCount is < MATSbufSize { // MAT-- I dont know. But If they had a window > 254 columns tt[localCount] = curschar; // MAT-- maybe it's a good idea. y--; localCount++; // MAT-- but it never hurts to be safe. } /* while */ // MAT-- if(localCount) RSsendstring(w, tt, localCount); // MAT-- curschar = '\020'; /* EMACS cursor up */ // MAT-- localCount=0; while (y < 0 && localCount < MATSbufSize) // MAT-- { // MAT-- tt[localCount] = curschar; // MAT-- y++; localCount++; // MAT-- } /* while */ // MAT-- if(localCount) RSsendstring(w, tt, localCount); // MAT-- curschar = '\006'; /* EMACS cursor right */ // MAT-- localCount=0; while (x > 0 && localCount < MATSbufSize) // MAT-- { // MAT-- tt[localCount] = curschar; // MAT-- x--; localCount++; // MAT-- } /* while */ // MAT-- if(localCount) RSsendstring(w, tt, localCount); // MAT-- // MAT-- if (0) //(note: supposed to look for "echo" here) // MAT-- { // MAT-- VSIcuroff(w); // MAT-- VSIw->x = x; // MAT-- VSIw->y = y; // MAT-- VSIcurson(w, VSIw->x, VSIw->y, 1); /* Force Move */ // MAT-- } /* if */ // MAT-- } /* VSpossendEM */ // changed comment // MAT-- void VSpossend ( short w, /* affected screen */ short x, /* column to move to */ short y, /* line to move to */ short echo /* local echo flag */ ) /* sends a stream of VT100 cursor-movement sequences to move the cursor on the specified screen to the specified position. */ { static char VSkbax[] = "\033O ", /* prefix for auxiliary code */ VSkban[] = "\033[ "; /* prefix for arrows normal */ char *vskptr; if (VSvalids(w) != 0) return; /* NCSA: SB - This would bomb before. You need to get the screens # from the translation routine before you access the record! */ if (screens[findbyVS(w)].arrowmap) { /* NCSA: SB - get the CORRECT screens # */ VSpossendEM(w,x,y,echo); // MAT-- call our cursor movement routine return; // MAT-- then exit } if (VSIw->DECPAM && VSIw->DECCKM) vskptr = VSkbax; else vskptr = VSkban; if (x < 0 || y < 0 || x > VSIw->maxwidth || y > VSIw->lines) return; /* convert x and y to relative distance to move */ x -= VSIw->x; y -= VSIw->y; vskptr[2] = 'D'; /* cursor left */ while (x < 0) { x++; RSsendstring(w, vskptr, 3); } /* while */ vskptr[2] = 'B'; /* cursor down */ while (y > 0) { y--; RSsendstring(w, vskptr, 3); } /* while */ vskptr[2] = 'A'; /* cursor up */ while (y < 0) { y++; RSsendstring(w, vskptr, 3); } /* while */ vskptr[2] = 'C'; /* cursor right */ while (x > 0) { x--; RSsendstring(w, vskptr, 3); } /* while */ if (echo) { VSIcuroff(w); VSIw->x = x; VSIw->y = y; VSIcurson(w, VSIw->x, VSIw->y, 1); /* Force Move */ } /* if */ } /* VSpossend */ char VSkbsend ( short w, /* active window */ unsigned char k, /* special key code if > 128, else ascii code */ short echo, /* local echo flag */ short shifted // RAB BetterTelnet 2.0b5 - shift key down ) /* sends the appropriate sequence for the specified key, taking due account of terminal mode settings. */ { // RAB BetterTelnet 2.0b5 - extensively rewritten // static char // VSkbkn[] = "\033O ", /* prefix for keypad normal */ // VSkbax[] = "\033O ", /* prefix for auxiliary code*/ // VSkban[] = "\033[ ", /* prefix for arrows normal */ // VSkbfn[] = "\033O ", /* prefix for function keys */ /* BYU 2.4.12 */ // VSk220[] = "\033[ ~"; /* prefix for vt220 keys */ /* BYU 2.4.12 */ char *vskptr; short vskplen; short macronum; if (VSvalids(w) != 0) return(-3); if ( screens[findbyVS(w)].arrowmap && (k <= VSLT) && (k >= VSUP) ) // MAT-- // MAT-- important...we need to check this first before { // MAT-- the next if() statement gets its hands on the string. switch (k) { // MAT-- do the mapping from arrowkeys -> EMACS ctrl keys. case VSLT: // MAT-- k = 0x02; // MAT-- ^B Question: Is there a way to find out if the option break; // MAT-- key was held down with this character? case VSRT: // MAT-- I didn't want to declare myEvent an extern k = 0x06; // MAT-- ^F (I didn't know if that was a no-no) break; // MAT-- If I can.....let me know, I want to make case VSUP: // MAT-- option-arrowkey's do useful things too k = 0x10; // MAT-- ^P break; // MAT-- checking the keymap would be a kludge here. case VSDN: // MAT-- k = 0x0e; // MAT-- ^N break; // MAT-- } /* switch k */ // MAT-- RSsendstring(w,(char *)&k,1); // MAT-- send the character return(0); // MAT-- } // MAT-- if (k < VSF10) { /* BYU 2.4.12 */ /* 7-bit ascii code -- send as is */ RSsendstring(w,(char *) &k, 1); /* BYU LSC */ return 0; // RAB BetterTelnet 2.0b5 - rest is for special keys } /* Keypad (Not Application Mode): 0-9 , - . Enter */ // was (k < VSF1) if ((k > VSLT) && (k < VSKE) && (!VSIw->DECPAM)) { // 2.0b5 - handle VSKE below RSsendstring(w, &VSIkpxlate[0][k - VSUP], 1); if (echo) VSwrite(w, &VSIkpxlate[0][k - VSUP], 1); // if (k == VSKE) // RSsendstring(w, "\012", 1); return(0); } /* if */ /* if (VSIw->DECPAM && VSIw->DECCKM) { // aux kp mode vskptr = VSkbax; vskplen = 3; vskptr[2] = VSIkpxlate[1][k - VSUP]; // BYU 2.4.12 } else if (k < VSUP) { // BYU 2.4.12 vskptr = VSk220; // BYU 2.4.12 vskplen = VSIkplen[k - VSF10]; // BYU 2.4.12 vskptr[2] = VSIkpxlate2[k - VSF10]; // BYU 2.4.12 vskptr[3] = VSIkpxlate3[k - VSF10]; // BYU 2.4.12 } else { // BYU 2.4.12 vskplen = 3; // BYU 2.4.12 if (k < VSK0) { // BYU 2.4.13 - arrow keys vskptr = VSkban; // BYU 2.4.12 if (VSIw->DECCKM) // BYU 2.4.13 vskptr[1] = 79; // BYU 2.4.13 else // BYU 2.4.13 vskptr[1] = 91; // BYU 2.4.13 } // BYU 2.4.13 else if (k < VSF1) // BYU 2.4.12 vskptr = VSkbkn; // BYU 2.4.12 else // BYU 2.4.12 vskptr = VSkbfn; // BYU 2.4.12 // BYU 2.4.12 vskptr[2] = VSIkpxlate[1][k - VSUP]; // BYU 2.4.12 } // BYU 2.4.12 RSsendstring(w, vskptr, vskplen); if (echo) VSwrite(w, vskptr, vskplen); */ // now for the new - RAB BetterTelnet 2.0b5 // first we get the number, then we mangle it depending on what other stuff is going on macronum = VSIkpnums[k - VSF10]; if ((macronum >= 20) && (macronum <= 29) && shifted) // Shift+F1-F10 macronum += 10; else if ((macronum >= 40) && (macronum <= 44) && shifted) // Shift+F11-F15 macronum += 5; else if ((macronum >= 80) && (macronum <= 83) && VSIw->DECCKM) // CKM arrows macronum += 5; else if ((k == VSKE) && !VSIw->DECPAM) // Enter (!AM) macronum++; sendmacro(&screens[findbyVS(VSIwn)], macronum); // and actually send it, the NEW way! return(0); } /* VSkbsend */ short VSreset ( short w ) /* resets virtual terminal settings to default state, clears screen and homes cursor. */ { if (VSvalids(w) != 0) return(-3); VSIcuroff(w); /* NCSA: SB -- get rid of extraneous cursor BS */ VSIreset(); /* causes cursor to disappear */ VSIcurson(w, VSIw->x, VSIw->y, 1); /* redisplay cursor at home position */ return(0); } /* VSreset */ void VSscrolright ( short w, short n /* number of columns to scroll */ ) /* moves the view of the virtual screen within its window the specified number of columns to the right. */ { short sn, lmmax; if (VSvalids(w) != 0) return; /* limit scroll amount against number of invisible columns */ lmmax = VSIw->maxwidth - (VSIw->Rright - VSIw->Rleft); if (VSIw->Rleft + n > lmmax) n = lmmax - VSIw->Rleft; /* can't scroll any further right than this */ if (n == 0) return; /* Do nothing if appropriate */ VSIcuroff(w); /* temporarily hide cursor */ VSIw->Rleft += n; /* update visible region */ VSIw->Rright += n; sn = VSIw->Rbottom - VSIw->Rtop; RSmargininfo(w, lmmax, VSIw->Rleft); /* update horizontal scroll bar */ RSdelcols(w, n); /* scroll the window contents */ VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ /* redraw newly-revealed portion of screen */ VSredraw(w, (VSIw->Rright - VSIw->Rleft) - n, 0, (VSIw->Rright - VSIw->Rleft), sn); } /* VSscrolright */ void VSscrolleft ( short w, short n /* number of columns to scroll */ ) /* moves the view of the virtual screen within its window the specified number of columns to the left. */ { short sn, lmmax; if (VSvalids(w) != 0) return; lmmax = VSIw->maxwidth - (VSIw->Rright - VSIw->Rleft); /* number of invisible columns */ if (n > VSIw->Rleft) n = VSIw->Rleft; /* can't scroll any further left than this */ if (n == 0) return; /* Do nothing if appropriate */ VSIcuroff(w); /* temporarily hide cursor */ VSIw->Rleft -= n; /* update visible region */ VSIw->Rright -= n; sn = VSIw->Rbottom - VSIw->Rtop; RSmargininfo(w, lmmax, VSIw->Rleft); /* update horizontal scroll bar */ RSinscols(w, n); /* scroll the window contents */ VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ VSredraw(w, 0, 0, n, sn); /* redraw newly-revealed portion of screen */ } /* VSscrolleft */ short VSscroltop( short w /* which window */) /* JMB 2.6 */ { /* JMB 2.6 */ if (VSvalids(w) != 0) /* JMB 2.6 */ return(-3); /* JMB 2.6 */ /* JMB 2.6 */ return(VSscrolback(w, VSIw->Rtop + VSIw->numlines)); /* can't scroll back any further than this */ } /* JMB 2.6 */ short VSscrolback ( short w, /* which window */ short in /* number of lines to scroll */ ) /* moves the view of the virtual screen within its window the specified number of lines upwards. */ { short sn, n; n = in; if (VSvalids(w) != 0) return(-3); if (VSIw->numlines < (n - VSIw->Rtop)) n = VSIw->Rtop + VSIw->numlines; /* can't scroll back any further than this */ if (n <= 0) return(0); /* Dont be scrollin' no lines.... */ VSIcuroff(w); /* temporarily hide cursor */ VSIw->Rtop = VSIw->Rtop - n; /* adjust the visible region */ VSIw->Rbottom = VSIw->Rbottom - n; /* find the line list element for the new topmost visible line */ sn = n; while (sn-- > 0) { #ifdef DEBUGMAC if (VSIw->vistop->prev == 0L) DebugStr("\pVSscrolback -- something wrong with linked list structure"); #endif DEBUGMAC VSIw->vistop = VSIw->vistop->prev; } /* while */ sn = VSIw->Rbottom - VSIw->Rtop; /* update vertical scroll bar */ RSbufinfo(w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); if (n <= VSIw->lines) { RSinslines(w, 0, sn, n, 0); /* scroll, preserving current selection */ VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ VSredraw(w, 0, 0, VSIw->maxwidth, n - 1); /* redraw newly-revealed portion */ } else { /* currently-visible contents scrolled completely off the screen-- just redraw everything */ VSredraw(w, 0, 0, VSIw->maxwidth, sn); } return(0); } /* VSscrolback */ short VSscrolforward ( short w, /* which window */ short n /* number of lines to scroll */ ) /* moves the view of the virtual screen within its window the specified number of lines downwards. */ { short sn; if (VSvalids(w) != 0) return(-3); if (n > VSIw->lines - VSIw->Rbottom) n = VSIw->lines - VSIw->Rbottom; /* can't scroll any further forward than this */ if (n <= 0) return(0); /* Dont be scrollin' no lines.... */ VSIcuroff(w); /* temporarily hide cursor */ VSIw->Rtop = n + VSIw->Rtop; /* adjust the visible region */ VSIw->Rbottom = n + VSIw->Rbottom; /* find the line list element for the new topmost visible line */ sn = n; while (sn-- > 0) { #ifdef DEBUGMAC if (VSIw->vistop->next == nil) DebugStr("\pVSscrolforward -- something wrong with linked list structure"); #endif DEBUGMAC VSIw->vistop = VSIw->vistop->next; } /* while */ sn = VSIw->Rbottom - VSIw->Rtop; /* update vertical scroll bar */ RSbufinfo(w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); if (n <= VSIw->lines) { RSdellines(w, 0, sn, n, 0); /* scroll, preserving current selection */ VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ VSredraw(w, 0, (sn + 1) - n, VSIw->maxwidth, sn); /* redraw newly-revealed portion */ } /* if */ else { /* currently-visible contents scrolled completely off the screen-- just redraw everything */ VSredraw(w, 0, 0, VSIw->maxwidth, sn); } return(0); } /* VSscrolforward */ short VSsetrgn ( short w, short x1, /* leftmost column */ short y1, /* uppermost line */ short x2, /* rightmost column */ short y2 /* bottommost line */ ) /* sets the visible region for the specified virtual screen in its window, scrolling its contents as appropriate. Assumes that either the vertical bounds or the height of the region has changed, but not both, and similarly that the horizontal bounds or the width has changed, but not both. */ { short n; if (VSvalids(w) != 0) return(-3); VSIw->Rbottom = VSIw->Rtop + (y2 - y1); /* make change in height of visible region first */ if (x2 > VSIw->maxwidth) { /* trying to make columns visible which aren't there-- adjust the left and right boundaries to avoid this */ n = x2 - VSIw->maxwidth; /* how far to adjust to the left */ if (n > x1) n = x1; /* but I'd rather have unused columns on the right than on the left */ x1 -= n; /* Adjust left */ x2 -= n; /* Adjust right */ } /* if */ if (VSIw->Rleft != x1) { /* left margin changed -- scroll horizontally */ /* (assume width of region hasn't also changed) */ n = x1 - VSIw->Rleft; if (n > 0) VSscrolright(w, n); else VSscrolleft(w, -n); } else /* just update horizontal scroll bar limits for new width of visible region */ RSmargininfo(w, VSIw->maxwidth - (x2 - x1), x1); VSIw->Rleft = x1; VSIw->Rright = x2; if (VSIw->Rbottom > VSIw->lines) /* don't scroll off the bottom of the screen */ n = VSIw->Rbottom - VSIw->lines; else /* scroll to new topmost line as specified */ n = VSIw->Rtop - y1; if (n != 0) /* scroll vertically (assume height of region hasn't also changed) */ if (n > 0) VSscrolback(w, n); else VSscrolforward(w, -n); else /* update vertical scroll bar limits for new height of visible region */ RSbufinfo(w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); return(0); } /* VSsetrgn */ short VSscrolcontrol ( short w, short scrolon, /* whether to save lines off top */ short offtop /* whether to save lines on clearing entire screen */ ) /* changes scrollback flag settings for a virtual screen. */ { if (VSvalids(w) != 0) return(-3); if (scrolon > -1) VSIw->savelines = scrolon; if (offtop > -1) VSIw->ESscroll = offtop; return(0); } /* VSscrolcontrol */ // RAB BetterTelnet 1.2 - set "ignore beeps" void VSbeepcontrol ( short w, short beep ) { if (VSvalids(w) != 0) return; VSIw->ignoreBeeps = beep; } short VSgetrgn ( short w, short *x1, short *y1, short *x2, short *y2 ) /* returns the current visible region for a virtual screen. */ { if (VSvalids(w) != 0) return(-3); *x1 = VSIw->Rleft; *y1 = VSIw->Rtop; *x2 = VSIw->Rright; *y2 = VSIw->Rbottom; return(0); } /* VSgetrgn */ short VSmaxwidth ( short w ) /* returns one less than the number of columns on a virtual screen. */ { if (VSvalids(w) != 0) return(-3); return(VSIw->maxwidth); } /* VSmaxwidth */ VSlinePtr VSIGetLineStart(short w, short y1) /* returns a pointer to the specified text line (number may be negative for a line in the scrollback buffer). */ { VSlinePtr ptr; short n; if (VSvalids(w) != 0) return((VSlinePtr) -3); if (y1 >= 0) return(VSIw->linest[y1]); n = y1 - VSIw->Rtop; /* Number of lines from VISTOP to scroll forward */ ptr = VSIw->vistop; while (n > 0) { n--; if (ptr->next) ptr = ptr->next; // sanity check here - RAB BetterTelnet 2.0b1 } /* while */ while (n < 0) { n++; if (ptr->prev) ptr = ptr->prev; // more BetterSanityChecking (tm) } /* while */ return(ptr); } /* VSIGetLineStart */ char *VSIstrcopy(char *src, short len, char *dest, short table, short noClip) /* copies characters from *src (length len) to *dest, dropping trailing blanks. If table is nonzero, then this number (or more) of consecutive embedded blanks will be replaced with a tab. Returns a pointer to the position one past the last character copied to the *dest buffer. */ { char *p, *tempp; short tblck; p = src + len - 1; /* skip trailing blanks, but only if !noClip */ if ((!noClip) || table || gApplicationPrefs->clipTrailingSpaces) // RAB BetterTelnet 1.0fc7, 1.1 while ((*p == ' ') && (p >= src)) p--; if (p < src) return(dest); if (!table) /* straight character copy */ while (src <= p) *dest++ = *src++; else /* tab-replacement copy */ while (src <= p) { while ((src <= p) && (*src != ' ')) *dest++ = *src++; if (src < p) { tempp = dest; /* remember start of run of spaces */ tblck = 0; /* length of run */ while ((src <= p) && (*src == ' ')) { *dest++ = *src++; tblck++; } /* while */ if (tblck >= table) { *tempp++ = '\011'; /* replace first space with a tab */ dest = tempp; /* drop remaining spaces */ } /* if */ } /* if */ } /* while */ return(dest); } /* VSIstrcopy */ long VSgettext(short w, short x1, short y1, short x2, short y2, char *charp, long max, char *EOLS, short table) /* copies a portion of text from the specified virtual screen into the *charp buffer. table, if nonzero, is the minimum length of runs of spaces to be replaced with single tabs. Returns the length of the copied text. max is supposed to be the maximum length to copy, but this is currently ignored! EOLS is the end-of-line sequence to insert at line boundaries. This is currently assumed to be exactly one character long. */ { UNUSED_ARG(max) /* !! */ short EOLlen; short lx,ly, /* Upper bounds of selection */ ux,uy; /* Lower bounds of selection */ short maxwid; char *origcp; VSlinePtr t; if (VSvalids(w) != 0) return(-3); EOLlen = strlen(EOLS); maxwid = VSIw->maxwidth; origcp = charp; if (y1 < -VSIw->numlines) { y1 = -VSIw->numlines; x1 = -1; } /* if */ if (y1 == y2) { /* copying no more than a single line */ t = VSIGetLineStart(w, y1); if (x1 < x2) /* Order the lower and upper bounds */ { ux = x1; uy = y1; lx = x2; ly = y2; } else { ux = x2; uy = y2; lx = x1; ly = y1; } /* if */ if ((long)(lx-ux) < max) charp=VSIstrcopy(&t->text[ux+1], lx-ux, charp, table, 1); else charp=VSIstrcopy(&t->text[ux+1], (short)(max - (long)(charp-origcp)), charp, table, 1); if (lx == maxwid) *charp++ = *EOLS; /* assumes it's only one character! */ } else { /* copying more than one line */ if (y1 < y2) /* Order the lower and upper bounds */ { ux = x1; uy = y1; lx = x2; ly = y2; } else { ux = x2; uy = y2; lx = x1; ly = y1; } /* if */ t = VSIGetLineStart(w, uy); if (((long) (maxwid-ux) < max)) charp=VSIstrcopy(&t->text[ux+1],maxwid-ux,charp,table, 0); else charp=VSIstrcopy(&t->text[ux+1],(short) (max-(long)(charp-origcp)),charp,table, 0); *charp++ = *EOLS; /* assumes it's only one character! */ uy++; if (t->next) t = t->next; // RAB BetterTelnet 2.0b1 - sanity checking while (uy < ly && uy < VSIw->lines) { if ((long)(maxwid+1) < max) charp=VSIstrcopy(t->text,maxwid+1,charp, table, 0); else charp=VSIstrcopy(t->text,(short)(max - (long) (charp-origcp)),charp, table, 0); *charp++=*EOLS; if (t->next) t=t->next; uy++; } /* while */ if (ly > VSIw->lines) lx = maxwid; if ((long) (lx+1) < max) charp=VSIstrcopy(t->text,lx+1,charp,table, 0); else charp=VSIstrcopy(t->text,(short)(max - (long)(charp-origcp)),charp,table, 0); if (lx >= maxwid) *charp++ = *EOLS; /* assumes it's only one character! */ } /* if */ return(charp - origcp); } /* VSgettext */ short VSgetnumlines ( short w ) /* returns the number of lines in the scrollback. */ { if (VSvalids(w) != 0) return(-2); return(VSIw->numlines); } /* VSgetlines */ short VSgetlines ( short w ) /* returns the number of lines in a virtual screen. */ { if (VSvalids(w) != 0) return(-2); return(VSIw->lines + 1); } /* VSgetlines */ short VSsetlines ( short w, /* window number */ short lines /* new number of lines */ ) /* sets the number of lines in a virtual screen, reallocating text and attribute arrays accordingly. Returns the new number of lines on success, or an error otherwise */ { VSlineArray linest; /* For storage of old ones */ VSlinePtr line; /* pointer to a line */ short i, j, oldlines; char *temp; unsigned short *tempa; if (VSvalids(w) != 0) return(-3000); if (VSIw->oldScrollback) return VSOsetlines(w, lines); lines -= 1; /* Correct for internal use */ oldlines = VSIw->lines; if (lines == oldlines) /* no change */ return(0); VSIw->x = 0; VSIw->y = 0; VSIcurson(w, VSIw->x, VSIw->y, 1); /* keeps cursor from pointing outside of window */ VSIw->vistop = VSIw->scrntop; /* Force view to the top of the screen */ linest = VSIw->linest; VSIw->linest = VSInewlinearray(lines + 1); /* allocate new screen buffers */ if (!VSIw->linest) { VSIw->linest = linest; /* mem problems */ return (-2000); } VSIw->lines = lines; /* set new number of screen lines */ VSIw->linest[0] = VSInewlines(lines + 1); /* allocate new text and attribute lines */ if (VSIw->linest[0]) { /* mem is there */ VSIlistndx(VSIw->linest[0]); /* build the new screen arrays */ if (VSIw->savelines) { /* save previous screen contents in scrollback buffer */ line = linest[oldlines]->next; /* save continuation */ linest[oldlines]->next = VSIw->linest[0]; VSIw->linest[lines]->next = line; /* restore continuation */ VSIw->linest[0]->prev = linest[oldlines]; /* backpointer */ if (line) /* if there was a follower */ line->prev = VSIw->linest[lines]; /* new prev for it */ VSIw->numlines += oldlines; /* we made more scrollback */ } else { /* get rid of previous screen contents */ VSIfreelinelist(linest[0]); DisposePtr((Ptr) linest); } } else { /* need more mem - emergency */ if (VSIw->linest[0]) /*if 1/2 of push for memory died, kill the other */ VSIfreelinelist(VSIw->linest[0]); /* Here we should ask if we want to lose the screen buffer!! CCP */ VSIfreelines(); /* release scrollback buffer */ VSIfreelinelist(linest[0]); /* release current visible lines */ DisposePtr((Ptr) linest); VSIw->linest[0] = VSInewlines(lines + 1); /* allocate new screen arrays */ if (!VSIw->linest[0]) { /* still not enough memory; Try to allocate just enough to go back to original size */ if (VSIw->linest[0]) /* this gets rid of useless */ VSIfreelinelist(VSIw->linest[0]); /* memory, since we are giving up */ VSIw->linest[0] = VSInewlines(oldlines + 1); /* try original size */ if (!VSIw->linest[0]) /* damage control: */ { /* Nope. Give up, and signal that */ if (VSIw->linest[0]) /* caller should kill this screen */ VSIfreelinelist(VSIw->linest[0]); /* dont destroy everything, as this will screw up VSdestroy later */ return(-4000); } else { lines = oldlines; VSIw->lines = lines; } } VSIw->buftop = VSIw->linest[0]; VSIw->numlines = 0; /* nothing in scrollback */ } /* if */ VSIw->scrntop = VSIw->linest[0]; /* new top of screen */ VSIw->vistop = VSIw->scrntop; /* Force a scroll to the top of the screen */ VSIlistndx(VSIw->scrntop); /* rebuild screen arrays */ if (!VSIw->savelines) { /* make text line list circular to indicate no extensions */ VSIw->linest[lines]->next = VSIw->linest[0]; VSIw->linest[0]->prev = VSIw->linest[lines]; } /* if */ /* initialize the new screen lines to blank text and no attributes */ for (i = 0; i <= lines; i++) { tempa = VSIw->linest[i]->attr; temp = VSIw->linest[i]->text; for (j = 0; j <= VSIw->allwidth; j++) { *temp++ = ' '; *tempa++ = 0; } /* for */ } /* for */ /* reset scrolling region */ VSIw->top = 0; VSIw->bottom = lines; /* reset visible region */ VSIw->Rtop = 0; VSIw->Rbottom = lines; VSredraw(w, 0, 0, VSIw->maxwidth, lines); /* draw new blank screen */ RSbufinfo(w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* adjust vertical scroll bar */ return(VSIw->lines); } /* VSsetlines */ short VSOsetlines ( short w, /* window number */ short lines /* new number of lines */ ) /* sets the number of lines in a virtual screen, reallocating text and attribute arrays accordingly. Returns the new number of lines on success, or an error otherwise */ { VSlineArray linest; /* For storage of old ones */ VSattrlineArray attrst; VSlinePtr line; /* pointer to a line */ short i, j, oldlines; char *temp; unsigned short *tempa; if (VSvalids(w) != 0) return(-3000); lines -= 1; /* Correct for internal use */ oldlines = VSIw->lines; if (lines == oldlines) /* no change */ return(0); VSIw->x = 0; VSIw->y = 0; VSIcurson(w, VSIw->x, VSIw->y, 1); /* keeps cursor from pointing outside of window */ VSIw->vistop = VSIw->scrntop; /* Force view to the top of the screen */ attrst = VSIw->attrst; /* save old screen arrays */ linest = VSIw->linest; VSIw->linest = VSInewlinearray(lines + 1); /* allocate new screen buffers */ if (!VSIw->linest) { VSIw->linest = linest; /* mem problems */ return (-2000); } VSIw->attrst = (VSattrlinePtr *)VSInewlinearray(lines + 1); if (!VSIw->attrst) { /* mem problems */ DisposePtr((Ptr) VSIw->linest); VSIw->linest = linest; VSIw->attrst = attrst; return (-2000); } VSIw->lines = lines; /* set new number of screen lines */ VSIw->linest[0] = VSOnewlines(lines + 1,1); /* allocate new text and attribute lines */ VSIw->attrst[0] = (VSattrlinePtr)VSOnewlines(lines + 1,2); if (VSIw->linest[0] && VSIw->attrst[0]) { /* mem is there */ /* dispose of old attribute lines */ VSIfreelinelist((VSlinePtr)attrst[0]); DisposePtr((Ptr) attrst); VSOlistndx(VSIw->linest[0],VSIw->attrst[0]); /* build the new screen arrays */ if (VSIw->savelines) { /* save previous screen contents in scrollback buffer */ line = linest[oldlines]->next; /* save continuation */ linest[oldlines]->next = VSIw->linest[0]; VSIw->linest[lines]->next = line; /* restore continuation */ VSIw->linest[0]->prev = linest[oldlines]; /* backpointer */ if (line) /* if there was a follower */ line->prev = VSIw->linest[lines]; /* new prev for it */ VSIw->numlines += oldlines; /* we made more scrollback */ } else { /* get rid of previous screen contents */ VSIfreelinelist(linest[0]); DisposePtr((Ptr) linest); } } else { /* need more mem - emergency */ if (VSIw->linest[0]) /*if 1/2 of push for memory died, kill the other */ VSIfreelinelist(VSIw->linest[0]); if (VSIw->attrst[0]) VSIfreelinelist((VSlinePtr)VSIw->attrst[0]); /* Here we should ask if we want to lose the screen buffer!! CCP */ VSIfreelines(); /* release scrollback buffer */ VSIfreelinelist(linest[0]); /* release current visible lines */ DisposePtr((Ptr) linest); VSIfreelinelist((VSlinePtr)attrst[0]); /* release current visible attrib */ DisposePtr((Ptr) attrst); VSIw->linest[0] = VSOnewlines(lines + 1,1); /* allocate new screen arrays */ VSIw->attrst[0] = (VSattrlinePtr)VSOnewlines(lines + 1,2); if (!VSIw->linest[0] || !VSIw->attrst[0]) { /* still not enough memory; Try to allocate just enough to go back to original size */ if (VSIw->linest[0]) /* this gets rid of useless */ VSIfreelinelist(VSIw->linest[0]); /* memory, since we are giving up */ if (VSIw->attrst[0]) VSIfreelinelist((VSlinePtr)VSIw->attrst[0]); VSIw->linest[0] = VSOnewlines(oldlines + 1,1); /* try original size */ VSIw->attrst[0] = (VSattrlinePtr)VSOnewlines(oldlines + 1,2); if (!VSIw->linest[0] || !VSIw->attrst[0]) /* damage control: */ { /* Nope. Give up, and signal that */ if (VSIw->linest[0]) /* caller should kill this screen */ VSIfreelinelist(VSIw->linest[0]); if (VSIw->attrst[0]) VSIfreelinelist((VSlinePtr)VSIw->attrst[0]); /* dont destroy everything, as this will screw up VSdestroy later */ return(-4000); } else { lines = oldlines; VSIw->lines = lines; } } VSIw->buftop = VSIw->linest[0]; VSIw->numlines = 0; /* nothing in scrollback */ } /* if */ VSIw->scrntop = VSIw->linest[0]; /* new top of screen */ VSIw->vistop = VSIw->scrntop; /* Force a scroll to the top of the screen */ VSOlistndx(VSIw->scrntop, VSIw->attrst[0]); /* rebuild screen arrays */ VSIw->attrst[0]->prev = VSIw->attrst[lines]; /* Make attribute list circular */ VSIw->attrst[lines]->next = VSIw->attrst[0]; if (!VSIw->savelines) { /* make text line list circular to indicate no extensions */ VSIw->linest[lines]->next = VSIw->linest[0]; VSIw->linest[0]->prev = VSIw->linest[lines]; } /* if */ /* initialize the new screen lines to blank text and no attributes */ for (i = 0; i <= lines; i++) { tempa = VSIw->attrst[i]->text; temp = VSIw->linest[i]->text; for (j = 0; j <= VSIw->allwidth; j++) { *temp++ = ' '; *tempa++ = 0; } /* for */ } /* for */ /* reset scrolling region */ VSIw->top = 0; VSIw->bottom = lines; /* reset visible region */ VSIw->Rtop = 0; VSIw->Rbottom = lines; VSOredraw(w, 0, 0, VSIw->maxwidth, lines); /* draw new blank screen */ RSbufinfo(w, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* adjust vertical scroll bar */ return(VSIw->lines); } /* VSOsetlines */ /*--------------------------------------------------------------------------*/ /* NCSA: SB - VSsetcols */ /* This allows external procedures to set the column width. Used by */ /* routines in main, to allow ARBITRARY column widths */ /*--------------------------------------------------------------------------*/ short VSsetcols(short w, short myWidth) /* NCSA: SB */ { /* NCSA: SB */ if (VSvalids(w) != 0) /* NCSA: SB */ return(-1); /* NCSA: SB */ VSIw->maxwidth = myWidth; /* NCSA: SB */ return 0; } /* NCSA: SB */ /*--------------------------------------------------------------------------*/ /* NCSA: SB - VSgetcols */ /* This returns the column width. Used by SetScreenDimensions, when */ /* the procedure needs to know the initial column width */ /*--------------------------------------------------------------------------*/ short VSgetcols(short w) /* NCSA: SB */ { /* NCSA: SB */ if (VSvalids(w) != 0) /* NCSA: SB */ return(-1); /* NCSA: SB */ return VSIw->maxwidth; /* NCSA: SB */ } /* NCSA: SB */ // BetterTelnet 2.0fc1 - integrated DJ's blinker code // DJ: VSPulseAll is an attempt to JUST do the blinkers. // VSPulseOne redraws one window with a different RS call. Still huge overkill....but oh well. short VSPulseOne(short w, short x1, short y1,short x2, short y2); void VSPulseAll(void) { short i; for(i=0; i < VSmax; i++) if ((VSscreens[i].stat == 1) && (VSscreens[i].loc->realBlink)) VSPulseOne(i, 0, 0, (VSscreens[i].loc->Rright - VSscreens[i].loc->Rleft), ( VSscreens[i].loc->Rbottom - VSscreens[i].loc->Rtop)); } short VSPulseOne ( short w, // window to redraw */ short x1, short y1, short x2, short y2 ) /* redisplays the specified portion of a virtual screen. */ { VSlinePtr ypt; VSattrlinePtr ypa; short y; short tx1, tx2, ty1, ty2, tn, offset; if (VSvalids(w) != 0) return(-3); if (VSIw->oldScrollback) return VSOPulseOne(w, x1, y1, x2, y2); // RAB x1 += VSIw->Rleft; // Make local coords global again x2 += VSIw->Rleft; y1 += VSIw->Rtop; y2 += VSIw->Rtop; if (x1 < 0) x1 = 0; else if (x1 > VSIw->maxwidth) x1 = VSIw->maxwidth; if (x2 < 0) x2 = 0; else if (x2 > VSIw->maxwidth) x2 = VSIw->maxwidth; if (y1 < -VSIw->numlines) y1 = -VSIw->numlines; else if (y1 > VSIw->lines) y1 = VSIw->lines; if (y2 < -VSIw->numlines) y2 = -VSIw->numlines; /* limit to amount of scrollback */ else if (y2 > VSIw->lines) y2 = VSIw->lines; tx1 = x1; // Set up to clip redraw area to visible area tx2 = x2; ty1 = y1; ty2 = y2; tn = -1; // so we include more than 1 line if (VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)!=0) return 0; // test clip region VSIcuroff(w); // temporarily hide cursor // RSerase(w, tx1, ty1, tx2, ty2); // Erase the offending area // Nah [DJ] (flicker) // draw visible part of scrollback buffer tx1 = x1; // Set up to clip redraw area to visible area of scrollback buffer tx2 = x2; ty1 = y1; ty2 = y2; // RAB tn = -1; // RAB BetterTelnet 2.0fc1 - DJ wrote this, but I had to revise it to cover // the "new" attributes-in-scrollback scenario if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { ypt = VSIw->vistop; for(y=VSIw->Rtop; ynext; // Get pointer to top line we need for (y=ty1; y<=ty2; y++) { char *pt; unsigned short *pa; unsigned short lasta; short x, lastx; pt = ypt->text + VSIw->Rleft; pa = ypt->attr + VSIw->Rleft; lastx = tx1; lasta = pa[tx1]; for(x=tx1+1; x<=tx2; x++) { if (pa[x]!=lasta && VSisblnk(lasta)) { // Ahah! [DJ] RSa = 0; // RAB - shouldn't be necessary, but... RSdraw(w, lastx, y, lasta, x-lastx, pt + lastx); lastx = x; lasta = pa[x]; } } if (lastx<=tx2 && VSisblnk(lasta)) { // Ditto [DJ] RSa = 0; RSdraw(w, lastx, y, lasta, tx2-lastx+1, pt + lastx); } ypt = ypt->next; } } VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ tx1 = ty1 = 0; tn = 132; return(0); } short VSOPulseOne ( short w, // window to redraw */ short x1, short y1, short x2, short y2 ) /* redisplays the specified portion of a virtual screen. */ { VSlinePtr ypt; VSattrlinePtr ypa; short y; short tx1, tx2, ty1, ty2, tn, offset; if (VSvalids(w) != 0) return(-3); x1 += VSIw->Rleft; // Make local coords global again x2 += VSIw->Rleft; y1 += VSIw->Rtop; y2 += VSIw->Rtop; if (x1 < 0) x1 = 0; else if (x1 > VSIw->maxwidth) x1 = VSIw->maxwidth; if (x2 < 0) x2 = 0; else if (x2 > VSIw->maxwidth) x2 = VSIw->maxwidth; if (y1 < -VSIw->numlines) y1 = -VSIw->numlines; else if (y1 > VSIw->lines) y1 = VSIw->lines; if (y2 < -VSIw->numlines) y2 = -VSIw->numlines; /* limit to amount of scrollback */ else if (y2 > VSIw->lines) y2 = VSIw->lines; tx1 = x1; // Set up to clip redraw area to visible area tx2 = x2; ty1 = y1; ty2 = y2; tn = -1; // so we include more than 1 line if (VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)!=0) return 0; // test clip region VSIcuroff(w); // temporarily hide cursor // RSerase(w, tx1, ty1, tx2, ty2); // Erase the offending area // Nah [DJ] (flicker) /* // draw visible part of scrollback buffer if (y1 < 0) { tx1 = x1; // Set up to clip redraw area to visible area of scrollback buffer tx2 = x2; ty1 = y1; ty2 = (y2>=0) ? -1 : y2; tn = -1; if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { ypt = VSIw->vistop; for(y=VSIw->Rtop; ynext; // Get pointer to top line we need for (y=ty1; y<=ty2; y++) { RSdraw(w, tx1, y, 0, tn, ypt->text + VSIw->Rleft +tx1); ypt = ypt->next; } } y1 = 0; // continue with on-screen buffer, if any } */ if(y1<0) y1=0; // draw visible part of on-screen buffer, taking account of attributes if (y2 >= 0) { tx1 = x1; // Set up to clip redraw area to visible area of on-screen buffer tx2 = x2; ty1 = y1; ty2 = y2; tn = -1; if (!VSIclip(&tx1, &ty1, &tx2, &ty2, &tn, &offset)) { ypt = VSIw->linest[VSIw->Rtop+ty1]; ypa = VSIw->attrst[VSIw->Rtop+ty1]; for (y=ty1; y<=ty2; y++) { char *pt; unsigned short *pa; unsigned short lasta; short x, lastx; pt = ypt->text + VSIw->Rleft; pa = ypa->text + VSIw->Rleft; lastx = tx1; lasta = pa[tx1]; for(x=tx1+1; x<=tx2; x++) { if (pa[x]!=lasta && VSisblnk(lasta)) { // Ahah! [DJ] RSa = 0; RSdraw(w, lastx, y, lasta, x-lastx, pt + lastx); lastx = x; lasta = pa[x]; } } if (lastx<=tx2 && VSisblnk(lasta)) { // Ditto [DJ] RSa = 0; RSdraw(w, lastx, y, lasta, tx2-lastx+1, pt + lastx); } ypt = ypt->next; ypa = ypa->next; } } } VSIcurson(w, VSIw->x, VSIw->y, 0); /* restore cursor at original position */ tx1 = ty1 = 0; tn = 132; return(0); } \ No newline at end of file diff --git a/source/Screens/vsinterf.proto.h b/source/Screens/vsinterf.proto.h index 82245cb..552b6f4 100755 --- a/source/Screens/vsinterf.proto.h +++ b/source/Screens/vsinterf.proto.h @@ -1 +1 @@ - /* vsinterf.c */ short VSinit(short max); short VSiscapturing(short w); short VSisprinting(short w); void ClosePrintingFile(short w); Boolean VSopencapture(short scrn_num, short w); void VSclosecapture(short w); void VScapture(unsigned char *ptr, short len); short VSvalids(short w); VSscrn *VSwhereis(short i); void VSIclrbuf(void); short VSnewscreen(short maxlines, short screensave, short numLines, short maxwid, short forcesave, short ignoreBeeps, short oldScrollback); short VSdestroy(short w); short VSredraw(short w, short x1, short y1, short x2, short y2); short VSOredraw(short, short, short, short, short); short VSwrite(short w, char *ptr, short len); void VSsetprintmode(short, short); short VSclear(short w); void VSpossendEM(short w, short x, short y, short echo); void VSpossend(short w, short x, short y, short echo); char VSkbsend(short w, unsigned char k, short echo); short VSclearall(short w); short VSreset(short w); char *VSgetline(short w, short y); void VSscrolright(short w, short n); void VSredrawLine(short w); void VSscrolleft(short w, short n); short VSscroltop(short w); short VSscrolback(short w, short in); short VSscrolforward(short w, short n); short VSsetrgn(short w, short x1, short y1, short x2, short y2); short VSscrolcontrol(short w, short scrolon, short offtop); void VSbeepcontrol(short, short); short VSgetrgn(short w, short *x1, short *y1, short *x2, short *y2); short VSsnapshot(short w); short VSmaxwidth(short w); VSlinePtr VSIGetLineStart(short w, short y1); char *VSIstrcopy(char*, short, char*, short, short); long VSgettext(short w, short x1, short y1, short x2, short y2, char *charp, long max, char *EOLS, short table); short VSgetlines(short w); short VSsetlines(short w, short lines); short VSOsetlines(short, short); short VSsetcols(short w, short myWidth); short VSgetcols(short w); short VSIgetNextTabDistance(void); \ No newline at end of file + /* vsinterf.c */ short VSinit(short max); short VSiscapturing(short w); short VSisprinting(short w); void ClosePrintingFile(short w); Boolean VSopencapture(short scrn_num, short w); void VSclosecapture(short w); void VScapture(unsigned char *ptr, short len); short VSvalids(short w); VSscrn *VSwhereis(short i); void VSIclrbuf(void); short VSnewscreen(short maxlines, short screensave, short numLines, short maxwid, short forcesave, short ignoreBeeps, short oldScrollback, short jump, short blink); short VSdestroy(short w); short VSredraw(short w, short x1, short y1, short x2, short y2); short VSOredraw(short, short, short, short, short); short VSwrite(short w, char *ptr, short len); short VSwritefast(short w, char *ptr, short len); void VSsetprintmode(short, short); short VSclear(short w); void VSpossendEM(short w, short x, short y, short echo); void VSpossend(short w, short x, short y, short echo); char VSkbsend(short w, unsigned char k, short echo, short blah); short VSclearall(short w); short VSreset(short w); char *VSgetline(short w, short y); void VSscrolright(short w, short n); void VSredrawLine(short w); void VSscrolleft(short w, short n); short VSscroltop(short w); short VSscrolback(short w, short in); short VSscrolforward(short w, short n); short VSsetrgn(short w, short x1, short y1, short x2, short y2); short VSscrolcontrol(short w, short scrolon, short offtop); void VSbeepcontrol(short, short); short VSgetrgn(short w, short *x1, short *y1, short *x2, short *y2); short VSsnapshot(short w); short VSmaxwidth(short w); VSlinePtr VSIGetLineStart(short w, short y1); char *VSIstrcopy(char*, short, char*, short, short); long VSgettext(short w, short x1, short y1, short x2, short y2, char *charp, long max, char *EOLS, short table); short VSgetlines(short w); short VSgetnumlines(short w); short VSsetlines(short w, short lines); short VSOsetlines(short, short); short VSsetcols(short w, short myWidth); short VSgetcols(short w); short VSIgetNextTabDistance(void); void VSflushwrite(short w); void VSrealloc(short); void VSPulseAll(void); short VSPulseOne(short, short, short, short, short); short VSOPulseOne(short, short, short, short, short); \ No newline at end of file diff --git a/source/Screens/vsintern.c b/source/Screens/vsintern.c index 2376d12..3c31df6 100755 --- a/source/Screens/vsintern.c +++ b/source/Screens/vsintern.c @@ -1 +1 @@ -/* * * Virtual Screen Kernel Internal Routines * (vsintern.c) * National Center for Supercomputing Applications * * by Gaige B. Paulsen * * This file contains the private internal calls for the NCSA * Virtual Screen Kernel. * * Version Date Notes * ------- ------ --------------------------------------------------- * 0.01 861102 Initial coding -GBP * 0.50 861113 First compiled edition -GBP * 0.70 861114 Internal operation confirmed -GBP * 2.1 871130 NCSA Telnet 2.1 -GBP * 2.2 880715 NCSA Telnet 2.2 -GBP */ #ifdef MPW #pragma segment VS #endif #include "vsdata.h" #include "vskeys.h" #include "vsinterf.proto.h" #include "rsmac.proto.h" #include "rsinterf.proto.h" #include "maclook.proto.h" #include "wind.h" #define ScrollbackQuantum 100 #define VSIclrattrib 0 #include "vsintern.proto.h" extern short TempItemsVRefNum; extern long TempItemsDirID; extern WindRec *screens; short VSIclip ( short *x1, /* starting column */ short *y1, /* line on which to draw (assumed to lie within visible region) */ short *x2, /* ending column (inclusive) (output if *n >= 0) */ short *y2, /* ending line (inclusive) (output if *n >= 0) */ short *n, /* length of text to draw (input and output) */ short *offset /* length of initial part of text to skip (output) */ ) /* clips a text string to the visible region, given the starting line and column in screen coordinates at which it is to be drawn. If the length of the string is given, will also compute the ending line and column. On return, these coordinates will be normalized to the current visible region. Returns a nonzero function result iff the string is completely invisible. */ { if (*n >= 0) { /* compute ending line and column (inclusive) */ *x2 = *x1 + *n - 1; *y2 = *y1; } /* else take these as given */ if ((*x1 > VSIw->Rright) || (*y2 < VSIw->Rtop)) return (-1); /* nothing to draw */ if (*x2 > VSIw->Rright) *x2 = VSIw->Rright; if (*y2 > VSIw->Rbottom) *y2 = VSIw->Rbottom; /* normalize x1, x2, y1, y2 to be relative to current visible region */ *x1 -= VSIw->Rleft; *x2 -= VSIw->Rleft; *y1 -= VSIw->Rtop; *y2 -= VSIw->Rtop; /* clip part of text string lying outside region, if any */ *offset = - *x1; if (*offset < 0) *offset = 0; /* text string starts within region--nothing to clip */ /* don't draw anything outside region */ if (*x1 < 0) *x1 = 0; if (*y1 < 0) *y1 = 0; *n = *x2 - *x1 + 1 ; /* length of string to draw (assuming it's all on one line) */ if ((*n <= 0) || (*y2 - *y1 < 0)) return (-1); /* nothing to draw */ return (0); } /* VSIclip */ short VSIcdellines(short w, short top, short bottom, short n, short scrolled) /* -ve => cancel current selection, if any; +ve => selection has moved up one line; 0 => don't touch selection */ /* updates the display to indicate deletion of the specified number of lines from the top of the specified region. Returns 0 iff any part of the change is visible. */ { short x1 = 0, x2 = VSIw->maxwidth, tn = -1, offset; if (VSIclip(&x1, &top, &x2, &bottom, &tn, &offset)) return(-1); /* affected region is invisible */ tn = bottom - top; if (tn < n) n = tn; /* don't bother scrolling more lines than scrolling region holds */ RSdellines(w, top, bottom, n, scrolled); return(0); /* I delete the whole thing! */ } /* VSIcdellines */ short VSIcinslines(short w, short top, short bottom, short n, short scrolled) /* -ve <=> cancel current selection, if any */ /* updates the display to indicate insertion of the specified number of blank lines at the top of the specified region. Returns 0 iff any part of the change is visible. */ { short x1 = 0, x2 = VSIw->maxwidth, tn = -1, offset; if (VSIclip(&x1, &top, &x2, &bottom, &tn, &offset)) return -1; /* affected region is invisible */ tn = bottom - top; if (tn < n) n = tn; /* don't bother scrolling more lines than scrolling region holds */ RSinslines(w, top, bottom, n, scrolled); return 0; } /* VSIcinslines */ void VSIcurson ( short w, short x, short y, short ForceMove ) /* displays the text cursor at the specified position. If ForceMove is true, I am to do any appropriate scrolling of the display to ensure the cursor is within the visible region. Assumes cursor isn't currently being shown. */ { short x2, y2, n = 1, offset; if (!VSIw->DECCM) return; // Bri 970610 if (!VSIclip(&x, &y, &x2, &y2, &n, &offset)) /* cursor already lies within visible region */ RScurson(w, x, y); /* just make it visible */ else if (ForceMove) { /* scroll to make cursor visible */ x2 = VSIw->Rbottom - VSIw->Rtop; if (x2 >= VSIw->lines) /* visible region is big enough to show entire screen-- make sure I don't scroll off the bottom of the screen. This call will also do any appropriate scrolling and redisplaying of the cursor. */ VSsetrgn(VSIwn, VSIw->Rleft, VSIw->lines - x2, VSIw->Rright, VSIw->lines); else { /* x & y have been normalized relative to left & top of current visible region. Just call the appropriate scroll routine, which will also redisplay the cursor. */ if (y > 0) VSscrolforward(VSIwn, y); else VSscrolback(VSIwn, -y); } /* if */ } /* if */ } /* VSIcurson */ void VSIcuroff ( short w ) /* hides the cursor for the specified screen. Assumes it is currently being shown (or that it's on an invisible part of the screen). */ { short x = VSIw->x, y = VSIw->y, x2, y2, n = 1, offset; if (!VSIclip(&x, &y, &x2, &y2, &n, &offset) || !VSIw->DECCM) // Bri 970610 /* cursor is on visible part of screen */ RScursoff(w); } /* VSIcuroff */ short VSIcursorvisible /* BYU 2.4.12 */ ( /* BYU 2.4.12 */ void /* BYU 2.4.12 */ ) /* BYU 2.4.12 */ { /* BYU 2.4.12 */ short /* BYU 2.4.12 */ x = VSIw->x, /* BYU 2.4.12 */ y = VSIw->y, /* BYU 2.4.12 */ x2, /* BYU 2.4.12 */ y2, /* BYU 2.4.12 */ n = 1, /* BYU 2.4.12 */ offset; /* BYU 2.4.12 */ if (!VSIw->DECCM) return 0; // Bri 970610 /* BYU 2.4.12 */ if (!VSIclip(&x, &y, &x2, &y2, &n, &offset)) /* BYU 2.4.12 */ return 1; /* BYU 2.4.12 */ else /* BYU 2.4.12 */ return 0; /* BYU 2.4.12 */ } /* BYU 2.4.12 */ VSlineArray VSInewlinearray ( short nrlines ) /* allocates an array to hold the specified number of pointers to line elements. */ { return (VSlineArray) myNewPtrCritical(sizeof(VSlinePtr) * nrlines); } /* VSInewlinearray */ VSlinePtr VSInewlines ( short nlines ) /* allocates a doubly-linked list of the specified number of line elements, and returns a pointer to the head of the list, or NULL if ran out of memory. The maximum number of characters each line can hold is controlled by VSIw->allwidth. */ { void* memoryPtr; VSlinePtr linePtr; char* textPtr; unsigned short* attrPtr; long width; long i; /* Allocated one large block that will be broken up as follows: +---------+-------+-------+ | VSlines | texts | attrs | +---------+-------+-------+ This way, we can save tons of time allocating and deallocating memory from the system. BCS 970726 */ width = VSIw->allwidth + 1; memoryPtr = myNewPtrCritical(nlines * (sizeof(VSline) + (width * 3))); if(memoryPtr == NULL) return (VSlinePtr)NULL; // Chop the memory up into its 3 chunks. linePtr = (VSlinePtr)memoryPtr; textPtr = (char*)(linePtr + nlines); attrPtr = (unsigned short*)(textPtr + (nlines * width)); // Loop through the elements, initializing each one. for(i = 0; i < nlines; i++) { linePtr->mem = 0; linePtr->text = textPtr; linePtr->attr = attrPtr; linePtr->prev = linePtr - 1; linePtr->next = linePtr + 1; linePtr++; textPtr += width; attrPtr += width; } // Flag the first line as the free element. // This seems really strange; should be fixed (BCS) ((VSline*)memoryPtr)->mem = 1; // Terminate the beginning and end nodes in the list. ((VSline*)memoryPtr)->prev = NULL; (linePtr-1)->next = NULL; // Return the head. return (VSline*)memoryPtr; } /* VSInewlines */ VSlinePtr VSOnewlines ( short nlines, short elementSize //CCP 2.7 ) /* allocates a doubly-linked list of the specified number of line elements, and returns a pointer to the head of the list, or nil if ran out of memory. The maximum number of characters each line can hold is controlled by VSIw->allwidth. */ { VSlinePtr t2; char *t; register short i; /* allocate one block for the line list elements, and another block for the line contents. These blocks will be divided up and appropriate flags set so I will be able to call DisposPtr the right number of times, with the right arguments. */ if ((t = myNewPtrCritical(nlines * (VSIw->allwidth + 1)*elementSize)) != 0L) { if ((t2 = (VSlinePtr) myNewPtrCritical(nlines * sizeof(VSline))) != 0L) t2->text = t; else { /* clean up gracefully before giving up */ DisposPtr(t); return(0L); } /* if */ } else /* sorree no memoree */ return((VSlinePtr) 0L); /* * indicate to the free routine that the first record is the one to free. */ t2->mem = 1; /* call DisposPtr on this one */ t2->next = t2 + 1; /* point to next one */ /* * Take our allocation for multiple lines and fill in the structures to * point to the right text fields and connect the doubly-linked chain. * */ for (i = 1; i < nlines; i++) { t += (VSIw->allwidth + 1)* elementSize; /* inc to next text space for a line */ t2[i].mem = 0; /* don't DisposPtr any of these */ t2[i].text = t; t2[i].prev = t2 + i - 1; /* point back one */ t2[i].next = t2 + i + 1; /* point forward one */ } /* for */ t2[0].prev = 0L; /* first one has no prev yet */ t2[nlines - 1].next = 0L; /* last one has no next yet */ return(t2); } /* VSOnewlines */ void VSIlistndx ( register VSlinePtr ts ) /* sets up the screen arrays for the current screen to point at the given lists of attribute and text lines. */ { register short i; for (i = 0; i <= VSIw->lines; i++) { VSIw->linest[i] = ts; ts = ts->next; } /* for */ } /* VSIlistndx */ void VSOlistndx ( register VSlinePtr ts, register VSattrlinePtr as ) /* sets up the screen arrays for the current screen to point at the given lists of attribute and text lines. */ { register short i; for (i = 0; i <= VSIw->lines; i++) { VSIw->attrst[i] = as; VSIw->linest[i] = ts; ts = ts->next; as = as->next; } /* for */ } /* VSOlistndx */ void VSIscroff ( void ) /* called to save current screen contents in scrollback buffer, if it is ordained that I should do so. This is called by VSIes (below) just before the entire screen is cleared. */ { VSlinePtr tmp; register short i, j; if ( (!VSIw->savelines) /* not saving lines */ || (VSIw->top != 0) || (VSIw->bottom != VSIw->lines) /* scrolling region isn't exactly the entire screen */ ) return; /* do nothing */ if (VSIw->oldScrollback) { VSOscroff(); return; } tmp = VSIw->linest[VSIw->lines]; /* need VSIw->lines + 1 more lines */ for (i = 0; i <= VSIw->lines; i++) { /* count off the lines in the part of the scrollback buffer below the screen (if any), to see if there's enough to hold a screenful. If the scrollback list isn't circular, then this part contains lines that have been allocated, but not yet used. If the list is circular (meaning it has reached its full size), then this is the part that is next in line for reuse. */ if (!tmp->next) { /* not enough */ j = VSIw->maxlines - VSIw->numlines - i; /* potential unallocated scrollback */ if (j > ScrollbackQuantum) j = ScrollbackQuantum; /* but don't bother allocating more than this */ if (j <= 0) { /* already reached user-specified scrollback limit-- */ /* make the list circular to indicate no more extension. */ tmp->next = VSIw->buftop; VSIw->buftop->prev = tmp; /* connect it up */ } else { /* extend the scrollback buffer to make room for another screenful */ if (j < VSIw->lines - i + 1) j = VSIw->lines - i + 1; /* need at least this many */ if ((tmp->next = VSInewlines(j)) != 0L) tmp->next->prev = tmp; /* got some space--link it up */ else { /* out of memory--no more extensions */ tmp->next = VSIw->buftop; VSIw->buftop->prev = tmp; } /* if */ } /* if */ break; /* only allocate once is enough */ } /* if */ tmp = tmp->next; /* keep counting */ } /* for */ /* * at this point, we know we have enough memory for the whole scroll. * It might be wraparound (reuse of some line elements), might not. */ for (i = 0; i <= VSIw->lines; i++) { /* push another screen line into the scrollback area */ // RAB BetterTelnet 1.2 - bug fix for bad linked list bug // What was NCSA thinking when they wrote this code, anyway? // if (VSIw->linest[i]->next == VSIw->buftop) if (VSIw->linest[VSIw->lines]->next == VSIw->buftop) VSIw->buftop = VSIw->buftop->next; /* reusing old space */ else VSIw->numlines++; /* using some new space */ VSIw->scrntop = VSIw->scrntop->next; /* move another line into the scrollback buffer */ VSIlistndx(VSIw->scrntop); /* and update screen arrays */ /* note that it's up to the caller to clear out the new screen text and attribute lines */ } /* for */ VSIw->vistop = VSIw->scrntop; RSbufinfo(VSIwn, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* update vertical scroll bar */ } /* VSIscroff */ void VSOscroff ( void ) /* called to save current screen contents in scrollback buffer, if it is ordained that I should do so. This is called by VSIes (below) just before the entire screen is cleared. */ { VSlinePtr tmp; register short i, j; if ( (!VSIw->savelines) /* not saving lines */ || (VSIw->top != 0) || (VSIw->bottom != VSIw->lines) /* scrolling region isn't exactly the entire screen */ ) return; /* do nothing */ tmp = VSIw->linest[VSIw->lines]; /* need VSIw->lines + 1 more lines */ for (i = 0; i <= VSIw->lines; i++) { /* count off the lines in the part of the scrollback buffer below the screen (if any), to see if there's enough to hold a screenful. If the scrollback list isn't circular, then this part contains lines that have been allocated, but not yet used. If the list is circular (meaning it has reached its full size), then this is the part that is next in line for reuse. */ if (!tmp->next) { /* not enough */ j = VSIw->maxlines - VSIw->numlines - i; /* potential unallocated scrollback */ if (j > ScrollbackQuantum) j = ScrollbackQuantum; /* but don't bother allocating more than this */ if (j <= 0) { /* already reached user-specified scrollback limit-- */ /* make the list circular to indicate no more extension. */ tmp->next = VSIw->buftop; VSIw->buftop->prev = tmp; /* connect it up */ } else { /* extend the scrollback buffer to make room for another screenful */ if (j < VSIw->lines - i + 1) j = VSIw->lines - i + 1; /* need at least this many */ if ((tmp->next = VSOnewlines(j,1)) != 0L) tmp->next->prev = tmp; /* got some space--link it up */ else { /* out of memory--no more extensions */ tmp->next = VSIw->buftop; VSIw->buftop->prev = tmp; } /* if */ } /* if */ break; /* only allocate once is enough */ } /* if */ tmp = tmp->next; /* keep counting */ } /* for */ /* * at this point, we know we have enough memory for the whole scroll. * It might be wraparound (reuse of some line elements), might not. */ for (i = 0; i <= VSIw->lines; i++) { /* push another screen line into the scrollback area */ // RAB BetterTelnet 1.2.1 - bug fix // if (VSIw->linest[i]->next == VSIw->buftop) if (VSIw->linest[VSIw->lines]->next == VSIw->buftop) VSIw->buftop = VSIw->buftop->next; /* reusing old space */ else VSIw->numlines++; /* using some new space */ VSIw->scrntop = VSIw->scrntop->next; /* move another line into the scrollback buffer */ VSOlistndx(VSIw->scrntop, VSIw->attrst[1]); /* and update screen arrays */ /* note that it's up to the caller to clear out the new screen text and attribute lines */ } /* for */ VSIw->vistop = VSIw->scrntop; RSbufinfo(VSIwn, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* update vertical scroll bar */ } /* VSOscroff */ void VSIelo ( short s /* line to erase, -ve => line containing cursor */ ) /* blanks out the specified line in the screen buffer. Doesn't do anything to the display. */ { char *tt; unsigned short *ta; short i; if (s < 0) s = VSIw->y; if (VSIw->oldScrollback) ta = &VSIw->attrst[s]->text[0]; else ta = &VSIw->linest[s]->attr[0]; tt = &VSIw->linest[s]->text[0]; for (i = 0; i <= VSIw->allwidth; i++) { *ta++ = VSIclrattrib; *tt++ = ' '; } /* for */ } /* VSIelo */ void VSIes ( void ) /* clears the screen, first saving its contents in the scrollback buffer if appropriate. Also updates the display. */ { short i; short x1 = 0, y1 = 0, x2 = VSIw->maxwidth, y2 = VSIw->lines, n = -1, offset; /* save screen contents in scrollback buffer, if appropriate */ if (VSIw->ESscroll) VSIscroff(); /* clear out screen buffer */ for (i = 0; i <= VSIw->lines; i++) VSIelo(i); /* update display to show what I've done */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSerase(VSIwn, x1, y1, x2, y2); VSIw->vistop = VSIw->scrntop; } /* VSIes */ void VSItabclear ( void ) /* clears all current tab settings. */ { short x = 0; while (x <= VSIw->allwidth) { VSIw->tabs[x] = ' '; x++; } /* while */ } /* VSItabclear */ void VSItabinit ( void ) /* sets tab settings to default (every 8 columns). */ { short x = 0; VSItabclear(); while (x <= VSIw->allwidth) { VSIw->tabs[x] = 'x'; x += 8; } VSIw->tabs[VSIw->allwidth] = 'x'; } /* VSItabinit */ void VSIreset ( void ) /* restores terminal mode settings to defaults and clears screen. */ { VSIw->top = 0; VSIw->bottom = VSIw->lines; VSIw->parmptr = 0; VSIw->escflg = 0; VSIw->DECAWM = 0; VSIw->DECCKM = 0; VSIw->DECPAM = 0; VSIw->DECORG = 0; /* NCSA: SB -- is this needed? */ VSIw->DECCM = 1; // Bri 970610 VSIw->Pattrib = -1; /* NCSA: SB -- is this needed? */ VSIw->IRM = 0; VSIw->attrib = 0; VSIw->x = 0; VSIw->y = 0; VSIw->charset = 0; VSIw->prbuf=0; /* LU */ if (VSIw->prredirect) { /* LU - kill redirection */ VSIw->prredirect=0; /* LU */ FSClose (VSIw->refNum); /* LU */ VSIw->refNum=-1; /* LU */ HDelete(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname); /* LU */ } /* LU */ VSIes(); VSItabinit(); } /* VSIreset */ void VSIlistmove(VSlinePtr TD, VSlinePtr BD, VSlinePtr TI, VSlinePtr BI) /* moves the lines from TD to BD inclusive from their present position to between TI and BI. Either of the latter may be nil. */ { /* unlink the lines from TD to BD */ if (TD->prev != 0L) TD->prev->next = BD->next; /* Maintain circularity */ if (BD->next != 0L) BD->next->prev = TD->prev; /* relink them between TI and BI */ TD->prev = TI; /* Place the node in its new home */ BD->next = BI; if (TI != 0L) TI->next = TD; /* Ditto prev->prev */ if (BI != 0L) BI->prev = BD; } /* VSIlistmove */ void VSIdellines ( short n, /* nr lines to delete */ short s /* starting line to delete, -ve => line containing cursor */ ) /* deletes lines from the screen, scrolling up the remainder and inserting new blank lines at the bottom of the scrolling region. */ { short i, j; char *tt; unsigned short *ta; VSlinePtr ts, TD, BD, TI, BI, itt; if (VSIw->oldScrollback) { VSOdellines(n, s); return; } if (s < 0) s = VSIw->y; if (s + n - 1 > VSIw->bottom) n = VSIw->bottom - s + 1; /* don't bother deleting more than scrolling region will hold */ /* find new tops of screen arrays */ if (s == 0 && n <= VSIw->lines) { /* element for line after last one being deleted */ ts = VSIw->linest[n]; } else { /* top line unaffected, or entire screen is being wiped */ ts = VSIw->linest[0]; } /* if */ TD = VSIw->linest[s]; /* topmost line to delete */ BD = VSIw->linest[s + n - 1]; /* bottommost line to delete */ TI = VSIw->linest[VSIw->bottom]; /* insert replacement blank lines after this line */ BI = TI->next; /* insert them before this line (might be nil) */ itt = TD; /* start of text lines to be blanked out */ /* the space taken by the deleted lines will be reused for the inserted blank lines */ if (TD != BI && TI != BD) /* insertion and deletion areas not adjacent -- move the lines to their new position */ VSIlistmove(TD, BD, TI, BI); for (i = 0; i < n; i++) { ta = itt->attr; tt = itt->text; for (j = 0; j <= VSIw->allwidth; j++) { *tt++ = ' '; *ta++ = VSIclrattrib; } /* for */ itt = itt->next; } /* for */ VSIw->scrntop = ts; /* new topmost line (if it's changed) */ /* re-sync screen arrays */ VSIlistndx(ts); if (VSIw->Rtop >= 0) /* make sure vistop still points to same line position on screen that it did before */ VSIw->vistop = VSIw->linest[VSIw->Rtop]; /* and actually display the change on-screen */ VSIcdellines(VSIwn, s, VSIw->bottom, n, -1); /* Cancel current selection */ } /* VSIdellines */ void VSOdellines ( short n, /* nr lines to delete */ short s /* starting line to delete, -ve => line containing cursor */ ) /* deletes lines from the screen, scrolling up the remainder and inserting new blank lines at the bottom of the scrolling region. */ { short i, j; char *tt; unsigned short *ta; VSlinePtr as, ts, TD, BD, TI, BI, itt, ita; if (s < 0) s = VSIw->y; if (s + n - 1 > VSIw->bottom) n = VSIw->bottom - s + 1; /* don't bother deleting more than scrolling region will hold */ /* find new tops of screen arrays */ if (s == 0 && n <= VSIw->lines) { /* element for line after last one being deleted */ ts = VSIw->linest[n]; as = (VSlinePtr)VSIw->attrst[n]; } else { /* top line unaffected, or entire screen is being wiped */ ts = VSIw->linest[0]; as = (VSlinePtr)VSIw->attrst[0]; } /* if */ TD = VSIw->linest[s]; /* topmost line to delete */ BD = VSIw->linest[s + n - 1]; /* bottommost line to delete */ TI = VSIw->linest[VSIw->bottom]; /* insert replacement blank lines after this line */ BI = TI->next; /* insert them before this line (might be nil) */ itt = TD; /* start of text lines to be blanked out */ /* the space taken by the deleted lines will be reused for the inserted blank lines */ if (TD != BI && TI != BD) /* insertion and deletion areas not adjacent -- move the lines to their new position */ VSIlistmove(TD, BD, TI, BI); TD = (VSlinePtr)VSIw->attrst[s]; /* topmost line to delete */ BD = (VSlinePtr)VSIw->attrst[s + n - 1]; /* bottommost line to delete */ TI = (VSlinePtr)VSIw->attrst[VSIw->bottom]; /* insert new lines after this one */ BI = TI->next; /* insert them before this line */ /* perform same rearrangement on attribute lines as on text lines */ if (TD != BI && TI != BD) /* insertion and deletion areas not adjacent -- move the lines to their new position */ VSIlistmove(TD, BD, TI, BI); /* blank out the newly-created replacement lines */ ita = TD; /* start of attribute lines to be blanked out */ for (i = 0; i < n; i++) { ta = ((VSattrlinePtr)ita)->text; tt = itt->text; for (j = 0; j <= VSIw->allwidth; j++) { *tt++ = ' '; *ta++ = VSIclrattrib; } /* for */ ita = ita->next; itt = itt->next; } /* for */ VSIw->scrntop = ts; /* new topmost line (if it's changed) */ /* re-sync screen arrays */ VSOlistndx(ts, (VSattrlinePtr)as); if (VSIw->Rtop >= 0) /* make sure vistop still points to same line position on screen that it did before */ VSIw->vistop = VSIw->linest[VSIw->Rtop]; /* and actually display the change on-screen */ VSIcdellines(VSIwn, s, VSIw->bottom, n, -1); /* Cancel current selection */ } /* VSOdellines */ void VSIinslines ( short n, /* how many to insert */ short s /* where to insert them, -ve => line containing cursor */ ) /* inserts the specified number of blank lines, scrolling the remaining ones down, and dropping off any that fall off the end of the scrolling region. */ { short i, j; char *tt; unsigned short *ta; VSlinePtr ts, TD, BD, TI, BI, itt; if (VSIw->oldScrollback) { VSOinslines(n, s); return; } if (s < 0) s = VSIw->y; if (s + n - 1 > VSIw->bottom) /* don't bother inserting more than scrolling region can hold */ n = VSIw->bottom - s + 1; /* find new tops of screen arrays */ if (s == 0 && n <= VSIw->lines) { /* element for first blank line being inserted */ ts = VSIw->linest[VSIw->bottom - n + 1]; } else { /* top line unaffected, or entire screen is being wiped */ ts = VSIw->linest[0]; } /* if */ BI = VSIw->linest[s]; /* insert blank lines before this one */ TI = BI->prev; /* insert them after this one */ TD = VSIw->linest[VSIw->bottom - n + 1]; /* topmost line to delete */ BD = VSIw->linest[VSIw->bottom]; /* bottommost line to delete */ itt = TD; /* start of text lines to be blanked out */ /* the space occupied by the deleted lines will be reused for the new blank lines */ if (TD != BI && TI != BD) /* new and deleted lines not contiguous -- move the space to its new position */ VSIlistmove(TD, BD, TI, BI); /* blank out the newly-inserted lines */ for (i = 0; i < n; i++) { tt = itt->text; ta = itt->attr; for (j = 0; j <= VSIw->allwidth; j++) { *tt++ = ' '; *ta++ = VSIclrattrib; } itt = itt->next; } /* for */ VSIw->scrntop = ts; VSIlistndx(ts); /* re-sync screen arrays */ if (VSIw->Rtop >= 0) /* make sure vistop still points to same line position on screen that it did before */ VSIw->vistop = VSIw->linest[VSIw->Rtop]; /* update display to match reality */ VSIcinslines(VSIwn, s, VSIw->bottom, n, -1); /* Destroy selection area if this is called tooo */ } /* VSIinslines */ void VSOinslines ( short n, /* how many to insert */ short s /* where to insert them, -ve => line containing cursor */ ) /* inserts the specified number of blank lines, scrolling the remaining ones down, and dropping off any that fall off the end of the scrolling region. */ { short i, j; char *tt; unsigned short *ta; VSlinePtr ts, TD, BD, TI, BI, itt; VSattrlinePtr as, aTD, aBD, aTI, aBI, ita; if (s < 0) s = VSIw->y; if (s + n - 1 > VSIw->bottom) /* don't bother inserting more than scrolling region can hold */ n = VSIw->bottom - s + 1; /* find new tops of screen arrays */ if (s == 0 && n <= VSIw->lines) { /* element for first blank line being inserted */ ts = VSIw->linest[VSIw->bottom - n + 1]; as = VSIw->attrst[VSIw->bottom - n + 1]; } else { /* top line unaffected, or entire screen is being wiped */ ts = VSIw->linest[0]; as = VSIw->attrst[0]; } /* if */ BI = VSIw->linest[s]; /* insert blank lines before this one */ TI = BI->prev; /* insert them after this one */ TD = VSIw->linest[VSIw->bottom - n + 1]; /* topmost line to delete */ BD = VSIw->linest[VSIw->bottom]; /* bottommost line to delete */ itt = TD; /* start of text lines to be blanked out */ /* the space occupied by the deleted lines will be reused for the new blank lines */ if (TD != BI && TI != BD) /* new and deleted lines not contiguous -- move the space to its new position */ VSIlistmove(TD, BD, TI, BI); aBI = VSIw->attrst[s]; /* insert new lines before this one */ aTI = aBI->prev; /* insert them after this one */ aTD = VSIw->attrst[VSIw->bottom - n + 1]; /* topmost line to delete */ aBD = VSIw->attrst[VSIw->bottom]; /* bottommost line to delete */ /* do the same rearrangement on the attribute lines */ if (aTD != aBI && aTI != aBD) /* new and deleted lines not contiguous -- move the space to its new position */ VSIlistmove((VSlinePtr)aTD, (VSlinePtr)aBD, (VSlinePtr)aTI, (VSlinePtr)aBI); /* blank out the newly-inserted lines */ ita = aTD; /* start of attribute lines to be blanked out */ for (i = 0; i < n; i++) { tt = itt->text; ta = ita->text; for (j = 0; j <= VSIw->allwidth; j++) { *tt++ = ' '; *ta++ = VSIclrattrib; } itt = itt->next; ita = ita->next; } /* for */ VSIw->scrntop = ts; VSOlistndx(ts, as); /* re-sync screen arrays */ if (VSIw->Rtop >= 0) /* make sure vistop still points to same line position on screen that it did before */ VSIw->vistop = VSIw->linest[VSIw->Rtop]; /* update display to match reality */ VSIcinslines(VSIwn, s, VSIw->bottom, n, -1); /* Destroy selection area if this is called tooo */ } /* VSOinslines */ void VSIscroll ( void ) /* scrolls scrolling region up one line. */ { register char *temp; register unsigned short *tempa; static VSlinePtr tmp, tmp2, tmp3, tmp4; register short i; short theBottom; /* NCSA 2.5: the correct screen bottom */ if (VSIw->y > VSIw->lines) /* BYU - replaces BYU modification below */ return; /* BYU */ if (VSIw->oldScrollback) { VSOscroll(); return; } if ((!VSIw->savelines) /* no scrollback */ || (VSIw->top != 0) /* NCSA 2.5 */ || ((VSIw->bottom != VSIw->lines) && !VSIw->forcesave)) /* NCSA 2.5 */ /* region being scrolled is not entire screen */ /* no saving of lines */ VSIdellines(1, VSIw->top); else { /* scrolling region is entire screen, and lines are being saved off top */ if (VSIw->linest[VSIw->lines]->next == 0L) { /* all currently-allocated scrollback lines have been used, but scrollback buffer isn't at its full size -- allocate some more space */ i = VSIw->maxlines - VSIw->numlines; /* number of lines that can be allocated */ if (i > ScrollbackQuantum) i = ScrollbackQuantum; /* don't bother allocating more than this at once */ if ((i > 0) && (tmp = VSInewlines(i)) != 0L) { /* link newly-allocated lines into the list */ VSIw->linest[VSIw->lines]->next = tmp; tmp->prev = VSIw->linest[VSIw->lines]; VSIw->numlines++; /* use one of the newly-allocated scrollback lines */ RSbufinfo(VSIwn, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* update vertical scroll bar accordingly */ } else { /* not enough memory to extend scrollback buffer--reuse oldest line and give up on future extensions */ VSIw->linest[VSIw->lines]->next = VSIw->buftop; /* Make it circular */ VSIw->buftop->prev = VSIw->linest[VSIw->lines]; VSIw->buftop = VSIw->buftop->next; /* step one forward */ } /* if */ } else { /* either there's allocated, but not yet used, space at VSIw->linest[VSIw->lines]->next, or the text line list is circular. Either way, don't do any new scrollback allocation. */ if (VSIw->linest[VSIw->lines]->next == VSIw->buftop) /* scrollback buffer is at full size--reuse oldest line */ VSIw->buftop = VSIw->buftop->next; else { /* haven't used up all the space I allocated last time */ VSIw->numlines++; /* count another line */ RSbufinfo(VSIwn, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* update vertical scroll bar accordingly */ } /* if */ } /* if */ VSIw->scrntop = VSIw->scrntop->next; /* scroll the screen buffer */ VSIlistndx(VSIw->scrntop); /* update screen arrays */ /* reflect the change in the display by scrolling up the visible part of the on-screen area, if any */ if (VSIw->forcesave) theBottom = VSIw->bottom; /* NCSA 2.5: get the correct scroll rgn */ else theBottom = VSIw->Rbottom; /* NCSA 2.5: just use whole screen */ if (VSIcdellines(VSIwn, VSIw->Rtop, theBottom, 1, 1)) /* NCSA 2.5 */ { /* no part of on-screen area is visible */ if (VSIw->Rtop > -VSIw->numlines) /* update bounds of visible region to be consistent with portion of scrollback buffer still being displayed */ { VSIw->Rtop--; VSIw->Rbottom--; } else { /* displaying right from top of scrollback buffer. Topmost line being shown has in fact vanished. Update the display to show this fact. */ VSIw->vistop = VSIw->vistop->next; RSdellines(VSIwn, 0, VSIw->Rbottom - VSIw->Rtop, 1, 1); } /* if */ } else VSIw->vistop = VSIw->vistop->next; /* consistent with changed display */ /* blank out newly-revealed bottom line */ tempa = VSIw->linest[VSIw->lines]->attr; temp = VSIw->linest[VSIw->lines]->text; for (i = 0; i <= VSIw->allwidth; i++) { *temp++ = ' '; *tempa++ = 0; } /* for */ // RAB BetterTelnet 1.2.1 - another bug fix for NCSA's insanity! if (VSIw->bottom != VSIw->lines) { // we're forcesaving here... tmp = VSIw->linest[VSIw->lines]->next; tmp2 = VSIw->linest[VSIw->lines]; tmp3 = VSIw->linest[VSIw->bottom]; tmp4 = VSIw->linest[VSIw->lines]->prev; VSIw->linest[VSIw->bottom]->prev->next = tmp2; tmp2->prev = VSIw->linest[VSIw->bottom]->prev; tmp2->next = tmp3; tmp3->prev = tmp2; tmp4->next = tmp; if (tmp4->next) tmp4->next->prev = tmp4; if (VSIw->scrntop == VSIw->linest[VSIw->bottom]) VSIw->scrntop = tmp2; VSIlistndx(VSIw->scrntop); } } /* if */ // if (RSisInFront(VSIwn)) // RSvalidateRect(VSIwn); } /* VSIscroll */ void VSOscroll ( void ) /* scrolls scrolling region up one line. */ { register char *temp; register unsigned short *tempa; register short i; short theBottom; /* NCSA 2.5: the correct screen bottom */ static VSlinePtr tmp, tmp2, tmp3, tmp4; if (VSIw->y > VSIw->lines) /* BYU - replaces BYU modification below */ return; /* BYU */ if ((!VSIw->savelines) /* no scrollback */ || (VSIw->top != 0) /* NCSA 2.5 */ || ((VSIw->bottom != VSIw->lines) && !VSIw->forcesave)) /* NCSA 2.5 */ /* region being scrolled is not entire screen */ /* no saving of lines */ VSOdellines(1, VSIw->top); else { /* scrolling region is entire screen, and lines are being saved off top */ if (VSIw->linest[VSIw->lines]->next == 0L) { /* all currently-allocated scrollback lines have been used, but scrollback buffer isn't at its full size -- allocate some more space */ i = VSIw->maxlines - VSIw->numlines; /* number of lines that can be allocated */ if (i > ScrollbackQuantum) i = ScrollbackQuantum; /* don't bother allocating more than this at once */ if ((i > 0) && (tmp = VSOnewlines(i,1)) != 0L) { /* link newly-allocated lines into the list */ VSIw->linest[VSIw->lines]->next = tmp; tmp->prev = VSIw->linest[VSIw->lines]; VSIw->numlines++; /* use one of the newly-allocated scrollback lines */ RSbufinfo(VSIwn, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* update vertical scroll bar accordingly */ } else { /* not enough memory to extend scrollback buffer--reuse oldest line and give up on future extensions */ VSIw->linest[VSIw->lines]->next = VSIw->buftop; /* Make it circular */ VSIw->buftop->prev = VSIw->linest[VSIw->lines]; VSIw->buftop = VSIw->buftop->next; /* step one forward */ } /* if */ } else { /* either there's allocated, but not yet used, space at VSIw->linest[VSIw->lines]->next, or the text line list is circular. Either way, don't do any new scrollback allocation. */ if (VSIw->linest[VSIw->lines]->next == VSIw->buftop) /* scrollback buffer is at full size--reuse oldest line */ VSIw->buftop = VSIw->buftop->next; else { /* haven't used up all the space I allocated last time */ VSIw->numlines++; /* count another line */ RSbufinfo(VSIwn, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* update vertical scroll bar accordingly */ } /* if */ } /* if */ VSIw->scrntop = VSIw->scrntop->next; /* scroll the screen buffer */ VSOlistndx(VSIw->scrntop, VSIw->attrst[1]); /* update screen arrays */ /* reflect the change in the display by scrolling up the visible part of the on-screen area, if any */ if (VSIw->forcesave) theBottom = VSIw->bottom; /* NCSA 2.5: get the correct scroll rgn */ else theBottom = VSIw->Rbottom; /* NCSA 2.5: just use whole screen */ if (VSIcdellines(VSIwn, VSIw->Rtop, theBottom, 1, 1)) /* NCSA 2.5 */ { /* no part of on-screen area is visible */ if (VSIw->Rtop > -VSIw->numlines) /* update bounds of visible region to be consistent with portion of scrollback buffer still being displayed */ { VSIw->Rtop--; VSIw->Rbottom--; } else { /* displaying right from top of scrollback buffer. Topmost line being shown has in fact vanished. Update the display to show this fact. */ VSIw->vistop = VSIw->vistop->next; RSdellines(VSIwn, 0, VSIw->Rbottom - VSIw->Rtop, 1, 1); } /* if */ } else VSIw->vistop = VSIw->vistop->next; /* consistent with changed display */ /* blank out newly-revealed bottom line */ tempa = VSIw->attrst[VSIw->lines]->text; temp = VSIw->linest[VSIw->lines]->text; for (i = 0; i <= VSIw->allwidth; i++) { *temp++ = ' '; *tempa++ = 0; } /* for */ // RAB BetterTelnet 1.2.1 - Return of the Bug Fix! if (VSIw->bottom != VSIw->lines) { // we're forcesaving here... tmp = VSIw->linest[VSIw->lines]->next; tmp2 = VSIw->linest[VSIw->lines]; tmp3 = VSIw->linest[VSIw->bottom]; tmp4 = VSIw->linest[VSIw->lines]->prev; VSIw->linest[VSIw->bottom]->prev->next = tmp2; tmp2->prev = VSIw->linest[VSIw->bottom]->prev; tmp2->next = tmp3; tmp3->prev = tmp2; tmp4->next = tmp; if (tmp4->next) tmp4->next->prev = tmp4; if (VSIw->scrntop == VSIw->linest[VSIw->bottom]) VSIw->scrntop = tmp2; // now for the attribute lines... VSIw->attrst[VSIw->lines]->next->prev = VSIw->attrst[VSIw->lines]->prev; VSIw->attrst[VSIw->lines]->prev->next = VSIw->attrst[VSIw->lines]->next; VSIw->attrst[VSIw->bottom]->prev->next = VSIw->attrst[VSIw->lines]; VSIw->attrst[VSIw->lines]->prev = VSIw->attrst[VSIw->bottom]->prev; VSIw->attrst[VSIw->lines]->next = VSIw->attrst[VSIw->bottom]; VSIw->attrst[VSIw->bottom]->prev = VSIw->attrst[VSIw->lines]; VSOlistndx(VSIw->scrntop, VSIw->attrst[0]); } } /* if */ // if (RSisInFront(VSIwn)) // RSvalidateRect(VSIwn); } /* VSOscroll */ void VSIindex ( void ) /* moves cursor down one line, unless it's at the bottom of the scrolling region, in which case scrolls up one. */ { if (VSIw->y == VSIw->bottom) /* BYU - changed "==" to ">=" and back again */ VSIscroll(); else if (VSIw->y < VSIw->lines) /* BYU - added "if ... " */ VSIw->y++; } /* VSIindex */ void VSIwrapnow(short *xp, short *yp) /* checks current cursor position for VSIw to see if it's within bounds, wrapping to next line if not. Returns correct cursor position in either case in *xp and *yp. */ { if (VSIw->x > VSIw->maxwidth) { VSIw->x = 0; VSIindex(); } /* if */ *xp = VSIw->x; *yp = VSIw->y; } /* VSIwrapnow */ void VSIeeol ( void ) /* erases characters to the end of the current line. */ { char *tt; unsigned short *ta; short x1 = VSIw->x, y1 = VSIw->y, x2 = VSIw->maxwidth, y2 = VSIw->y, n = -1, offset; short i; if ((VSIw->x == 0)&&(VSIw->y == 0)&&(VSIw->possibleForce == 1)) { VSIw->possibleForce = 0; VSIscroff(); } VSIwrapnow(&x1, &y1); y2 = y1; /* clear out screen line */ if (VSIw->oldScrollback) ta = &VSIw->attrst[y1]->text[x1]; else ta = &VSIw->linest[y1]->attr[x1]; tt = &VSIw->linest[y1]->text[x1]; for (i = VSIw->allwidth - x1 + 1; i > 0; i--) { *ta++ = VSIclrattrib; *tt++ = ' '; } /* update display */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSerase(VSIwn, x1, y1, x2, y2); } /* VSIeeol */ void VSIdelchars ( short x /* how many characters to delete */ ) /* deletes characters at the current cursor position onwards, moving the remainder of the line to the left. */ { short i; short x1 = VSIw->x, y1 = VSIw->y, x2 = VSIw->maxwidth, y2 = VSIw->y, n = -1, offset; char *temp; unsigned short *tempa; VSIwrapnow(&x1, &y1); y2 = y1; if (x > VSIw->maxwidth) x = VSIw->maxwidth; if (VSIw->oldScrollback) tempa = VSIw->attrst[y1]->text; else tempa = VSIw->linest[y1]->attr; temp = VSIw->linest[y1]->text; for (i = x1; i <= VSIw->maxwidth - x; i++) { /* move remainder of line to the left */ temp[i] = temp[x + i]; tempa[i] = tempa[x + i]; } for (i = VSIw->maxwidth - x + 1; i <= VSIw->allwidth; i++) { /* insert blank characters after end of line */ temp[i] = ' '; tempa[i] = VSIclrattrib; } /* update display */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSdelchars(VSIwn, x1, y1, x); } /* VSIdelchars */ void VSIfreelinelist ( VSlinePtr listhead ) /* frees up the list of line elements pointed to by listhead. */ { register VSlinePtr ThisElt, NextElt, ToFree; ThisElt = listhead; ToFree = nil; while (true) { if (ThisElt == nil) break; NextElt = ThisElt->next; if (ThisElt->mem) { ThisElt->next = ToFree; ToFree = ThisElt; } /* if */ ThisElt = NextElt; if (ThisElt == listhead) break; } /* while */ while (ToFree) { NextElt = ToFree->next; DisposPtr((Ptr) ToFree); if (VSIw->oldScrollback) DisposPtr((Ptr) ToFree->text); ToFree = NextElt; } /* while */ } /* VSIfreelinelist */ void VSIfreelines ( void ) /* frees up all the memory allocated for screen and scrollback text lines for the current screen. */ { VSIfreelinelist(VSIw->buftop); } /* VSIfreelines */ void VSIrindex ( void ) /* moves cursor up one line, unless it's at the top of the scrolling region, in which case scrolls down one. */ { if (VSIw->y == VSIw->top) VSIinslines(1, VSIw->top); else VSIw->y--; } /* VSIrindex */ void VSIebol ( void ) /* erases characters from beginning of line to cursor. */ { char *tt; unsigned short *ta; short x1 = 0, y1 = VSIw->y, x2 = VSIw->x, y2 = VSIw->y, n = -1, offset; short i; VSIwrapnow(&x2, &y1); y2 = y1; /* clear from beginning of line to cursor */ if (VSIw->oldScrollback) ta = &VSIw->attrst[y1]->text[0]; else ta = &VSIw->linest[y1]->attr[0]; tt = &VSIw->linest[y1]->text[0]; for (i = 0; i <= x2; i++) { *ta++ = VSIclrattrib; *tt++ = ' '; } /* update display */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSerase(VSIwn, x1, y1, x2, y2); } /* VSIebol */ void VSIel ( short s /* line to clear, -ve => line containing cursor */ ) /* erases the specified line. */ { char *tt; unsigned short *ta; short x1 = 0, y1 = s, x2 = VSIw->maxwidth, y2 = s, n = -1, offset; short i; if (s < 0) { VSIwrapnow(&x1, &y1); s = y2 = y1; x1 = 0; } /* clear out line */ if (VSIw->oldScrollback) ta = &VSIw->attrst[s]->text[0]; else ta = &VSIw->linest[s]->attr[0]; tt = &VSIw->linest[s]->text[0]; for(i = 0; i <= VSIw->allwidth; i++) { *ta++ = VSIclrattrib; *tt++ = ' '; } /* update display */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSerase(VSIwn, x1, y1, x2, y2); } /* VSIel */ void VSIeeos ( void ) /* erases characters from cursor to end of screen. */ { short i; short x1 = 0, y1 = VSIw->y + 1, x2 = VSIw->maxwidth, y2 = VSIw->lines, n = -1, offset; VSIwrapnow(&x1, &y1); y1++; x1 = 0; i = y1; if ((VSIw->forcesave)&&(VSIw->y == 0)&&(VSIw->x == 0)) //trashes screen unless we are in 0,0 VSIscroff(); VSIw->possibleForce = FALSE; //CCP better forcesave stuff /* erase complete lines from screen */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSerase(VSIwn, x1, y1, x2, y2); /* blank out current line from cursor to end */ VSIeeol(); /* this also erases the partial line on-screen */ /* blank out remaining lines to end of screen */ while (i <= VSIw->lines) { VSIelo(i); i++; } /* while */ if (VSIw->y < VSIw->lines && (VSIw->x <= VSIw->maxwidth)) /* erase the partial line (what--again??) */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSerase(VSIwn, x1, y1, x2, y2); } /* VSIeeos */ void VSIebos ( void ) /* erases characters from beginning of screen to cursor. */ { short i; short x1, y1, x2 = VSIw->maxwidth, y2, n = -1, offset; VSIwrapnow(&x1, &y1); y2 = y1 - 1; x1 = 0; y1 = 0; /* blank out current line from beginning to cursor */ VSIebol(); /* this also erases the partial line on-screen */ i = 0; /* blank out remaining lines from beginning of screen to previous line */ while (i < (y2 + 1)) { VSIelo(i); i++; } if (y2 >= 0) /* erase the partial line (what--again??) */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSerase(VSIwn, x1, y1, x2, y2); } /* VSIebos */ void VSIrange ( void ) /* constrains cursor position to valid range (somewhere on the screen). */ { short wrap = 0; if (VSIw->DECAWM) wrap = 1; if (VSIw->x < 0) VSIw->x = 0; if (VSIw->x > (VSIw->maxwidth + wrap)) VSIw->x = VSIw->maxwidth + wrap; if (VSIw->y < 0) VSIw->y = 0; if (VSIw->y > VSIw->lines) VSIw->y = VSIw->lines; } /* VSIrange */ void VTsendpos ( void ) /* sends an escape sequence representing the current cursor position. */ { char tempbuf[19]; short x = VSIw->x, y = VSIw->y; if (x > VSIw->maxwidth) { /* autowrap pending */ x = 0; y++; } if (y > VSIw->lines) /* scroll pending (because of the autowrap) */ y = VSIw->lines; sprintf(tempbuf, "\033[%d;%dR", y + 1, x + 1); RSsendstring(VSIwn, tempbuf, strlen(tempbuf)); } /* VTsendpos */ void VTsendstat ( void ) /* sends the terminal status string. */ { RSsendstring(VSIwn, "\033[0n", 4); } /* VTsendstat */ void VTsendident ( void ) /* sends an appropriate terminal identification sequence. */ { if (screens[findbyVS(VSIwn)].vtemulation) RSsendstring(VSIwn, "\033[?62;1;6c", 10); /* BYU 2.4.12 - VT200-series*/ else /* BYU 2.4.12 */ RSsendstring(VSIwn, "\033[?6c", 5); /* BYU 2.4.12 - VT102 */ } /* VTsendident */ void VTalign ( void ) /* fills screen with uppercase "E"s, for checking screen alignment. */ /* Yeah, right. */ { char *tt; short i, j; VSIes(); /* erase the screen */ for (j = 0; j < VSIw->lines; j++) { tt = &VSIw->linest[j]->text[0]; for (i = 0; i <= VSIw->maxwidth; i++) *tt++ = 'E'; } /* for */ /* update the display */ VSredraw(VSIwn, 0, 0, (VSIw->Rright - VSIw->Rleft), (VSIw->Rbottom - VSIw->Rtop)); } /* VTalign */ void VSIapclear ( void ) /* initializes all the parameters for the current control sequence, and the current param index, to zero. */ { short parmptr = maxparms; while (--parmptr >= 0) VSIw->parms[parmptr] = -1; VSIw->parmptr = 0; } /* VSIapclear */ void VSIsetoption ( short toggle /* 1 => set, 0 => reset */ ) /* sets/resets various options, as specified by the parms in the current control sequence. Note that this implementation will not set/reset more than one option at a time! */ { short WindWidth = VSIw->Rright - VSIw->Rleft; switch (VSIw->parms[0]) { case -2: /* DEC-private control sequence */ switch (VSIw->parms[1]) { case 1: /* cursor-key mode */ VSIw->DECCKM = toggle; break; case 3: /* 80/132 columns */ // VSIw->x = VSIw->y = 0; /* home cursor */ // VSIes(); /* and clear screen */ if (toggle) /* 132 column mode */ { /* NCSA: SB */ VSIw->maxwidth = 131; /* NCSA: SB */ RScalcwsize(VSIwn,132); /* NCSA: SB */ } /* NCSA: SB */ else /* NCSA: SB */ { /* NCSA: SB */ VSIw->maxwidth = 79; /* NCSA: SB */ RScalcwsize(VSIwn,80); /* NCSA: SB */ } /* NCSA: SB */ /* update scroll bars */ RSmargininfo(VSIwn, VSIw->maxwidth, VSIw->Rleft); /* NCSA: SB */ break; /* NCSA: SB - this next one will allow us to flip the foreground and */ /* background colors. */ case 5: /* NCSA: SB - screen mode */ RSbackground(VSIwn,toggle); break; case 6: /* origin mode */ VSIw->DECORG = toggle; break; case 7: /* autowrap mode */ VSIw->DECAWM = toggle; break; case 25: /* cursor mode */ VSIw->DECCM = toggle; break; default: break; } /* switch */ break; case 4: /* insert/replace character writing mode */ VSIw->IRM = toggle; break; default: break; } /* switch */ } /* VSIsetoption */ void VSItab //BUGG ( void ) /* advances VSIw->x to the next tab position. */ { VSIw->x += VSIgetNextTabDistance(); } /* VSItab */ void VSIinschar ( short x /* number of blanks to insert */ ) /* inserts the specified number of blank characters at the current cursor position, moving the rest of the line along, losing any characters that fall off the right margin. Does not update the display. */ { short i, j; char *temp; unsigned short *tempa; VSIwrapnow(&i, &j); if (VSIw->oldScrollback) tempa = VSIw->attrst[VSIw->y]->text; else tempa = VSIw->linest[VSIw->y]->attr; temp = VSIw->linest[VSIw->y]->text; for (i = VSIw->maxwidth - x; i >= VSIw->x; i--) { /* move along remaining characters on line */ temp[x + i] =temp[i]; tempa[x + i] = tempa[i]; } /* for */ for (i = VSIw->x; i < VSIw->x + x; i++) { /* insert appropriate number of blanks */ temp[i] = ' '; tempa[i] = VSIclrattrib; } /* for */ } /* VSIinschar */ void VSIinsstring ( short len, char *start ) /* updates the screen to show insertion of a string of characters at the current cursor position. The text has already been inserted into the screen buffer. Also, the cursor position has already been updated, so the part needing redrawing begins at column (VSIw->x - len). */ { RSinsstring(VSIwn, VSIw->x - len, VSIw->y, VSIw->attrib, len, start); } /* VSIinsstring */ void VSIsave ( void ) /* saves the current cursor position and attribute settings. */ { VSIw->Px = VSIw->x; VSIw->Py = VSIw->y; VSIw->Pattrib = VSIw->attrib; } /* VSIsave */ void VSIrestore ( void ) /* restores the last-saved cursor position and attribute settings. */ { if (VSIw->Pattrib < 0) /* no previous save */ return; VSIw->x = VSIw->Px; VSIw->y = VSIw->Py; VSIrange(); VSIw->attrib = VSinattr(VSIw->Pattrib); /* hmm, this will clear the graphics character set selection */ } /* VSIrestore */ void VSIdraw ( short VSIwn, /* window number */ short x, /* starting column */ short y, /* line on which to draw */ short a, /* text attributes */ short len, /* length of text to draw */ char *c /* pointer to text */ ) /* displays a piece of text (assumed to fit on a single line) on a screen, using the specified attributes, and clipping to the current visible region. Highlights any part of the text lying within the current selection. */ { short x2, y2, offset; if (!VSIclip(&x, &y, &x2, &y2, &len, &offset)) RSdraw(VSIwn, x, y, a, len, (char *) (c + offset)); /* BYU LSC */ } /* VSIdraw */ \ No newline at end of file +// BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // #pragma profile on /* * * Virtual Screen Kernel Internal Routines * (vsintern.c) * National Center for Supercomputing Applications * * by Gaige B. Paulsen * * This file contains the private internal calls for the NCSA * Virtual Screen Kernel. * * Version Date Notes * ------- ------ --------------------------------------------------- * 0.01 861102 Initial coding -GBP * 0.50 861113 First compiled edition -GBP * 0.70 861114 Internal operation confirmed -GBP * 2.1 871130 NCSA Telnet 2.1 -GBP * 2.2 880715 NCSA Telnet 2.2 -GBP */ #include "vsdata.h" #include "vskeys.h" #include "vsinterf.proto.h" #include "rsmac.proto.h" #include "rsinterf.proto.h" #include "maclook.proto.h" #include "wind.h" #include "rsdefs.h" #define ScrollbackQuantum 100 #define VSIclrattrib 0 #include "vsintern.proto.h" extern short TempItemsVRefNum; extern long TempItemsDirID; extern WindRec *screens; extern RSdata *RSlocal; short VSIclip ( short *x1, /* starting column */ short *y1, /* line on which to draw (assumed to lie within visible region) */ short *x2, /* ending column (inclusive) (output if *n >= 0) */ short *y2, /* ending line (inclusive) (output if *n >= 0) */ short *n, /* length of text to draw (input and output) */ short *offset /* length of initial part of text to skip (output) */ ) /* clips a text string to the visible region, given the starting line and column in screen coordinates at which it is to be drawn. If the length of the string is given, will also compute the ending line and column. On return, these coordinates will be normalized to the current visible region. Returns a nonzero function result iff the string is completely invisible. */ { if (*n >= 0) { /* compute ending line and column (inclusive) */ *x2 = *x1 + *n - 1; *y2 = *y1; } /* else take these as given */ if ((*x1 > VSIw->Rright) || (*y2 < VSIw->Rtop)) return (-1); /* nothing to draw */ if (*x2 > VSIw->Rright) *x2 = VSIw->Rright; if (*y2 > VSIw->Rbottom) *y2 = VSIw->Rbottom; /* normalize x1, x2, y1, y2 to be relative to current visible region */ *x1 -= VSIw->Rleft; *x2 -= VSIw->Rleft; *y1 -= VSIw->Rtop; *y2 -= VSIw->Rtop; /* clip part of text string lying outside region, if any */ *offset = - *x1; if (*offset < 0) *offset = 0; /* text string starts within region--nothing to clip */ /* don't draw anything outside region */ if (*x1 < 0) *x1 = 0; if (*y1 < 0) *y1 = 0; *n = *x2 - *x1 + 1 ; /* length of string to draw (assuming it's all on one line) */ if ((*n <= 0) || (*y2 - *y1 < 0)) return (-1); /* nothing to draw */ return (0); } /* VSIclip */ short VSIcdellines(short w, short top, short bottom, short n, short scrolled) /* -ve => cancel current selection, if any; +ve => selection has moved up one line; 0 => don't touch selection */ /* updates the display to indicate deletion of the specified number of lines from the top of the specified region. Returns 0 iff any part of the change is visible. */ { short x1 = 0, x2 = VSIw->maxwidth, tn = -1, offset; if (VSIclip(&x1, &top, &x2, &bottom, &tn, &offset)) return(-1); /* affected region is invisible */ tn = bottom - top; if (tn < n) n = tn; /* don't bother scrolling more lines than scrolling region holds */ RSdellines(w, top, bottom, n, scrolled); return(0); /* I delete the whole thing! */ } /* VSIcdellines */ short VSIcinslines(short w, short top, short bottom, short n, short scrolled) /* -ve <=> cancel current selection, if any */ /* updates the display to indicate insertion of the specified number of blank lines at the top of the specified region. Returns 0 iff any part of the change is visible. */ { short x1 = 0, x2 = VSIw->maxwidth, tn = -1, offset; if (VSIclip(&x1, &top, &x2, &bottom, &tn, &offset)) return -1; /* affected region is invisible */ tn = bottom - top; if (tn < n) n = tn; /* don't bother scrolling more lines than scrolling region holds */ RSinslines(w, top, bottom, n, scrolled); return 0; } /* VSIcinslines */ void VSIcurson ( short w, short x, short y, short ForceMove ) /* displays the text cursor at the specified position. If ForceMove is true, I am to do any appropriate scrolling of the display to ensure the cursor is within the visible region. Assumes cursor isn't currently being shown. */ { short x2, y2, n = 1, offset; if (!VSIw->DECCM) return; // Bri 970610 if (VSIw->disableCursor) return; // RAB BetterTelnet 2.0b4 if (!VSIclip(&x, &y, &x2, &y2, &n, &offset)) /* cursor already lies within visible region */ RScurson(w, x, y); /* just make it visible */ else if (ForceMove) { /* scroll to make cursor visible */ x2 = VSIw->Rbottom - VSIw->Rtop; if (x2 >= VSIw->lines) /* visible region is big enough to show entire screen-- make sure I don't scroll off the bottom of the screen. This call will also do any appropriate scrolling and redisplaying of the cursor. */ VSsetrgn(VSIwn, VSIw->Rleft, VSIw->lines - x2, VSIw->Rright, VSIw->lines); else { /* x & y have been normalized relative to left & top of current visible region. Just call the appropriate scroll routine, which will also redisplay the cursor. */ if (y > 0) VSscrolforward(VSIwn, y); else VSscrolback(VSIwn, -y); } /* if */ } /* if */ } /* VSIcurson */ void VSIcuroff ( short w ) /* hides the cursor for the specified screen. Assumes it is currently being shown (or that it's on an invisible part of the screen). */ { short x = VSIw->x, y = VSIw->y, x2, y2, n = 1, offset; if (!VSIclip(&x, &y, &x2, &y2, &n, &offset) || !VSIw->DECCM) // Bri 970610 /* cursor is on visible part of screen */ RScursoff(w); } /* VSIcuroff */ void VSIcursdisable() // RAB BetterTelnet 2.0b4 { VSIw->disableCursor = 1; } void VSIcursenable() { VSIw->disableCursor = 0; } short VSIcursorvisible /* BYU 2.4.12 */ ( /* BYU 2.4.12 */ void /* BYU 2.4.12 */ ) /* BYU 2.4.12 */ { /* BYU 2.4.12 */ short /* BYU 2.4.12 */ x = VSIw->x, /* BYU 2.4.12 */ y = VSIw->y, /* BYU 2.4.12 */ x2, /* BYU 2.4.12 */ y2, /* BYU 2.4.12 */ n = 1, /* BYU 2.4.12 */ offset; /* BYU 2.4.12 */ if (!VSIw->DECCM) return 0; // Bri 970610 if (VSIw->disableCursor) return 0; // RAB BetterTelnet 2.0b4 /* BYU 2.4.12 */ if (!VSIclip(&x, &y, &x2, &y2, &n, &offset)) /* BYU 2.4.12 */ return 1; /* BYU 2.4.12 */ else /* BYU 2.4.12 */ return 0; /* BYU 2.4.12 */ } /* BYU 2.4.12 */ VSlineArray VSInewlinearray ( short nrlines ) /* allocates an array to hold the specified number of pointers to line elements. */ { return (VSlineArray) myNewPtrCritical(sizeof(VSlinePtr) * nrlines); } /* VSInewlinearray */ VSlinePtr VSInewlines ( short nlines ) /* allocates a doubly-linked list of the specified number of line elements, and returns a pointer to the head of the list, or NULL if ran out of memory. The maximum number of characters each line can hold is controlled by VSIw->allwidth. */ { void* memoryPtr; VSlinePtr linePtr; char* textPtr; unsigned short* attrPtr; long width; long i; /* Allocated one large block that will be broken up as follows: +---------+-------+-------+ | VSlines | texts | attrs | +---------+-------+-------+ This way, we can save tons of time allocating and deallocating memory from the system. BCS 970726 */ width = VSIw->allwidth + 1; memoryPtr = myNewPtrCritical(nlines * (sizeof(VSline) + (width * 3))); if(memoryPtr == NULL) return (VSlinePtr)NULL; // Chop the memory up into its 3 chunks. linePtr = (VSlinePtr)memoryPtr; textPtr = (char*)(linePtr + nlines); attrPtr = (unsigned short*)(textPtr + (nlines * width)); // Loop through the elements, initializing each one. for(i = 0; i < nlines; i++) { linePtr->mem = 0; linePtr->text = textPtr; linePtr->attr = attrPtr; linePtr->prev = linePtr - 1; linePtr->next = linePtr + 1; linePtr++; textPtr += width; attrPtr += width; } // Flag the first line as the free element. // This seems really strange; should be fixed (BCS) ((VSline*)memoryPtr)->mem = 1; // Terminate the beginning and end nodes in the list. ((VSline*)memoryPtr)->prev = NULL; (linePtr-1)->next = NULL; // Return the head. return (VSline*)memoryPtr; } /* VSInewlines */ VSlinePtr VSOnewlines ( short nlines, short elementSize //CCP 2.7 ) /* allocates a doubly-linked list of the specified number of line elements, and returns a pointer to the head of the list, or nil if ran out of memory. The maximum number of characters each line can hold is controlled by VSIw->allwidth. */ { VSlinePtr t2; char *t; register short i; /* allocate one block for the line list elements, and another block for the line contents. These blocks will be divided up and appropriate flags set so I will be able to call DisposePtr the right number of times, with the right arguments. */ if ((t = myNewPtrCritical(nlines * (VSIw->allwidth + 1)*elementSize)) != 0L) { if ((t2 = (VSlinePtr) myNewPtrCritical(nlines * sizeof(VSline))) != 0L) t2->text = t; else { /* clean up gracefully before giving up */ DisposePtr(t); return(0L); } /* if */ } else /* sorree no memoree */ return((VSlinePtr) 0L); /* * indicate to the free routine that the first record is the one to free. */ t2->mem = 1; /* call DisposePtr on this one */ t2->next = t2 + 1; /* point to next one */ /* * Take our allocation for multiple lines and fill in the structures to * point to the right text fields and connect the doubly-linked chain. * */ for (i = 1; i < nlines; i++) { t += (VSIw->allwidth + 1)* elementSize; /* inc to next text space for a line */ t2[i].mem = 0; /* don't DisposePtr any of these */ t2[i].text = t; t2[i].prev = t2 + i - 1; /* point back one */ t2[i].next = t2 + i + 1; /* point forward one */ } /* for */ t2[0].prev = 0L; /* first one has no prev yet */ t2[nlines - 1].next = 0L; /* last one has no next yet */ return(t2); } /* VSOnewlines */ void VSIlistndx ( register VSlinePtr ts ) /* sets up the screen arrays for the current screen to point at the given lists of attribute and text lines. */ { register short i; for (i = 0; i <= VSIw->lines; i++) { VSIw->linest[i] = ts; ts = ts->next; } /* for */ } /* VSIlistndx */ void VSOlistndx ( register VSlinePtr ts, register VSattrlinePtr as ) /* sets up the screen arrays for the current screen to point at the given lists of attribute and text lines. */ { register short i; for (i = 0; i <= VSIw->lines; i++) { VSIw->attrst[i] = as; VSIw->linest[i] = ts; ts = ts->next; as = as->next; } /* for */ } /* VSOlistndx */ void VSIscroff ( void ) /* called to save current screen contents in scrollback buffer, if it is ordained that I should do so. This is called by VSIes (below) just before the entire screen is cleared. */ { VSlinePtr tmp; register short i, j; if ( (!VSIw->savelines) /* not saving lines */ || (VSIw->top != 0) || (VSIw->bottom != VSIw->lines) /* scrolling region isn't exactly the entire screen */ ) return; /* do nothing */ if (VSIw->oldScrollback) { VSOscroff(); return; } tmp = VSIw->linest[VSIw->lines]; /* need VSIw->lines + 1 more lines */ for (i = 0; i <= VSIw->lines; i++) { /* count off the lines in the part of the scrollback buffer below the screen (if any), to see if there's enough to hold a screenful. If the scrollback list isn't circular, then this part contains lines that have been allocated, but not yet used. If the list is circular (meaning it has reached its full size), then this is the part that is next in line for reuse. */ if (!tmp->next) { /* not enough */ j = VSIw->maxlines - VSIw->numlines - i; /* potential unallocated scrollback */ if (j > ScrollbackQuantum) j = ScrollbackQuantum; /* but don't bother allocating more than this */ if (j <= 0) { /* already reached user-specified scrollback limit-- */ /* make the list circular to indicate no more extension. */ tmp->next = VSIw->buftop; VSIw->buftop->prev = tmp; /* connect it up */ } else { /* extend the scrollback buffer to make room for another screenful */ if (j < VSIw->lines - i + 1) j = VSIw->lines - i + 1; /* need at least this many */ if ((tmp->next = VSInewlines(j)) != 0L) tmp->next->prev = tmp; /* got some space--link it up */ else { /* out of memory--no more extensions */ tmp->next = VSIw->buftop; VSIw->buftop->prev = tmp; } /* if */ } /* if */ break; /* only allocate once is enough */ } /* if */ tmp = tmp->next; /* keep counting */ } /* for */ /* * at this point, we know we have enough memory for the whole scroll. * It might be wraparound (reuse of some line elements), might not. */ for (i = 0; i <= VSIw->lines; i++) { /* push another screen line into the scrollback area */ // RAB BetterTelnet 1.2 - bug fix for bad linked list bug // What was NCSA thinking when they wrote this code, anyway? // if (VSIw->linest[i]->next == VSIw->buftop) if (VSIw->linest[VSIw->lines]->next == VSIw->buftop) VSIw->buftop = VSIw->buftop->next; /* reusing old space */ else VSIw->numlines++; /* using some new space */ VSIw->scrntop = VSIw->scrntop->next; /* move another line into the scrollback buffer */ VSIlistndx(VSIw->scrntop); /* and update screen arrays */ /* note that it's up to the caller to clear out the new screen text and attribute lines */ } /* for */ VSIw->vistop = VSIw->scrntop; // RAB BetterTelnet 2.0b3 - hopefully the very last scrollback bug // I think this one caused quite a few crashes now and then. // Rtop and Rbottom weren't being synced with vistop (stupid) VSIw->Rbottom -= VSIw->Rtop; VSIw->Rtop = 0; // VSIw->Rbottom = VSIw->lines; RSbufinfo(VSIwn, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* update vertical scroll bar */ } /* VSIscroff */ void VSOscroff ( void ) /* called to save current screen contents in scrollback buffer, if it is ordained that I should do so. This is called by VSIes (below) just before the entire screen is cleared. */ { VSlinePtr tmp; register short i, j; if ( (!VSIw->savelines) /* not saving lines */ || (VSIw->top != 0) || (VSIw->bottom != VSIw->lines) /* scrolling region isn't exactly the entire screen */ ) return; /* do nothing */ tmp = VSIw->linest[VSIw->lines]; /* need VSIw->lines + 1 more lines */ for (i = 0; i <= VSIw->lines; i++) { /* count off the lines in the part of the scrollback buffer below the screen (if any), to see if there's enough to hold a screenful. If the scrollback list isn't circular, then this part contains lines that have been allocated, but not yet used. If the list is circular (meaning it has reached its full size), then this is the part that is next in line for reuse. */ if (!tmp->next) { /* not enough */ j = VSIw->maxlines - VSIw->numlines - i; /* potential unallocated scrollback */ if (j > ScrollbackQuantum) j = ScrollbackQuantum; /* but don't bother allocating more than this */ if (j <= 0) { /* already reached user-specified scrollback limit-- */ /* make the list circular to indicate no more extension. */ tmp->next = VSIw->buftop; VSIw->buftop->prev = tmp; /* connect it up */ } else { /* extend the scrollback buffer to make room for another screenful */ if (j < VSIw->lines - i + 1) j = VSIw->lines - i + 1; /* need at least this many */ if ((tmp->next = VSOnewlines(j,1)) != 0L) tmp->next->prev = tmp; /* got some space--link it up */ else { /* out of memory--no more extensions */ tmp->next = VSIw->buftop; VSIw->buftop->prev = tmp; } /* if */ } /* if */ break; /* only allocate once is enough */ } /* if */ tmp = tmp->next; /* keep counting */ } /* for */ /* * at this point, we know we have enough memory for the whole scroll. * It might be wraparound (reuse of some line elements), might not. */ for (i = 0; i <= VSIw->lines; i++) { /* push another screen line into the scrollback area */ // RAB BetterTelnet 1.2.1 - bug fix // if (VSIw->linest[i]->next == VSIw->buftop) if (VSIw->linest[VSIw->lines]->next == VSIw->buftop) VSIw->buftop = VSIw->buftop->next; /* reusing old space */ else VSIw->numlines++; /* using some new space */ VSIw->scrntop = VSIw->scrntop->next; /* move another line into the scrollback buffer */ VSOlistndx(VSIw->scrntop, VSIw->attrst[1]); /* and update screen arrays */ /* note that it's up to the caller to clear out the new screen text and attribute lines */ } /* for */ VSIw->vistop = VSIw->scrntop; // RAB BetterTelnet 2.0b3 - bug fix VSIw->Rbottom -= VSIw->Rtop; VSIw->Rtop = 0; // VSIw->Rbottom = VSIw->lines; RSbufinfo(VSIwn, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* update vertical scroll bar */ } /* VSOscroff */ void VSIelo ( short s /* line to erase, -ve => line containing cursor */ ) /* blanks out the specified line in the screen buffer. Doesn't do anything to the display. */ { char *tt; unsigned short *ta; short i; if (s < 0) s = VSIw->y; if (VSIw->oldScrollback) ta = &VSIw->attrst[s]->text[0]; else ta = &VSIw->linest[s]->attr[0]; tt = &VSIw->linest[s]->text[0]; for (i = 0; i <= VSIw->allwidth; i++) { *ta++ = VSIclrattrib; *tt++ = ' '; } /* for */ } /* VSIelo */ void VSIes ( void ) /* clears the screen, first saving its contents in the scrollback buffer if appropriate. Also updates the display. */ { short i; short x1 = 0, y1 = 0, x2 = VSIw->maxwidth, y2 = VSIw->lines, n = -1, offset; VSIflush(); // RAB BetterTelnet 2.0b3 /* save screen contents in scrollback buffer, if appropriate */ if (VSIw->ESscroll) VSIscroff(); /* clear out screen buffer */ for (i = 0; i <= VSIw->lines; i++) VSIelo(i); /* update display to show what I've done */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSerase(VSIwn, x1, y1, x2, y2); VSIw->vistop = VSIw->scrntop; // RAB BetterTelnet 2.0b3 - bug fix VSIw->Rtop = 0; VSIw->Rbottom = VSIw->lines; RSbufinfo(VSIwn, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* update vertical scroll bar */ } /* VSIes */ void VSItabclear ( void ) /* clears all current tab settings. */ { short x = 0; while (x <= VSIw->allwidth) { VSIw->tabs[x] = ' '; x++; } /* while */ } /* VSItabclear */ void VSItabinit ( void ) /* sets tab settings to default (every 8 columns). */ { short x = 0; VSItabclear(); while (x <= VSIw->allwidth) { VSIw->tabs[x] = 'x'; x += 8; } VSIw->tabs[VSIw->allwidth] = 'x'; } /* VSItabinit */ void VSIreset ( void ) /* restores terminal mode settings to defaults and clears screen. */ { VSIflush(); // RAB BetterTelnet 2.0b3 VSIw->top = 0; VSIw->bottom = VSIw->lines; VSIw->parmptr = 0; VSIw->escflg = 0; VSIw->DECAWM = 0; VSIw->DECCKM = 0; VSIw->DECPAM = 0; VSIw->DECORG = 0; /* NCSA: SB -- is this needed? */ VSIw->DECCM = 1; // Bri 970610 VSIw->Pattrib = -1; /* NCSA: SB -- is this needed? */ VSIw->IRM = 0; VSIw->attrib = 0; VSIw->x = 0; VSIw->y = 0; VSIw->charset = 0; VSIw->prbuf=0; /* LU */ if (VSIw->prredirect) { /* LU - kill redirection */ VSIw->prredirect=0; /* LU */ FSClose (VSIw->refNum); /* LU */ VSIw->refNum=-1; /* LU */ HDelete(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname); /* LU */ } /* LU */ VSIes(); VSItabinit(); } /* VSIreset */ void VSIlistmove(VSlinePtr TD, VSlinePtr BD, VSlinePtr TI, VSlinePtr BI) /* moves the lines from TD to BD inclusive from their present position to between TI and BI. Either of the latter may be nil. */ { /* unlink the lines from TD to BD */ if (TD->prev != 0L) TD->prev->next = BD->next; /* Maintain circularity */ if (BD->next != 0L) BD->next->prev = TD->prev; /* relink them between TI and BI */ TD->prev = TI; /* Place the node in its new home */ BD->next = BI; if (TI != 0L) TI->next = TD; /* Ditto prev->prev */ if (BI != 0L) BI->prev = BD; } /* VSIlistmove */ void VSIdellines ( short n, /* nr lines to delete */ short s /* starting line to delete, -ve => line containing cursor */ ) /* deletes lines from the screen, scrolling up the remainder and inserting new blank lines at the bottom of the scrolling region. */ { short i, j; char *tt; unsigned short *ta; VSlinePtr ts, TD, BD, TI, BI, itt; if (VSIw->oldScrollback) { VSOdellines(n, s); return; } if (s < 0) s = VSIw->y; if (s + n - 1 > VSIw->bottom) n = VSIw->bottom - s + 1; /* don't bother deleting more than scrolling region will hold */ /* find new tops of screen arrays */ // RAB BetterTelnet 2.0b3 // argh, must I keep fixing bugs here? // if (s == 0 && n <= VSIw->lines) if (s == 0 && n <= VSIw->bottom) { /* element for line after last one being deleted */ ts = VSIw->linest[n]; } else { /* top line unaffected, or entire screen is being wiped */ ts = VSIw->linest[0]; } /* if */ TD = VSIw->linest[s]; /* topmost line to delete */ BD = VSIw->linest[s + n - 1]; /* bottommost line to delete */ TI = VSIw->linest[VSIw->bottom]; /* insert replacement blank lines after this line */ BI = TI->next; /* insert them before this line (might be nil) */ itt = TD; /* start of text lines to be blanked out */ /* the space taken by the deleted lines will be reused for the inserted blank lines */ if (TD != BI && TI != BD) /* insertion and deletion areas not adjacent -- move the lines to their new position */ VSIlistmove(TD, BD, TI, BI); for (i = 0; i < n; i++) { ta = itt->attr; tt = itt->text; for (j = 0; j <= VSIw->allwidth; j++) { *tt++ = ' '; *ta++ = VSIclrattrib; } /* for */ itt = itt->next; } /* for */ VSIw->scrntop = ts; /* new topmost line (if it's changed) */ /* re-sync screen arrays */ VSIlistndx(ts); if (VSIw->Rtop >= 0) /* make sure vistop still points to same line position on screen that it did before */ VSIw->vistop = VSIw->linest[VSIw->Rtop]; /* and actually display the change on-screen */ VSIcdellines(VSIwn, s, VSIw->bottom, n, -1); /* Cancel current selection */ } /* VSIdellines */ void VSOdellines ( short n, /* nr lines to delete */ short s /* starting line to delete, -ve => line containing cursor */ ) /* deletes lines from the screen, scrolling up the remainder and inserting new blank lines at the bottom of the scrolling region. */ { short i, j; char *tt; unsigned short *ta; VSlinePtr as, ts, TD, BD, TI, BI, itt, ita; if (s < 0) s = VSIw->y; if (s + n - 1 > VSIw->bottom) n = VSIw->bottom - s + 1; /* don't bother deleting more than scrolling region will hold */ /* find new tops of screen arrays */ // RAB BetterTelnet 2.0b3 // way way too many bugs squashed // if (s == 0 && n <= VSIw->lines) if (s == 0 && n <= VSIw->bottom) { /* element for line after last one being deleted */ ts = VSIw->linest[n]; as = (VSlinePtr)VSIw->attrst[n]; } else { /* top line unaffected, or entire screen is being wiped */ ts = VSIw->linest[0]; as = (VSlinePtr)VSIw->attrst[0]; } /* if */ TD = VSIw->linest[s]; /* topmost line to delete */ BD = VSIw->linest[s + n - 1]; /* bottommost line to delete */ TI = VSIw->linest[VSIw->bottom]; /* insert replacement blank lines after this line */ BI = TI->next; /* insert them before this line (might be nil) */ itt = TD; /* start of text lines to be blanked out */ /* the space taken by the deleted lines will be reused for the inserted blank lines */ if (TD != BI && TI != BD) /* insertion and deletion areas not adjacent -- move the lines to their new position */ VSIlistmove(TD, BD, TI, BI); TD = (VSlinePtr)VSIw->attrst[s]; /* topmost line to delete */ BD = (VSlinePtr)VSIw->attrst[s + n - 1]; /* bottommost line to delete */ TI = (VSlinePtr)VSIw->attrst[VSIw->bottom]; /* insert new lines after this one */ BI = TI->next; /* insert them before this line */ /* perform same rearrangement on attribute lines as on text lines */ if (TD != BI && TI != BD) /* insertion and deletion areas not adjacent -- move the lines to their new position */ VSIlistmove(TD, BD, TI, BI); /* blank out the newly-created replacement lines */ ita = TD; /* start of attribute lines to be blanked out */ for (i = 0; i < n; i++) { ta = ((VSattrlinePtr)ita)->text; tt = itt->text; for (j = 0; j <= VSIw->allwidth; j++) { *tt++ = ' '; *ta++ = VSIclrattrib; } /* for */ ita = ita->next; itt = itt->next; } /* for */ VSIw->scrntop = ts; /* new topmost line (if it's changed) */ /* re-sync screen arrays */ VSOlistndx(ts, (VSattrlinePtr)as); if (VSIw->Rtop >= 0) /* make sure vistop still points to same line position on screen that it did before */ VSIw->vistop = VSIw->linest[VSIw->Rtop]; /* and actually display the change on-screen */ VSIcdellines(VSIwn, s, VSIw->bottom, n, -1); /* Cancel current selection */ } /* VSOdellines */ void VSIinslines ( short n, /* how many to insert */ short s /* where to insert them, -ve => line containing cursor */ ) /* inserts the specified number of blank lines, scrolling the remaining ones down, and dropping off any that fall off the end of the scrolling region. */ { short i, j; char *tt; unsigned short *ta; VSlinePtr ts, TD, BD, TI, BI, itt; VSIflush(); // RAB BetterTelnet 2.0b3 if (VSIw->oldScrollback) { VSOinslines(n, s); return; } if (s < 0) s = VSIw->y; if (s + n - 1 > VSIw->bottom) /* don't bother inserting more than scrolling region can hold */ n = VSIw->bottom - s + 1; /* find new tops of screen arrays */ if (s == 0 && n <= VSIw->lines) { /* element for first blank line being inserted */ ts = VSIw->linest[VSIw->bottom - n + 1]; } else { /* top line unaffected, or entire screen is being wiped */ ts = VSIw->linest[0]; } /* if */ BI = VSIw->linest[s]; /* insert blank lines before this one */ TI = BI->prev; /* insert them after this one */ TD = VSIw->linest[VSIw->bottom - n + 1]; /* topmost line to delete */ BD = VSIw->linest[VSIw->bottom]; /* bottommost line to delete */ itt = TD; /* start of text lines to be blanked out */ /* the space occupied by the deleted lines will be reused for the new blank lines */ if (TD != BI && TI != BD) /* new and deleted lines not contiguous -- move the space to its new position */ VSIlistmove(TD, BD, TI, BI); /* blank out the newly-inserted lines */ for (i = 0; i < n; i++) { tt = itt->text; ta = itt->attr; for (j = 0; j <= VSIw->allwidth; j++) { *tt++ = ' '; *ta++ = VSIclrattrib; } itt = itt->next; } /* for */ VSIw->scrntop = ts; VSIlistndx(ts); /* re-sync screen arrays */ if (VSIw->Rtop >= 0) /* make sure vistop still points to same line position on screen that it did before */ VSIw->vistop = VSIw->linest[VSIw->Rtop]; /* update display to match reality */ VSIcinslines(VSIwn, s, VSIw->bottom, n, -1); /* Destroy selection area if this is called tooo */ } /* VSIinslines */ void VSOinslines ( short n, /* how many to insert */ short s /* where to insert them, -ve => line containing cursor */ ) /* inserts the specified number of blank lines, scrolling the remaining ones down, and dropping off any that fall off the end of the scrolling region. */ { short i, j; char *tt; unsigned short *ta; VSlinePtr ts, TD, BD, TI, BI, itt; VSattrlinePtr as, aTD, aBD, aTI, aBI, ita; if (s < 0) s = VSIw->y; if (s + n - 1 > VSIw->bottom) /* don't bother inserting more than scrolling region can hold */ n = VSIw->bottom - s + 1; /* find new tops of screen arrays */ if (s == 0 && n <= VSIw->lines) { /* element for first blank line being inserted */ ts = VSIw->linest[VSIw->bottom - n + 1]; as = VSIw->attrst[VSIw->bottom - n + 1]; } else { /* top line unaffected, or entire screen is being wiped */ ts = VSIw->linest[0]; as = VSIw->attrst[0]; } /* if */ BI = VSIw->linest[s]; /* insert blank lines before this one */ TI = BI->prev; /* insert them after this one */ TD = VSIw->linest[VSIw->bottom - n + 1]; /* topmost line to delete */ BD = VSIw->linest[VSIw->bottom]; /* bottommost line to delete */ itt = TD; /* start of text lines to be blanked out */ /* the space occupied by the deleted lines will be reused for the new blank lines */ if (TD != BI && TI != BD) /* new and deleted lines not contiguous -- move the space to its new position */ VSIlistmove(TD, BD, TI, BI); aBI = VSIw->attrst[s]; /* insert new lines before this one */ aTI = aBI->prev; /* insert them after this one */ aTD = VSIw->attrst[VSIw->bottom - n + 1]; /* topmost line to delete */ aBD = VSIw->attrst[VSIw->bottom]; /* bottommost line to delete */ /* do the same rearrangement on the attribute lines */ if (aTD != aBI && aTI != aBD) /* new and deleted lines not contiguous -- move the space to its new position */ VSIlistmove((VSlinePtr)aTD, (VSlinePtr)aBD, (VSlinePtr)aTI, (VSlinePtr)aBI); /* blank out the newly-inserted lines */ ita = aTD; /* start of attribute lines to be blanked out */ for (i = 0; i < n; i++) { tt = itt->text; ta = ita->text; for (j = 0; j <= VSIw->allwidth; j++) { *tt++ = ' '; *ta++ = VSIclrattrib; } itt = itt->next; ita = ita->next; } /* for */ VSIw->scrntop = ts; VSOlistndx(ts, as); /* re-sync screen arrays */ if (VSIw->Rtop >= 0) /* make sure vistop still points to same line position on screen that it did before */ VSIw->vistop = VSIw->linest[VSIw->Rtop]; /* update display to match reality */ VSIcinslines(VSIwn, s, VSIw->bottom, n, -1); /* Destroy selection area if this is called tooo */ } /* VSOinslines */ void VSIscroll ( void ) /* scrolls scrolling region up one line. */ { register char *temp; register unsigned short *tempa; static VSlinePtr tmp, tmp2, tmp3, tmp4; register short i; short theBottom; /* NCSA 2.5: the correct screen bottom */ if (VSIw->y > VSIw->lines) /* BYU - replaces BYU modification below */ return; /* BYU */ if (VSIw->oldScrollback) { VSOscroll(); return; } if ((!VSIw->savelines) /* no scrollback */ || (VSIw->top != 0)) /* NCSA 2.5 */ // || ((VSIw->bottom != VSIw->lines) && !VSIw->forcesave)) /* NCSA 2.5 */ /* region being scrolled is not entire screen */ /* no saving of lines */ VSIdellines(1, VSIw->top); else { /* scrolling region is entire screen, and lines are being saved off top */ if (VSIw->linest[VSIw->lines]->next == 0L) { /* all currently-allocated scrollback lines have been used, but scrollback buffer isn't at its full size -- allocate some more space */ i = VSIw->maxlines - VSIw->numlines; /* number of lines that can be allocated */ if (i > ScrollbackQuantum) i = ScrollbackQuantum; /* don't bother allocating more than this at once */ if ((i > 0) && (tmp = VSInewlines(i)) != 0L) { /* link newly-allocated lines into the list */ VSIw->linest[VSIw->lines]->next = tmp; tmp->prev = VSIw->linest[VSIw->lines]; VSIw->numlines++; /* use one of the newly-allocated scrollback lines */ RSbufinfo(VSIwn, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* update vertical scroll bar accordingly */ } else { /* not enough memory to extend scrollback buffer--reuse oldest line and give up on future extensions */ VSIw->linest[VSIw->lines]->next = VSIw->buftop; /* Make it circular */ VSIw->buftop->prev = VSIw->linest[VSIw->lines]; VSIw->buftop = VSIw->buftop->next; /* step one forward */ } /* if */ } else { /* either there's allocated, but not yet used, space at VSIw->linest[VSIw->lines]->next, or the text line list is circular. Either way, don't do any new scrollback allocation. */ if (VSIw->linest[VSIw->lines]->next == VSIw->buftop) /* scrollback buffer is at full size--reuse oldest line */ VSIw->buftop = VSIw->buftop->next; else { /* haven't used up all the space I allocated last time */ VSIw->numlines++; /* count another line */ RSbufinfo(VSIwn, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* update vertical scroll bar accordingly */ } /* if */ } /* if */ VSIw->scrntop = VSIw->scrntop->next; /* scroll the screen buffer */ VSIlistndx(VSIw->scrntop); /* update screen arrays */ /* reflect the change in the display by scrolling up the visible part of the on-screen area, if any */ // if (VSIw->forcesave) theBottom = VSIw->bottom; /* NCSA 2.5: get the correct scroll rgn */ // else theBottom = VSIw->Rbottom; /* NCSA 2.5: just use whole screen */ if (VSIcdellines(VSIwn, VSIw->Rtop, theBottom, 1, 1)) /* NCSA 2.5 */ { /* no part of on-screen area is visible */ if (VSIw->Rtop > -VSIw->numlines) /* update bounds of visible region to be consistent with portion of scrollback buffer still being displayed */ { VSIw->Rtop--; VSIw->Rbottom--; } else { /* displaying right from top of scrollback buffer. Topmost line being shown has in fact vanished. Update the display to show this fact. */ VSIw->vistop = VSIw->vistop->next; RSdellines(VSIwn, 0, VSIw->Rbottom - VSIw->Rtop, 1, 1); } /* if */ } else VSIw->vistop = VSIw->vistop->next; /* consistent with changed display */ /* blank out newly-revealed bottom line */ tempa = VSIw->linest[VSIw->lines]->attr; temp = VSIw->linest[VSIw->lines]->text; for (i = 0; i <= VSIw->allwidth; i++) { *temp++ = ' '; *tempa++ = 0; } /* for */ // RAB BetterTelnet 1.2.1 - another bug fix for NCSA's insanity! if (VSIw->bottom != VSIw->lines) { // we're forcesaving here... tmp = VSIw->linest[VSIw->lines]->next; tmp2 = VSIw->linest[VSIw->lines]; tmp3 = VSIw->linest[VSIw->bottom]; tmp4 = VSIw->linest[VSIw->lines]->prev; VSIw->linest[VSIw->bottom]->prev->next = tmp2; tmp2->prev = VSIw->linest[VSIw->bottom]->prev; tmp2->next = tmp3; tmp3->prev = tmp2; tmp4->next = tmp; if (tmp4->next) tmp4->next->prev = tmp4; if (VSIw->scrntop == VSIw->linest[VSIw->bottom]) VSIw->scrntop = tmp2; VSIlistndx(VSIw->scrntop); } } /* if */ // if (RSisInFront(VSIwn)) // RSvalidateRect(VSIwn); } /* VSIscroll */ void VSOscroll ( void ) /* scrolls scrolling region up one line. */ { register char *temp; register unsigned short *tempa; register short i; short theBottom; /* NCSA 2.5: the correct screen bottom */ static VSlinePtr tmp, tmp2, tmp3, tmp4; if (VSIw->y > VSIw->lines) /* BYU - replaces BYU modification below */ return; /* BYU */ if ((!VSIw->savelines) /* no scrollback */ || (VSIw->top != 0)) /* NCSA 2.5 */ // || ((VSIw->bottom != VSIw->lines) && !VSIw->forcesave)) /* NCSA 2.5 */ /* region being scrolled is not entire screen */ /* no saving of lines */ VSOdellines(1, VSIw->top); else { /* scrolling region is entire screen, and lines are being saved off top */ if (VSIw->linest[VSIw->lines]->next == 0L) { /* all currently-allocated scrollback lines have been used, but scrollback buffer isn't at its full size -- allocate some more space */ i = VSIw->maxlines - VSIw->numlines; /* number of lines that can be allocated */ if (i > ScrollbackQuantum) i = ScrollbackQuantum; /* don't bother allocating more than this at once */ if ((i > 0) && (tmp = VSOnewlines(i,1)) != 0L) { /* link newly-allocated lines into the list */ VSIw->linest[VSIw->lines]->next = tmp; tmp->prev = VSIw->linest[VSIw->lines]; VSIw->numlines++; /* use one of the newly-allocated scrollback lines */ RSbufinfo(VSIwn, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* update vertical scroll bar accordingly */ } else { /* not enough memory to extend scrollback buffer--reuse oldest line and give up on future extensions */ VSIw->linest[VSIw->lines]->next = VSIw->buftop; /* Make it circular */ VSIw->buftop->prev = VSIw->linest[VSIw->lines]; VSIw->buftop = VSIw->buftop->next; /* step one forward */ } /* if */ } else { /* either there's allocated, but not yet used, space at VSIw->linest[VSIw->lines]->next, or the text line list is circular. Either way, don't do any new scrollback allocation. */ if (VSIw->linest[VSIw->lines]->next == VSIw->buftop) /* scrollback buffer is at full size--reuse oldest line */ VSIw->buftop = VSIw->buftop->next; else { /* haven't used up all the space I allocated last time */ VSIw->numlines++; /* count another line */ RSbufinfo(VSIwn, VSIw->numlines, VSIw->Rtop, VSIw->Rbottom); /* update vertical scroll bar accordingly */ } /* if */ } /* if */ VSIw->scrntop = VSIw->scrntop->next; /* scroll the screen buffer */ VSOlistndx(VSIw->scrntop, VSIw->attrst[1]); /* update screen arrays */ /* reflect the change in the display by scrolling up the visible part of the on-screen area, if any */ // if (VSIw->forcesave) theBottom = VSIw->bottom; /* NCSA 2.5: get the correct scroll rgn */ // else theBottom = VSIw->Rbottom; /* NCSA 2.5: just use whole screen */ if (VSIcdellines(VSIwn, VSIw->Rtop, theBottom, 1, 1)) /* NCSA 2.5 */ { /* no part of on-screen area is visible */ if (VSIw->Rtop > -VSIw->numlines) /* update bounds of visible region to be consistent with portion of scrollback buffer still being displayed */ { VSIw->Rtop--; VSIw->Rbottom--; } else { /* displaying right from top of scrollback buffer. Topmost line being shown has in fact vanished. Update the display to show this fact. */ VSIw->vistop = VSIw->vistop->next; RSdellines(VSIwn, 0, VSIw->Rbottom - VSIw->Rtop, 1, 1); } /* if */ } else VSIw->vistop = VSIw->vistop->next; /* consistent with changed display */ /* blank out newly-revealed bottom line */ tempa = VSIw->attrst[VSIw->lines]->text; temp = VSIw->linest[VSIw->lines]->text; for (i = 0; i <= VSIw->allwidth; i++) { *temp++ = ' '; *tempa++ = 0; } /* for */ // RAB BetterTelnet 1.2.1 - Return of the Bug Fix! if (VSIw->bottom != VSIw->lines) { // we're forcesaving here... tmp = VSIw->linest[VSIw->lines]->next; tmp2 = VSIw->linest[VSIw->lines]; tmp3 = VSIw->linest[VSIw->bottom]; tmp4 = VSIw->linest[VSIw->lines]->prev; VSIw->linest[VSIw->bottom]->prev->next = tmp2; tmp2->prev = VSIw->linest[VSIw->bottom]->prev; tmp2->next = tmp3; tmp3->prev = tmp2; tmp4->next = tmp; if (tmp4->next) tmp4->next->prev = tmp4; if (VSIw->scrntop == VSIw->linest[VSIw->bottom]) VSIw->scrntop = tmp2; // now for the attribute lines... VSIw->attrst[VSIw->lines]->next->prev = VSIw->attrst[VSIw->lines]->prev; VSIw->attrst[VSIw->lines]->prev->next = VSIw->attrst[VSIw->lines]->next; VSIw->attrst[VSIw->bottom]->prev->next = VSIw->attrst[VSIw->lines]; VSIw->attrst[VSIw->lines]->prev = VSIw->attrst[VSIw->bottom]->prev; VSIw->attrst[VSIw->lines]->next = VSIw->attrst[VSIw->bottom]; VSIw->attrst[VSIw->bottom]->prev = VSIw->attrst[VSIw->lines]; VSOlistndx(VSIw->scrntop, VSIw->attrst[0]); } } /* if */ // if (RSisInFront(VSIwn)) // RSvalidateRect(VSIwn); } /* VSOscroll */ // RAB BetterTelnet 2.0b3 - flush the jump scroller here void VSIflush(void) { if (!VSIw->linesjumped) return; // nothing to flush RSlocal[VSIwn].skip = 0; VSIcdellines(VSIwn, VSIw->top, VSIw->bottom, VSIw->linesjumped, -1); if (VSIw->linesjumped > (VSIw->bottom - VSIw->top)) VSredraw(VSIwn, 0, VSIw->top - VSIw->Rtop, VSIw->maxwidth, VSIw->bottom - VSIw->Rtop); // redraw the whole thing else // redraw just a part of the screen VSredraw(VSIwn, 0, VSIw->bottom - VSIw->linesjumped + 1 - VSIw->Rtop, VSIw->maxwidth, VSIw->bottom - VSIw->Rtop); VSIw->linesjumped = 0; } void VSIindex ( void ) /* moves cursor down one line, unless it's at the bottom of the scrolling region, in which case scrolls up one. */ // RAB BetterTelnet 2.0b3 - added jump scrolling so it runs faster { if (VSIw->y == VSIw->bottom) { /* BYU - changed "==" to ">=" and back again */ if (VSIw->jumpScroll) if (VSIw->linesjumped || !RSlocal[VSIwn].skip) /* if ((VSIw->top == 0) && (VSIw->bottom == VSIw->lines)) */ { RSlocal[VSIwn].skip = 1; VSIw->linesjumped++; if (VSIw->linesjumped > (VSIw->bottom - VSIw->top)) VSIflush(); } VSIscroll(); } else if (VSIw->y < VSIw->lines) /* BYU - added "if ... " */ VSIw->y++; } /* VSIindex */ void VSIwrapnow(short *xp, short *yp) /* checks current cursor position for VSIw to see if it's within bounds, wrapping to next line if not. Returns correct cursor position in either case in *xp and *yp. */ { if (VSIw->x > VSIw->maxwidth) { VSIw->x = 0; VSIindex(); } /* if */ *xp = VSIw->x; *yp = VSIw->y; } /* VSIwrapnow */ void VSIeeol ( void ) /* erases characters to the end of the current line. */ { char *tt; unsigned short *ta; short x1 = VSIw->x, y1 = VSIw->y, x2 = VSIw->maxwidth, y2 = VSIw->y, n = -1, offset; short i; // RAB BetterTelnet 2.0b1 - Fix for forcesave bug VSlinePtr savedTextBlock, savedTextPtr; if ((VSIw->x == 0)&&(VSIw->y == 0)&&(VSIw->possibleForce == 1)) { VSIw->possibleForce = 0; savedTextBlock = VSInewlines(VSIw->lines + 1); savedTextPtr = savedTextBlock; for (i = 0; i <= VSIw->lines; i++) { BlockMoveData(VSIw->linest[i]->text, savedTextPtr->text, VSIw->allwidth + 1); if (savedTextPtr->next) savedTextPtr = savedTextPtr->next; } savedTextPtr = savedTextBlock; for (i = 0; i <= VSIw->lines; i++) { if (VSIw->oldScrollback) BlockMoveData(VSIw->attrst[i]->text, savedTextPtr->attr, (VSIw->allwidth + 1) * 2); else BlockMoveData(VSIw->linest[i]->attr, savedTextPtr->attr, (VSIw->allwidth + 1) * 2); if (savedTextPtr->next) savedTextPtr = savedTextPtr->next; } VSIscroff(); savedTextPtr = savedTextBlock; for (i = 0; i <= VSIw->lines; i++) { BlockMoveData(savedTextPtr->text, VSIw->linest[i]->text, VSIw->allwidth + 1); if (savedTextPtr->next) savedTextPtr = savedTextPtr->next; } savedTextPtr = savedTextBlock; for (i = 0; i <= VSIw->lines; i++) { if (VSIw->oldScrollback) BlockMoveData(savedTextPtr->attr, VSIw->attrst[i]->text, (VSIw->allwidth + 1) * 2); else BlockMoveData(savedTextPtr->attr, VSIw->linest[i]->attr, (VSIw->allwidth + 1) * 2); if (savedTextPtr->next) savedTextPtr = savedTextPtr->next; } DisposePtr((Ptr) savedTextBlock); // VSIfreelinelist adds un-needed overhead here } VSIwrapnow(&x1, &y1); y2 = y1; /* clear out screen line */ if (VSIw->oldScrollback) ta = &VSIw->attrst[y1]->text[x1]; else ta = &VSIw->linest[y1]->attr[x1]; tt = &VSIw->linest[y1]->text[x1]; for (i = VSIw->allwidth - x1 + 1; i > 0; i--) { *ta++ = VSIclrattrib; *tt++ = ' '; } /* update display */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSerase(VSIwn, x1, y1, x2, y2); } /* VSIeeol */ void VSIdelchars ( short x /* how many characters to delete */ ) /* deletes characters at the current cursor position onwards, moving the remainder of the line to the left. */ { short i; short x1 = VSIw->x, y1 = VSIw->y, x2 = VSIw->maxwidth, y2 = VSIw->y, n = -1, offset; char *temp; unsigned short *tempa; VSIwrapnow(&x1, &y1); y2 = y1; if (x > VSIw->maxwidth) x = VSIw->maxwidth; if (VSIw->oldScrollback) tempa = VSIw->attrst[y1]->text; else tempa = VSIw->linest[y1]->attr; temp = VSIw->linest[y1]->text; for (i = x1; i <= VSIw->maxwidth - x; i++) { /* move remainder of line to the left */ temp[i] = temp[x + i]; tempa[i] = tempa[x + i]; } for (i = VSIw->maxwidth - x + 1; i <= VSIw->allwidth; i++) { /* insert blank characters after end of line */ temp[i] = ' '; tempa[i] = VSIclrattrib; } /* update display */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSdelchars(VSIwn, x1, y1, x); } /* VSIdelchars */ void VSIfreelinelist ( VSlinePtr listhead ) /* frees up the list of line elements pointed to by listhead. */ { register VSlinePtr ThisElt, NextElt, ToFree; ThisElt = listhead; ToFree = nil; while (true) { if (ThisElt == nil) break; NextElt = ThisElt->next; if (ThisElt->mem) { ThisElt->next = ToFree; ToFree = ThisElt; } /* if */ ThisElt = NextElt; if (ThisElt == listhead) break; } /* while */ while (ToFree) { NextElt = ToFree->next; DisposePtr((Ptr) ToFree); if (VSIw->oldScrollback) DisposePtr((Ptr) ToFree->text); ToFree = NextElt; } /* while */ } /* VSIfreelinelist */ void VSIfreelines ( void ) /* frees up all the memory allocated for screen and scrollback text lines for the current screen. */ { VSIfreelinelist(VSIw->buftop); } /* VSIfreelines */ void VSIrindex ( void ) /* moves cursor up one line, unless it's at the top of the scrolling region, in which case scrolls down one. */ { VSIflush(); // RAB BetterTelnet 2.0b3 if (VSIw->y == VSIw->top) VSIinslines(1, VSIw->top); else VSIw->y--; } /* VSIrindex */ void VSIebol ( void ) /* erases characters from beginning of line to cursor. */ { char *tt; unsigned short *ta; short x1 = 0, y1 = VSIw->y, x2 = VSIw->x, y2 = VSIw->y, n = -1, offset; short i; VSIwrapnow(&x2, &y1); y2 = y1; /* clear from beginning of line to cursor */ if (VSIw->oldScrollback) ta = &VSIw->attrst[y1]->text[0]; else ta = &VSIw->linest[y1]->attr[0]; tt = &VSIw->linest[y1]->text[0]; for (i = 0; i <= x2; i++) { *ta++ = VSIclrattrib; *tt++ = ' '; } /* update display */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSerase(VSIwn, x1, y1, x2, y2); } /* VSIebol */ void VSIel ( short s /* line to clear, -ve => line containing cursor */ ) /* erases the specified line. */ { char *tt; unsigned short *ta; short x1 = 0, y1 = s, x2 = VSIw->maxwidth, y2 = s, n = -1, offset; short i; if (s < 0) { VSIwrapnow(&x1, &y1); s = y2 = y1; x1 = 0; } /* clear out line */ if (VSIw->oldScrollback) ta = &VSIw->attrst[s]->text[0]; else ta = &VSIw->linest[s]->attr[0]; tt = &VSIw->linest[s]->text[0]; for(i = 0; i <= VSIw->allwidth; i++) { *ta++ = VSIclrattrib; *tt++ = ' '; } /* update display */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSerase(VSIwn, x1, y1, x2, y2); } /* VSIel */ void VSIeeos ( void ) /* erases characters from cursor to end of screen. */ { short i; short x1 = 0, y1 = VSIw->y + 1, x2 = VSIw->maxwidth, y2 = VSIw->lines, n = -1, offset; VSIflush(); // RAB BetterTelnet 2.0b3 VSIwrapnow(&x1, &y1); y1++; x1 = 0; i = y1; if ((VSIw->ESscroll)&&(VSIw->y == 0)&&(VSIw->x == 0)) //trashes screen unless we are in 0,0 VSIscroff(); VSIw->possibleForce = FALSE; //CCP better forcesave stuff /* erase complete lines from screen */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSerase(VSIwn, x1, y1, x2, y2); /* blank out current line from cursor to end */ VSIeeol(); /* this also erases the partial line on-screen */ /* blank out remaining lines to end of screen */ while (i <= VSIw->lines) { VSIelo(i); i++; } /* while */ if (VSIw->y < VSIw->lines && (VSIw->x <= VSIw->maxwidth)) /* erase the partial line (what--again??) */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSerase(VSIwn, x1, y1, x2, y2); } /* VSIeeos */ void VSIebos ( void ) /* erases characters from beginning of screen to cursor. */ { short i; short x1, y1, x2 = VSIw->maxwidth, y2, n = -1, offset; VSIflush(); // RAB BetterTelnet 2.0b3 VSIwrapnow(&x1, &y1); y2 = y1 - 1; x1 = 0; y1 = 0; /* blank out current line from beginning to cursor */ VSIebol(); /* this also erases the partial line on-screen */ i = 0; /* blank out remaining lines from beginning of screen to previous line */ while (i < (y2 + 1)) { VSIelo(i); i++; } if (y2 >= 0) /* erase the partial line (what--again??) */ if (!VSIclip(&x1, &y1, &x2, &y2, &n, &offset)) RSerase(VSIwn, x1, y1, x2, y2); } /* VSIebos */ void VSIrange ( void ) /* constrains cursor position to valid range (somewhere on the screen). */ { short wrap = 0; if (VSIw->DECAWM) wrap = 1; if (VSIw->x < 0) VSIw->x = 0; if (VSIw->x > (VSIw->maxwidth + wrap)) VSIw->x = VSIw->maxwidth + wrap; if (VSIw->y < 0) VSIw->y = 0; if (VSIw->y > VSIw->lines) VSIw->y = VSIw->lines; } /* VSIrange */ void VTsendpos ( void ) /* sends an escape sequence representing the current cursor position. */ { char tempbuf[19]; short x = VSIw->x, y = VSIw->y; if (x > VSIw->maxwidth) { /* autowrap pending */ x = 0; y++; } if (y > VSIw->lines) /* scroll pending (because of the autowrap) */ y = VSIw->lines; sprintf(tempbuf, "\033[%d;%dR", y + 1, x + 1); RSsendstring(VSIwn, tempbuf, strlen(tempbuf)); } /* VTsendpos */ void VTsendstat ( void ) /* sends the terminal status string. */ { RSsendstring(VSIwn, "\033[0n", 4); } /* VTsendstat */ void VTsendident ( void ) /* sends an appropriate terminal identification sequence. */ { if (screens[findbyVS(VSIwn)].vtemulation) RSsendstring(VSIwn, "\033[?62;1;6c", 10); /* BYU 2.4.12 - VT200-series*/ else /* BYU 2.4.12 */ RSsendstring(VSIwn, "\033[?6c", 5); /* BYU 2.4.12 - VT102 */ } /* VTsendident */ void VTalign ( void ) /* fills screen with uppercase "E"s, for checking screen alignment. */ /* Yeah, right. */ { char *tt; short i, j; VSIes(); /* erase the screen */ for (j = 0; j < VSIw->lines; j++) { tt = &VSIw->linest[j]->text[0]; for (i = 0; i <= VSIw->maxwidth; i++) *tt++ = 'E'; } /* for */ /* update the display */ VSredraw(VSIwn, 0, 0, (VSIw->Rright - VSIw->Rleft), (VSIw->Rbottom - VSIw->Rtop)); } /* VTalign */ void VSIapclear ( void ) /* initializes all the parameters for the current control sequence, and the current param index, to zero. */ { short parmptr = maxparms; while (--parmptr >= 0) VSIw->parms[parmptr] = -1; VSIw->parmptr = 0; } /* VSIapclear */ void VSIsetoption ( short toggle /* 1 => set, 0 => reset */ ) /* sets/resets various options, as specified by the parms in the current control sequence. Note that this implementation will not set/reset more than one option at a time! */ { short WindWidth = VSIw->Rright - VSIw->Rleft; switch (VSIw->parms[0]) { case -2: /* DEC-private control sequence */ switch (VSIw->parms[1]) { case 1: /* cursor-key mode */ VSIw->DECCKM = toggle; break; case 3: /* 80/132 columns */ // VSIw->x = VSIw->y = 0; /* home cursor */ // VSIes(); /* and clear screen */ VSIflush(); // RAB BetterTelnet 2.0b3 if (toggle) /* 132 column mode */ { /* NCSA: SB */ VSIw->maxwidth = 131; /* NCSA: SB */ RScalcwsize(VSIwn,132); /* NCSA: SB */ } /* NCSA: SB */ else /* NCSA: SB */ { /* NCSA: SB */ VSIw->maxwidth = 79; /* NCSA: SB */ RScalcwsize(VSIwn,80); /* NCSA: SB */ } /* NCSA: SB */ /* update scroll bars */ RSmargininfo(VSIwn, VSIw->maxwidth, VSIw->Rleft); /* NCSA: SB */ break; /* NCSA: SB - this next one will allow us to flip the foreground and */ /* background colors. */ case 5: /* NCSA: SB - screen mode */ VSIflush(); // RAB BetterTelnet 2.0b3 RSbackground(VSIwn,toggle); break; case 6: /* origin mode */ VSIw->DECORG = toggle; break; case 7: /* autowrap mode */ VSIw->DECAWM = toggle; break; case 25: /* cursor mode */ VSIw->DECCM = toggle; break; default: break; } /* switch */ break; case 4: /* insert/replace character writing mode */ VSIw->IRM = toggle; break; default: break; } /* switch */ } /* VSIsetoption */ void VSItab //BUGG ( void ) /* advances VSIw->x to the next tab position. */ { VSIw->x += VSIgetNextTabDistance(); } /* VSItab */ void VSIinschar ( short x /* number of blanks to insert */ ) /* inserts the specified number of blank characters at the current cursor position, moving the rest of the line along, losing any characters that fall off the right margin. Does not update the display. */ { short i, j; char *temp; unsigned short *tempa; VSIwrapnow(&i, &j); if (VSIw->oldScrollback) tempa = VSIw->attrst[VSIw->y]->text; else tempa = VSIw->linest[VSIw->y]->attr; temp = VSIw->linest[VSIw->y]->text; for (i = VSIw->maxwidth - x; i >= VSIw->x; i--) { /* move along remaining characters on line */ temp[x + i] =temp[i]; tempa[x + i] = tempa[i]; } /* for */ for (i = VSIw->x; i < VSIw->x + x; i++) { /* insert appropriate number of blanks */ temp[i] = ' '; tempa[i] = VSIclrattrib; } /* for */ } /* VSIinschar */ void VSIinsstring ( short len, char *start ) /* updates the screen to show insertion of a string of characters at the current cursor position. The text has already been inserted into the screen buffer. Also, the cursor position has already been updated, so the part needing redrawing begins at column (VSIw->x - len). */ { RSinsstring(VSIwn, VSIw->x - len, VSIw->y, VSIw->attrib, len, start); } /* VSIinsstring */ void VSIsave ( void ) /* saves the current cursor position and attribute settings. */ { VSIw->Px = VSIw->x; VSIw->Py = VSIw->y; VSIw->Pattrib = VSIw->attrib; } /* VSIsave */ void VSIrestore ( void ) /* restores the last-saved cursor position and attribute settings. */ { if (VSIw->Pattrib < 0) /* no previous save */ return; VSIflush(); // RAB BetterTelnet 2.0b3 VSIw->x = VSIw->Px; VSIw->y = VSIw->Py; VSIrange(); VSIw->attrib = VSinattr(VSIw->Pattrib); /* hmm, this will clear the graphics character set selection */ } /* VSIrestore */ void VSIdraw ( short VSIwn, /* window number */ short x, /* starting column */ short y, /* line on which to draw */ short a, /* text attributes */ short len, /* length of text to draw */ char *c /* pointer to text */ ) /* displays a piece of text (assumed to fit on a single line) on a screen, using the specified attributes, and clipping to the current visible region. Highlights any part of the text lying within the current selection. */ { short x2, y2, offset; if (!VSIclip(&x, &y, &x2, &y2, &len, &offset)) RSdraw(VSIwn, x, y, a, len, (char *) (c + offset)); /* BYU LSC */ } /* VSIdraw */ short VSIgetblinkflag(void) { return VSIw->realBlink; } \ No newline at end of file diff --git a/source/Screens/vsintern.proto.h b/source/Screens/vsintern.proto.h index 14c8c5b..b8b1178 100755 --- a/source/Screens/vsintern.proto.h +++ b/source/Screens/vsintern.proto.h @@ -1 +1 @@ - /* vsintern.c */ short VSIclip(short *x1, short *y1, short *x2, short *y2, short *n, short *offset); short VSIcdellines(short w, short top, short bottom, short n, short scrolled); short VSIcinslines(short w, short top, short bottom, short n, short scrolled); void VSIcurson(short w, short x, short y, short ForceMove); void VSIcuroff(short w); short VSIcursorvisible(void); VSlineArray VSInewlinearray(short nrlines); VSlinePtr VSInewlines(short nlines); VSlinePtr VSOnewlines(short, short); void VSIlistndx(register VSlinePtr ts); void VSOlistndx(register VSlinePtr ts, register VSattrlinePtr as); void VSIscroff(void); void VSOscroff(void); void VSIelo(short s); void VSIes(void); void VSItabclear(void); void VSItabinit(void); void VSIreset(void); void VSIlistmove(VSlinePtr TD, VSlinePtr BD, VSlinePtr TI, VSlinePtr BI); void VSIdellines(short n, short s); void VSIinslines(short n, short s); void VSOdellines(short n, short s); void VSOinslines(short n, short s); void VSIscroll(void); void VSOscroll(void); void VSIindex(void); void VSIwrapnow(short *xp, short *yp); void VSIeeol(void); void VSIdelchars(short x); void VSIfreelinelist(VSlinePtr listhead); void VSIfreelines(void); void VSIrindex(void); void VSIebol(void); void VSIel(short s); void VSIeeos(void); void VSIebos(void); void VSIrange(void); void VTsendpos(void); void VTsendstat(void); void VTsendident(void); void VTalign(void); void VSIapclear(void); void VSIsetoption(short toggle); void VSItab(void); void VSIinschar(short x); void VSIinsstring(short len, char *start); void VSIsave(void); void VSIrestore(void); void VSIdraw(short VSIwn, short x, short y, short a, short len, char *c); \ No newline at end of file + /* vsintern.c */ short VSIclip(short *x1, short *y1, short *x2, short *y2, short *n, short *offset); short VSIcdellines(short w, short top, short bottom, short n, short scrolled); short VSIcinslines(short w, short top, short bottom, short n, short scrolled); void VSIcurson(short w, short x, short y, short ForceMove); void VSIcuroff(short w); short VSIcursorvisible(void); VSlineArray VSInewlinearray(short nrlines); VSlinePtr VSInewlines(short nlines); VSlinePtr VSOnewlines(short, short); void VSIlistndx(register VSlinePtr ts); void VSOlistndx(register VSlinePtr ts, register VSattrlinePtr as); void VSIscroff(void); void VSOscroff(void); void VSIelo(short s); void VSIes(void); void VSItabclear(void); void VSItabinit(void); void VSIreset(void); void VSIlistmove(VSlinePtr TD, VSlinePtr BD, VSlinePtr TI, VSlinePtr BI); void VSIdellines(short n, short s); void VSIinslines(short n, short s); void VSOdellines(short n, short s); void VSOinslines(short n, short s); void VSIscroll(void); void VSOscroll(void); void VSIindex(void); void VSIwrapnow(short *xp, short *yp); void VSIeeol(void); void VSIdelchars(short x); void VSIfreelinelist(VSlinePtr listhead); void VSIfreelines(void); void VSIrindex(void); void VSIebol(void); void VSIel(short s); void VSIeeos(void); void VSIebos(void); void VSIrange(void); void VTsendpos(void); void VTsendstat(void); void VTsendident(void); void VTalign(void); void VSIapclear(void); void VSIsetoption(short toggle); void VSItab(void); void VSIinschar(short x); void VSIinsstring(short len, char *start); void VSIsave(void); void VSIrestore(void); void VSIdraw(short VSIwn, short x, short y, short a, short len, char *c); void VSIflush(void); void VSIcursdisable(); void VSIcursenable(); short VSIgetblinkflag(); \ No newline at end of file diff --git a/source/Screens/vskeys.h b/source/Screens/vskeys.h index 4a90afc..a773891 100755 --- a/source/Screens/vskeys.h +++ b/source/Screens/vskeys.h @@ -1 +1 @@ -/* * %W% (NCSA) %G% * * Virtual Screen Kernel Keys and Attribute Definitions * * National Center for Supercomputing Applications * by Gaige B. Paulsen * * This file contains equates used by the program for specification of * special Keyboard characters and definition of the Attribute byte. * * Version Date Notes * ------- ------ --------------------------------------------------- * 0.01 861102 Initial coding -GBP * 2.1 871130 NCSA Telnet 2.1 -GBP * 2.2 880715 NCSA Telnet 2.2 -GBP * */ /* internal codes for identifying special keys */ #define VSF10 96 /* Function key 10 */ /* Mac Key F5 */ /* BYU 2.4.12 */ #define VSF11 97 /* Function key 11 */ /* Mac Key F6 */ /* BYU 2.4.12 */ #define VSF12 98 /* Function key 12 */ /* Mac Key F7 */ /* BYU 2.4.12 */ #define VSF8 99 /* Function key 8 */ /* Mac Key F3 */ /* BYU 2.4.12 */ #define VSF13 100 /* Function key 13 */ /* Mac Key F8 */ /* BYU 2.4.12 */ #define VSF14 101 /* Function key 14 */ /* Mac Key F9 */ /* BYU 2.4.12 */ #define VSF16 103 /* Function key 16 */ /* Mac Key F11 */ /* BYU 2.4.12 */ #define VSF18 105 /* Function key 18 */ /* Mac Key F13 */ /* BYU 2.4.12 */ #define VSF19 107 /* Function key 19 */ /* Mac Key F14 */ /* BYU 2.4.12 */ #define VSF15 109 /* Function key 15 */ /* Mac Key F10 */ /* BYU 2.4.12 */ #define VSF17 111 /* Function key 17 */ /* Mac Key F12 */ /* BYU 2.4.12 */ #define VSF20 113 /* Function key 20 */ /* Mac Key F15 */ /* BYU 2.4.12 */ #define VSHELP 114 /* Help */ /* BYU 2.4.12 */ #define VSHOME 115 /* Home */ /* BYU 2.4.12 */ #define VSPGUP 116 /* Page up */ /* BYU 2.4.12 */ #define VSDEL 117 /* Del */ /* BYU 2.4.12 */ #define VSF9 118 /* Function key 9 */ /* Mac Key F4 */ /* BYU 2.4.12 */ #define VSEND 119 /* End */ /* BYU 2.4.12 */ #define VSF7 120 /* Function key 7 */ /* Mac Key F2 */ /* BYU 2.4.12 */ #define VSPGDN 121 /* Page down */ /* BYU 2.4.12 */ #define VSF6 122 /* Function key 6 */ /* Mac Key F1 */ /* BYU 2.4.12 */ /* Following group is the "Cursor Control" keys */ #define VSUP 129 /* Up Arrow */ #define VSDN 130 /* Down Arrow */ #define VSRT 131 /* Right Arrow */ #define VSLT 132 /* Left Arrow */ /* Following group is the "Auxilliary Keypad" keys */ #define VSK0 133 /* Keypad 0 */ #define VSK1 134 /* Keypad 1 */ #define VSK2 135 /* Keypad 2 */ #define VSK3 136 /* Keypad 3 */ #define VSK4 137 /* Keypad 4 */ #define VSK5 138 /* Keypad 5 */ #define VSK6 139 /* Keypad 6 */ #define VSK7 140 /* Keypad 7 */ #define VSK8 141 /* Keypad 8 */ #define VSK9 142 /* Keypad 9 */ #define VSKC 143 /* Keypad , */ #define VSKM 144 /* Keypad - */ #define VSKP 145 /* Keypad . */ #define VSKE 146 /* Keypad Enter */ #define VSF1 147 /* Function 1 */ /* Mac Keypad Clear */ #define VSF2 148 /* Function 2 */ /* Mac Keypad = */ #define VSF3 149 /* Function 3 */ /* Mac Keypad / */ #define VSF4 150 /* Function 4 */ /* Mac Keypad * */ #ifdef VSMASTER char VSIkpxlate[2][23] = { "ABCD0123456789,-.\15PQRS", "ABCDpqrstuvwxylmnMPQRS" }; char VSIkpxlate2[] = "222122?2?3?3?2?3?3123425161"; /* BYU 2.4.12 */ char VSIkpxlate3[] = "134956?9?2?3?8?1?4~~~~0~8~7"; /* BYU 2.4.12 */ unsigned char VSIkplen[] = /* BYU 2.4.12 */ { 5,5,5,5,5,5,5,5,5,5, /* BYU 2.4.12 */ 5,5,5,5,5,5,5,5,4,4, /* BYU 2.4.12 */ 4,4,5,4,5,4,5 }; /* BYU 2.4.12 */ #else extern char *VSIkpxlate,*VSIkpxlate2,*VSIkpxlate2; /* BYU 2.4.12 */ extern unsigned char *VSIkplen; /* BYU 2.4.12 */ #endif /* * Definition of attribute bits in the Virtual Screen * * 0 - Bold * 1 - * 2 - * 3 - Underline * 4 - Blink * 5 - * 6 - Reverse * 7 - Graphics character set * 8 - bit 0 of ansi foreground color index * 9 - bit 1 of ansi foreground color index * 10 - bit 2 of ansi foreground color index * 11 - use ansi foreground color * 12 - bit 0 of ansi background color index * 13 - bit 1 of ansi background color index * 14 - bit 2 of ansi background color index * 15 - use ansi background color * */ #define VSa(x) ( 1 << ((x)-1) ) #define VSisbold(x) ((x) & 0x01) #define VSisundl(x) ((x) & 0x08) #define VSisblnk(x) ((x) & 0x10) #define VSisrev(x) ((x) & 0x40) #define VSisgrph(x) ((x) & 0x80) #define VSinattr(x) ((x) & 0xff) #define VSgraph(x) ((x) | 0x80) #define VSnotgraph(x) ((x) & 0x7F) #define VSisansifg(x) ((x) & 0x0800) #define VSisansibg(x) ((x) & 0x8000) #define VSisansi(x) ((x) & 0x8800) //#define VSisbold(x) (x & 0x01) //#define VSisundl(x) (x & 0x08) //#define VSisblnk(x) (x & 0x10) //#define VSisrev(x) (x & 0x40) //#define VSisgrph(x) (x & 0x80) //#define VSinattr(x) (x & 0xd9) //#define VSgraph(x) (x | 0x80) //#define VSnotgraph(x) (x & 0x7F) \ No newline at end of file +/* * %W% (NCSA) %G% * * Virtual Screen Kernel Keys and Attribute Definitions * * National Center for Supercomputing Applications * by Gaige B. Paulsen * * This file contains equates used by the program for specification of * special Keyboard characters and definition of the Attribute byte. * * Version Date Notes * ------- ------ --------------------------------------------------- * 0.01 861102 Initial coding -GBP * 2.1 871130 NCSA Telnet 2.1 -GBP * 2.2 880715 NCSA Telnet 2.2 -GBP * */ /* internal codes for identifying special keys */ #define VSF10 96 /* Function key 10 */ /* Mac Key F5 */ /* BYU 2.4.12 */ #define VSF11 97 /* Function key 11 */ /* Mac Key F6 */ /* BYU 2.4.12 */ #define VSF12 98 /* Function key 12 */ /* Mac Key F7 */ /* BYU 2.4.12 */ #define VSF8 99 /* Function key 8 */ /* Mac Key F3 */ /* BYU 2.4.12 */ #define VSF13 100 /* Function key 13 */ /* Mac Key F8 */ /* BYU 2.4.12 */ #define VSF14 101 /* Function key 14 */ /* Mac Key F9 */ /* BYU 2.4.12 */ #define VSF16 103 /* Function key 16 */ /* Mac Key F11 */ /* BYU 2.4.12 */ #define VSF18 105 /* Function key 18 */ /* Mac Key F13 */ /* BYU 2.4.12 */ #define VSF19 107 /* Function key 19 */ /* Mac Key F14 */ /* BYU 2.4.12 */ #define VSF15 109 /* Function key 15 */ /* Mac Key F10 */ /* BYU 2.4.12 */ #define VSF17 111 /* Function key 17 */ /* Mac Key F12 */ /* BYU 2.4.12 */ #define VSF20 113 /* Function key 20 */ /* Mac Key F15 */ /* BYU 2.4.12 */ #define VSHELP 114 /* Help */ /* BYU 2.4.12 */ #define VSHOME 115 /* Home */ /* BYU 2.4.12 */ #define VSPGUP 116 /* Page up */ /* BYU 2.4.12 */ #define VSDEL 117 /* Del */ /* BYU 2.4.12 */ #define VSF9 118 /* Function key 9 */ /* Mac Key F4 */ /* BYU 2.4.12 */ #define VSEND 119 /* End */ /* BYU 2.4.12 */ #define VSF7 120 /* Function key 7 */ /* Mac Key F2 */ /* BYU 2.4.12 */ #define VSPGDN 121 /* Page down */ /* BYU 2.4.12 */ #define VSF6 122 /* Function key 6 */ /* Mac Key F1 */ /* BYU 2.4.12 */ /* Following group is the "Cursor Control" keys */ #define VSUP 129 /* Up Arrow */ #define VSDN 130 /* Down Arrow */ #define VSRT 131 /* Right Arrow */ #define VSLT 132 /* Left Arrow */ /* Following group is the "Auxilliary Keypad" keys */ #define VSK0 133 /* Keypad 0 */ #define VSK1 134 /* Keypad 1 */ #define VSK2 135 /* Keypad 2 */ #define VSK3 136 /* Keypad 3 */ #define VSK4 137 /* Keypad 4 */ #define VSK5 138 /* Keypad 5 */ #define VSK6 139 /* Keypad 6 */ #define VSK7 140 /* Keypad 7 */ #define VSK8 141 /* Keypad 8 */ #define VSK9 142 /* Keypad 9 */ #define VSKC 143 /* Keypad , */ #define VSKM 144 /* Keypad - */ #define VSKP 145 /* Keypad . */ #define VSKE 146 /* Keypad Enter */ #define VSF1 147 /* Function 1 */ /* Mac Keypad Clear */ #define VSF2 148 /* Function 2 */ /* Mac Keypad = */ #define VSF3 149 /* Function 3 */ /* Mac Keypad / */ #define VSF4 150 /* Function 4 */ /* Mac Keypad * */ #ifdef VSMASTER char VSIkpxlate[2][23] = { "ABCD0123456789,-.\15PQRS", "ABCDpqrstuvwxylmnMPQRS" }; char VSIkpxlate2[] = "222122?2?3?3?2?3?3123425161"; /* BYU 2.4.12 */ char VSIkpxlate3[] = "134956?9?2?3?8?1?4~~~~0~8~7"; /* BYU 2.4.12 */ unsigned char VSIkplen[] = /* BYU 2.4.12 */ { 5,5,5,5,5,5,5,5,5,5, /* BYU 2.4.12 */ 5,5,5,5,5,5,5,5,4,4, /* BYU 2.4.12 */ 4,4,5,4,5,4,5 }; /* BYU 2.4.12 */ unsigned short VSIkpnums[] = // RAB BetterTelnet 2.0b5 - macro numbers { 24, 25, 26, 22, 27, 28, 0, 40, 0, 42, 0, 43, 0, 29, 0, 41, 0, 44, 58, 56, 54, 59, 23, 57, 21, 55, 20, 0, 0, 0, 0, 0, 0, 80, 81, 83, 82, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 70, 72, 73, 50, 51, 52, 53 }; #else extern char *VSIkpxlate,*VSIkpxlate2,*VSIkpxlate2; /* BYU 2.4.12 */ extern unsigned char *VSIkplen; /* BYU 2.4.12 */ #endif /* * Definition of attribute bits in the Virtual Screen * * 0 - Bold * 1 - * 2 - * 3 - Underline * 4 - Blink * 5 - * 6 - Reverse * 7 - Graphics character set * 8 - bit 0 of ansi foreground color index * 9 - bit 1 of ansi foreground color index * 10 - bit 2 of ansi foreground color index * 11 - use ansi foreground color * 12 - bit 0 of ansi background color index * 13 - bit 1 of ansi background color index * 14 - bit 2 of ansi background color index * 15 - use ansi background color * */ #define VSa(x) ( 1 << ((x)-1) ) #define VSisbold(x) ((x) & 0x01) #define VSisundl(x) ((x) & 0x08) #define VSisblnk(x) ((x) & 0x10) #define VSisrev(x) ((x) & 0x40) #define VSisgrph(x) ((x) & 0x80) #define VSinattr(x) ((x) & 0xff) #define VSgraph(x) ((x) | 0x80) #define VSnotgraph(x) ((x) & 0x7F) #define VSisansifg(x) ((x) & 0x0800) #define VSisansibg(x) ((x) & 0x8000) #define VSisansi(x) ((x) & 0x8800) //#define VSisbold(x) (x & 0x01) //#define VSisundl(x) (x & 0x08) //#define VSisblnk(x) (x & 0x10) //#define VSisrev(x) (x & 0x40) //#define VSisgrph(x) (x & 0x80) //#define VSinattr(x) (x & 0xd9) //#define VSgraph(x) (x | 0x80) //#define VSnotgraph(x) (x & 0x7F) \ No newline at end of file diff --git a/source/Screens/wind.h b/source/Screens/wind.h index 6e8fdf6..553edbb 100755 --- a/source/Screens/wind.h +++ b/source/Screens/wind.h @@ -1 +1 @@ -// // MacLook Window Management Data Structure Definition // #define MAXKB 256 // BYU mod #define PASTE_IN_PROGRESS 0x4000 // BYU LSC #define PASTE_DONE 0x0040 //CCP 2.7 // The following are for the "active" field. #define CNXN_NOTINUSE -2 #define CNXN_DNRWAIT -1 #define CNXN_ACTIVE 0 #define CNXN_OPENING 1 #define CNXN_ISCORPSE 2 #define MHOPTS_BASE 37 // Base option for {my,his}opts (Authenticate) // {my,his} opts should only be used for telnet options // in the range starting at MHOPTS_BASE and limited // by MHOPTS_SIZE. This saves memory. #define MHOPTS_SIZE 2 // Number of options supported in {my,his}opts #define SLC_ARRAY_SIZE 30 // This should match the value of SLC_MAX from parse.h struct WindRec { short vs, // virtual screen number port, // TCP/IP port number active, // See above for definition of possible values enabled, // Are we currently enabled for receive? vtemulation, // 0 = VT100, 1 = VT 220 bsdel, // backspace or delete is default eightbit, // eight bit font displayed (false is seven bit display national, // LU/MP: translation table to use for this connection arrowmap, // MAT: should we allow the arrow keys to be mapped?? showErrors, // show ALL errors if this is set pgupdwn, // JMB/MAT: should we have page up/down do local window movement? keypadmap, // CCP 2.7: should we have numeric keypad operators work like regular operators? emacsmeta, // JMB/SMB: should option key work as EMACS meta key? Xterm, // JMB/WNR: should Xterm sequences be recognized? remapCtrlD, // RAB BetterTelnet 1.0fc4: remap Del to ^D halfdup, // If true then half-duplex mode forcesave, // NCSA 2.5: force lines to be saved crmap, // BYU mod - CR's second byte is ... tekclear, // Does tektronix (1) clear screen or (0) add window tektype, // -1 = TEK not allowed, 0 = 4014, 1 = 4105 curgraph, // Associated Tek drawing qprint, // Queue print requests ignoreff, // RAB BetterTelnet 1.0fc8 - ignore FF maxscroll, // Requested amount of scroll back wrap, // whether vtwrap is set or not for this screen echo, // NOTE: this is backwards - I am echoing your chars ESscroll, // will Clear Screen Save Lines? ANSIgraphics, // ANSI color sequences (CCP 2.7) termstate, // Emulation State (-1 is none, 0 is VT100) // = TEKTYPE, send data to VGwrite // = RASTYPE, send data to VRwrite positionIndex, // CCP 2.7: for determining window placement naws, // NCSA: will negotiate NAWS lineAllow, // allow linemode? Isga, // I am supressing go ahead Usga, // You are supressing go ahead Ittype, // I am sending terminal type negotiations.. telstate, // Telnet State timing, // True if waiting for timing mark remote_flow, // true if they are dictating flow_control allow_flow, // true unless prior is true AND the host has told us to turn flow control off restart_any_flow,// true if any character (except XOFF) will restart flow substat, // Telnet Subnegot. State parseIndex, // save an index into the subnegotiation parsed data portNum, // port number from the application save set portNegative, // port number is negative: RAB BetterTelnet 1.0fc4 allowBold, // allow font boldfacing: RAB BetterTelnet 1.0fc4 colorBold, // use color for bold: RAB BetterTelnet 1.0fc4 realbold, ignoreBeeps, // ignore beeps: RAB BetterTelnet 1.0fc7 inversebold, // use inverse for bold: RAB BetterTelnet 1.0fc9 kblen, // Pointer to next char in buffer to be used clientflags; // BYU mod - boolean flags for ftp client short otpautostate, otpauto, otpnoprompt, otpmulti, otphex, otpautolength, otpsavepass, oldScrollback; char otpautobuffer[10], otppassword[64], otpautostring[256]; Str63 machine; // Name of machine we are connecting to Str32 answerback; // Message to send when server sends TERMTYPE Telnet option // The following are used during paste operations short outlen, // Length of text remaining to be pasted pastemethod, // 0 = All at once, 1 = in blocks of size pasteblock pastesize; // Size of paste "blocks" char *outptr, // Pointer to next char to send **outhand; // Handle to text from the Paste long incount, // BYU LSC - Count of bytes into this port outcount; // BYU LSC - Count of bytes out this port short isUploading, // RAB BetterTelnet 1.0fc9 - file upload in progress uploadRefNum; // RAB BetterTelnet 1.0fc9 - refNum for file upload //linemode options short litNext, // next key should be echo'd literal lmodeBits, // Current linemode MODE. Currently support EDIT and TRAPSIG lmode, // linemode is active forwardMask, // should we forward on certain characters numForwardKeys; // how many keys to forward on unsigned char slcLevel[SLC_ARRAY_SIZE+1], //levelBits forwardKeys[32],// which keys to forward on slc[SLC_ARRAY_SIZE+1]; //actual values char TELstop, // Character for scrolling to stop TELgo, // Character for scrolling to go TELip, // Character for interrupt process kbbuf[MAXKB]; // The keyboard buffer (echo mode ) GrafPtr wind; Handle myInitParams; // So we can look up stuff after we have DNS'd. Ptr aedata; unsigned char myopts[MHOPTS_SIZE], // My telnet options. Warning: see MHOPTS_BASE hisopts[MHOPTS_SIZE], // His telnet options. Warning: see MHOPTS_BASE parsedat[450]; // save the subnegotiation data here // must be big enough for a Kerberos AP message char cannon[80]; // Cannonical hostname Boolean authenticate, // true if authenticating connection wanted encrypt; // true if encrypting connection wanted }; typedef struct WindRec WindRec, * WindRecPtr; \ No newline at end of file +// // MacLook Window Management Data Structure Definition // #define MAXKB 256 // BYU mod #define PASTE_IN_PROGRESS 0x4000 // BYU LSC #define PASTE_DONE 0x0040 //CCP 2.7 // The following are for the "active" field. #define CNXN_NOTINUSE -2 #define CNXN_DNRWAIT -1 #define CNXN_ACTIVE 0 #define CNXN_OPENING 1 #define CNXN_ISCORPSE 2 #define MHOPTS_BASE 37 // Base option for {my,his}opts (Authenticate) // {my,his} opts should only be used for telnet options // in the range starting at MHOPTS_BASE and limited // by MHOPTS_SIZE. This saves memory. #define MHOPTS_SIZE 2 // Number of options supported in {my,his}opts #define SLC_ARRAY_SIZE 30 // This should match the value of SLC_MAX from parse.h // RAB BetterTelnet 2.0b2 - the struct for ssh stuff typedef struct sshinfo { short fsmstate, allowwrites, dead, encryption, enabled; Ptr contextptr; struct { short packettype; Handle dataHandle; Ptr data; long length; } write; struct { short packettype, state; Handle dataHandle; Ptr data; long length, packetLength; long readLength; long position; } read; } sshinfo; struct WindRec { short vs, // virtual screen number port, // TCP/IP port number active, // See above for definition of possible values enabled, // Are we currently enabled for receive? vtemulation, // 0 = VT100, 1 = VT 220 bsdel, // backspace or delete is default eightbit, // eight bit font displayed (false is seven bit display national, // LU/MP: translation table to use for this connection arrowmap, // MAT: should we allow the arrow keys to be mapped?? showErrors, // show ALL errors if this is set pgupdwn, // JMB/MAT: should we have page up/down do local window movement? keypadmap, // CCP 2.7: should we have numeric keypad operators work like regular operators? emacsmeta, // JMB/SMB: should option key work as EMACS meta key? Xterm, // JMB/WNR: should Xterm sequences be recognized? remapCtrlD, // RAB BetterTelnet 1.0fc4: remap Del to ^D halfdup, // If true then half-duplex mode forcesave, // NCSA 2.5: force lines to be saved crmap, // BYU mod - CR's second byte is ... tekclear, // Does tektronix (1) clear screen or (0) add window tektype, // -1 = TEK not allowed, 0 = 4014, 1 = 4105 curgraph, // Associated Tek drawing qprint, // Queue print requests ignoreff, // RAB BetterTelnet 1.0fc8 - ignore FF maxscroll, // Requested amount of scroll back wrap, // whether vtwrap is set or not for this screen echo, // NOTE: this is backwards - I am echoing your chars ESscroll, // will Clear Screen Save Lines? ANSIgraphics, // ANSI color sequences (CCP 2.7) termstate, // Emulation State (-1 is none, 0 is VT100) // = TEKTYPE, send data to VGwrite // = RASTYPE, send data to VRwrite positionIndex, // CCP 2.7: for determining window placement naws, // NCSA: will negotiate NAWS lineAllow, // allow linemode? Isga, // I am supressing go ahead Usga, // You are supressing go ahead Ittype, // I am sending terminal type negotiations.. telstate, // Telnet State timing, // True if waiting for timing mark remote_flow, // true if they are dictating flow_control allow_flow, // true unless prior is true AND the host has told us to turn flow control off restart_any_flow,// true if any character (except XOFF) will restart flow substat, // Telnet Subnegot. State parseIndex, // save an index into the subnegotiation parsed data portNum, // port number from the application save set portNegative, // port number is negative: RAB BetterTelnet 1.0fc4 allowBold, // allow font boldfacing: RAB BetterTelnet 1.0fc4 colorBold, // use color for bold: RAB BetterTelnet 1.0fc4 realbold, ignoreBeeps, // ignore beeps: RAB BetterTelnet 1.0fc7 inversebold, // use inverse for bold: RAB BetterTelnet 1.0fc9 kblen, // Pointer to next char in buffer to be used clientflags, // BYU mod - boolean flags for ftp client jsNoFlush, // RAB BetterTelnet 2.0b4 - don't flush jump scroller at all realBlink; short otpautostate, otpauto, otpnoprompt, otpmulti, otphex, otpautolength, otpsavepass, oldScrollback; char otpautobuffer[10], otppassword[64], otpautostring[256]; short cachedFontNum, cachedBoldFontNum; short cxWeHaveAppleEvent; AppleEvent cxAppleEvent, cxAEReply; short waWeHaveAppleEvent, waWaiting, waWaitPos, waWasEnabled, waWaitLength; char waWaitString[256], waPrefixFunction[256]; AppleEvent waAppleEvent, waAEReply; char username[256], password[256], clientuser[256], command[256]; short protocol, encryption; sshinfo sshdata; short jumpScroll; NewMacroInfo newMacros; short usesocks, socksinprogress, socks4a, socksport, sockspos, sockslookup; char sockshost[256], socksusername[256]; ip_addr actualIP, socksIP; Str63 machine; // Name of machine we are connecting to Str32 answerback; // Message to send when server sends TERMTYPE Telnet option // The following are used during paste operations short outlen, // Length of text remaining to be pasted pastemethod, // 0 = All at once, 1 = in blocks of size pasteblock pastesize; // Size of paste "blocks" char *outptr, // Pointer to next char to send **outhand; // Handle to text from the Paste long incount, // BYU LSC - Count of bytes into this port outcount; // BYU LSC - Count of bytes out this port short isUploading, // RAB BetterTelnet 1.0fc9 - file upload in progress uploadRefNum; // RAB BetterTelnet 1.0fc9 - refNum for file upload //linemode options short litNext, // next key should be echo'd literal lmodeBits, // Current linemode MODE. Currently support EDIT and TRAPSIG lmode, // linemode is active forwardMask, // should we forward on certain characters numForwardKeys; // how many keys to forward on unsigned char slcLevel[SLC_ARRAY_SIZE+1], //levelBits forwardKeys[32],// which keys to forward on slc[SLC_ARRAY_SIZE+1]; //actual values char TELstop, // Character for scrolling to stop TELgo, // Character for scrolling to go TELip, // Character for interrupt process kbbuf[MAXKB]; // The keyboard buffer (echo mode ) GrafPtr wind; Handle myInitParams; // So we can look up stuff after we have DNS'd. Ptr aedata; unsigned char myopts[MHOPTS_SIZE], // My telnet options. Warning: see MHOPTS_BASE hisopts[MHOPTS_SIZE], // His telnet options. Warning: see MHOPTS_BASE parsedat[450]; // save the subnegotiation data here // must be big enough for a Kerberos AP message char cannon[80]; // Cannonical hostname Boolean authenticate, // true if authenticating connection wanted encrypt; // true if encrypting connection wanted NewMacroInfo sessmacros; }; typedef struct WindRec WindRec, * WindRecPtr; \ No newline at end of file diff --git a/source/Sets/Sets.c b/source/Sets/Sets.c index 5f2ce15..158ecb1 100755 --- a/source/Sets/Sets.c +++ b/source/Sets/Sets.c @@ -1 +1 @@ -/* * Sets.c * All code relating to loading, parsing, and saving of sets * ***************************************************************** * Revisions: * 7/92 Telnet 2.6: Code moved here from config.c and maclook.c... Jim Browne */ // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #ifdef MPW #pragma segment Files #endif #define SAVE_SET_STRINGS_COUNT 73 #include "macros.proto.h" #include "wind.h" /* For WindRec definition */ #include "Sets.proto.h" #include "telneterrors.h" #include "prefs.proto.h" #include "Connections.proto.h" #include "rsinterf.proto.h" #include "rsmac.proto.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "rsdefs.h" #include "DlogUtils.proto.h" extern RSdata *RScurrent; //#define DEBUG_SETS #ifdef DEBUG_SETS #define sets_debug_print(x) putln(x) #else #define sets_debug_print(x) #endif ConnInitParams **SetParams; SessionPrefs *SetSessionPtr; TerminalPrefs *SetTerminalPtr; char *Cspace; extern WindRec *screens; /* Window Records (VS) for : Current Sessions */ extern MenuHandle myMenus[NMENUS]; /* Menu Handles .... */ #define PORTNUM 37 /* NCSA 2.5: the port variable */ void SETSunload(void) {} /* affirmative() checks a token to see if it is a valid Affirmation string. We now get the affirmative strings from the resource */ Boolean affirmative( char *s) { short i; Str255 AffWords; /* Telnet 2.6: get string resources */ for (i=0; iposition; i++) s[i] = tolower(s[i]); for (i=1; i<= AFF_WORDS_COUNT ;i++) { GetIndString(AffWords,AFF_WORDS_ID,i); p2cstr(AffWords); if (!ncstrcmp((char *)AffWords,s)) break; } if (i <= AFF_WORDS_COUNT) return(TRUE); else return(FALSE); } /**************************************************************************/ /* Sissep * is the character a valid separator for the hosts file? * separators are white space, special chars and :;= * */ Boolean Sissep( char c) { if (c < 33) return(1); if (c == ':' || c == ';' || c == '=') return(TRUE); return(FALSE); } /************************************************************************/ /* ncstrcmp * No case string compare. * Only returns 0=match, 1=no match, does not compare greater or less * There is a tiny bit of overlap with the | 32 trick, but shouldn't be * a problem. It causes some different symbols to match. */ short ncstrcmp(char *sa, char *sb) { while (*sa && *sa < 33) /* don't compare leading spaces */ sa++; while (*sb && *sb < 33) sb++; while (*sa && *sb) { if ((*sa != *sb) && ((*sa | 32) != (*sb | 32))) return(1); sa++;sb++; } if (!*sa && !*sb) /* if both at end of string */ return(0); else return(1); } /* confile() now gets all of its keywords from the string resources, for greater ease, flexibility, and overall coolness. */ short confile( char *s) { short i, port, portNeg; Boolean success; unsigned int a,b,c,d; int signedint; Str255 Ckeyw; char tempCstring[256]; sets_debug_print(s); if (!(*s) ) return(0); switch( TelInfo->CONFstate) { case 0: /* No keyword yet! */ for (i=0; iposition; i++) s[i] = tolower(s[i]); for (i=1; i<= SAVE_SET_STRINGS_COUNT ;i++) { GetIndString(Ckeyw,SAVE_SET_STRINGS_ID,i); p2cstr(Ckeyw); if (!ncstrcmp((char *)Ckeyw,s)) break; } if ( i > SAVE_SET_STRINGS_COUNT ) { // OperationFailedAlert(BAD_SET_ERR, 0, 0); TelInfo->CONFstate = 0; break; // return(1); } TelInfo->CONFstate=i; if (TelInfo->CONFstate==5) { SetSessionPtr->bksp = 0; TelInfo->CONFstate=0; } if (TelInfo->CONFstate==6) { SetSessionPtr->bksp = 1; TelInfo->CONFstate=0; } break; case 1: /* NAME */ { char *p; if (NULL == (p = myNewPtr(40000))) /* is there enough memory? */ { /* NOT enough memory for the set! */ DoError(107 | MEMORY_ERRORCLASS, LEVEL2, NULL); /* register the error */ return(-1); } else DisposPtr(p); } if (TelInfo->CONFactive) { success = CreateConnectionFromParams(SetParams); SetParams = NULL; if (!success) { sets_debug_print("ERROR IN OPENING!! "); return(42); } } if (SetParams == NULL) { SetParams = ReturnDefaultConnInitParams(); HLockHi((Handle)SetParams); HLockHi((Handle)(**SetParams).session); SetSessionPtr = *(**SetParams).session; HLockHi((Handle)(**SetParams).terminal); SetTerminalPtr = *(**SetParams).terminal; } strncpy(tempCstring, s, 255); /* Move name in */ CtoPstr(tempCstring); if ((tempCstring[0] == 1) && (tempCstring[1] == ' ')) tempCstring[0] = 0; BlockMove(tempCstring, (**SetParams).WindowName, tempCstring[0]+1); TelInfo->CONFstate=0; TelInfo->CONFactive=1; break; case 2: /* HOST */ strncpy(tempCstring, s, 63); /* Move name in */ CtoPstr(tempCstring); // Process the hosname string. if (ProcessHostnameString((StringPtr)tempCstring, &port, &portNeg)) SetSessionPtr->port = port; BlockMove(tempCstring, SetSessionPtr->hostname, tempCstring[0]+1); TelInfo->CONFstate=0; break; case 3: /* SIZE */ if ( 4 != sscanf(s, "{%d,%d,%d,%d}", &a, &b, &c,&d) ) { sets_debug_print("Error in window size"); return(2); } (**SetParams).WindowLocation.top=a; (**SetParams).WindowLocation.left=b; (**SetParams).WindowLocation.bottom=c; (**SetParams).WindowLocation.right=d; TelInfo->CONFstate=0; break; case 4: if ( 1 != sscanf(s,"%d", &a) ) { sets_debug_print("Scrollback needs parameter"); return(1); } SetTerminalPtr->numbkscroll = a; TelInfo->CONFstate=0; break; case 5: SetSessionPtr->bksp = 0; TelInfo->CONFstate=0; break; case 6: SetSessionPtr->bksp = 1; TelInfo->CONFstate=0; break; case 7: setmacro( 0, s); TelInfo->CONFstate=0; break; case 8: setmacro( 1, s); TelInfo->CONFstate=0; break; case 9: setmacro( 2, s); TelInfo->CONFstate=0; break; case 10: setmacro( 3, s); TelInfo->CONFstate=0; break; case 11: setmacro( 4, s); TelInfo->CONFstate=0; break; case 12: setmacro( 5, s); TelInfo->CONFstate=0; break; case 13: setmacro( 6, s); TelInfo->CONFstate=0; break; case 14: setmacro( 7, s); TelInfo->CONFstate=0; break; case 15: setmacro( 8, s); TelInfo->CONFstate=0; break; case 16: setmacro( 9, s); TelInfo->CONFstate=0; break; case 17: TelInfo->CONFstate=0; // Now ignored (was commandkeys) break; case 18: if (!strcmp(s,"backspace") ) SetSessionPtr->bksp = 0; else SetSessionPtr->bksp = 1; TelInfo->CONFstate=0; break; case 19: case 21: if ( 1 == sscanf(s,"%d", &a) ) SetTerminalPtr->vtwidth = a; TelInfo->CONFstate=0; break; case 20: if (affirmative(s)) SetSessionPtr->tekclear = 1; else SetSessionPtr->tekclear = 0; TelInfo->CONFstate = 0; break; case 22: if ( 3 != sscanf(s, "{%u,%u,%u}", &a, &b, &c)) { /* BYU LSC - "%d" changed to "%u" */ sets_debug_print("Bad Parms to rgb"); return(2); } SetTerminalPtr->nfcolor.red = a; SetTerminalPtr->nfcolor.green = b; SetTerminalPtr->nfcolor.blue = c; TelInfo->CONFstate = 0; break; case 23: if ( 3 != sscanf(s, "{%u,%u,%u}", &a, &b, &c)) { /* BYU LSC - "%d" changed to "%u" */ sets_debug_print("Bad Parms to rgb"); return(2); } SetTerminalPtr->nbcolor.red = a; SetTerminalPtr->nbcolor.green = b; SetTerminalPtr->nbcolor.blue = c; TelInfo->CONFstate = 0; break; case 24: if ( 3 != sscanf(s, "{%u,%u,%u}", &a, &b, &c)) { /* BYU LSC - "%d" changed to "%u" */ sets_debug_print("Bad Parms to rgb"); return(2); } SetTerminalPtr->bfcolor.red = a; SetTerminalPtr->bfcolor.green = b; SetTerminalPtr->bfcolor.blue = c; TelInfo->CONFstate = 0; break; case 25: if ( 3 != sscanf(s, "{%u,%u,%u}", &a, &b, &c)) { /* BYU LSC - "%d" changed to "%u" */ sets_debug_print("Bad Parms to rgb"); return(2); } SetTerminalPtr->bbcolor.red = a; SetTerminalPtr->bbcolor.green = b; SetTerminalPtr->bbcolor.blue = c; TelInfo->CONFstate = 0; break; case 26: /* Font Name */ strncpy(tempCstring, s, 63); /* Move name in */ CtoPstr(tempCstring); BlockMove(tempCstring, &(SetTerminalPtr->DisplayFont[0]), tempCstring[0]+1); TelInfo->CONFstate = 0; break; case 27: /* Font Size */ if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->fontsize = a; TelInfo->CONFstate = 0; break; case 28: /* number of lines to use for window's editable region */ if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->vtheight = a; TelInfo->CONFstate = 0; break; case 29: /* keystop, XOFF key */ if (1 == sscanf( s, "%d", &a)) SetSessionPtr->skey = a; TelInfo->CONFstate = 0; break; case 30: /* keygo, XON key */ if (1 == sscanf( s, "%d", &a)) SetSessionPtr->qkey = a; TelInfo->CONFstate = 0; break; case 31: /* keyip, kill key */ if (1 == sscanf( s, "%d", &a)) SetSessionPtr->ckey = a; TelInfo->CONFstate = 0; break; case 32: /* cr-map */ if ((1 == sscanf( s, "%d", &a)) && (a !=0)) SetSessionPtr->crmap = TRUE; else SetSessionPtr->crmap = FALSE; TelInfo->CONFstate = 0; break; case 33: /* BYU 2.4.9 */ if ((1 == sscanf( s, "%d", &a)) && (a !=0)) /* BYU 2.4.9 */ SetSessionPtr->linemode = TRUE; /* BYU 2.4.9 */ else /* BYU 2.4.9 */ SetSessionPtr->linemode = FALSE; /* BYU 2.4.9 */ TelInfo->CONFstate=0; /* BYU 2.4.9 */ break; /* BYU 2.4.9 */ case 34: /* BYU 2.4.9 */ if ((1 == sscanf( s, "%d", &a)) && (a !=0)) SetTerminalPtr->eightbit = TRUE; /* BYU 2.4.9 */ else /* BYU 2.4.9 */ SetTerminalPtr->eightbit = FALSE; /* BYU 2.4.9 */ TelInfo->CONFstate=0; /* BYU 2.4.9 */ break; /* BYU 2.4.9 */ case 35: /* BYU */ // (**SetParams).ftpstate = 1; /* BYU */ TelInfo->CONFstate=0; /* BYU */ break; /* BYU */ case 36: // ignored TelInfo->CONFstate=0; break; case PORTNUM: /* NCSA 2.5: get the real port # */ if (1 == sscanf( s, "%d", &a)) /* NCSA */ SetSessionPtr->port = a; /* NCSA */ TelInfo->CONFstate = 0; /* NCSA */ break; /* NCSA */ case 38: // translation strncpy((char *) SetSessionPtr->TranslationTable, s, 32); CtoPstr((char *) SetSessionPtr->TranslationTable); TelInfo->CONFstate=0; break; case 39: // tekem if (1 == sscanf(s, "%d", &signedint)) SetSessionPtr->tektype = signedint; TelInfo->CONFstate=0; break; case 40: // answerback strncpy((char *) SetTerminalPtr->AnswerBackMessage, s, 32); CtoPstr((char *) SetTerminalPtr->AnswerBackMessage); TelInfo->CONFstate=0; break; case 41: //authenticate if (affirmative(s)) SetSessionPtr->authenticate = TRUE; else SetSessionPtr->authenticate = FALSE; TelInfo->CONFstate=0; break; case 42: //encrypt if (affirmative(s)) SetSessionPtr->encrypt = TRUE; else SetSessionPtr->encrypt = FALSE; TelInfo->CONFstate=0; break; case 43: //pageup/down map if (affirmative(s)) SetTerminalPtr->MATmappings = TRUE; else SetTerminalPtr->MATmappings = FALSE; TelInfo->CONFstate=0; break; case 44: //keypad map if (affirmative(s)) SetTerminalPtr->remapKeypad = TRUE; else SetTerminalPtr->remapKeypad = FALSE; TelInfo->CONFstate=0; break; case 45: // ansicolor if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->ANSIgraphics = a; TelInfo->CONFstate=0; break; case 46: // arrowmap if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->emacsarrows = a; TelInfo->CONFstate=0; break; case 47: // emacsmeta if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->emacsmetakey = a; TelInfo->CONFstate=0; break; case 48: // pastemethod if (1 == sscanf( s, "%d", &a)) SetSessionPtr->pastemethod = a; TelInfo->CONFstate=0; break; case 49: // pastesize if (1 == sscanf( s, "%d", &a)) SetSessionPtr->pasteblocksize = a; TelInfo->CONFstate=0; break; case 50: // saveclear if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->clearsave = a; TelInfo->CONFstate=0; break; case 51: // vtemulation if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->vtemulation = a; TelInfo->CONFstate=0; break; case 52: // forcesave if (1 == sscanf( s, "%d", &a)) SetSessionPtr->forcesave = a; TelInfo->CONFstate=0; break; case 53: // vtwrap if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->vtwrap = a; TelInfo->CONFstate=0; break; case 54: // xterm if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->Xtermsequences = a; TelInfo->CONFstate=0; break; case 55: // localecho if (1 == sscanf( s, "%d", &a)) SetSessionPtr->localecho = a; TelInfo->CONFstate=0; break; case 56: // halfdup if (1 == sscanf( s, "%d", &a)) SetSessionPtr->halfdup = a; TelInfo->CONFstate=0; break; case 57: // remapctrld if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->remapCtrlD = a; TelInfo->CONFstate=0; break; case 58: // negative if (1 == sscanf( s, "%d", &a)) SetSessionPtr->portNegative = a; TelInfo->CONFstate=0; break; case 59: // allowbold if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->allowBold = a; TelInfo->CONFstate=0; break; case 60: // colorbold if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->colorBold = a; TelInfo->CONFstate=0; break; case 61: // ignorebeeps if (1 == sscanf( s, "%d", &a)) SetSessionPtr->ignoreBeeps = a; TelInfo->CONFstate=0; break; case 62: // ignoreff if (1 == sscanf( s, "%d", &a)) SetSessionPtr->ignoreff = a; TelInfo->CONFstate=0; break; case 63: // boldfont strncpy(tempCstring, s, 63); /* Move name in */ CtoPstr(tempCstring); BlockMove(tempCstring, &(SetTerminalPtr->BoldFont[0]), tempCstring[0]+1); TelInfo->CONFstate = 0; break; case 64: // inversebold if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->boldFontStyle = a; TelInfo->CONFstate = 0; break; case 65: // otpauto if (1 == sscanf( s, "%d", &a)) SetSessionPtr->otpauto = a; TelInfo->CONFstate = 0; break; case 66: // otpmulti if (1 == sscanf( s, "%d", &a)) SetSessionPtr->otpmulti = a; TelInfo->CONFstate = 0; break; case 67: // otphex if (1 == sscanf( s, "%d", &a)) SetSessionPtr->otphex = a; TelInfo->CONFstate = 0; break; case 68: // otpnoprompt if (1 == sscanf( s, "%d", &a)) SetSessionPtr->otpnoprompt = a; TelInfo->CONFstate = 0; break; case 69: // otppassword strncpy(tempCstring, s, 63); /* Move name in */ CtoPstr(tempCstring); BlockMove(tempCstring, &(SetSessionPtr->otppassword[0]), tempCstring[0]+1); TelInfo->CONFstate = 0; break; case 70: // realbold if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->realbold = a; TelInfo->CONFstate = 0; break; case 71: // otpsavepass if (1 == sscanf( s, "%d", &a)) SetSessionPtr->otpsavepass = a; TelInfo->CONFstate = 0; break; case 72: // oldscrollback if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->oldScrollback = a; TelInfo->CONFstate = 0; break; default: TelInfo->CONFstate=0; } return(0); } /* confile */ /************************************************************************/ /* contoken * tokenize the strings which get passed to confile. * Handles quotes and uses separators: <33, ;:= */ short contoken( char c) { short retval; Boolean success; if (c == EOF) { Cspace[TelInfo->position++] = '\0'; sets_debug_print("Eof handler called"); confile(Cspace); if (TelInfo->CONFactive) { success = CreateConnectionFromParams(SetParams); if (!success) { sets_debug_print("ERROR IN OPENING!! "); return(42); } } return(-1); } if (!TelInfo->position && !TelInfo->inquote && Sissep(c)) /*if (!TelInfo->position && Sissep(c)) */ /* old_skip over junk before keyword */ return(0); if (TelInfo->inquote || !Sissep(c)) { if (TelInfo->position > 200) { sets_debug_print("Out of bounds error!"); return(1); } /* * check for quotes, a little mixed up here, could be reorganized */ if (c == '"' ) { if (!TelInfo->inquote) { /* beginning of quotes */ TelInfo->inquote = 1; return(0); } Cspace[TelInfo->position++] =c; return(0); } else { /* include in current string */ if (c != '\012' && c != '\015') /* BYU 2.4.18 - changed \n to \015 and added \012 */ { Cspace[TelInfo->position++] = c; return(0); } } } if (Cspace[TelInfo->position-1] == '"') TelInfo->position--; Cspace[TelInfo->position++] = '\0'; retval = confile(Cspace); /* pass the token along */ TelInfo->position = 0; TelInfo->inquote = 0; Cspace[0] = '\0'; return(retval); } /************************************************************************/ /* readconfig * read the saved set file into our in-memory data structure. * Handle everything by keyword (stored in resources). */ void readconfig(FSSpec theSet) { short c,retval; short fn; OSErr err; Cspace = myNewPtr(256); /* BYU LSC - get room for gathering stuff */ SetParams = ReturnDefaultConnInitParams(); HLockHi((Handle)SetParams); HLockHi((Handle)(**SetParams).session); SetSessionPtr = *(**SetParams).session; HLockHi((Handle)(**SetParams).terminal); SetTerminalPtr = *(**SetParams).terminal; if (NULL == Cspace) /* no memory left for the set to load in */ { /* we're out of memory */ DoError(107 | MEMORY_ERRORCLASS, LEVEL2, NULL); return; } TelInfo->position = TelInfo->CONFstate = TelInfo->CONFactive = TelInfo->inquote = TelInfo->lineno = 0; /* state vars */ err = HOpenDF(theSet.vRefNum, theSet.parID, theSet.name, fsRdPerm, &fn); retval = 0; while (!retval) { c = Myfgetc(fn); if (c == '#' && !TelInfo->inquote) { while (c != EOF && c != '\012' && c != '\015') /* skip to EOL */ /* BYU 2.4.18 - changed \n to \015 and added \012*/ c = Myfgetc(fn); } if (c == '\012' || c == '\015') /* BYU 2.4.18 - changed \n to \015 and added \012 */ TelInfo->lineno++; retval = contoken(c); } FSClose(fn); DisposPtr((Ptr) Cspace); if (retval == EOF) { /* EOF is normal end */ sets_debug_print("EOF termination"); } else { sets_debug_print("NON-EOF termination"); } return; } void LoadSet( void) { SFReply sfr; long junk; SFTypeList typesok = {'CONF'}; Point where; FSSpec set; Str255 tempString; where.h=100;where.v=100; GetIndString(tempString,MISC_STRINGS,SET_TO_LOAD_STRING); SFGetFile( where,tempString, 0L, 1, typesok, 0L, &sfr); if (! sfr.good) return; BlockMove(&sfr.fName, set.name, (*sfr.fName)+1); // pstring copy sfr.fName -> set.name GetWDInfo(sfr.vRefNum, &set.vRefNum, &set.parID, &junk); readconfig(set); } char Myfgetc(short myfile) { OSErr err; long count; unsigned char buffer; count = 1; if ((err = FSRead(myfile, &count, &buffer)) == eofErr) buffer = EOF; return (buffer); } void CStringToFile(short myfile, unsigned char *mystring) { long mycount; /* BYU LSC */ short fstatus; /* BYU LSC */ mycount = strlen((char *) mystring); /* BYU LSC */ fstatus = FSWrite(myfile,&mycount,mystring); /* BYU LSC */ } void SaveSet(short doSaveMacros, short dontSaveTitle) { SFReply sfr; short fn, truncate; WindowPeek wpeek; Rect rect; Point where; long junk; char temp[256], temp2[256]; /* BYU LSC */ short fnum,fsiz; short i; FSSpec set; OSErr err; Str255 scratchPstring,scratchPstring2; where.h = 100; where.v = 100; GetIndString(scratchPstring,MISC_STRINGS,SAVE_SET_STRING); GetIndString(scratchPstring2,MISC_STRINGS,DEFAULT_SAVE_SET_NAME); SFPutFile(where,scratchPstring,scratchPstring2, 0L, &sfr); /* BYU LSC */ if (!sfr.good) return; BlockMoveData(&sfr.fName, set.name, (*sfr.fName)+1); // pstring copy sfr.fName -> set.name GetWDInfo(sfr.vRefNum, &set.vRefNum, &set.parID, &junk); if ((err = HCreate(set.vRefNum, set.parID, set.name, kNCSACreatorSignature, kNCSASetFileType)) == dupFNErr) truncate = 1; err = HOpenDF(set.vRefNum, set.parID, set.name, fsWrPerm, &fn); if (truncate) SetEOF(fn, 0L); if (gApplicationPrefs->CommandKeys) CStringToFile(fn,(unsigned char *) "commandkeys = yes\015"); /* BYU LSC */ else CStringToFile(fn,(unsigned char *) "commandkeys = no\015"); /* BYU LSC */ if (doSaveMacros) for (i = 0; i < 10; i++) { getmacro(i, temp, sizeof(temp)); /* BYU LSC */ if (*temp) { /* BYU LSC */ sprintf(temp2, "key%d = \"", i); /* BYU 2.4.16 */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp); /* BYU LSC */ strcpy(temp2,"\"\015"); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ } /* BYU LSC */ } /* for */ #if 0 /* BYU LSC */ for (i = 0; i < TelInfo->numwindows; i++) { short j; j = RSgetfont(screens[i].vs, &fnum, &fsiz); } /* for */ #endif /* BYU LSC */ for (i = 0; i < TelInfo->numwindows; i++) { if (!dontSaveTitle) { GetWTitle(screens[i].wind, scratchPstring); PtoCstr(scratchPstring); sprintf(temp2, "name= \"%s\"\015", scratchPstring); } else sprintf(temp2, "name= \" \"\015", scratchPstring); CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ BlockMove((Ptr)screens[i].machine, (Ptr)scratchPstring, Length(screens[i].machine)+1); PtoCstr(scratchPstring); sprintf(temp2, "host= \"%s\"\015", scratchPstring); CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf (temp2,"port= %d\015",screens[i].portNum); /* NCSA: save port # */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf(temp2, "scrollback= %d\015", (screens[i].maxscroll)); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ if (screens[i].bsdel) CStringToFile(fn,(unsigned char *) "erase = delete\015"); /* BYU LSC */ else CStringToFile(fn,(unsigned char *) "erase = backspace\015"); /* BYU LSC */ wpeek = (WindowPeek) screens[i].wind; rect = (*wpeek->contRgn)->rgnBBox; if (!dontSaveTitle) { sprintf(temp2, "size = {%d,%d,%d,%d}\015", rect.top, rect.left, /* BYU LSC */ rect.bottom, rect.right); CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ } sprintf(temp2, "vtwidth = %d\015", VSmaxwidth(screens[i].vs) + 1); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ if (screens[i].tekclear) CStringToFile(fn,(unsigned char *) "tekclear = yes\015"); /* BYU LSC */ else CStringToFile(fn,(unsigned char *) "tekclear = no\015"); /* BYU LSC */ if (TelInfo->haveColorQuickDraw) { RGBColor theColor; short j; for (j = 0; j < 4; j++) { theColor = RSgetcolor( screens[i].vs, j); sprintf(temp2, "rgb%d = {%u,%u,%u}\015", j, theColor.red, theColor.green, theColor.blue); CStringToFile(fn,(unsigned char *) temp2); } } RSgetfont( screens[i].vs, &fnum, &fsiz); GetFontName( fnum, (StringPtr)temp); /* BYU LSC */ #ifndef MPW p2cstr((unsigned char *) temp); /* BYU LSC */ #endif sprintf( temp2, "font = \"%s\"\015", temp); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "fsize= %d\015", fsiz); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ RSsetwind(screens[i].vs); fnum = RScurrent->bfnum; GetFontName( fnum, (StringPtr)temp); /* BYU LSC */ #ifndef MPW p2cstr((unsigned char *) temp); /* BYU LSC */ #endif sprintf( temp2, "boldfont = \"%s\"\015", temp); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "nlines= %d\015", VSgetlines(screens[i].vs));/* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "keystop= %d\015", screens[i].TELstop); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "keygo= %d\015", screens[i].TELgo); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "keyip= %d\015", screens[i].TELip); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "crmap= %d\015", screens[i].crmap); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "tekem= %d\015", screens[i].tektype); CStringToFile(fn,(unsigned char *) temp2); // All this stuff was added in BetterTelnet 1.0b3... (RAB) sprintf( temp2, "vtemulation = %d\015", screens[i].vtemulation); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "forcesave = %d\015", screens[i].forcesave); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "eightbit = %d\015", screens[i].eightbit); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "vtwrap = %d\015", screens[i].wrap); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "xterm = %d\015", screens[i].Xterm); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "remapctrld = %d\015", screens[i].remapCtrlD); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "ansicolor = %d\015", screens[i].ANSIgraphics); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "arrowmap = %d\015", screens[i].arrowmap); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "emacsmeta = %d\015", screens[i].emacsmeta); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "pastemethod = %d\015", screens[i].pastemethod); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "pastesize = %d\015", screens[i].pastesize); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "saveclear = %d\015", screens[i].ESscroll); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "linemode = %d\015", screens[i].lineAllow); CStringToFile(fn,(unsigned char *) temp2); // And all this stuff was added a bit later... (RAB BetterTelnet 1.0 and later) sprintf( temp2, "negative = %d\015", screens[i].portNegative); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "allowbold = %d\015", screens[i].allowBold); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "colorbold = %d\015", screens[i].colorBold); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "ignorebeeps = %d\015", screens[i].ignoreBeeps); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "ignoreff = %d\015", screens[i].ignoreff); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "inversebold = %d\015", screens[i].inversebold); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otpauto = %d\015", screens[i].otpauto); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otpmulti = %d\015", screens[i].otpmulti); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otphex = %d\015", screens[i].otphex); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otpnoprompt = %d\015", screens[i].otpnoprompt); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "realbold = %d\015", screens[i].realbold); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "oldscrollback = %d\015", screens[i].oldScrollback); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otpsavepass = %d\015", screens[i].otpsavepass); CStringToFile(fn,(unsigned char *) temp2); // end of "all this stuff" if (screens[i].otppassword[0]) { // RAB BetterTelnet 1.2 pstrcpy(scratchPstring, (unsigned char *)screens[i].otppassword); p2cstr(scratchPstring); sprintf(temp2, "otppassword = \"%s\"\015", scratchPstring); CStringToFile(fn, (unsigned char *)temp2); } if (screens[i].national) { // Don't do this if using default translation table GetItem(myMenus[National], screens[i].national+1, scratchPstring); PtoCstr(scratchPstring); sprintf(temp2, "translation= \"%s\"\015", scratchPstring); CStringToFile(fn, (unsigned char *)temp2); } BlockMove(screens[i].answerback, scratchPstring, *(screens[i].answerback)+1); PtoCstr(scratchPstring); sprintf(temp2, "answerback= \"%s\"\015", scratchPstring); CStringToFile(fn, (unsigned char *)temp2); if (screens[i].authenticate) CStringToFile(fn,(unsigned char *) "authenticate = yes\015"); //CCP added next four lines for authencrypt else CStringToFile(fn,(unsigned char *) "authenticate = no\015"); if (screens[i].encrypt) CStringToFile(fn,(unsigned char *) "encrypt = yes\015"); else CStringToFile(fn,(unsigned char *) "encrypt = no\015"); if (screens[i].pgupdwn) CStringToFile(fn,(unsigned char *) "pageup = yes\015"); //CCP 2.7 else CStringToFile(fn,(unsigned char *) "pageup = no\015"); if (screens[i].keypadmap) CStringToFile(fn,(unsigned char *) "keypad = yes\015"); //CCP 2.7 else CStringToFile(fn,(unsigned char *) "keypad = no\015"); } /* for i */ FSClose(fn); /* BYU LSC */ } // This is new for BetterTelnet 1.0b4. It saves sessions directly from the Favorites. (RAB) void SaveSetFromSession(SessionPrefs* setSession, TerminalPrefs* setTerminal, short doWeAppend, short doSaveMacros) { SFReply sfr; short fn, truncate; WindowPeek wpeek; Rect rect; Point where; long junk; char temp[256], temp2[256]; /* BYU LSC */ short fnum,fsiz, i; FSSpec set; OSErr err; Str255 scratchPstring,scratchPstring2; SFTypeList typesok = {'CONF'}; where.h = 100; where.v = 100; if (doWeAppend) { GetIndString(scratchPstring,MISC_STRINGS,SAVE_SET_STRING); SFGetFile( where,scratchPstring, 0L, 1, typesok, 0L, &sfr); } else { GetIndString(scratchPstring,MISC_STRINGS,SAVE_SET_STRING); GetIndString(scratchPstring2,MISC_STRINGS,DEFAULT_SAVE_SET_NAME); SFPutFile(where,scratchPstring,scratchPstring2, 0L, &sfr); /* BYU LSC */ } if (!sfr.good) return; BlockMoveData(&sfr.fName, set.name, (*sfr.fName)+1); // pstring copy sfr.fName -> set.name GetWDInfo(sfr.vRefNum, &set.vRefNum, &set.parID, &junk); if (!doWeAppend) if ((err = HCreate(set.vRefNum, set.parID, set.name, kNCSACreatorSignature, kNCSASetFileType)) == dupFNErr) truncate = 1; err = HOpenDF(set.vRefNum, set.parID, set.name, fsWrPerm, &fn); if ((!doWeAppend) && truncate) SetEOF(fn, 0L); if (doWeAppend) SetFPos(fn, 2, 0L); if (doSaveMacros) for (i = 0; i < 10; i++) { getmacro(i, temp, sizeof(temp)); /* BYU LSC */ if (*temp) { /* BYU LSC */ sprintf(temp2, "key%d = \"", i); /* BYU 2.4.16 */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp); /* BYU LSC */ strcpy(temp2,"\"\015"); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ } /* BYU LSC */ } /* for */ sprintf(temp2, "name= \" \"\015"); CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ BlockMove(setSession->hostname, (Ptr)scratchPstring, Length(setSession->hostname)+1); PtoCstr(scratchPstring); sprintf(temp2, "host= \"%s\"\015", scratchPstring); CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf (temp2,"port= %d\015",setSession->port); /* NCSA: save port # */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf(temp2, "scrollback= %d\015", setTerminal->numbkscroll); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ if (setSession->bksp) CStringToFile(fn,(unsigned char *) "erase = delete\015"); /* BYU LSC */ else CStringToFile(fn,(unsigned char *) "erase = backspace\015"); /* BYU LSC */ sprintf(temp2, "vtwidth = %d\015", setTerminal->vtwidth); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ if (setSession->tekclear) CStringToFile(fn,(unsigned char *) "tekclear = yes\015"); /* BYU LSC */ else CStringToFile(fn,(unsigned char *) "tekclear = no\015"); /* BYU LSC */ if (TelInfo->haveColorQuickDraw) { sprintf(temp2, "rgb%d = {%u,%u,%u}\015", 0, setTerminal->nfcolor.red, setTerminal->nfcolor.green, setTerminal->nfcolor.blue); CStringToFile(fn,(unsigned char *) temp2); sprintf(temp2, "rgb%d = {%u,%u,%u}\015", 1, setTerminal->nbcolor.red, setTerminal->nbcolor.green, setTerminal->nbcolor.blue); CStringToFile(fn,(unsigned char *) temp2); sprintf(temp2, "rgb%d = {%u,%u,%u}\015", 2, setTerminal->bfcolor.red, setTerminal->bfcolor.green, setTerminal->bfcolor.blue); CStringToFile(fn,(unsigned char *) temp2); sprintf(temp2, "rgb%d = {%u,%u,%u}\015", 3, setTerminal->bbcolor.red, setTerminal->bbcolor.green, setTerminal->bbcolor.blue); CStringToFile(fn,(unsigned char *) temp2); } BlockMove(setTerminal->DisplayFont, temp, Length(setTerminal->DisplayFont) + 1); #ifndef MPW p2cstr((unsigned char *) temp); /* BYU LSC */ #endif sprintf( temp2, "font = \"%s\"\015", temp); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "fsize= %d\015", setTerminal->fontsize); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ BlockMove(setTerminal->BoldFont, temp, Length(setTerminal->BoldFont) + 1); #ifndef MPW p2cstr((unsigned char *) temp); #endif sprintf( temp2, "boldfont = \"%s\"\015", temp); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "nlines= %d\015", setTerminal->vtheight);/* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "keystop= %d\015", setSession->skey); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "keygo= %d\015", setSession->qkey); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "keyip= %d\015", setSession->ckey); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "crmap= %d\015", setSession->crmap); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "tekem= %d\015", setSession->tektype); CStringToFile(fn,(unsigned char *) temp2); // All this stuff was added in BetterTelnet 1.0b3... (RAB) sprintf( temp2, "vtemulation = %d\015", setTerminal->vtemulation); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "forcesave = %d\015", setSession->forcesave); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "eightbit = %d\015", setTerminal->eightbit); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "vtwrap = %d\015", setTerminal->vtwrap); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "xterm = %d\015", setTerminal->Xtermsequences); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "remapctrld = %d\015", setTerminal->remapCtrlD); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "ansicolor = %d\015", setTerminal->ANSIgraphics); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "arrowmap = %d\015", setTerminal->emacsarrows); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "emacsmeta = %d\015", setTerminal->emacsmetakey); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "pastemethod = %d\015", setSession->pastemethod); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "pastesize = %d\015", setSession->pasteblocksize); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "saveclear = %d\015", setTerminal->clearsave); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "linemode = %d\015", setSession->linemode); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "negative = %d\015", setSession->portNegative); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "allowbold = %d\015", setTerminal->allowBold); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "colorbold = %d\015", setTerminal->colorBold); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "ignorebeeps = %d\015", setSession->ignoreBeeps); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "ignoreff = %d\015", setSession->ignoreff); CStringToFile(fn,(unsigned char *) temp2); // And all this stuff was added in 1.0b5... (RAB) sprintf( temp2, "localecho = %d\015", setSession->localecho); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "halfdup = %d\015", setSession->halfdup); CStringToFile(fn,(unsigned char *) temp2); // end of "all this stuff" (RAB) sprintf( temp2, "otpauto = %d\015", setSession->otpauto); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otpmulti = %d\015", setSession->otpmulti); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otphex = %d\015", setSession->otphex); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otpnoprompt = %d\015", setSession->otpnoprompt); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "realbold = %d\015", setTerminal->realbold); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "oldscrollback = %d\015", setTerminal->oldScrollback); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otpsavepass = %d\015", setSession->otpsavepass); CStringToFile(fn,(unsigned char *) temp2); if (screens[i].otppassword[0]) { // RAB BetterTelnet 1.2 pstrcpy(scratchPstring, (unsigned char *)setSession->otppassword); p2cstr(scratchPstring); sprintf(temp2, "otppassword = \"%s\"\015", scratchPstring); CStringToFile(fn, (unsigned char *)temp2); } BlockMove(setSession->TranslationTable, scratchPstring, Length(setSession->TranslationTable) + 1); PtoCstr(scratchPstring); sprintf(temp2, "translation= \"%s\"\015", scratchPstring); CStringToFile(fn, (unsigned char *)temp2); BlockMove(setTerminal->AnswerBackMessage, scratchPstring, *(setTerminal->AnswerBackMessage)+1); PtoCstr(scratchPstring); sprintf(temp2, "answerback= \"%s\"\015", scratchPstring); CStringToFile(fn, (unsigned char *)temp2); if (setSession->authenticate) CStringToFile(fn,(unsigned char *) "authenticate = yes\015"); //CCP added next four lines for authencrypt else CStringToFile(fn,(unsigned char *) "authenticate = no\015"); if (setSession->encrypt) CStringToFile(fn,(unsigned char *) "encrypt = yes\015"); else CStringToFile(fn,(unsigned char *) "encrypt = no\015"); if (setTerminal->MATmappings) CStringToFile(fn,(unsigned char *) "pageup = yes\015"); //CCP 2.7 else CStringToFile(fn,(unsigned char *) "pageup = no\015"); if (setTerminal->remapKeypad) CStringToFile(fn,(unsigned char *) "keypad = yes\015"); //CCP 2.7 else CStringToFile(fn,(unsigned char *) "keypad = no\015"); FSClose(fn); /* BYU LSC */ } \ No newline at end of file +/* * Sets.c * All code relating to loading, parsing, and saving of sets * ***************************************************************** * Revisions: * 7/92 Telnet 2.6: Code moved here from config.c and maclook.c... Jim Browne */ // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #define SAVE_SET_STRINGS_COUNT 73 #include "macros.proto.h" #include "wind.h" /* For WindRec definition */ #include "Sets.proto.h" #include "telneterrors.h" #include "prefs.proto.h" #include "Connections.proto.h" #include "rsinterf.proto.h" #include "rsmac.proto.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "rsdefs.h" #include "DlogUtils.proto.h" extern RSdata *RScurrent; //#define DEBUG_SETS #ifdef DEBUG_SETS #define sets_debug_print(x) putln(x) #else #define sets_debug_print(x) #endif ConnInitParams **SetParams; SessionPrefs *SetSessionPtr; TerminalPrefs *SetTerminalPtr; char *Cspace; extern WindRec *screens; /* Window Records (VS) for : Current Sessions */ extern MenuHandle myMenus[NMENUS]; /* Menu Handles .... */ #define PORTNUM 37 /* NCSA 2.5: the port variable */ void SETSunload(void) {} /* affirmative() checks a token to see if it is a valid Affirmation string. We now get the affirmative strings from the resource */ Boolean affirmative( char *s) { short i; Str255 AffWords; /* Telnet 2.6: get string resources */ for (i=0; iposition; i++) s[i] = tolower(s[i]); for (i=1; i<= AFF_WORDS_COUNT ;i++) { GetIndString(AffWords,AFF_WORDS_ID,i); p2cstr(AffWords); if (!ncstrcmp((char *)AffWords,s)) break; } if (i <= AFF_WORDS_COUNT) return(TRUE); else return(FALSE); } /**************************************************************************/ /* Sissep * is the character a valid separator for the hosts file? * separators are white space, special chars and :;= * */ Boolean Sissep( char c) { if (c < 33) return(1); if (c == ':' || c == ';' || c == '=') return(TRUE); return(FALSE); } /************************************************************************/ /* ncstrcmp * No case string compare. * Only returns 0=match, 1=no match, does not compare greater or less * There is a tiny bit of overlap with the | 32 trick, but shouldn't be * a problem. It causes some different symbols to match. */ short ncstrcmp(char *sa, char *sb) { while (*sa && *sa < 33) /* don't compare leading spaces */ sa++; while (*sb && *sb < 33) sb++; while (*sa && *sb) { if ((*sa != *sb) && ((*sa | 32) != (*sb | 32))) return(1); sa++;sb++; } if (!*sa && !*sb) /* if both at end of string */ return(0); else return(1); } /* confile() now gets all of its keywords from the string resources, for greater ease, flexibility, and overall coolness. */ short confile( char *s) { short i, port, portNeg; Boolean success; unsigned int a,b,c,d; int signedint; Str255 Ckeyw; char tempCstring[256]; sets_debug_print(s); if (!(*s) ) return(0); switch( TelInfo->CONFstate) { case 0: /* No keyword yet! */ for (i=0; iposition; i++) s[i] = tolower(s[i]); for (i=1; i<= SAVE_SET_STRINGS_COUNT ;i++) { GetIndString(Ckeyw,SAVE_SET_STRINGS_ID,i); p2cstr(Ckeyw); if (!ncstrcmp((char *)Ckeyw,s)) break; } if ( i > SAVE_SET_STRINGS_COUNT ) { // OperationFailedAlert(BAD_SET_ERR, 0, 0); TelInfo->CONFstate = 0; break; // return(1); } TelInfo->CONFstate=i; if (TelInfo->CONFstate==5) { SetSessionPtr->bksp = 0; TelInfo->CONFstate=0; } if (TelInfo->CONFstate==6) { SetSessionPtr->bksp = 1; TelInfo->CONFstate=0; } break; case 1: /* NAME */ { char *p; if (NULL == (p = myNewPtr(40000))) /* is there enough memory? */ { /* NOT enough memory for the set! */ DoError(107 | MEMORY_ERRORCLASS, LEVEL2, NULL); /* register the error */ return(-1); } else DisposePtr(p); } if (TelInfo->CONFactive) { success = CreateConnectionFromParams(SetParams); SetParams = NULL; if (!success) { sets_debug_print("ERROR IN OPENING!! "); return(42); } } if (SetParams == NULL) { SetParams = ReturnDefaultConnInitParams(); HLockHi((Handle)SetParams); HLockHi((Handle)(**SetParams).session); SetSessionPtr = *(**SetParams).session; HLockHi((Handle)(**SetParams).terminal); SetTerminalPtr = *(**SetParams).terminal; } strncpy(tempCstring, s, 255); /* Move name in */ CtoPstr(tempCstring); if ((tempCstring[0] == 1) && (tempCstring[1] == ' ')) tempCstring[0] = 0; BlockMove(tempCstring, (**SetParams).WindowName, tempCstring[0]+1); TelInfo->CONFstate=0; TelInfo->CONFactive=1; break; case 2: /* HOST */ strncpy(tempCstring, s, 63); /* Move name in */ CtoPstr(tempCstring); // Process the hosname string. if (ProcessHostnameString((StringPtr)tempCstring, &port, &portNeg)) SetSessionPtr->port = port; BlockMove(tempCstring, SetSessionPtr->hostname, tempCstring[0]+1); TelInfo->CONFstate=0; break; case 3: /* SIZE */ if ( 4 != sscanf(s, "{%d,%d,%d,%d}", &a, &b, &c,&d) ) { sets_debug_print("Error in window size"); return(2); } (**SetParams).WindowLocation.top=a; (**SetParams).WindowLocation.left=b; (**SetParams).WindowLocation.bottom=c; (**SetParams).WindowLocation.right=d; TelInfo->CONFstate=0; break; case 4: if ( 1 != sscanf(s,"%d", &a) ) { sets_debug_print("Scrollback needs parameter"); return(1); } SetTerminalPtr->numbkscroll = a; TelInfo->CONFstate=0; break; case 5: SetSessionPtr->bksp = 0; TelInfo->CONFstate=0; break; case 6: SetSessionPtr->bksp = 1; TelInfo->CONFstate=0; break; case 7: setmacro(&TelInfo->newMacros, 0, s); TelInfo->CONFstate=0; break; case 8: setmacro(&TelInfo->newMacros, 1, s); TelInfo->CONFstate=0; break; case 9: setmacro(&TelInfo->newMacros, 2, s); TelInfo->CONFstate=0; break; case 10: setmacro(&TelInfo->newMacros, 3, s); TelInfo->CONFstate=0; break; case 11: setmacro(&TelInfo->newMacros, 4, s); TelInfo->CONFstate=0; break; case 12: setmacro(&TelInfo->newMacros, 5, s); TelInfo->CONFstate=0; break; case 13: setmacro(&TelInfo->newMacros, 6, s); TelInfo->CONFstate=0; break; case 14: setmacro(&TelInfo->newMacros, 7, s); TelInfo->CONFstate=0; break; case 15: setmacro(&TelInfo->newMacros, 8, s); TelInfo->CONFstate=0; break; case 16: setmacro(&TelInfo->newMacros, 9, s); TelInfo->CONFstate=0; break; case 17: TelInfo->CONFstate=0; // Now ignored (was commandkeys) break; case 18: if (!strcmp(s,"backspace") ) SetSessionPtr->bksp = 0; else SetSessionPtr->bksp = 1; TelInfo->CONFstate=0; break; case 19: case 21: if ( 1 == sscanf(s,"%d", &a) ) SetTerminalPtr->vtwidth = a; TelInfo->CONFstate=0; break; case 20: if (affirmative(s)) SetSessionPtr->tekclear = 1; else SetSessionPtr->tekclear = 0; TelInfo->CONFstate = 0; break; case 22: if ( 3 != sscanf(s, "{%u,%u,%u}", &a, &b, &c)) { /* BYU LSC - "%d" changed to "%u" */ sets_debug_print("Bad Parms to rgb"); return(2); } SetTerminalPtr->nfcolor.red = a; SetTerminalPtr->nfcolor.green = b; SetTerminalPtr->nfcolor.blue = c; TelInfo->CONFstate = 0; break; case 23: if ( 3 != sscanf(s, "{%u,%u,%u}", &a, &b, &c)) { /* BYU LSC - "%d" changed to "%u" */ sets_debug_print("Bad Parms to rgb"); return(2); } SetTerminalPtr->nbcolor.red = a; SetTerminalPtr->nbcolor.green = b; SetTerminalPtr->nbcolor.blue = c; TelInfo->CONFstate = 0; break; case 24: if ( 3 != sscanf(s, "{%u,%u,%u}", &a, &b, &c)) { /* BYU LSC - "%d" changed to "%u" */ sets_debug_print("Bad Parms to rgb"); return(2); } SetTerminalPtr->bfcolor.red = a; SetTerminalPtr->bfcolor.green = b; SetTerminalPtr->bfcolor.blue = c; TelInfo->CONFstate = 0; break; case 25: if ( 3 != sscanf(s, "{%u,%u,%u}", &a, &b, &c)) { /* BYU LSC - "%d" changed to "%u" */ sets_debug_print("Bad Parms to rgb"); return(2); } SetTerminalPtr->bbcolor.red = a; SetTerminalPtr->bbcolor.green = b; SetTerminalPtr->bbcolor.blue = c; TelInfo->CONFstate = 0; break; case 26: /* Font Name */ strncpy(tempCstring, s, 63); /* Move name in */ CtoPstr(tempCstring); BlockMove(tempCstring, &(SetTerminalPtr->DisplayFont[0]), tempCstring[0]+1); TelInfo->CONFstate = 0; break; case 27: /* Font Size */ if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->fontsize = a; TelInfo->CONFstate = 0; break; case 28: /* number of lines to use for window's editable region */ if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->vtheight = a; TelInfo->CONFstate = 0; break; case 29: /* keystop, XOFF key */ if (1 == sscanf( s, "%d", &a)) SetSessionPtr->skey = a; TelInfo->CONFstate = 0; break; case 30: /* keygo, XON key */ if (1 == sscanf( s, "%d", &a)) SetSessionPtr->qkey = a; TelInfo->CONFstate = 0; break; case 31: /* keyip, kill key */ if (1 == sscanf( s, "%d", &a)) SetSessionPtr->ckey = a; TelInfo->CONFstate = 0; break; case 32: /* cr-map */ if ((1 == sscanf( s, "%d", &a)) && (a !=0)) SetSessionPtr->crmap = TRUE; else SetSessionPtr->crmap = FALSE; TelInfo->CONFstate = 0; break; case 33: /* BYU 2.4.9 */ if ((1 == sscanf( s, "%d", &a)) && (a !=0)) /* BYU 2.4.9 */ SetSessionPtr->linemode = TRUE; /* BYU 2.4.9 */ else /* BYU 2.4.9 */ SetSessionPtr->linemode = FALSE; /* BYU 2.4.9 */ TelInfo->CONFstate=0; /* BYU 2.4.9 */ break; /* BYU 2.4.9 */ case 34: /* BYU 2.4.9 */ if ((1 == sscanf( s, "%d", &a)) && (a !=0)) SetTerminalPtr->eightbit = TRUE; /* BYU 2.4.9 */ else /* BYU 2.4.9 */ SetTerminalPtr->eightbit = FALSE; /* BYU 2.4.9 */ TelInfo->CONFstate=0; /* BYU 2.4.9 */ break; /* BYU 2.4.9 */ case 35: /* BYU */ // (**SetParams).ftpstate = 1; /* BYU */ TelInfo->CONFstate=0; /* BYU */ break; /* BYU */ case 36: // ignored TelInfo->CONFstate=0; break; case PORTNUM: /* NCSA 2.5: get the real port # */ if (1 == sscanf( s, "%d", &a)) /* NCSA */ SetSessionPtr->port = a; /* NCSA */ TelInfo->CONFstate = 0; /* NCSA */ break; /* NCSA */ case 38: // translation strncpy((char *) SetSessionPtr->TranslationTable, s, 32); CtoPstr((char *) SetSessionPtr->TranslationTable); TelInfo->CONFstate=0; break; case 39: // tekem if (1 == sscanf(s, "%d", &signedint)) SetSessionPtr->tektype = signedint; TelInfo->CONFstate=0; break; case 40: // answerback strncpy((char *) SetTerminalPtr->AnswerBackMessage, s, 32); CtoPstr((char *) SetTerminalPtr->AnswerBackMessage); TelInfo->CONFstate=0; break; case 41: //authenticate if (affirmative(s)) SetSessionPtr->authenticate = TRUE; else SetSessionPtr->authenticate = FALSE; TelInfo->CONFstate=0; break; case 42: //encrypt if (affirmative(s)) SetSessionPtr->encrypt = TRUE; else SetSessionPtr->encrypt = FALSE; TelInfo->CONFstate=0; break; case 43: //pageup/down map if (affirmative(s)) SetTerminalPtr->MATmappings = TRUE; else SetTerminalPtr->MATmappings = FALSE; TelInfo->CONFstate=0; break; case 44: //keypad map if (affirmative(s)) SetTerminalPtr->remapKeypad = TRUE; else SetTerminalPtr->remapKeypad = FALSE; TelInfo->CONFstate=0; break; case 45: // ansicolor if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->ANSIgraphics = a; TelInfo->CONFstate=0; break; case 46: // arrowmap if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->emacsarrows = a; TelInfo->CONFstate=0; break; case 47: // emacsmeta if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->emacsmetakey = a; TelInfo->CONFstate=0; break; case 48: // pastemethod if (1 == sscanf( s, "%d", &a)) SetSessionPtr->pastemethod = a; TelInfo->CONFstate=0; break; case 49: // pastesize if (1 == sscanf( s, "%d", &a)) SetSessionPtr->pasteblocksize = a; TelInfo->CONFstate=0; break; case 50: // saveclear if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->clearsave = a; TelInfo->CONFstate=0; break; case 51: // vtemulation if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->vtemulation = a; TelInfo->CONFstate=0; break; case 52: // forcesave if (1 == sscanf( s, "%d", &a)) SetSessionPtr->forcesave = a; TelInfo->CONFstate=0; break; case 53: // vtwrap if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->vtwrap = a; TelInfo->CONFstate=0; break; case 54: // xterm if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->Xtermsequences = a; TelInfo->CONFstate=0; break; case 55: // localecho if (1 == sscanf( s, "%d", &a)) SetSessionPtr->localecho = a; TelInfo->CONFstate=0; break; case 56: // halfdup if (1 == sscanf( s, "%d", &a)) SetSessionPtr->halfdup = a; TelInfo->CONFstate=0; break; case 57: // remapctrld if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->remapCtrlD = a; TelInfo->CONFstate=0; break; case 58: // negative if (1 == sscanf( s, "%d", &a)) SetSessionPtr->portNegative = a; TelInfo->CONFstate=0; break; case 59: // allowbold if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->allowBold = a; TelInfo->CONFstate=0; break; case 60: // colorbold if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->colorBold = a; TelInfo->CONFstate=0; break; case 61: // ignorebeeps if (1 == sscanf( s, "%d", &a)) SetSessionPtr->ignoreBeeps = a; TelInfo->CONFstate=0; break; case 62: // ignoreff if (1 == sscanf( s, "%d", &a)) SetSessionPtr->ignoreff = a; TelInfo->CONFstate=0; break; case 63: // boldfont strncpy(tempCstring, s, 63); /* Move name in */ CtoPstr(tempCstring); BlockMove(tempCstring, &(SetTerminalPtr->BoldFont[0]), tempCstring[0]+1); TelInfo->CONFstate = 0; break; case 64: // inversebold if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->boldFontStyle = a; TelInfo->CONFstate = 0; break; case 65: // otpauto if (1 == sscanf( s, "%d", &a)) SetSessionPtr->otpauto = a; TelInfo->CONFstate = 0; break; case 66: // otpmulti if (1 == sscanf( s, "%d", &a)) SetSessionPtr->otpmulti = a; TelInfo->CONFstate = 0; break; case 67: // otphex if (1 == sscanf( s, "%d", &a)) SetSessionPtr->otphex = a; TelInfo->CONFstate = 0; break; case 68: // otpnoprompt if (1 == sscanf( s, "%d", &a)) SetSessionPtr->otpnoprompt = a; TelInfo->CONFstate = 0; break; case 69: // otppassword strncpy(tempCstring, s, 63); /* Move name in */ CtoPstr(tempCstring); BlockMove(tempCstring, &(SetSessionPtr->otppassword[0]), tempCstring[0]+1); TelInfo->CONFstate = 0; break; case 70: // realbold if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->realbold = a; TelInfo->CONFstate = 0; break; case 71: // otpsavepass if (1 == sscanf( s, "%d", &a)) SetSessionPtr->otpsavepass = a; TelInfo->CONFstate = 0; break; case 72: // oldscrollback if (1 == sscanf( s, "%d", &a)) SetTerminalPtr->oldScrollback = a; TelInfo->CONFstate = 0; break; default: TelInfo->CONFstate=0; } return(0); } /* confile */ /************************************************************************/ /* contoken * tokenize the strings which get passed to confile. * Handles quotes and uses separators: <33, ;:= */ short contoken( char c) { short retval; Boolean success; if (c == EOF) { Cspace[TelInfo->position++] = '\0'; sets_debug_print("Eof handler called"); confile(Cspace); if (TelInfo->CONFactive) { success = CreateConnectionFromParams(SetParams); if (!success) { sets_debug_print("ERROR IN OPENING!! "); return(42); } } return(-1); } if (!TelInfo->position && !TelInfo->inquote && Sissep(c)) /*if (!TelInfo->position && Sissep(c)) */ /* old_skip over junk before keyword */ return(0); if (TelInfo->inquote || !Sissep(c)) { if (TelInfo->position > 200) { sets_debug_print("Out of bounds error!"); return(1); } /* * check for quotes, a little mixed up here, could be reorganized */ if (c == '"' ) { if (!TelInfo->inquote) { /* beginning of quotes */ TelInfo->inquote = 1; return(0); } Cspace[TelInfo->position++] =c; return(0); } else { /* include in current string */ if (c != '\012' && c != '\015') /* BYU 2.4.18 - changed \n to \015 and added \012 */ { Cspace[TelInfo->position++] = c; return(0); } } } if (Cspace[TelInfo->position-1] == '"') TelInfo->position--; Cspace[TelInfo->position++] = '\0'; retval = confile(Cspace); /* pass the token along */ TelInfo->position = 0; TelInfo->inquote = 0; Cspace[0] = '\0'; return(retval); } /************************************************************************/ /* readconfig * read the saved set file into our in-memory data structure. * Handle everything by keyword (stored in resources). */ void readconfig(FSSpec theSet) { short c,retval; short fn; OSErr err; Cspace = myNewPtr(256); /* BYU LSC - get room for gathering stuff */ SetParams = ReturnDefaultConnInitParams(); HLockHi((Handle)SetParams); HLockHi((Handle)(**SetParams).session); SetSessionPtr = *(**SetParams).session; HLockHi((Handle)(**SetParams).terminal); SetTerminalPtr = *(**SetParams).terminal; if (NULL == Cspace) /* no memory left for the set to load in */ { /* we're out of memory */ DoError(107 | MEMORY_ERRORCLASS, LEVEL2, NULL); return; } TelInfo->position = TelInfo->CONFstate = TelInfo->CONFactive = TelInfo->inquote = TelInfo->lineno = 0; /* state vars */ err = HOpenDF(theSet.vRefNum, theSet.parID, theSet.name, fsRdPerm, &fn); retval = 0; while (!retval) { c = Myfgetc(fn); if (c == '#' && !TelInfo->inquote) { while (c != EOF && c != '\012' && c != '\015') /* skip to EOL */ /* BYU 2.4.18 - changed \n to \015 and added \012*/ c = Myfgetc(fn); } if (c == '\012' || c == '\015') /* BYU 2.4.18 - changed \n to \015 and added \012 */ TelInfo->lineno++; retval = contoken(c); } FSClose(fn); DisposePtr((Ptr) Cspace); if (retval == EOF) { /* EOF is normal end */ sets_debug_print("EOF termination"); } else { sets_debug_print("NON-EOF termination"); } return; } void LoadSet( void) { SFReply sfr; long junk; SFTypeList typesok = {'CONF'}; Point where; FSSpec set; Str255 tempString; where.h=100;where.v=100; GetIndString(tempString,MISC_STRINGS,SET_TO_LOAD_STRING); SFGetFile( where,tempString, 0L, 1, typesok, 0L, &sfr); if (! sfr.good) return; BlockMove(&sfr.fName, set.name, (*sfr.fName)+1); // pstring copy sfr.fName -> set.name GetWDInfo(sfr.vRefNum, &set.vRefNum, &set.parID, &junk); readconfig(set); } char Myfgetc(short myfile) { OSErr err; long count; unsigned char buffer; count = 1; if ((err = FSRead(myfile, &count, &buffer)) == eofErr) buffer = EOF; return (buffer); } void CStringToFile(short myfile, unsigned char *mystring) { long mycount; /* BYU LSC */ short fstatus; /* BYU LSC */ mycount = strlen((char *) mystring); /* BYU LSC */ fstatus = FSWrite(myfile,&mycount,mystring); /* BYU LSC */ } void SaveSet(short doSaveMacros, short dontSaveTitle) { SFReply sfr; short fn, truncate; WindowPeek wpeek; Rect rect; Point where; long junk; char temp[256], temp2[256]; /* BYU LSC */ short fnum,fsiz; short i; FSSpec set; OSErr err; Str255 scratchPstring,scratchPstring2; where.h = 100; where.v = 100; GetIndString(scratchPstring,MISC_STRINGS,SAVE_SET_STRING); GetIndString(scratchPstring2,MISC_STRINGS,DEFAULT_SAVE_SET_NAME); SFPutFile(where,scratchPstring,scratchPstring2, 0L, &sfr); /* BYU LSC */ if (!sfr.good) return; BlockMoveData(&sfr.fName, set.name, (*sfr.fName)+1); // pstring copy sfr.fName -> set.name GetWDInfo(sfr.vRefNum, &set.vRefNum, &set.parID, &junk); if ((err = HCreate(set.vRefNum, set.parID, set.name, kNCSACreatorSignature, kNCSASetFileType)) == dupFNErr) truncate = 1; err = HOpenDF(set.vRefNum, set.parID, set.name, fsWrPerm, &fn); if (truncate) SetEOF(fn, 0L); if (gApplicationPrefs->CommandKeys) CStringToFile(fn,(unsigned char *) "commandkeys = yes\015"); /* BYU LSC */ else CStringToFile(fn,(unsigned char *) "commandkeys = no\015"); /* BYU LSC */ if (doSaveMacros) for (i = 0; i < 10; i++) { getmacro(&TelInfo->newMacros,i, temp, sizeof(temp)); /* BYU LSC */ if (*temp) { /* BYU LSC */ sprintf(temp2, "key%d = \"", i); /* BYU 2.4.16 */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp); /* BYU LSC */ strcpy(temp2,"\"\015"); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ } /* BYU LSC */ } /* for */ #if 0 /* BYU LSC */ for (i = 0; i < TelInfo->numwindows; i++) { short j; j = RSgetfont(screens[i].vs, &fnum, &fsiz); } /* for */ #endif /* BYU LSC */ for (i = 0; i < TelInfo->numwindows; i++) { if (!dontSaveTitle) { GetWTitle(screens[i].wind, scratchPstring); PtoCstr(scratchPstring); sprintf(temp2, "name= \"%s\"\015", scratchPstring); } else sprintf(temp2, "name= \" \"\015", scratchPstring); CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ BlockMove((Ptr)screens[i].machine, (Ptr)scratchPstring, StrLength(screens[i].machine)+1); PtoCstr(scratchPstring); sprintf(temp2, "host= \"%s\"\015", scratchPstring); CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf (temp2,"port= %d\015",screens[i].portNum); /* NCSA: save port # */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf(temp2, "scrollback= %d\015", (screens[i].maxscroll)); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ if (screens[i].bsdel) CStringToFile(fn,(unsigned char *) "erase = delete\015"); /* BYU LSC */ else CStringToFile(fn,(unsigned char *) "erase = backspace\015"); /* BYU LSC */ wpeek = (WindowPeek) screens[i].wind; rect = (*wpeek->contRgn)->rgnBBox; if (!dontSaveTitle) { sprintf(temp2, "size = {%d,%d,%d,%d}\015", rect.top, rect.left, /* BYU LSC */ rect.bottom, rect.right); CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ } sprintf(temp2, "vtwidth = %d\015", VSmaxwidth(screens[i].vs) + 1); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ if (screens[i].tekclear) CStringToFile(fn,(unsigned char *) "tekclear = yes\015"); /* BYU LSC */ else CStringToFile(fn,(unsigned char *) "tekclear = no\015"); /* BYU LSC */ if (TelInfo->haveColorQuickDraw) { RGBColor theColor; short j; for (j = 0; j < 4; j++) { theColor = RSgetcolor( screens[i].vs, j); sprintf(temp2, "rgb%d = {%u,%u,%u}\015", j, theColor.red, theColor.green, theColor.blue); CStringToFile(fn,(unsigned char *) temp2); } } RSgetfont( screens[i].vs, &fnum, &fsiz); GetFontName( fnum, (StringPtr)temp); /* BYU LSC */ #ifndef MPW p2cstr((unsigned char *) temp); /* BYU LSC */ #endif sprintf( temp2, "font = \"%s\"\015", temp); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "fsize= %d\015", fsiz); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ RSsetwind(screens[i].vs); fnum = RScurrent->bfnum; GetFontName( fnum, (StringPtr)temp); /* BYU LSC */ #ifndef MPW p2cstr((unsigned char *) temp); /* BYU LSC */ #endif sprintf( temp2, "boldfont = \"%s\"\015", temp); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "nlines= %d\015", VSgetlines(screens[i].vs));/* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "keystop= %d\015", screens[i].TELstop); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "keygo= %d\015", screens[i].TELgo); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "keyip= %d\015", screens[i].TELip); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "crmap= %d\015", screens[i].crmap); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "tekem= %d\015", screens[i].tektype); CStringToFile(fn,(unsigned char *) temp2); // All this stuff was added in BetterTelnet 1.0b3... (RAB) sprintf( temp2, "vtemulation = %d\015", screens[i].vtemulation); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "forcesave = %d\015", screens[i].forcesave); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "eightbit = %d\015", screens[i].eightbit); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "vtwrap = %d\015", screens[i].wrap); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "xterm = %d\015", screens[i].Xterm); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "remapctrld = %d\015", screens[i].remapCtrlD); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "ansicolor = %d\015", screens[i].ANSIgraphics); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "arrowmap = %d\015", screens[i].arrowmap); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "emacsmeta = %d\015", screens[i].emacsmeta); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "pastemethod = %d\015", screens[i].pastemethod); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "pastesize = %d\015", screens[i].pastesize); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "saveclear = %d\015", screens[i].ESscroll); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "linemode = %d\015", screens[i].lineAllow); CStringToFile(fn,(unsigned char *) temp2); // And all this stuff was added a bit later... (RAB BetterTelnet 1.0 and later) sprintf( temp2, "negative = %d\015", screens[i].portNegative); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "allowbold = %d\015", screens[i].allowBold); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "colorbold = %d\015", screens[i].colorBold); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "ignorebeeps = %d\015", screens[i].ignoreBeeps); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "ignoreff = %d\015", screens[i].ignoreff); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "inversebold = %d\015", screens[i].inversebold); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otpauto = %d\015", screens[i].otpauto); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otpmulti = %d\015", screens[i].otpmulti); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otphex = %d\015", screens[i].otphex); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otpnoprompt = %d\015", screens[i].otpnoprompt); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "realbold = %d\015", screens[i].realbold); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "oldscrollback = %d\015", screens[i].oldScrollback); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otpsavepass = %d\015", screens[i].otpsavepass); CStringToFile(fn,(unsigned char *) temp2); // end of "all this stuff" if (screens[i].otppassword[0]) { // RAB BetterTelnet 1.2 pstrcpy(scratchPstring, (unsigned char *)screens[i].otppassword); p2cstr(scratchPstring); sprintf(temp2, "otppassword = \"%s\"\015", scratchPstring); CStringToFile(fn, (unsigned char *)temp2); } if (screens[i].national) { // Don't do this if using default translation table GetMenuItemText(myMenus[National], screens[i].national+1, scratchPstring); PtoCstr(scratchPstring); sprintf(temp2, "translation= \"%s\"\015", scratchPstring); CStringToFile(fn, (unsigned char *)temp2); } BlockMove(screens[i].answerback, scratchPstring, *(screens[i].answerback)+1); PtoCstr(scratchPstring); sprintf(temp2, "answerback= \"%s\"\015", scratchPstring); CStringToFile(fn, (unsigned char *)temp2); if (screens[i].authenticate) CStringToFile(fn,(unsigned char *) "authenticate = yes\015"); //CCP added next four lines for authencrypt else CStringToFile(fn,(unsigned char *) "authenticate = no\015"); if (screens[i].encrypt) CStringToFile(fn,(unsigned char *) "encrypt = yes\015"); else CStringToFile(fn,(unsigned char *) "encrypt = no\015"); if (screens[i].pgupdwn) CStringToFile(fn,(unsigned char *) "pageup = yes\015"); //CCP 2.7 else CStringToFile(fn,(unsigned char *) "pageup = no\015"); if (screens[i].keypadmap) CStringToFile(fn,(unsigned char *) "keypad = yes\015"); //CCP 2.7 else CStringToFile(fn,(unsigned char *) "keypad = no\015"); } /* for i */ FSClose(fn); /* BYU LSC */ } // This is new for BetterTelnet 1.0b4. It saves sessions directly from the Favorites. (RAB) void SaveSetFromSession(SessionPrefs* setSession, TerminalPrefs* setTerminal, short doWeAppend, short doSaveMacros) { SFReply sfr; short fn, truncate; WindowPeek wpeek; Rect rect; Point where; long junk; char temp[256], temp2[256]; /* BYU LSC */ short fnum,fsiz, i; FSSpec set; OSErr err; Str255 scratchPstring,scratchPstring2; SFTypeList typesok = {'CONF'}; where.h = 100; where.v = 100; if (doWeAppend) { GetIndString(scratchPstring,MISC_STRINGS,SAVE_SET_STRING); SFGetFile( where,scratchPstring, 0L, 1, typesok, 0L, &sfr); } else { GetIndString(scratchPstring,MISC_STRINGS,SAVE_SET_STRING); GetIndString(scratchPstring2,MISC_STRINGS,DEFAULT_SAVE_SET_NAME); SFPutFile(where,scratchPstring,scratchPstring2, 0L, &sfr); /* BYU LSC */ } if (!sfr.good) return; BlockMoveData(&sfr.fName, set.name, (*sfr.fName)+1); // pstring copy sfr.fName -> set.name GetWDInfo(sfr.vRefNum, &set.vRefNum, &set.parID, &junk); if (!doWeAppend) if ((err = HCreate(set.vRefNum, set.parID, set.name, kNCSACreatorSignature, kNCSASetFileType)) == dupFNErr) truncate = 1; err = HOpenDF(set.vRefNum, set.parID, set.name, fsWrPerm, &fn); if ((!doWeAppend) && truncate) SetEOF(fn, 0L); if (doWeAppend) SetFPos(fn, 2, 0L); if (doSaveMacros) for (i = 0; i < 10; i++) { getmacro(&TelInfo->newMacros,i, temp, sizeof(temp)); /* BYU LSC */ if (*temp) { /* BYU LSC */ sprintf(temp2, "key%d = \"", i); /* BYU 2.4.16 */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp); /* BYU LSC */ strcpy(temp2,"\"\015"); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ } /* BYU LSC */ } /* for */ sprintf(temp2, "name= \" \"\015"); CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ BlockMove(setSession->hostname, (Ptr)scratchPstring, StrLength(setSession->hostname)+1); PtoCstr(scratchPstring); sprintf(temp2, "host= \"%s\"\015", scratchPstring); CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf (temp2,"port= %d\015",setSession->port); /* NCSA: save port # */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf(temp2, "scrollback= %d\015", setTerminal->numbkscroll); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ if (setSession->bksp) CStringToFile(fn,(unsigned char *) "erase = delete\015"); /* BYU LSC */ else CStringToFile(fn,(unsigned char *) "erase = backspace\015"); /* BYU LSC */ sprintf(temp2, "vtwidth = %d\015", setTerminal->vtwidth); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ if (setSession->tekclear) CStringToFile(fn,(unsigned char *) "tekclear = yes\015"); /* BYU LSC */ else CStringToFile(fn,(unsigned char *) "tekclear = no\015"); /* BYU LSC */ if (TelInfo->haveColorQuickDraw) { sprintf(temp2, "rgb%d = {%u,%u,%u}\015", 0, setTerminal->nfcolor.red, setTerminal->nfcolor.green, setTerminal->nfcolor.blue); CStringToFile(fn,(unsigned char *) temp2); sprintf(temp2, "rgb%d = {%u,%u,%u}\015", 1, setTerminal->nbcolor.red, setTerminal->nbcolor.green, setTerminal->nbcolor.blue); CStringToFile(fn,(unsigned char *) temp2); sprintf(temp2, "rgb%d = {%u,%u,%u}\015", 2, setTerminal->bfcolor.red, setTerminal->bfcolor.green, setTerminal->bfcolor.blue); CStringToFile(fn,(unsigned char *) temp2); sprintf(temp2, "rgb%d = {%u,%u,%u}\015", 3, setTerminal->bbcolor.red, setTerminal->bbcolor.green, setTerminal->bbcolor.blue); CStringToFile(fn,(unsigned char *) temp2); } BlockMove(setTerminal->DisplayFont, temp, StrLength(setTerminal->DisplayFont) + 1); #ifndef MPW p2cstr((unsigned char *) temp); /* BYU LSC */ #endif sprintf( temp2, "font = \"%s\"\015", temp); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "fsize= %d\015", setTerminal->fontsize); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ BlockMove(setTerminal->BoldFont, temp, StrLength(setTerminal->BoldFont) + 1); #ifndef MPW p2cstr((unsigned char *) temp); #endif sprintf( temp2, "boldfont = \"%s\"\015", temp); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "nlines= %d\015", setTerminal->vtheight);/* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "keystop= %d\015", setSession->skey); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "keygo= %d\015", setSession->qkey); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "keyip= %d\015", setSession->ckey); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "crmap= %d\015", setSession->crmap); /* BYU LSC */ CStringToFile(fn,(unsigned char *) temp2); /* BYU LSC */ sprintf( temp2, "tekem= %d\015", setSession->tektype); CStringToFile(fn,(unsigned char *) temp2); // All this stuff was added in BetterTelnet 1.0b3... (RAB) sprintf( temp2, "vtemulation = %d\015", setTerminal->vtemulation); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "forcesave = %d\015", setSession->forcesave); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "eightbit = %d\015", setTerminal->eightbit); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "vtwrap = %d\015", setTerminal->vtwrap); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "xterm = %d\015", setTerminal->Xtermsequences); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "remapctrld = %d\015", setTerminal->remapCtrlD); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "ansicolor = %d\015", setTerminal->ANSIgraphics); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "arrowmap = %d\015", setTerminal->emacsarrows); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "emacsmeta = %d\015", setTerminal->emacsmetakey); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "pastemethod = %d\015", setSession->pastemethod); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "pastesize = %d\015", setSession->pasteblocksize); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "saveclear = %d\015", setTerminal->clearsave); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "linemode = %d\015", setSession->linemode); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "negative = %d\015", setSession->portNegative); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "allowbold = %d\015", setTerminal->allowBold); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "colorbold = %d\015", setTerminal->colorBold); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "ignorebeeps = %d\015", setSession->ignoreBeeps); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "ignoreff = %d\015", setSession->ignoreff); CStringToFile(fn,(unsigned char *) temp2); // And all this stuff was added in 1.0b5... (RAB) sprintf( temp2, "localecho = %d\015", setSession->localecho); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "halfdup = %d\015", setSession->halfdup); CStringToFile(fn,(unsigned char *) temp2); // end of "all this stuff" (RAB) sprintf( temp2, "otpauto = %d\015", setSession->otpauto); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otpmulti = %d\015", setSession->otpmulti); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otphex = %d\015", setSession->otphex); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otpnoprompt = %d\015", setSession->otpnoprompt); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "realbold = %d\015", setTerminal->realbold); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "oldscrollback = %d\015", setTerminal->oldScrollback); CStringToFile(fn,(unsigned char *) temp2); sprintf( temp2, "otpsavepass = %d\015", setSession->otpsavepass); CStringToFile(fn,(unsigned char *) temp2); if (screens[i].otppassword[0]) { // RAB BetterTelnet 1.2 pstrcpy(scratchPstring, (unsigned char *)setSession->otppassword); p2cstr(scratchPstring); sprintf(temp2, "otppassword = \"%s\"\015", scratchPstring); CStringToFile(fn, (unsigned char *)temp2); } BlockMove(setSession->TranslationTable, scratchPstring, StrLength(setSession->TranslationTable) + 1); PtoCstr(scratchPstring); sprintf(temp2, "translation= \"%s\"\015", scratchPstring); CStringToFile(fn, (unsigned char *)temp2); BlockMove(setTerminal->AnswerBackMessage, scratchPstring, *(setTerminal->AnswerBackMessage)+1); PtoCstr(scratchPstring); sprintf(temp2, "answerback= \"%s\"\015", scratchPstring); CStringToFile(fn, (unsigned char *)temp2); if (setSession->authenticate) CStringToFile(fn,(unsigned char *) "authenticate = yes\015"); //CCP added next four lines for authencrypt else CStringToFile(fn,(unsigned char *) "authenticate = no\015"); if (setSession->encrypt) CStringToFile(fn,(unsigned char *) "encrypt = yes\015"); else CStringToFile(fn,(unsigned char *) "encrypt = no\015"); if (setTerminal->MATmappings) CStringToFile(fn,(unsigned char *) "pageup = yes\015"); //CCP 2.7 else CStringToFile(fn,(unsigned char *) "pageup = no\015"); if (setTerminal->remapKeypad) CStringToFile(fn,(unsigned char *) "keypad = yes\015"); //CCP 2.7 else CStringToFile(fn,(unsigned char *) "keypad = no\015"); FSClose(fn); /* BYU LSC */ } \ No newline at end of file diff --git a/source/Url/url.c b/source/Url/url.c index c943ce6..12e7418 100755 --- a/source/Url/url.c +++ b/source/Url/url.c @@ -1 +1 @@ -// url.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "rsinterf.proto.h" #include "IConfig.proto.h" #include "url.proto.h" #include "vsdata.h"//because the damn prototype on the next line needs it #include "vsinterf.proto.h" #include "ICTypes.h" #include "ICAPI.h" #include "ICKeys.h" // Revised 5/97 to use IC 1.1's new ICLaunchURL routine. (RAB BetterTelnet 1.0b2c2) extern ICInstance inst; TURLKind ParseURL(Handle, short*); Boolean MyStrNEqual (char *s1, char *s2, short n); OSErr FindAppOnVolume (OSType sig, short vRefNum, FSSpec *file); OSErr FindAppFromSig (OSType sig, FSSpec *fSpec, Boolean *running, ProcessSerialNumber *psn); OSErr FindRunningAppBySignature (OSType sig, FSSpec *fSpec, ProcessSerialNumber *psn); OSErr LaunchAppWithEventAndString (Boolean running, FSSpec *appSpec, ProcessSerialNumber *psn, OSType eventClass, OSType eventID, OSType keyword, char *str, unsigned short launchFileFlags, unsigned short launchControlFlags); OSErr OpenHelperWithURL (OSType sig, char *url); OSErr GetLastModDateTime(FSSpec *fSpec, unsigned long *lastModDateTime); OSErr VolHasDesktopDB (short vRefNum, Boolean *hasDesktop); OSErr GetIndVolume (short index, short *vRefNum); #define kGetURLEventClass 'GURL' #define kGetURLEventID 'GURL' static unsigned char gTable[256] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x41, 0x41, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0x4F, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xAE, 0x4F, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0x22, 0x22, 0xC9, 0x20, 0x41, 0x41, 0x4F, 0xAE, 0xAE, 0xD0, 0xD1, 0x22, 0x22, 0x27, 0x27, 0xD6, 0xD7, 0x59, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, }; char *gURLSchemeNames[] = { ":", /* kNotURL */ "mailto:", "news:", "nntp:", "ftp:", "http:", "gopher:", "wais:", "telnet:", "rlogin:", "tn3270:", "finger:", "whois:", nil }; void UnloadURL(void) { } Boolean MyStrNEqual (char *s1, char *s2, short n) { unsigned char *t = gTable; unsigned char *us1 = (unsigned char *)s1; unsigned char *us2 = (unsigned char *)s2; while (--n >= 0 && t[*us1++] == t[*us2++]) /* do nothing */; return n < 0; } #define CR 0x0d /* the carriage return character */ #define isLWSP(a) ((a) == ' ' || (a) == '\t') #define isLWSPorCR(a) (isLWSP(a) || (a) == CR) void HandleURL(short w) { Handle urlH; TURLKind urlKind; OSErr err; OSType sig; short returnedSize; long fakeSelBegin, fakeSelEnd; urlH = RSGetTextSel(w, 0); if ((urlH == (char **)-1L) || (urlH == nil)) { return; } HLock(urlH); urlKind = ParseURL(urlH, &returnedSize); if (urlKind == 100) return; else if ((urlKind == kTelnetURL)/*||(urlKind == kRloginURL)*/) { //we handle this, send apple event to ourselves ProcessSerialNumber psn; unsigned short launchControlFlags; FlashSelection(w); launchControlFlags = launchContinue | launchNoFileFlags; launchControlFlags |= launchDontSwitch; GetCurrentProcess(&psn); err = LaunchAppWithEventAndString(TRUE, NULL, &psn, kGetURLEventClass, kGetURLEventID, keyDirectObject, *urlH, 0, launchControlFlags); return; } else { fakeSelBegin = 0; fakeSelEnd = returnedSize; ICFindConfigFile(inst, 0, 0); ICLaunchURL(inst, aligned_pstring("\p"), *urlH, returnedSize, &fakeSelBegin, &fakeSelEnd); } // sig = GetHelperInfo(urlKind); // if (sig == NULL) // return; FlashSelection(w); // err = OpenHelperWithURL(sig, *urlH); return; } TURLKind ParseURL(Handle urlH, short *returnedSize) { short size; char *textBegin, *textEnd, *p; TURLKind urlKind; char *schemeName; size = GetHandleSize(urlH); textBegin = *urlH; textEnd = *urlH + size - 1; /* strip off leading white space and lagging white space */ while (isLWSPorCR(*textBegin) && textBegin < textEnd) textBegin++; while (isLWSPorCR(*textBegin) && textBegin < textEnd) textEnd--; /* look for < and > on each end, strip em off */ if (*textBegin == '<') textBegin++; if (*textEnd == '>') textEnd--; /* look for URL:, strip it*/ if ((MyStrNEqual("URL:", textBegin, 4))) textBegin += 4; size = textEnd - textBegin + 1; if (size <= 0) return 100; /* strip CR inside */ p = textBegin; while (p < textEnd) { if (*p == CR) { BlockMoveData(p+1, p,size - (p-textBegin + 1)); size--; textEnd--; } else p++; } /* Clean up and NULL terminate */ BlockMoveData(textBegin, *urlH, size); *(*urlH + size) = 0; /* get url type */ p = *urlH; while ((*p != ':')&&(p < *urlH + size - 1)) p++; if (p - *urlH >= size - 1) // colon not found { /* might be mail address */ //if (isMailAddress(urlH)) // return kMailtoURL; // else return 100; } *returnedSize = size; for (urlKind = kNotURL; ; urlKind++) { schemeName = gURLSchemeNames[urlKind]; if (schemeName == nil) return kNotURL; if (MyStrNEqual(*urlH, schemeName, strlen(schemeName))) return urlKind; } } OSErr FindAppOnVolume (OSType sig, short vRefNum, FSSpec *file) { DTPBRec pb; OSErr err = noErr; short ioDTRefNum, i; FInfo fInfo; FSSpec candidate; unsigned long lastModDateTime, maxLastModDateTime; memset(&pb, 0, sizeof(DTPBRec)); pb.ioCompletion = nil; pb.ioVRefNum = vRefNum; pb.ioNamePtr = nil; err = PBDTGetPath(&pb); if (err != noErr) return err; ioDTRefNum = pb.ioDTRefNum; memset(&pb, 0, sizeof(DTPBRec)); pb.ioCompletion = nil; pb.ioIndex = 0; pb.ioFileCreator = sig; pb.ioNamePtr = file->name; pb.ioDTRefNum = ioDTRefNum; err = PBDTGetAPPLSync(&pb); if (err == fnfErr || err == paramErr) return afpItemNotFound; if (err != noErr) return err; file->vRefNum = vRefNum; file->parID = pb.ioAPPLParID; err = FSpGetFInfo(file, &fInfo); if (err == noErr) return noErr; i = 1; maxLastModDateTime = 0; while (true) { memset(&pb, 0, sizeof(DTPBRec)); pb.ioCompletion = nil; pb.ioIndex = i; pb.ioFileCreator = sig; pb.ioNamePtr = candidate.name; pb.ioDTRefNum = ioDTRefNum; err = PBDTGetAPPLSync(&pb); if (err != noErr) break; candidate.vRefNum = vRefNum; candidate.parID = pb.ioAPPLParID; err = GetLastModDateTime(file, &lastModDateTime); if (err == noErr) { if (lastModDateTime > maxLastModDateTime) { maxLastModDateTime = lastModDateTime; *file = candidate; } } i++; } return maxLastModDateTime > 0 ? noErr : afpItemNotFound; } /*---------------------------------------------------------------------------- GetLastModDateTime Get the last mod date and time of a file. Entry: fSpec = pointer to file spec. Exit: function result = error code. *lastModDateTime = last mod date and time. ----------------------------------------------------------------------------*/ OSErr GetLastModDateTime(FSSpec *fSpec, unsigned long *lastModDateTime) { CInfoPBRec pBlock; OSErr err = noErr; pBlock.hFileInfo.ioNamePtr = fSpec->name; pBlock.hFileInfo.ioVRefNum = fSpec->vRefNum; pBlock.hFileInfo.ioFDirIndex = 0; pBlock.hFileInfo.ioDirID = fSpec->parID; err = PBGetCatInfoSync(&pBlock); if (err != noErr) return err; *lastModDateTime = pBlock.hFileInfo.ioFlMdDat; return noErr; } /*---------------------------------------------------------------------------- VolHasDesktopDB Check to see if a volume supports the new desktop database. Entry: vRefNum = vol ref num of volumn Exit: function result = error code. *hasDesktop = true if volume has the new desktop database. ----------------------------------------------------------------------------*/ OSErr VolHasDesktopDB (short vRefNum, Boolean *hasDesktop) { HParamBlockRec pb; GetVolParmsInfoBuffer info; OSErr err = noErr; pb.ioParam.ioCompletion = nil; pb.ioParam.ioNamePtr = nil; pb.ioParam.ioVRefNum = vRefNum; pb.ioParam.ioBuffer = (Ptr)&info; pb.ioParam.ioReqCount = sizeof(info); err = PBHGetVolParmsSync(&pb); *hasDesktop = err == noErr && (info.vMAttrib & (1L << bHasDesktopMgr)) != 0; return err; } OSErr FindAppFromSig (OSType sig, FSSpec *fSpec, Boolean *running, ProcessSerialNumber *psn) { OSErr err = noErr; short sysVRefNum, vRefNum, index; Boolean hasDesktopDB; long junk; if (running != nil) { err = FindRunningAppBySignature(sig, fSpec, psn); *running = true; if (err == noErr) return noErr; *running = false; if (err != procNotFound) return err; } err = FindFolder(kOnSystemDisk, kSystemFolderType, false, &sysVRefNum, &junk); if (err != noErr) return err; vRefNum = sysVRefNum; index = 0; while (true) { if (index == 0 || vRefNum != sysVRefNum) { err = VolHasDesktopDB(vRefNum, &hasDesktopDB); if (err != noErr) return err; if (hasDesktopDB) { err = FindAppOnVolume(sig, vRefNum, fSpec); if (err != afpItemNotFound) return err; } } index++; err = GetIndVolume(index, &vRefNum); if (err == nsvErr) return fnfErr; if (err != noErr) return err; } } OSErr GetIndVolume (short index, short *vRefNum) { ParamBlockRec pb; OSErr err = noErr; pb.volumeParam.ioCompletion = nil; pb.volumeParam.ioNamePtr = nil; pb.volumeParam.ioVolIndex = index; err = PBGetVInfoSync(&pb); *vRefNum = pb.volumeParam.ioVRefNum; return err; } /*---------------------------------------------------------------------------- FindRunningAppBySignature Find a running app given its signature. Entry: sig = signature of app. Exit: function result = error code. = procNotFound if not running. *fSpec = file spec of app. *psn = process serial number of running app. ----------------------------------------------------------------------------*/ OSErr FindRunningAppBySignature (OSType sig, FSSpec *fSpec, ProcessSerialNumber *psn) { OSErr err = noErr; ProcessInfoRec info; psn->highLongOfPSN = 0; psn->lowLongOfPSN = kNoProcess; while (true) { err = GetNextProcess(psn); if (err != noErr) return err; info.processInfoLength = sizeof(info); info.processName = nil; info.processAppSpec = fSpec; err = GetProcessInformation(psn, &info); if (err != noErr) return err; if (info.processSignature == sig) return noErr; } } /*---------------------------------------------------------------------------- LaunchAppWithEventAndString Launch an application with an initial event with a string parameter. Entry: running = true if application is running, in which case it is sent the odoc event. appSpec = file spec of application. *psn = process serial number of app if it is running. eventClass = event class. eventID = event id. keyword = parameter keyword (keyDirectObject if string is the direct object). str = the string parameter for the event. launchFileFlags = file flags. launchControlFlags = control flags. Exit: function result = error code. ----------------------------------------------------------------------------*/ OSErr LaunchAppWithEventAndString (Boolean running, FSSpec *appSpec, ProcessSerialNumber *psn, OSType eventClass, OSType eventID, OSType keyword, char *str, unsigned short launchFileFlags, unsigned short launchControlFlags) { ProcessSerialNumber thePSN; LaunchParamBlockRec launchThis; AEDesc target = {0, nil}; AEDesc stringDesc = {0, nil}; AEDesc launchDesc = {0, nil}; AppleEvent theEvent = {0, nil}; AppleEvent theReply = {0, nil}; OSErr err = noErr; Boolean autoParamValue = false; if (running) thePSN = *psn; err = AECreateDesc(typeProcessSerialNumber, &thePSN, sizeof(thePSN), &target); if (err != noErr) goto exit; err = AECreateAppleEvent(eventClass, eventID, &target, kAutoGenerateReturnID, kAnyTransactionID, &theEvent); if (err != noErr) goto exit; err = AECreateDesc(typeChar, str, strlen(str), &stringDesc); if (err != noErr) goto exit; err = AEPutParamDesc(&theEvent, keyword, &stringDesc); if (err != noErr) goto exit; if (running) { err = AESend(&theEvent, &theReply, kAENoReply, kAENormalPriority, kNoTimeOut, nil, nil); if (err != noErr) goto exit; if ((launchControlFlags & launchDontSwitch) == 0) { err = SetFrontProcess(psn); if (err != noErr) goto exit; } } else { err = AECoerceDesc(&theEvent, typeAppParameters, &launchDesc); if (err != noErr) goto exit; HLock(theEvent.dataHandle); launchThis.launchAppSpec = appSpec; launchThis.launchAppParameters = (AppParametersPtr)*launchDesc.dataHandle; launchThis.launchBlockID = extendedBlock; launchThis.launchEPBLength = extendedBlockLen; launchThis.launchFileFlags = launchFileFlags; launchThis.launchControlFlags = launchControlFlags; err = LaunchApplication(&launchThis); } exit: if (target.dataHandle != nil) AEDisposeDesc(&target); if (stringDesc.dataHandle != nil) AEDisposeDesc(&stringDesc); if (launchDesc.dataHandle != nil) AEDisposeDesc(&launchDesc); if (theEvent.dataHandle != nil) AEDisposeDesc(&theEvent); if (theReply.dataHandle != nil) AEDisposeDesc(&theReply); return err; } /*---------------------------------------------------------------------------- OpenHelperWithURL Open a helper program and pass it a URL string. Entry: helperInfo = pointer to helper info. url = URL string. Exit: function result = error code. ----------------------------------------------------------------------------*/ OSErr OpenHelperWithURL (OSType sig, char *url) { OSErr err = noErr; ProcessSerialNumber psn; FSSpec appSpec; Boolean running; unsigned short launchControlFlags; launchControlFlags = launchContinue | launchNoFileFlags; err = FindAppFromSig(sig, &appSpec, &running, &psn); if (err != noErr) return err; err = LaunchAppWithEventAndString(running, &appSpec, &psn, kGetURLEventClass, kGetURLEventID, keyDirectObject, url, 0, launchControlFlags); return err; } #define isurlschemechar(c) (isalnum((c)) || c == '+' || c == '.' || c == '-') Boolean FindURLAroundPoint(Point curr, short w) { /* called by RSSelect when Command Click has occured outside any selection. This routine looks for urls around the current point, makes that the selected area if it finds one, and returns TRUE. Otherwise leaves the current selection area untouched and returns FALSE. */ /* Note: the point we receive is already normalized to a character position */ short columns; Handle block; char *original, *start, *end, *textEnd, *p, *q; short i, numLines = 1; char EOLS = CR; short neededLines, endLine = 0, startLine = 0; short blockSize; Point startPoint, endPoint; short currentLine; char *tempBlockPtr; short tempCounter, lineLength[20]; Boolean found = FALSE, allowSpaces=FALSE; columns = VSgetcols(w) + 1; //VSgetcols returns one less than the number of columns /* we need enough space to find a 255 char URL on either side of the cursor */ neededLines = 510/columns; if (255%columns != 0) neededLines += 2; /* want it to be symmetric about this line */ if (neededLines%2 == 0) neededLines += 1; blockSize = neededLines*(columns + 1); //we need space for the \r block = myNewHandle((long)blockSize); textEnd = *block + blockSize; HLock(block); /* get the lines we need */ VSgettext(w, 0, curr.v-(neededLines-1)/2, columns-1, curr.v+(neededLines-1)/2, *block, blockSize, &EOLS, 0); original = *block; for (i = 0; i < (neededLines-1)/2; i++) { while (*original != CR) original++; original++; } original+= curr.h + 1; tempBlockPtr = *block; for (i = 0; i < neededLines; i++) { tempCounter = 0; while (*tempBlockPtr++ != CR) tempCounter++; lineLength[i] = tempCounter; } p = original; q = original - 1; currentLine = (neededLines-1)/2 + 1; while ((!found)&&(p > *block)) { while (p >= *block && !isLWSPorCR(*p) && *p != '<' && *p != '"') p--; if (*p == CR) { if (lineLength[currentLine - 2] == columns) { p--; //this is just a wrapped line currentLine--; } else found = TRUE; } else found = TRUE; } startLine = currentLine; if (*p != '<') p++; else allowSpaces = TRUE; currentLine = (neededLines-1)/2 + 1; found = FALSE; while (!found) { while (q < textEnd && (*q != CR) &&(!isLWSP(*q) || allowSpaces) && *q != '>' && *q != '"') q++; if (*q == CR) { if (lineLength[currentLine-1] == columns) { q++; //this is just a wrapped line currentLine++; } else found = TRUE; } else found = TRUE; } endLine = currentLine; if (*q != '>') q--; if (p >= q) return FALSE; while (p < q && (isLWSPorCR(*p))) p++; while (p < q && (isLWSPorCR(*q))) q--; if (*p == '<') { if (*q != '>') return FALSE; } else { if (*q == '>') return FALSE; } start = p; end = q; UnHiliteSelection(w); HUnlock(block); startPoint.v = curr.v - ((neededLines-1)/2 + 1 - startLine); endPoint.v = curr.v + (endLine -(neededLines-1)/2 - 1); if (startPoint.v == curr.v) startPoint.h = curr.h - (original - start); else { long numChars = 0; for (i = 0; i < startLine - 1; i++) numChars += lineLength[i] + 1; startPoint.h = (start - *block - numChars - 1); } if (endPoint.v == curr.v) endPoint.h = curr.h + (end - original + 1); else { long numChars = 0; for (i = 0; i < endLine - 1; i++) numChars += lineLength[i] + 1; endPoint.h = (end - *block - numChars); } HiliteThis(w, startPoint, endPoint); return TRUE; } \ No newline at end of file +// url.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "rsinterf.proto.h" #include "IConfig.proto.h" #include "url.proto.h" #include "vsdata.h"//because the damn prototype on the next line needs it #include "vsinterf.proto.h" #include "ICTypes.h" #include "ICAPI.h" #include "ICKeys.h" // Revised 5/97 to use IC 1.1's new ICLaunchURL routine. (RAB BetterTelnet 1.0b2c2) extern ICInstance inst; TURLKind ParseURL(Handle, short*); Boolean MyStrNEqual (char *s1, char *s2, short n); OSErr FindAppOnVolume (OSType sig, short vRefNum, FSSpec *file); OSErr FindAppFromSig (OSType sig, FSSpec *fSpec, Boolean *running, ProcessSerialNumber *psn); OSErr FindRunningAppBySignature (OSType sig, FSSpec *fSpec, ProcessSerialNumber *psn); OSErr LaunchAppWithEventAndString (Boolean running, FSSpec *appSpec, ProcessSerialNumber *psn, OSType eventClass, OSType eventID, OSType keyword, char *str, unsigned short launchFileFlags, unsigned short launchControlFlags); OSErr OpenHelperWithURL (OSType sig, char *url); OSErr GetLastModDateTime(FSSpec *fSpec, unsigned long *lastModDateTime); OSErr VolHasDesktopDB (short vRefNum, Boolean *hasDesktop); OSErr GetIndVolume (short index, short *vRefNum); #define kGetURLEventClass 'GURL' #define kGetURLEventID 'GURL' static unsigned char gTable[256] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x41, 0x41, 0x43, 0x45, 0x4E, 0x4F, 0x55, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x55, 0x55, 0x55, 0x55, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0x4F, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xAE, 0x4F, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0x22, 0x22, 0xC9, 0x20, 0x41, 0x41, 0x4F, 0xAE, 0xAE, 0xD0, 0xD1, 0x22, 0x22, 0x27, 0x27, 0xD6, 0xD7, 0x59, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, }; char *gURLSchemeNames[] = { ":", /* kNotURL */ "mailto:", "news:", "nntp:", "ftp:", "http:", "gopher:", "wais:", "telnet:", "rlogin:", "tn3270:", "finger:", "whois:", nil }; void UnloadURL(void) { } Boolean MyStrNEqual (char *s1, char *s2, short n) { unsigned char *t = gTable; unsigned char *us1 = (unsigned char *)s1; unsigned char *us2 = (unsigned char *)s2; while (--n >= 0 && t[*us1++] == t[*us2++]) /* do nothing */; return n < 0; } #define CR 0x0d /* the carriage return character */ #define isLWSP(a) ((a) == ' ' || (a) == '\t') #define isLWSPorCR(a) (isLWSP(a) || (a) == CR) void HandleURL(short w) { Handle urlH; TURLKind urlKind; OSErr err; OSType sig; short returnedSize; long fakeSelBegin, fakeSelEnd, handleSize; urlH = RSGetTextSel(w, 0); if ((urlH == (char **)-1L) || (urlH == nil)) { return; } // 12/10/97, RJZ. Increase size by one // so there is room for a NULL // terminator. handleSize = GetHandleSize(urlH); SetHandleSize(urlH, handleSize + 1); if (MemError() != noErr) { DisposeHandle(urlH); return; } HLock(urlH); (*urlH)[handleSize] = ' '; urlKind = ParseURL(urlH, &returnedSize); if (urlKind == 100) return; else if ((urlKind == kTelnetURL)/*||(urlKind == kRloginURL)*/) { //we handle this, send apple event to ourselves ProcessSerialNumber psn; unsigned short launchControlFlags; FlashSelection(w); launchControlFlags = launchContinue | launchNoFileFlags; launchControlFlags |= launchDontSwitch; GetCurrentProcess(&psn); err = LaunchAppWithEventAndString(TRUE, NULL, &psn, kGetURLEventClass, kGetURLEventID, keyDirectObject, *urlH, 0, launchControlFlags); return; } else { fakeSelBegin = 0; fakeSelEnd = returnedSize; FlashSelection(w); ICFindConfigFile(inst, 0, 0); ICLaunchURL(inst, aligned_pstring("\p"), *urlH, returnedSize, &fakeSelBegin, &fakeSelEnd); } // sig = GetHelperInfo(urlKind); // if (sig == NULL) // return; // err = OpenHelperWithURL(sig, *urlH); return; } TURLKind ParseURL(Handle urlH, short *returnedSize) { short size; char *textBegin, *textEnd, *p; TURLKind urlKind; char *schemeName; size = GetHandleSize(urlH); textBegin = *urlH; textEnd = *urlH + size - 1; /* strip off leading white space and lagging white space */ while (isLWSPorCR(*textBegin) && textBegin < textEnd) textBegin++; // RJZ. 12/10/97 Start search at end! while (isLWSPorCR(*textEnd) && textBegin < textEnd) textEnd--; /* look for < and > on each end, strip em off */ if (*textBegin == '<') textBegin++; if (*textEnd == '>') textEnd--; /* look for URL:, strip it*/ if ((MyStrNEqual("URL:", textBegin, 4))) textBegin += 4; size = textEnd - textBegin + 1; if (size <= 0) return 100; /* strip CR inside */ p = textBegin; while (p < textEnd) { if (*p == CR) { BlockMoveData(p+1, p,size - (p-textBegin + 1)); size--; textEnd--; } else p++; } /* Clean up and NULL terminate */ BlockMoveData(textBegin, *urlH, size); *(*urlH + size) = 0; /* get url type */ p = *urlH; while ((*p != ':')&&(p < *urlH + size - 1)) p++; if (p - *urlH >= size - 1) // colon not found { /* might be mail address */ //if (isMailAddress(urlH)) // return kMailtoURL; // else return 100; } *returnedSize = size; for (urlKind = kNotURL; ; urlKind++) { schemeName = gURLSchemeNames[urlKind]; if (schemeName == nil) return kNotURL; if (MyStrNEqual(*urlH, schemeName, strlen(schemeName))) return urlKind; } } OSErr FindAppOnVolume (OSType sig, short vRefNum, FSSpec *file) { DTPBRec pb; OSErr err = noErr; short ioDTRefNum, i; FInfo fInfo; FSSpec candidate; unsigned long lastModDateTime, maxLastModDateTime; memset(&pb, 0, sizeof(DTPBRec)); pb.ioCompletion = nil; pb.ioVRefNum = vRefNum; pb.ioNamePtr = nil; err = PBDTGetPath(&pb); if (err != noErr) return err; ioDTRefNum = pb.ioDTRefNum; memset(&pb, 0, sizeof(DTPBRec)); pb.ioCompletion = nil; pb.ioIndex = 0; pb.ioFileCreator = sig; pb.ioNamePtr = file->name; pb.ioDTRefNum = ioDTRefNum; err = PBDTGetAPPLSync(&pb); if (err == fnfErr || err == paramErr) return afpItemNotFound; if (err != noErr) return err; file->vRefNum = vRefNum; file->parID = pb.ioAPPLParID; err = FSpGetFInfo(file, &fInfo); if (err == noErr) return noErr; i = 1; maxLastModDateTime = 0; while (true) { memset(&pb, 0, sizeof(DTPBRec)); pb.ioCompletion = nil; pb.ioIndex = i; pb.ioFileCreator = sig; pb.ioNamePtr = candidate.name; pb.ioDTRefNum = ioDTRefNum; err = PBDTGetAPPLSync(&pb); if (err != noErr) break; candidate.vRefNum = vRefNum; candidate.parID = pb.ioAPPLParID; err = GetLastModDateTime(file, &lastModDateTime); if (err == noErr) { if (lastModDateTime > maxLastModDateTime) { maxLastModDateTime = lastModDateTime; *file = candidate; } } i++; } return maxLastModDateTime > 0 ? noErr : afpItemNotFound; } /*---------------------------------------------------------------------------- GetLastModDateTime Get the last mod date and time of a file. Entry: fSpec = pointer to file spec. Exit: function result = error code. *lastModDateTime = last mod date and time. ----------------------------------------------------------------------------*/ OSErr GetLastModDateTime(FSSpec *fSpec, unsigned long *lastModDateTime) { CInfoPBRec pBlock; OSErr err = noErr; pBlock.hFileInfo.ioNamePtr = fSpec->name; pBlock.hFileInfo.ioVRefNum = fSpec->vRefNum; pBlock.hFileInfo.ioFDirIndex = 0; pBlock.hFileInfo.ioDirID = fSpec->parID; err = PBGetCatInfoSync(&pBlock); if (err != noErr) return err; *lastModDateTime = pBlock.hFileInfo.ioFlMdDat; return noErr; } /*---------------------------------------------------------------------------- VolHasDesktopDB Check to see if a volume supports the new desktop database. Entry: vRefNum = vol ref num of volumn Exit: function result = error code. *hasDesktop = true if volume has the new desktop database. ----------------------------------------------------------------------------*/ OSErr VolHasDesktopDB (short vRefNum, Boolean *hasDesktop) { HParamBlockRec pb; GetVolParmsInfoBuffer info; OSErr err = noErr; pb.ioParam.ioCompletion = nil; pb.ioParam.ioNamePtr = nil; pb.ioParam.ioVRefNum = vRefNum; pb.ioParam.ioBuffer = (Ptr)&info; pb.ioParam.ioReqCount = sizeof(info); err = PBHGetVolParmsSync(&pb); *hasDesktop = err == noErr && (info.vMAttrib & (1L << bHasDesktopMgr)) != 0; return err; } OSErr FindAppFromSig (OSType sig, FSSpec *fSpec, Boolean *running, ProcessSerialNumber *psn) { OSErr err = noErr; short sysVRefNum, vRefNum, index; Boolean hasDesktopDB; long junk; if (running != nil) { err = FindRunningAppBySignature(sig, fSpec, psn); *running = true; if (err == noErr) return noErr; *running = false; if (err != procNotFound) return err; } err = FindFolder(kOnSystemDisk, kSystemFolderType, false, &sysVRefNum, &junk); if (err != noErr) return err; vRefNum = sysVRefNum; index = 0; while (true) { if (index == 0 || vRefNum != sysVRefNum) { err = VolHasDesktopDB(vRefNum, &hasDesktopDB); if (err != noErr) return err; if (hasDesktopDB) { err = FindAppOnVolume(sig, vRefNum, fSpec); if (err != afpItemNotFound) return err; } } index++; err = GetIndVolume(index, &vRefNum); if (err == nsvErr) return fnfErr; if (err != noErr) return err; } } OSErr GetIndVolume (short index, short *vRefNum) { ParamBlockRec pb; OSErr err = noErr; pb.volumeParam.ioCompletion = nil; pb.volumeParam.ioNamePtr = nil; pb.volumeParam.ioVolIndex = index; err = PBGetVInfoSync(&pb); *vRefNum = pb.volumeParam.ioVRefNum; return err; } /*---------------------------------------------------------------------------- FindRunningAppBySignature Find a running app given its signature. Entry: sig = signature of app. Exit: function result = error code. = procNotFound if not running. *fSpec = file spec of app. *psn = process serial number of running app. ----------------------------------------------------------------------------*/ OSErr FindRunningAppBySignature (OSType sig, FSSpec *fSpec, ProcessSerialNumber *psn) { OSErr err = noErr; ProcessInfoRec info; psn->highLongOfPSN = 0; psn->lowLongOfPSN = kNoProcess; while (true) { err = GetNextProcess(psn); if (err != noErr) return err; info.processInfoLength = sizeof(info); info.processName = nil; info.processAppSpec = fSpec; err = GetProcessInformation(psn, &info); if (err != noErr) return err; if (info.processSignature == sig) return noErr; } } /*---------------------------------------------------------------------------- LaunchAppWithEventAndString Launch an application with an initial event with a string parameter. Entry: running = true if application is running, in which case it is sent the odoc event. appSpec = file spec of application. *psn = process serial number of app if it is running. eventClass = event class. eventID = event id. keyword = parameter keyword (keyDirectObject if string is the direct object). str = the string parameter for the event. launchFileFlags = file flags. launchControlFlags = control flags. Exit: function result = error code. ----------------------------------------------------------------------------*/ OSErr LaunchAppWithEventAndString (Boolean running, FSSpec *appSpec, ProcessSerialNumber *psn, OSType eventClass, OSType eventID, OSType keyword, char *str, unsigned short launchFileFlags, unsigned short launchControlFlags) { ProcessSerialNumber thePSN; LaunchParamBlockRec launchThis; AEDesc target = {0, nil}; AEDesc stringDesc = {0, nil}; AEDesc launchDesc = {0, nil}; AppleEvent theEvent = {0, nil}; AppleEvent theReply = {0, nil}; OSErr err = noErr; Boolean autoParamValue = false; if (running) thePSN = *psn; err = AECreateDesc(typeProcessSerialNumber, &thePSN, sizeof(thePSN), &target); if (err != noErr) goto exit; err = AECreateAppleEvent(eventClass, eventID, &target, kAutoGenerateReturnID, kAnyTransactionID, &theEvent); if (err != noErr) goto exit; err = AECreateDesc(typeChar, str, strlen(str), &stringDesc); if (err != noErr) goto exit; err = AEPutParamDesc(&theEvent, keyword, &stringDesc); if (err != noErr) goto exit; if (running) { err = AESend(&theEvent, &theReply, kAENoReply, kAENormalPriority, kNoTimeOut, nil, nil); if (err != noErr) goto exit; if ((launchControlFlags & launchDontSwitch) == 0) { err = SetFrontProcess(psn); if (err != noErr) goto exit; } } else { err = AECoerceDesc(&theEvent, typeAppParameters, &launchDesc); if (err != noErr) goto exit; HLock(theEvent.dataHandle); launchThis.launchAppSpec = appSpec; launchThis.launchAppParameters = (AppParametersPtr)*launchDesc.dataHandle; launchThis.launchBlockID = extendedBlock; launchThis.launchEPBLength = extendedBlockLen; launchThis.launchFileFlags = launchFileFlags; launchThis.launchControlFlags = launchControlFlags; err = LaunchApplication(&launchThis); } exit: if (target.dataHandle != nil) AEDisposeDesc(&target); if (stringDesc.dataHandle != nil) AEDisposeDesc(&stringDesc); if (launchDesc.dataHandle != nil) AEDisposeDesc(&launchDesc); if (theEvent.dataHandle != nil) AEDisposeDesc(&theEvent); if (theReply.dataHandle != nil) AEDisposeDesc(&theReply); return err; } /*---------------------------------------------------------------------------- OpenHelperWithURL Open a helper program and pass it a URL string. Entry: helperInfo = pointer to helper info. url = URL string. Exit: function result = error code. ----------------------------------------------------------------------------*/ OSErr OpenHelperWithURL (OSType sig, char *url) { OSErr err = noErr; ProcessSerialNumber psn; FSSpec appSpec; Boolean running; unsigned short launchControlFlags; launchControlFlags = launchContinue | launchNoFileFlags; err = FindAppFromSig(sig, &appSpec, &running, &psn); if (err != noErr) return err; err = LaunchAppWithEventAndString(running, &appSpec, &psn, kGetURLEventClass, kGetURLEventID, keyDirectObject, url, 0, launchControlFlags); return err; } #define isurlschemechar(c) (isalnum((c)) || c == '+' || c == '.' || c == '-') Boolean FindURLAroundPoint(Point curr, short w) { /* called by RSSelect when Command Click has occured outside any selection. This routine looks for urls around the current point, makes that the selected area if it finds one, and returns TRUE. Otherwise leaves the current selection area untouched and returns FALSE. */ /* Note: the point we receive is already normalized to a character position */ short columns; Handle block; char *original, *start, *end, *textEnd, *p, *q; short i, numLines = 1; char EOLS = CR; short neededLines, endLine = 0, startLine = 0; short blockSize; Point startPoint, endPoint; short currentLine, currentLength; char *tempBlockPtr; short tempCounter, lineLength[20]; Boolean found = FALSE, allowSpaces=FALSE; short firstLine, lastLine; short numPreviousLines; columns = VSgetcols(w) + 1; //VSgetcols returns one less than the number of columns /* we need enough space to find a 255 char URL on either side of the cursor */ neededLines = 510/columns; if (255%columns != 0) neededLines += 2; /* want it to be symmetric about this line */ if (neededLines%2 == 0) neededLines += 1; // RJZ 12/11/97. Make sure the first // line is on the screen. firstLine = curr.v - (neededLines - 1)/2; lastLine = curr.v + (neededLines - 1)/2; if (firstLine < -VSgetnumlines(w)) { neededLines += (firstLine + VSgetnumlines(w)); firstLine = -VSgetnumlines(w); } numPreviousLines = curr.v - firstLine; blockSize = neededLines*(columns + 1); //we need space for the \r block = myNewHandle((long)blockSize); HLock(block); // RJZ. 12/11/97. Get pointer to end // of text *after* locking the handle. textEnd = *block + blockSize; /* get the lines we need */ VSgettext(w, 0, firstLine, columns-1, lastLine, *block, blockSize, &EOLS, 0); original = *block; // RJZ 12/12/97. Fixed so that after // this loop, original points to the // start of the line where click // occurred. // numPreviousLines = (neededLines - 1)/2; // if (numPreviousLines > curr.v) // numPreviousLines = curr.v; for (i = 0; i < numPreviousLines; i++) { while (*original != CR) original++; original++; } original+= curr.h + 1; tempBlockPtr = *block; for (i = 0; i < neededLines; i++) { tempCounter = 0; while (*tempBlockPtr++ != CR) tempCounter++; lineLength[i] = tempCounter; } p = original; q = original - 1; // RJZ 12/11/97 currentLine = numPreviousLines; while ((!found)&&(p > *block)) { while (p >= *block && !isLWSPorCR(*p) && *p != '<' && *p != '"') p--; if (*p == CR) { if (currentLine > 0) currentLength = lineLength[currentLine - 1]; else currentLength = 0; if (currentLength == columns) { p--; //this is just a wrapped line if (currentLine > 0) // RAB BetterTelnet 2.0b1 - sanity check currentLine--; } else found = TRUE; } else found = TRUE; } startLine = currentLine; if (*p != '<') p++; else allowSpaces = TRUE; // RJZ 12/11/97 currentLine = numPreviousLines; found = FALSE; while (!found) { while (q < textEnd && (*q != CR) &&(!isLWSP(*q) || allowSpaces) && *q != '>' && *q != '"') q++; if (*q == CR) { // RJZ 12/10/97 if (lineLength[currentLine] == columns || allowSpaces) { q++; //this is just a wrapped line currentLine++; } else found = TRUE; } else found = TRUE; } endLine = currentLine; if (*q != '>') q--; // RJZ 12/10/97. Dispose of block // before returning. if (p >= q) { DisposeHandle(block); return FALSE; } while (p < q && (isLWSPorCR(*p))) p++; while (p < q && (isLWSPorCR(*q))) q--; // RJZ. 12/10/97. Dispose block // before returning. if (*p == '<') { if (*q != '>') { DisposeHandle(block); return FALSE; } } else { if (*q == '>') { DisposeHandle(block); return FALSE; } } start = p; end = q; UnHiliteSelection(w); HUnlock(block); // RJZ 12/11/97 startPoint.v = curr.v - (numPreviousLines - startLine); endPoint.v = curr.v + endLine - numPreviousLines; if (startPoint.v == curr.v) startPoint.h = curr.h - (original - start); else { long numChars = 0; // RJZ 12/11/97 for (i = 0; i < startLine; i++) numChars += lineLength[i] + 1; startPoint.h = (start - *block - numChars - 1); } if (endPoint.v == curr.v) endPoint.h = curr.h + (end - original + 1); else { long numChars = 0; // RJZ 12/11/97 for (i = 0; i < endLine; i++) numChars += lineLength[i] + 1; endPoint.h = (end - *block - numChars); } HiliteThis(w, startPoint, endPoint); // RJZ 12/10/97. Dispose block // before returning. DisposeHandle(block); return TRUE; } \ No newline at end of file diff --git a/source/ae/ae.c b/source/ae/ae.c index 37d6a96..78c7aed 100755 --- a/source/ae/ae.c +++ b/source/ae/ae.c @@ -1 +1 @@ -/* * ae.c * Code to handle the AppleEvents we recognize */ // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "wind.h" // For connections.proto.h #include "ae.proto.h" #include "connections.proto.h" // For OpenConnectionFromURL proto #include "Sets.proto.h" // For readconfig proto #include "macros.proto.h" // For loadMacro proto #include "menuseg.proto.h" // For HandleQuit proto #include "debug.h" // For ShowDebugWindow proto static void ProcessURLEscapeCodes (char *url, char **end); void AEunload(void) { } SIMPLE_UPP(MyHandleODoc, AEEventHandler); pascal OSErr MyHandleODoc (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon) { FSSpec myFSS; AEDescList docList; OSErr err; long index, itemsInList; Size actualSize; AEKeyword keywd; DescType returnedType; FInfo fileInfo; if ((err = AEGetParamDesc (theAppleEvent, keyDirectObject, typeAEList, &docList)) != noErr) return err; // check for missing parameters if ((err = MyGotRequiredParams (theAppleEvent)) != noErr) return err; // count the number of descriptor records in the list if ((err = AECountItems (&docList, &itemsInList)) != noErr) return err; for (index = 1; index <= itemsInList; index++) { err = AEGetNthPtr (&docList, index, typeFSS, &keywd, &returnedType, (Ptr) &myFSS, sizeof(myFSS), &actualSize); if (err) return err; FSpGetFInfo(&myFSS, &fileInfo); /* make sure it's a data file */ if (fileInfo.fdType == kNCSASetFileType) { TelInfo->gotDocument = 1; readconfig(myFSS); // Read the actual set } else if(fileInfo.fdType == 'TEXT') loadMacros(&myFSS); else if (fileInfo.fdType == 'DBUG') { TelInfo->debug = TRUE; ShowDebugWindow(); } } err = AEDisposeDesc (&docList); return noErr; } SIMPLE_UPP(MyHandlePDoc, AEEventHandler); pascal OSErr MyHandlePDoc (AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefCon) { // We don't print files. return (errAEEventNotHandled); } SIMPLE_UPP(MyHandleOApp, AEEventHandler); pascal OSErr MyHandleOApp (AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefCon) { // Don't need to do anything for OApp. // Well, actually, we do, because we don't want to show the Open Connection box // automatically if a set file was opened. if (gApplicationPrefs->autoOpenDialog && !TelInfo->gotDocument) PresentOpenConnectionDialog(); return noErr; } SIMPLE_UPP(MyHandleQuit, AEEventHandler); pascal OSErr MyHandleQuit (AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefCon) { if (HandleQuit()) return(-128); // userCancelledErr return(noErr); } SIMPLE_UPP(MyHandleGURL, AEEventHandler); pascal OSErr MyHandleGURL (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon) { OSErr err; DescType returnedType; Size actualSize; char URLString[255]; char *beg, *end, *user, *password, *portstring, *host; if ((err = AEGetParamPtr(theAppleEvent, keyDirectObject, typeChar, &returnedType, URLString, sizeof(URLString)-1, &actualSize)) != noErr) return err; // check for missing parameters if ((err = MyGotRequiredParams(theAppleEvent)) != noErr) return err; URLString[actualSize] = 0; // Terminate the C string beg = &URLString[0]; end = &URLString[actualSize-1]; // Strip leading spaces while ((beg < end) && (*beg == ' ')) beg++; // Strip trailing spaces while ((end < beg) && (*end == ' ')) end--; // Look for (and strip) beginning and ending angle brackets if (*beg == '<') { if (*end != '>') { // Leading angle bracket, but no trailing angle bracket err = paramErr; goto badExit; } // Nuke the brackets beg++; end--; } // Terminate the string we currently have (for strncmp fn's) *(end+1) = 0; // Look for (and strip) leading "URL:" if (!strncmp(beg, "URL:", 4)) { beg += 4; } // Look for (and strip) leading "telnet://" if (strncmp(beg, "telnet://", 9)) // No leading "telnet://" { if (strncmp(beg, "rlogin://", 9)) { err = paramErr; goto badExit; } } beg += 9; // Drop any ending slash if (*end == '/') { *end = 0; end--; } // Process any escaped characters ProcessURLEscapeCodes(beg, &end); // Set up for URL parsing password = nil; portstring = nil; host = nil; // Assume exists user = beg; // Leading : or @ is a no-no if ((*beg == ':') || (*beg == '@')) { err = paramErr; goto badExit; } // Scan for : or @ or end of string while ((beg <= end) && (*beg != ':') && (*beg != '@')) beg++; // If we reached the end, only a host was given if (beg > end) { host = user; user = nil; goto goodUrl; } // If : was found, scan in the password (or port) if (*beg == ':') { *beg++ = 0; password = beg; // Scan for : or @ or end of string while ((beg <= end) && (*beg != ':') && (*beg != '@')) beg++; if (*beg == ':') { // xxxx:yyyy: is a no-no err = paramErr; goto badExit; } if (*beg != '@') { // End of string. Must be host:port host = user; user = nil; portstring = password; password = nil; goto goodUrl; } // Have xxx:yyy@ *beg++ = 0; // Terminate password string } else { // Found @ *beg++ = 0; // Terminate user string } // Ok at this point have xxx:yyy@ or xxxx@ host = beg; // Scan for : or @ or end of string while ((beg <= end) && (*beg != ':') && (*beg != '@') && (*beg != '/')) //CCP fix bad telnets beg++; if (*beg == '@') { //xxx[:yyyy]@xxx@ is a no-no err = paramErr; goto badExit; } if (*beg != ':') { // End of string, we have xxxx[:yyyy]@zzzz *beg = 0; } else { *beg++ = 0; // Terminate host string portstring = beg; } goodUrl: TelInfo->gotDocument = 1; OpenConnectionFromURL(host, portstring, user, password); err = noErr; badExit: return err; } /*---------------------------------------------------------------------------- ProcessURLEscapeCodes Process "%xx" escape codes in a URL string (replace them by the characters they represent). Entry: url = URL with escape codes. Exit: url = URL with escape codes replaced by the characters they represent. Copyright 1994, Northwestern University. Modified 12/94 Jim Browne for NCSA ----------------------------------------------------------------------------*/ static void ProcessURLEscapeCodes (char *url, char **end) { char *p, *q; char c1, c2; p = q = url; while (*p != 0) { if (*p == '%') { c1 = tolower(*(p+1)); c2 = tolower(*(p+2)); if (isxdigit(c1) && isxdigit(c2)) { c1 = isdigit(c1) ? c1 - '0' : c1 - 'a' + 10; c2 = isdigit(c2) ? c2 - '0' : c2 - 'a' + 10; *q++ = (c1 << 4) + c2; p += 3; } else { *q++ = *p++; } } else { *q++ = *p++; } } *q = 0; *end = q-1; } OSErr MyGotRequiredParams (AppleEvent *theAppleEvent) { DescType returnedType; Size actualSize; OSErr err; err = AEGetAttributePtr (theAppleEvent, keyMissedKeywordAttr, typeWildCard, &returnedType, nil, 0, &actualSize); if (err == errAEDescNotFound) // you got all the required parameters return noErr; else if (!err) // you missed a required parameter return errAEEventNotHandled; else // the call to AEGetAttributePtr failed return err; } \ No newline at end of file +/* * ae.c * Code to handle the AppleEvents we recognize */ // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "wind.h" // For connections.proto.h #include "ae.proto.h" #include "connections.proto.h" // For OpenConnectionFromURL proto #include "Sets.proto.h" // For readconfig proto #include "macros.proto.h" // For loadMacro proto #include "menuseg.proto.h" // For HandleQuit proto #include "debug.h" // For ShowDebugWindow proto #include "parse.proto.h" #include "linemode.proto.h" extern WindRec *screens; extern short scrn; static void ProcessURLEscapeCodes (char *url, char **end); void AEunload(void) { } SIMPLE_UPP(MyHandleODoc, AEEventHandler); pascal OSErr MyHandleODoc (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon) { FSSpec myFSS; AEDescList docList; OSErr err; long index, itemsInList; Size actualSize; AEKeyword keywd; DescType returnedType; FInfo fileInfo; if ((err = AEGetParamDesc (theAppleEvent, keyDirectObject, typeAEList, &docList)) != noErr) return err; // check for missing parameters if ((err = MyGotRequiredParams (theAppleEvent)) != noErr) return err; // count the number of descriptor records in the list if ((err = AECountItems (&docList, &itemsInList)) != noErr) return err; for (index = 1; index <= itemsInList; index++) { err = AEGetNthPtr (&docList, index, typeFSS, &keywd, &returnedType, (Ptr) &myFSS, sizeof(myFSS), &actualSize); if (err) return err; FSpGetFInfo(&myFSS, &fileInfo); /* make sure it's a data file */ if (fileInfo.fdType == kNCSASetFileType) { TelInfo->gotDocument = 1; readconfig(myFSS); // Read the actual set } else if(fileInfo.fdType == 'TEXT') loadMacros(&TelInfo->newMacros, &myFSS); else if (fileInfo.fdType == 'DBUG') { TelInfo->debug = TRUE; ShowDebugWindow(); } } err = AEDisposeDesc (&docList); return noErr; } SIMPLE_UPP(MyHandlePDoc, AEEventHandler); pascal OSErr MyHandlePDoc (AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefCon) { // We don't print files. return (errAEEventNotHandled); } SIMPLE_UPP(MyHandleOApp, AEEventHandler); pascal OSErr MyHandleOApp (AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefCon) { // Don't need to do anything for OApp. // Well, actually, we do, because we don't want to show the Open Connection box // automatically if a set file was opened. if (gApplicationPrefs->autoOpenDialog && !TelInfo->gotDocument) PresentOpenConnectionDialog(); return noErr; } SIMPLE_UPP(MyHandleQuit, AEEventHandler); pascal OSErr MyHandleQuit (AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefCon) { if (HandleQuit()) return(-128); // userCancelledErr return(noErr); } SIMPLE_UPP(MyHandleSendData, AEEventHandler); pascal OSErr MyHandleSendData (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon) { OSErr err; DescType returnedType; Size actualSize; char DataString[255]; if ((err = AEGetParamPtr(theAppleEvent, keyDirectObject, typeChar, &returnedType, DataString, sizeof(DataString)-1, &actualSize)) != noErr) return err; // check for missing parameters if ((err = MyGotRequiredParams(theAppleEvent)) != noErr) return err; DataString[actualSize] = 0; // Terminate the C string if (actualSize == 0) return noErr; if (TelInfo->numwindows < 1) return noErr; SendStringAsIfTyped(&screens[scrn], DataString, strlen(DataString)); goodexit: err = noErr; badexit: return err; } SIMPLE_UPP(MyHandleSendCR, AEEventHandler); pascal OSErr MyHandleSendCR (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon) { OSErr err; if (TelInfo->numwindows < 1) return noErr; if (screens[scrn].lmode) { process_key('\015', &screens[scrn]); return noErr; } /* if (screens[scrn].crmap) SendStringAsIfTyped(&screens[scrn],"\015\0",2); else SendStringAsIfTyped(&screens[scrn],"\015\012",2); */ SendCRAsIfTyped(&screens[scrn]); goodexit: err = noErr; badexit: return err; } SIMPLE_UPP(MyHandleSuspend, AEEventHandler); pascal OSErr MyHandleSuspend (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon) { OSErr err; if (TelInfo->numwindows < 1) return noErr; screens[scrn].enabled = 0; changeport(scrn, scrn); return noErr; } SIMPLE_UPP(MyHandleUnSuspend, AEEventHandler); pascal OSErr MyHandleUnSuspend (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon) { OSErr err; if (TelInfo->numwindows < 1) return noErr; screens[scrn].enabled = 1; changeport(scrn, scrn); return noErr; } SIMPLE_UPP(MyHandleConnect, AEEventHandler); pascal OSErr MyHandleConnect (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon) { OSErr err; DescType returnedType; Size actualSize; char NameString[255]; char HostString[255]; char TitleString[255]; short mystrpos, doWait, isSuspended; ConnInitParams **theParams; if (handlerRefCon == 1) return noErr; if (handlerRefCon == 2) return paramErr; if ((err = AEGetParamPtr(theAppleEvent, keyDirectObject, typeChar, &returnedType, NameString, sizeof(NameString)-1, &actualSize)) != noErr) return err; NameString[actualSize] = 0; if (actualSize == 0) return paramErr; if (AEGetParamPtr(theAppleEvent, 'host', typeChar, &returnedType, HostString, sizeof(HostString)-1, &actualSize)) HostString[0] = 0; // nope else HostString[actualSize] = 0; // yup if (AEGetParamPtr(theAppleEvent, 'wait', typeChar, &returnedType, TitleString, sizeof(TitleString)-1, &actualSize)) doWait = 0; else doWait = 1; if (AEGetParamPtr(theAppleEvent, 'susp', typeChar, &returnedType, TitleString, sizeof(TitleString)-1, &actualSize)) isSuspended = 0; else isSuspended = 1; if (AEGetParamPtr(theAppleEvent, 'titl', typeChar, &returnedType, TitleString, sizeof(TitleString)-1, &actualSize)) TitleString[0] = 0; // nope else TitleString[actualSize] = 0; // yup // check for missing parameters if ((err = MyGotRequiredParams(theAppleEvent)) != noErr) return err; c2pstr(NameString); c2pstr(HostString); if (HostString[0]) { for (mystrpos = 0; mystrpos < StrLength(HostString); mystrpos++) if (HostString[mystrpos + 1] == ':') HostString[mystrpos + 1] = ' '; theParams = NameToConnInitParams((unsigned char *)HostString, FALSE, (unsigned char *)NameString); } else theParams = NameToConnInitParams((unsigned char *)NameString, TRUE, 0); if (theParams == NULL) return paramErr; if (CreateConnectionFromParams(theParams)) { if (doWait) { err = AESuspendTheCurrentEvent(theAppleEvent); screens[TelInfo->numwindows - 1].cxWeHaveAppleEvent = 1; screens[TelInfo->numwindows - 1].cxAppleEvent = *theAppleEvent; screens[TelInfo->numwindows - 1].cxAEReply = *reply; } if (isSuspended) screens[TelInfo->numwindows - 1].enabled = 0; return noErr; } err = paramErr; goodexit: err = noErr; badexit: return err; } SIMPLE_UPP(MyHandleWait, AEEventHandler); pascal OSErr MyHandleWait (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon) { OSErr err; DescType returnedType; Size actualSize; char DataString[255]; short i, k; if (handlerRefCon == 1) return noErr; if (handlerRefCon == 2) return paramErr; if (TelInfo->numwindows < 1) return noErr; // RAB BetterTelnet 2.0b2 (oops) if ((err = AEGetParamPtr(theAppleEvent, keyDirectObject, typeChar, &returnedType, DataString, sizeof(DataString)-1, &actualSize)) != noErr) return err; DataString[actualSize] = 0; if (actualSize == 0) return paramErr; // check for missing parameters if ((err = MyGotRequiredParams(theAppleEvent)) != noErr) return err; if (err = AESuspendTheCurrentEvent(theAppleEvent)) return err; screens[scrn].waWeHaveAppleEvent = 1; screens[scrn].waAppleEvent = *theAppleEvent; screens[scrn].waAEReply = *reply; screens[scrn].waWasEnabled = screens[scrn].enabled; screens[scrn].enabled = 1; screens[scrn].waWaitPos = 0; screens[scrn].waWaiting = 1; screens[scrn].waWaitLength = strlen(DataString); strcpy(screens[scrn].waWaitString, DataString); // RAB BetterTelnet 2.0b2 // This next code computes the Knuth-Morris-Platt prefix function for the string // search. screens[scrn].waPrefixFunction[0] = 0; k = 0; if (screens[scrn].waWaitLength >= 2) for (i = 1; i < screens[scrn].waWaitLength; i++) { while ((k > 0) && (screens[scrn].waWaitString[k] != screens[scrn].waWaitString[i])) k = screens[scrn].waPrefixFunction[k - 1]; if (screens[scrn].waWaitString[k] == screens[scrn].waWaitString[i]) k++; screens[scrn].waPrefixFunction[i] = k; } changeport(scrn, scrn); return noErr; } SIMPLE_UPP(MyHandleGURL, AEEventHandler); pascal OSErr MyHandleGURL (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon) { OSErr err; DescType returnedType; Size actualSize; char URLString[255]; char *beg, *end, *user, *password, *portstring, *host; if ((err = AEGetParamPtr(theAppleEvent, keyDirectObject, typeChar, &returnedType, URLString, sizeof(URLString)-1, &actualSize)) != noErr) return err; // check for missing parameters if ((err = MyGotRequiredParams(theAppleEvent)) != noErr) return err; URLString[actualSize] = 0; // Terminate the C string beg = &URLString[0]; end = &URLString[actualSize-1]; // Strip leading spaces while ((beg < end) && (*beg == ' ')) beg++; // Strip trailing spaces while ((end < beg) && (*end == ' ')) end--; // Look for (and strip) beginning and ending angle brackets if (*beg == '<') { if (*end != '>') { // Leading angle bracket, but no trailing angle bracket err = paramErr; goto badExit; } // Nuke the brackets beg++; end--; } // Terminate the string we currently have (for strncmp fn's) *(end+1) = 0; // Look for (and strip) leading "URL:" if (!strncmp(beg, "URL:", 4)) { beg += 4; } // Look for (and strip) leading "telnet://" if (strncmp(beg, "telnet://", 9)) // No leading "telnet://" { if (strncmp(beg, "rlogin://", 9)) { err = paramErr; goto badExit; } } beg += 9; // Drop any ending slash if (*end == '/') { *end = 0; end--; } // Process any escaped characters ProcessURLEscapeCodes(beg, &end); // Set up for URL parsing password = nil; portstring = nil; host = nil; // Assume exists user = beg; // Leading : or @ is a no-no if ((*beg == ':') || (*beg == '@')) { err = paramErr; goto badExit; } // Scan for : or @ or end of string while ((beg <= end) && (*beg != ':') && (*beg != '@')) beg++; // If we reached the end, only a host was given if (beg > end) { host = user; user = nil; goto goodUrl; } // If : was found, scan in the password (or port) if (*beg == ':') { *beg++ = 0; password = beg; // Scan for : or @ or end of string while ((beg <= end) && (*beg != ':') && (*beg != '@')) beg++; if (*beg == ':') { // xxxx:yyyy: is a no-no err = paramErr; goto badExit; } if (*beg != '@') { // End of string. Must be host:port host = user; user = nil; portstring = password; password = nil; goto goodUrl; } // Have xxx:yyy@ *beg++ = 0; // Terminate password string } else { // Found @ *beg++ = 0; // Terminate user string } // Ok at this point have xxx:yyy@ or xxxx@ host = beg; // Scan for : or @ or end of string while ((beg <= end) && (*beg != ':') && (*beg != '@') && (*beg != '/')) //CCP fix bad telnets beg++; if (*beg == '@') { //xxx[:yyyy]@xxx@ is a no-no err = paramErr; goto badExit; } if (*beg != ':') { // End of string, we have xxxx[:yyyy]@zzzz *beg = 0; } else { *beg++ = 0; // Terminate host string portstring = beg; } goodUrl: TelInfo->gotDocument = 1; OpenConnectionFromURL(host, portstring, user, password); err = noErr; badExit: return err; } /*---------------------------------------------------------------------------- ProcessURLEscapeCodes Process "%xx" escape codes in a URL string (replace them by the characters they represent). Entry: url = URL with escape codes. Exit: url = URL with escape codes replaced by the characters they represent. Copyright 1994, Northwestern University. Modified 12/94 Jim Browne for NCSA ----------------------------------------------------------------------------*/ static void ProcessURLEscapeCodes (char *url, char **end) { char *p, *q; char c1, c2; p = q = url; while (*p != 0) { if (*p == '%') { c1 = tolower(*(p+1)); c2 = tolower(*(p+2)); if (isxdigit(c1) && isxdigit(c2)) { c1 = isdigit(c1) ? c1 - '0' : c1 - 'a' + 10; c2 = isdigit(c2) ? c2 - '0' : c2 - 'a' + 10; *q++ = (c1 << 4) + c2; p += 3; } else { *q++ = *p++; } } else { *q++ = *p++; } } *q = 0; *end = q-1; } OSErr MyGotRequiredParams (AppleEvent *theAppleEvent) { DescType returnedType; Size actualSize; OSErr err; err = AEGetAttributePtr (theAppleEvent, keyMissedKeywordAttr, typeWildCard, &returnedType, nil, 0, &actualSize); if (err == errAEDescNotFound) // you got all the required parameters return noErr; else if (!err) // you missed a required parameter return errAEEventNotHandled; else // the call to AEGetAttributePtr failed return err; } \ No newline at end of file diff --git a/source/ae/ae.proto.h b/source/ae/ae.proto.h index 943f550..f934a29 100755 --- a/source/ae/ae.proto.h +++ b/source/ae/ae.proto.h @@ -1 +1 @@ -pascal OSErr MyHandleODoc (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon); pascal OSErr MyHandlePDoc (AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefCon); pascal OSErr MyHandleOApp (AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefCon); pascal OSErr MyHandleQuit (AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefCon); pascal OSErr MyHandleGURL (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon); OSErr MyGotRequiredParams (AppleEvent *theAppleEvent); PROTO_UPP(MyHandleODoc, AEEventHandler); PROTO_UPP(MyHandleOApp, AEEventHandler); PROTO_UPP(MyHandlePDoc, AEEventHandler); PROTO_UPP(MyHandleQuit, AEEventHandler); PROTO_UPP(MyHandleGURL, AEEventHandler); void AEunload(void); \ No newline at end of file +pascal OSErr MyHandleODoc (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon); pascal OSErr MyHandlePDoc (AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefCon); pascal OSErr MyHandleOApp (AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefCon); pascal OSErr MyHandleQuit (AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefCon); pascal OSErr MyHandleGURL (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon); pascal OSErr MyHandleSendData (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon); pascal OSErr MyHandleSendCR (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon); pascal OSErr MyHandleConnect (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon); pascal OSErr MyHandleWait (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon); pascal OSErr MyHandleSuspend (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon); pascal OSErr MyHandleUnSuspend (AppleEvent *theAppleEvent, AppleEvent* reply, long handlerRefCon); OSErr MyGotRequiredParams (AppleEvent *theAppleEvent); PROTO_UPP(MyHandleODoc, AEEventHandler); PROTO_UPP(MyHandleOApp, AEEventHandler); PROTO_UPP(MyHandlePDoc, AEEventHandler); PROTO_UPP(MyHandleQuit, AEEventHandler); PROTO_UPP(MyHandleGURL, AEEventHandler); PROTO_UPP(MyHandleSendData, AEEventHandler); PROTO_UPP(MyHandleSendCR, AEEventHandler); PROTO_UPP(MyHandleConnect, AEEventHandler); PROTO_UPP(MyHandleWait, AEEventHandler); PROTO_UPP(MyHandleSuspend, AEEventHandler); PROTO_UPP(MyHandleUnSuspend, AEEventHandler); void AEunload(void); \ No newline at end of file diff --git a/source/config/IC/IConfig.c b/source/config/IC/IConfig.c index d96c370..21e21cf 100755 --- a/source/config/IC/IConfig.c +++ b/source/config/IC/IConfig.c @@ -1 +1 @@ -/* IConfig.c */ // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "IConfig.proto.h" #include "ICTypes.h" #include "ICAPI.h" #include "ICKeys.h" #define kICftpHelper "\pHelperftp" #define kIChttpHelper "\pHelperhttp" #define kICgopherHelper "\pHelpergopher" #define kICwaisHelper "\pHelperwais" #define kICtelnetHelper "\pHelpertelnet" #define kICtn3270Helper "\pHelpertn3270" #define kICfingerHelper "\pHelperfinger" #define kICwhoisHelper "\pHelperwhois" ICInstance inst; Boolean gHaveIC; char * gICHelperKeys[] = { NULL, /* kNotURL*/ (char *)"\pHelpermailto", (char *)"\pHelpernntp", (char *)"\pHelpernntp", (char *)"\pHelperftp", (char *)"\pHelperhttp", (char *)"\pHelpergopher", (char *)"\pHelperwais", NULL, /* we handle telnet URL */ NULL, /* we handle rlogin URL */ (char *)"\pHelpertn3270", (char *)"\pHelperfinger", (char *)"\pHelperwhois" }; void ICUnload(void) { } OSType GetHelperInfo(TURLKind urlKind) { StringPtr key; ICError icErr; ICAttr attr; long size; ICAppSpec icAppSpec; if (!gHaveIC) return NULL; key = (unsigned char *)gICHelperKeys[urlKind]; if (key == NULL) return NULL; size = sizeof(icAppSpec); icErr = ICBegin(inst, icReadOnlyPerm); //we dont touch icErr |= ICGetPref(inst, aligned_pstring(key), &attr, (Ptr)&icAppSpec, &size); icErr |= ICEnd(inst); if (icErr == noErr) return (icAppSpec.fCreator); else return (NULL); } void ICinit(void) { ICError ICerr; ICDirSpecArray folder_spec; ICerr = ICStart(&inst, 'rlfT'); /* tell it our creator */ folder_spec[0].vRefNum = -1; /* search for prefs in system */ folder_spec[0].dirID = 2; ICerr = ICFindConfigFile(inst, 1, (ICDirSpecArrayPtr) &folder_spec); gHaveIC = (ICerr == noErr); } void stopInternetConfig(void) { ICError ICerr; if (gHaveIC) ICerr = ICStop(inst); } // This hack was written by Jim Matthews, of Fetch fame. Thanks! // It works around a bug in CodeWarrior that doesn't word-align Pascal strings. // Apparently, Internet Config is very sensitive to this. /* * aligned_pstring() -- * Passed a possibly-aligned pstring, we return the address of an aligned * one (either the original or a copy). * * Note: we use static data for the copy. */ StringPtr aligned_pstring(StringPtr pstr) { static Str255 aligned; if (((long) pstr) & 0x1) { memcpy(aligned, pstr, pstr[0] + 1); return aligned; } else return pstr; } /* aligned_pstring() */ \ No newline at end of file +/* IConfig.c */ // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "IConfig.proto.h" #include "ICTypes.h" #include "ICAPI.h" #include "ICKeys.h" #define kICftpHelper "\pHelperftp" #define kIChttpHelper "\pHelperhttp" #define kICgopherHelper "\pHelpergopher" #define kICwaisHelper "\pHelperwais" #define kICtelnetHelper "\pHelpertelnet" #define kICtn3270Helper "\pHelpertn3270" #define kICfingerHelper "\pHelperfinger" #define kICwhoisHelper "\pHelperwhois" ICInstance inst; Boolean gHaveIC; char * gICHelperKeys[] = { NULL, /* kNotURL*/ (char *)"\pHelpermailto", (char *)"\pHelpernntp", (char *)"\pHelpernntp", (char *)"\pHelperftp", (char *)"\pHelperhttp", (char *)"\pHelpergopher", (char *)"\pHelperwais", NULL, /* we handle telnet URL */ NULL, /* we handle rlogin URL */ (char *)"\pHelpertn3270", (char *)"\pHelperfinger", (char *)"\pHelperwhois" }; void ICUnload(void) { } OSType GetHelperInfo(TURLKind urlKind) { StringPtr key; ICError icErr; ICAttr attr; long size; ICAppSpec icAppSpec; if (!gHaveIC) return NULL; key = (unsigned char *)gICHelperKeys[urlKind]; if (key == NULL) return NULL; size = sizeof(icAppSpec); icErr = ICBegin(inst, icReadOnlyPerm); //we dont touch icErr |= ICGetPref(inst, aligned_pstring(key), &attr, (Ptr)&icAppSpec, &size); icErr |= ICEnd(inst); if (icErr == noErr) return (icAppSpec.fCreator); else return (NULL); } void ICinit(void) { ICError ICerr; ICDirSpecArray folder_spec; ICerr = ICStart(&inst, 'rlfT'); /* tell it our creator */ folder_spec[0].vRefNum = -1; /* search for prefs in system */ folder_spec[0].dirID = 2; ICerr = ICFindConfigFile(inst, 1, (ICDirSpecArrayPtr) &folder_spec); gHaveIC = (ICerr == noErr); } void stopInternetConfig(void) { ICError ICerr; if (gHaveIC) ICerr = ICStop(inst); } // This hack was written by Jim Matthews, of Fetch fame. Thanks! // It works around a bug in CodeWarrior that doesn't word-align Pascal strings. // Apparently, Internet Config is very sensitive to this. /* * aligned_pstring() -- * Passed a possibly-aligned pstring, we return the address of an aligned * one (either the original or a copy). * * Note: we use static data for the copy. */ StringPtr aligned_pstring(StringPtr pstr) { static Str255 aligned; if (((long) pstr) & 0x1) { memcpy(aligned, pstr, pstr[0] + 1); return aligned; } else return pstr; } /* aligned_pstring() */ \ No newline at end of file diff --git a/source/config/LinkedList.c b/source/config/LinkedList.c index cc53fce..13c88e2 100755 --- a/source/config/LinkedList.c +++ b/source/config/LinkedList.c @@ -1 +1 @@ -// LinkedList.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "LinkedList.proto.h" short reSortElement(LinkedListNode **theHead, LinkedListNode *theChangedElement) { LinkedListNode *leader, *copyOfNew; short index = 1; copyOfNew = (LinkedListNode *) myNewPtrCritical(sizeof(LinkedListNode)); copyOfNew->name = NewString(*theChangedElement->name); copyOfNew->next = NULL; deleteItem(theHead, *theChangedElement->name); insertInSortedList(theHead, copyOfNew); //now its in there; return where it is leader = *theHead; while ((leader->next != NULL)&& (!(EqualString(*leader->name,*copyOfNew->name,TRUE,FALSE)))) { leader = leader->next; index++; } return index - 1; } void deleteList(LinkedListNode **theHead) { LinkedListNode *current,*nextNode; current = *theHead; if (current == NULL) return; nextNode = current->next; while(current != NULL) { DisposeHandle((Handle)current->name); DisposePtr((Ptr)current); current = nextNode; nextNode = nextNode->next; } *theHead = NULL; } void insertInSortedList(LinkedListNode **head, LinkedListNode *newItem) { LinkedListNode *leader, *trailer; Boolean done = FALSE; short newOneIsBigger; if (*head == NULL)//this is first element in list { *head = newItem; return; } trailer = *head; leader = (*head)->next; if (leader == NULL) { (*head)->next = newItem; newItem->next = NULL; return; } while (!done) { newOneIsBigger = RelString(*(newItem->name),*(leader->name),TRUE,FALSE); if (newOneIsBigger == 1) { if (leader->next == NULL)//end of list { leader->next = newItem; newItem->next = NULL; done = TRUE; } else { trailer = leader; leader = leader->next; } } else { trailer->next = newItem; newItem->next = leader; done = TRUE; } } } //returns position short createNodeAndSort(LinkedListNode **head, Str255 theName) { short index=1; LinkedListNode *leader = *head; LinkedListNode *newNode = (LinkedListNode *)myNewPtrCritical(sizeof(LinkedListNode)); newNode->name = NewString(theName); newNode->next = NULL; if (*head == NULL) { *head = newNode; return 1; } else { insertInSortedList(head, newNode); while ((leader->next != NULL)&& (!(EqualString(*leader->name,theName,TRUE,FALSE)))) { leader = leader->next; index++; } return (index - 1); } } LinkedListNode *createSortedList(ResType ConfigResourceType,short numberofitems,Str255 placeThisFirst) { short index, resID; Handle ItemResource; Str255 ItemName; ResType restype; LinkedListNode *newNode, *theHead = NULL; if (placeThisFirst != NULL) { theHead = (LinkedListNode *) myNewPtrCritical(sizeof(LinkedListNode)); ItemResource = Get1NamedResource(ConfigResourceType,placeThisFirst); theHead->name = NewString(placeThisFirst); //set the head of our list theHead->next = NULL; if (ItemResource != NULL) ReleaseResource(ItemResource); } for (index = 1; index <= numberofitems; index++) { ItemResource = Get1IndResource(ConfigResourceType, index); GetResInfo(ItemResource, &resID, &restype, (StringPtr)&ItemName); if (!(EqualString(placeThisFirst,ItemName,1,0))) { newNode = (LinkedListNode *) myNewPtrCritical(sizeof(LinkedListNode)); newNode->name = NewString(ItemName); insertInSortedList(&theHead, newNode); ReleaseResource(ItemResource); } } return (theHead); } LinkedListNode *createSortedList2(ResType ConfigResourceType,short numberofitems,Str255 placeThisFirst) { short index, resID; Handle ItemResource; Str255 ItemName; ResType restype; LinkedListNode *newNode, *theHead = NULL; if (placeThisFirst != NULL) { theHead = (LinkedListNode *) myNewPtrCritical(sizeof(LinkedListNode)); ItemResource = GetNamedResource(ConfigResourceType,placeThisFirst); theHead->name = NewString(placeThisFirst); //set the head of our list theHead->next = NULL; if (ItemResource != NULL) ReleaseResource(ItemResource); } for (index = 1; index <= numberofitems; index++) { ItemResource = GetIndResource(ConfigResourceType, index); GetResInfo(ItemResource, &resID, &restype, (StringPtr)&ItemName); if (!(EqualString(placeThisFirst,ItemName,1,0))) { newNode = (LinkedListNode *) myNewPtrCritical(sizeof(LinkedListNode)); newNode->name = NewString(ItemName); insertInSortedList(&theHead, newNode); ReleaseResource(ItemResource); } } return (theHead); } void deleteItem(LinkedListNode **theHead,Str255 ItemName) { LinkedListNode *leader = *theHead, *trailer = *theHead; while(!(EqualString(ItemName,*leader->name,TRUE,FALSE))&&(leader->next != NULL)) { trailer = leader; leader = leader->next; } if (leader == *theHead) { *theHead = (*theHead)->next; DisposeHandle((Handle)leader->name); DisposePtr((Ptr)leader); } else { trailer->next = leader->next; DisposeHandle((Handle)leader->name); DisposePtr((Ptr)leader); } } LinkedListNode *findNode(LinkedListNode *theHead,Str255 ItemName) { LinkedListNode *leader = theHead; while ((leader->next != NULL)&&(!(EqualString(ItemName,*leader->name,TRUE,FALSE)))) leader = leader->next; if (!(EqualString(ItemName,*leader->name,TRUE,FALSE))) return NULL; else return(leader); } LinkedListNode *findNodeNC(LinkedListNode *theHead,Str255 ItemName) { LinkedListNode *leader = theHead; while ((leader->next != NULL)&&(!(EqualString(ItemName,*leader->name,FALSE,FALSE)))) leader = leader->next; if (!(EqualString(ItemName,*leader->name,FALSE,FALSE))) return NULL; else return(leader); } short findClosestNodeIndex(LinkedListNode *theHead,Str255 ItemName) { short index=1; LinkedListNode *leader = theHead, *trailer = theHead; while ((leader->next != NULL) && (RelString(*leader->name,ItemName,TRUE,FALSE) == -1)) { trailer = leader; leader = leader->next; index++; } return index-1; } short findNodeIndex(LinkedListNode *theHead,Str255 ItemName) { short index = 1; LinkedListNode *leader = theHead; while ((leader->next != NULL)&& (!(EqualString(*leader->name,ItemName,TRUE,FALSE)))) { leader = leader->next; index++; } return (index - 1); } void addListToMenu(MenuHandle theMenu, LinkedListNode *theHead, short itemIndex) { LinkedListNode *traverser = theHead; // short itemIndex = 1; while(traverser != NULL) { HLock((Handle)traverser->name); AppendMenu(theMenu,"\poops"); //these two avoid diacritcal interpertation of '<' SetItem(theMenu,itemIndex,*traverser->name); HUnlock((Handle)traverser->name); traverser = traverser->next; itemIndex++; } } void getAUniqueName(LinkedListNode *theHead, Str255 theName) { while(findNodeNC(theHead,theName)) { if ((theName[theName[0]] > '9')|| (theName[theName[0]] < '0')) //add a number { theName[++theName[0]] = ' '; theName[++theName[0]] = '1'; } else if (theName[theName[0]] == '9') //add another digit { theName[theName[0]] = '-'; theName[++theName[0]] = '1'; } else theName[theName[0]]++; //incremement the number } } \ No newline at end of file +// LinkedList.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "LinkedList.proto.h" short reSortElement(LinkedListNode **theHead, LinkedListNode *theChangedElement) { LinkedListNode *leader, *copyOfNew; short index = 1; copyOfNew = (LinkedListNode *) myNewPtrCritical(sizeof(LinkedListNode)); copyOfNew->name = NewString(*theChangedElement->name); copyOfNew->next = NULL; deleteItem(theHead, *theChangedElement->name); insertInSortedList(theHead, copyOfNew); //now its in there; return where it is leader = *theHead; while ((leader->next != NULL)&& (!(EqualString(*leader->name,*copyOfNew->name,TRUE,FALSE)))) { leader = leader->next; index++; } return index - 1; } void deleteList(LinkedListNode **theHead) { LinkedListNode *current,*nextNode; current = *theHead; if (current == NULL) return; nextNode = current->next; while(current != NULL) { DisposeHandle((Handle)current->name); DisposePtr((Ptr)current); current = nextNode; // RJZ, 12/10/97. Avoid dereferencing // a NULL pointer. if (current != NULL) nextNode = nextNode->next; } *theHead = NULL; } void insertInSortedList(LinkedListNode **head, LinkedListNode *newItem) { LinkedListNode *leader, *trailer; Boolean done = FALSE; short newOneIsBigger; if (*head == NULL)//this is first element in list { *head = newItem; return; } trailer = *head; leader = (*head)->next; if (leader == NULL) { (*head)->next = newItem; newItem->next = NULL; return; } while (!done) { newOneIsBigger = RelString(*(newItem->name),*(leader->name),TRUE,FALSE); if (newOneIsBigger == 1) { if (leader->next == NULL)//end of list { leader->next = newItem; newItem->next = NULL; done = TRUE; } else { trailer = leader; leader = leader->next; } } else { trailer->next = newItem; newItem->next = leader; done = TRUE; } } } //returns position short createNodeAndSort(LinkedListNode **head, Str255 theName) { short index=1; LinkedListNode *leader = *head; LinkedListNode *newNode = (LinkedListNode *)myNewPtrCritical(sizeof(LinkedListNode)); newNode->name = NewString(theName); newNode->next = NULL; if (*head == NULL) { *head = newNode; return 1; } else { insertInSortedList(head, newNode); while ((leader->next != NULL)&& (!(EqualString(*leader->name,theName,TRUE,FALSE)))) { leader = leader->next; index++; } return (index - 1); } } LinkedListNode *createSortedList(ResType ConfigResourceType,short numberofitems,Str255 placeThisFirst) { short index, resID; Handle ItemResource; Str255 ItemName; ResType restype; LinkedListNode *newNode, *theHead = NULL; if (placeThisFirst != NULL) { theHead = (LinkedListNode *) myNewPtrCritical(sizeof(LinkedListNode)); ItemResource = Get1NamedResource(ConfigResourceType,placeThisFirst); theHead->name = NewString(placeThisFirst); //set the head of our list theHead->next = NULL; if (ItemResource != NULL) ReleaseResource(ItemResource); } for (index = 1; index <= numberofitems; index++) { ItemResource = Get1IndResource(ConfigResourceType, index); GetResInfo(ItemResource, &resID, &restype, (StringPtr)&ItemName); if (!(EqualString(placeThisFirst,ItemName,1,0))) { newNode = (LinkedListNode *) myNewPtrCritical(sizeof(LinkedListNode)); newNode->name = NewString(ItemName); insertInSortedList(&theHead, newNode); ReleaseResource(ItemResource); } } return (theHead); } LinkedListNode *createSortedList2(ResType ConfigResourceType,short numberofitems,Str255 placeThisFirst) { short index, resID; Handle ItemResource; Str255 ItemName; ResType restype; LinkedListNode *newNode, *theHead = NULL; if (placeThisFirst != NULL) { theHead = (LinkedListNode *) myNewPtrCritical(sizeof(LinkedListNode)); ItemResource = GetNamedResource(ConfigResourceType,placeThisFirst); theHead->name = NewString(placeThisFirst); //set the head of our list theHead->next = NULL; if (ItemResource != NULL) ReleaseResource(ItemResource); } for (index = 1; index <= numberofitems; index++) { ItemResource = GetIndResource(ConfigResourceType, index); GetResInfo(ItemResource, &resID, &restype, (StringPtr)&ItemName); if (!(EqualString(placeThisFirst,ItemName,1,0))) { newNode = (LinkedListNode *) myNewPtrCritical(sizeof(LinkedListNode)); newNode->name = NewString(ItemName); insertInSortedList(&theHead, newNode); ReleaseResource(ItemResource); } } return (theHead); } void deleteItem(LinkedListNode **theHead,Str255 ItemName) { LinkedListNode *leader = *theHead, *trailer = *theHead; while(!(EqualString(ItemName,*leader->name,TRUE,FALSE))&&(leader->next != NULL)) { trailer = leader; leader = leader->next; } if (leader == *theHead) { *theHead = (*theHead)->next; DisposeHandle((Handle)leader->name); DisposePtr((Ptr)leader); } else { trailer->next = leader->next; DisposeHandle((Handle)leader->name); DisposePtr((Ptr)leader); } } LinkedListNode *findNode(LinkedListNode *theHead,Str255 ItemName) { LinkedListNode *leader = theHead; while ((leader->next != NULL)&&(!(EqualString(ItemName,*leader->name,TRUE,FALSE)))) leader = leader->next; if (!(EqualString(ItemName,*leader->name,TRUE,FALSE))) return NULL; else return(leader); } LinkedListNode *findNodeNC(LinkedListNode *theHead,Str255 ItemName) { LinkedListNode *leader = theHead; while ((leader->next != NULL)&&(!(EqualString(ItemName,*leader->name,FALSE,FALSE)))) leader = leader->next; if (!(EqualString(ItemName,*leader->name,FALSE,FALSE))) return NULL; else return(leader); } short findClosestNodeIndex(LinkedListNode *theHead,Str255 ItemName) { short index=1; LinkedListNode *leader = theHead, *trailer = theHead; while ((leader->next != NULL) && (RelString(*leader->name,ItemName,TRUE,FALSE) == -1)) { trailer = leader; leader = leader->next; index++; } return index-1; } short findNodeIndex(LinkedListNode *theHead,Str255 ItemName) { short index = 1; LinkedListNode *leader = theHead; while ((leader->next != NULL)&& (!(EqualString(*leader->name,ItemName,TRUE,FALSE)))) { leader = leader->next; index++; } return (index - 1); } void addListToMenu(MenuHandle theMenu, LinkedListNode *theHead, short itemIndex) { LinkedListNode *traverser = theHead; // short itemIndex = 1; while(traverser != NULL) { HLock((Handle)traverser->name); AppendMenu(theMenu,"\poops"); //these two avoid diacritcal interpertation of '<' SetMenuItemText(theMenu,itemIndex,*traverser->name); HUnlock((Handle)traverser->name); traverser = traverser->next; itemIndex++; } } void getAUniqueName(LinkedListNode *theHead, Str255 theName) { while(findNodeNC(theHead,theName)) { if ((theName[theName[0]] > '9')|| (theName[theName[0]] < '0')) //add a number { theName[++theName[0]] = ' '; theName[++theName[0]] = '1'; } else if (theName[theName[0]] == '9') //add another digit { theName[theName[0]] = '-'; theName[++theName[0]] = '1'; } else theName[theName[0]]++; //incremement the number } } \ No newline at end of file diff --git a/source/config/configure.c b/source/config/configure.c index 6b0a67e..d7a689f 100755 --- a/source/config/configure.c +++ b/source/config/configure.c @@ -1 +1 @@ -/* Configure.c * New Configuration scheme (the death of config.tel) * * Revisions: * 8/92 Telnet 2.6: Initial version. Jim Browne */ // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #ifdef MPW #pragma segment Configure #endif #include "DlogUtils.proto.h" #include "popup.h" #include "popup.proto.h" #include "configure.proto.h" #include "netevent.proto.h" /* For Stask proto */ #include "prefs.proto.h" #include "bkgr.proto.h" // For StartUpFTP proto #include "menuseg.proto.h" #include "macutil.proto.h" #include "rsinterf.proto.h" #include "LinkedList.proto.h" #include "Sets.proto.h" #include "movableModal.h" static Boolean isACopy(Str255 theName);//looks for an occurance of "copy" in a string static pascal short TerminalModalProc( DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(TerminalModalProc, ModalFilter); static pascal short SessionModalProc(DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(SessionModalProc, ModalFilter); static pascal short MyDlogWListFilter( DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(MyDlogWListFilter, ModalFilter); static pascal void listDitemproc(DialogPtr theDlg, short itemNo); PROTO_UPP(listDitemproc, UserItem); extern FTPServerPrefs* gFTPServerPrefs; extern ApplicationPrefs* gApplicationPrefs; extern MenuHandle myMenus[]; static void ZeroNumOnly(void); static Boolean InNumOnly(short item); static char configPassword[256]; static LinkedListNode *currentHead; static ListHandle currentList; #define NUMONLYSIZE 8 short NumOnly[NUMONLYSIZE]; /* Items for which non-number keys are ignored */ // NumOnly[0] is number of "safe" item to return void CONFIGUREunload(void) {} void Cenviron( void) { DialogPtr dptr; short ditem, defaultBoldColor; Str255 scratchPstring; long scratchlong; OSType newtype; PaletteHandle toSave; Boolean tempBoolean; SetUpMovableModalMenus(); dptr = GetNewMySmallStrangeDialog( PrefDLOG, NULL, kInFront, (void *)ThirdCenterDialog); SetDialogDefaultItem(dptr, 1); SetDialogCancelItem(dptr, 2); SetDialogTracksCursor(dptr, 1); SetCntrl(dptr, PrefDClose, gApplicationPrefs->WindowsDontGoAway); SetCntrl(dptr, PrefStag, gApplicationPrefs->StaggerWindows); defaultBoldColor = gApplicationPrefs->defaultBoldColor; if (!gApplicationPrefs->StaggerWindows) { HideDItem(dptr,PrefStaggerOffset); HideDItem(dptr,PrefStaggerBY); tempBoolean = FALSE; } else { scratchlong = gApplicationPrefs->StaggerWindowsOffset; NumToString(scratchlong, scratchPstring); SetTEText(dptr, PrefStaggerOffset, scratchPstring); tempBoolean = TRUE; } if (!TelInfo->haveColorQuickDraw) HideDItem(dptr,PrefAnsiColor); SetCntrl(dptr, PrefCMDkey, gApplicationPrefs->CommandKeys); SetCntrl(dptr, PrefTMap, gApplicationPrefs->RemapTilde); SetCntrl(dptr, PrefBlink, gApplicationPrefs->BlinkCursor); SetCntrl(dptr, PrefKeyFuncMenus, gApplicationPrefs->KeyPadAndFuncMenus); SetCntrl(dptr, PrefNotifyUser, gApplicationPrefs->NotifyUser); SetCntrl(dptr, PrefBlockCursor, (gApplicationPrefs->CursorType == 0)); SetCntrl(dptr, PrefUnderscoreCursor, (gApplicationPrefs->CursorType == 1)); SetCntrl(dptr, PrefVerticalCursor, (gApplicationPrefs->CursorType == 2)); SetCntrl(dptr, PrefDestroyTickets, gApplicationPrefs->destroyKTickets); SetCntrl(dptr, 30, gApplicationPrefs->autoOpenDialog); SetCntrl(dptr, 31, gApplicationPrefs->dontWarnOnQuit); SetCntrl(dptr, 32, gApplicationPrefs->autoOpenDefault); SetCntrl(dptr, 33, gApplicationPrefs->parseAliases); SetCntrl(dptr, 34, gApplicationPrefs->monospacedOut); SetCntrl(dptr, 36, gApplicationPrefs->clipTrailingSpaces); SetCntrl(dptr, 37, gApplicationPrefs->globalSavePass); scratchPstring[0] = 4; BlockMove(&(gApplicationPrefs->CaptureFileCreator), &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, PrefCaptTE, scratchPstring); newtype = gApplicationPrefs->CaptureFileCreator; scratchlong = gApplicationPrefs->CopyTableThresh; NumToString(scratchlong, scratchPstring); SetTEText(dptr, PrefCTt, scratchPstring); SelIText(dptr, PrefCTt, 0, 32767); NumToString(gApplicationPrefs->TimeSlice, scratchPstring); SetTEText(dptr, PrefTimeSlice, scratchPstring); scratchlong = (long) gApplicationPrefs->OpenTimeout; NumToString(scratchlong,scratchPstring); SetTEText(dptr,PrefOpenTime, scratchPstring); scratchlong = (long) gApplicationPrefs->SendTimeout; NumToString(scratchlong,scratchPstring); SetTEText(dptr,PrefSendTime, scratchPstring); ShowWindow(dptr); ditem=0; /* initially no hits */ while((ditem>2) || (ditem==0)) { movableModalDialog(0,&ditem); switch(ditem) { case PrefDClose: case PrefCMDkey: case PrefTMap: case PrefBlink: case PrefNotifyUser: case PrefKeyFuncMenus: case PrefDestroyTickets: case 30: case 31: case 32: case 33: case 34: case 36: case 37: FlipCheckBox( dptr, ditem); break; case PrefStag: FlipCheckBox( dptr, ditem); tempBoolean = !tempBoolean; if (!tempBoolean) { HideDItem(dptr,PrefStaggerOffset); HideDItem(dptr,PrefStaggerBY); } else { ShowDItem(dptr, PrefStaggerBY); ShowDItem(dptr, PrefStaggerOffset); scratchlong = gApplicationPrefs->StaggerWindowsOffset; NumToString(scratchlong, scratchPstring); SetTEText(dptr, PrefStaggerOffset, scratchPstring); } break; case PrefBlockCursor: SetCntrl(dptr, PrefBlockCursor, 1); SetCntrl(dptr, PrefUnderscoreCursor, 0); SetCntrl(dptr, PrefVerticalCursor, 0); break; case PrefUnderscoreCursor: SetCntrl(dptr, PrefBlockCursor, 0); SetCntrl(dptr, PrefUnderscoreCursor, 1); SetCntrl(dptr, PrefVerticalCursor, 0); break; case PrefVerticalCursor: SetCntrl(dptr, PrefBlockCursor, 0); SetCntrl(dptr, PrefUnderscoreCursor, 0); SetCntrl(dptr, PrefVerticalCursor, 1); break; case PrefCaptCreat: GetApplicationType(&newtype); scratchPstring[0] = 4; BlockMove(&newtype, &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, PrefCaptTE, scratchPstring); break; case PrefAnsiColor: AnsiPrompt(1, &defaultBoldColor); break; default: break; } /* switch */ } if (ditem==DLOGCancel) { DisposDialog( dptr); ResetMenus(); return; } gApplicationPrefs->defaultBoldColor = defaultBoldColor; GetTEText(dptr, PrefCTt, scratchPstring); StringToNum(scratchPstring, &scratchlong); gApplicationPrefs->CopyTableThresh = (short) scratchlong; GetTEText(dptr, PrefTimeSlice, scratchPstring); StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 100, 2); gApplicationPrefs->TimeSlice = scratchlong; GetTEText(dptr,PrefOpenTime, scratchPstring); StringToNum(scratchPstring, &scratchlong); gApplicationPrefs->OpenTimeout = (short) scratchlong; GetTEText(dptr,PrefSendTime, scratchPstring); StringToNum(scratchPstring, &scratchlong); gApplicationPrefs->SendTimeout = (short) scratchlong; GetTEText(dptr, PrefCaptTE, scratchPstring); BlockMove(&scratchPstring[1], &(gApplicationPrefs->CaptureFileCreator), sizeof(OSType)); GetTEText(dptr,PrefStaggerOffset, scratchPstring); StringToNum(scratchPstring, &scratchlong); gApplicationPrefs->StaggerWindowsOffset = (short) scratchlong; gApplicationPrefs->CommandKeys = GetCntlVal(dptr, PrefCMDkey); gApplicationPrefs->WindowsDontGoAway = GetCntlVal(dptr, PrefDClose); gApplicationPrefs->RemapTilde = GetCntlVal(dptr, PrefTMap); gApplicationPrefs->StaggerWindows = GetCntlVal(dptr, PrefStag); gApplicationPrefs->BlinkCursor = GetCntlVal(dptr, PrefBlink); gApplicationPrefs->KeyPadAndFuncMenus = GetCntlVal(dptr, PrefKeyFuncMenus); gApplicationPrefs->NotifyUser = GetCntlVal(dptr,PrefNotifyUser); gApplicationPrefs->destroyKTickets = GetCntlVal(dptr,PrefDestroyTickets); gApplicationPrefs->autoOpenDialog = GetCntlVal(dptr,30); gApplicationPrefs->dontWarnOnQuit = GetCntlVal(dptr,31); gApplicationPrefs->autoOpenDefault = GetCntlVal(dptr,32); gApplicationPrefs->parseAliases = GetCntlVal(dptr,33); gApplicationPrefs->monospacedOut = GetCntlVal(dptr,34); gApplicationPrefs->clipTrailingSpaces = GetCntlVal(dptr,36); gApplicationPrefs->globalSavePass = GetCntlVal(dptr,37); gApplicationPrefs->CursorType = (GetCntlVal(dptr, PrefUnderscoreCursor) == 1) + (2 * (GetCntlVal(dptr, PrefVerticalCursor) == 1)); if (TelInfo->haveColorQuickDraw) { RSUpdatePalette(); //reflects any ANSI change UseResFile(TelInfo->SettingsFile); toSave = (PaletteHandle) Get1Resource('pltt', 10001); if (toSave == NULL)//this shouldnt happen; make a new copy { UseResFile(TelInfo->ApplicationFile); toSave = (PaletteHandle)GetNewPalette(9999); UseResFile(TelInfo->SettingsFile); AddResource((Handle)toSave, 'pltt', 10001, "\pANSI Colors");//make the new resource UpdateResFile(TelInfo->SettingsFile); } CopyPalette(TelInfo->AnsiColors,toSave,0,0,16); ChangedResource((Handle)toSave); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)toSave); } switchMenus(gApplicationPrefs->CommandKeys, 1); AdjustMenus(); DoTheMenuChecks(); SaveAppPreferences(); DisposDialog( dptr); ResetMenus(); } void Cftp(void) { DialogPtr dptr; short ditem; Str255 scratchPstring; OSType scratchOSType; SFReply sfr; FInfo fi; Point where = {100,100}; dptr = GetNewMySmallStrangeDialog( FTPDLOG, NULL, kInFront, (void *)ThirdCenterDialog); SetCntrl(dptr, FTPServerOff, (gFTPServerPrefs->ServerState == 0)); SetCntrl(dptr, FTPServerUnsecure, (gFTPServerPrefs->ServerState == 1)); SetCntrl(dptr, FTPServerPswdPlease, (gFTPServerPrefs->ServerState == 2)); SetCntrl(dptr, FTPShowFTPlog, gFTPServerPrefs->ShowFTPlog); SetCntrl(dptr, FTPrevDNS, gFTPServerPrefs->DNSlookupconnections); SetCntrl(dptr, FTPUseMacBinaryII, gFTPServerPrefs->UseMacBinaryII); SetCntrl(dptr, FTPResetMacBinary, gFTPServerPrefs->ResetMacBinary); SetCntrl(dptr, FTPISO, gFTPServerPrefs->DoISOtranslation); HideDItem(dptr, FTPrevDNS); // Sometime later, perhaps. scratchPstring[0] = 4; BlockMove(&(gFTPServerPrefs->BinaryCreator), &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, FTPbincreatTE, scratchPstring); BlockMove(&(gFTPServerPrefs->BinaryType), &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, FTPbintypeTE, scratchPstring); SelIText(dptr, FTPbintypeTE, 0, 32767); BlockMove(&(gFTPServerPrefs->TextCreator), &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, FTPtextcreatTE, scratchPstring); ShowWindow(dptr); ditem=0; /* initially no hits */ while((ditem>2) || (ditem==0)) { ModalDialog(DLOGwOK_CancelUPP,&ditem); switch(ditem) { case FTPShowFTPlog: case FTPrevDNS: case FTPUseMacBinaryII: case FTPResetMacBinary: case FTPISO: FlipCheckBox( dptr, ditem); break; case FTPServerOff: SetCntrl(dptr, FTPServerOff, 1); SetCntrl(dptr, FTPServerUnsecure, 0); SetCntrl(dptr, FTPServerPswdPlease, 0); break; case FTPServerUnsecure: SetCntrl(dptr, FTPServerOff, 0); SetCntrl(dptr, FTPServerUnsecure, 1); SetCntrl(dptr, FTPServerPswdPlease, 0); break; case FTPServerPswdPlease: SetCntrl(dptr, FTPServerOff, 0); SetCntrl(dptr, FTPServerUnsecure, 0); SetCntrl(dptr, FTPServerPswdPlease, 1); break; case FTPtextcreatorbutton: if (GetApplicationType(&scratchOSType)) { BlockMove(&scratchOSType, &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, FTPtextcreatTE, scratchPstring); } break; case FTPbinexamplebutton: SFGetFile(where, NULL, NULL, -1, NULL, NULL, &sfr); if (sfr.good) { GetFInfo(sfr.fName, sfr.vRefNum, &fi); scratchPstring[0] = sizeof(OSType); BlockMove(&fi.fdCreator, &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, FTPbincreatTE, scratchPstring); BlockMove(&fi.fdType, &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, FTPbintypeTE, scratchPstring); } break; default: break; } /* switch */ } /* while */ if (ditem==DLOGCancel) { DisposDialog( dptr); return; } gFTPServerPrefs->ServerState = GetCntlVal(dptr, FTPServerUnsecure) + GetCntlVal(dptr, FTPServerPswdPlease) * 2; StartUpFTP(); // Make sure FTP server recognizes new mode. gFTPServerPrefs->ShowFTPlog = GetCntlVal(dptr, FTPShowFTPlog); gFTPServerPrefs->DNSlookupconnections = GetCntlVal(dptr, FTPrevDNS); gFTPServerPrefs->UseMacBinaryII = GetCntlVal(dptr, FTPUseMacBinaryII); gFTPServerPrefs->ResetMacBinary = GetCntlVal(dptr, FTPResetMacBinary); gFTPServerPrefs->DoISOtranslation = GetCntlVal(dptr, FTPISO); GetTEText(dptr, FTPbincreatTE, scratchPstring); BlockMove(&scratchPstring[1], &(gFTPServerPrefs->BinaryCreator), sizeof(OSType)); GetTEText(dptr, FTPbintypeTE, scratchPstring); BlockMove(&scratchPstring[1], &(gFTPServerPrefs->BinaryType), sizeof(OSType)); GetTEText(dptr, FTPtextcreatTE, scratchPstring); BlockMove(&scratchPstring[1], &(gFTPServerPrefs->TextCreator), sizeof(OSType)); SaveFTPPreferences(); DisposDialog( dptr); ResetMenus(); } Boolean GetApplicationType(OSType *type) { SFTypeList types; SFReply sfr; FInfo fi; Point where; SetPt(&where, 100, 100); types[0] = 'APPL'; SFGetFile(where, NULL, NULL, 1, types, NULL, &sfr); if (sfr.good) { GetFInfo(sfr.fName, sfr.vRefNum, &fi); BlockMove(&fi.fdCreator, type, sizeof(OSType)); // Copy the application creator type } return(sfr.good); } // Our standard modal dialog filter with code for handling user items containing lists. SIMPLE_UPP(MyDlogWListFilter, ModalFilter); pascal short MyDlogWListFilter( DialogPtr dptr, EventRecord *evt, short *item) { short key, iType; Handle iHndl; Rect iRect; Point scratchPoint; Cell tempCell; static unsigned long lastTime = 0; static char shortcut[] = {0,0,0,0,0,0,0,0,0,0,0}; SetPort(dptr); if ((evt->what == keyDown)||(evt->what == autoKey)) { key = evt->message & charCodeMask; //keyCode = (evt->message >>8) & 0xff ; if ((key == 0x0d) || (key == 0x03)) { // 0x0d == return, 0x03 == enter // RAB BetterTelnet 1.2 - we let StdFilterProc handle this // *item = 1; // ok // FlashButton(dptr, 1); // return(-1); return CallStdFilterProc(dptr, evt, item); } else if (evt->modifiers & cmdKey) { switch(evt->message & charCodeMask) { case 'e': *item = kChange; break; case 'r': *item = kRemove; break; case 'n': *item = kNew; break; case 'd': *item = kDuplicate; break; default: return(FALSE); break; } FlashButton(dptr, *item); return (-1); } else // a normal key { char keyCode = (evt->message & keyCodeMask) >> 8; if (keyCode >=0x7B) //CCP: arrow keys { tempCell.h = tempCell.v = 0; switch(keyCode) { case 0x7E: //up case 0x7B: //left if (LGetSelect(TRUE,&tempCell,currentList)) { LSetSelect(FALSE,tempCell,currentList);//unselect it tempCell.v--; } else tempCell.v = 0; break; case 0x7D: //down case 0x7C: //right if (LGetSelect(TRUE,&tempCell,currentList)) { LSetSelect(FALSE,tempCell,currentList);//unselect it tempCell.v++; } else tempCell.v = (**currentList).dataBounds.bottom - 1; break; default: return (FALSE); break; } if (tempCell.v > (**currentList).dataBounds.bottom - 1) tempCell.v = (**currentList).dataBounds.bottom - 1; if (tempCell.v < 0) tempCell.v = 0; LSetSelect(TRUE,tempCell,currentList);//select it LAutoScroll(currentList); Hilite(dptr, kRemove, 0); Hilite(dptr, kChange, 0); return(FALSE); } else //CCP go to right list item based on keystroke { if ((TickCount() - lastTime) > GetCaretTime() ) shortcut[0] = 0; lastTime = TickCount(); shortcut[(shortcut[0]++) +1] = key; tempCell.h = tempCell.v = 0; if (LGetSelect(TRUE,&tempCell,currentList)) LSetSelect(FALSE,tempCell,currentList); tempCell.v = findClosestNodeIndex(currentHead,(StringPtr)shortcut); LSetSelect(TRUE,tempCell,currentList); LAutoScroll(currentList); if (shortcut[0] == 10) shortcut[0] = 0; Hilite(dptr, kRemove, 0); Hilite(dptr, kChange, 0); } } } else if (evt->what == updateEvt) { if ((WindowPtr)evt->message == dptr) { // RAB BetterTelnet 1.2 - we let StdFilterProc handle this // GetDItem(dptr,1,&iType,&iHndl,&iRect); // ok // PenSize(3,3); // InsetRect(&iRect,-4,-4); // FrameRoundRect(&iRect,16,16); CallStdFilterProc(dptr, evt, item); return 0; } } else if (evt->what == mouseDown) { GetDItem(dptr, kItemList, &iType, &iHndl, &iRect); scratchPoint = evt->where; GlobalToLocal(&scratchPoint); if (PtInRect(scratchPoint, &iRect)) { *item = kItemList; if (LClick(scratchPoint, evt->modifiers, (ListHandle)GetWRefCon(dptr))) { *item = kChange; FlashButton(dptr, kChange); } return(-1); } } return CallStdFilterProc(dptr, evt, item); } Boolean isACopy(Str255 theName) { Boolean yes=FALSE; char copyString[] = "copy"; p2cstr(theName); if (strstr((char *)theName,copyString)) yes = TRUE; c2pstr((char *)theName); return(yes); } // User Dialog Item Procedure for a list. Assumes the Dialog's refcon contains the list // handle. SIMPLE_UPP(listDitemproc, UserItem); pascal void listDitemproc(DialogPtr theDlg, short itemNo) { short itemType; Handle ControlHndl; Rect scratchRect; GetDItem(theDlg, itemNo, &itemType, &ControlHndl, &scratchRect); PenNormal(); InsetRect(&scratchRect, -1, -1); FrameRect(&scratchRect); LUpdate(theDlg->visRgn, (ListHandle)GetWRefCon(theDlg)); } void BoundsCheck(long *value, long high, long low) { if (*value > high) *value = high; if (*value < low) *value = low; } #define kSCListMods lNoNilHilite+lOnlyOne void EditConfigType(ResType ConfigResourceType, Boolean (*EditFunction)(StringPtr)) { DialogPtr dptr; Handle iHndl; short iType, length, ditem,numberofitems, index; Rect ListBox, ListBounds; Point cellSize, theCell; ListHandle thelist; Handle ItemResource; Str255 ItemName; LinkedListNode *theHead, *leader; SetUpMovableModalMenus(); dptr = GetNewMySmallDialog(kItemDLOG, NULL, kInFront, (void *)ThirdCenterDialog); SetDialogDefaultItem(dptr, 1); SetDialogTracksCursor(dptr, 1); ditem = 3; GetDItem(dptr, kItemList, &iType, &iHndl, &ListBox); SetDItem(dptr, kItemList, iType, (Handle)listDitemprocUPP, &ListBox); ListBox.right -= 15; // Make room for scrollbar SetRect(&ListBounds, 0,0,1,0); SetPt(&cellSize,(ListBox.right-ListBox.left),16); thelist = LNew(&ListBox, &ListBounds, cellSize, 0, (WindowPtr)dptr,0,0,0,1); (*(thelist))->listFlags = kSCListMods; currentList = thelist; SetWRefCon(dptr, (long)thelist); // So the Ditem proc can find the list UseResFile(TelInfo->SettingsFile); numberofitems = Count1Resources(ConfigResourceType); if (numberofitems) theHead = createSortedList(ConfigResourceType,numberofitems,"\p"); //now we have a sorted linked list of the names else theHead = NULL; leader = theHead; for(index = 1, theCell.v = 0, theCell.h = 0; index <= numberofitems;index++, theCell.v++) { LAddRow(1,-1, thelist); HLock((Handle)leader->name); LSetCell(*(leader->name) +1, (*leader->name)[0], theCell, thelist); HUnlock((Handle)leader->name); leader = leader->next; } theCell.v = 0; theCell.h = 0; if (numberofitems) LSetSelect(1, theCell, thelist); LDoDraw(1, thelist); currentHead = theHead; //let dialog filter know about the list while (ditem > 1) { movableModalDialog(MyDlogWListFilterUPP, &ditem); switch(ditem) { case kRemove: SetPt(&theCell, 0, 0); if (LGetSelect(TRUE, &theCell, thelist)) { length = 254; LGetCell(ItemName+1, &length, theCell, thelist); ItemName[0] = (char)length; if (!(EqualString(ItemName, "\p", TRUE, FALSE))) { deleteItem(&theHead,ItemName);//delete it from the linked list LDelRow(1,theCell.v,thelist); theCell.v--; LSetSelect(TRUE,theCell,thelist); UseResFile(TelInfo->SettingsFile); ItemResource = Get1NamedResource(ConfigResourceType, ItemName); RmveResource(ItemResource); ReleaseResource(ItemResource); UpdateResFile(TelInfo->SettingsFile); } } break; case kChange: SetPt(&theCell, 0, 0); if (LGetSelect(TRUE, &theCell, thelist)) { short newPosition; length = 254; LGetCell(ItemName+1, &length, theCell, thelist); ItemName[0] = (char)length; leader = findNode(theHead,ItemName); if ((*EditFunction)((StringPtr)&ItemName)) { if (!(EqualString(ItemName,*leader->name,TRUE,FALSE)))//new name { DisposeHandle((Handle)leader->name); leader->name = NewString(ItemName);//set the new name newPosition = reSortElement(&theHead,leader);//resort LDelRow(1,theCell.v,thelist);//delete the old row theCell.v = newPosition; LAddRow(1,newPosition,thelist); //add a new row LSetCell(&ItemName[1], ItemName[0],theCell, thelist);//write the name in LSetSelect(TRUE,theCell,thelist); } } } break; case kNew: ItemName[0] = 0; // Signal new shortcut if ((*EditFunction)((StringPtr)&ItemName)) { short whereAt = createNodeAndSort(&theHead, ItemName); if (LGetSelect(TRUE, &theCell, thelist)) LSetSelect(FALSE,theCell,thelist); //turn off old selection theCell.v = LAddRow(1, whereAt, thelist); LSetCell(ItemName+1, Length(ItemName), theCell, thelist); LSetSelect(TRUE,theCell,thelist); //turn on new selection } break; case kDuplicate: SetPt(&theCell, 0, 0); if (LGetSelect(TRUE, &theCell, thelist)) { Handle oldResource,newResource; unsigned char copyString[] = " copy"; short resourceID; short index; length = 254; LGetCell(ItemName+1, &length, theCell, thelist); LSetSelect(FALSE,theCell,thelist); ItemName[0] = (char)length; leader = findNode(theHead,ItemName); UseResFile(TelInfo->SettingsFile); oldResource = GetNamedResource(ConfigResourceType,ItemName); if (!isACopy(ItemName))//add the copy extension { ItemName[0] += 5; BlockMoveData(copyString, &(ItemName[ItemName[0]-4]),5); } getAUniqueName(theHead,ItemName); resourceID = UniqueID(ConfigResourceType); newResource = myNewHandle(GetHandleSize(oldResource)); BlockMoveData(*oldResource,*newResource,GetHandleSize(newResource)); AddResource((Handle)newResource, ConfigResourceType, resourceID, ItemName); UpdateResFile(TelInfo->SettingsFile); index = createNodeAndSort(¤tHead,ItemName); theCell.v = index; LAddRow(1,index,thelist); //add a new row LSetCell(&ItemName[1], ItemName[0],theCell, thelist);//write the name in LSetSelect(TRUE,theCell,thelist); ReleaseResource((Handle)newResource); ReleaseResource((Handle)oldResource); } break; default: break; } // switch SetPt(&theCell, 0, 0); if (LGetSelect(TRUE, &theCell, thelist)) { Hilite(dptr, kRemove, 0); Hilite(dptr, kChange, 0); } else { Hilite(dptr, kRemove, 255); Hilite(dptr, kChange, 255); } } // while LDispose(thelist); DisposDialog(dptr); ResetMenus(); deleteList(&theHead); } void ZeroNumOnly(void) { short i; for(i=0; iwhat == keyDown) || (evt->what == autoKey)) { key = evt->message & charCodeMask; keyCode = (evt->message >>8) & 0xff; if ((key == 0x0d) || (key == 0x03)) { // 0x0d == return, 0x03 == enter // *item = DLOGOk; // return(-1); /* BYU LSC - pascal doesn't like "1" as true */ return CallStdFilterProc(dptr, evt, item); } if (((key == '.') && (evt->modifiers & cmdKey)) || ((key == 0x1b) && (keyCode == 0x35)) ) { // 0x35 == escKey // *item = DLOGCancel; // return(-1); /* BYU LSC - pascal doesn't like "1" as true */ return CallStdFilterProc(dptr, evt, item); } if ((key < '0' || key > '9') && !(key == 0x08 || key == 0x09 || (key > 0x1B && key < 0x20)) && InNumOnly(((DialogPeek)dptr)->editField + 1)) { /* Reject non-numbers for this TE */ *item = NumOnly[0]; /* Kludge -- Return "safe" item */ return(-1); } } if (evt->what == updateEvt) { if ((WindowPtr)evt->message == dptr) { // RAB BetterTelnet 1.2 - We let StdFilterProc handle this. // GetDItem(dptr,DLOGOk,&iType,&iHndl,&iRect); // ok // PenSize(3,3); // InsetRect(&iRect,-4,-4); // FrameRoundRect(&iRect,16,16); for (index = 0; index < NumberOfColorBoxes; index++) ColorBoxItemProc(dptr, BoxColorItems[index]); // update color boxes } CallStdFilterProc(dptr, evt, item); } Stask(); return CallStdFilterProc(dptr, evt, item); } SIMPLE_UPP(TerminalModalProc, ModalFilter); pascal short TerminalModalProc( DialogPtr dptr, EventRecord *evt, short *item) { if (evt->what == mouseDown) return(PopupMousedown(dptr, evt, item)); return(ColorBoxModalProc(dptr, evt, item)); } SIMPLE_UPP(SessionModalProc, ModalFilter); pascal short SessionModalProc(DialogPtr dptr, EventRecord *evt, short *item) { short key, tempLen; // if ((evt->what == keyDown) || (evt->what == autoKey)) // if ((evt->message & charCodeMask) == ' ') { // *item = NumOnly[0]; /* Kludge -- Return "safe" item */ // return(-1); // } if ((evt->what == keyDown) || (evt->what == autoKey)) if ((((DialogPeek)dptr)->editField + 1) == 52) { key = evt->message & charCodeMask; if (key == 8) { configPassword[0] = 0; SetTEText(dptr, 52, "\p"); *item = 0; return -1; } if (key == 9) return 0; if (key < 32) { *item = 0; StdFilterProc(dptr, evt, item); return -1; } tempLen = strlen(configPassword); if (tempLen < 250) { configPassword[tempLen] = key; configPassword[tempLen+1] = 0; } evt->message = (evt->message & 0xFFFFFF00) + ''; return 0; } return(TerminalModalProc(dptr, evt, item)); } Boolean EditTerminal(StringPtr PrefRecordNamePtr) { DialogPtr dptr; short ditem, scratchshort, resourceID, i, currentPanel, newPanel; long scratchlong; ResType scratchResType; Boolean IsNewPrefRecord, UserLikesNewColor,wasInAliasText; TerminalPrefs** TermPrefsHdl; TerminalPrefs* TermPrefsPtr; Str255 scratchPstring; RGBColor scratchRGBcolor; Point ColorBoxPoint; MenuHandle WeNeedAFontMenuHandle, WeNeedAnotherFontMenuHandle; popup TPopup[] = {{TermFontPopup, (MenuHandle) 0, 1}, {43, (MenuHandle) 0, 1}, {0, (MenuHandle) 0, 0}}; dptr = GetNewMySmallStrangeDialog(TermDLOG, NULL, kInFront, (void *)ThirdCenterDialog); ditem = 3; SetDialogDefaultItem(dptr, 1); SetDialogCancelItem(dptr, 2); SetDialogTracksCursor(dptr, 1); currentPanel = TelInfo->lastPanelTerminal + 1; SetCntrl(dptr, 46, currentPanel); HideDItemRange(dptr, 11, 16); HideDItemRange(dptr, 22, 23); HideDItemRange(dptr, 25, 27); HideDItemRange(dptr, 30, 31); HideDItemRange(dptr, 33, 34); HideDItem(dptr, 48); HideDItemRange(dptr, 28, 29); HideDItem(dptr, 32); HideDItemRange(dptr, 35, 39); DrawBlank(dptr, 20); DrawBlank(dptr, 43); HideDItemRange(dptr, 19, 21); HideDItemRange(dptr, 40, 44); HideDItemRange(dptr, 3, 10); HideDItem(dptr, 24); HideDItem(dptr, 47); switch (currentPanel) { case 1: ShowDItemRange(dptr, 11, 16); ShowDItemRange(dptr, 22, 23); ShowDItemRange(dptr, 25, 27); ShowDItemRange(dptr, 30, 31); ShowDItemRange(dptr, 33, 34); ShowDItem(dptr, 48); break; case 2: ShowDItemRange(dptr, 28, 29); ShowDItem(dptr, 32); ShowDItemRange(dptr, 35, 39); break; case 3: ShowDItemRange(dptr, 19, 21); ShowDItemRange(dptr, 40, 44); DrawPopUp(dptr, 20); DrawPopUp(dptr, 43); ShowDItem(dptr, 47); break; case 4: ShowDItemRange(dptr, 3, 10); ShowDItem(dptr, 24); break; } WeNeedAFontMenuHandle = NewMenu(666, "\p"); //get the fonts from the font menu in the menu bar scratchshort = CountMItems(myMenus[Font]); for (i = 1; i <= scratchshort; i++) { GetItem(myMenus[Font],i,scratchPstring); AppendMenu(WeNeedAFontMenuHandle,scratchPstring); } TPopup[0].h = WeNeedAFontMenuHandle; WeNeedAnotherFontMenuHandle = NewMenu(667, "\p"); //get the fonts from the font menu in the menu bar scratchshort = CountMItems(myMenus[Font]); for (i = 1; i <= scratchshort; i++) { GetItem(myMenus[Font],i,scratchPstring); AppendMenu(WeNeedAnotherFontMenuHandle,scratchPstring); } TPopup[1].h = WeNeedAnotherFontMenuHandle; PopupInit(dptr, TPopup); if (PrefRecordNamePtr[0] != 0) { IsNewPrefRecord = FALSE; UseResFile(TelInfo->SettingsFile); TermPrefsHdl = (TerminalPrefs **)Get1NamedResource(TERMINALPREFS_RESTYPE, PrefRecordNamePtr); if (EqualString(PrefRecordNamePtr, "\p", FALSE, FALSE)) { HideDItem(dptr, TermNameStatText); HideDItem(dptr, TermName); } } else { //make sure we have a unique name TermPrefsHdl = GetDefaultTerminal(); IsNewPrefRecord = TRUE; GetIndString(PrefRecordNamePtr, MISC_STRINGS, MISC_NEWTERM); getAUniqueName(currentHead,PrefRecordNamePtr); } HLock((Handle) TermPrefsHdl); TermPrefsPtr = *TermPrefsHdl; SetTEText(dptr, TermName, PrefRecordNamePtr); SetCntrl(dptr, TermANSI, TermPrefsPtr->ANSIgraphics); SetCntrl(dptr, TermXterm, TermPrefsPtr->Xtermsequences); SetCntrl(dptr, 39, TermPrefsPtr->remapCtrlD); SetCntrl(dptr, 40, TermPrefsPtr->allowBold); SetCntrl(dptr, 41, TermPrefsPtr->colorBold); SetCntrl(dptr, 44, TermPrefsPtr->boldFontStyle); SetCntrl(dptr, 47, TermPrefsPtr->realbold); SetCntrl(dptr, 48, TermPrefsPtr->oldScrollback); SetCntrl(dptr, Termvtwrap, TermPrefsPtr->vtwrap); // SetCntrl(dptr, Termmeta, TermPrefsPtr->emacsmetakey); SetCntrl(dptr, TermMetaIsCmdCntrol, (TermPrefsPtr->emacsmetakey == 1)); SetCntrl(dptr, TermMetaIsOption, (TermPrefsPtr->emacsmetakey == 2)); SetCntrl(dptr, TermMetaIsOff, (TermPrefsPtr->emacsmetakey == 0)); SetCntrl(dptr, Termarrow, TermPrefsPtr->emacsarrows); SetCntrl(dptr, TermMAT, TermPrefsPtr->MATmappings); SetCntrl(dptr, Termeightbit, TermPrefsPtr->eightbit); SetCntrl(dptr, Termclearsave, TermPrefsPtr->clearsave); SetCntrl(dptr, TermVT100, (TermPrefsPtr->vtemulation == 0)); SetCntrl(dptr, TermVT220, (TermPrefsPtr->vtemulation == 1)); SetCntrl(dptr, TermRemapKeypad, TermPrefsPtr->remapKeypad); scratchlong = (long)(TermPrefsPtr->vtwidth); NumToString(scratchlong, scratchPstring); SetTEText(dptr, TermWidth, scratchPstring); scratchlong = (short)(TermPrefsPtr->vtheight); NumToString(scratchlong, scratchPstring); SetTEText(dptr, TermHeight, scratchPstring); scratchlong = TermPrefsPtr->fontsize; NumToString(scratchlong, scratchPstring); SetTEText(dptr, TermFontSize, scratchPstring); scratchlong = TermPrefsPtr->numbkscroll; NumToString(scratchlong, scratchPstring); SetTEText(dptr, TermScrollback, scratchPstring); SetTEText(dptr, TermAnswerback, TermPrefsPtr->AnswerBackMessage); for(scratchshort = CountMItems(TPopup[0].h); scratchshort; scratchshort--) { GetItem(TPopup[0].h, scratchshort, scratchPstring); if (EqualString(scratchPstring, (TermPrefsPtr->DisplayFont), TRUE, FALSE)) TPopup[0].choice = scratchshort; } for(scratchshort = CountMItems(TPopup[1].h); scratchshort; scratchshort--) { GetItem(TPopup[1].h, scratchshort, scratchPstring); if (EqualString(scratchPstring, (TermPrefsPtr->BoldFont), TRUE, FALSE)) TPopup[1].choice = scratchshort; } ZeroNumOnly(); NumOnly[0] = TermSafeItem; NumOnly[1] = TermWidth; NumOnly[2] = TermHeight; NumOnly[3] = TermFontSize; NumOnly[4] = TermScrollback; NumOnly[5] = 0; // if (TermPrefsPtr->vtemulation != 1) // { // HideDItem(dptr,TermRemapKeypad); // HideDItem(dptr,TermMAT); // } if (TelInfo->haveColorQuickDraw) { for (scratchshort = 0, NumberOfColorBoxes = 4; scratchshort < NumberOfColorBoxes; scratchshort++) { BoxColorItems[scratchshort] = TermNFcolor + scratchshort; BlockMove(&(TermPrefsPtr->nfcolor) + scratchshort, &BoxColorData[scratchshort], sizeof(RGBColor)); UItemAssign( dptr, TermNFcolor + scratchshort, ColorBoxItemProcUPP); } } else NumberOfColorBoxes = 0; // B&W machine ColorBoxPoint.h = 0; // Have the color picker center the box on the main ColorBoxPoint.v = 0; // screen SelIText(dptr, TermName, 0, 32767); ShowWindow(dptr); wasInAliasText = FALSE; while (ditem > 2) { movableModalDialog(TerminalModalProcUPP, &ditem); if ((wasInAliasText)&&(ditem != TermName)) { wasInAliasText = FALSE; GetTEText(dptr, TermName,scratchPstring); if (EqualString(scratchPstring,PrefRecordNamePtr,FALSE,FALSE)) goto okayTermName; if (scratchPstring[0] == 0) { DialogPtr alertUser; short alertDItem = 3; alertUser = GetNewMyDialog(kBadPrefNameDLOG, NULL, kInFront, (void *)ThirdCenterDialog); while (alertDItem > 1) { ModalDialog(DLOGwOK_CancelUPP,&alertDItem); DisposeDialog(alertUser); } SetPort(dptr); //back to old dialog SetTEText(dptr,TermName,PrefRecordNamePtr);//set the string back to the original SelIText(dptr,TermName,0,32767); ditem = TermName; //so that if they hit ok or cancel, it doesn't kill the window } else if(findNodeNC(currentHead,scratchPstring)) //we already have that name { DialogPtr alertUser; short alertDItem = 3; alertUser = GetNewMyDialog(kBadPrefNameDLOG, NULL, kInFront, (void *)ThirdCenterDialog); while (alertDItem > 1) { ModalDialog(DLOGwOK_CancelUPP,&alertDItem); DisposeDialog(alertUser); } SetPort(dptr); //back to old dialog SetTEText(dptr,TermName,PrefRecordNamePtr);//set the string back to the original SelIText(dptr,TermName,0,32767); ditem = TermName; //so that if they hit ok or cancel, it doesn't kill the window } else goto okayTermName; } else { okayTermName: switch (ditem) { case TermANSI: case TermXterm: case 39: case 40: case 41: case 44: case 47: case 48: case Termvtwrap: case Termarrow: case TermMAT: case Termeightbit: case Termclearsave: case TermRemapKeypad: FlipCheckBox(dptr, ditem); break; case TermVT100: SetCntrl(dptr, TermVT100, 1); SetCntrl(dptr, TermVT220, 0); SetTEText(dptr, TermAnswerback, "\pVT100"); //HideDItem(dptr,TermRemapKeypad); //HideDItem(dptr,TermMAT); break; case TermVT220: SetCntrl(dptr, TermVT100, 0); SetCntrl(dptr, TermVT220, 1); SetTEText(dptr, TermAnswerback, "\pVT220"); //ShowDItem(dptr,TermRemapKeypad); //ShowDItem(dptr,TermMAT); break; case TermMetaIsCmdCntrol: SetCntrl(dptr, TermMetaIsOption, 0); SetCntrl(dptr, TermMetaIsOff, 0); SetCntrl(dptr, TermMetaIsCmdCntrol, 1); break; case TermMetaIsOption: SetCntrl(dptr, TermMetaIsOff, 0); SetCntrl(dptr, TermMetaIsCmdCntrol, 0); SetCntrl(dptr, TermMetaIsOption, 1); break; case TermMetaIsOff: SetCntrl(dptr, TermMetaIsCmdCntrol, 0); SetCntrl(dptr, TermMetaIsOption, 0); SetCntrl(dptr, TermMetaIsOff, 1); break; case TermNFcolor: case TermNBcolor: case TermBFcolor: case TermBBcolor: if (TelInfo->haveColorQuickDraw) { Str255 askColorString; GetIndString(askColorString,MISC_STRINGS,PICK_NEW_COLOR_STRING); UserLikesNewColor = GetColor(ColorBoxPoint, askColorString, &BoxColorData[ditem-TermNFcolor], &scratchRGBcolor); if (UserLikesNewColor) BoxColorData[ditem-TermNFcolor] = scratchRGBcolor; } break; case 46: // switch tabs newPanel = GetCntlVal(dptr, 46); if (newPanel == currentPanel) break; switch (currentPanel) { case 1: HideDItemRange(dptr, 11, 16); HideDItemRange(dptr, 22, 23); HideDItemRange(dptr, 25, 27); HideDItemRange(dptr, 30, 31); HideDItemRange(dptr, 33, 34); HideDItem(dptr, 48); break; case 2: HideDItemRange(dptr, 28, 29); HideDItem(dptr, 32); HideDItemRange(dptr, 35, 39); break; case 3: DrawBlank(dptr, 20); DrawBlank(dptr, 43); HideDItemRange(dptr, 19, 21); HideDItemRange(dptr, 40, 44); HideDItem(dptr, 47); break; case 4: HideDItemRange(dptr, 3, 10); HideDItem(dptr, 24); break; } switch (newPanel) { case 1: ShowDItemRange(dptr, 11, 16); ShowDItemRange(dptr, 22, 23); ShowDItemRange(dptr, 25, 27); ShowDItemRange(dptr, 30, 31); ShowDItemRange(dptr, 33, 34); ShowDItem(dptr, 48); break; case 2: ShowDItemRange(dptr, 28, 29); ShowDItem(dptr, 32); ShowDItemRange(dptr, 35, 39); break; case 3: ShowDItemRange(dptr, 19, 21); ShowDItemRange(dptr, 40, 44); DrawPopUp(dptr, 20); DrawPopUp(dptr, 43); ShowDItem(dptr, 47); break; case 4: ShowDItemRange(dptr, 3, 10); ShowDItem(dptr, 24); break; } currentPanel = newPanel; break; case TermName: wasInAliasText = TRUE; default: break; } // switch }//else not wasInAliasText } // while GetItem(TPopup[1].h, TPopup[1].choice, scratchPstring); if (Length(scratchPstring) > 63) scratchPstring[0] = 63; BlockMove(scratchPstring, (TermPrefsPtr->BoldFont), scratchPstring[0]+1); GetItem(TPopup[0].h, TPopup[0].choice, scratchPstring); PopupCleanup(); if (ditem == 2) { if (IsNewPrefRecord) DisposeHandle((Handle) TermPrefsHdl); else ReleaseResource((Handle) TermPrefsHdl); TelInfo->lastPanelTerminal = currentPanel - 1; DisposeDialog(dptr); return(FALSE); // No changes should be made. } if (TelInfo->haveColorQuickDraw) { for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) { BlockMove(&BoxColorData[scratchshort], &(TermPrefsPtr->nfcolor) + scratchshort, sizeof(RGBColor)); } } if (Length(scratchPstring) > 63) scratchPstring[0] = 63; BlockMove(scratchPstring, (TermPrefsPtr->DisplayFont), scratchPstring[0]+1); TermPrefsPtr->ANSIgraphics = GetCntlVal(dptr, TermANSI); TermPrefsPtr->Xtermsequences = GetCntlVal(dptr, TermXterm); TermPrefsPtr->remapCtrlD = GetCntlVal(dptr, 39); TermPrefsPtr->allowBold = GetCntlVal(dptr, 40); TermPrefsPtr->colorBold = GetCntlVal(dptr, 41); TermPrefsPtr->realbold = GetCntlVal(dptr, 47); TermPrefsPtr->oldScrollback = GetCntlVal(dptr, 48); TermPrefsPtr->boldFontStyle = GetCntlVal(dptr, 44); TermPrefsPtr->vtwrap = GetCntlVal(dptr, Termvtwrap); if (GetCntlVal(dptr, TermMetaIsCmdCntrol)) TermPrefsPtr->emacsmetakey = 1; else if (GetCntlVal(dptr, TermMetaIsOption)) TermPrefsPtr->emacsmetakey = 2; else TermPrefsPtr->emacsmetakey = 0; TermPrefsPtr->emacsarrows = GetCntlVal(dptr, Termarrow); TermPrefsPtr->MATmappings = GetCntlVal(dptr, TermMAT); TermPrefsPtr->eightbit = GetCntlVal(dptr, Termeightbit); TermPrefsPtr->clearsave = GetCntlVal(dptr, Termclearsave); TermPrefsPtr->remapKeypad = GetCntlVal(dptr, TermRemapKeypad); TermPrefsPtr->vtemulation = (GetCntlVal(dptr, TermVT220) != 0); GetTEText(dptr, TermWidth, scratchPstring); StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 133, 10); TermPrefsPtr->vtwidth = (short) scratchlong; GetTEText(dptr, TermHeight, scratchPstring); StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 80, 10); TermPrefsPtr->vtheight = (short) scratchlong; GetTEText(dptr, TermFontSize, scratchPstring); StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 24, 4); TermPrefsPtr->fontsize = (short) scratchlong; GetTEText(dptr, TermScrollback, scratchPstring); StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 50000, 24); TermPrefsPtr->numbkscroll = (short) scratchlong; GetTEText(dptr, TermAnswerback, scratchPstring); if (Length(scratchPstring) > 63) scratchPstring[0] = 63; BlockMove(scratchPstring, TermPrefsPtr->AnswerBackMessage, scratchPstring[0]+1); GetTEText(dptr, TermName, PrefRecordNamePtr); if (IsNewPrefRecord) { UseResFile(TelInfo->SettingsFile); resourceID = UniqueID(TERMINALPREFS_RESTYPE); AddResource((Handle)TermPrefsHdl, TERMINALPREFS_RESTYPE, resourceID, PrefRecordNamePtr); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)TermPrefsHdl); } else { UseResFile(TelInfo->SettingsFile); GetResInfo((Handle)TermPrefsHdl, &resourceID, &scratchResType,(StringPtr) &scratchPstring); SetResInfo((Handle)TermPrefsHdl, resourceID, PrefRecordNamePtr); ChangedResource((Handle)TermPrefsHdl); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)TermPrefsHdl); } TelInfo->lastPanelTerminal = currentPanel - 1; DisposeDialog(dptr); return(TRUE); // A resource has changed or been added. } Boolean EditSession(StringPtr PrefRecordNamePtr) { DialogPtr dptr; short ditem, scratchshort, resourceID, currentPanel, newPanel, i; short numberOfTerms; long scratchlong; ResType scratchResType; Boolean IsNewPrefRecord, wasInAliasText; SessionPrefs** SessPrefsHdl; SessionPrefs* SessPrefsPtr; TerminalPrefs** tempTermPrefsHdl; Str255 scratchPstring, scratchPstring2; LinkedListNode *savedList; EventRecord optKeyEvtRec; popup SPopup[] = {{SessTermPopup, (MenuHandle) 0, 1}, {SessTransTablePopup, (MenuHandle) 0, 1}, {0, (MenuHandle) 0, 0}}; dptr = GetNewMySmallStrangeDialog(SessionConfigDLOG, NULL, kInFront, (void *)ThirdCenterDialog); ditem = 3; SetDialogDefaultItem(dptr, 1); SetDialogCancelItem(dptr, 2); SetDialogTracksCursor(dptr, 1); currentPanel = TelInfo->lastPanelSession + 1; savedList = currentHead; //save the current list, so the list that got us here works SPopup[0].h = NewMenu(666, "\p"); UseResFile(TelInfo->SettingsFile); numberOfTerms = Count1Resources(TERMINALPREFS_RESTYPE); currentHead = createSortedList(TERMINALPREFS_RESTYPE,numberOfTerms,"\p"); addListToMenu(SPopup[0].h, currentHead, 1); EnableItem(SPopup[0].h, 0); // Make sure the entire menu is enabled deleteList(¤tHead); UseResFile(TelInfo->ApplicationFile); SPopup[1].h = NewMenu(667, "\p"); numberOfTerms = CountResources(USER_TRSL); currentHead = createSortedList2(USER_TRSL,numberOfTerms,NULL); GetIndString(scratchPstring,MISC_STRINGS,NONE_STRING); //"None" string AppendMenu(SPopup[1].h,scratchPstring); addListToMenu/*3*/(SPopup[1].h, currentHead, 2); EnableItem(SPopup[1].h, 0); // Make sure the entire menu is enabled deleteList(¤tHead); UseResFile(TelInfo->SettingsFile); currentHead = savedList; PopupInit(dptr, SPopup); if (PrefRecordNamePtr[0] != 0) { IsNewPrefRecord = FALSE; UseResFile(TelInfo->SettingsFile); SessPrefsHdl = (SessionPrefs **)Get1NamedResource(SESSIONPREFS_RESTYPE, PrefRecordNamePtr); if (EqualString(PrefRecordNamePtr, "\p", FALSE, FALSE)) { HideDItem(dptr, SessAlias); HideDItem(dptr, SessAliasStatText); } } else { SessPrefsHdl = GetDefaultSession(); IsNewPrefRecord = TRUE; GetIndString(PrefRecordNamePtr, MISC_STRINGS, MISC_NEWSESSION); getAUniqueName(currentHead,PrefRecordNamePtr); } HLock((Handle) SessPrefsHdl); SessPrefsPtr = *SessPrefsHdl; SetCntrl(dptr, SessTEKinhib, (SessPrefsPtr->tektype == -1)); SetCntrl(dptr, SessTEK4014, (SessPrefsPtr->tektype == 0)); SetCntrl(dptr, SessTEK4105, (SessPrefsPtr->tektype == 1)); SetCntrl(dptr, SessPasteQuick, (SessPrefsPtr->pastemethod == 0)); SetCntrl(dptr, SessPasteBlock, (SessPrefsPtr->pastemethod == 1)); SetCntrl(dptr, SessDeleteDel, (SessPrefsPtr->bksp == 1)); SetCntrl(dptr, SessDeleteBS, (SessPrefsPtr->bksp == 0)); SetCntrl(dptr, SessForceSave, SessPrefsPtr->forcesave); SetCntrl(dptr, SessBezerkeley, SessPrefsPtr->crmap); SetCntrl(dptr, 42, SessPrefsPtr->alwaysBSD); SetCntrl(dptr, 43, SessPrefsPtr->ignoreBeeps); SetCntrl(dptr, 44, SessPrefsPtr->ignoreff); SetCntrl(dptr, SessLinemode, SessPrefsPtr->linemode); SetCntrl(dptr, SessTEKclear, SessPrefsPtr->tekclear); SetCntrl(dptr, SessHalfDuplex, SessPrefsPtr->halfdup); SetCntrl(dptr, SessAuthenticate, SessPrefsPtr->authenticate); SetCntrl(dptr, SessEncrypt, SessPrefsPtr->encrypt); SetCntrl(dptr, SessLocalEcho, SessPrefsPtr->localecho); SetCntrl(dptr, 47, SessPrefsPtr->otpauto); SetCntrl(dptr, 48, SessPrefsPtr->otpmulti); SetCntrl(dptr, 49, SessPrefsPtr->otphex); SetCntrl(dptr, 50, SessPrefsPtr->otpnoprompt); SetCntrl(dptr, 53, SessPrefsPtr->otpsavepass); configPassword[0] = 0; if (SessPrefsPtr->otppassword[0]) { pstrcpy((unsigned char *)configPassword, (unsigned char *)SessPrefsPtr->otppassword); p2cstr((unsigned char *)configPassword); for (i = 1; i < 250; i++) scratchPstring[i] = ''; scratchPstring[0] = strlen(configPassword); SetTEText(dptr, 52, scratchPstring); } SetTEText(dptr, SessHostName, SessPrefsPtr->hostname); SetTEText(dptr, SessAlias, PrefRecordNamePtr); if (SessPrefsPtr->portNegative) { NumToString((unsigned short)SessPrefsPtr->port, &scratchPstring[1]); scratchPstring[0] = scratchPstring[1] + 1; scratchPstring[1] = '-'; } else NumToString((unsigned short)SessPrefsPtr->port, scratchPstring); SetTEText(dptr, SessPort, scratchPstring); NumToString(SessPrefsPtr->pasteblocksize, scratchPstring); SetTEText(dptr, SessBlockSize, scratchPstring); if (SessPrefsPtr->NetBlockSize <= 512) SessPrefsPtr->NetBlockSize = 512; NumToString(SessPrefsPtr->NetBlockSize, scratchPstring); SetTEText(dptr, SessBlockSizeTE, scratchPstring); scratchPstring[0] = 2; scratchPstring[1] = '^'; if (SessPrefsPtr->ckey != -1) { scratchPstring[2] = SessPrefsPtr->ckey ^ 64; SetTEText(dptr, SessInterrupt, scratchPstring); } if (SessPrefsPtr->skey != -1) { scratchPstring[2] = SessPrefsPtr->skey ^ 64; SetTEText(dptr, SessSuspend, scratchPstring); } if (SessPrefsPtr->qkey != -1) { scratchPstring[2] = SessPrefsPtr->qkey ^ 64; SetTEText(dptr, SessResume, scratchPstring); } for(scratchshort = CountMItems(SPopup[0].h); scratchshort; scratchshort--) { GetItem(SPopup[0].h, scratchshort, scratchPstring); if (EqualString(scratchPstring, (SessPrefsPtr->TerminalEmulation), TRUE, FALSE)) SPopup[0].choice = scratchshort; } for(scratchshort = CountMItems(SPopup[1].h); scratchshort; scratchshort--) { GetItem(SPopup[1].h, scratchshort, scratchPstring); if (EqualString(scratchPstring, (SessPrefsPtr->TranslationTable), TRUE, FALSE)) SPopup[1].choice = scratchshort; } NumberOfColorBoxes = 0; ZeroNumOnly(); NumOnly[0] = SessSafeItem; NumOnly[1] = SessBlockSize; SetCntrl(dptr, 46, currentPanel); HideDItemRange(dptr, 19, 20); HideDItemRange(dptr, 25, 27); HideDItem(dptr, 29); HideDItemRange(dptr, 36, 37); HideDItemRange(dptr, 40, 41); HideDItemRange(dptr, 6, 7); HideDItemRange(dptr, 21, 24); HideDItem(dptr, 12); HideDItem(dptr, 14); HideDItem(dptr, 17); HideDItem(dptr, 31); HideDItemRange(dptr, 33, 35); HideDItemRange(dptr, 38, 39); HideDItemRange(dptr, 3, 5); HideDItemRange(dptr, 8, 11); HideDItem(dptr, 13); HideDItem(dptr, 30); HideDItem(dptr, 32); HideDItemRange(dptr, 42, 44); HideDItemRange(dptr, 15, 16); HideDItemRange(dptr, 47, 53); switch (currentPanel) { case 1: ShowDItemRange(dptr, 19, 20); ShowDItemRange(dptr, 25, 27); ShowDItem(dptr, 29); ShowDItemRange(dptr, 36, 37); ShowDItemRange(dptr, 40, 41); DrawPopUp(dptr, 25); DrawPopUp(dptr, 26); break; case 2: ShowDItemRange(dptr, 6, 7); ShowDItemRange(dptr, 21, 24); ShowDItem(dptr, 12); ShowDItem(dptr, 14); ShowDItem(dptr, 17); ShowDItem(dptr, 31); ShowDItemRange(dptr, 33, 35); ShowDItemRange(dptr, 38, 39); break; case 3: ShowDItemRange(dptr, 3, 5); ShowDItemRange(dptr, 8, 11); ShowDItem(dptr, 13); ShowDItem(dptr, 30); ShowDItem(dptr, 32); ShowDItemRange(dptr, 42, 44); break; case 4: ShowDItemRange(dptr, 15, 16); ShowDItemRange(dptr, 47, 53); } SelIText(dptr, SessAlias, 0, 32767); ShowWindow(dptr); wasInAliasText = FALSE; while ((ditem > 2) || (ditem == 0)) { movableModalDialog(SessionModalProcUPP, &ditem); if (ditem == 0) continue; if ((wasInAliasText)&&(ditem != SessAlias)) { wasInAliasText = FALSE; GetTEText(dptr, SessAlias, scratchPstring); if (EqualString(scratchPstring,PrefRecordNamePtr,FALSE,FALSE)) goto okaySessName; if (scratchPstring[0] == 0) { DialogPtr alertUser; short alertDItem = 3; alertUser = GetNewMyDialog(kBadPrefNameDLOG, NULL, kInFront, (void *)ThirdCenterDialog); while (alertDItem > 1) { ModalDialog(DLOGwOK_CancelUPP,&alertDItem); DisposeDialog(alertUser); } SetPort(dptr); //back to old dialog SetTEText(dptr,SessAlias,PrefRecordNamePtr);//set the string back to the original SelIText(dptr,SessAlias,0,32767); ditem = SessAlias; //so that if they hit ok or cancel, it doesn't kill the window } else if(findNodeNC(currentHead,scratchPstring)) //we already have that name { DialogPtr alertUser; short alertDItem = 3; alertUser = GetNewMyDialog(kBadPrefNameDLOG, NULL, kInFront, (void *)ThirdCenterDialog); while (alertDItem > 1) { ModalDialog(DLOGwOK_CancelUPP,&alertDItem); DisposeDialog(alertUser); } SetPort(dptr); //back to old dialog SetTEText(dptr,SessAlias,PrefRecordNamePtr);//set the string back to the original SelIText(dptr,SessAlias,0,32767); ditem = SessAlias; //so that if they hit ok or cancel, it doesn't kill the window } else goto okaySessName; } else { okaySessName: switch (ditem) { case SessForceSave: case SessBezerkeley: case SessLinemode: case SessTEKclear: case SessHalfDuplex: case SessAuthenticate: case SessEncrypt: case SessLocalEcho: case 42: case 43: case 44: case 47: case 48: case 49: case 50: case 53: FlipCheckBox(dptr, ditem); break; case SessTEKinhib: SetCntrl(dptr, SessTEKinhib, 1); SetCntrl(dptr, SessTEK4014, 0); SetCntrl(dptr, SessTEK4105, 0); break; case SessTEK4014: SetCntrl(dptr, SessTEKinhib, 0); SetCntrl(dptr, SessTEK4014, 1); SetCntrl(dptr, SessTEK4105, 0); break; case SessTEK4105: SetCntrl(dptr, SessTEKinhib, 0); SetCntrl(dptr, SessTEK4014, 0); SetCntrl(dptr, SessTEK4105, 1); break; case SessPasteQuick: SetCntrl(dptr, SessPasteQuick, 1); SetCntrl(dptr, SessPasteBlock, 0); break; case SessPasteBlock: SetCntrl(dptr, SessPasteQuick, 0); SetCntrl(dptr, SessPasteBlock, 1); break; case SessDeleteDel: SetCntrl(dptr, SessDeleteDel, 1); SetCntrl(dptr, SessDeleteBS, 0); break; case SessDeleteBS: SetCntrl(dptr, SessDeleteDel, 0); SetCntrl(dptr, SessDeleteBS, 1); break; case SessInterrupt: case SessSuspend: case SessResume: GetTEText(dptr, ditem, scratchPstring); if ((scratchPstring[1] < 32) && (scratchPstring[1] > 0)) { scratchPstring[0] = 2; scratchPstring[2] = scratchPstring[1] ^ 64; scratchPstring[1] = '^'; SetTEText(dptr, ditem, scratchPstring); } break; case 46: // tab control newPanel = GetCntlVal(dptr, 46); if (newPanel == currentPanel) break; switch (currentPanel) { case 1: DrawBlank(dptr, 25); DrawBlank(dptr, 26); HideDItemRange(dptr, 19, 20); HideDItemRange(dptr, 25, 27); HideDItem(dptr, 29); HideDItemRange(dptr, 36, 37); HideDItemRange(dptr, 40, 41); break; case 2: HideDItemRange(dptr, 6, 7); HideDItemRange(dptr, 21, 24); HideDItem(dptr, 12); HideDItem(dptr, 14); HideDItem(dptr, 17); HideDItem(dptr, 31); HideDItemRange(dptr, 33, 35); HideDItemRange(dptr, 38, 39); break; case 3: HideDItemRange(dptr, 3, 5); HideDItemRange(dptr, 8, 11); HideDItem(dptr, 13); HideDItem(dptr, 30); HideDItem(dptr, 32); HideDItemRange(dptr, 42, 44); break; case 4: HideDItemRange(dptr, 15, 16); HideDItemRange(dptr, 47, 53); } switch (newPanel) { case 1: ShowDItemRange(dptr, 19, 20); ShowDItemRange(dptr, 25, 27); ShowDItem(dptr, 29); ShowDItemRange(dptr, 36, 37); ShowDItemRange(dptr, 40, 41); DrawPopUp(dptr, 25); DrawPopUp(dptr, 26); break; case 2: ShowDItemRange(dptr, 6, 7); ShowDItemRange(dptr, 21, 24); ShowDItem(dptr, 12); ShowDItem(dptr, 14); ShowDItem(dptr, 17); ShowDItem(dptr, 31); ShowDItemRange(dptr, 33, 35); ShowDItemRange(dptr, 38, 39); break; case 3: ShowDItemRange(dptr, 3, 5); ShowDItemRange(dptr, 8, 11); ShowDItem(dptr, 13); ShowDItem(dptr, 30); ShowDItem(dptr, 32); ShowDItemRange(dptr, 42, 44); break; case 4: ShowDItemRange(dptr, 15, 16); ShowDItemRange(dptr, 47, 53); } currentPanel = newPanel; break; case 40: // Save as Set... case 41: // Add to Set... GetItem(SPopup[0].h, SPopup[0].choice, scratchPstring); GetItem(SPopup[1].h, SPopup[1].choice, scratchPstring2); if (Length(scratchPstring) > 63) scratchPstring[0] = 63; BlockMove(scratchPstring, (SessPrefsPtr->TerminalEmulation), scratchPstring[0]+1); if (Length(scratchPstring2) > 63) scratchPstring[0] = 63; BlockMove(scratchPstring2, (SessPrefsPtr->TranslationTable), scratchPstring2[0]+1); SessPrefsPtr->tektype = (-1 * GetCntlVal(dptr, SessTEKinhib)) + GetCntlVal(dptr, SessTEK4105); SessPrefsPtr->pastemethod = !GetCntlVal(dptr, SessPasteQuick); SessPrefsPtr->bksp = GetCntlVal(dptr, SessDeleteDel); SessPrefsPtr->forcesave = GetCntlVal(dptr, SessForceSave); SessPrefsPtr->crmap = GetCntlVal(dptr, SessBezerkeley); SessPrefsPtr->alwaysBSD = GetCntlVal(dptr, 42); SessPrefsPtr->ignoreBeeps = GetCntlVal(dptr, 43); SessPrefsPtr->ignoreff = GetCntlVal(dptr, 44); SessPrefsPtr->linemode = GetCntlVal(dptr, SessLinemode); SessPrefsPtr->tekclear = GetCntlVal(dptr, SessTEKclear); SessPrefsPtr->halfdup = GetCntlVal(dptr, SessHalfDuplex); SessPrefsPtr->authenticate = GetCntlVal(dptr, SessAuthenticate); SessPrefsPtr->encrypt = GetCntlVal(dptr, SessEncrypt); SessPrefsPtr->localecho = GetCntlVal(dptr, SessLocalEcho); SessPrefsPtr->otpauto = GetCntlVal(dptr, 47); SessPrefsPtr->otpmulti = GetCntlVal(dptr, 48); SessPrefsPtr->otphex = GetCntlVal(dptr, 49); SessPrefsPtr->otpnoprompt = GetCntlVal(dptr, 50); SessPrefsPtr->otpsavepass = GetCntlVal(dptr, 53); c2pstr(configPassword); pstrcpy((unsigned char *)SessPrefsPtr->otppassword, (unsigned char *)configPassword); GetTEText(dptr, SessPort, scratchPstring); SessPrefsPtr->portNegative = 0; if (scratchPstring[1] == '-') { SessPrefsPtr->portNegative = 1; scratchPstring[1] = scratchPstring[0] - 1; StringToNum(&scratchPstring[1], &scratchlong); } else StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 65530, 1); SessPrefsPtr->port = (short) scratchlong; GetTEText(dptr, SessBlockSize, scratchPstring); StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 4097, 10); SessPrefsPtr->pasteblocksize = (short) scratchlong; GetTEText(dptr, SessHostName, scratchPstring); if (Length(scratchPstring) > 63) scratchPstring[0] = 63; /* if (scratchPstring[0] == 0) { scratchPstring[0] = 5; scratchPstring[1] = 'a'; scratchPstring[2] = '.'; scratchPstring[3] = 'e'; scratchPstring[4] = 'd'; scratchPstring[5] = 'u'; } */ BlockMove(scratchPstring, SessPrefsPtr->hostname, scratchPstring[0]+1); GetTEText(dptr, SessAlias, PrefRecordNamePtr); GetTEText(dptr, SessInterrupt, scratchPstring); if (scratchPstring[0]) SessPrefsPtr->ckey = toupper(scratchPstring[2]) ^ 64; else SessPrefsPtr->ckey = -1; GetTEText(dptr, SessSuspend, scratchPstring); if (scratchPstring[0]) SessPrefsPtr->skey = toupper(scratchPstring[2]) ^ 64; else SessPrefsPtr->skey = -1; GetTEText(dptr, SessResume, scratchPstring); if (scratchPstring[0]) SessPrefsPtr->qkey = toupper(scratchPstring[2]) ^ 64; else SessPrefsPtr->qkey = -1; GetTEText(dptr,SessBlockSizeTE,scratchPstring); StringToNum(scratchPstring,&scratchlong); BoundsCheck(&scratchlong, 4096, 512); SessPrefsPtr->NetBlockSize = (short) scratchlong; UseResFile(TelInfo->SettingsFile); tempTermPrefsHdl = (TerminalPrefs **)Get1NamedResource (TERMINALPREFS_RESTYPE, SessPrefsPtr->TerminalEmulation); DetachResource((Handle) tempTermPrefsHdl); HLock((Handle) tempTermPrefsHdl); EventAvail(everyEvent, &optKeyEvtRec); SaveSetFromSession(SessPrefsPtr, *tempTermPrefsHdl, (ditem == 41), (optKeyEvtRec.modifiers & 0x0800)); DisposeHandle((Handle) tempTermPrefsHdl); break; case SessAlias: wasInAliasText = TRUE; break; default: break; } // switch } //else not bad alias } // while GetItem(SPopup[0].h, SPopup[0].choice, scratchPstring); GetItem(SPopup[1].h, SPopup[1].choice, scratchPstring2); PopupCleanup(); if (ditem == 2) { if (IsNewPrefRecord) DisposeHandle((Handle) SessPrefsHdl); else ReleaseResource((Handle) SessPrefsHdl); TelInfo->lastPanelSession = currentPanel - 1; DisposeDialog(dptr); return(FALSE); // No changes should be made. } if (Length(scratchPstring) > 63) scratchPstring[0] = 63; BlockMove(scratchPstring, (SessPrefsPtr->TerminalEmulation), scratchPstring[0]+1); if (Length(scratchPstring2) > 63) scratchPstring[0] = 63; BlockMove(scratchPstring2, (SessPrefsPtr->TranslationTable), scratchPstring2[0]+1); SessPrefsPtr->tektype = (-1 * GetCntlVal(dptr, SessTEKinhib)) + GetCntlVal(dptr, SessTEK4105); SessPrefsPtr->pastemethod = !GetCntlVal(dptr, SessPasteQuick); SessPrefsPtr->bksp = GetCntlVal(dptr, SessDeleteDel); SessPrefsPtr->forcesave = GetCntlVal(dptr, SessForceSave); SessPrefsPtr->crmap = GetCntlVal(dptr, SessBezerkeley); SessPrefsPtr->alwaysBSD = GetCntlVal(dptr, 42); SessPrefsPtr->ignoreBeeps = GetCntlVal(dptr, 43); SessPrefsPtr->ignoreff = GetCntlVal(dptr, 44); SessPrefsPtr->linemode = GetCntlVal(dptr, SessLinemode); SessPrefsPtr->tekclear = GetCntlVal(dptr, SessTEKclear); SessPrefsPtr->halfdup = GetCntlVal(dptr, SessHalfDuplex); SessPrefsPtr->authenticate = GetCntlVal(dptr, SessAuthenticate); SessPrefsPtr->encrypt = GetCntlVal(dptr, SessEncrypt); SessPrefsPtr->localecho = GetCntlVal(dptr, SessLocalEcho); SessPrefsPtr->otpauto = GetCntlVal(dptr, 47); SessPrefsPtr->otpmulti = GetCntlVal(dptr, 48); SessPrefsPtr->otphex = GetCntlVal(dptr, 49); SessPrefsPtr->otpnoprompt = GetCntlVal(dptr, 50); SessPrefsPtr->otpsavepass = GetCntlVal(dptr, 53); c2pstr(configPassword); pstrcpy((unsigned char *)SessPrefsPtr->otppassword, (unsigned char *)configPassword); GetTEText(dptr, SessPort, scratchPstring); SessPrefsPtr->portNegative = 0; if (scratchPstring[1] == '-') { SessPrefsPtr->portNegative = 1; scratchPstring[1] = scratchPstring[0] - 1; StringToNum(&scratchPstring[1], &scratchlong); } else StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 65530, 1); SessPrefsPtr->port = (short) scratchlong; GetTEText(dptr, SessBlockSize, scratchPstring); StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 4097, 10); SessPrefsPtr->pasteblocksize = (short) scratchlong; GetTEText(dptr, SessHostName, scratchPstring); if (Length(scratchPstring) > 63) scratchPstring[0] = 63; /* if (scratchPstring[0] == 0) { scratchPstring[0] = 5; scratchPstring[1] = 'a'; scratchPstring[2] = '.'; scratchPstring[3] = 'e'; scratchPstring[4] = 'd'; scratchPstring[5] = 'u'; } */ BlockMove(scratchPstring, SessPrefsPtr->hostname, scratchPstring[0]+1); GetTEText(dptr, SessAlias, PrefRecordNamePtr); GetTEText(dptr, SessInterrupt, scratchPstring); if (scratchPstring[0]) SessPrefsPtr->ckey = toupper(scratchPstring[2]) ^ 64; else SessPrefsPtr->ckey = -1; GetTEText(dptr, SessSuspend, scratchPstring); if (scratchPstring[0]) SessPrefsPtr->skey = toupper(scratchPstring[2]) ^ 64; else SessPrefsPtr->skey = -1; GetTEText(dptr, SessResume, scratchPstring); if (scratchPstring[0]) SessPrefsPtr->qkey = toupper(scratchPstring[2]) ^ 64; else SessPrefsPtr->qkey = -1; GetTEText(dptr,SessBlockSizeTE,scratchPstring); StringToNum(scratchPstring,&scratchlong); BoundsCheck(&scratchlong, 4096, 512); SessPrefsPtr->NetBlockSize = (short) scratchlong; if (IsNewPrefRecord) { UseResFile(TelInfo->SettingsFile); resourceID = UniqueID(SESSIONPREFS_RESTYPE); AddResource((Handle)SessPrefsHdl, SESSIONPREFS_RESTYPE, resourceID, PrefRecordNamePtr); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)SessPrefsHdl); } else { UseResFile(TelInfo->SettingsFile); GetResInfo((Handle)SessPrefsHdl, &resourceID, &scratchResType,(StringPtr) &scratchPstring); SetResInfo((Handle)SessPrefsHdl, resourceID, PrefRecordNamePtr); ChangedResource((Handle)SessPrefsHdl); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)SessPrefsHdl); } TelInfo->lastPanelSession = currentPanel - 1; DisposeDialog(dptr); return(TRUE); // A resource has changed or been added. } Boolean EditFTPUser(StringPtr PrefRecordNamePtr) { DialogPtr dptr; short ditem, scratchshort, resourceID, vRefNum; ResType scratchResType; Boolean IsNewPrefRecord; FTPUser** FTPUHdl; FTPUser* FTPUptr; Str255 scratchPstring, scratchPstring2; dptr = GetNewMySmallStrangeDialog(FTPUserDLOG, NULL, kInFront, (void *)ThirdCenterDialog); ditem = 3; HideDItem(dptr, FTPUcanchangeCWD); // Sometime later, perhaps if (PrefRecordNamePtr[0] != 0) { IsNewPrefRecord = FALSE; UseResFile(TelInfo->SettingsFile); FTPUHdl = (FTPUser **)Get1NamedResource(FTPUSER, PrefRecordNamePtr); HLock((Handle) FTPUHdl); FTPUptr = *FTPUHdl; SetCntrl(dptr, FTPUcanchangeCWD, FTPUptr->UserCanCWD); SetTEText(dptr, FTPUusername, PrefRecordNamePtr); for (scratchshort = 8, scratchPstring[0] = 8; scratchshort > 0; scratchshort--) scratchPstring[scratchshort] = ''; SetTEText(dptr, FTPUpassword, scratchPstring); vRefNum = VolumeNameToRefNum(FTPUptr->DefaultDirVolName); } else { IsNewPrefRecord = TRUE; FTPUHdl = (FTPUser **)myNewHandle(sizeof(FTPUser)); HLock((Handle) FTPUHdl); FTPUptr = *FTPUHdl; vRefNum = -1; // Default Volume FTPUptr->DefaultDirDirID = 2; // Root directory SetCntrl(dptr, FTPUcanchangeCWD, 0); } PathNameFromDirID(FTPUptr->DefaultDirDirID, vRefNum, scratchPstring); SetTEText(dptr, FTPUDfltDirDsply, scratchPstring); SelIText(dptr, FTPUusername, 0, 32767); ShowWindow(dptr); while (ditem > 2) { ModalDialog(DLOGwOK_CancelUPP, &ditem); switch (ditem) { case FTPUcanchangeCWD: FlipCheckBox(dptr, ditem); break; case FTPUDfltDirButton: SelectDirectory(&vRefNum, &(FTPUptr->DefaultDirDirID)); PathNameFromDirID(FTPUptr->DefaultDirDirID, vRefNum, scratchPstring); SetTEText(dptr, FTPUDfltDirDsply, scratchPstring); break; default: break; } // switch } // while if (ditem == 2) { if (IsNewPrefRecord) DisposeHandle((Handle) FTPUHdl); else ReleaseResource((Handle) FTPUHdl); DisposeDialog(dptr); return(FALSE); // No changes should be made. } FTPUptr->UserCanCWD = GetCntlVal(dptr, FTPUcanchangeCWD); GetDirectoryName(vRefNum, 2, FTPUptr->DefaultDirVolName); GetTEText(dptr, FTPUusername, PrefRecordNamePtr); GetTEText(dptr, FTPUpassword, scratchPstring); if (scratchPstring[0] != '') { // Encrypt the new (or possibly modified) password. PtoCstr(scratchPstring); Sencompass((char *)scratchPstring, (char *)scratchPstring2); CtoPstr((char *)scratchPstring2); BlockMove(scratchPstring2, FTPUptr->EncryptedPassword, Length(scratchPstring2)+1); } if (IsNewPrefRecord) { UseResFile(TelInfo->SettingsFile); resourceID = UniqueID(FTPUSER); AddResource((Handle)FTPUHdl, FTPUSER, resourceID, PrefRecordNamePtr); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)FTPUHdl); } else { UseResFile(TelInfo->SettingsFile); GetResInfo((Handle)FTPUHdl, &resourceID, &scratchResType,(StringPtr) &scratchPstring); SetResInfo((Handle)FTPUHdl, resourceID, PrefRecordNamePtr); ChangedResource((Handle)FTPUHdl); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)FTPUHdl); } DisposeDialog(dptr); return(TRUE); // A resource has changed or been added. } short AnsiPrompt(short allowDefaultBoldSelect, short *defaultBoldColor) { /* puts up the dialog that lets the user examine and change the ANSI color settings for the specified window. */ short scratchshort, ditem; Point ColorBoxPoint; DialogPtr dptr; Boolean UserLikesNewColor; RGBColorPtr scratchRGB; scratchRGB = (RGBColorPtr) myNewPtr(sizeof(RGBColor)); dptr = GetNewMySmallDialog(ANSIColorDLOG, NULL, kInFront, (void *)ThirdCenterDialog); SetDialogDefaultItem(dptr, 1); SetDialogCancelItem(dptr, 2); SetDialogTracksCursor(dptr, 1); NumberOfColorBoxes = 16; if (allowDefaultBoldSelect) SetCntrl(dptr, ANSIBlackRadio+(*defaultBoldColor), 1); else { for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) HideDItem(dptr, scratchshort + ANSIBlackRadio); HideDItem(dptr, 45); } for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) { BoxColorItems[scratchshort] = ANSIBlack + scratchshort; GetEntryColor(TelInfo->AnsiColors, scratchshort, scratchRGB); BlockMove(scratchRGB,&BoxColorData[scratchshort], sizeof(RGBColor)); UItemAssign( dptr, scratchshort + ANSIBlack, ColorBoxItemProcUPP); } ColorBoxPoint.h = 0; // Have the color picker center the box on the main ColorBoxPoint.v = 0; // screen NumOnly[0] = 12; //safe item ditem = 3; while (ditem > 2) { movableModalDialog(ColorBoxModalProcUPP, &ditem); switch (ditem) { case ANSIBlack: case ANSIRed: case ANSIGreen: case ANSIYellow: case ANSIBlue: case ANSIMagenta: case ANSICyan: case ANSIWhite: case ANSIBoldBlack: case ANSIBoldRed: case ANSIBoldGreen: case ANSIBoldYellow: case ANSIBoldBlue: case ANSIBoldMagenta: case ANSIBoldCyan: case ANSIBoldWhite: if (TelInfo->haveColorQuickDraw) { Str255 askColorString; GetIndString(askColorString,MISC_STRINGS,PICK_NEW_COLOR_STRING); UserLikesNewColor = GetColor(ColorBoxPoint,askColorString, &BoxColorData[ditem-ANSIBlack], scratchRGB); if (UserLikesNewColor) BoxColorData[ditem-ANSIBlack] = *scratchRGB; } break; case ANSIBlackRadio: case ANSIRedRadio: case ANSIGreenRadio: case ANSIYellowRadio: case ANSIBlueRadio: case ANSIMagentaRadio: case ANSICyanRadio: case ANSIWhiteRadio: case ANSIBoldBlackRadio: case ANSIBoldRedRadio: case ANSIBoldGreenRadio: case ANSIBoldYellowRadio: case ANSIBoldBlueRadio: case ANSIBoldMagentaRadio: case ANSIBoldCyanRadio: case ANSIBoldWhiteRadio: for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) SetCntrl(dptr, ANSIBlackRadio + scratchshort, 0); SetCntrl(dptr, ditem, 1); default: break; } // switch } // while if (ditem == DLOGCancel) { DisposeDialog(dptr); return -1; } if (allowDefaultBoldSelect) for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) if (GetCntlVal(dptr, ANSIBlackRadio + scratchshort)) *defaultBoldColor = scratchshort; for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) SetEntryColor(TelInfo->AnsiColors, scratchshort, &(BoxColorData[scratchshort])); DisposeDialog(dptr); } \ No newline at end of file +/* Configure.c * New Configuration scheme (the death of config.tel) * * Revisions: * 8/92 Telnet 2.6: Initial version. Jim Browne */ // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // RAB BetterTelnet 2.0fc1 - seriously cleaned up large parts of this code // (given that I had messed it up in previous versions :-) #include "DlogUtils.proto.h" #include "popup.h" #include "popup.proto.h" #include "configure.proto.h" #include "netevent.proto.h" /* For Stask proto */ #include "prefs.proto.h" #include "bkgr.proto.h" // For StartUpFTP proto #include "menuseg.proto.h" #include "macutil.proto.h" #include "rsinterf.proto.h" #include "LinkedList.proto.h" #include "Sets.proto.h" #include "movableModal.h" #include "wind.h" #include "Connections.proto.h" #include "sshglue.proto.h" #include "errors.proto.h" #include "macros.proto.h" static Boolean isACopy(Str255 theName);//looks for an occurance of "copy" in a string static pascal short TerminalModalProc( DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(TerminalModalProc, ModalFilter); static pascal short SessionModalProc(DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(SessionModalProc, ModalFilter); static pascal short MyDlogWListFilter( DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(MyDlogWListFilter, ModalFilter); static pascal void listDitemproc(DialogPtr theDlg, short itemNo); PROTO_UPP(listDitemproc, UserItem); extern FTPServerPrefs* gFTPServerPrefs; extern ApplicationPrefs* gApplicationPrefs; extern MenuHandle myMenus[]; static void ZeroNumOnly(void); static Boolean InNumOnly(short item); static char configPassword[256], configPassword2[256]; static LinkedListNode *currentHead; static ListHandle currentList; #define NUMONLYSIZE 8 short NumOnly[NUMONLYSIZE]; /* Items for which non-number keys are ignored */ // NumOnly[0] is number of "safe" item to return extern Handle oldMacros; extern NewMacroInfo oldMacroIndexes; extern short dialogPane; void CONFIGUREunload(void) {} void Cenviron( void) { DialogPtr dptr; short ditem, defaultBoldColor; Str255 scratchPstring; long scratchlong; OSType newtype; PaletteHandle toSave; Boolean tempBoolean; SetUpMovableModalMenus(); dptr = GetNewMySmallStrangeDialog( PrefDLOG, NULL, kInFront, (void *)ThirdCenterDialog); SetDialogDefaultItem(dptr, 1); SetDialogCancelItem(dptr, 2); SetDialogTracksCursor(dptr, 1); SetCntrl(dptr, PrefDClose, gApplicationPrefs->WindowsDontGoAway); SetCntrl(dptr, PrefStag, gApplicationPrefs->StaggerWindows); defaultBoldColor = gApplicationPrefs->defaultBoldColor; if (!gApplicationPrefs->StaggerWindows) { HideDialogItem(dptr,PrefStaggerOffset); HideDialogItem(dptr,PrefStaggerBY); tempBoolean = FALSE; } else { scratchlong = gApplicationPrefs->StaggerWindowsOffset; NumToString(scratchlong, scratchPstring); SetTEText(dptr, PrefStaggerOffset, scratchPstring); tempBoolean = TRUE; } if (!TelInfo->haveColorQuickDraw) HideDialogItem(dptr,PrefAnsiColor); SetCntrl(dptr, PrefCMDkey, gApplicationPrefs->CommandKeys); SetCntrl(dptr, PrefTMap, gApplicationPrefs->RemapTilde); SetCntrl(dptr, PrefBlink, gApplicationPrefs->BlinkCursor); SetCntrl(dptr, PrefKeyFuncMenus, gApplicationPrefs->KeyPadAndFuncMenus); SetCntrl(dptr, PrefNotifyUser, gApplicationPrefs->NotifyUser); SetCntrl(dptr, PrefBlockCursor, (gApplicationPrefs->CursorType == 0)); SetCntrl(dptr, PrefUnderscoreCursor, (gApplicationPrefs->CursorType == 1)); SetCntrl(dptr, PrefVerticalCursor, (gApplicationPrefs->CursorType == 2)); SetCntrl(dptr, PrefDestroyTickets, gApplicationPrefs->destroyKTickets); SetCntrl(dptr, 30, gApplicationPrefs->autoOpenDialog); SetCntrl(dptr, 31, gApplicationPrefs->dontWarnOnQuit); SetCntrl(dptr, 32, gApplicationPrefs->autoOpenDefault); SetCntrl(dptr, 33, gApplicationPrefs->parseAliases); SetCntrl(dptr, 34, gApplicationPrefs->monospacedOut); SetCntrl(dptr, 36, gApplicationPrefs->clipTrailingSpaces); SetCntrl(dptr, 37, gApplicationPrefs->globalSavePass); SetCntrl(dptr, 38, !gApplicationPrefs->noLiveScrolling); scratchPstring[0] = 4; BlockMove(&(gApplicationPrefs->CaptureFileCreator), &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, PrefCaptTE, scratchPstring); newtype = gApplicationPrefs->CaptureFileCreator; scratchlong = gApplicationPrefs->CopyTableThresh; NumToString(scratchlong, scratchPstring); SetTEText(dptr, PrefCTt, scratchPstring); SelectDialogItemText(dptr, PrefCTt, 0, 32767); NumToString(gApplicationPrefs->TimeSlice, scratchPstring); SetTEText(dptr, PrefTimeSlice, scratchPstring); scratchlong = (long) gApplicationPrefs->OpenTimeout; NumToString(scratchlong,scratchPstring); SetTEText(dptr,PrefOpenTime, scratchPstring); scratchlong = (long) gApplicationPrefs->SendTimeout; NumToString(scratchlong,scratchPstring); SetTEText(dptr,PrefSendTime, scratchPstring); ShowWindow(dptr); ditem=0; /* initially no hits */ while((ditem>2) || (ditem==0)) { movableModalDialog(0,&ditem); switch(ditem) { case PrefDClose: case PrefCMDkey: case PrefTMap: case PrefBlink: case PrefNotifyUser: case PrefKeyFuncMenus: case PrefDestroyTickets: case 30: case 31: case 32: case 33: case 34: case 36: case 37: case 38: FlipCheckBox( dptr, ditem); break; case PrefStag: FlipCheckBox( dptr, ditem); tempBoolean = !tempBoolean; if (!tempBoolean) { HideDialogItem(dptr,PrefStaggerOffset); HideDialogItem(dptr,PrefStaggerBY); } else { ShowDialogItem(dptr, PrefStaggerBY); ShowDialogItem(dptr, PrefStaggerOffset); scratchlong = gApplicationPrefs->StaggerWindowsOffset; NumToString(scratchlong, scratchPstring); SetTEText(dptr, PrefStaggerOffset, scratchPstring); } break; case PrefBlockCursor: SetCntrl(dptr, PrefBlockCursor, 1); SetCntrl(dptr, PrefUnderscoreCursor, 0); SetCntrl(dptr, PrefVerticalCursor, 0); break; case PrefUnderscoreCursor: SetCntrl(dptr, PrefBlockCursor, 0); SetCntrl(dptr, PrefUnderscoreCursor, 1); SetCntrl(dptr, PrefVerticalCursor, 0); break; case PrefVerticalCursor: SetCntrl(dptr, PrefBlockCursor, 0); SetCntrl(dptr, PrefUnderscoreCursor, 0); SetCntrl(dptr, PrefVerticalCursor, 1); break; case PrefCaptCreat: GetApplicationType(&newtype); scratchPstring[0] = 4; BlockMove(&newtype, &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, PrefCaptTE, scratchPstring); break; case PrefAnsiColor: AnsiPrompt(1, &defaultBoldColor); break; default: break; } /* switch */ } if (ditem==DLOGCancel) { DisposeDialog( dptr); ResetMenus(); return; } gApplicationPrefs->defaultBoldColor = defaultBoldColor; GetTEText(dptr, PrefCTt, scratchPstring); StringToNum(scratchPstring, &scratchlong); gApplicationPrefs->CopyTableThresh = (short) scratchlong; GetTEText(dptr, PrefTimeSlice, scratchPstring); StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 100, 2); gApplicationPrefs->TimeSlice = scratchlong; GetTEText(dptr,PrefOpenTime, scratchPstring); StringToNum(scratchPstring, &scratchlong); gApplicationPrefs->OpenTimeout = (short) scratchlong; GetTEText(dptr,PrefSendTime, scratchPstring); StringToNum(scratchPstring, &scratchlong); gApplicationPrefs->SendTimeout = (short) scratchlong; GetTEText(dptr, PrefCaptTE, scratchPstring); BlockMove(&scratchPstring[1], &(gApplicationPrefs->CaptureFileCreator), sizeof(OSType)); GetTEText(dptr,PrefStaggerOffset, scratchPstring); StringToNum(scratchPstring, &scratchlong); gApplicationPrefs->StaggerWindowsOffset = (short) scratchlong; gApplicationPrefs->CommandKeys = GetCntlVal(dptr, PrefCMDkey); gApplicationPrefs->WindowsDontGoAway = GetCntlVal(dptr, PrefDClose); gApplicationPrefs->RemapTilde = GetCntlVal(dptr, PrefTMap); gApplicationPrefs->StaggerWindows = GetCntlVal(dptr, PrefStag); gApplicationPrefs->BlinkCursor = GetCntlVal(dptr, PrefBlink); gApplicationPrefs->KeyPadAndFuncMenus = GetCntlVal(dptr, PrefKeyFuncMenus); gApplicationPrefs->NotifyUser = GetCntlVal(dptr,PrefNotifyUser); gApplicationPrefs->destroyKTickets = GetCntlVal(dptr,PrefDestroyTickets); gApplicationPrefs->autoOpenDialog = GetCntlVal(dptr,30); gApplicationPrefs->dontWarnOnQuit = GetCntlVal(dptr,31); gApplicationPrefs->autoOpenDefault = GetCntlVal(dptr,32); gApplicationPrefs->parseAliases = GetCntlVal(dptr,33); gApplicationPrefs->monospacedOut = GetCntlVal(dptr,34); gApplicationPrefs->clipTrailingSpaces = GetCntlVal(dptr,36); gApplicationPrefs->globalSavePass = GetCntlVal(dptr,37); gApplicationPrefs->noLiveScrolling = !GetCntlVal(dptr,38); gApplicationPrefs->CursorType = (GetCntlVal(dptr, PrefUnderscoreCursor) == 1) + (2 * (GetCntlVal(dptr, PrefVerticalCursor) == 1)); if (TelInfo->haveColorQuickDraw) { RSUpdatePalette(); //reflects any ANSI change UseResFile(TelInfo->SettingsFile); toSave = (PaletteHandle) Get1Resource('pltt', 10001); if (toSave == NULL)//this shouldnt happen; make a new copy { UseResFile(TelInfo->ApplicationFile); toSave = (PaletteHandle)GetNewPalette(9999); UseResFile(TelInfo->SettingsFile); AddResource((Handle)toSave, 'pltt', 10001, "\pANSI Colors");//make the new resource UpdateResFile(TelInfo->SettingsFile); } CopyPalette(TelInfo->AnsiColors,toSave,0,0,16); ChangedResource((Handle)toSave); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)toSave); } switchMenus(gApplicationPrefs->CommandKeys, 1); AdjustMenus(); DoTheMenuChecks(); SaveAppPreferences(); DisposeDialog( dptr); ResetMenus(); } void Cftp(void) { DialogPtr dptr; short ditem; Str255 scratchPstring; OSType scratchOSType; SFReply sfr; FInfo fi; Point where = {100,100}; dptr = GetNewMySmallStrangeDialog( FTPDLOG, NULL, kInFront, (void *)ThirdCenterDialog); SetCntrl(dptr, FTPServerOff, (gFTPServerPrefs->ServerState == 0)); SetCntrl(dptr, FTPServerUnsecure, (gFTPServerPrefs->ServerState == 1)); SetCntrl(dptr, FTPServerPswdPlease, (gFTPServerPrefs->ServerState == 2)); SetCntrl(dptr, FTPShowFTPlog, gFTPServerPrefs->ShowFTPlog); SetCntrl(dptr, FTPrevDNS, gFTPServerPrefs->DNSlookupconnections); SetCntrl(dptr, FTPUseMacBinaryII, gFTPServerPrefs->UseMacBinaryII); SetCntrl(dptr, FTPResetMacBinary, gFTPServerPrefs->ResetMacBinary); SetCntrl(dptr, FTPISO, gFTPServerPrefs->DoISOtranslation); HideDialogItem(dptr, FTPrevDNS); // Sometime later, perhaps. scratchPstring[0] = 4; BlockMove(&(gFTPServerPrefs->BinaryCreator), &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, FTPbincreatTE, scratchPstring); BlockMove(&(gFTPServerPrefs->BinaryType), &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, FTPbintypeTE, scratchPstring); SelectDialogItemText(dptr, FTPbintypeTE, 0, 32767); BlockMove(&(gFTPServerPrefs->TextCreator), &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, FTPtextcreatTE, scratchPstring); ShowWindow(dptr); ditem=0; /* initially no hits */ while((ditem>2) || (ditem==0)) { ModalDialog(DLOGwOK_CancelUPP,&ditem); switch(ditem) { case FTPShowFTPlog: case FTPrevDNS: case FTPUseMacBinaryII: case FTPResetMacBinary: case FTPISO: FlipCheckBox( dptr, ditem); break; case FTPServerOff: SetCntrl(dptr, FTPServerOff, 1); SetCntrl(dptr, FTPServerUnsecure, 0); SetCntrl(dptr, FTPServerPswdPlease, 0); break; case FTPServerUnsecure: SetCntrl(dptr, FTPServerOff, 0); SetCntrl(dptr, FTPServerUnsecure, 1); SetCntrl(dptr, FTPServerPswdPlease, 0); break; case FTPServerPswdPlease: SetCntrl(dptr, FTPServerOff, 0); SetCntrl(dptr, FTPServerUnsecure, 0); SetCntrl(dptr, FTPServerPswdPlease, 1); break; case FTPtextcreatorbutton: if (GetApplicationType(&scratchOSType)) { BlockMove(&scratchOSType, &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, FTPtextcreatTE, scratchPstring); } break; case FTPbinexamplebutton: SFGetFile(where, NULL, NULL, -1, NULL, NULL, &sfr); if (sfr.good) { GetFInfo(sfr.fName, sfr.vRefNum, &fi); scratchPstring[0] = sizeof(OSType); BlockMove(&fi.fdCreator, &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, FTPbincreatTE, scratchPstring); BlockMove(&fi.fdType, &scratchPstring[1], sizeof(OSType)); SetTEText(dptr, FTPbintypeTE, scratchPstring); } break; default: break; } /* switch */ } /* while */ if (ditem==DLOGCancel) { DisposeDialog( dptr); return; } gFTPServerPrefs->ServerState = GetCntlVal(dptr, FTPServerUnsecure) + GetCntlVal(dptr, FTPServerPswdPlease) * 2; StartUpFTP(); // Make sure FTP server recognizes new mode. gFTPServerPrefs->ShowFTPlog = GetCntlVal(dptr, FTPShowFTPlog); gFTPServerPrefs->DNSlookupconnections = GetCntlVal(dptr, FTPrevDNS); gFTPServerPrefs->UseMacBinaryII = GetCntlVal(dptr, FTPUseMacBinaryII); gFTPServerPrefs->ResetMacBinary = GetCntlVal(dptr, FTPResetMacBinary); gFTPServerPrefs->DoISOtranslation = GetCntlVal(dptr, FTPISO); GetTEText(dptr, FTPbincreatTE, scratchPstring); BlockMove(&scratchPstring[1], &(gFTPServerPrefs->BinaryCreator), sizeof(OSType)); GetTEText(dptr, FTPbintypeTE, scratchPstring); BlockMove(&scratchPstring[1], &(gFTPServerPrefs->BinaryType), sizeof(OSType)); GetTEText(dptr, FTPtextcreatTE, scratchPstring); BlockMove(&scratchPstring[1], &(gFTPServerPrefs->TextCreator), sizeof(OSType)); SaveFTPPreferences(); DisposeDialog( dptr); ResetMenus(); } Boolean GetApplicationType(OSType *type) { SFTypeList types; SFReply sfr; FInfo fi; Point where; SetPt(&where, 100, 100); types[0] = 'APPL'; SFGetFile(where, NULL, NULL, 1, types, NULL, &sfr); if (sfr.good) { GetFInfo(sfr.fName, sfr.vRefNum, &fi); BlockMove(&fi.fdCreator, type, sizeof(OSType)); // Copy the application creator type } return(sfr.good); } // Our standard modal dialog filter with code for handling user items containing lists. SIMPLE_UPP(MyDlogWListFilter, ModalFilter); pascal short MyDlogWListFilter( DialogPtr dptr, EventRecord *evt, short *item) { short key, iType; Handle iHndl; Rect iRect; Point scratchPoint; Cell tempCell; static unsigned long lastTime = 0; static char shortcut[] = {0,0,0,0,0,0,0,0,0,0,0}; SetPort(dptr); if ((evt->what == keyDown)||(evt->what == autoKey)) { key = evt->message & charCodeMask; //keyCode = (evt->message >>8) & 0xff ; if ((key == 0x0d) || (key == 0x03)) { // 0x0d == return, 0x03 == enter // RAB BetterTelnet 1.2 - we let StdFilterProc handle this // *item = 1; // ok // FlashButton(dptr, 1); // return(-1); return CallStdFilterProc(dptr, evt, item); } else if (evt->modifiers & cmdKey) { switch(evt->message & charCodeMask) { case 'e': *item = kChange; break; case 'r': *item = kRemove; break; case 'n': *item = kNew; break; case 'd': *item = kDuplicate; break; default: return(FALSE); break; } FlashButton(dptr, *item); return (-1); } else // a normal key { char keyCode = (evt->message & keyCodeMask) >> 8; if (keyCode >=0x7B) //CCP: arrow keys { tempCell.h = tempCell.v = 0; switch(keyCode) { case 0x7E: //up case 0x7B: //left if (LGetSelect(TRUE,&tempCell,currentList)) { LSetSelect(FALSE,tempCell,currentList);//unselect it tempCell.v--; } else tempCell.v = 0; break; case 0x7D: //down case 0x7C: //right if (LGetSelect(TRUE,&tempCell,currentList)) { LSetSelect(FALSE,tempCell,currentList);//unselect it tempCell.v++; } else tempCell.v = (**currentList).dataBounds.bottom - 1; break; default: return (FALSE); break; } if (tempCell.v > (**currentList).dataBounds.bottom - 1) tempCell.v = (**currentList).dataBounds.bottom - 1; if (tempCell.v < 0) tempCell.v = 0; LSetSelect(TRUE,tempCell,currentList);//select it LAutoScroll(currentList); Hilite(dptr, kRemove, 0); Hilite(dptr, kChange, 0); return(FALSE); } else //CCP go to right list item based on keystroke { if ((TickCount() - lastTime) > GetCaretTime() ) shortcut[0] = 0; lastTime = TickCount(); shortcut[(shortcut[0]++) +1] = key; tempCell.h = tempCell.v = 0; if (LGetSelect(TRUE,&tempCell,currentList)) LSetSelect(FALSE,tempCell,currentList); tempCell.v = findClosestNodeIndex(currentHead,(StringPtr)shortcut); LSetSelect(TRUE,tempCell,currentList); LAutoScroll(currentList); if (shortcut[0] == 10) shortcut[0] = 0; Hilite(dptr, kRemove, 0); Hilite(dptr, kChange, 0); } } } else if (evt->what == updateEvt) { if ((WindowPtr)evt->message == dptr) { // RAB BetterTelnet 1.2 - we let StdFilterProc handle this // GetDialogItem(dptr,1,&iType,&iHndl,&iRect); // ok // PenSize(3,3); // InsetRect(&iRect,-4,-4); // FrameRoundRect(&iRect,16,16); CallStdFilterProc(dptr, evt, item); return 0; } } else if (evt->what == mouseDown) { GetDialogItem(dptr, kItemList, &iType, &iHndl, &iRect); scratchPoint = evt->where; GlobalToLocal(&scratchPoint); if (PtInRect(scratchPoint, &iRect)) { *item = kItemList; if (LClick(scratchPoint, evt->modifiers, (ListHandle)GetWRefCon(dptr))) { *item = kChange; FlashButton(dptr, kChange); } return(-1); } } return CallStdFilterProc(dptr, evt, item); } Boolean isACopy(Str255 theName) { Boolean yes=FALSE; char copyString[] = "copy"; p2cstr(theName); if (strstr((char *)theName,copyString)) yes = TRUE; c2pstr((char *)theName); return(yes); } // User Dialog Item Procedure for a list. Assumes the Dialog's refcon contains the list // handle. SIMPLE_UPP(listDitemproc, UserItem); pascal void listDitemproc(DialogPtr theDlg, short itemNo) { short itemType; Handle ControlHndl; Rect scratchRect; GetDialogItem(theDlg, itemNo, &itemType, &ControlHndl, &scratchRect); PenNormal(); InsetRect(&scratchRect, -1, -1); FrameRect(&scratchRect); LUpdate(theDlg->visRgn, (ListHandle)GetWRefCon(theDlg)); } void BoundsCheck(long *value, long high, long low) { if (*value > high) *value = high; if (*value < low) *value = low; } #define kSCListMods lNoNilHilite+lOnlyOne void EditConfigType(ResType ConfigResourceType, Boolean (*EditFunction)(StringPtr)) { DialogPtr dptr; Handle iHndl; short iType, length, ditem,numberofitems, index; Rect ListBox, ListBounds; Point cellSize, theCell; ListHandle thelist; Handle ItemResource; Str255 ItemName; LinkedListNode *theHead, *leader; SetUpMovableModalMenus(); dptr = GetNewMySmallDialog(kItemDLOG, NULL, kInFront, (void *)ThirdCenterDialog); SetDialogDefaultItem(dptr, 1); SetDialogTracksCursor(dptr, 1); ditem = 3; GetDialogItem(dptr, kItemList, &iType, &iHndl, &ListBox); SetDialogItem(dptr, kItemList, iType, (Handle)listDitemprocUPP, &ListBox); ListBox.right -= 15; // Make room for scrollbar SetRect(&ListBounds, 0,0,1,0); SetPt(&cellSize,(ListBox.right-ListBox.left),16); thelist = LNew(&ListBox, &ListBounds, cellSize, 0, (WindowPtr)dptr,0,0,0,1); (*(thelist))->listFlags = kSCListMods; currentList = thelist; SetWRefCon(dptr, (long)thelist); // So the Ditem proc can find the list UseResFile(TelInfo->SettingsFile); numberofitems = Count1Resources(ConfigResourceType); if (numberofitems) theHead = createSortedList(ConfigResourceType,numberofitems,"\p"); //now we have a sorted linked list of the names else theHead = NULL; leader = theHead; for(index = 1, theCell.v = 0, theCell.h = 0; index <= numberofitems;index++, theCell.v++) { LAddRow(1,-1, thelist); HLock((Handle)leader->name); LSetCell(*(leader->name) +1, (*leader->name)[0], theCell, thelist); HUnlock((Handle)leader->name); leader = leader->next; } theCell.v = 0; theCell.h = 0; if (numberofitems) LSetSelect(1, theCell, thelist); LSetDrawingMode(1, thelist); currentHead = theHead; //let dialog filter know about the list while (ditem > 1) { movableModalDialog(MyDlogWListFilterUPP, &ditem); switch(ditem) { case kRemove: SetPt(&theCell, 0, 0); if (LGetSelect(TRUE, &theCell, thelist)) { length = 254; LGetCell(ItemName+1, &length, theCell, thelist); ItemName[0] = (char)length; if (!(EqualString(ItemName, "\p", TRUE, FALSE))) { deleteItem(&theHead,ItemName);//delete it from the linked list LDelRow(1,theCell.v,thelist); theCell.v--; LSetSelect(TRUE,theCell,thelist); UseResFile(TelInfo->SettingsFile); ItemResource = Get1NamedResource(ConfigResourceType, ItemName); RemoveTaggedResource(ItemResource, ConfigResourceType, ItemName); ReleaseResource(ItemResource); UpdateResFile(TelInfo->SettingsFile); } } break; case kChange: SetPt(&theCell, 0, 0); if (LGetSelect(TRUE, &theCell, thelist)) { short newPosition; length = 254; LGetCell(ItemName+1, &length, theCell, thelist); ItemName[0] = (char)length; leader = findNode(theHead,ItemName); if ((*EditFunction)((StringPtr)&ItemName)) { if (!(EqualString(ItemName,*leader->name,TRUE,FALSE)))//new name { DisposeHandle((Handle)leader->name); leader->name = NewString(ItemName);//set the new name newPosition = reSortElement(&theHead,leader);//resort LDelRow(1,theCell.v,thelist);//delete the old row theCell.v = newPosition; LAddRow(1,newPosition,thelist); //add a new row LSetCell(&ItemName[1], ItemName[0],theCell, thelist);//write the name in LSetSelect(TRUE,theCell,thelist); } } } break; case kNew: ItemName[0] = 0; // Signal new shortcut if ((*EditFunction)((StringPtr)&ItemName)) { short whereAt = createNodeAndSort(&theHead, ItemName); if (LGetSelect(TRUE, &theCell, thelist)) LSetSelect(FALSE,theCell,thelist); //turn off old selection theCell.v = LAddRow(1, whereAt, thelist); LSetCell(ItemName+1, StrLength(ItemName), theCell, thelist); LSetSelect(TRUE,theCell,thelist); //turn on new selection } break; case kDuplicate: SetPt(&theCell, 0, 0); if (LGetSelect(TRUE, &theCell, thelist)) { Handle oldResource,newResource; unsigned char copyString[] = " copy"; short resourceID; short index; length = 254; LGetCell(ItemName+1, &length, theCell, thelist); LSetSelect(FALSE,theCell,thelist); ItemName[0] = (char)length; leader = findNode(theHead,ItemName); UseResFile(TelInfo->SettingsFile); oldResource = GetNamedResource(ConfigResourceType,ItemName); if (!isACopy(ItemName))//add the copy extension { ItemName[0] += 5; BlockMoveData(copyString, &(ItemName[ItemName[0]-4]),5); } getAUniqueName(theHead,ItemName); resourceID = UniqueID(ConfigResourceType); newResource = myNewHandle(GetHandleSize(oldResource)); BlockMoveData(*oldResource,*newResource,GetHandleSize(newResource)); AddResource((Handle)newResource, ConfigResourceType, resourceID, ItemName); UpdateResFile(TelInfo->SettingsFile); index = createNodeAndSort(¤tHead,ItemName); theCell.v = index; LAddRow(1,index,thelist); //add a new row LSetCell(&ItemName[1], ItemName[0],theCell, thelist);//write the name in LSetSelect(TRUE,theCell,thelist); ReleaseResource((Handle)newResource); ReleaseResource((Handle)oldResource); } break; default: break; } // switch SetPt(&theCell, 0, 0); if (LGetSelect(TRUE, &theCell, thelist)) { Hilite(dptr, kRemove, 0); Hilite(dptr, kChange, 0); } else { Hilite(dptr, kRemove, 255); Hilite(dptr, kChange, 255); } } // while LDispose(thelist); DisposeDialog(dptr); ResetMenus(); deleteList(&theHead); } void ZeroNumOnly(void) { short i; for(i=0; iwhat == keyDown) || (evt->what == autoKey)) { key = evt->message & charCodeMask; keyCode = (evt->message >>8) & 0xff; if ((key == 0x0d) || (key == 0x03)) { // 0x0d == return, 0x03 == enter // *item = DLOGOk; // return(-1); /* BYU LSC - pascal doesn't like "1" as true */ return CallStdFilterProc(dptr, evt, item); } if (((key == '.') && (evt->modifiers & cmdKey)) || ((key == 0x1b) && (keyCode == 0x35)) ) { // 0x35 == escKey // *item = DLOGCancel; // return(-1); /* BYU LSC - pascal doesn't like "1" as true */ return CallStdFilterProc(dptr, evt, item); } if ((key < '0' || key > '9') && !(key == 0x08 || key == 0x09 || (key > 0x1B && key < 0x20)) && InNumOnly(((DialogPeek)dptr)->editField + 1)) { /* Reject non-numbers for this TE */ *item = NumOnly[0]; /* Kludge -- Return "safe" item */ return(-1); } } if (evt->what == updateEvt) { if ((WindowPtr)evt->message == dptr) { // RAB BetterTelnet 1.2 - We let StdFilterProc handle this. // GetDialogItem(dptr,DLOGOk,&iType,&iHndl,&iRect); // ok // PenSize(3,3); // InsetRect(&iRect,-4,-4); // FrameRoundRect(&iRect,16,16); for (index = 0; index < NumberOfColorBoxes; index++) ColorBoxItemProc(dptr, BoxColorItems[index]); // update color boxes } CallStdFilterProc(dptr, evt, item); } Stask(); return CallStdFilterProc(dptr, evt, item); } SIMPLE_UPP(TerminalModalProc, ModalFilter); pascal short TerminalModalProc( DialogPtr dptr, EventRecord *evt, short *item) { if (evt->what == mouseDown) return(PopupMousedown(dptr, evt, item)); return(ColorBoxModalProc(dptr, evt, item)); } SIMPLE_UPP(SessionModalProc, ModalFilter); pascal short SessionModalProc(DialogPtr dptr, EventRecord *evt, short *item) { short key, tempLen, editField; // if ((evt->what == keyDown) || (evt->what == autoKey)) // if ((evt->message & charCodeMask) == ' ') { // *item = NumOnly[0]; /* Kludge -- Return "safe" item */ // return(-1); // } editField = ((DialogPeek)dptr)->editField + 1; if ((evt->what == keyDown) || (evt->what == autoKey)) if ((editField == 52) || (editField == 60)) { key = evt->message & charCodeMask; if (key == 8) { if (editField == 52) configPassword[0] = 0; else configPassword2[0] = 0; SetTEText(dptr, editField, "\p"); *item = 0; return -1; } if (key == 9) return 0; if (key < 32) { *item = 0; StdFilterProc(dptr, evt, item); return -1; } if (editField == 52) { tempLen = strlen(configPassword); if (tempLen < 250) { configPassword[tempLen] = key; configPassword[tempLen+1] = 0; } } else { tempLen = strlen(configPassword2); if (tempLen < 250) { configPassword2[tempLen] = key; configPassword2[tempLen+1] = 0; } } evt->message = (evt->message & 0xFFFFFF00) + ''; return 0; } return(TerminalModalProc(dptr, evt, item)); } void ShowTermPanel(DialogPtr dptr, short panel) { switch (panel) { case 1: ShowDialogItemRange(dptr, 11, 16); ShowDialogItemRange(dptr, 22, 23); ShowDialogItemRange(dptr, 25, 27); ShowDialogItemRange(dptr, 30, 31); ShowDialogItemRange(dptr, 33, 34); ShowDialogItemRange(dptr, 48, 49); break; case 2: ShowDialogItemRange(dptr, 28, 29); ShowDialogItem(dptr, 32); ShowDialogItemRange(dptr, 35, 39); break; case 3: ShowDialogItemRange(dptr, 19, 21); ShowDialogItemRange(dptr, 40, 44); DrawPopUp(dptr, 20); DrawPopUp(dptr, 43); ShowDialogItem(dptr, 47); break; case 4: ShowDialogItemRange(dptr, 3, 10); ShowDialogItem(dptr, 24); ShowDialogItem(dptr, 50); break; } } void HideTermPanel(DialogPtr dptr, short panel) { switch (panel) { case 1: HideDialogItemRange(dptr, 11, 16); HideDialogItemRange(dptr, 22, 23); HideDialogItemRange(dptr, 25, 27); HideDialogItemRange(dptr, 30, 31); HideDialogItemRange(dptr, 33, 34); HideDialogItemRange(dptr, 48, 49); break; case 2: HideDialogItemRange(dptr, 28, 29); HideDialogItem(dptr, 32); HideDialogItemRange(dptr, 35, 39); break; case 3: DrawBlank(dptr, 20); DrawBlank(dptr, 43); HideDialogItemRange(dptr, 19, 21); HideDialogItemRange(dptr, 40, 44); HideDialogItem(dptr, 47); break; case 4: HideDialogItemRange(dptr, 3, 10); HideDialogItem(dptr, 24); HideDialogItem(dptr, 50); break; } } Boolean EditTerminal(StringPtr PrefRecordNamePtr) { DialogPtr dptr; short ditem, scratchshort, resourceID, i, currentPanel, newPanel; long scratchlong; ResType scratchResType; Boolean IsNewPrefRecord, UserLikesNewColor,wasInAliasText; TerminalPrefs** TermPrefsHdl; TerminalPrefs* TermPrefsPtr; Str255 scratchPstring; RGBColor scratchRGBcolor; Point ColorBoxPoint; MenuHandle WeNeedAFontMenuHandle, WeNeedAnotherFontMenuHandle; popup TPopup[] = {{TermFontPopup, (MenuHandle) 0, 1}, {43, (MenuHandle) 0, 1}, {0, (MenuHandle) 0, 0}}; dptr = GetNewMySmallStrangeDialog(TermDLOG, NULL, kInFront, (void *)ThirdCenterDialog); ditem = 3; SetDialogDefaultItem(dptr, 1); SetDialogCancelItem(dptr, 2); SetDialogTracksCursor(dptr, 1); currentPanel = TelInfo->lastPanelTerminal + 1; SetCntrl(dptr, 46, currentPanel); HideTermPanel(dptr, 1); HideTermPanel(dptr, 2); HideTermPanel(dptr, 3); HideTermPanel(dptr, 4); ShowTermPanel(dptr, currentPanel); WeNeedAFontMenuHandle = NewMenu(666, "\p"); //get the fonts from the font menu in the menu bar scratchshort = CountMItems(myMenus[Font]); for (i = 1; i <= scratchshort; i++) { GetMenuItemText(myMenus[Font],i,scratchPstring); AppendMenu(WeNeedAFontMenuHandle,scratchPstring); } TPopup[0].h = WeNeedAFontMenuHandle; WeNeedAnotherFontMenuHandle = NewMenu(667, "\p"); //get the fonts from the font menu in the menu bar scratchshort = CountMItems(myMenus[Font]); for (i = 1; i <= scratchshort; i++) { GetMenuItemText(myMenus[Font],i,scratchPstring); AppendMenu(WeNeedAnotherFontMenuHandle,scratchPstring); } TPopup[1].h = WeNeedAnotherFontMenuHandle; PopupInit(dptr, TPopup); if (PrefRecordNamePtr[0] != 0) { IsNewPrefRecord = FALSE; UseResFile(TelInfo->SettingsFile); TermPrefsHdl = (TerminalPrefs **)Get1NamedSizedResource(TERMINALPREFS_RESTYPE, PrefRecordNamePtr, sizeof(TerminalPrefs)); if (EqualString(PrefRecordNamePtr, "\p", FALSE, FALSE)) { HideDialogItem(dptr, TermNameStatText); HideDialogItem(dptr, TermName); } } else { //make sure we have a unique name TermPrefsHdl = GetDefaultTerminal(); IsNewPrefRecord = TRUE; GetIndString(PrefRecordNamePtr, MISC_STRINGS, MISC_NEWTERM); getAUniqueName(currentHead,PrefRecordNamePtr); } HLock((Handle) TermPrefsHdl); TermPrefsPtr = *TermPrefsHdl; SetTEText(dptr, TermName, PrefRecordNamePtr); SetCntrl(dptr, TermANSI, TermPrefsPtr->ANSIgraphics); SetCntrl(dptr, TermXterm, TermPrefsPtr->Xtermsequences); SetCntrl(dptr, 39, TermPrefsPtr->remapCtrlD); SetCntrl(dptr, 40, TermPrefsPtr->allowBold); SetCntrl(dptr, 41, TermPrefsPtr->colorBold); SetCntrl(dptr, 44, TermPrefsPtr->boldFontStyle); SetCntrl(dptr, 47, TermPrefsPtr->realbold); SetCntrl(dptr, 48, TermPrefsPtr->oldScrollback); SetCntrl(dptr, 49, TermPrefsPtr->jumpScroll); SetCntrl(dptr, Termvtwrap, TermPrefsPtr->vtwrap); // SetCntrl(dptr, Termmeta, TermPrefsPtr->emacsmetakey); SetCntrl(dptr, TermMetaIsCmdCntrol, (TermPrefsPtr->emacsmetakey == 1)); SetCntrl(dptr, TermMetaIsOption, (TermPrefsPtr->emacsmetakey == 2)); SetCntrl(dptr, TermMetaIsOff, (TermPrefsPtr->emacsmetakey == 0)); SetCntrl(dptr, Termarrow, TermPrefsPtr->emacsarrows); SetCntrl(dptr, TermMAT, TermPrefsPtr->MATmappings); SetCntrl(dptr, Termeightbit, TermPrefsPtr->eightbit); SetCntrl(dptr, Termclearsave, TermPrefsPtr->clearsave); SetCntrl(dptr, TermVT100, (TermPrefsPtr->vtemulation == 0)); SetCntrl(dptr, TermVT220, (TermPrefsPtr->vtemulation == 1)); SetCntrl(dptr, TermRemapKeypad, TermPrefsPtr->remapKeypad); SetCntrl(dptr, 50, TermPrefsPtr->realBlink); scratchlong = (long)(TermPrefsPtr->vtwidth); NumToString(scratchlong, scratchPstring); SetTEText(dptr, TermWidth, scratchPstring); scratchlong = (short)(TermPrefsPtr->vtheight); NumToString(scratchlong, scratchPstring); SetTEText(dptr, TermHeight, scratchPstring); scratchlong = TermPrefsPtr->fontsize; NumToString(scratchlong, scratchPstring); SetTEText(dptr, TermFontSize, scratchPstring); scratchlong = TermPrefsPtr->numbkscroll; NumToString(scratchlong, scratchPstring); SetTEText(dptr, TermScrollback, scratchPstring); SetTEText(dptr, TermAnswerback, TermPrefsPtr->AnswerBackMessage); for(scratchshort = CountMItems(TPopup[0].h); scratchshort; scratchshort--) { GetMenuItemText(TPopup[0].h, scratchshort, scratchPstring); if (EqualString(scratchPstring, (TermPrefsPtr->DisplayFont), TRUE, FALSE)) TPopup[0].choice = scratchshort; } for(scratchshort = CountMItems(TPopup[1].h); scratchshort; scratchshort--) { GetMenuItemText(TPopup[1].h, scratchshort, scratchPstring); if (EqualString(scratchPstring, (TermPrefsPtr->BoldFont), TRUE, FALSE)) TPopup[1].choice = scratchshort; } ZeroNumOnly(); NumOnly[0] = TermSafeItem; NumOnly[1] = TermWidth; NumOnly[2] = TermHeight; NumOnly[3] = TermFontSize; NumOnly[4] = TermScrollback; NumOnly[5] = 0; // if (TermPrefsPtr->vtemulation != 1) // { // HideDialogItem(dptr,TermRemapKeypad); // HideDialogItem(dptr,TermMAT); // } if (TelInfo->haveColorQuickDraw) { for (scratchshort = 0, NumberOfColorBoxes = 4; scratchshort < NumberOfColorBoxes; scratchshort++) { BoxColorItems[scratchshort] = TermNFcolor + scratchshort; BlockMove(&(TermPrefsPtr->nfcolor) + scratchshort, &BoxColorData[scratchshort], sizeof(RGBColor)); UItemAssign( dptr, TermNFcolor + scratchshort, ColorBoxItemProcUPP); } } else NumberOfColorBoxes = 0; // B&W machine ColorBoxPoint.h = 0; // Have the color picker center the box on the main ColorBoxPoint.v = 0; // screen SelectDialogItemText(dptr, TermName, 0, 32767); ShowWindow(dptr); wasInAliasText = FALSE; while (ditem > 2) { movableModalDialog(TerminalModalProcUPP, &ditem); if ((wasInAliasText)&&(ditem != TermName)) { wasInAliasText = FALSE; GetTEText(dptr, TermName,scratchPstring); if (EqualString(scratchPstring,PrefRecordNamePtr,FALSE,FALSE)) goto okayTermName; if (scratchPstring[0] == 0) { DialogPtr alertUser; short alertDItem = 3; alertUser = GetNewMyDialog(kBadPrefNameDLOG, NULL, kInFront, (void *)ThirdCenterDialog); while (alertDItem > 1) { ModalDialog(DLOGwOK_CancelUPP,&alertDItem); DisposeDialog(alertUser); } SetPort(dptr); //back to old dialog SetTEText(dptr,TermName,PrefRecordNamePtr);//set the string back to the original SelectDialogItemText(dptr,TermName,0,32767); ditem = TermName; //so that if they hit ok or cancel, it doesn't kill the window } else if(findNodeNC(currentHead,scratchPstring)) //we already have that name { DialogPtr alertUser; short alertDItem = 3; alertUser = GetNewMyDialog(kBadPrefNameDLOG, NULL, kInFront, (void *)ThirdCenterDialog); while (alertDItem > 1) { ModalDialog(DLOGwOK_CancelUPP,&alertDItem); DisposeDialog(alertUser); } SetPort(dptr); //back to old dialog SetTEText(dptr,TermName,PrefRecordNamePtr);//set the string back to the original SelectDialogItemText(dptr,TermName,0,32767); ditem = TermName; //so that if they hit ok or cancel, it doesn't kill the window } else goto okayTermName; } else { okayTermName: switch (ditem) { case TermANSI: case TermXterm: case 39: case 40: case 41: case 44: case 47: case 48: case 49: case 50: case Termvtwrap: case Termarrow: case TermMAT: case Termeightbit: case Termclearsave: case TermRemapKeypad: FlipCheckBox(dptr, ditem); break; case TermVT100: SetCntrl(dptr, TermVT100, 1); SetCntrl(dptr, TermVT220, 0); SetTEText(dptr, TermAnswerback, "\pVT100"); //HideDialogItem(dptr,TermRemapKeypad); //HideDialogItem(dptr,TermMAT); break; case TermVT220: SetCntrl(dptr, TermVT100, 0); SetCntrl(dptr, TermVT220, 1); SetTEText(dptr, TermAnswerback, "\pVT220"); //ShowDialogItem(dptr,TermRemapKeypad); //ShowDialogItem(dptr,TermMAT); break; case TermMetaIsCmdCntrol: SetCntrl(dptr, TermMetaIsOption, 0); SetCntrl(dptr, TermMetaIsOff, 0); SetCntrl(dptr, TermMetaIsCmdCntrol, 1); break; case TermMetaIsOption: SetCntrl(dptr, TermMetaIsOff, 0); SetCntrl(dptr, TermMetaIsCmdCntrol, 0); SetCntrl(dptr, TermMetaIsOption, 1); break; case TermMetaIsOff: SetCntrl(dptr, TermMetaIsCmdCntrol, 0); SetCntrl(dptr, TermMetaIsOption, 0); SetCntrl(dptr, TermMetaIsOff, 1); break; case TermNFcolor: case TermNBcolor: case TermBFcolor: case TermBBcolor: if (TelInfo->haveColorQuickDraw) { Str255 askColorString; GetIndString(askColorString,MISC_STRINGS,PICK_NEW_COLOR_STRING); UserLikesNewColor = GetColor(ColorBoxPoint, askColorString, &BoxColorData[ditem-TermNFcolor], &scratchRGBcolor); if (UserLikesNewColor) BoxColorData[ditem-TermNFcolor] = scratchRGBcolor; } break; case 46: // switch tabs newPanel = GetCntlVal(dptr, 46); if (newPanel == currentPanel) break; HideTermPanel(dptr, currentPanel); ShowTermPanel(dptr, newPanel); currentPanel = newPanel; break; case TermName: wasInAliasText = TRUE; default: break; } // switch }//else not wasInAliasText } // while GetMenuItemText(TPopup[1].h, TPopup[1].choice, scratchPstring); if (StrLength(scratchPstring) > 63) scratchPstring[0] = 63; BlockMove(scratchPstring, (TermPrefsPtr->BoldFont), scratchPstring[0]+1); GetMenuItemText(TPopup[0].h, TPopup[0].choice, scratchPstring); PopupCleanup(); if (ditem == 2) { if (IsNewPrefRecord) DisposeHandle((Handle) TermPrefsHdl); else ReleaseResource((Handle) TermPrefsHdl); TelInfo->lastPanelTerminal = currentPanel - 1; DisposeDialog(dptr); return(FALSE); // No changes should be made. } if (TelInfo->haveColorQuickDraw) { for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) { BlockMove(&BoxColorData[scratchshort], &(TermPrefsPtr->nfcolor) + scratchshort, sizeof(RGBColor)); } } if (StrLength(scratchPstring) > 63) scratchPstring[0] = 63; BlockMove(scratchPstring, (TermPrefsPtr->DisplayFont), scratchPstring[0]+1); TermPrefsPtr->ANSIgraphics = GetCntlVal(dptr, TermANSI); TermPrefsPtr->Xtermsequences = GetCntlVal(dptr, TermXterm); TermPrefsPtr->remapCtrlD = GetCntlVal(dptr, 39); TermPrefsPtr->allowBold = GetCntlVal(dptr, 40); TermPrefsPtr->colorBold = GetCntlVal(dptr, 41); TermPrefsPtr->realbold = GetCntlVal(dptr, 47); TermPrefsPtr->oldScrollback = GetCntlVal(dptr, 48); TermPrefsPtr->jumpScroll = GetCntlVal(dptr, 49); TermPrefsPtr->boldFontStyle = GetCntlVal(dptr, 44); TermPrefsPtr->realBlink = GetCntlVal(dptr, 50); TermPrefsPtr->vtwrap = GetCntlVal(dptr, Termvtwrap); if (GetCntlVal(dptr, TermMetaIsCmdCntrol)) TermPrefsPtr->emacsmetakey = 1; else if (GetCntlVal(dptr, TermMetaIsOption)) TermPrefsPtr->emacsmetakey = 2; else TermPrefsPtr->emacsmetakey = 0; TermPrefsPtr->emacsarrows = GetCntlVal(dptr, Termarrow); TermPrefsPtr->MATmappings = GetCntlVal(dptr, TermMAT); TermPrefsPtr->eightbit = GetCntlVal(dptr, Termeightbit); TermPrefsPtr->clearsave = GetCntlVal(dptr, Termclearsave); TermPrefsPtr->remapKeypad = GetCntlVal(dptr, TermRemapKeypad); TermPrefsPtr->vtemulation = (GetCntlVal(dptr, TermVT220) != 0); GetTEText(dptr, TermWidth, scratchPstring); StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 133, 10); TermPrefsPtr->vtwidth = (short) scratchlong; GetTEText(dptr, TermHeight, scratchPstring); StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 80, 10); TermPrefsPtr->vtheight = (short) scratchlong; GetTEText(dptr, TermFontSize, scratchPstring); StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 24, 4); TermPrefsPtr->fontsize = (short) scratchlong; GetTEText(dptr, TermScrollback, scratchPstring); StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 50000, 24); TermPrefsPtr->numbkscroll = (short) scratchlong; GetTEText(dptr, TermAnswerback, scratchPstring); if (StrLength(scratchPstring) > 63) scratchPstring[0] = 63; BlockMove(scratchPstring, TermPrefsPtr->AnswerBackMessage, scratchPstring[0]+1); GetTEText(dptr, TermName, PrefRecordNamePtr); if (IsNewPrefRecord) { UseResFile(TelInfo->SettingsFile); resourceID = UniqueID(TERMINALPREFS_RESTYPE); AddResource((Handle)TermPrefsHdl, TERMINALPREFS_RESTYPE, resourceID, PrefRecordNamePtr); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)TermPrefsHdl); } else { UseResFile(TelInfo->SettingsFile); GetResInfo((Handle)TermPrefsHdl, &resourceID, &scratchResType,(StringPtr) &scratchPstring); SetResInfo((Handle)TermPrefsHdl, resourceID, PrefRecordNamePtr); ChangedResource((Handle)TermPrefsHdl); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)TermPrefsHdl); } TelInfo->lastPanelTerminal = currentPanel - 1; DisposeDialog(dptr); return(TRUE); // A resource has changed or been added. } void ShowSessPanel(DialogPtr dptr, short panel) { switch (panel) { case 1: ShowDialogItemRange(dptr, 19, 20); ShowDialogItemRange(dptr, 25, 27); ShowDialogItem(dptr, 29); ShowDialogItemRange(dptr, 36, 37); ShowDialogItemRange(dptr, 40, 41); DrawPopUp(dptr, 25); DrawPopUp(dptr, 26); ShowDialogItem(dptr, 73); break; case 2: ShowDialogItemRange(dptr, 6, 7); ShowDialogItemRange(dptr, 21, 24); ShowDialogItem(dptr, 12); ShowDialogItem(dptr, 14); ShowDialogItem(dptr, 17); ShowDialogItem(dptr, 31); ShowDialogItemRange(dptr, 33, 35); ShowDialogItemRange(dptr, 38, 39); break; case 3: ShowDialogItemRange(dptr, 3, 5); ShowDialogItemRange(dptr, 8, 11); ShowDialogItem(dptr, 13); ShowDialogItem(dptr, 30); ShowDialogItem(dptr, 32); ShowDialogItemRange(dptr, 42, 44); break; case 4: ShowDialogItemRange(dptr, 15, 16); ShowDialogItemRange(dptr, 54, 62); break; case 5: ShowDialogItemRange(dptr, 47, 53); break; case 6: ShowDialogItemRange(dptr, 63, 64); break; case 7: ShowDialogItemRange(dptr, 65, 72); break; } } void HideSessPanel(DialogPtr dptr, short panel) { switch (panel) { case 1: DrawBlank(dptr, 25); DrawBlank(dptr, 26); HideDialogItemRange(dptr, 19, 20); HideDialogItemRange(dptr, 25, 27); HideDialogItem(dptr, 29); HideDialogItemRange(dptr, 36, 37); HideDialogItemRange(dptr, 40, 41); HideDialogItem(dptr, 73); break; case 2: HideDialogItemRange(dptr, 6, 7); HideDialogItemRange(dptr, 21, 24); HideDialogItem(dptr, 12); HideDialogItem(dptr, 14); HideDialogItem(dptr, 17); HideDialogItem(dptr, 31); HideDialogItemRange(dptr, 33, 35); HideDialogItemRange(dptr, 38, 39); break; case 3: HideDialogItemRange(dptr, 3, 5); HideDialogItemRange(dptr, 8, 11); HideDialogItem(dptr, 13); HideDialogItem(dptr, 30); HideDialogItem(dptr, 32); HideDialogItemRange(dptr, 42, 44); break; case 4: HideDialogItemRange(dptr, 15, 16); HideDialogItemRange(dptr, 54, 62); break; case 5: HideDialogItemRange(dptr, 47, 53); break; case 6: HideDialogItemRange(dptr, 63, 64); break; case 7: HideDialogItemRange(dptr, 65, 72); } } Boolean EditSession(StringPtr PrefRecordNamePtr) { DialogPtr dptr; short ditem, scratchshort, resourceID, currentPanel, newPanel, i; short numberOfTerms; long scratchlong; ResType scratchResType; Boolean IsNewPrefRecord, wasInAliasText; SessionPrefs** SessPrefsHdl; SessionPrefs* SessPrefsPtr; TerminalPrefs** tempTermPrefsHdl; Str255 scratchPstring, scratchPstring2; LinkedListNode *savedList; EventRecord optKeyEvtRec; popup SPopup[] = {{SessTermPopup, (MenuHandle) 0, 1}, {SessTransTablePopup, (MenuHandle) 0, 1}, {0, (MenuHandle) 0, 0}}; dptr = GetNewMySmallStrangeDialog(SessionConfigDLOG, NULL, kInFront, (void *)ThirdCenterDialog); ditem = 3; SetDialogDefaultItem(dptr, 1); SetDialogCancelItem(dptr, 2); SetDialogTracksCursor(dptr, 1); currentPanel = TelInfo->lastPanelSession + 1; savedList = currentHead; //save the current list, so the list that got us here works SPopup[0].h = NewMenu(666, "\p"); UseResFile(TelInfo->SettingsFile); numberOfTerms = Count1Resources(TERMINALPREFS_RESTYPE); currentHead = createSortedList(TERMINALPREFS_RESTYPE,numberOfTerms,"\p"); addListToMenu(SPopup[0].h, currentHead, 1); EnableItem(SPopup[0].h, 0); // Make sure the entire menu is enabled deleteList(¤tHead); UseResFile(TelInfo->ApplicationFile); SPopup[1].h = NewMenu(667, "\p"); numberOfTerms = CountResources(USER_TRSL); currentHead = createSortedList2(USER_TRSL,numberOfTerms,NULL); GetIndString(scratchPstring,MISC_STRINGS,NONE_STRING); //"None" string AppendMenu(SPopup[1].h,scratchPstring); addListToMenu/*3*/(SPopup[1].h, currentHead, 2); EnableItem(SPopup[1].h, 0); // Make sure the entire menu is enabled deleteList(¤tHead); UseResFile(TelInfo->SettingsFile); currentHead = savedList; PopupInit(dptr, SPopup); if (PrefRecordNamePtr[0] != 0) { IsNewPrefRecord = FALSE; UseResFile(TelInfo->SettingsFile); SessPrefsHdl = (SessionPrefs **)Get1NamedSizedResource(SESSIONPREFS_RESTYPE, PrefRecordNamePtr, sizeof(SessionPrefs)); if (EqualString(PrefRecordNamePtr, "\p", FALSE, FALSE)) { HideDialogItem(dptr, SessAlias); HideDialogItem(dptr, SessAliasStatText); } } else { SessPrefsHdl = GetDefaultSession(); IsNewPrefRecord = TRUE; GetIndString(PrefRecordNamePtr, MISC_STRINGS, MISC_NEWSESSION); getAUniqueName(currentHead,PrefRecordNamePtr); } HLock((Handle) SessPrefsHdl); SessPrefsPtr = *SessPrefsHdl; SetCntrl(dptr, SessTEKinhib, (SessPrefsPtr->tektype == -1)); SetCntrl(dptr, SessTEK4014, (SessPrefsPtr->tektype == 0)); SetCntrl(dptr, SessTEK4105, (SessPrefsPtr->tektype == 1)); SetCntrl(dptr, SessPasteQuick, (SessPrefsPtr->pastemethod == 0)); SetCntrl(dptr, SessPasteBlock, (SessPrefsPtr->pastemethod == 1)); SetCntrl(dptr, SessDeleteDel, (SessPrefsPtr->bksp == 1)); SetCntrl(dptr, SessDeleteBS, (SessPrefsPtr->bksp == 0)); SetCntrl(dptr, SessForceSave, SessPrefsPtr->forcesave); SetCntrl(dptr, SessBezerkeley, SessPrefsPtr->crmap); SetCntrl(dptr, 42, SessPrefsPtr->alwaysBSD); SetCntrl(dptr, 43, SessPrefsPtr->ignoreBeeps); SetCntrl(dptr, 44, SessPrefsPtr->ignoreff); SetCntrl(dptr, SessLinemode, SessPrefsPtr->linemode); SetCntrl(dptr, SessTEKclear, SessPrefsPtr->tekclear); SetCntrl(dptr, SessHalfDuplex, SessPrefsPtr->halfdup); SetCntrl(dptr, SessAuthenticate, SessPrefsPtr->authenticate); SetCntrl(dptr, SessEncrypt, SessPrefsPtr->encrypt); SetCntrl(dptr, SessLocalEcho, SessPrefsPtr->localecho); SetCntrl(dptr, 47, SessPrefsPtr->otpauto); SetCntrl(dptr, 48, SessPrefsPtr->otpmulti); SetCntrl(dptr, 49, SessPrefsPtr->otphex); SetCntrl(dptr, 50, SessPrefsPtr->otpnoprompt); SetCntrl(dptr, 53, SessPrefsPtr->otpsavepass); SetCntrl(dptr, 54, SessPrefsPtr->protocol + 1); SetCntrl(dptr, 63, SessPrefsPtr->encryption + 1); SetCntrl(dptr, 65, SessPrefsPtr->usesocks); SetCntrl(dptr, 66, SessPrefsPtr->socks4a); configPassword[0] = 0; if (SessPrefsPtr->otppassword[0]) { pstrcpy((unsigned char *)configPassword, (unsigned char *)SessPrefsPtr->otppassword); p2cstr((unsigned char *)configPassword); for (i = 1; i < 250; i++) scratchPstring[i] = ''; scratchPstring[0] = strlen(configPassword); SetTEText(dptr, 52, scratchPstring); } configPassword2[0] = 0; if (SessPrefsPtr->password[0]) { pstrcpy((unsigned char *)configPassword2, (unsigned char *)SessPrefsPtr->password); p2cstr((unsigned char *)configPassword2); for (i = 1; i < 250; i++) scratchPstring[i] = ''; scratchPstring[0] = strlen(configPassword2); SetTEText(dptr, 60, scratchPstring); } SetTEText(dptr, SessHostName, SessPrefsPtr->hostname); SetTEText(dptr, SessAlias, PrefRecordNamePtr); SetTEText(dptr, 59, (unsigned char *)SessPrefsPtr->username); // SetTEText(dptr, 60, (unsigned char *)SessPrefsPtr->password); SetTEText(dptr, 61, (unsigned char *)SessPrefsPtr->clientuser); SetTEText(dptr, 62, (unsigned char *)SessPrefsPtr->command); SetTEText(dptr, 67, (unsigned char *)SessPrefsPtr->sockshost); SetTEText(dptr, 72, (unsigned char *)SessPrefsPtr->socksusername); if (SessPrefsPtr->portNegative) { NumToString((unsigned short)SessPrefsPtr->port, &scratchPstring[1]); scratchPstring[0] = scratchPstring[1] + 1; scratchPstring[1] = '-'; } else NumToString((unsigned short)SessPrefsPtr->port, scratchPstring); SetTEText(dptr, SessPort, scratchPstring); NumToString(SessPrefsPtr->pasteblocksize, scratchPstring); SetTEText(dptr, SessBlockSize, scratchPstring); if (!SessPrefsPtr->socksport) SessPrefsPtr->socksport = 1080; NumToString(SessPrefsPtr->socksport, scratchPstring); SetTEText(dptr, 68, scratchPstring); if (SessPrefsPtr->NetBlockSize <= 512) SessPrefsPtr->NetBlockSize = 512; NumToString(SessPrefsPtr->NetBlockSize, scratchPstring); SetTEText(dptr, SessBlockSizeTE, scratchPstring); scratchPstring[0] = 2; scratchPstring[1] = '^'; if (SessPrefsPtr->ckey != -1) { scratchPstring[2] = SessPrefsPtr->ckey ^ 64; SetTEText(dptr, SessInterrupt, scratchPstring); } if (SessPrefsPtr->skey != -1) { scratchPstring[2] = SessPrefsPtr->skey ^ 64; SetTEText(dptr, SessSuspend, scratchPstring); } if (SessPrefsPtr->qkey != -1) { scratchPstring[2] = SessPrefsPtr->qkey ^ 64; SetTEText(dptr, SessResume, scratchPstring); } for(scratchshort = CountMItems(SPopup[0].h); scratchshort; scratchshort--) { GetMenuItemText(SPopup[0].h, scratchshort, scratchPstring); if (EqualString(scratchPstring, (SessPrefsPtr->TerminalEmulation), TRUE, FALSE)) SPopup[0].choice = scratchshort; } for(scratchshort = CountMItems(SPopup[1].h); scratchshort; scratchshort--) { GetMenuItemText(SPopup[1].h, scratchshort, scratchPstring); if (EqualString(scratchPstring, (SessPrefsPtr->TranslationTable), TRUE, FALSE)) SPopup[1].choice = scratchshort; } NumberOfColorBoxes = 0; ZeroNumOnly(); NumOnly[0] = SessSafeItem; NumOnly[1] = SessBlockSize; SetCntrl(dptr, 46, currentPanel); for (i = 1; i < 8; i++) HideSessPanel(dptr, i); ShowSessPanel(dptr, currentPanel); SelectDialogItemText(dptr, SessAlias, 0, 32767); ShowWindow(dptr); wasInAliasText = FALSE; while ((ditem > 2) || (ditem == 0)) { movableModalDialog(SessionModalProcUPP, &ditem); if (ditem == 0) continue; if ((wasInAliasText)&&(ditem != SessAlias)) { wasInAliasText = FALSE; GetTEText(dptr, SessAlias, scratchPstring); if (EqualString(scratchPstring,PrefRecordNamePtr,FALSE,FALSE)) goto okaySessName; if (scratchPstring[0] == 0) { DialogPtr alertUser; short alertDItem = 3; alertUser = GetNewMyDialog(kBadPrefNameDLOG, NULL, kInFront, (void *)ThirdCenterDialog); while (alertDItem > 1) { ModalDialog(DLOGwOK_CancelUPP,&alertDItem); DisposeDialog(alertUser); } SetPort(dptr); //back to old dialog SetTEText(dptr,SessAlias,PrefRecordNamePtr);//set the string back to the original SelectDialogItemText(dptr,SessAlias,0,32767); ditem = SessAlias; //so that if they hit ok or cancel, it doesn't kill the window } else if(findNodeNC(currentHead,scratchPstring)) //we already have that name { DialogPtr alertUser; short alertDItem = 3; alertUser = GetNewMyDialog(kBadPrefNameDLOG, NULL, kInFront, (void *)ThirdCenterDialog); while (alertDItem > 1) { ModalDialog(DLOGwOK_CancelUPP,&alertDItem); DisposeDialog(alertUser); } SetPort(dptr); //back to old dialog SetTEText(dptr,SessAlias,PrefRecordNamePtr);//set the string back to the original SelectDialogItemText(dptr,SessAlias,0,32767); ditem = SessAlias; //so that if they hit ok or cancel, it doesn't kill the window } else goto okaySessName; } else { okaySessName: switch (ditem) { case SessForceSave: case SessBezerkeley: case SessLinemode: case SessTEKclear: case SessHalfDuplex: case SessAuthenticate: case SessEncrypt: case SessLocalEcho: case 42: case 43: case 44: case 47: case 48: case 49: case 50: case 53: case 65: case 66: FlipCheckBox(dptr, ditem); break; case 64: if (ssh_glue_installed()) ssh_glue_randomize(); else OperationFailedAlert(6, 0, 0); break; case 54: { short protocol, tempPort; protocol = GetCntlVal(dptr, 54); tempPort = getDefaultPort(protocol - 1); NumToString((unsigned short)tempPort, scratchPstring); SetTEText(dptr, SessPort, scratchPstring); } break; case SessTEKinhib: SetCntrl(dptr, SessTEKinhib, 1); SetCntrl(dptr, SessTEK4014, 0); SetCntrl(dptr, SessTEK4105, 0); break; case SessTEK4014: SetCntrl(dptr, SessTEKinhib, 0); SetCntrl(dptr, SessTEK4014, 1); SetCntrl(dptr, SessTEK4105, 0); break; case SessTEK4105: SetCntrl(dptr, SessTEKinhib, 0); SetCntrl(dptr, SessTEK4014, 0); SetCntrl(dptr, SessTEK4105, 1); break; case SessPasteQuick: SetCntrl(dptr, SessPasteQuick, 1); SetCntrl(dptr, SessPasteBlock, 0); break; case SessPasteBlock: SetCntrl(dptr, SessPasteQuick, 0); SetCntrl(dptr, SessPasteBlock, 1); break; case SessDeleteDel: SetCntrl(dptr, SessDeleteDel, 1); SetCntrl(dptr, SessDeleteBS, 0); break; case SessDeleteBS: SetCntrl(dptr, SessDeleteDel, 0); SetCntrl(dptr, SessDeleteBS, 1); break; case SessInterrupt: case SessSuspend: case SessResume: GetTEText(dptr, ditem, scratchPstring); if ((scratchPstring[1] < 32) && (scratchPstring[1] > 0)) { scratchPstring[0] = 2; scratchPstring[2] = scratchPstring[1] ^ 64; scratchPstring[1] = '^'; SetTEText(dptr, ditem, scratchPstring); } break; case 46: // tab control newPanel = GetCntlVal(dptr, 46); if (newPanel == currentPanel) break; HideSessPanel(dptr, currentPanel); ShowSessPanel(dptr, newPanel); currentPanel = newPanel; break; case 40: // Save as Set... case 41: // Add to Set... SetSessionData(dptr, SessPrefsPtr, (char *)SPopup, PrefRecordNamePtr); UseResFile(TelInfo->SettingsFile); tempTermPrefsHdl = (TerminalPrefs **)Get1NamedSizedResource (TERMINALPREFS_RESTYPE, SessPrefsPtr->TerminalEmulation, sizeof(TerminalPrefs)); DetachResource((Handle) tempTermPrefsHdl); HLock((Handle) tempTermPrefsHdl); EventAvail(everyEvent, &optKeyEvtRec); SaveSetFromSession(SessPrefsPtr, *tempTermPrefsHdl, (ditem == 41), (optKeyEvtRec.modifiers & 0x0800)); DisposeHandle((Handle) tempTermPrefsHdl); break; case 73: // Edit Session Macros { static NewMacroInfo tmpmacros, savedmacroidx; Handle tmpmacrohdl, savedmacrohdl; short macropanel, macroitem; long len; char *pos; savedmacrohdl = oldMacros; savedmacroidx = oldMacroIndexes; macropanel = dialogPane; setupNewMacros(&tmpmacros); UseResFile(TelInfo->SettingsFile); tmpmacrohdl = Get1NamedResource('uMac', PrefRecordNamePtr); if (tmpmacrohdl) { HLock(tmpmacrohdl); DetachResource(tmpmacrohdl); disposemacros(&tmpmacros); ParseMacrosFromHandle(&tmpmacros, tmpmacrohdl); } macroitem = ModalMacros(&tmpmacros); if (macroitem != 2) { UseResFile(TelInfo->SettingsFile); tmpmacrohdl = Get1NamedResource('uMac', PrefRecordNamePtr); if (tmpmacrohdl) RemoveResource(tmpmacrohdl); HLock(tmpmacros.handle); len = GetHandleSize(tmpmacros.handle); tmpmacrohdl = myNewHandle(len + 2); HLock(tmpmacrohdl); pos = *tmpmacrohdl; *pos = '!'; pos++; *pos = '\015'; pos++; BlockMoveData(*(tmpmacros.handle), pos, len); DisposeHandle(tmpmacros.handle); HUnlock(tmpmacrohdl); AddResource(tmpmacrohdl, 'uMac', UniqueID('uMac'), PrefRecordNamePtr); UpdateResFile(TelInfo->SettingsFile); ReleaseResource(tmpmacrohdl); } else DisposeHandle(tmpmacros.handle); oldMacros = savedmacrohdl; oldMacroIndexes = savedmacroidx; dialogPane = macropanel; } break; case SessAlias: wasInAliasText = TRUE; break; default: break; } // switch } //else not bad alias } // while if (ditem == 2) { PopupCleanup(); if (IsNewPrefRecord) DisposeHandle((Handle) SessPrefsHdl); else ReleaseResource((Handle) SessPrefsHdl); TelInfo->lastPanelSession = currentPanel - 1; DisposeDialog(dptr); return(FALSE); // No changes should be made. } SetSessionData(dptr, SessPrefsPtr, (char *)SPopup, PrefRecordNamePtr); PopupCleanup(); if (IsNewPrefRecord) { UseResFile(TelInfo->SettingsFile); resourceID = UniqueID(SESSIONPREFS_RESTYPE); AddResource((Handle)SessPrefsHdl, SESSIONPREFS_RESTYPE, resourceID, PrefRecordNamePtr); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)SessPrefsHdl); } else { UseResFile(TelInfo->SettingsFile); GetResInfo((Handle)SessPrefsHdl, &resourceID, &scratchResType,(StringPtr) &scratchPstring); SetTaggedSesResInfo((Handle)SessPrefsHdl, resourceID, scratchPstring, PrefRecordNamePtr); ChangedResource((Handle)SessPrefsHdl); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)SessPrefsHdl); } TelInfo->lastPanelSession = currentPanel - 1; DisposeDialog(dptr); return(TRUE); // A resource has changed or been added. } void SetSessionData(DialogPtr dptr, SessionPrefs *SessPrefsPtr, char *SPopupRef, StringPtr PrefRecordNamePtr) { short scratchshort; long scratchlong; Str255 scratchPstring, scratchPstring2; popup *SPopup = (popup *)SPopupRef; GetMenuItemText(SPopup[0].h, SPopup[0].choice, scratchPstring); GetMenuItemText(SPopup[1].h, SPopup[1].choice, scratchPstring2); if (StrLength(scratchPstring) > 63) scratchPstring[0] = 63; BlockMove(scratchPstring, (SessPrefsPtr->TerminalEmulation), scratchPstring[0]+1); if (StrLength(scratchPstring2) > 63) scratchPstring[0] = 63; BlockMove(scratchPstring2, (SessPrefsPtr->TranslationTable), scratchPstring2[0]+1); SessPrefsPtr->tektype = (-1 * GetCntlVal(dptr, SessTEKinhib)) + GetCntlVal(dptr, SessTEK4105); SessPrefsPtr->pastemethod = !GetCntlVal(dptr, SessPasteQuick); SessPrefsPtr->bksp = GetCntlVal(dptr, SessDeleteDel); SessPrefsPtr->forcesave = GetCntlVal(dptr, SessForceSave); SessPrefsPtr->crmap = GetCntlVal(dptr, SessBezerkeley); SessPrefsPtr->alwaysBSD = GetCntlVal(dptr, 42); SessPrefsPtr->ignoreBeeps = GetCntlVal(dptr, 43); SessPrefsPtr->ignoreff = GetCntlVal(dptr, 44); SessPrefsPtr->linemode = GetCntlVal(dptr, SessLinemode); SessPrefsPtr->tekclear = GetCntlVal(dptr, SessTEKclear); SessPrefsPtr->halfdup = GetCntlVal(dptr, SessHalfDuplex); SessPrefsPtr->authenticate = GetCntlVal(dptr, SessAuthenticate); SessPrefsPtr->encrypt = GetCntlVal(dptr, SessEncrypt); SessPrefsPtr->localecho = GetCntlVal(dptr, SessLocalEcho); SessPrefsPtr->otpauto = GetCntlVal(dptr, 47); SessPrefsPtr->otpmulti = GetCntlVal(dptr, 48); SessPrefsPtr->otphex = GetCntlVal(dptr, 49); SessPrefsPtr->otpnoprompt = GetCntlVal(dptr, 50); SessPrefsPtr->otpsavepass = GetCntlVal(dptr, 53); SessPrefsPtr->protocol = GetCntlVal(dptr, 54) - 1; SessPrefsPtr->encryption = GetCntlVal(dptr,63) - 1; SessPrefsPtr->usesocks = GetCntlVal(dptr, 65); SessPrefsPtr->socks4a = GetCntlVal(dptr, 66); memset(SessPrefsPtr->otppassword, 0, sizeof(SessPrefsPtr->otppassword)); c2pstr(configPassword); pstrcpy((unsigned char *)SessPrefsPtr->otppassword, (unsigned char *)configPassword); memset(SessPrefsPtr->password, 0, sizeof(SessPrefsPtr->password)); c2pstr(configPassword2); pstrcpy((unsigned char *)SessPrefsPtr->password, (unsigned char *)configPassword2); GetTEText(dptr, SessPort, scratchPstring); SessPrefsPtr->portNegative = 0; if (scratchPstring[1] == '-') { SessPrefsPtr->portNegative = 1; scratchPstring[1] = scratchPstring[0] - 1; StringToNum(&scratchPstring[1], &scratchlong); } else StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 65530, 1); SessPrefsPtr->port = (short) scratchlong; GetTEText(dptr, 68, scratchPstring); StringToNum(scratchPstring, &scratchlong); SessPrefsPtr->socksport = (short) scratchlong; GetTEText(dptr, SessBlockSize, scratchPstring); StringToNum(scratchPstring, &scratchlong); BoundsCheck(&scratchlong, 4097, 10); SessPrefsPtr->pasteblocksize = (short) scratchlong; GetTEText(dptr, SessHostName, scratchPstring); if (StrLength(scratchPstring) > 63) scratchPstring[0] = 63; BlockMove(scratchPstring, SessPrefsPtr->hostname, scratchPstring[0]+1); GetTEText(dptr, 67, scratchPstring); if (StrLength(scratchPstring) > 63) scratchPstring[0] = 63; BlockMove(scratchPstring, SessPrefsPtr->sockshost, scratchPstring[0]+1); GetTEText(dptr, SessAlias, PrefRecordNamePtr); GetTEText(dptr, 59, (unsigned char *)SessPrefsPtr->username); // GetTEText(dptr, 60, (unsigned char *)SessPrefsPtr->password); GetTEText(dptr, 61, (unsigned char *)SessPrefsPtr->clientuser); GetTEText(dptr, 62, (unsigned char *)SessPrefsPtr->command); GetTEText(dptr, 72, (unsigned char *)SessPrefsPtr->socksusername); GetTEText(dptr, SessInterrupt, scratchPstring); if (scratchPstring[0]) SessPrefsPtr->ckey = toupper(scratchPstring[2]) ^ 64; else SessPrefsPtr->ckey = -1; GetTEText(dptr, SessSuspend, scratchPstring); if (scratchPstring[0]) SessPrefsPtr->skey = toupper(scratchPstring[2]) ^ 64; else SessPrefsPtr->skey = -1; GetTEText(dptr, SessResume, scratchPstring); if (scratchPstring[0]) SessPrefsPtr->qkey = toupper(scratchPstring[2]) ^ 64; else SessPrefsPtr->qkey = -1; GetTEText(dptr,SessBlockSizeTE,scratchPstring); StringToNum(scratchPstring,&scratchlong); BoundsCheck(&scratchlong, 4096, 512); SessPrefsPtr->NetBlockSize = (short) scratchlong; } Boolean EditFTPUser(StringPtr PrefRecordNamePtr) { DialogPtr dptr; short ditem, scratchshort, resourceID, vRefNum; ResType scratchResType; Boolean IsNewPrefRecord; FTPUser** FTPUHdl; FTPUser* FTPUptr; Str255 scratchPstring, scratchPstring2; dptr = GetNewMySmallStrangeDialog(FTPUserDLOG, NULL, kInFront, (void *)ThirdCenterDialog); ditem = 3; HideDialogItem(dptr, FTPUcanchangeCWD); // Sometime later, perhaps if (PrefRecordNamePtr[0] != 0) { IsNewPrefRecord = FALSE; UseResFile(TelInfo->SettingsFile); FTPUHdl = (FTPUser **)Get1NamedResource(FTPUSER, PrefRecordNamePtr); HLock((Handle) FTPUHdl); FTPUptr = *FTPUHdl; SetCntrl(dptr, FTPUcanchangeCWD, FTPUptr->UserCanCWD); SetTEText(dptr, FTPUusername, PrefRecordNamePtr); for (scratchshort = 8, scratchPstring[0] = 8; scratchshort > 0; scratchshort--) scratchPstring[scratchshort] = ''; SetTEText(dptr, FTPUpassword, scratchPstring); vRefNum = VolumeNameToRefNum(FTPUptr->DefaultDirVolName); } else { IsNewPrefRecord = TRUE; FTPUHdl = (FTPUser **)myNewHandle(sizeof(FTPUser)); HLock((Handle) FTPUHdl); FTPUptr = *FTPUHdl; vRefNum = -1; // Default Volume FTPUptr->DefaultDirDirID = 2; // Root directory SetCntrl(dptr, FTPUcanchangeCWD, 0); } PathNameFromDirID(FTPUptr->DefaultDirDirID, vRefNum, scratchPstring); SetTEText(dptr, FTPUDfltDirDsply, scratchPstring); SelectDialogItemText(dptr, FTPUusername, 0, 32767); ShowWindow(dptr); while (ditem > 2) { ModalDialog(DLOGwOK_CancelUPP, &ditem); switch (ditem) { case FTPUcanchangeCWD: FlipCheckBox(dptr, ditem); break; case FTPUDfltDirButton: SelectDirectory(&vRefNum, &(FTPUptr->DefaultDirDirID)); PathNameFromDirID(FTPUptr->DefaultDirDirID, vRefNum, scratchPstring); SetTEText(dptr, FTPUDfltDirDsply, scratchPstring); break; default: break; } // switch } // while if (ditem == 2) { if (IsNewPrefRecord) DisposeHandle((Handle) FTPUHdl); else ReleaseResource((Handle) FTPUHdl); DisposeDialog(dptr); return(FALSE); // No changes should be made. } FTPUptr->UserCanCWD = GetCntlVal(dptr, FTPUcanchangeCWD); GetDirectoryName(vRefNum, 2, FTPUptr->DefaultDirVolName); GetTEText(dptr, FTPUusername, PrefRecordNamePtr); GetTEText(dptr, FTPUpassword, scratchPstring); if (scratchPstring[0] != '') { // Encrypt the new (or possibly modified) password. PtoCstr(scratchPstring); Sencompass((char *)scratchPstring, (char *)scratchPstring2); CtoPstr((char *)scratchPstring2); BlockMove(scratchPstring2, FTPUptr->EncryptedPassword, StrLength(scratchPstring2)+1); } if (IsNewPrefRecord) { UseResFile(TelInfo->SettingsFile); resourceID = UniqueID(FTPUSER); AddResource((Handle)FTPUHdl, FTPUSER, resourceID, PrefRecordNamePtr); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)FTPUHdl); } else { UseResFile(TelInfo->SettingsFile); GetResInfo((Handle)FTPUHdl, &resourceID, &scratchResType,(StringPtr) &scratchPstring); SetResInfo((Handle)FTPUHdl, resourceID, PrefRecordNamePtr); ChangedResource((Handle)FTPUHdl); UpdateResFile(TelInfo->SettingsFile); ReleaseResource((Handle)FTPUHdl); } DisposeDialog(dptr); return(TRUE); // A resource has changed or been added. } short AnsiPrompt(short allowDefaultBoldSelect, short *defaultBoldColor) { /* puts up the dialog that lets the user examine and change the ANSI color settings for the specified window. */ short scratchshort, ditem; Point ColorBoxPoint; DialogPtr dptr; Boolean UserLikesNewColor; RGBColorPtr scratchRGB; scratchRGB = (RGBColorPtr) myNewPtr(sizeof(RGBColor)); dptr = GetNewMySmallDialog(ANSIColorDLOG, NULL, kInFront, (void *)ThirdCenterDialog); SetDialogDefaultItem(dptr, 1); SetDialogCancelItem(dptr, 2); SetDialogTracksCursor(dptr, 1); NumberOfColorBoxes = 16; if (allowDefaultBoldSelect) SetCntrl(dptr, ANSIBlackRadio+(*defaultBoldColor), 1); else { for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) HideDialogItem(dptr, scratchshort + ANSIBlackRadio); HideDialogItem(dptr, 45); } for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) { BoxColorItems[scratchshort] = ANSIBlack + scratchshort; GetEntryColor(TelInfo->AnsiColors, scratchshort, scratchRGB); BlockMove(scratchRGB,&BoxColorData[scratchshort], sizeof(RGBColor)); UItemAssign( dptr, scratchshort + ANSIBlack, ColorBoxItemProcUPP); } ColorBoxPoint.h = 0; // Have the color picker center the box on the main ColorBoxPoint.v = 0; // screen NumOnly[0] = 12; //safe item ditem = 3; while (ditem > 2) { movableModalDialog(ColorBoxModalProcUPP, &ditem); switch (ditem) { case ANSIBlack: case ANSIRed: case ANSIGreen: case ANSIYellow: case ANSIBlue: case ANSIMagenta: case ANSICyan: case ANSIWhite: case ANSIBoldBlack: case ANSIBoldRed: case ANSIBoldGreen: case ANSIBoldYellow: case ANSIBoldBlue: case ANSIBoldMagenta: case ANSIBoldCyan: case ANSIBoldWhite: if (TelInfo->haveColorQuickDraw) { Str255 askColorString; GetIndString(askColorString,MISC_STRINGS,PICK_NEW_COLOR_STRING); UserLikesNewColor = GetColor(ColorBoxPoint,askColorString, &BoxColorData[ditem-ANSIBlack], scratchRGB); if (UserLikesNewColor) BoxColorData[ditem-ANSIBlack] = *scratchRGB; } break; case ANSIBlackRadio: case ANSIRedRadio: case ANSIGreenRadio: case ANSIYellowRadio: case ANSIBlueRadio: case ANSIMagentaRadio: case ANSICyanRadio: case ANSIWhiteRadio: case ANSIBoldBlackRadio: case ANSIBoldRedRadio: case ANSIBoldGreenRadio: case ANSIBoldYellowRadio: case ANSIBoldBlueRadio: case ANSIBoldMagentaRadio: case ANSIBoldCyanRadio: case ANSIBoldWhiteRadio: for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) SetCntrl(dptr, ANSIBlackRadio + scratchshort, 0); SetCntrl(dptr, ditem, 1); default: break; } // switch } // while if (ditem == DLOGCancel) { DisposeDialog(dptr); return -1; } if (allowDefaultBoldSelect) for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) if (GetCntlVal(dptr, ANSIBlackRadio + scratchshort)) *defaultBoldColor = scratchshort; for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) SetEntryColor(TelInfo->AnsiColors, scratchshort, &(BoxColorData[scratchshort])); DisposeDialog(dptr); } \ No newline at end of file diff --git a/source/config/configure.proto.h b/source/config/configure.proto.h index 2c8ce06..1e1c44b 100755 --- a/source/config/configure.proto.h +++ b/source/config/configure.proto.h @@ -1 +1 @@ -void CONFIGUREunload(void); void Cenviron( void); void Cftp( void); Boolean GetApplicationType(OSType *type); void BoundsCheck(long *value, long high, long low); void EditConfigType(ResType ConfigResourceType, Boolean (*EditFunction)()); Boolean EditTerminal(StringPtr PrefRecordNamePtr); Boolean EditSession(StringPtr PrefRecordNamePtr); Boolean EditFTPUser(StringPtr PrefRecordNamePtr); pascal short ColorBoxModalProc( DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(ColorBoxModalProc, ModalFilter); pascal void ColorBoxItemProc(DialogPtr theDlg, short itemNo); PROTO_UPP(ColorBoxItemProc, UserItem); short AnsiPrompt(short, short*); \ No newline at end of file +void CONFIGUREunload(void); void Cenviron( void); void Cftp( void); Boolean GetApplicationType(OSType *type); void BoundsCheck(long *value, long high, long low); void EditConfigType(ResType ConfigResourceType, Boolean (*EditFunction)()); Boolean EditTerminal(StringPtr PrefRecordNamePtr); Boolean EditSession(StringPtr PrefRecordNamePtr); Boolean EditFTPUser(StringPtr PrefRecordNamePtr); pascal short ColorBoxModalProc( DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(ColorBoxModalProc, ModalFilter); pascal void ColorBoxItemProc(DialogPtr theDlg, short itemNo); PROTO_UPP(ColorBoxItemProc, UserItem); void SetSessionData(DialogPtr, SessionPrefs*, char*, StringPtr); short AnsiPrompt(short, short*); void HideSessPanel(DialogPtr, short); void ShowSessPanel(DialogPtr, short); void HideTermPanel(DialogPtr, short); void ShowTermPanel(DialogPtr, short); \ No newline at end of file diff --git a/source/config/popup.c b/source/config/popup.c index 4ffc4d5..2c4d764 100755 --- a/source/config/popup.c +++ b/source/config/popup.c @@ -1 +1 @@ -/* * popup.c * Code for doing popup menus in our dialog boxes * Credit for this goes to Apple Sample Code and a conglomeration of other code I've seen. * * NCSA Revisions: * 8/92 Telnet 2.6: Initial version. Jim Browne */ // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #ifdef MPW #pragma segment Configure #endif #include "popup.h" #include "popup.proto.h" static popup *FindPopup(short item); PROTO_UPP(DrawPopUp, UserItem); popup *Popup; /* Current popup structure array */ static popup *FindPopup( short item) { popup *p = Popup; while (p->item) { if (p->item == item) return p; ++p; } return 0; /* Not found */ } SIMPLE_UPP(DrawPopUp, UserItem); pascal void DrawPopUp(DialogPtr dptr, short item) { char text[256]; char* s; PenState savePen; Rect box, title; FontInfo info; short type, width, newwidth; Handle hdl; popup *p; GetPenState(&savePen); GetFontInfo(&info); GetDItem(dptr, item, &type, &hdl, &box); p = FindPopup(item); title = box; title.right = box.left - 1; title.left = title.right - StringWidth((**(p->h)).menuData) - 2; box.top -= 1; box.left -= 1; box.bottom += 2; box.right += 2; EraseRect(&box); if ((**(p->h)).menuData[0] != 0) InvertRect(&title); /* Get and draw menu title. Get item text. */ if (!p || !p->h) return; s = (char *)(**(p->h)).menuData; /* Menu title */ MoveTo(box.left - StringWidth((StringPtr)s) - 2, box.top + info.ascent); DrawString((StringPtr)s); GetItem(p->h, p->choice, (StringPtr)text); width = (box.right - box.left) - (CharWidth(checkMark) + 2); newwidth = StringWidth((StringPtr)text); if (newwidth > width) { width -= CharWidth(''); do { newwidth -= CharWidth(text[text[0]]); --text[0]; } while (newwidth > width && text[0]); ++text[0]; text[text[0]] = ''; } MoveTo(box.left + CharWidth(checkMark) + 2, box.top + info.ascent); DrawString((StringPtr)text); InsetRect(&box, -1, -1); /* A la Apple Sample Code */ PenSize(1, 1); FrameRect(&box); MoveTo(box.left + 2, box.bottom); LineTo(box.right, box.bottom); LineTo(box.right, box.top + 2); SetPenState(&savePen); } Boolean PopupMousedown( DialogPtr dptr, EventRecord *event, short *i) { short item, choice, type; popup *p; Point clikloc; long chosen; Handle hdl; Rect box, title; Boolean result = FALSE; clikloc = event->where; GlobalToLocal(&clikloc); if ((item = FindDItem(dptr, clikloc) + 1) < 1) return result; p = FindPopup(item); if (!p || !p->h) return result; GetDItem(dptr, item, &type, &hdl, &box); clikloc = topLeft(box); LocalToGlobal(&clikloc); title = box; title.right = box.left - 1; title.left = title.right - StringWidth((**(p->h)).menuData) - 2; box.top -= 1; box.left -= 1; box.bottom += 2; box.right += 2; EraseRect(&box); if ((**(p->h)).menuData[0] != 0) InvertRect(&title); InsertMenu(p->h, hierMenu); SetItemMark(p->h, p->choice, checkMark); CalcMenuSize(p->h); chosen = PopUpMenuSelect(p->h, clikloc.v, clikloc.h, p->choice); SetItemMark(p->h, p->choice, noMark); DeleteMenu((**(p->h)).menuID); if (chosen) { choice = chosen & 0xFFFF; /* Apple sez ignore high word */ if (choice != p->choice) { p->choice = choice; *i = item; result = TRUE; } } DrawPopUp(dptr, item); return result; } void PopupInit( DialogPtr dptr, popup *popups) { popup *p; short w; FontInfo info; short type; Handle hdl; Rect box; Popup = p = popups; SetPort(dptr); GetFontInfo(&info); while (p->item) { if (p->h) { /* Correct user item box. */ GetDItem(dptr, p->item, &type, &hdl, &box); CalcMenuSize(p->h); w = (**(p->h)).menuWidth; w += 16; if (w < (box.right - box.left)) box.right = box.left + w; box.bottom = box.top + info.ascent + info.descent + info.leading; SetDItem(dptr, p->item, type, (Handle)DrawPopUpUPP, &box); } ++p; } } void PopupCleanup(void) { popup *p = Popup; while (p->item) { if (p->h) DisposeMenu(/*(Handle)*/p->h); // Since we're using NewMenu's, we need // to do a DisposeMenu, rather than a // Releaseresource ++p; } } \ No newline at end of file +/* * popup.c * Code for doing popup menus in our dialog boxes * Credit for this goes to Apple Sample Code and a conglomeration of other code I've seen. * * NCSA Revisions: * 8/92 Telnet 2.6: Initial version. Jim Browne */ // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "popup.h" #include "popup.proto.h" static popup *FindPopup(short item); PROTO_UPP(DrawPopUp, UserItem); popup *Popup; /* Current popup structure array */ static popup *FindPopup( short item) { popup *p = Popup; while (p->item) { if (p->item == item) return p; ++p; } return 0; /* Not found */ } SIMPLE_UPP(DrawPopUp, UserItem); pascal void DrawPopUp(DialogPtr dptr, short item) { char text[256]; char* s; PenState savePen; Rect box, title; FontInfo info; short type, width, newwidth; Handle hdl; popup *p; SetPort(dptr); // RAB BetterTelnet 2.0b2 GetPenState(&savePen); GetFontInfo(&info); GetDialogItem(dptr, item, &type, &hdl, &box); p = FindPopup(item); title = box; title.right = box.left - 1; title.left = title.right - StringWidth((**(p->h)).menuData) - 2; box.top -= 1; box.left -= 1; box.bottom += 2; box.right += 2; EraseRect(&box); if ((**(p->h)).menuData[0] != 0) InvertRect(&title); /* Get and draw menu title. Get item text. */ if (!p || !p->h) return; s = (char *)(**(p->h)).menuData; /* Menu title */ MoveTo(box.left - StringWidth((StringPtr)s) - 2, box.top + info.ascent); DrawString((StringPtr)s); GetMenuItemText(p->h, p->choice, (StringPtr)text); width = (box.right - box.left) - (CharWidth(checkMark) + 2); newwidth = StringWidth((StringPtr)text); if (newwidth > width) { width -= CharWidth(''); do { newwidth -= CharWidth(text[text[0]]); --text[0]; } while (newwidth > width && text[0]); ++text[0]; text[text[0]] = ''; } MoveTo(box.left + CharWidth(checkMark) + 2, box.top + info.ascent); DrawString((StringPtr)text); InsetRect(&box, -1, -1); /* A la Apple Sample Code */ PenSize(1, 1); FrameRect(&box); MoveTo(box.left + 2, box.bottom); LineTo(box.right, box.bottom); LineTo(box.right, box.top + 2); SetPenState(&savePen); } Boolean PopupMousedown( DialogPtr dptr, EventRecord *event, short *i) { short item, choice, type; popup *p; Point clikloc; long chosen; Handle hdl; Rect box, title; Boolean result = FALSE; clikloc = event->where; GlobalToLocal(&clikloc); if ((item = FindDialogItem(dptr, clikloc) + 1) < 1) return result; p = FindPopup(item); if (!p || !p->h) return result; GetDialogItem(dptr, item, &type, &hdl, &box); clikloc = topLeft(box); LocalToGlobal(&clikloc); title = box; title.right = box.left - 1; title.left = title.right - StringWidth((**(p->h)).menuData) - 2; box.top -= 1; box.left -= 1; box.bottom += 2; box.right += 2; EraseRect(&box); if ((**(p->h)).menuData[0] != 0) InvertRect(&title); InsertMenu(p->h, hierMenu); SetItemMark(p->h, p->choice, checkMark); CalcMenuSize(p->h); chosen = PopUpMenuSelect(p->h, clikloc.v, clikloc.h, p->choice); SetItemMark(p->h, p->choice, noMark); DeleteMenu((**(p->h)).menuID); if (chosen) { choice = chosen & 0xFFFF; /* Apple sez ignore high word */ if (choice != p->choice) { p->choice = choice; *i = item; result = TRUE; } } DrawPopUp(dptr, item); return result; } void PopupInit( DialogPtr dptr, popup *popups) { popup *p; short w; FontInfo info; short type; Handle hdl; Rect box; Popup = p = popups; SetPort(dptr); GetFontInfo(&info); while (p->item) { if (p->h) { /* Correct user item box. */ GetDialogItem(dptr, p->item, &type, &hdl, &box); CalcMenuSize(p->h); w = (**(p->h)).menuWidth; w += 16; if (w < (box.right - box.left)) box.right = box.left + w; box.bottom = box.top + info.ascent + info.descent + info.leading; SetDialogItem(dptr, p->item, type, (Handle)DrawPopUpUPP, &box); } ++p; } } void PopupCleanup(void) { popup *p = Popup; while (p->item) { if (p->h) DisposeMenu(/*(Handle)*/p->h); // Since we're using NewMenu's, we need // to do a DisposeMenu, rather than a // Releaseresource ++p; } } \ No newline at end of file diff --git a/source/debug:errors/DlogUtils.c b/source/debug:errors/DlogUtils.c index 1e15845..309e9a2 100755 --- a/source/debug:errors/DlogUtils.c +++ b/source/debug:errors/DlogUtils.c @@ -1 +1 @@ -/* * DlogUtils.c * Very Useful Dialog Utilities Apple SHOULD have provided in the toolbox... * * Revisions: * 8/92 Telnet 2.6: Initial version. Jim Browne */ // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #ifdef MPW #pragma segment Debug #endif #include "DlogUtils.proto.h" #include "netevent.proto.h" #include "movableModal.h" #include "Popup.h" #include "popup.proto.h" pascal short modalProc(DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(modalProc, ModalFilter); pascal short FileHook(short item, DialogPtr theDialog); PROTO_UPP(FileHook, DlgHook); pascal Boolean FolderFilter(FileParam *pbp); PROTO_UPP(FolderFilter, FileFilter); void GetTEText( DialogPtr dptr, short item, Str255 str) { short type; Handle itemh; Rect theRect; GetDItem(dptr, item, &type, &itemh, &theRect); GetIText(itemh, str); } void SetTEText( DialogPtr dptr, short item, Str255 str) { short type; Handle itemh; Rect theRect; GetDItem(dptr, item, &type, &itemh, &theRect); SetIText(itemh, str); } void Hilite( DialogPtr dptr, short item, short value) { short Type; Handle Itemh; Rect Box; GetDItem(dptr, item, &Type, &Itemh, &Box); HiliteControl((ControlHandle)Itemh, value); } void FlipCheckBox( DialogPtr dptr, short item) { short type; Handle itemHdl; Rect box; GetDItem(dptr, item, &type, &itemHdl, &box); SetCtlValue((ControlHandle)itemHdl, (GetCtlValue((ControlHandle)itemHdl) == 0) ? 1 : 0); } void FlipRadioButton( DialogPtr dptr, short item) { short type; Handle itemHdl; Rect box; GetDItem(dptr, item, &type, &itemHdl, &box); SetCtlValue((ControlHandle)itemHdl, (GetCtlValue((ControlHandle)itemHdl) == 0) ? 1 : 0); } void SetCntrl( DialogPtr dptr, short item, short value) { short Type; Handle Itemh; Rect Box; GetDItem(dptr, item, &Type, &Itemh, &Box); SetCtlValue((ControlHandle)Itemh, value); } short GetCntlVal( DialogPtr dptr, short item) { short Type; Handle Itemh; Rect Box; GetDItem(dptr, item, &Type, &Itemh, &Box); return GetCtlValue((ControlHandle)Itemh); } short findPopupMenuItem(MenuHandle theHandle, Str255 name) { short id; Str255 tempName; short numItems; numItems = CountMItems(theHandle); for (id = 1; id < numItems; id++) { GetItem(theHandle,id,tempName); if (EqualString(tempName, name, 0, 0)) break; } return id; } #ifndef NO_UNIVERSAL void UItemAssign( DialogPtr dptr, short item, UserItemUPP proc) #else void UItemAssign( DialogPtr dptr, short item, ProcPtr proc) #endif /* sets the handler for a user item to the specified procedure. */ { Rect ibox; char **ihndl; short typ; GetDItem( dptr, item, &typ, &ihndl, &ibox); SetDItem( dptr, item, typ, (Handle) proc, &ibox); } SIMPLE_UPP(OutlineItem, UserItem); pascal void OutlineItem( DialogPtr dptr, short itm) { Rect ibox; char **ihndl; short typ; short item=itm; GetDItem( dptr, item, &typ, &ihndl, &ibox); PenSize( 3,3); InsetRect( &ibox, -4,-4); FrameRoundRect( &ibox, 16,16); } SIMPLE_UPP(VersionNumber, UserItem); pascal void VersionNumber( DialogPtr dptr, short itm) { Rect ibox; char **ihndl; short typ; short item=itm; VersRecHndl version; Str63 versionString; if ((version = (VersRecHndl) GetResource('vers',1)) != nil) { BlockMove((*version)->shortVersion+*(*version)->shortVersion+1, versionString, *((*version)->shortVersion+*(*version)->shortVersion+1)+1); ReleaseResource((Handle)version); } else *versionString = 0; GetDItem( dptr, item, &typ, &ihndl, &ibox); TextFont( 3); TextSize( 9); MoveTo( ibox.left /* +((ibox.right-ibox.left)/2)-(StringWidth(versionString)/2) */, ibox.bottom-2); DrawString(versionString); } SIMPLE_UPP(modalProc, ModalFilter); pascal short modalProc( DialogPtr dptr, EventRecord *evt, short *item) { UNUSED_ARG(dptr) short keyCode, key; if (evt->what == keyDown) { key = evt->message & charCodeMask; keyCode = (evt->message >>8) & 0xff ; if ((key == 0x0d) || (key == 0x03)) { // 0x0d == return, 0x03 == enter *item = DLOGOk; return(-1); /* BYU LSC - pascal doesn't like "1" as true */ } if (((key == '.') && (evt->modifiers & cmdKey)) || ((key == 0x1b) && (keyCode == 0x35)) ) { // 0x35 == escKey *item = DLOGCancel; return(-1); /* BYU LSC - pascal doesn't like "1" as true */ } } Stask(); return(FALSE); } void FlashButton (DialogPtr theDialog, short item) { short itemType; ControlHandle theItem; Rect itemRect; long myticks; if (item > 0) { GetDItem(theDialog,item,&itemType,(Handle *)&theItem,&itemRect); HiliteControl(theItem,1); Delay(8,&myticks); HiliteControl(theItem,0); } } SIMPLE_UPP(DLOGwOK, ModalFilter); pascal short DLOGwOK( DialogPtr dptr, EventRecord *evt, short *item) { return(MyDLOGfilter(dptr, evt, item, true, false, false)); } SIMPLE_UPP(DLOGwOK_Cancel, ModalFilter); pascal short DLOGwOK_Cancel( DialogPtr dptr, EventRecord *evt, short *item) { return(MyDLOGfilter(dptr, evt, item, true, true, false)); } SIMPLE_UPP(DLOGwOK_Cancel_Popup, ModalFilter); pascal short DLOGwOK_Cancel_Popup( DialogPtr dptr, EventRecord *evt, short *item) { return(MyDLOGfilter(dptr, evt, item, true, true, true)); } // Our standard modal dialog box filter. // RAB BetterTelnet 1.2 - we use StdFilterProc now... SIMPLE_UPP(MyDLOGfilter, ModalFilter); pascal short MyDLOGfilter( DialogPtr dptr, EventRecord *evt, short *item, Boolean hasOK, Boolean hasCancel, Boolean hasPopup) { short keyCode, key, iType; Handle iHndl; Rect iRect; if (hasOK) SetDialogDefaultItem(dptr, 1); if (hasCancel) SetDialogCancelItem(dptr, 2); SetDialogTracksCursor(dptr, 1); /* SetPort(dptr); if (evt->what == keyDown) { key = evt->message & charCodeMask; keyCode = (evt->message >>8) & 0xff ; if (((key == 0x0d) || (key == 0x03)) && hasOK) { // 0x0d == return, 0x03 == enter *item = DLOGOk; // ok FlashButton(dptr, DLOGOk); return(-1); } if ((((key == '.') && (evt->modifiers & cmdKey)) || ((key == 0x1b) && (keyCode == 0x35))) && hasCancel) { // 0x35 == escKey *item = DLOGCancel; FlashButton(dptr, DLOGCancel); return(-1); } } else if ((evt->what == updateEvt) && hasOK) { if ((WindowPtr)evt->message == dptr) { // GetDItem(dptr,DLOGOk,&iType,&iHndl,&iRect); // ok // PenSize(3,3); // InsetRect(&iRect,-4,-4); // FrameRoundRect(&iRect,16,16); } } */ if ((evt->what == mouseDown) && hasPopup) return(PopupMousedown(dptr, evt, item)); Stask(); return CallStdFilterProc(dptr, evt, item); } #if 0 // Our standard modal dialog box filter with code to handle popup user items. pascal short MyDLOGfilterWPopupFilter( DialogPtr dptr, EventRecord *evt, short *item) { short keyCode, key, iType; Handle iHndl; Rect iRect; SetPort(dptr); if (evt->what == keyDown) { key = evt->message & charCodeMask; keyCode = (evt->message >>8) & 0xff ; if ((key == 0x0d) || (key == 0x03)) { // 0x0d == return, 0x03 == enter *item = DLOGOk; // ok FlashButton(dptr, DLOGOk); return(-1); } if (((key == '.') && (evt->modifiers & cmdKey)) || ((key == 0x1b) && (keyCode == 0x35)) ) { // 0x35 == escKey *item = DLOGCancel; FlashButton(dptr, DLOGCancel); return(-1); } } else if (evt->what == updateEvt) { if ((WindowPtr)evt->message == dptr) { GetDItem(dptr,DLOGOk,&iType,&iHndl,&iRect); // ok PenSize(3,3); InsetRect(&iRect,-4,-4); FrameRoundRect(&iRect,16,16); } } if (evt->what == mouseDown) return(PopupMousedown(dptr, evt, item)); Stask(); return(FALSE); } #endif #ifdef NO_UNIVERSAL #define LMSetSFSaveDisk(SFSaveDiskValue) ((* (short *) 0x0214) = (SFSaveDiskValue)) #define LMGetSFSaveDisk() (* (short *) 0x0214) #define LMGetCurDirStore() (* (long *) 0x0398) #define LMSetCurDirStore(CurDirStoreValue) ((* (long *) 0x0398) = (CurDirStoreValue)) #endif void SelectDirectory(short *VRefNum, long *DirID) { Point where; SFReply sfr; LMSetSFSaveDisk( - (*VRefNum)); LMSetCurDirStore(*DirID); StandardFileCenter(&where, WDSET_DLOG); TelInfo->setdir = 0; /* clear dir found flag */ SFPGetFile( where, NULL, FolderFilterUPP, -1, NULL, /* BYU LSC */ FileHookUPP, &sfr, WDSET_DLOG, modalProcUPP); if (TelInfo->setdir) /* we got a dir */ { *VRefNum = - LMGetSFSaveDisk(); *DirID = LMGetCurDirStore(); } } SIMPLE_UPP(FileHook, DlgHook); pascal short FileHook( short item, DialogPtr theDialog) { #ifdef MPW #pragma unused(theDialog) #endif if(item == 11) { /* Set Directory Button */ TelInfo->setdir = 1; return(3); /* pretend we hit cancel, but we didn't */ } else if (item == 12) item = 9; /* these don't count, map to disabled item */ return(item); } SIMPLE_UPP(FolderFilter, FileFilter); pascal Boolean FolderFilter(FileParam *pbp) { if (pbp->ioFlAttrib & 0x0010) return(FALSE); else return(-1); } OSErr SetIndString(StringPtr theStr,short resID,short strIndex) { Handle theRes; /* handle pointing to STR# resource */ short numStrings; /* number of strings in STR# */ short ourString; /* counter to index up to strIndex */ char *resStr; /* string pointer to STR# string to replace */ long oldSize; /* size of STR# resource before call */ long newSize; /* size of STR# resource after call */ unsigned long offset; /* resource offset to str to replace*/ OSErr memError; /* make sure index is in bounds */ if (resID < 1) return -1; /* make sure resource exists */ theRes = GetResource('STR#',resID); if (ResError()!=noErr) return ResError(); if (!theRes || !(*theRes)) return resNotFound; HLock(theRes); HNoPurge(theRes); /* get # of strings in STR# */ BlockMove(*theRes,&numStrings,sizeof(short)); if (strIndex > numStrings) return resNotFound; /* get a pointer to the string to replace */ offset = sizeof(short); resStr = (char *) *theRes + sizeof(short); for (ourString=1; ourStringcontR = ((GrafPtr)win)->portRect; */ /* win->qWindow.refCon = CREATOR; */ return(win); } /* Do a GetNewMyDialog, but make the text small... */ WindowPtr GetNewMySmallDialog(short template,Ptr wStorage,WindowPtr behind, void (*centerFunction)(short)) { short size; DialogPtr dlogptr; size = 9; SetDAFont(applFont); dlogptr = GetNewMyDialog(template,wStorage,behind,centerFunction); SetDAFont(systemFont); if (dlogptr==nil) return 0; SetPort(dlogptr); TextSize(size); TextFont(applFont); { TEHandle teh = ((DialogPeek)dlogptr)->textH; ControlHandle cntl = ((WindowPeek)dlogptr)->controlList; (*teh)->txSize = size; (*teh)->lineHeight = GetLeading(applFont,size); (*teh)->fontAscent = GetAscent(applFont,size); } /* For those dialogs with non-system font buttons, make them inititally invisible and then do a ShowWindow. This keeps the Control Manager from every using Chicago on our turf. -- JMB */ if (! ((((DialogPeek) dlogptr)->window).visible)) ShowWindow(dlogptr); return(dlogptr); } /* Do a GetNewMySmallDialog, but read the item titles from a STR#... */ WindowPtr GetNewMySmallStrangeDialog(short template,Ptr wStorage,WindowPtr behind, void (*centerFunction)(short)) { short size, index, limit, itemType; DialogPtr dlogptr; Handle resource; ControlHandle itemHandle; Rect scratchRect; Str255 scratchPstring; size = 9; SetDAFont(applFont); dlogptr = GetNewMyDialog(template,wStorage,behind,centerFunction); SetDAFont(systemFont); if (dlogptr==nil) return 0; SetPort(dlogptr); TextSize(size); TextFont(applFont); { TEHandle teh = ((DialogPeek)dlogptr)->textH; ControlHandle cntl = ((WindowPeek)dlogptr)->controlList; (*teh)->txSize = size; (*teh)->lineHeight = GetLeading(applFont,size); (*teh)->fontAscent = GetAscent(applFont,size); } /* For those dialogs with non-system font buttons, make them inititally invisible and then do a ShowWindow. This keeps the Control Manager from ever using Chicago on our turf. -- JMB */ if ((resource = GetResource('STR#', template)) != NULL) { short base; Str255 baseStr; GetIndString(baseStr, template, 1); base = atoi(p2cstr(baseStr)); limit = *(short *)(*resource); ReleaseResource(resource); for(index = 2; index <= limit; index++) { GetDItem(dlogptr, index + base, &itemType, (Handle *)&itemHandle, &scratchRect); if ((itemType == 7) && ((**itemHandle).contrlRfCon == 1991)) { GetIndString(scratchPstring, template, index); SetCTitle(itemHandle, scratchPstring); } } } return(dlogptr); } // RAB BetterTelnet 1.2: // Do a GetNewMySmallStrange Dialog, but use Geneva 10, not Geneva 9... WindowPtr GetNewMySmall10StrangeDialog(short template,Ptr wStorage,WindowPtr behind, void (*centerFunction)(short)) { short size, index, limit, itemType; DialogPtr dlogptr; Handle resource; ControlHandle itemHandle; Rect scratchRect; Str255 scratchPstring; size = 10; SetDAFont(applFont); dlogptr = GetNewMyDialog(template,wStorage,behind,centerFunction); SetDAFont(systemFont); if (dlogptr==nil) return 0; SetPort(dlogptr); TextSize(size); TextFont(applFont); { TEHandle teh = ((DialogPeek)dlogptr)->textH; ControlHandle cntl = ((WindowPeek)dlogptr)->controlList; (*teh)->txSize = size; (*teh)->lineHeight = GetLeading(applFont,size); (*teh)->fontAscent = GetAscent(applFont,size); } if ((resource = GetResource('STR#', template)) != NULL) { short base; Str255 baseStr; GetIndString(baseStr, template, 1); base = atoi(p2cstr(baseStr)); limit = *(short *)(*resource); ReleaseResource(resource); for(index = 2; index <= limit; index++) { GetDItem(dlogptr, index + base, &itemType, (Handle *)&itemHandle, &scratchRect); if ((itemType == 7) && ((**itemHandle).contrlRfCon == 1991)) { GetIndString(scratchPstring, template, index); SetCTitle(itemHandle, scratchPstring); } } } return(dlogptr); } // Hide a range of dialog items. RAB BetterTelnet 1.2 void HideDItemRange(DialogPtr dlogp, short startItem, short endItem) { short i; for (i = startItem; i <= endItem; i++) HideDItem(dlogp, i); } // Show a range of dialog items. RAB BetterTelnet 1.2 void ShowDItemRange(DialogPtr dlogp, short startItem, short endItem) { short i; for (i = startItem; i <= endItem; i++) ShowDItem(dlogp, i); } // RAB BetterTelnet 1.2 // Draw the background color over an item. Needed to hide NCSA's brain-dead // fake popup menus. One of these days, I'll rip out popup.c, but until then... void DrawBlank(DialogPtr dlogp, short theItem) { Handle hdl; Rect box; short type; GrafPtr savePort; GetDItem(dlogp, theItem, &type, &hdl, &box); GetPort(&savePort); SetPort(dlogp); InsetRect(&box, -5, -5); EraseRect(&box); SetPort(savePort); } /********************************************************************** * write zeroes over an area of memory **********************************************************************/ void WriteZero(Ptr pointer,long size) { while (size--) *pointer++ = 0; } /********************************************************************** * figure out the appropriate leading for a font **********************************************************************/ short GetLeading(short fontID,short fontSize) { FMInput fInInfo; FMOutput *fOutInfo; /* set up the font input struct */ fInInfo.family = fontID; fInInfo.size = fontSize; fInInfo.face = 0; fInInfo.needBits = FALSE; fInInfo.device = 0; fInInfo.numer.h = fInInfo.numer.v = 1; fInInfo.denom.h = fInInfo.denom.v = 1; /* get the actual info */ fOutInfo = FMSwapFont(&fInInfo); return(((fOutInfo->leading + fOutInfo->ascent + fOutInfo->descent)*fOutInfo->numer.v)/fOutInfo->denom.v); } /********************************************************************** * find ascent font **********************************************************************/ short GetAscent(short fontID,short fontSize) { FMInput fInInfo; FMOutput *fOutInfo; /* set up the font input struct */ fInInfo.family = fontID; fInInfo.size = fontSize; fInInfo.face = 0; fInInfo.needBits = FALSE; fInInfo.device = 0; fInInfo.numer.h = fInInfo.numer.v = 1; fInInfo.denom.h = fInInfo.denom.v = 1; /* get the actual info */ fOutInfo = FMSwapFont(&fInInfo); return((fOutInfo->ascent * fOutInfo->numer.v)/fOutInfo->denom.v); } /************************************************************************ * CenterRectIn - center one rect in another ************************************************************************/ void CenterRectIn(Rect *inner,Rect *outer) { OffsetRect(inner,(outer->left+outer->right-inner->left-inner->right)/2, (outer->top+outer->bottom-inner->top-inner->bottom)/2); } /************************************************************************ * TopCenterRectIn - center one rect in (the bottom of) another ************************************************************************/ void TopCenterRectIn(Rect *inner,Rect *outer) { OffsetRect(inner,(outer->left+outer->right-inner->left-inner->right)/2, outer->top-inner->top); } /************************************************************************ * BottomCenterRectIn - center one rect in (the bottom of) another ************************************************************************/ void BottomCenterRectIn(Rect *inner,Rect *outer) { OffsetRect(inner,(outer->left+outer->right-inner->left-inner->right)/2, outer->bottom-inner->bottom); } /************************************************************************ * ThirdCenterRectIn - center one rect in (the top 1/3 of) another ************************************************************************/ void ThirdCenterRectIn(Rect *inner,Rect *outer) { OffsetRect(inner,(outer->left+outer->right-inner->left-inner->right)/2, outer->top-inner->top + (outer->bottom-outer->top-inner->bottom+inner->top)/3); } void SecondThirdCenterRectIn(Rect *inner,Rect *outer) { OffsetRect(inner,(outer->left+outer->right-inner->left-inner->right)/2, outer->top-inner->top + 2*(outer->bottom-outer->top-inner->bottom+inner->top)/3); } void ThirdCenterDialog(short id) { DialogTHndl dTempl; Rect r = qd.screenBits.bounds; r.top += GetMBarHeight(); dTempl=(DialogTHndl)GetResource('ALRT',id); if (!dTempl) dTempl=(DialogTHndl)GetResource('DLOG',id); if (dTempl) ThirdCenterRectIn(&(*dTempl)->boundsRect,&r); } void SecondThirdCenterDialog(short id) { DialogTHndl dTempl; Rect r = qd.screenBits.bounds; r.top += GetMBarHeight(); dTempl=(DialogTHndl)GetResource('ALRT',id); if (!dTempl) dTempl=(DialogTHndl)GetResource('DLOG',id); if (dTempl) SecondThirdCenterRectIn(&(*dTempl)->boundsRect,&r); } /************************************************************************ * StandardFileCenter - figure out where a stdfile dialog should go ************************************************************************/ void StandardFileCenter(Point *where, short id) { Rect r,in; DialogTHndl dTempl; dTempl=(DialogTHndl)GetResource('ALRT',id); if (!dTempl) dTempl=(DialogTHndl)GetResource('DLOG',id); if (dTempl) { r = (*dTempl)->boundsRect; in = qd.screenBits.bounds; in.top += GetMBarHeight(); ThirdCenterRectIn(&r,&in); where->h = r.left; where->v = r.top; } else { where->h = 100; where->v = 100; } } /* Pascal string utilities */ /* pstrcat - add string 'src' to end of string 'dst' */ void pstrcat(StringPtr dst, StringPtr src) { /* copy string in */ BlockMove(src + 1, dst + *dst + 1, *src); /* adjust length byte */ *dst += *src; } /* pstrinsert - insert string 'src' at beginning of string 'dst' */ void pstrinsert(StringPtr dst, StringPtr src) { /* make room for new string */ BlockMove(dst + 1, dst + *src + 1, *dst); /* copy new string in */ BlockMove(src + 1, dst + 1, *src); /* adjust length byte */ *dst += *src; } void pstrcpy(StringPtr dst, StringPtr src) { BlockMove(src, dst, *src + 1); } \ No newline at end of file +/* * DlogUtils.c * Very Useful Dialog Utilities Apple SHOULD have provided in the toolbox... * * Revisions: * 8/92 Telnet 2.6: Initial version. Jim Browne */ // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "DlogUtils.proto.h" #include "netevent.proto.h" #include "movableModal.h" #include "Popup.h" #include "popup.proto.h" pascal short modalProc(DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(modalProc, ModalFilter); pascal short FileHook(short item, DialogPtr theDialog); PROTO_UPP(FileHook, DlgHook); pascal Boolean FolderFilter(FileParam *pbp); PROTO_UPP(FolderFilter, FileFilter); void GetTEText( DialogPtr dptr, short item, Str255 str) { short type; Handle itemh; Rect theRect; GetDialogItem(dptr, item, &type, &itemh, &theRect); GetDialogItemText(itemh, str); } void SetTEText( DialogPtr dptr, short item, Str255 str) { short type; Handle itemh; Rect theRect; GetDialogItem(dptr, item, &type, &itemh, &theRect); SetDialogItemText(itemh, str); } void Hilite( DialogPtr dptr, short item, short value) { short Type; Handle Itemh; Rect Box; GetDialogItem(dptr, item, &Type, &Itemh, &Box); HiliteControl((ControlHandle)Itemh, value); } void FlipCheckBox( DialogPtr dptr, short item) { short type; Handle itemHdl; Rect box; GetDialogItem(dptr, item, &type, &itemHdl, &box); SetControlValue((ControlHandle)itemHdl, (GetControlValue((ControlHandle)itemHdl) == 0) ? 1 : 0); } void FlipRadioButton( DialogPtr dptr, short item) { short type; Handle itemHdl; Rect box; GetDialogItem(dptr, item, &type, &itemHdl, &box); SetControlValue((ControlHandle)itemHdl, (GetControlValue((ControlHandle)itemHdl) == 0) ? 1 : 0); } void SetCntrl( DialogPtr dptr, short item, short value) { short Type; Handle Itemh; Rect Box; GetDialogItem(dptr, item, &Type, &Itemh, &Box); SetControlValue((ControlHandle)Itemh, value); } short GetCntlVal( DialogPtr dptr, short item) { short Type; Handle Itemh; Rect Box; GetDialogItem(dptr, item, &Type, &Itemh, &Box); return GetControlValue((ControlHandle)Itemh); } short findPopupMenuItem(MenuHandle theHandle, Str255 name) { short id; Str255 tempName; short numItems; numItems = CountMItems(theHandle); for (id = 1; id < numItems; id++) { GetMenuItemText(theHandle,id,tempName); if (EqualString(tempName, name, 0, 0)) break; } return id; } #ifndef NO_UNIVERSAL void UItemAssign( DialogPtr dptr, short item, UserItemUPP proc) #else void UItemAssign( DialogPtr dptr, short item, ProcPtr proc) #endif /* sets the handler for a user item to the specified procedure. */ { Rect ibox; char **ihndl; short typ; GetDialogItem( dptr, item, &typ, &ihndl, &ibox); SetDialogItem( dptr, item, typ, (Handle) proc, &ibox); } SIMPLE_UPP(OutlineItem, UserItem); pascal void OutlineItem( DialogPtr dptr, short itm) { Rect ibox; char **ihndl; short typ; short item=itm; GetDialogItem( dptr, item, &typ, &ihndl, &ibox); PenSize( 3,3); InsetRect( &ibox, -4,-4); FrameRoundRect( &ibox, 16,16); } SIMPLE_UPP(VersionNumber, UserItem); pascal void VersionNumber( DialogPtr dptr, short itm) { Rect ibox; char **ihndl; short typ; short item=itm; VersRecHndl version; Str63 versionString; if ((version = (VersRecHndl) GetResource('vers',1)) != nil) { BlockMove((*version)->shortVersion+*(*version)->shortVersion+1, versionString, *((*version)->shortVersion+*(*version)->shortVersion+1)+1); ReleaseResource((Handle)version); } else *versionString = 0; GetDialogItem( dptr, item, &typ, &ihndl, &ibox); TextFont( 3); TextSize( 9); MoveTo( ibox.left /* +((ibox.right-ibox.left)/2)-(StringWidth(versionString)/2) */, ibox.bottom-2); DrawString(versionString); } SIMPLE_UPP(modalProc, ModalFilter); pascal short modalProc( DialogPtr dptr, EventRecord *evt, short *item) { UNUSED_ARG(dptr) short keyCode, key; if (evt->what == keyDown) { key = evt->message & charCodeMask; keyCode = (evt->message >>8) & 0xff ; if ((key == 0x0d) || (key == 0x03)) { // 0x0d == return, 0x03 == enter *item = DLOGOk; return(-1); /* BYU LSC - pascal doesn't like "1" as true */ } if (((key == '.') && (evt->modifiers & cmdKey)) || ((key == 0x1b) && (keyCode == 0x35)) ) { // 0x35 == escKey *item = DLOGCancel; return(-1); /* BYU LSC - pascal doesn't like "1" as true */ } } Stask(); return(FALSE); } void FlashButton (DialogPtr theDialog, short item) { short itemType; ControlHandle theItem; Rect itemRect; DELAYLONG myticks; if (item > 0) { GetDialogItem(theDialog,item,&itemType,(Handle *)&theItem,&itemRect); HiliteControl(theItem,1); Delay(8,&myticks); HiliteControl(theItem,0); } } SIMPLE_UPP(DLOGwOK, ModalFilter); pascal short DLOGwOK( DialogPtr dptr, EventRecord *evt, short *item) { return(MyDLOGfilter(dptr, evt, item, true, false, false)); } SIMPLE_UPP(DLOGwOK_Cancel, ModalFilter); pascal short DLOGwOK_Cancel( DialogPtr dptr, EventRecord *evt, short *item) { return(MyDLOGfilter(dptr, evt, item, true, true, false)); } SIMPLE_UPP(DLOGwOK_Cancel_Popup, ModalFilter); pascal short DLOGwOK_Cancel_Popup( DialogPtr dptr, EventRecord *evt, short *item) { return(MyDLOGfilter(dptr, evt, item, true, true, true)); } // Our standard modal dialog box filter. // RAB BetterTelnet 1.2 - we use StdFilterProc now... SIMPLE_UPP(MyDLOGfilter, ModalFilter); pascal short MyDLOGfilter( DialogPtr dptr, EventRecord *evt, short *item, Boolean hasOK, Boolean hasCancel, Boolean hasPopup) { short keyCode, key, iType; Handle iHndl; Rect iRect; if (hasOK) SetDialogDefaultItem(dptr, 1); if (hasCancel) SetDialogCancelItem(dptr, 2); SetDialogTracksCursor(dptr, 1); SetPort(dptr); /* if (evt->what == keyDown) { key = evt->message & charCodeMask; keyCode = (evt->message >>8) & 0xff ; if (((key == 0x0d) || (key == 0x03)) && hasOK) { // 0x0d == return, 0x03 == enter *item = DLOGOk; // ok FlashButton(dptr, DLOGOk); return(-1); } if ((((key == '.') && (evt->modifiers & cmdKey)) || ((key == 0x1b) && (keyCode == 0x35))) && hasCancel) { // 0x35 == escKey *item = DLOGCancel; FlashButton(dptr, DLOGCancel); return(-1); } } else if ((evt->what == updateEvt) && hasOK) { if ((WindowPtr)evt->message == dptr) { // GetDialogItem(dptr,DLOGOk,&iType,&iHndl,&iRect); // ok // PenSize(3,3); // InsetRect(&iRect,-4,-4); // FrameRoundRect(&iRect,16,16); } } */ if ((evt->what == mouseDown) && hasPopup) return(PopupMousedown(dptr, evt, item)); Stask(); return CallStdFilterProc(dptr, evt, item); } #if 0 // Our standard modal dialog box filter with code to handle popup user items. pascal short MyDLOGfilterWPopupFilter( DialogPtr dptr, EventRecord *evt, short *item) { short keyCode, key, iType; Handle iHndl; Rect iRect; SetPort(dptr); if (evt->what == keyDown) { key = evt->message & charCodeMask; keyCode = (evt->message >>8) & 0xff ; if ((key == 0x0d) || (key == 0x03)) { // 0x0d == return, 0x03 == enter *item = DLOGOk; // ok FlashButton(dptr, DLOGOk); return(-1); } if (((key == '.') && (evt->modifiers & cmdKey)) || ((key == 0x1b) && (keyCode == 0x35)) ) { // 0x35 == escKey *item = DLOGCancel; FlashButton(dptr, DLOGCancel); return(-1); } } else if (evt->what == updateEvt) { if ((WindowPtr)evt->message == dptr) { GetDialogItem(dptr,DLOGOk,&iType,&iHndl,&iRect); // ok PenSize(3,3); InsetRect(&iRect,-4,-4); FrameRoundRect(&iRect,16,16); } } if (evt->what == mouseDown) return(PopupMousedown(dptr, evt, item)); Stask(); return(FALSE); } #endif #ifdef NO_UNIVERSAL #define LMSetSFSaveDisk(SFSaveDiskValue) ((* (short *) 0x0214) = (SFSaveDiskValue)) #define LMGetSFSaveDisk() (* (short *) 0x0214) #define LMGetCurDirStore() (* (long *) 0x0398) #define LMSetCurDirStore(CurDirStoreValue) ((* (long *) 0x0398) = (CurDirStoreValue)) #endif void SelectDirectory(short *VRefNum, long *DirID) { Point where; SFReply sfr; LMSetSFSaveDisk( - (*VRefNum)); LMSetCurDirStore(*DirID); StandardFileCenter(&where, WDSET_DLOG); TelInfo->setdir = 0; /* clear dir found flag */ SFPGetFile( where, NULL, FolderFilterUPP, -1, NULL, /* BYU LSC */ FileHookUPP, &sfr, WDSET_DLOG, modalProcUPP); if (TelInfo->setdir) /* we got a dir */ { *VRefNum = - LMGetSFSaveDisk(); *DirID = LMGetCurDirStore(); } } SIMPLE_UPP(FileHook, DlgHook); pascal short FileHook( short item, DialogPtr theDialog) { #ifdef MPW #pragma unused(theDialog) #endif if(item == 11) { /* Set Directory Button */ TelInfo->setdir = 1; return(3); /* pretend we hit cancel, but we didn't */ } else if (item == 12) item = 9; /* these don't count, map to disabled item */ return(item); } SIMPLE_UPP(FolderFilter, FileFilter); pascal Boolean FolderFilter(FileParam *pbp) { if (pbp->ioFlAttrib & 0x0010) return(FALSE); else return(-1); } OSErr SetIndString(StringPtr theStr,short resID,short strIndex) { Handle theRes; /* handle pointing to STR# resource */ short numStrings; /* number of strings in STR# */ short ourString; /* counter to index up to strIndex */ char *resStr; /* string pointer to STR# string to replace */ long oldSize; /* size of STR# resource before call */ long newSize; /* size of STR# resource after call */ unsigned long offset; /* resource offset to str to replace*/ OSErr memError; /* make sure index is in bounds */ if (resID < 1) return -1; /* make sure resource exists */ theRes = GetResource('STR#',resID); if (ResError()!=noErr) return ResError(); if (!theRes || !(*theRes)) return resNotFound; HLock(theRes); HNoPurge(theRes); /* get # of strings in STR# */ BlockMove(*theRes,&numStrings,sizeof(short)); if (strIndex > numStrings) return resNotFound; /* get a pointer to the string to replace */ offset = sizeof(short); resStr = (char *) *theRes + sizeof(short); for (ourString=1; ourStringcontR = ((GrafPtr)win)->portRect; */ /* win->qWindow.refCon = CREATOR; */ return(win); } /* Do a GetNewMyDialog, but make the text small... */ WindowPtr GetNewMySmallDialog(short template,Ptr wStorage,WindowPtr behind, void (*centerFunction)(short)) { short size; DialogPtr dlogptr; size = 9; SetDialogFont(applFont); dlogptr = GetNewMyDialog(template,wStorage,behind,centerFunction); SetDialogFont(systemFont); if (dlogptr==nil) return 0; SetPort(dlogptr); TextSize(size); TextFont(applFont); { TEHandle teh = ((DialogPeek)dlogptr)->textH; ControlHandle cntl = (ControlHandle)((WindowPeek)dlogptr)->controlList; (*teh)->txSize = size; (*teh)->lineHeight = GetLeading(applFont,size); (*teh)->fontAscent = GetAscent(applFont,size); } /* For those dialogs with non-system font buttons, make them inititally invisible and then do a ShowWindow. This keeps the Control Manager from every using Chicago on our turf. -- JMB */ if (! ((((DialogPeek) dlogptr)->window).visible)) ShowWindow(dlogptr); return(dlogptr); } /* Do a GetNewMySmallDialog, but read the item titles from a STR#... */ WindowPtr GetNewMySmallStrangeDialog(short template,Ptr wStorage,WindowPtr behind, void (*centerFunction)(short)) { short size, index, limit, itemType; DialogPtr dlogptr; Handle resource; ControlHandle itemHandle; Rect scratchRect; Str255 scratchPstring; size = 9; SetDialogFont(applFont); dlogptr = GetNewMyDialog(template,wStorage,behind,centerFunction); SetDialogFont(systemFont); if (dlogptr==nil) return 0; SetPort(dlogptr); TextSize(size); TextFont(applFont); { TEHandle teh = ((DialogPeek)dlogptr)->textH; ControlHandle cntl = (ControlHandle)((WindowPeek)dlogptr)->controlList; (*teh)->txSize = size; (*teh)->lineHeight = GetLeading(applFont,size); (*teh)->fontAscent = GetAscent(applFont,size); } /* For those dialogs with non-system font buttons, make them inititally invisible and then do a ShowWindow. This keeps the Control Manager from ever using Chicago on our turf. -- JMB */ if ((resource = GetResource('STR#', template)) != NULL) { short base; Str255 baseStr; GetIndString(baseStr, template, 1); base = atoi(p2cstr(baseStr)); limit = *(short *)(*resource); ReleaseResource(resource); for(index = 2; index <= limit; index++) { GetDialogItem(dlogptr, index + base, &itemType, (Handle *)&itemHandle, &scratchRect); if ((itemType == 7) && ((**itemHandle).contrlRfCon == 1991)) { GetIndString(scratchPstring, template, index); SetControlTitle(itemHandle, scratchPstring); } } } return(dlogptr); } // RAB BetterTelnet 1.2: // Do a GetNewMySmallStrange Dialog, but use Geneva 10, not Geneva 9... WindowPtr GetNewMySmall10StrangeDialog(short template,Ptr wStorage,WindowPtr behind, void (*centerFunction)(short)) { short size, index, limit, itemType; DialogPtr dlogptr; Handle resource; ControlHandle itemHandle; Rect scratchRect; Str255 scratchPstring; size = 10; SetDialogFont(applFont); dlogptr = GetNewMyDialog(template,wStorage,behind,centerFunction); SetDialogFont(systemFont); if (dlogptr==nil) return 0; SetPort(dlogptr); TextSize(size); TextFont(applFont); { TEHandle teh = ((DialogPeek)dlogptr)->textH; ControlHandle cntl = (ControlHandle)((WindowPeek)dlogptr)->controlList; (*teh)->txSize = size; (*teh)->lineHeight = GetLeading(applFont,size); (*teh)->fontAscent = GetAscent(applFont,size); } if ((resource = GetResource('STR#', template)) != NULL) { short base; Str255 baseStr; GetIndString(baseStr, template, 1); base = atoi(p2cstr(baseStr)); limit = *(short *)(*resource); ReleaseResource(resource); for(index = 2; index <= limit; index++) { GetDialogItem(dlogptr, index + base, &itemType, (Handle *)&itemHandle, &scratchRect); if ((itemType == 7) && ((**itemHandle).contrlRfCon == 1991)) { GetIndString(scratchPstring, template, index); SetControlTitle(itemHandle, scratchPstring); } } } return(dlogptr); } // Hide a range of dialog items. RAB BetterTelnet 1.2 void HideDialogItemRange(DialogPtr dlogp, short startItem, short endItem) { short i; for (i = startItem; i <= endItem; i++) HideDialogItem(dlogp, i); } // Show a range of dialog items. RAB BetterTelnet 1.2 void ShowDialogItemRange(DialogPtr dlogp, short startItem, short endItem) { short i; for (i = startItem; i <= endItem; i++) ShowDialogItem(dlogp, i); } // RAB BetterTelnet 1.2 // Draw the background color over an item. Needed to hide NCSA's brain-dead // fake popup menus. One of these days, I'll rip out popup.c, but until then... void DrawBlank(DialogPtr dlogp, short theItem) { Handle hdl; Rect box; short type; GrafPtr savePort; GetDialogItem(dlogp, theItem, &type, &hdl, &box); GetPort(&savePort); SetPort(dlogp); InsetRect(&box, -5, -5); EraseRect(&box); SetPort(savePort); } /********************************************************************** * write zeroes over an area of memory **********************************************************************/ void WriteZero(Ptr pointer,long size) { while (size--) *pointer++ = 0; } /********************************************************************** * figure out the appropriate leading for a font **********************************************************************/ short GetLeading(short fontID,short fontSize) { FMInput fInInfo; FMOutput *fOutInfo; /* set up the font input struct */ fInInfo.family = fontID; fInInfo.size = fontSize; fInInfo.face = 0; fInInfo.needBits = FALSE; fInInfo.device = 0; fInInfo.numer.h = fInInfo.numer.v = 1; fInInfo.denom.h = fInInfo.denom.v = 1; /* get the actual info */ fOutInfo = FMSwapFont(&fInInfo); return(((fOutInfo->leading + fOutInfo->ascent + fOutInfo->descent)*fOutInfo->numer.v)/fOutInfo->denom.v); } /********************************************************************** * find ascent font **********************************************************************/ short GetAscent(short fontID,short fontSize) { FMInput fInInfo; FMOutput *fOutInfo; /* set up the font input struct */ fInInfo.family = fontID; fInInfo.size = fontSize; fInInfo.face = 0; fInInfo.needBits = FALSE; fInInfo.device = 0; fInInfo.numer.h = fInInfo.numer.v = 1; fInInfo.denom.h = fInInfo.denom.v = 1; /* get the actual info */ fOutInfo = FMSwapFont(&fInInfo); return((fOutInfo->ascent * fOutInfo->numer.v)/fOutInfo->denom.v); } /************************************************************************ * CenterRectIn - center one rect in another ************************************************************************/ void CenterRectIn(Rect *inner,Rect *outer) { OffsetRect(inner,(outer->left+outer->right-inner->left-inner->right)/2, (outer->top+outer->bottom-inner->top-inner->bottom)/2); } /************************************************************************ * TopCenterRectIn - center one rect in (the bottom of) another ************************************************************************/ void TopCenterRectIn(Rect *inner,Rect *outer) { OffsetRect(inner,(outer->left+outer->right-inner->left-inner->right)/2, outer->top-inner->top); } /************************************************************************ * BottomCenterRectIn - center one rect in (the bottom of) another ************************************************************************/ void BottomCenterRectIn(Rect *inner,Rect *outer) { OffsetRect(inner,(outer->left+outer->right-inner->left-inner->right)/2, outer->bottom-inner->bottom); } /************************************************************************ * ThirdCenterRectIn - center one rect in (the top 1/3 of) another ************************************************************************/ void ThirdCenterRectIn(Rect *inner,Rect *outer) { OffsetRect(inner,(outer->left+outer->right-inner->left-inner->right)/2, outer->top-inner->top + (outer->bottom-outer->top-inner->bottom+inner->top)/3); } void SecondThirdCenterRectIn(Rect *inner,Rect *outer) { OffsetRect(inner,(outer->left+outer->right-inner->left-inner->right)/2, outer->top-inner->top + 2*(outer->bottom-outer->top-inner->bottom+inner->top)/3); } void ThirdCenterDialog(short id) { DialogTHndl dTempl; Rect r = qd.screenBits.bounds; r.top += GetMBarHeight(); dTempl=(DialogTHndl)GetResource('ALRT',id); if (!dTempl) dTempl=(DialogTHndl)GetResource('DLOG',id); if (dTempl) ThirdCenterRectIn(&(*dTempl)->boundsRect,&r); } void SecondThirdCenterDialog(short id) { DialogTHndl dTempl; Rect r = qd.screenBits.bounds; r.top += GetMBarHeight(); dTempl=(DialogTHndl)GetResource('ALRT',id); if (!dTempl) dTempl=(DialogTHndl)GetResource('DLOG',id); if (dTempl) SecondThirdCenterRectIn(&(*dTempl)->boundsRect,&r); } /************************************************************************ * StandardFileCenter - figure out where a stdfile dialog should go ************************************************************************/ void StandardFileCenter(Point *where, short id) { Rect r,in; DialogTHndl dTempl; dTempl=(DialogTHndl)GetResource('ALRT',id); if (!dTempl) dTempl=(DialogTHndl)GetResource('DLOG',id); if (dTempl) { r = (*dTempl)->boundsRect; in = qd.screenBits.bounds; in.top += GetMBarHeight(); ThirdCenterRectIn(&r,&in); where->h = r.left; where->v = r.top; } else { where->h = 100; where->v = 100; } } /* Pascal string utilities */ /* pstrcat - add string 'src' to end of string 'dst' */ void pstrcat(StringPtr dst, StringPtr src) { /* copy string in */ BlockMove(src + 1, dst + *dst + 1, *src); /* adjust length byte */ *dst += *src; } /* pstrinsert - insert string 'src' at beginning of string 'dst' */ void pstrinsert(StringPtr dst, StringPtr src) { /* make room for new string */ BlockMove(dst + 1, dst + *src + 1, *dst); /* copy new string in */ BlockMove(src + 1, dst + 1, *src); /* adjust length byte */ *dst += *src; } void pstrcpy(StringPtr dst, StringPtr src) { BlockMove(src, dst, *src + 1); } \ No newline at end of file diff --git a/source/debug:errors/DlogUtils.proto.h b/source/debug:errors/DlogUtils.proto.h index f103e93..227995d 100755 --- a/source/debug:errors/DlogUtils.proto.h +++ b/source/debug:errors/DlogUtils.proto.h @@ -1 +1 @@ - /* DlogUtils.c */ void HideDItemRange(DialogPtr, short, short); void ShowDItemRange(DialogPtr, short, short); void DrawBlank(DialogPtr, short); void GetTEText(DialogPtr dptr, short item, Str255 str); void SetTEText(DialogPtr dptr, short item, Str255 str); void Hilite(DialogPtr dptr, short item, short value); void FlipCheckBox(DialogPtr dptr, short item); void FlipRadioButton(DialogPtr dptr, short item); void SetCntrl(DialogPtr dptr, short item, short value); short GetCntlVal(DialogPtr dptr, short item); void FlashButton(DialogPtr theDialog, short item); short findPopupMenuItem(MenuHandle theHandle, Str255 name); void SelectDirectory(short *VRefNum, long *DirID); OSErr SetIndString(StringPtr theStr, short resID, short strIndex); WindowPtr GetNewMyDialog(short template, Ptr wStorage, WindowPtr behind, void (*centerFunction )(short)); WindowPtr GetNewMySmallDialog(short template, Ptr wStorage, WindowPtr behind, void (*centerFunction )(short)); WindowPtr GetNewMySmallStrangeDialog(short template, Ptr wStorage, WindowPtr behind, void (*centerFunction )(short)); WindowPtr GetNewMySmall10StrangeDialog(short template, Ptr wStorage, WindowPtr behind, void (*centerFunction )(short)); void WriteZero(Ptr pointer, long size); short GetLeading(short fontID, short fontSize); short GetAscent(short fontID, short fontSize); void CenterRectIn(Rect *inner, Rect *outer); void TopCenterRectIn(Rect *inner, Rect *outer); void BottomCenterRectIn(Rect *inner, Rect *outer); void ThirdCenterRectIn(Rect *inner, Rect *outer); void ThirdCenterDialog(short template); void SecondThirdCenterDialog(short id); void SecondThirdCenterRectIn(Rect *inner,Rect *outer); void StandardFileCenter(Point *where, short id); void pstrcat(StringPtr dst, StringPtr src); void pstrinsert(StringPtr dst, StringPtr src); void pstrcpy(StringPtr dst, StringPtr src); pascal short DLOGwOK( DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(DLOGwOK, ModalFilter); pascal short DLOGwOK_Cancel( DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(DLOGwOK_Cancel, ModalFilter); pascal short DLOGwOK_Cancel_Popup( DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(DLOGwOK_Cancel_Popup, ModalFilter); pascal short MyDLOGfilter( DialogPtr dptr, EventRecord *evt, short *item, Boolean hasOK, Boolean hasCancel, Boolean hasPopup); PROTO_UPP(MyDLOGfilter, ModalFilter); pascal void OutlineItem(DialogPtr dptr, short itm); PROTO_UPP(OutlineItem, UserItem); pascal void VersionNumber(DialogPtr dptr, short itm); PROTO_UPP(VersionNumber, UserItem); #ifndef NO_UNIVERSAL void UItemAssign( DialogPtr dptr, short item, UserItemUPP proc); #else void UItemAssign( DialogPtr dptr, short item, ProcPtr proc); #endif \ No newline at end of file + /* DlogUtils.c */ void HideDialogItemRange(DialogPtr, short, short); void ShowDialogItemRange(DialogPtr, short, short); void DrawBlank(DialogPtr, short); void GetTEText(DialogPtr dptr, short item, Str255 str); void SetTEText(DialogPtr dptr, short item, Str255 str); void Hilite(DialogPtr dptr, short item, short value); void FlipCheckBox(DialogPtr dptr, short item); void FlipRadioButton(DialogPtr dptr, short item); void SetCntrl(DialogPtr dptr, short item, short value); short GetCntlVal(DialogPtr dptr, short item); void FlashButton(DialogPtr theDialog, short item); short findPopupMenuItem(MenuHandle theHandle, Str255 name); void SelectDirectory(short *VRefNum, long *DirID); OSErr SetIndString(StringPtr theStr, short resID, short strIndex); WindowPtr GetNewMyDialog(short template, Ptr wStorage, WindowPtr behind, void (*centerFunction )(short)); WindowPtr GetNewMySmallDialog(short template, Ptr wStorage, WindowPtr behind, void (*centerFunction )(short)); WindowPtr GetNewMySmallStrangeDialog(short template, Ptr wStorage, WindowPtr behind, void (*centerFunction )(short)); WindowPtr GetNewMySmall10StrangeDialog(short template, Ptr wStorage, WindowPtr behind, void (*centerFunction )(short)); void WriteZero(Ptr pointer, long size); short GetLeading(short fontID, short fontSize); short GetAscent(short fontID, short fontSize); void CenterRectIn(Rect *inner, Rect *outer); void TopCenterRectIn(Rect *inner, Rect *outer); void BottomCenterRectIn(Rect *inner, Rect *outer); void ThirdCenterRectIn(Rect *inner, Rect *outer); void ThirdCenterDialog(short template); void SecondThirdCenterDialog(short id); void SecondThirdCenterRectIn(Rect *inner,Rect *outer); void StandardFileCenter(Point *where, short id); void pstrcat(StringPtr dst, StringPtr src); void pstrinsert(StringPtr dst, StringPtr src); void pstrcpy(StringPtr dst, StringPtr src); pascal short DLOGwOK( DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(DLOGwOK, ModalFilter); pascal short DLOGwOK_Cancel( DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(DLOGwOK_Cancel, ModalFilter); pascal short DLOGwOK_Cancel_Popup( DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(DLOGwOK_Cancel_Popup, ModalFilter); pascal short MyDLOGfilter( DialogPtr dptr, EventRecord *evt, short *item, Boolean hasOK, Boolean hasCancel, Boolean hasPopup); PROTO_UPP(MyDLOGfilter, ModalFilter); pascal void OutlineItem(DialogPtr dptr, short itm); PROTO_UPP(OutlineItem, UserItem); pascal void VersionNumber(DialogPtr dptr, short itm); PROTO_UPP(VersionNumber, UserItem); #ifndef NO_UNIVERSAL void UItemAssign( DialogPtr dptr, short item, UserItemUPP proc); #else void UItemAssign( DialogPtr dptr, short item, ProcPtr proc); #endif \ No newline at end of file diff --git a/source/debug:errors/SmartTrackControl.c b/source/debug:errors/SmartTrackControl.c new file mode 100755 index 0000000..95cf582 --- /dev/null +++ b/source/debug:errors/SmartTrackControl.c @@ -0,0 +1 @@ +/*************************************************************************************** Smart Track Control SmartTrackControl.c Copyright 1994-1996 Bob Bradley, All Rights Reserved ***************************************************************************************/ // Revised 2/98 by Rolf Braun for BetterTelnet 2.0 // to handle signed control minimums and maximums #ifndef _SMARTTRACKCONTROL_ #include "SmartTrackControl.h" #endif /*************************************************************************************** SmartTrackControl Replaces TrackControl to correctly handle situations where the click is in the thumb portion of the control. ***************************************************************************************/ short SmartTrackControl( ControlRef control, Point where, ControlActionUPP ActionProc ) { short part; short newControlValue; Rect dragLimits; Boolean isVertical; Point currentPoint; short pixelValue; // Figure out where the click occurred. part = TestControl( control, where ); // Check if TrackControl can handle it on it's own. if( !( ( part == inThumb ) && ( ActionProc != ( ControlActionUPP ) 0 ) ) ) { // For cases when the click isn't in the thumb AND the action proc is isn't // greater than zero (ie. it's doesn't appears to be a valid ActionProc), // TrackControl does it correctly (at least as far as I know). return( TrackControl( control, where, ActionProc ) ); } // The click is in the indicator (thumb) and the caller passed us a seemingly // valid action proc (UniversalProcPtr). We need to replace the behavior of // TrackControl cause TrackControl doesn't handle clicks inThumb correctly. It // doesn't pass anything in the ActionProc's parameter so you'd have to use globals // if you want to implement live scroll. It also would only draw the thumb's outline // which isn't really accurate since you would be changing the data on the fly and // the thumb should be drawn normal and just move with the mouse. This replacement // will do all the work of calculating the thumb position and then calling the // ActionProc but, it will use the same ActionProc parameters as clicks inXXButton // and inPageXX do so it's completely consistant with the other ActionProcs. // This or something which allows the same functionality should have been done from // the start. // Get the bounds of the control. GetControlBounds( control, &dragLimits ); // Check it to see if it's a vertical or horizontal control. if( ( dragLimits.bottom - dragLimits.top ) > ( dragLimits.right - dragLimits.left ) ) { // It's vertical so set the isVertical flag and subtract the arrows from the // top and bottom of the dragLimit rect. We also subtract the area of the thumb // away from the top and bottom. We do this by subtracing half of the thumb size // from the top and half from the bottom. I'm just shifting the bits to right to // divide by two since it's a lot faster to bit-shift than to divide. isVertical = true; dragLimits.top += ( kScrollBarThumbSize + ( kScrollBarThumbSize >> 1 ) ); dragLimits.bottom -= ( kScrollBarThumbSize + ( kScrollBarThumbSize >> 1 ) ); } else { // It's not vertical so clear the isVertical flag and subtract the arrows from // the left and right of the dragLimit rect. We also subtract the area of the // thumb away from the left and right. We do this by subtracing half of the thumb // size from the left and half from the right. I'm just shifting the bits to right // to divide by two since it's a lot faster to bit-shift than to divide. isVertical = false; dragLimits.left += ( kScrollBarThumbSize + ( kScrollBarThumbSize >> 1 ) ); dragLimits.right -= ( kScrollBarThumbSize + ( kScrollBarThumbSize >> 1 ) ); } // Start the mouse tracking loop. while( StillDown() ) { // Get the current mouse location. GetMouse( ¤tPoint ); // Since the horizontal and vertical calculations are basically the same, I'll // just explain this once here for both horizontal and vertical. // // Calculate the new control value based on the mouse's location within the // dragLimits rect of the control. To do this, We pin the current point to a // point inside the dragLimits rect, calculate the distance from the top (or // left) of the dragLimits to the point that we just pinned, and finally, we // translate the value we just calculated from the dragLimits rect's top and // bottom (or left and right) to the controls' minimum and maximum. This tells // us what the control value should be in relation to where the mouse is // located within the dragLimits rect. It's just a transformation function. if( isVertical ) { currentPoint.v = PinValueInRange( currentPoint.v, dragLimits.top, dragLimits.bottom ); pixelValue = currentPoint.v - dragLimits.top; newControlValue = TranslateValue( dragLimits.top, dragLimits.bottom, pixelValue, GetControlMinimum( control ), GetControlMaximum( control ) ); } else { currentPoint.h = PinValueInRange( currentPoint.h, dragLimits.left, dragLimits.right ); pixelValue = currentPoint.h - dragLimits.left; newControlValue = TranslateValue( dragLimits.left, dragLimits.right, pixelValue, GetControlMinimum( control ), GetControlMaximum( control ) ); } // Set the new control value to the value that we just calculated. SetControlValue( control, newControlValue ); // Call the ActionProc but, this time we call the normal action proc that is // used by inXXButton and inPageXX, not the one TrackControl calls for inThumb. CallControlActionProc( ActionProc, control, part ); } return( part ); } /*************************************************************************************** GetControlBounds ***************************************************************************************/ void GetControlBounds( ControlRef control, Rect *controlBounds ) { *controlBounds = ( **control ).contrlRect; } /************************************************************************************* PinValueInRange This pins the value passed in between the start and end parameters. The pinned value is return. *************************************************************************************/ long PinValueInRange( long value, long rangeStart, long rangeEnd ) { // Here's two versions of the same code. The commented one is a lot more readable // but, I heard the ? : operators are faster somehow since the compiler can // optimize better of something. It's probably not even true and even if it is, it // probably wouldn't make any difference anyway but, I'll let you do the choosing. // RAB BetterTelnet - I was bored one day, and I tested this. The generated assembly code // is almost identical, except for the registers it uses. So I guess it doesn't really matter... /* if( value > rangeEnd ) { return( rangeEnd ); } else { if( value < rangeStart ) { return( rangeStart ); } else { return( value ); } } */ return( ( value > rangeEnd ) ? rangeEnd : ( ( value < rangeStart ) ? rangeStart : value ) ); } /************************************************************************************* TranslateValue Translate a value from one range to another. This works in going from larger to smaller and from smaller to larger. It is generally used to translate a long coordinate to a short coordinate or vice versa in order to work with QuickDraw's 2-byte limitation on it's coordinate system. *************************************************************************************/ long TranslateValue( long min, long max, long value, long newMin, long newMax ) { Fixed ratio; long result; long difference; if (newMin < 0) { difference = 0 - newMin; newMin += difference; newMax += difference; } else difference = 0; ratio = FixDiv( ( max - min ), value ); result = FixDiv( ( newMax - newMin ), ratio ); result = PinValueInRange( result, newMin, newMax ); result -= difference; return( result ); } \ No newline at end of file diff --git a/source/debug:errors/SmartTrackControl.h b/source/debug:errors/SmartTrackControl.h new file mode 100755 index 0000000..25ef844 --- /dev/null +++ b/source/debug:errors/SmartTrackControl.h @@ -0,0 +1 @@ +/*************************************************************************************** Smart Track Control SmartTrackControl.h Copyright 1994-1996 Bob Bradley, All Rights Reserved ***************************************************************************************/ #ifndef _SMARTTRACKCONTROL_ #define _SMARTTRACKCONTROL_ /*************************************************************************************** Constants ***************************************************************************************/ enum { kScrollBarThumbSize = 16 }; /*************************************************************************************** Prototypes ***************************************************************************************/ short SmartTrackControl( ControlRef control, Point where, ControlActionUPP ActionProc ); void GetControlBounds( ControlRef control, Rect *controlBounds ); long PinValueInRange( long value, long rangeStart, long rangeEnd ); long TranslateValue( long min, long max, long value, long newMin, long newMax ); #endif \ No newline at end of file diff --git a/source/debug:errors/debug.c b/source/debug:errors/debug.c index 486f5e7..5b1820a 100755 --- a/source/debug:errors/debug.c +++ b/source/debug:errors/debug.c @@ -1 +1 @@ -// debug.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "vsdata.h" #include "vsinterf.proto.h" // For VSwrite proto #include "wind.h" // For WindRec structure #include "parse.proto.h" // For DemangleLinemodeShort #include "rsinterf.proto.h" // For RSshow proto #include "linemode.proto.h" WindRec *console; // Window Record (VS) for console Window extern WindRec *screens; //#define DEBUG_FACILITIES void InitDebug(void) { #ifdef DEBUG_FACILITIES Rect pRect; TerminalPrefs **termHdl; Boolean scratchBoolean; console = (WindRec *) myNewPtr(sizeof(WindRec)); SetRect(&pRect, 50, 150, 700, 350); // Need to make this a resource! console->vs=RSnewwindow( &pRect, 350, 80, 24, "\p", 1, DefFONT, DefSIZE, TelInfo->debug,0,0,0,0,1, DefFONT, DefSIZE, 0, 0); /* NCSA 2.5 */ console->wind = RSgetwindow( console->vs); ((WindowPeek)console->wind)->windowKind = WIN_CONSOLE; VSwrite(console->vs,"\033[24;0H",1); console->active=0; console->port=0; console->termstate=VTEKTYPE; console->national = 0; /* LU: no translation */ UseResFile(TelInfo->SettingsFile); termHdl = (TerminalPrefs **)Get1NamedResource (TERMINALPREFS_RESTYPE, "\p"); DetachResource((Handle) termHdl); HLock((Handle)termHdl); scratchBoolean = RSsetcolor( console->vs, 0, (*termHdl)->nfcolor); scratchBoolean = RSsetcolor( console->vs, 1, (*termHdl)->nbcolor); scratchBoolean = RSsetcolor( console->vs, 2, (*termHdl)->bfcolor); scratchBoolean = RSsetcolor( console->vs, 3, (*termHdl)->bbcolor); DisposeHandle((Handle)termHdl); #else console = NULL; #endif } void putln( char *cp) { #ifdef DEBUG_FACILITIES short temp; if (!TelInfo->debug) return; temp=strlen(cp); if (temp>80) return; VSwrite(console->vs,cp,temp); VSwrite(console->vs,"\015\012",2); #endif } // Called by HandleKeyDown. Allows me to insert debug info keys all in one place // that can be easily #defined out for release versions. Returns TRUE if // HandleKeyDown should do an immediate return after calling us. Boolean DebugKeys(Boolean cmddwn, unsigned char ascii, short s) { #ifdef DEBUG_FACILITIES if (cmddwn && (ascii == ';')) { // 2.6b16.1 char hackhackhack[80]; strcpy(hackhackhack, "Linemode: "); DemangleLineModeShort(hackhackhack, screens[s].lmodeBits); putln(hackhackhack); return(FALSE); } if (cmddwn && (ascii == 39)) //single quote ShowDebugWindow(); return(FALSE); #endif return (FALSE); } void ShowDebugWindow(void) { #ifdef DEBUG_FACILITIES if (console != NULL) { TelInfo->debug = TRUE; RSshow(console->vs); } #endif } \ No newline at end of file +// debug.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "vsdata.h" #include "vsinterf.proto.h" // For VSwrite proto #include "wind.h" // For WindRec structure #include "parse.proto.h" // For DemangleLinemodeShort #include "rsinterf.proto.h" // For RSshow proto #include "linemode.proto.h" #include "prefs.proto.h" WindRec *console; // Window Record (VS) for console Window extern WindRec *screens; #define DEBUG_FACILITIES void InitDebug(void) { #ifdef DEBUG_FACILITIES Rect pRect; TerminalPrefs **termHdl; Boolean scratchBoolean; console = (WindRec *) myNewPtr(sizeof(WindRec)); // SetRect(&pRect, 50, 150, 700, 350); // Need to make this a resource! SetRect(&pRect, 50, 150, 0, 0); console->vs=RSnewwindow( &pRect, 350, 80, 24, "\p", 1, DefFONT, DefSIZE, TelInfo->debug,0,0,0,0,0,1, DefFONT, DefSIZE, 0, 0, 1, 0, 0); /* NCSA 2.5 */ console->wind = RSgetwindow( console->vs); ((WindowPeek)console->wind)->windowKind = WIN_CONSOLE; // VSwrite(console->vs,"\033[24;0H",7); console->active=0; console->port=0; console->termstate=VTEKTYPE; console->national = 0; /* LU: no translation */ UseResFile(TelInfo->SettingsFile); termHdl = (TerminalPrefs **)Get1NamedSizedResource (TERMINALPREFS_RESTYPE, "\p", sizeof(TerminalPrefs)); DetachResource((Handle) termHdl); HLock((Handle)termHdl); scratchBoolean = RSsetcolor( console->vs, 0, (*termHdl)->nfcolor); scratchBoolean = RSsetcolor( console->vs, 1, (*termHdl)->nbcolor); scratchBoolean = RSsetcolor( console->vs, 2, (*termHdl)->bfcolor); scratchBoolean = RSsetcolor( console->vs, 3, (*termHdl)->bbcolor); DisposeHandle((Handle)termHdl); #else console = NULL; #endif } void putln( char *cp) { #ifdef DEBUG_FACILITIES short temp; if (!TelInfo->debug) return; temp=strlen(cp); if (temp>80) return; VSwrite(console->vs,cp,temp); VSwrite(console->vs,"\015\012",2); #endif } // Called by HandleKeyDown. Allows me to insert debug info keys all in one place // that can be easily #defined out for release versions. Returns TRUE if // HandleKeyDown should do an immediate return after calling us. Boolean DebugKeys(Boolean cmddwn, unsigned char ascii, short s) { #ifdef DEBUG_FACILITIES if (cmddwn && (ascii == ';')) { // 2.6b16.1 char hackhackhack[80]; strcpy(hackhackhack, "Linemode: "); DemangleLineModeShort(hackhackhack, screens[s].lmodeBits); putln(hackhackhack); return(FALSE); } if (cmddwn && (ascii == 39)) { //single quote if (TelInfo->debug) HideDebugWindow(); else ShowDebugWindow(); return(FALSE); } #endif return (FALSE); } void ShowDebugWindow(void) { #ifdef DEBUG_FACILITIES if (console != NULL) { TelInfo->debug = TRUE; RSshow(console->vs); } #endif } void HideDebugWindow(void) { #ifdef DEBUG_FACILITIES if (console != NULL) { TelInfo->debug = FALSE; RShide(console->vs); } #endif } \ No newline at end of file diff --git a/source/debug:errors/debug.h b/source/debug:errors/debug.h index 4209405..7eaded0 100755 --- a/source/debug:errors/debug.h +++ b/source/debug:errors/debug.h @@ -1 +1 @@ -extern void putln(char *DebugString); void InitDebug(void); Boolean DebugKeys(Boolean cmddwn, unsigned char ascii, short s); void ShowDebugWindow(void); // Don't undef this if compiling for PPC!!!!!!!! Yeah, sure Audit works w/PPC! ;) //#define SUPPORT_AUDIT \ No newline at end of file +extern void putln(char *DebugString); void InitDebug(void); Boolean DebugKeys(Boolean cmddwn, unsigned char ascii, short s); void ShowDebugWindow(void); void HideDebugWindow(void); // Don't undef this if compiling for PPC!!!!!!!! Yeah, sure Audit works w/PPC! ;) //#define SUPPORT_AUDIT \ No newline at end of file diff --git a/source/debug:errors/errors.c b/source/debug:errors/errors.c index 973d2ef..73c014a 100755 --- a/source/debug:errors/errors.c +++ b/source/debug:errors/errors.c @@ -1 +1 @@ -/* * errors.c * This file handles all of the error printing in one centralized place. * There are several classes of errors (network, memory, etc). * To Handle an error, just call into DoError with the appropriate * mask and error number. The routine goes from there. * ***************************************************************** * Revisions: * 7/92 Telnet 2.6: Initial version. Scott Bulmahn */ // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #ifdef MPW #pragma segment Debug #endif #include "InternalEvents.h" #include "DlogUtils.proto.h" #include "mainseg.proto.h" // for forcequit proto #include "errors.proto.h" #include "telneterrors.h" void loadErrors(void) { } // so that we can load this code high and lock it early /*================================= ERROR HANDLING CODE ============================*/ /* This is the main error handling code. Get all the errors out of the resource */ /* file. The resource number that contains the errors depends on what error */ /* class we are talking about */ void DoError(short code, short level, char *mess1) { char buffer1[256],buffer2[256]; short dItem; DialogPtr dtemp; buffer1[0]=0; /* dont print extraneous garbage to the screen... */ buffer2[0]=0; switch (code & ERRORMASK) { case NET_ERRORCLASS: case MEMORY_ERRORCLASS: case RESOURCE_ERRORCLASS: strncpy( buffer1, geterrstring(code), 255); if (mess1) strncpy(buffer2, mess1, 255); break; case NOCODE: /* no code given, just 2 strings */ strncpy(buffer1, mess1, 255); } if (level ==2 || level ==3) { c2pstr(buffer1); c2pstr(buffer2); ParamText((StringPtr) buffer1,(StringPtr) buffer2,"\p","\p"); dtemp=GetNewDialog(OopsDLOG,(Ptr) 0L,kInFront); /* Put up the error notice */ ModalDialog(DLOGwOKUPP,&dItem); /* Get an event */ DisposDialog(dtemp); /* Take it off.....all off......*/ } } /************************************************************************/ /* geterrstring * returns the string associated with a particular error number * NOTE: strings moved to resource # 23237 * error number is formatted %4d at the beginning of the string */ char *geterrstring(short code) { short i; char s[10]; Str255 ErrorString; /* BYU 2.4.16 */ short errorResource, numberOfErrors; switch (code & ERRORMASK) { case NET_ERRORCLASS: errorResource = NETERROR_RESOURCE_ID; numberOfErrors = NETERROR_RESOURCE_COUNT; break; case MEMORY_ERRORCLASS: errorResource = MEMERROR_RESOURCE_ID; numberOfErrors = MEMERROR_RESOURCE_COUNT; break; case RESOURCE_ERRORCLASS: errorResource = RESERROR_RESOURCE_ID; numberOfErrors = RESERROR_RESOURCE_COUNT; break; } code &= FLAGMASK; sprintf(s,"%4d",code); for (i=1; i <= numberOfErrors; i++) { GetIndString(ErrorString,errorResource,i); p2cstr(ErrorString); if (!strncmp((char *) ErrorString,s,4)) return((char *) ErrorString + 5); } GetIndString(ErrorString, errorResource,1); return((char *) ErrorString+5); } void FatalCancelAlert(short messageID, StringPtr DefaultButtonString, short InternalID, short MacID) { Str255 errorString, numberString, numberString2; DialogPtr theDialog; short Type, ditem = 3; Handle Itemh; Rect Box; GetIndString(errorString, GENERAL_MESSAGES_ID, messageID); NumToString((long)InternalID, numberString); NumToString((long)MacID, numberString2); ParamText(errorString, numberString, numberString2, NULL); theDialog = GetNewMyDialog(FATALCANCEL_ID, NULL, kInFront, (void *)ThirdCenterDialog); GetDItem(theDialog, DLOGOk, &Type, &Itemh, &Box); SetCTitle((ControlHandle)Itemh, DefaultButtonString); ShowWindow(theDialog); while (ditem > 2) ModalDialog(DLOGwOK_CancelUPP, &ditem); DisposeDialog(theDialog); // If the user chose quit, then do it... else return. if (ditem == DLOGCancel) forcequit(); } void FatalAlert(short messageID, short InternalID, short MacID) { Str255 errorString, numberString, numberString2; DialogPtr theDialog; short ditem = 3; GetIndString(errorString, GENERAL_MESSAGES_ID, messageID); NumToString((long)InternalID, numberString); NumToString((long)MacID, numberString2); ParamText(errorString, numberString, numberString2, NULL); theDialog = GetNewMyDialog(FATAL_ID, NULL, kInFront, (void *)ThirdCenterDialog); ShowWindow(theDialog); while (ditem > 1) ModalDialog(DLOGwOKUPP, &ditem); forcequit(); // It's a fatal error, so quit } void OperationFailedAlert(short messageID, short InternalID, short MacID) { Str255 errorString, numberString, numberString2; DialogPtr theDialog; short ditem = 3; GetIndString(errorString, OPFAILED_MESSAGES_ID, messageID); NumToString((long)InternalID, numberString); NumToString((long)MacID, numberString2); ParamText(errorString, numberString, numberString2, NULL); theDialog = GetNewMyDialog(OPFAILED_ID, NULL, kInFront, (void *)ThirdCenterDialog); if (theDialog) ShowWindow(theDialog); else return; while (ditem > 1) ModalDialog(DLOGwOKUPP, &ditem); DisposeDialog(theDialog); } void OutOfMemory(short InternalID) { OperationFailedAlert(OUT_OF_MEMORY, InternalID, 0); } // Returns "TRUE" if default button is hit. Boolean AskUserAlert(short messageID, Boolean CancelIsDefault) { Str255 errorString; DialogPtr theDialog; short Type, ditem = 3; Handle Itemh; Rect Box; GetIndString(errorString, GENERAL_MESSAGES_ID, messageID); ParamText(errorString, NULL, NULL, NULL); theDialog = GetNewMyDialog(ASKUSER_ID, NULL, kInFront, (void *)ThirdCenterDialog); if (!CancelIsDefault) { // We need to swap cancel and ok buttons Str255 temp; GetDItem(theDialog, DLOGOk, &Type, &Itemh, &Box); GetIndString(temp,MISC_STRINGS,OK_STRING); SetCTitle((ControlHandle)Itemh, temp); GetDItem(theDialog, DLOGCancel, &Type, &Itemh, &Box); GetIndString(temp,MISC_STRINGS,CANCEL_STRING); SetCTitle((ControlHandle)Itemh, temp); } ShowWindow(theDialog); while (ditem > 2) ModalDialog(DLOGwOK_CancelUPP, &ditem); DisposeDialog(theDialog); if (ditem == 1) return (TRUE); else return (FALSE); } \ No newline at end of file +/* * errors.c * This file handles all of the error printing in one centralized place. * There are several classes of errors (network, memory, etc). * To Handle an error, just call into DoError with the appropriate * mask and error number. The routine goes from there. * ***************************************************************** * Revisions: * 7/92 Telnet 2.6: Initial version. Scott Bulmahn */ // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "InternalEvents.h" #include "DlogUtils.proto.h" #include "mainseg.proto.h" // for forcequit proto #include "errors.proto.h" #include "telneterrors.h" void loadErrors(void) { } // so that we can load this code high and lock it early /*================================= ERROR HANDLING CODE ============================*/ /* This is the main error handling code. Get all the errors out of the resource */ /* file. The resource number that contains the errors depends on what error */ /* class we are talking about */ void DoError(short code, short level, char *mess1) { char buffer1[256],buffer2[256]; short dItem; DialogPtr dtemp; buffer1[0]=0; /* dont print extraneous garbage to the screen... */ buffer2[0]=0; switch (code & ERRORMASK) { case NET_ERRORCLASS: case MEMORY_ERRORCLASS: case RESOURCE_ERRORCLASS: strncpy( buffer1, geterrstring(code), 255); if (mess1) strncpy(buffer2, mess1, 255); break; case NOCODE: /* no code given, just 2 strings */ strncpy(buffer1, mess1, 255); } if (level ==2 || level ==3) { c2pstr(buffer1); c2pstr(buffer2); ParamText((StringPtr) buffer1,(StringPtr) buffer2,"\p","\p"); dtemp=GetNewDialog(OopsDLOG,(Ptr) 0L,kInFront); /* Put up the error notice */ ModalDialog(DLOGwOKUPP,&dItem); /* Get an event */ DisposeDialog(dtemp); /* Take it off.....all off......*/ } } /************************************************************************/ /* geterrstring * returns the string associated with a particular error number * NOTE: strings moved to resource # 23237 * error number is formatted %4d at the beginning of the string */ char *geterrstring(short code) { short i; char s[10]; Str255 ErrorString; /* BYU 2.4.16 */ short errorResource, numberOfErrors; switch (code & ERRORMASK) { case NET_ERRORCLASS: errorResource = NETERROR_RESOURCE_ID; numberOfErrors = NETERROR_RESOURCE_COUNT; break; case MEMORY_ERRORCLASS: errorResource = MEMERROR_RESOURCE_ID; numberOfErrors = MEMERROR_RESOURCE_COUNT; break; case RESOURCE_ERRORCLASS: errorResource = RESERROR_RESOURCE_ID; numberOfErrors = RESERROR_RESOURCE_COUNT; break; } code &= FLAGMASK; sprintf(s,"%4d",code); for (i=1; i <= numberOfErrors; i++) { GetIndString(ErrorString,errorResource,i); p2cstr(ErrorString); if (!strncmp((char *) ErrorString,s,4)) return((char *) ErrorString + 5); } GetIndString(ErrorString, errorResource,1); return((char *) ErrorString+5); } void FatalCancelAlert(short messageID, StringPtr DefaultButtonString, short InternalID, short MacID) { Str255 errorString, numberString, numberString2; DialogPtr theDialog; short Type, ditem = 3; Handle Itemh; Rect Box; GetIndString(errorString, GENERAL_MESSAGES_ID, messageID); NumToString((long)InternalID, numberString); NumToString((long)MacID, numberString2); ParamText(errorString, numberString, numberString2, NULL); theDialog = GetNewMyDialog(FATALCANCEL_ID, NULL, kInFront, (void *)ThirdCenterDialog); GetDialogItem(theDialog, DLOGOk, &Type, &Itemh, &Box); SetControlTitle((ControlHandle)Itemh, DefaultButtonString); ShowWindow(theDialog); while (ditem > 2) ModalDialog(DLOGwOK_CancelUPP, &ditem); DisposeDialog(theDialog); // If the user chose quit, then do it... else return. if (ditem == DLOGCancel) forcequit(); } void FatalAlert(short messageID, short InternalID, short MacID) { Str255 errorString, numberString, numberString2; DialogPtr theDialog; short ditem = 3; GetIndString(errorString, GENERAL_MESSAGES_ID, messageID); NumToString((long)InternalID, numberString); NumToString((long)MacID, numberString2); ParamText(errorString, numberString, numberString2, NULL); theDialog = GetNewMyDialog(FATAL_ID, NULL, kInFront, (void *)ThirdCenterDialog); ShowWindow(theDialog); while (ditem > 1) ModalDialog(DLOGwOKUPP, &ditem); forcequit(); // It's a fatal error, so quit } void OperationFailedAlert(short messageID, short InternalID, short MacID) { Str255 errorString, numberString, numberString2; DialogPtr theDialog; short ditem = 3; GetIndString(errorString, OPFAILED_MESSAGES_ID, messageID); NumToString((long)InternalID, numberString); NumToString((long)MacID, numberString2); ParamText(errorString, numberString, numberString2, NULL); theDialog = GetNewMyDialog(OPFAILED_ID, NULL, kInFront, (void *)ThirdCenterDialog); if (theDialog) ShowWindow(theDialog); else return; while (ditem > 1) ModalDialog(DLOGwOKUPP, &ditem); DisposeDialog(theDialog); } void OutOfMemory(short InternalID) { OperationFailedAlert(OUT_OF_MEMORY, InternalID, 0); } // Returns "TRUE" if default button is hit. Boolean AskUserAlert(short messageID, Boolean CancelIsDefault) { Str255 errorString; DialogPtr theDialog; short Type, ditem = 3; Handle Itemh; Rect Box; GetIndString(errorString, GENERAL_MESSAGES_ID, messageID); ParamText(errorString, NULL, NULL, NULL); theDialog = GetNewMyDialog(ASKUSER_ID, NULL, kInFront, (void *)ThirdCenterDialog); if (!CancelIsDefault) { // We need to swap cancel and ok buttons Str255 temp; GetDialogItem(theDialog, DLOGOk, &Type, &Itemh, &Box); GetIndString(temp,MISC_STRINGS,OK_STRING); SetControlTitle((ControlHandle)Itemh, temp); GetDialogItem(theDialog, DLOGCancel, &Type, &Itemh, &Box); GetIndString(temp,MISC_STRINGS,CANCEL_STRING); SetControlTitle((ControlHandle)Itemh, temp); } ShowWindow(theDialog); while (ditem > 2) ModalDialog(DLOGwOK_CancelUPP, &ditem); DisposeDialog(theDialog); if (ditem == 1) return (TRUE); else return (FALSE); } \ No newline at end of file diff --git a/source/debug:errors/movableModal.c b/source/debug:errors/movableModal.c index 4645025..2037802 100755 --- a/source/debug:errors/movableModal.c +++ b/source/debug:errors/movableModal.c @@ -1 +1 @@ -//---------------------------------------------------------------------------------- // File : movableModal.c // Date : April 4, 1994 // Author : Jim Stout // Purpose : Implements movableModal dialogs //------------------------------------------------------------------------------------ // This was originally written by Jim Stout (of Jim's CDEFs fame), but was extensively // hacked by Rolf Braun for BetterTelnet 1.2. The most important change is that // the new version of movableModal.c now calls StdFilterProc() instead of doing // its own filtering. #include "movableModal.h" #include "menuseg.proto.h" #include "tekrgmac.proto.h" #include "rsinterf.proto.h" extern MenuHandle myMenus[]; pascal void movableModalDialog(ModalFilterUPP filter, short *theItem) { EventRecord theEvent; DialogPtr d,thisDialog; GrafPtr oldPort; thisDialog = FrontWindow(); GetPort(&oldPort); SetPort(thisDialog); for(;;) { WaitNextEvent(everyEvent, &theEvent, 20, 0L); if( (*theItem = preFilterEvent(thisDialog, &theEvent)) != 0) break; if (filter != nil) { if (CallModalFilterProc(filter, thisDialog, &theEvent, theItem)) break; } else if (CallStdFilterProc(thisDialog, &theEvent, theItem)) break; if (IsDialogEvent(&theEvent)) if (DialogSelect(&theEvent, &d, theItem)) break; } SetPort(oldPort); } // RAB BetterTelnet 1.2 // For some reason, StdFilterProc() doesn't seem to return a meaningful result. // CallStdFilterProc() is a kludge that works around this. short CallStdFilterProc(DialogPtr dptr, EventRecord *theEvent, short *ditem) { *ditem = 0; StdFilterProc(dptr, theEvent, ditem); if (*ditem != 0) return -1; return 0; } short preFilterEvent(DialogPtr d, EventRecord *theEvent) { short ret=0; switch (theEvent->what) { case mouseDown: ret = doMouseDialog(d,theEvent); /* handle drag etc. of dialog */ break; case diskEvt: diskEvent(theEvent); break; case updateEvt: break; case keyDown: case autoKey: break; } return (ret); } short doMouseDialog(DialogPtr d, EventRecord *theEvent) { WindowPtr theWindow; short partCode, ret=0, theItem, theMenu; long mResult; switch (partCode = FindWindow(theEvent->where,&theWindow)) { case inDrag: if(theWindow == d) { DragWindow(d, theEvent->where, &qd.screenBits.bounds); theEvent->what = nullEvent; } else SysBeep(1); break; case inMenuBar: mResult = MenuSelect(theEvent->where); HiliteMenu(0); theMenu = mResult >> 16; theItem = mResult & 0xFFFF; if ((theMenu != editMenu) && (theMenu != NeditMenu)) break; switch (theItem) { case EDcut: DialogCut(d); break; case EDcopy: DialogCopy(d); break; case EDpaste: DialogPaste(d); break; case EDclear: DialogDelete(d); break; default: break; } break; case inGoAway: if (TrackBox (theWindow, theEvent->where, partCode)) { ret = cancel; theEvent->what = nullEvent; } break; /* add code if you need to deal with these mouseDown events */ case inGrow: break; case inZoomIn: case inZoomOut: break; case inContent: if(theWindow != d) { SysBeep(1); } break; default: break; } return(ret); } void diskEvent(EventRecord *theEvent) { Point diskInitPt; if (HiWord (theEvent->message) != noErr) { diskInitPt.v = 120; diskInitPt.h = 100; DILoad (); (void) DIBadMount (diskInitPt, theEvent->message); DIUnload (); theEvent->what = nullEvent; } } void SetUpMovableModalMenus(void) { DisableItem(myMenus[Fil], 0); DisableItem(myMenus[0], 1); DisableItem(myMenus[Emul], 0); DisableItem(myMenus[Conn], 0); DisableItem(myMenus[Net], 0); DisableItem(myMenus[OpSpec], 0); DisableItem(myMenus[Keypad], 0); DisableItem(myMenus[Function], 0); DisableItem(myMenus[Edit], EDundo); EnableItem(myMenus[Edit], EDcut); EnableItem(myMenus[Edit], EDcopy); EnableItem(myMenus[Edit], EDpaste); EnableItem(myMenus[Edit], EDclear); DisableItem(myMenus[Edit], EDcopyt); DisableItem(myMenus[Edit], EDretype); DisableItem(myMenus[Edit], EDmacros); DisableItem(myMenus[Edit], EDprefs+1); DisableItem(myMenus[Edit], EDprefs+2); DisableItem(myMenus[Edit], EDprefs+4); DisableItem(myMenus[Edit], EDprefs+5); DrawMenuBar(); HiliteMenu(0); } void ResetMenus(void) { short i; EnableItem(myMenus[Fil], 0); EnableItem(myMenus[0], 1); EnableItem(myMenus[Net], 0); EnableItem(myMenus[OpSpec], 0); DisableItem(myMenus[Edit], EDcut); DisableItem(myMenus[Edit], EDclear); EnableItem(myMenus[Edit], EDcopyt); EnableItem(myMenus[Edit], EDretype); EnableItem(myMenus[Edit], EDmacros); EnableItem(myMenus[Edit], EDprefs+1); EnableItem(myMenus[Edit], EDprefs+2); EnableItem(myMenus[Edit], EDprefs+4); EnableItem(myMenus[Edit], EDprefs+5); AdjustMenus(); DoTheMenuChecks(); DrawMenuBar(); if (!FrontWindow()) return; if ((i=RSfindvwind(FrontWindow()))>=0) { if (RSTextSelected(i)) { EnableItem(myMenus[Edit],EDcopy); EnableItem(myMenus[Edit],EDcopyt); } else { DisableItem(myMenus[Edit],EDcopy); DisableItem(myMenus[Edit],EDcopyt); } } else { if ( (i = RGgetdnum(FrontWindow())) >-1) { if (( i = RGgetVS( i)) >-1) { EnableItem(myMenus[Edit],EDcopy); // - enable copying DisableItem(myMenus[Edit],EDcopyt); } } } } \ No newline at end of file +//---------------------------------------------------------------------------------- // File : movableModal.c // Date : April 4, 1994 // Author : Jim Stout // Purpose : Implements movableModal dialogs //------------------------------------------------------------------------------------ // This was originally written by Jim Stout (of Jim's CDEFs fame), but was extensively // hacked by Rolf Braun for BetterTelnet 1.2. The most important change is that // the new version of movableModal.c now calls StdFilterProc() instead of doing // its own filtering. #include "movableModal.h" #include "menuseg.proto.h" #include "tekrgmac.proto.h" #include "rsinterf.proto.h" #include "event.proto.h" extern MenuHandle myMenus[]; pascal void movableModalDialog(ModalFilterUPP filter, short *theItem) { EventRecord theEvent; DialogPtr d,thisDialog; GrafPtr oldPort; thisDialog = FrontWindow(); GetPort(&oldPort); SetPort(thisDialog); for(;;) { WaitNextEvent(everyEvent, &theEvent, 20, 0L); if( (*theItem = preFilterEvent(thisDialog, &theEvent)) != 0) break; if (filter != nil) { if (CallModalFilterProc(filter, thisDialog, &theEvent, theItem)) break; } else if (CallStdFilterProc(thisDialog, &theEvent, theItem)) break; if (IsDialogEvent(&theEvent)) if (DialogSelect(&theEvent, &d, theItem)) break; } SetPort(oldPort); } // RAB BetterTelnet 1.2 // For some reason, StdFilterProc() doesn't seem to return a meaningful result. // CallStdFilterProc() is a kludge that works around this. short CallStdFilterProc(DialogPtr dptr, EventRecord *theEvent, short *ditem) { *ditem = 0; StdFilterProc(dptr, theEvent, ditem); if (*ditem != 0) return -1; return 0; } short preFilterEvent(DialogPtr d, EventRecord *theEvent) { short ret=0; switch (theEvent->what) { case mouseDown: ret = doMouseDialog(d,theEvent); /* handle drag etc. of dialog */ break; case diskEvt: diskEvent(theEvent); break; case updateEvt: if ((DialogPtr)theEvent->message != d) HandleEvent(theEvent); // We really do need to handle update events... break; case keyDown: case autoKey: break; } return (ret); } short doMouseDialog(DialogPtr d, EventRecord *theEvent) { WindowPtr theWindow; short partCode, ret=0, theItem, theMenu; long mResult; switch (partCode = FindWindow(theEvent->where,&theWindow)) { case inDrag: if(theWindow == d) { DragWindow(d, theEvent->where, &qd.screenBits.bounds); theEvent->what = nullEvent; } else SysBeep(1); break; case inMenuBar: mResult = MenuSelect(theEvent->where); HiliteMenu(0); theMenu = mResult >> 16; theItem = mResult & 0xFFFF; if ((theMenu != editMenu) && (theMenu != NeditMenu)) break; switch (theItem) { case EDcut: DialogCut(d); break; case EDcopy: DialogCopy(d); break; case EDpaste: DialogPaste(d); break; case EDclear: DialogDelete(d); break; default: break; } break; case inGoAway: if (TrackBox (theWindow, theEvent->where, partCode)) { ret = cancel; theEvent->what = nullEvent; } break; /* add code if you need to deal with these mouseDown events */ case inGrow: break; case inZoomIn: case inZoomOut: break; case inContent: if(theWindow != d) { SysBeep(1); } break; default: break; } return(ret); } void diskEvent(EventRecord *theEvent) { Point diskInitPt; if (HiWord (theEvent->message) != noErr) { diskInitPt.v = 120; diskInitPt.h = 100; DILoad (); (void) DIBadMount (diskInitPt, theEvent->message); DIUnload (); theEvent->what = nullEvent; } } void SetUpMovableModalMenus(void) { DisableItem(myMenus[Fil], 0); DisableItem(myMenus[0], 1); DisableItem(myMenus[Emul], 0); DisableItem(myMenus[Conn], 0); DisableItem(myMenus[Net], 0); DisableItem(myMenus[OpSpec], 0); DisableItem(myMenus[Keypad], 0); DisableItem(myMenus[Function], 0); DisableItem(myMenus[Edit], EDundo); EnableItem(myMenus[Edit], EDcut); EnableItem(myMenus[Edit], EDcopy); EnableItem(myMenus[Edit], EDpaste); EnableItem(myMenus[Edit], EDclear); DisableItem(myMenus[Edit], EDcopyt); DisableItem(myMenus[Edit], EDretype); DisableItem(myMenus[Edit], EDmacros); DisableItem(myMenus[Edit], EDprefs+1); DisableItem(myMenus[Edit], EDprefs+2); DisableItem(myMenus[Edit], EDprefs+4); DisableItem(myMenus[Edit], EDprefs+5); DrawMenuBar(); HiliteMenu(0); } void ResetMenus(void) { short i; EnableItem(myMenus[Fil], 0); EnableItem(myMenus[0], 1); EnableItem(myMenus[Net], 0); EnableItem(myMenus[OpSpec], 0); DisableItem(myMenus[Edit], EDcut); DisableItem(myMenus[Edit], EDclear); EnableItem(myMenus[Edit], EDcopyt); EnableItem(myMenus[Edit], EDretype); EnableItem(myMenus[Edit], EDmacros); EnableItem(myMenus[Edit], EDprefs+1); EnableItem(myMenus[Edit], EDprefs+2); EnableItem(myMenus[Edit], EDprefs+4); EnableItem(myMenus[Edit], EDprefs+5); AdjustMenus(); DoTheMenuChecks(); DrawMenuBar(); if (!FrontWindow()) return; if ((i=RSfindvwind(FrontWindow()))>=0) { if (RSTextSelected(i)) { EnableItem(myMenus[Edit],EDcopy); EnableItem(myMenus[Edit],EDcopyt); } else { DisableItem(myMenus[Edit],EDcopy); DisableItem(myMenus[Edit],EDcopyt); } } else { if ( (i = RGgetdnum(FrontWindow())) >-1) { if (( i = RGgetVS( i)) >-1) { EnableItem(myMenus[Edit],EDcopy); // - enable copying DisableItem(myMenus[Edit],EDcopyt); } } } } \ No newline at end of file diff --git a/source/drag/drag.c b/source/drag/drag.c index b311f1f..ec919c7 100755 --- a/source/drag/drag.c +++ b/source/drag/drag.c @@ -1 +1 @@ -// drag.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include #include #include "wind.h" #include "maclook.proto.h" // For WindowPtr2WindRecPtr proto #include "rsinterf.proto.h" #include "parse.proto.h" #include "drag.proto.h" #ifdef MPW #pragma segment RS #endif Boolean gHaveDragMgr, gDropcanAcceptItems, gDropcursorInContent, gDropDestCanAcceptItems; #define kScrollbarSize 15 pascal OSErr MyReceiveDropHandler(WindowPtr theWindow, unsigned long handlerRefCon, DragReference theDrag); PROTO_UPP(MyReceiveDropHandler, DragReceiveHandler); pascal OSErr MyTrackingHandler(short message, WindowPtr theWindow, void *handlerRefCon, DragReference theDrag); PROTO_UPP(MyTrackingHandler, DragTrackingHandler); static void LocalToGlobalRgn (RgnHandle rgn); static void OutlineRegion (RgnHandle theRgn); void MyDragInit(void) { OSErr err; long dragMgrAttr; err = Gestalt(gestaltDragMgrAttr, &dragMgrAttr); gHaveDragMgr = (err == noErr) && (dragMgrAttr & (1L << gestaltDragMgrPresent)) != 0; #ifdef powerc gHaveDragMgr = gHaveDragMgr && (dragMgrAttr & (1L << gestaltPPCDragLibPresent)) != 0 && ((long) InstallTrackingHandler) != kUnresolvedSymbolAddress; #endif // If the DragManager is available, install our tracking handlers if (gHaveDragMgr) { err = InstallTrackingHandler(MyTrackingHandlerUPP, nil, nil); if (err == noErr) { // If all is ok so far, install the rcv handler err = InstallReceiveHandler(MyReceiveDropHandlerUPP, nil, nil); if (err != noErr) { // If an error ocurred installing the rcv handler, remove the tracking handler RemoveTrackingHandler(MyTrackingHandlerUPP, nil); } } // If any error occurred, turn off DragManager support if (err != noErr) { gHaveDragMgr = false; } } } /* MyReceiveDropHandler * Called by the Drag Manager when a drop occurs over one of Telnet's windows. */ SIMPLE_UPP(MyReceiveDropHandler, DragReceiveHandler); pascal OSErr MyReceiveDropHandler(WindowPtr theWindow, unsigned long handlerRefCon, DragReference theDrag) { OSErr result,memError; Handle dataH; unsigned short items, index; ItemReference theItem; DragAttributes attributes; Size textSize; short mouseDownModifiers, mouseUpModifiers; WindRecPtr tw; if (!gDropcanAcceptItems || !gDropcursorInContent) return(dragNotAcceptedErr); SetPort(theWindow); // No text yet dataH = nil; GetDragAttributes(theDrag, &attributes); GetDragModifiers(theDrag, 0L, &mouseDownModifiers, &mouseUpModifiers); // Loop through all of the drag items contained in this drag and collect the text // into the accumulation handle. CountDragItems(theDrag, &items); for (index = 1; index <= items; index++) { // Get the item's reference number, so we can refer to it. GetDragItemReferenceNumber(theDrag, index, &theItem); // Try to get the flags for a 'TEXT' flavor. If this returns noErr, // then we know that a 'TEXT' flavor exists in the item. result = GetFlavorDataSize(theDrag, theItem, 'TEXT', &textSize); if (result == noErr) { if (dataH == nil) { // No data yet, create a new handle for accumulation dataH = myNewHandle(textSize); if (dataH == nil) { return memFullErr; // Exit if there is an error } } else { // Append to existing TEXT data memError = mySetHandleSize(dataH, GetHandleSize(dataH) + textSize); // Grow the handle if (memError != noErr) { return memFullErr; // Exit if there is a problem } } // Temporarily lock down the accumlation handle HLock(dataH); // Get the drag data GetFlavorData(theDrag, theItem, 'TEXT', *dataH, &textSize, 0L); // Ok to unlock the accumulation handle HUnlock(dataH); } } // Get the length of all that was accumulated textSize = GetHandleSize(dataH); // If we actually received text, insert it into the destination. if (textSize != 0) { if (attributes & dragHasLeftSenderWindow) { HideDragHilite(theDrag); } HLock(dataH); // Send the text to the window. tw = WindowPtr2WindRecPtr(theWindow); if (tw != nil) { SendStringAsIfTyped(tw, *dataH, textSize); } HUnlock(dataH); } if (dataH != nil) { DisposeHandle(dataH); } return(noErr); } /* MyTrackingHandler * This is the drag tracking handler for windows in the DragText application.*/ SIMPLE_UPP(MyTrackingHandler, DragTrackingHandler); pascal OSErr MyTrackingHandler(short message, WindowPtr theWindow, void *handlerRefCon, DragReference theDrag) { short result; unsigned short count, index; unsigned long flavorFlags, attributes; ItemReference theItem; RgnHandle theRgn, selectionRgn; Point theMouse, localMouse; Rect dragRect; GrafPtr savePort; Boolean inOriginalSelection; if ((message != dragTrackingEnterHandler) && (!gDropcanAcceptItems)) return(noErr); if ((message != dragTrackingEnterHandler) && (message != dragTrackingEnterWindow) && (!gDropDestCanAcceptItems)) return(noErr); GetDragAttributes(theDrag, &attributes); switch (message) { case dragTrackingEnterHandler: // We get called with this message the first time that a drag enters ANY // window in our application. gDropcanAcceptItems = true; // Check to see if all of the drag items contain // TEXT. We only accept a drag if all of the items in the drag can be accepted. CountDragItems(theDrag, &count); for (index = 1; index <= count; index++) { GetDragItemReferenceNumber(theDrag, index, &theItem); result = GetFlavorFlags(theDrag, theItem, 'TEXT', &flavorFlags); if (result != noErr) { gDropcanAcceptItems = false; break; } } break; case dragTrackingEnterWindow: // We receive an EnterWindow message each time a drag enters one of our // application's windows. We initialize our global variables for tracking // the drag through the window. // Assume this window can accept the drag gDropDestCanAcceptItems = true; // If it is not a connection window, it cannot accept a drop. if (((WindowPeek)theWindow)->windowKind != WIN_CNXN) { gDropDestCanAcceptItems = false; break; } // Initially no blue box. gDropcursorInContent = false; break; case dragTrackingInWindow: GetPort(&savePort); SetPort(theWindow); // We receive InWindow messages as long as the mouse is in one of our windows // during a drag. We draw the window highlighting when we get these messages. GetDragMouse(theDrag, &theMouse, 0L); // If we are still in the sender window, check to see if we should draw a blue box. // inOriginalSelection is true if the mouse is still within the confines of the // selected text's original location. This allows the user to cancel a drop by // dropping the text somewhere inside of the original selection. if (attributes & dragInsideSenderWindow) { localMouse = theMouse; GlobalToLocal(&localMouse); selectionRgn = RSGetTextSelRgn(WindowPtr2WindRecPtr(theWindow)->vs); inOriginalSelection = PtInRgn(localMouse, selectionRgn); DisposeRgn(selectionRgn); } else { inOriginalSelection = false; } // Show or hide the window highlighting when the mouse enters or leaves the // text area in our window (we don't want to show the highlighting when // the mouse is over the scroll bars). dragRect = (*(((WindowPeek)theWindow)->contRgn))->rgnBBox; // Subtract out the scrollbars. dragRect.right -= kScrollbarSize; dragRect.bottom -= kScrollbarSize; // If the mouse is in the text area and not in the original selection, // draw the blue box. if (PtInRect(theMouse, &dragRect) && !inOriginalSelection) { if (!gDropcursorInContent) { // Set up the blue box region. GlobalToLocal(&topLeft(dragRect)); GlobalToLocal(&botRight(dragRect)); RectRgn(theRgn = NewRgn(), &dragRect); ShowDragHilite(theDrag, theRgn, true); DisposeRgn(theRgn); } // Remember that we are in a valid drop location. gDropcursorInContent = true; } else { // We have moved out of a valid drop region. if (gDropcursorInContent) { // Hide the box if it was drawn. HideDragHilite(theDrag); } // Remember that we are outside of a valid drop region. gDropcursorInContent = false; } SetPort(savePort); break; case dragTrackingLeaveWindow: HideDragHilite(theDrag); break; case dragTrackingLeaveHandler: break; } return(noErr); } OSErr DragText(EventRecord *ev, Point where, short w, Boolean *dragged) { DragReference dragRef; OSErr err = noErr; Boolean haveDragRef = false; RgnHandle dragRgn = nil; Handle textH = nil; long size; *dragged = false; if (!gHaveDragMgr) { return noErr; } dragRgn = RSGetTextSelRgn(w); if (dragRgn == nil) { return noErr; } if (!PtInRgn(where, dragRgn)) { DisposeRgn(dragRgn); return noErr; } if (!WaitMouseMoved(ev->where)) return noErr; *dragged = true; textH = RSGetTextSel(w, 0); if ((textH == (char **)-1L) || (textH == nil)) { textH = nil; goto exit; } HLock(textH); size = GetHandleSize(textH); err = NewDrag(&dragRef); if (err != noErr) goto exit; haveDragRef = true; err = AddDragItemFlavor(dragRef, 1, 'TEXT', *textH, size, 0); if (err != noErr) goto exit; LocalToGlobalRgn(dragRgn); OutlineRegion(dragRgn); err = TrackDrag(dragRef, ev, dragRgn); if (err != noErr && err != userCanceledErr) goto exit; DisposeRgn(dragRgn); DisposeDrag(dragRef); DisposeHandle(textH); return noErr; exit: if (haveDragRef) DisposeDrag(dragRef); if (dragRgn != nil) DisposeRgn(dragRgn); if (textH != nil) DisposeHandle(textH); return err; } static void LocalToGlobalRgn (RgnHandle rgn) { Point where; SetPt(&where, 0, 0); LocalToGlobal(&where); OffsetRgn(rgn, where.h, where.v); } static void OutlineRegion (RgnHandle theRgn) { RgnHandle tempRgn; tempRgn = NewRgn(); CopyRgn(theRgn, tempRgn); InsetRgn(tempRgn, 1, 1); DiffRgn(theRgn, tempRgn, theRgn); DisposeRgn(tempRgn); } \ No newline at end of file +// drag.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include #include #include "wind.h" #include "maclook.proto.h" // For WindowPtr2WindRecPtr proto #include "rsinterf.proto.h" #include "parse.proto.h" #include "drag.proto.h" Boolean gHaveDragMgr, gDropcanAcceptItems, gDropcursorInContent, gDropDestCanAcceptItems; #define kScrollbarSize 15 pascal OSErr MyReceiveDropHandler(WindowPtr theWindow, unsigned long handlerRefCon, DragReference theDrag); PROTO_UPP(MyReceiveDropHandler, DragReceiveHandler); pascal OSErr MyTrackingHandler(short message, WindowPtr theWindow, void *handlerRefCon, DragReference theDrag); PROTO_UPP(MyTrackingHandler, DragTrackingHandler); static void LocalToGlobalRgn (RgnHandle rgn); static void OutlineRegion (RgnHandle theRgn); void MyDragInit(void) { OSErr err; long dragMgrAttr; err = Gestalt(gestaltDragMgrAttr, &dragMgrAttr); gHaveDragMgr = (err == noErr) && (dragMgrAttr & (1L << gestaltDragMgrPresent)) != 0; #ifdef powerc gHaveDragMgr = gHaveDragMgr && (dragMgrAttr & (1L << gestaltPPCDragLibPresent)) != 0 && ((long) InstallTrackingHandler) != kUnresolvedCFragSymbolAddress; #endif // If the DragManager is available, install our tracking handlers if (gHaveDragMgr) { err = InstallTrackingHandler(MyTrackingHandlerUPP, nil, nil); if (err == noErr) { // If all is ok so far, install the rcv handler err = InstallReceiveHandler(MyReceiveDropHandlerUPP, nil, nil); if (err != noErr) { // If an error ocurred installing the rcv handler, remove the tracking handler RemoveTrackingHandler(MyTrackingHandlerUPP, nil); } } // If any error occurred, turn off DragManager support if (err != noErr) { gHaveDragMgr = false; } } } /* MyReceiveDropHandler * Called by the Drag Manager when a drop occurs over one of Telnet's windows. */ SIMPLE_UPP(MyReceiveDropHandler, DragReceiveHandler); pascal OSErr MyReceiveDropHandler(WindowPtr theWindow, unsigned long handlerRefCon, DragReference theDrag) { OSErr result,memError; Handle dataH; unsigned short items, index; ItemReference theItem; DragAttributes attributes; Size textSize; short mouseDownModifiers, mouseUpModifiers; WindRecPtr tw; if (!gDropcanAcceptItems || !gDropcursorInContent) return(dragNotAcceptedErr); SetPort(theWindow); // No text yet dataH = nil; GetDragAttributes(theDrag, &attributes); GetDragModifiers(theDrag, 0L, &mouseDownModifiers, &mouseUpModifiers); // Loop through all of the drag items contained in this drag and collect the text // into the accumulation handle. CountDragItems(theDrag, &items); for (index = 1; index <= items; index++) { // Get the item's reference number, so we can refer to it. GetDragItemReferenceNumber(theDrag, index, &theItem); // Try to get the flags for a 'TEXT' flavor. If this returns noErr, // then we know that a 'TEXT' flavor exists in the item. result = GetFlavorDataSize(theDrag, theItem, 'TEXT', &textSize); if (result == noErr) { if (dataH == nil) { // No data yet, create a new handle for accumulation dataH = myNewHandle(textSize); if (dataH == nil) { return memFullErr; // Exit if there is an error } } else { // Append to existing TEXT data memError = mySetHandleSize(dataH, GetHandleSize(dataH) + textSize); // Grow the handle if (memError != noErr) { return memFullErr; // Exit if there is a problem } } // Temporarily lock down the accumlation handle HLock(dataH); // Get the drag data GetFlavorData(theDrag, theItem, 'TEXT', *dataH, &textSize, 0L); // Ok to unlock the accumulation handle HUnlock(dataH); } } // Get the length of all that was accumulated textSize = GetHandleSize(dataH); // If we actually received text, insert it into the destination. if (textSize != 0) { if (attributes & dragHasLeftSenderWindow) { HideDragHilite(theDrag); } HLock(dataH); // Send the text to the window. tw = WindowPtr2WindRecPtr(theWindow); if (tw != nil) { SendStringAsIfTyped(tw, *dataH, textSize); } HUnlock(dataH); } if (dataH != nil) { DisposeHandle(dataH); } return(noErr); } /* MyTrackingHandler * This is the drag tracking handler for windows in the DragText application.*/ SIMPLE_UPP(MyTrackingHandler, DragTrackingHandler); pascal OSErr MyTrackingHandler(short message, WindowPtr theWindow, void *handlerRefCon, DragReference theDrag) { short result; unsigned short count, index; unsigned long flavorFlags, attributes; ItemReference theItem; RgnHandle theRgn, selectionRgn; Point theMouse, localMouse; Rect dragRect; GrafPtr savePort; Boolean inOriginalSelection; if ((message != dragTrackingEnterHandler) && (!gDropcanAcceptItems)) return(noErr); if ((message != dragTrackingEnterHandler) && (message != dragTrackingEnterWindow) && (!gDropDestCanAcceptItems)) return(noErr); GetDragAttributes(theDrag, &attributes); switch (message) { case dragTrackingEnterHandler: // We get called with this message the first time that a drag enters ANY // window in our application. gDropcanAcceptItems = true; // Check to see if all of the drag items contain // TEXT. We only accept a drag if all of the items in the drag can be accepted. CountDragItems(theDrag, &count); for (index = 1; index <= count; index++) { GetDragItemReferenceNumber(theDrag, index, &theItem); result = GetFlavorFlags(theDrag, theItem, 'TEXT', &flavorFlags); if (result != noErr) { gDropcanAcceptItems = false; break; } } break; case dragTrackingEnterWindow: // We receive an EnterWindow message each time a drag enters one of our // application's windows. We initialize our global variables for tracking // the drag through the window. // Assume this window can accept the drag gDropDestCanAcceptItems = true; // If it is not a connection window, it cannot accept a drop. if (((WindowPeek)theWindow)->windowKind != WIN_CNXN) { gDropDestCanAcceptItems = false; break; } // Initially no blue box. gDropcursorInContent = false; break; case dragTrackingInWindow: GetPort(&savePort); SetPort(theWindow); // We receive InWindow messages as long as the mouse is in one of our windows // during a drag. We draw the window highlighting when we get these messages. GetDragMouse(theDrag, &theMouse, 0L); // If we are still in the sender window, check to see if we should draw a blue box. // inOriginalSelection is true if the mouse is still within the confines of the // selected text's original location. This allows the user to cancel a drop by // dropping the text somewhere inside of the original selection. if (attributes & dragInsideSenderWindow) { localMouse = theMouse; GlobalToLocal(&localMouse); selectionRgn = RSGetTextSelRgn(WindowPtr2WindRecPtr(theWindow)->vs); inOriginalSelection = PtInRgn(localMouse, selectionRgn); DisposeRgn(selectionRgn); } else { inOriginalSelection = false; } // Show or hide the window highlighting when the mouse enters or leaves the // text area in our window (we don't want to show the highlighting when // the mouse is over the scroll bars). dragRect = (*(((WindowPeek)theWindow)->contRgn))->rgnBBox; // Subtract out the scrollbars. dragRect.right -= kScrollbarSize; dragRect.bottom -= kScrollbarSize; // If the mouse is in the text area and not in the original selection, // draw the blue box. if (PtInRect(theMouse, &dragRect) && !inOriginalSelection) { if (!gDropcursorInContent) { // Set up the blue box region. GlobalToLocal(&topLeft(dragRect)); GlobalToLocal(&botRight(dragRect)); RectRgn(theRgn = NewRgn(), &dragRect); ShowDragHilite(theDrag, theRgn, true); DisposeRgn(theRgn); } // Remember that we are in a valid drop location. gDropcursorInContent = true; } else { // We have moved out of a valid drop region. if (gDropcursorInContent) { // Hide the box if it was drawn. HideDragHilite(theDrag); } // Remember that we are outside of a valid drop region. gDropcursorInContent = false; } SetPort(savePort); break; case dragTrackingLeaveWindow: HideDragHilite(theDrag); break; case dragTrackingLeaveHandler: break; } return(noErr); } OSErr DragText(EventRecord *ev, Point where, short w, Boolean *dragged) { DragReference dragRef; OSErr err = noErr; Boolean haveDragRef = false; RgnHandle dragRgn = nil; Handle textH = nil; long size; *dragged = false; if (!gHaveDragMgr) { return noErr; } dragRgn = RSGetTextSelRgn(w); if (dragRgn == nil) { return noErr; } if (!PtInRgn(where, dragRgn)) { DisposeRgn(dragRgn); return noErr; } if (!WaitMouseMoved(ev->where)) return noErr; *dragged = true; textH = RSGetTextSel(w, 0); if ((textH == (char **)-1L) || (textH == nil)) { textH = nil; goto exit; } HLock(textH); size = GetHandleSize(textH); err = NewDrag(&dragRef); if (err != noErr) goto exit; haveDragRef = true; err = AddDragItemFlavor(dragRef, 1, 'TEXT', *textH, size, 0); if (err != noErr) goto exit; LocalToGlobalRgn(dragRgn); OutlineRegion(dragRgn); err = TrackDrag(dragRef, ev, dragRgn); if (err != noErr && err != userCanceledErr) goto exit; DisposeRgn(dragRgn); DisposeDrag(dragRef); DisposeHandle(textH); return noErr; exit: if (haveDragRef) DisposeDrag(dragRef); if (dragRgn != nil) DisposeRgn(dragRgn); if (textH != nil) DisposeHandle(textH); return err; } static void LocalToGlobalRgn (RgnHandle rgn) { Point where; SetPt(&where, 0, 0); LocalToGlobal(&where); OffsetRgn(rgn, where.h, where.v); } static void OutlineRegion (RgnHandle theRgn) { RgnHandle tempRgn; tempRgn = NewRgn(); CopyRgn(theRgn, tempRgn); InsetRgn(tempRgn, 1, 1); DiffRgn(theRgn, tempRgn, theRgn); DisposeRgn(tempRgn); } \ No newline at end of file diff --git a/source/init/iNetwork.c b/source/init/iNetwork.c index 58c1a54..9db3693 100755 --- a/source/init/iNetwork.c +++ b/source/init/iNetwork.c @@ -1 +1 @@ -// iNetwork.c // General network initialization routines // Called only by init.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // NCSA Revisions: // 7/92 Telnet 2.6: Initial version. Jim Browne #ifdef MPW #pragma segment INIT #endif #include "iNetwork.proto.h" #include "InternalEvents.h" #include "network.proto.h" // For Mnetinit proto #include "netevent.proto.h" // For Stask & setblocksize proto #include "bkgr.proto.h" // For StartUpFTP proto extern QHdr gEventsQueue, gEventsFreeQueue; extern short gQueueLength; /*************************************************************************/ /* neteventinit * load up the pointers for the event queue * makes a circular list to follow, required for error messages */ void neteventinit( void) { gEventsFreeQueue.qHead = 0; gEventsFreeQueue.qTail = 0; gEventsFreeQueue.qFlags = 0; gEventsQueue.qHead = 0; gEventsQueue.qTail = 0; gEventsQueue.qFlags = 0; ChangeQueueLength(NEVENTS); gQueueLength = NEVENTS; } /* initnet - init all of the network stuff... */ void initnet( void) { neteventinit(); /* initializes for error messages to count */ networkUPPinit(); //initialize UPP's for TCP callbacks // Mnetinit(); StartUpFTP(); } \ No newline at end of file +// BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // iNetwork.c // General network initialization routines // Called only by init.c // NCSA Revisions: // 7/92 Telnet 2.6: Initial version. Jim Browne #include "iNetwork.proto.h" #include "InternalEvents.h" #include "network.proto.h" // For Mnetinit proto #include "netevent.proto.h" // For Stask & setblocksize proto #include "bkgr.proto.h" // For StartUpFTP proto extern QHdr gEventsQueue, gEventsFreeQueue; extern short gQueueLength; /*************************************************************************/ /* neteventinit * load up the pointers for the event queue * makes a circular list to follow, required for error messages */ void neteventinit( void) { gEventsFreeQueue.qHead = 0; gEventsFreeQueue.qTail = 0; gEventsFreeQueue.qFlags = 0; gEventsQueue.qHead = 0; gEventsQueue.qTail = 0; gEventsQueue.qFlags = 0; ChangeQueueLength(NEVENTS); gQueueLength = NEVENTS; } /* initnet - init all of the network stuff... */ void initnet( void) { neteventinit(); /* initializes for error messages to count */ networkUPPinit(); //initialize UPP's for TCP callbacks // Mnetinit(); StartUpFTP(); } \ No newline at end of file diff --git a/source/init/init.c b/source/init/init.c index 792edde..ebbc2b5 100755 --- a/source/init/init.c +++ b/source/init/init.c @@ -1 +1 @@ - // init.c // Top level of init code & general initialization routines // Called only by main() // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // Revisions: // 7/92 Telnet 2.6: Initial version. Jim Browne #include "init.proto.h" #include "mainseg.proto.h" /* For forcequit() proto */ #include "iNetwork.proto.h" /* For initnet proto */ #include "macros.proto.h" /* For initmacro proto */ #include "wind.h" /* For WindRec definition */ #include "rsinterf.proto.h" /* For RSgetwindow & RSnewwindow protos */ #include "DlogUtils.proto.h" /* For VersionNumber, UItemAssign, GetNewMyDialog protos */ #include "Sets.proto.h" /* For readconfig proto */ #include "prefs.proto.h" #include "vr.h" /* For VRinit proto */ #include "vsdata.h" #include "vsinterf.proto.h" /* For VSinit proto */ #include "vgtek.proto.h" /* For VGinit proto */ #include "vrrgmac.proto.h" /* For MacRGinit proto */ #include "menuseg.proto.h" #include "translate.proto.h" #include "tnae.h" #include "authencrypt.h" #include "authencrypt.proto.h" #include "ae.proto.h" /* For AppleEvent handlers */ #include "MacBinary.h" #include "binsubs.proto.h" /* For init_mb_files proto */ #include "drag.proto.h" /* For MyDragInit */ #include "IConfig.proto.h" #include "errors.proto.h" #include "telneterrors.h" #include "wdefpatch.proto.h" //for wdefLoad #include "memory.proto.h" #include "AddressXLation.h" /*--------------------------------------------------------------------------------*/ #define CurrentVersion 1 /* Last known SysEnvirons version */ #define HFSPtr ((long *)1014) //extern char *tempspot; /* for temp storage only */ extern Cursor *theCursors[]; extern WindRec *screens, /* Window Records (VS) for : Current Sessions */ *ftplog; /* FTP Log */ extern MenuHandle myMenus[]; OSErr io; SysEnvRec theWorld; /* System Environment record */ short TempItemsVRefNum; long TempItemsDirID; Boolean gKeyboardHasControlKey, gAEavail; short **topLeftCorners; //CCP 2.7: Better window positioning scheme Boolean encryptOK; // true if des encryption routines available Boolean authOK; // true if authentication driver available /* checkCONF - check if the user clicked on a configuration file */ void checkCONF( void) { short i,mess,count; AppFile theFile; FSSpec FileSpec; long junk = 0; if (gAEavail) return; // If AppleEvents are available, we'll get ODOCs #ifndef __powerpc__ CountAppFiles(&mess,&count); if (mess==1) return; if (count<1) return; for(i=1;i<=count;i++) { GetAppFiles(i, &theFile); if (theFile.fType=='CONF') { ClrAppFiles(i); BlockMove(&theFile.fName, FileSpec.name, (*theFile.fName)+1); // pstring copy theFile.fName -> FileSpec.name GetWDInfo(theFile.vRefNum, &FileSpec.vRefNum, &FileSpec.parID, &junk); readconfig(FileSpec); /* BYU LSC */ } } #endif return; } void initEvents( void) { EventRecord myEvent; FlushEvents(everyEvent - diskEvt,0); /* Don't Let 'em get off without seeing it. */ WaitNextEvent(everyEvent, &myEvent, gApplicationPrefs->TimeSlice, 0L); /* WNE always avail */ WaitNextEvent(everyEvent, &myEvent, gApplicationPrefs->TimeSlice, 0L); } /* initftplog - initialize the FTP log window */ void initftplog( void) { Rect prect; TerminalPrefs **termHdl; Boolean scratchBoolean; Str255 tempString; SetRect(&prect, 300,256,512,384); ftplog = (WindRec *) myNewPtr(sizeof(WindRec)); GetIndString(tempString,MISC_STRINGS,FTP_LOG_STRING); ftplog->vs=RSnewwindow( &prect, 50, 80, 24, tempString, 1, DefFONT, DefSIZE, gFTPServerPrefs->ShowFTPlog, 1,0,0,0,0,1, DefFONT, DefSIZE, 0, 0, 1); /* NCSA 2.5 */ ftplog->wind = RSgetwindow( ftplog->vs); ((WindowPeek)ftplog->wind)->windowKind = WIN_LOG; UseResFile(TelInfo->SettingsFile); termHdl = (TerminalPrefs **)Get1NamedResource (TERMINALPREFS_RESTYPE, "\p"); DetachResource((Handle) termHdl); HLock((Handle)termHdl); scratchBoolean = RSsetcolor( ftplog->vs, 0, (*termHdl)->nfcolor); scratchBoolean = RSsetcolor( ftplog->vs, 1, (*termHdl)->nbcolor); scratchBoolean = RSsetcolor( ftplog->vs, 2, (*termHdl)->bfcolor); scratchBoolean = RSsetcolor( ftplog->vs, 3, (*termHdl)->bbcolor); DisposeHandle((Handle)termHdl); VSwrite(ftplog->vs,"\033[24;0H",7); /* Move to bottom of screen */ ftplog->active=0; /* Meaningless */ ftplog->port=0; /* As is this */ ftplog->termstate=VTEKTYPE; } /* copies a specified cursor from a resource into a nonrelocatable block and returns a pointer to it in *result. */ void loadcursor( short CursorID, CursPtr *result) { CursHandle tempcurs; OSErr Err; *result = nil; do /* once */ { tempcurs = GetCursor(CursorID); Err = ResError(); if (Err != noErr) break; *result = (CursPtr) myNewPtr(sizeof(Cursor)); /* BYU LSC */ Err = MemError(); if (Err != noErr) break; LoadResource((Handle) tempcurs); /* in case it was purged */ Err = ResError(); if (Err != noErr) break; BlockMove((Ptr) *tempcurs, (Ptr) *result, sizeof(Cursor)); } while (false); if (Err != noErr) { if (*result != nil) DisposPtr((Ptr) *result); *result = &qd.arrow; } } /* loadcursor */ /* initmcurs - Set up the mouse Cursors * NOTE: debug tells if the bug or the pointer is to be used as dflt.*/ void initmcurs ( short debug) { loadcursor(rWatchCursor, &theCursors[watchcurs]); loadcursor(rCrossCursor, &theCursors[graphcurs]); loadcursor(rPOSCURS, &theCursors[poscurs]); loadcursor(rBeamCursor, &theCursors[textcurs]); loadcursor(rGINCURS, &theCursors[gincurs]); loadcursor(rXferCURS, &theCursors[xfercurs]); if (debug) loadcursor(rDbugCURS, &theCursors[normcurs]); else theCursors[normcurs] = &qd.arrow; SetCursor(theCursors[normcurs]); } /* If a file with the filetype "DBUG" was sent to us, set the debug mode. */ short checkdebug( void) { short i,mess,count; AppFile theFile; long junk = 0; if (gAEavail) return(FALSE); // Don't use CountAppFiles if AppleEvents // are available. #ifndef __powerpc__ CountAppFiles(&mess,&count); if (mess==1) return(FALSE); if (count<1) return(FALSE); for(i=1;i<=count;i++) { GetAppFiles(i, &theFile); if (theFile.fType=='DBUG') { ClrAppFiles(i); return(TRUE); } } return(FALSE); #endif } void InquireEnvironment( void) { OSErr err; Boolean HFSflag; long response; long *HFSp=(long *)1014L; HFSflag= (*HFSp) > 0L; if (!HFSflag) FatalAlert(NEED_HFS_ERR, 0, 0); err = SysEnvirons(CurrentVersion, &theWorld); if (err == envVersTooBig) FatalAlert(SYS_ENVIRON_ERR, 0, 0); if (theWorld.systemVersion < 0x0600) FatalAlert(SYSTEM_VERS_ERR, 0, 0); if (theWorld.machineType < 0) FatalAlert(ROM_VERS_ERR, 0, 0); // If there is a problem w/Gestalt, assume our keyboard has a Control key. // Otherwise, we assume we have a control key unless a Mac or MacPlus keyboard is // present. if ((err = Gestalt(gestaltKeyboardType, &response)) != noErr) gKeyboardHasControlKey = TRUE; else gKeyboardHasControlKey = !( (response == gestaltMacKbd) || (response == gestaltMacAndPad) || (response == gestaltMacPlusKbd) ); { short virtualCode = 0; Ptr KCHRPtr; long newStuff; unsigned long state = 0; virtualCode = 0x10;//this will be a 'y' for Querty KCHRPtr = (Ptr)GetScriptManagerVariable(smKCHRCache); newStuff = KeyTranslate(KCHRPtr,virtualCode,&state); newStuff &= 0xFF; //only look at bottom byte TelInfo->isQuerty = ((unsigned char) newStuff == 'y'); } TelInfo->haveColorQuickDraw = theWorld.hasColorQD; } #define kURLEventClass 'GURL' #define kGetURLEvent 'GURL' void initmac( void) { EventRecord myEvent; short i; long gestaltvalue; OSErr err; Handle tempHandle; InitGraf(&qd.thePort); InitFonts(); InitWindows(); InitMenus(); TEInit(); InitDialogs(0L); /* No resume proc */ InitCursor(); TelInfo = (TelInfoRec *)myNewPtr(sizeof(TelInfoRec)); //tempspot = (char *)myNewPtr(256); tempHandle = myNewHandle(sizeof(ApplicationPrefs)); HLockHi(tempHandle); gApplicationPrefs = (ApplicationPrefs *) *tempHandle; tempHandle = myNewHandle(sizeof(FTPServerPrefs)); HLockHi(tempHandle); gFTPServerPrefs = (FTPServerPrefs *)*tempHandle; screens = (WindRec *)myNewPtr(MaxSess*sizeof(WindRec)); for (i = 0; i < MaxSess; i++) screens[i].active = CNXN_NOTINUSE; topLeftCorners = (short **) myNewHandle(MaxSess*sizeof(short)); InquireEnvironment(); for (i=1;i<12;i++) EventAvail( 0xffff, &myEvent); err = Gestalt(gestaltAppleEventsAttr, &gestaltvalue); // See if AppleEvents are available gAEavail = (!err && ((gestaltvalue >> gestaltAppleEventsPresent) & 0x0001)); if (gAEavail) { if ((err = AEInstallEventHandler(kCoreEventClass,kAEOpenApplication, MyHandleOAppUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); if ((err = AEInstallEventHandler(kCoreEventClass,kAEOpenDocuments, MyHandleODocUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); if ((err = AEInstallEventHandler(kCoreEventClass,kAEPrintDocuments, MyHandlePDocUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); if ((err = AEInstallEventHandler(kCoreEventClass,kAEQuitApplication, MyHandleQuitUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); if ((err = AEInstallEventHandler(kURLEventClass,kGetURLEvent, MyHandleGURLUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); } TelInfo->screenRect = qd.screenBits.bounds; /* well, they have to be set */ /* somewhere, where else ? */ TelInfo->greyRegion = GetGrayRgn(); SetRect(&TelInfo->dragRect, 4, 24, TelInfo->screenRect.right-4, TelInfo->screenRect.bottom-4); } void DoTheGlobalInits(void) { long junk = 0; ParamBlockRec pb; TelInfo->ScrlLock=0; TelInfo->ftplogon=0; TelInfo->done=0; TelInfo->MacBinary=0; TelInfo->numwindows=0; TelInfo->CONFstate=0; TelInfo->CONFactive=0; TelInfo->SettingsFile=-1; TelInfo->ApplicationFile = CurResFile(); TelInfo->ginon = 0; TelInfo->xferon = 0; TelInfo->graphs = 0; TelInfo->debug = 1; TelInfo->myfronttype = NO_WINDOW; TelInfo->myfrontvs = 0; TelInfo->suspended = FALSE; TelInfo->myfrontwindow = 0L; TelInfo->myfrontRgn = 0L; TelInfo->lastCursor = 0L; TelInfo->DefaultDirVRefNum = -1; TelInfo->FTPClientVRefNum = -1; TelInfo->DefaultDirDirID = 2; TelInfo->FTPClientDirID = 2; TelInfo->macrosModeless = 0; TelInfo->ipModeless = 0; TelInfo->otpword[0] = 0; TelInfo->lastPanelSession = 0; TelInfo->lastPanelTerminal = 0; pb.ioParam.ioNamePtr = 0L; PBGetVol(&pb, FALSE); /* see Tech Note 140 for implications of this */ GetWDInfo(pb.ioParam.ioVRefNum, &(TelInfo->ApFolder.vRefNum), &(TelInfo->ApFolder.parID), &junk); TelInfo->ApFolder.name[0] = 0; FindFolder( kOnSystemDisk, kSystemFolderType, kCreateFolder, &(TelInfo->SysFolder.vRefNum), &(TelInfo->SysFolder.parID)); TelInfo->SysFolder.name[0]=0; FindFolder( kOnSystemDisk, kPreferencesFolderType, kCreateFolder, &(TelInfo->PrefFolder.vRefNum), &(TelInfo->PrefFolder.parID)); TelInfo->PrefFolder.name[0]=0; FindFolder( kOnSystemDisk, kTemporaryFolderType, kCreateFolder, &TempItemsVRefNum, &TempItemsDirID); } void init (void) { DialogPtr dtemp; /* Used for dialog display */ Size junk; long junk2; FlushEvents(everyEvent,0); initmac(); /* initialize Macintosh stuff */ DoTheGlobalInits(); OpenPreferencesFile(); LoadPreferences(); UnloadSeg(&LoadPreferences); dtemp = GetNewMySmallDialog(FirstDLOG, NULL, kInFront, (void *)ThirdCenterDialog); /* opening dialog */ UItemAssign( dtemp, 2, VersionNumberUPP); DrawDialog(dtemp); /* while we init everything */ scriptKbdInit(); TelInfo->debug=checkdebug(); /* must return TRUE or FALSE */ initmcurs(TelInfo->debug); /* init the mouse cursor */ SetCursor(theCursors[watchcurs]); setupmenu(gApplicationPrefs->CommandKeys, dtemp); trInit(myMenus[National]); /* LU: Initialize translation routines; must be done */ /* LU: prior to checkdebug(), since even the debug */ /* LU: output goes through the translation routines. */ if (VSinit(MaxSess+2)) { /* initialize the VS (which also inits RS stuff) */ DoError(104 | MEMORY_ERRORCLASS, LEVEL3, NULL); forcequit(); } //UnloadSeg(&VSinit); //MaxMem(&junk2); InitDebug(); initftplog(); /* allocate/initialize ftp log screen */ VGinit(); /* initialize Virtual Graphics after VS so that */ /* init messages can come on console screen */ VRinit(); /* ICR init */ MacRGinit(); /* ditto */ init_mb_files(); /* Initialize file id's to closed state */ switchMenus(gApplicationPrefs->CommandKeys, 0); TelInfo->done = FALSE; // We're not quitting yet. SetCursor(theCursors[normcurs]); initmacros(); CheckGlobalMacros(); ICinit(); UnloadSegments(); //get all of them at once MaxMem(&junk); //so DNR gets locked high in memory TelInfo->startedTCP = 0; /* io = OpenResolver(NULL); if (io) { DialogPtr theErrDialog; short itemhit = 0; theErrDialog = GetNewDialog(RESOLVERERROR, NULL, kInFront); DrawDialog(theErrDialog); while (!itemhit) ModalDialog(DLOGwOKUPP,&itemhit); DisposDialog(theErrDialog); } */ initnet(); /* initialize network stuff */ updateMenuChecks(); DoTheMenuChecks(); MyDragInit(); checkCONF(); /* Did user click on a set? */ DisposDialog(dtemp); /* Remove the splashbox... */ AdjustMenus(); // and adjust the menus again - RAB BetterTelnet 1.2 UnloadSeg(&init_mb_files);//this allows the authencrypt stuff to be locked above the FTP code segment UnloadSeg(&MyDragInit); MaxMem(&junk2); encryptOK = authOK = true; if (!auth_encrypt_init()) { encryptOK = false; authOK = false; } loadWDEF(); //this just loads the WDEF code in so that it doesnt fragment the heap later loadErrors(); //ditto for the error code initMemoryBuffer(5*1024,30*1024); //this gives use a grow zone for emergency situations } \ No newline at end of file +// BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // init.c // Top level of init code & general initialization routines // Called only by main() // Revisions: // 7/92 Telnet 2.6: Initial version. Jim Browne #include "init.proto.h" #include "mainseg.proto.h" /* For forcequit() proto */ #include "iNetwork.proto.h" /* For initnet proto */ #include "macros.proto.h" /* For initmacro proto */ #include "wind.h" /* For WindRec definition */ #include "rsinterf.proto.h" /* For RSgetwindow & RSnewwindow protos */ #include "DlogUtils.proto.h" /* For VersionNumber, UItemAssign, GetNewMyDialog protos */ #include "Sets.proto.h" /* For readconfig proto */ #include "prefs.proto.h" #include "vr.h" /* For VRinit proto */ #include "vsdata.h" #include "vsinterf.proto.h" /* For VSinit proto */ #include "vgtek.proto.h" /* For VGinit proto */ #include "vrrgmac.proto.h" /* For MacRGinit proto */ #include "menuseg.proto.h" #include "translate.proto.h" #include "tnae.h" #include "authencrypt.h" #include "authencrypt.proto.h" #include "ae.proto.h" /* For AppleEvent handlers */ #include "MacBinary.h" #include "binsubs.proto.h" /* For init_mb_files proto */ #include "drag.proto.h" /* For MyDragInit */ #include "IConfig.proto.h" #include "errors.proto.h" #include "telneterrors.h" #include "wdefpatch.proto.h" //for wdefLoad #include "memory.proto.h" #include "AddressXLation.h" /*--------------------------------------------------------------------------------*/ #define CurrentVersion 1 /* Last known SysEnvirons version */ #define HFSPtr ((long *)1014) //extern char *tempspot; /* for temp storage only */ extern Cursor *theCursors[]; extern WindRec *screens, /* Window Records (VS) for : Current Sessions */ *ftplog; /* FTP Log */ extern MenuHandle myMenus[]; OSErr io; SysEnvRec theWorld; /* System Environment record */ short TempItemsVRefNum; long TempItemsDirID; Boolean gKeyboardHasControlKey, gAEavail; short **topLeftCorners; //CCP 2.7: Better window positioning scheme Boolean encryptOK; // true if des encryption routines available Boolean authOK; // true if authentication driver available /* checkCONF - check if the user clicked on a configuration file */ void checkCONF( void) { short i,mess,count; // AppFile theFile; FSSpec FileSpec; long junk = 0; if (gAEavail) return; // If AppleEvents are available, we'll get ODOCs // System 6 users: TOO BAD. The old file code has been removed as of 2.0b2. return; } void initEvents( void) { EventRecord myEvent; FlushEvents(everyEvent - diskEvt,0); /* Don't Let 'em get off without seeing it. */ WaitNextEvent(everyEvent, &myEvent, gApplicationPrefs->TimeSlice, 0L); /* WNE always avail */ WaitNextEvent(everyEvent, &myEvent, gApplicationPrefs->TimeSlice, 0L); } /* initftplog - initialize the FTP log window */ void initftplog( void) { Rect prect; TerminalPrefs **termHdl; Boolean scratchBoolean; Str255 tempString; SetRect(&prect, 300,256,512,384); ftplog = (WindRec *) myNewPtr(sizeof(WindRec)); GetIndString(tempString,MISC_STRINGS,FTP_LOG_STRING); ftplog->vs=RSnewwindow( &prect, 50, 80, 24, tempString, 1, DefFONT, DefSIZE, gFTPServerPrefs->ShowFTPlog, 1,0,0,0,0,1, DefFONT, DefSIZE, 0, 0, 1, 0, 0); /* NCSA 2.5 */ ftplog->wind = RSgetwindow( ftplog->vs); ((WindowPeek)ftplog->wind)->windowKind = WIN_LOG; UseResFile(TelInfo->SettingsFile); termHdl = (TerminalPrefs **)Get1NamedSizedResource (TERMINALPREFS_RESTYPE, "\p", sizeof(TerminalPrefs)); DetachResource((Handle) termHdl); HLock((Handle)termHdl); scratchBoolean = RSsetcolor( ftplog->vs, 0, (*termHdl)->nfcolor); scratchBoolean = RSsetcolor( ftplog->vs, 1, (*termHdl)->nbcolor); scratchBoolean = RSsetcolor( ftplog->vs, 2, (*termHdl)->bfcolor); scratchBoolean = RSsetcolor( ftplog->vs, 3, (*termHdl)->bbcolor); DisposeHandle((Handle)termHdl); VSwrite(ftplog->vs,"\033[24;0H",7); /* Move to bottom of screen */ ftplog->active=0; /* Meaningless */ ftplog->port=0; /* As is this */ ftplog->termstate=VTEKTYPE; } /* copies a specified cursor from a resource into a nonrelocatable block and returns a pointer to it in *result. */ void loadcursor( short CursorID, CursPtr *result) { CursHandle tempcurs; OSErr Err; *result = nil; do /* once */ { tempcurs = GetCursor(CursorID); Err = ResError(); if (Err != noErr) break; *result = (CursPtr) myNewPtr(sizeof(Cursor)); /* BYU LSC */ Err = MemError(); if (Err != noErr) break; LoadResource((Handle) tempcurs); /* in case it was purged */ Err = ResError(); if (Err != noErr) break; BlockMove((Ptr) *tempcurs, (Ptr) *result, sizeof(Cursor)); } while (false); if (Err != noErr) { if (*result != nil) DisposePtr((Ptr) *result); *result = &qd.arrow; } } /* loadcursor */ /* initmcurs - Set up the mouse Cursors * NOTE: debug tells if the bug or the pointer is to be used as dflt.*/ void initmcurs ( short debug) { loadcursor(rWatchCursor, &theCursors[watchcurs]); loadcursor(rCrossCursor, &theCursors[graphcurs]); loadcursor(rPOSCURS, &theCursors[poscurs]); loadcursor(rBeamCursor, &theCursors[textcurs]); loadcursor(rGINCURS, &theCursors[gincurs]); loadcursor(rXferCURS, &theCursors[xfercurs]); if (debug) loadcursor(rDbugCURS, &theCursors[normcurs]); else theCursors[normcurs] = &qd.arrow; SetCursor(theCursors[normcurs]); } /* If a file with the filetype "DBUG" was sent to us, set the debug mode. */ short checkdebug( void) { short i,mess,count; // AppFile theFile; long junk = 0; if (gAEavail) return(FALSE); // Don't use CountAppFiles if AppleEvents // are available. // removed old Sys6 stuff (RAB 2.0b2) return (FALSE); } void InquireEnvironment( void) { OSErr err; Boolean HFSflag; long response; // RJZ. 12/10/97. Got rid of test for // HFS. Checking absolute memory // locations is bad. // Hey, we need System 7 anyway... // long *HFSp=(long *)1014L; // HFSflag= (*HFSp) > 0L; // if (!HFSflag) FatalAlert(NEED_HFS_ERR, 0, 0); err = SysEnvirons(CurrentVersion, &theWorld); if (err == envVersTooBig) FatalAlert(SYS_ENVIRON_ERR, 0, 0); // RAB BetterTelnet - we need System 7 now. (or Mac OS 8) // Get rid of the System 6 users right here. :) if (theWorld.systemVersion < 0x0700) FatalAlert(SYSTEM_VERS_ERR, 0, 0); if (theWorld.machineType < 0) FatalAlert(ROM_VERS_ERR, 0, 0); // If there is a problem w/Gestalt, assume our keyboard has a Control key. // Otherwise, we assume we have a control key unless a Mac or MacPlus keyboard is // present. if ((err = Gestalt(gestaltKeyboardType, &response)) != noErr) gKeyboardHasControlKey = TRUE; else gKeyboardHasControlKey = !( (response == gestaltMacKbd) || (response == gestaltMacAndPad) || (response == gestaltMacPlusKbd) ); { short virtualCode = 0; Ptr KCHRPtr; long newStuff; unsigned long state = 0; virtualCode = 0x10;//this will be a 'y' for Querty KCHRPtr = (Ptr)GetScriptManagerVariable(smKCHRCache); newStuff = KeyTranslate(KCHRPtr,virtualCode,&state); newStuff &= 0xFF; //only look at bottom byte TelInfo->isQuerty = ((unsigned char) newStuff == 'y'); } TelInfo->haveColorQuickDraw = theWorld.hasColorQD; } #define kURLEventClass 'GURL' #define kGetURLEvent 'GURL' void initmac( void) { EventRecord myEvent; short i; long gestaltvalue; OSErr err; Handle tempHandle; InitGraf(&qd.thePort); InitFonts(); InitWindows(); InitMenus(); TEInit(); InitDialogs(0L); /* No resume proc */ InitCursor(); TelInfo = (TelInfoRec *)myNewPtr(sizeof(TelInfoRec)); //tempspot = (char *)myNewPtr(256); tempHandle = myNewHandle(sizeof(ApplicationPrefs)); HLockHi(tempHandle); gApplicationPrefs = (ApplicationPrefs *) *tempHandle; tempHandle = myNewHandle(sizeof(FTPServerPrefs)); HLockHi(tempHandle); gFTPServerPrefs = (FTPServerPrefs *)*tempHandle; screens = (WindRec *)myNewPtr(MaxSess*sizeof(WindRec)); for (i = 0; i < MaxSess; i++) screens[i].active = CNXN_NOTINUSE; topLeftCorners = (short **) myNewHandle(MaxSess*sizeof(short)); InquireEnvironment(); for (i=1;i<12;i++) EventAvail( 0xffff, &myEvent); err = Gestalt(gestaltAppleEventsAttr, &gestaltvalue); // See if AppleEvents are available gAEavail = (!err && ((gestaltvalue >> gestaltAppleEventsPresent) & 0x0001)); if (gAEavail) { if ((err = AEInstallEventHandler(kCoreEventClass,kAEOpenApplication, MyHandleOAppUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); if ((err = AEInstallEventHandler(kCoreEventClass,kAEOpenDocuments, MyHandleODocUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); if ((err = AEInstallEventHandler(kCoreEventClass,kAEPrintDocuments, MyHandlePDocUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); if ((err = AEInstallEventHandler(kCoreEventClass,kAEQuitApplication, MyHandleQuitUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); if ((err = AEInstallEventHandler(kURLEventClass,kGetURLEvent, MyHandleGURLUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); if ((err = AEInstallEventHandler('rlfT','send',MyHandleSendDataUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); if ((err = AEInstallEventHandler('rlfT','seCR',MyHandleSendCRUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); if ((err = AEInstallEventHandler('rlfT','mkCX',MyHandleConnectUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); if ((err = AEInstallEventHandler('rlfT','WaiT',MyHandleWaitUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); if ((err = AEInstallEventHandler('rlfT','susp',MyHandleSuspendUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); if ((err = AEInstallEventHandler('rlfT','!sus',MyHandleUnSuspendUPP,0,FALSE)) != noErr) FatalAlert(AE_PROBLEM_ERR, 0, 0); } TelInfo->screenRect = qd.screenBits.bounds; /* well, they have to be set */ /* somewhere, where else ? */ TelInfo->greyRegion = GetGrayRgn(); SetRect(&TelInfo->dragRect, 4, 24, TelInfo->screenRect.right-4, TelInfo->screenRect.bottom-4); } void DoTheGlobalInits(void) { long junk = 0; ParamBlockRec pb; TelInfo->ScrlLock=0; TelInfo->ftplogon=0; TelInfo->done=0; TelInfo->MacBinary=0; TelInfo->numwindows=0; TelInfo->CONFstate=0; TelInfo->CONFactive=0; TelInfo->SettingsFile=-1; TelInfo->ApplicationFile = CurResFile(); TelInfo->ginon = 0; TelInfo->xferon = 0; TelInfo->graphs = 0; TelInfo->debug = 1; TelInfo->myfronttype = NO_WINDOW; TelInfo->myfrontvs = 0; TelInfo->suspended = FALSE; TelInfo->myfrontwindow = 0L; TelInfo->myfrontRgn = 0L; TelInfo->lastCursor = 0L; TelInfo->DefaultDirVRefNum = -1; TelInfo->FTPClientVRefNum = -1; TelInfo->DefaultDirDirID = 2; TelInfo->FTPClientDirID = 2; TelInfo->macrosModeless = 0; TelInfo->ipModeless = 0; TelInfo->otpword[0] = 0; TelInfo->lastPanelSession = 0; TelInfo->lastPanelTerminal = 0; TelInfo->checkedBoldFontNum = 0; TelInfo->checkedFontNum = 0; pb.ioParam.ioNamePtr = 0L; PBGetVolSync(&pb); /* see Tech Note 140 for implications of this */ GetWDInfo(pb.ioParam.ioVRefNum, &(TelInfo->ApFolder.vRefNum), &(TelInfo->ApFolder.parID), &junk); TelInfo->ApFolder.name[0] = 0; FindFolder( kOnSystemDisk, kSystemFolderType, kCreateFolder, &(TelInfo->SysFolder.vRefNum), &(TelInfo->SysFolder.parID)); TelInfo->SysFolder.name[0]=0; FindFolder( kOnSystemDisk, kPreferencesFolderType, kCreateFolder, &(TelInfo->PrefFolder.vRefNum), &(TelInfo->PrefFolder.parID)); TelInfo->PrefFolder.name[0]=0; FindFolder( kOnSystemDisk, kTemporaryFolderType, kCreateFolder, &TempItemsVRefNum, &TempItemsDirID); } void init (void) { DialogPtr dtemp; /* Used for dialog display */ Size junk; long junk2; FlushEvents(everyEvent,0); initmac(); /* initialize Macintosh stuff */ DoTheGlobalInits(); OpenPreferencesFile(); LoadPreferences(); UnloadSeg(&LoadPreferences); dtemp = GetNewMySmallDialog(FirstDLOG, NULL, kInFront, (void *)ThirdCenterDialog); /* opening dialog */ UItemAssign( dtemp, 2, VersionNumberUPP); DrawDialog(dtemp); /* while we init everything */ scriptKbdInit(); TelInfo->debug=checkdebug(); /* must return TRUE or FALSE */ initmcurs(0); /* init the mouse cursor */ SetCursor(theCursors[watchcurs]); setupmenu(gApplicationPrefs->CommandKeys, dtemp); trInit(myMenus[National]); /* LU: Initialize translation routines; must be done */ /* LU: prior to checkdebug(), since even the debug */ /* LU: output goes through the translation routines. */ if (VSinit(MaxSess+2)) { /* initialize the VS (which also inits RS stuff) */ DoError(104 | MEMORY_ERRORCLASS, LEVEL3, NULL); forcequit(); } //UnloadSeg(&VSinit); //MaxMem(&junk2); InitDebug(); // ShowDebugWindow(); initftplog(); /* allocate/initialize ftp log screen */ VGinit(); /* initialize Virtual Graphics after VS so that */ /* init messages can come on console screen */ VRinit(); /* ICR init */ MacRGinit(); /* ditto */ init_mb_files(); /* Initialize file id's to closed state */ switchMenus(gApplicationPrefs->CommandKeys, 0); TelInfo->done = FALSE; // We're not quitting yet. SetCursor(theCursors[normcurs]); initmacros(); CheckGlobalMacros(); ICinit(); UnloadSegments(); //get all of them at once MaxMem(&junk); //so DNR gets locked high in memory TelInfo->startedTCP = 0; /* io = OpenResolver(NULL); if (io) { DialogPtr theErrDialog; short itemhit = 0; theErrDialog = GetNewDialog(RESOLVERERROR, NULL, kInFront); DrawDialog(theErrDialog); while (!itemhit) ModalDialog(DLOGwOKUPP,&itemhit); DisposeDialog(theErrDialog); } */ initnet(); /* initialize network stuff */ updateMenuChecks(); DoTheMenuChecks(); MyDragInit(); checkCONF(); /* Did user click on a set? */ DisposeDialog(dtemp); /* Remove the splashbox... */ AdjustMenus(); // and adjust the menus again - RAB BetterTelnet 1.2 UnloadSeg(&init_mb_files);//this allows the authencrypt stuff to be locked above the FTP code segment UnloadSeg(&MyDragInit); MaxMem(&junk2); encryptOK = authOK = true; if (!auth_encrypt_init()) { encryptOK = false; authOK = false; } loadWDEF(); //this just loads the WDEF code in so that it doesnt fragment the heap later loadErrors(); //ditto for the error code initMemoryBuffer(5*1024,30*1024); //this gives use a grow zone for emergency situations } \ No newline at end of file diff --git a/source/macros/macros.c b/source/macros/macros.c index 03350a6..04cbcb5 100755 --- a/source/macros/macros.c +++ b/source/macros/macros.c @@ -1 +1 @@ -/* * macros.c * originally by Gaige B. Paulsen * * NCSA Revisions: * 7/92 Moved here from event.c and maclook.c by JMB * 11/94 Rewritten to use handle based macros JMB */ // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #ifdef MPW #pragma segment Macros #endif #include "network.proto.h" /* For netwrite proto */ #include "wind.h" /* For WindRec definition */ #include "DlogUtils.proto.h" #include "parse.proto.h" #include "event.proto.h" #include "menuseg.proto.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "macros.proto.h" #include "Sets.proto.h" //for CStringToFile /* Macro Defines */ #define MACRO_IP 0xff /* Send IP number here */ #define MACRO_LINES 0xfe /* Send # of lines here */ #define MACRO_MAX_LEN 256 // Maximum macro length extern Cursor *theCursors[]; Handle gMacros[10]; void MACROSunload(void) {} void initmacros( void) { short i; for (i=0; i<10 ; i++) { gMacros[i] = nil; } } void CheckGlobalMacros(void) { OSErr err; FSSpec macroFile; Boolean dummy1, dummy2; err = FSMakeFSSpec(TelInfo->PrefFolder.vRefNum, TelInfo->PrefFolder.parID, "\pBetterTelnet Macros", ¯oFile); if (!err) { ResolveAliasFile(¯oFile, FALSE, &dummy1, &dummy2); loadMacros(¯oFile); } } void SaveGlobalMacros(void) { OSErr err; FSSpec macroFile; Boolean dummy1, dummy2; err = FSMakeFSSpec(TelInfo->PrefFolder.vRefNum, TelInfo->PrefFolder.parID, "\pBetterTelnet Macros", ¯oFile); if ((!err) || (err == -43)) { ResolveAliasFile(¯oFile, FALSE, &dummy1, &dummy2); saveMacros(¯oFile); } } void setmacro(short n, char *s) /* Set macro number to the value of s */ { unsigned char *p; short num, pos, escape; short len; OSErr memError; if (n<0 || n>9) return; // Restrict the maximum length of macros to MACRO_MAX_LEN bytes len = strlen(s)+1; if (len > (MACRO_MAX_LEN - 1)) { len = MACRO_MAX_LEN; s[MACRO_MAX_LEN - 1] = 0; } // If this is an empty string, remove whatever storage might have been used previously // by this macro. if (len == 1) { if (gMacros[n] != nil) { DisposeHandle(gMacros[n]); gMacros[n] = nil; } return; } // If neccessary, create storage for the macro if (gMacros[n] == nil) { gMacros[n] = myNewHandle(len); if (gMacros[n] == nil) { // Memory error return; } } // Adjust the handle to the proper size (may be making an existing macro longer) memError = mySetHandleSize(gMacros[n], len); if (memError != noErr) { return; } HLock(gMacros[n]); p = (unsigned char *)*gMacros[n]; num = 0; pos = 0; escape = 0; while ( *s) { if (escape) { escape = 0; switch (*s) { case 'i': if ( pos >0) { *p++=num; *p++=*s; pos=0; } *p++=MACRO_IP; break; case '#': if ( pos >0) { *p++=num; *p++=*s; pos=0; } *p++=MACRO_LINES; break; case 'n': if ( pos >0) { *p++=num; *p++=*s; pos=0; } *p++='\012'; break; case 'r': if ( pos >0) { *p++=num; *p++=*s; pos=0; } *p++='\015'; break; case 't': if ( pos >0) { *p++=num; *p++=*s; pos=0; } *p++='\t'; break; case '"': if ( pos >0) { *p++=num; *p++=*s; pos=0; } *p++='\"'; break; case '\\': if ( pos >0) { *p++=num; escape=1; pos=0; num=0; } else *p++='\\'; break; default: if (*s <='9' && *s >='0' && pos <3) { num= num*8+( *s -'0'); pos++; escape=1; } else { if (pos ==0 && num==0) { *p++='\\'; *p++=*s; } else { *p++=num; pos= 0; s--; /* back up the buffer. */ } } break; } } else { if (*s=='\\') { num=0; pos=0; escape=1; } else *p++=*s; } s++; } if (pos >0) *p++=num; *p=0; // The resultant macro may be shorter than the input string due to escaped characters. // So, recalculate the length of the macro and resize than handle if neccessary. len = strlen(*gMacros[n])+1; HUnlock(gMacros[n]); mySetHandleSize(gMacros[n], len); } /* setmacro */ short sendmacro(struct WindRec *tw, short n) /* send macro number n */ { char temp[20]; unsigned char *mp, *first; unsigned char myipnum[4]; // Invalid number if (n<0 || n>9) { return -1; } // Empty macro, so do nothing if (gMacros[n] == nil) { return 0; } HLock(gMacros[n]); mp = (unsigned char *)*gMacros[n]; first = mp; netgetip(myipnum); while ( *mp) { if (*mp==MACRO_IP) { SendStringAsIfTyped(tw, (char *)first, mp-first); sprintf(temp,"%d.%d.%d.%d", myipnum[0], myipnum[1], myipnum[2], myipnum[3]); SendStringAsIfTyped(tw, temp, strlen(temp)); first = mp+1; } else if ( *mp==MACRO_LINES) { SendStringAsIfTyped(tw, (char *)first, mp-first); sprintf(temp,"%d", VSgetlines(tw->vs)); SendStringAsIfTyped(tw, temp, strlen(temp)); first = mp+1; } mp++; } SendStringAsIfTyped(tw, (char *)first, mp-first); HUnlock(gMacros[n]); return 0; } short getmacro(short n, char *dest, short room) { unsigned char *s; // Invalid number if (n<0 || n>9) { return -1; } // Empty macro, so return empty string if (gMacros[n] == nil) { *dest = 0; return 0; } s = (unsigned char *)*gMacros[n]; while (*s && (room >= 5)) { // 5 = (size of \xxx) + (terminating \0) switch( *s) { case MACRO_IP : *dest++='\\'; *dest++='i'; room--; break; case MACRO_LINES : *dest++='\\'; *dest++='#'; room--; break; case '\\': *dest++='\\'; *dest++='\\'; room--; break; case '\015': *dest++='\\'; *dest++='r'; room--; break; case '\012': *dest++='\\'; *dest++='n'; room--; break; case '\t': *dest++='\\'; *dest++='t'; room--; break; default: if ( isprint(*s)) *dest++=*s; else { *dest++='\\'; *dest++= (*s / 64) +'0'; *dest++= ((*s % 64) / 8)+'0'; *dest++= (*s % 8) +'0'; room = room - 3; } break; } room--; s++; } *dest = 0; return( 0); } void Macros( void) { DialogPtr dtemp; short dItem; short i; Rect dBox; Str255 temp; Handle MacString[10]; SetCursor(theCursors[normcurs]); if (TelInfo->macrosModeless) { SelectWindow(TelInfo->macrosModeless); return; } dtemp=GetNewMyDialog( MacroDLOG, NULL, kInFront, (void *)ThirdCenterDialog); SetDialogDefaultItem(dtemp, 1); SetDialogCancelItem(dtemp, 2); SetDialogTracksCursor(dtemp, 1); for (i=0; i<10; i++) { getmacro(i, (char *) &temp, 256); /* BYU LSC */ c2pstr((char *)temp); /* BYU LSC */ GetDItem( dtemp, i+13, &dItem, &MacString[i], &dBox); SetIText( MacString[i], temp ); } TelInfo->macrosModeless = dtemp; } void MacroDialog(EventRecord *theEvent, short dItem) { DialogPtr dtemp; short i; Rect dBox; Str255 temp; Handle MacString[10]; dtemp = TelInfo->macrosModeless; switch (dItem) { case (MacroExport): for (i=0; i<10; i++) { GetDItem( dtemp, i+13, &dItem, &MacString[i], &dBox); GetIText( MacString[i], temp); p2cstr(temp); setmacro(i, (char *) &temp); } saveMacros((FSSpec *) NULL); break; case 25: for (i=0; i<10; i++) { GetDItem( dtemp, i+13, &dItem, &MacString[i], &dBox); GetIText( MacString[i], temp); p2cstr(temp); setmacro(i, (char *) &temp); } SaveGlobalMacros(); break; case (MacroImport): loadMacros((FSSpec *) NULL); for (i=0; i<10; i++) { getmacro(i, (char *) &temp, 256); c2pstr((char *)temp); GetDItem( dtemp, i+13, &dItem, &MacString[i], &dBox); SetIText( MacString[i], temp ); } break; case 1: updateCursor(1); CloseMacros(); break; case 2: updateCursor(1); DisposeDialog(dtemp); TelInfo->macrosModeless = 0; AdjustMenus(); DoTheMenuChecks(); break; default: if (dItem >2 && dItem <13) { i=dItem-3; getmacro( i, (char *) &temp, 256); /* BYU LSC */ c2pstr((char *)temp); GetDItem( dtemp, i+13, &dItem, &MacString[i], &dBox); SetIText( MacString[i], temp ); /* BYU LSC - Revert the mother */ SelIText( dtemp, i+13, 0, 32767); /* And select it... */ } break; } } void CloseMacros(void) { DialogPtr dtemp; short dItem; short i; Rect dBox; Str255 temp; Handle MacString[10]; dtemp = TelInfo->macrosModeless; for (i=0; i<10; i++) { GetDItem( dtemp, i+13, &dItem, &MacString[i], &dBox); GetIText( MacString[i], temp); p2cstr(temp); setmacro(i, (char *) &temp); } DisposeDialog(TelInfo->macrosModeless); TelInfo->macrosModeless = 0; AdjustMenus(); DoTheMenuChecks(); } void saveMacros(FSSpec *theFile) { SFReply whereReply; short refNum,exist; FSSpec macroFile; long junk; short i; char temp[256], temp2[256]; Point where; OSErr err; Str255 tempString,tempString2; where.h = 100; where.v = 100; GetIndString(tempString,MISC_STRINGS,SAVE_MACROS_STRING); GetIndString(tempString2,MISC_STRINGS,DEFAULT_MACRO_SET_NAME); if (theFile == 0) { SFPutFile( where, tempString, tempString2, 0L, &whereReply); if (!whereReply.good) return; BlockMoveData(&whereReply.fName, macroFile.name, (*whereReply.fName)+1); GetWDInfo(whereReply.vRefNum, ¯oFile.vRefNum, ¯oFile.parID, &junk); } else macroFile = *theFile; if ((err = HCreate(macroFile.vRefNum, macroFile.parID, macroFile.name, kNCSACreatorSignature, 'TEXT')) == dupFNErr) exist = 1; err = HOpenDF(macroFile.vRefNum, macroFile.parID, macroFile.name, fsWrPerm, &refNum); if (exist) SetEOF(refNum, 0L); for (i = 0; i < 10; i++) { getmacro(i, temp, sizeof(temp)); sprintf(temp2, "key%d = \"", i); CStringToFile(refNum,(unsigned char *) temp2); if (*temp) { CStringToFile(refNum,(unsigned char *) temp); } strcpy(temp2,"\"\015"); CStringToFile(refNum,(unsigned char *) temp2); } FSClose(refNum); } void loadMacros(FSSpec *theFile) { SFReply sfr; long junk; SFTypeList typesok = {'TEXT'}; Point where; FSSpec macros; OSErr err; short fileRef; where.h=100;where.v=100; if (theFile == 0L) { SFGetFile( where, NULL, 0L, 1, typesok, 0L, &sfr); if (!sfr.good) return; BlockMove(&sfr.fName, macros.name, (*sfr.fName)+1); GetWDInfo(sfr.vRefNum, ¯os.vRefNum, ¯os.parID, &junk); err = HOpenDF(macros.vRefNum, macros.parID, macros.name, fsRdPerm, &fileRef); } else err = HOpenDF(theFile->vRefNum, theFile->parID, theFile->name, fsRdPerm, &fileRef); if (err != noErr) return; parseMacroFile(fileRef); FSClose(fileRef); } void parseMacroFile(short fileRef) { unsigned char buffer[300],*bufferPtr; unsigned char newMacro[256], *newMacroPtr; OSErr fileErr = noErr; short numMacrosRead = 0; short totalLen,i; long count=1; bufferPtr = buffer; for(i = 0; i < 10; i++) { if (gMacros[i] != NULL) DisposHandle(gMacros[i]); } initmacros(); //sets all handles to null while ((fileErr != eofErr)&&(numMacrosRead < 10)) { fileErr = FSRead(fileRef,&count,bufferPtr); while((*bufferPtr != 0x0D)&&(fileErr != eofErr)) //while not CR or EOF { ++bufferPtr; fileErr = FSRead(fileRef,&count,bufferPtr); } totalLen = bufferPtr-buffer; bufferPtr = buffer; newMacroPtr = newMacro; while((*bufferPtr++ != '"')&&(totalLen != 0)) --totalLen; while((*bufferPtr != '"')&&(totalLen != 0)) { *newMacroPtr++ = *bufferPtr++; --totalLen; } *newMacroPtr = NULL; //make this a C string setmacro(numMacrosRead,(char *)newMacro); bufferPtr = buffer; ++numMacrosRead; } } \ No newline at end of file +/* * macros.c * originally by Gaige B. Paulsen * * NCSA Revisions: * 7/92 Moved here from event.c and maclook.c by JMB * 11/94 Rewritten to use handle based macros JMB */ // 11/98 - totally revised for BetterTelnet 2.0b5 (RAB) // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "network.proto.h" /* For netwrite proto */ #include "wind.h" /* For WindRec definition */ #include "DlogUtils.proto.h" #include "parse.proto.h" #include "event.proto.h" #include "menuseg.proto.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "macros.proto.h" #include "Sets.proto.h" //for CStringToFile #include "movableModal.h" /* Macro Defines */ #define MACRO_IP 0xff /* Send IP number here */ #define MACRO_LINES 0xfe /* Send # of lines here */ #define MACRO_MAX_LEN 256 // Maximum macro length #define NUM_MACROS 110 // RAB BetterTelnet 2.0b5 extern Cursor *theCursors[]; //Handle gMacros[10]; Handle oldMacros; NewMacroInfo oldMacroIndexes; short dialogPane; // which key set are we using? // (needs to be global because there's no struct) void MACROSunload(void) {} void initmacros( void) { short i; /* for (i=0; i<10 ; i++) { gMacros[i] = nil; } */ for (i=0; inewMacros.index[i] = 0; TelInfo->newMacros.handle = 0; setupNewMacros(&TelInfo->newMacros); } void disposemacros(NewMacroInfo *macrost) // same as init, but don't put in default // null-macros and get rid of all the handles { short i; if (macrost->handle != NULL) DisposeHandle(macrost->handle); /* for (i = 0; i < 10; i++) { if (gMacros[i] != NULL) DisposeHandle(gMacros[i]); gMacros[i] = NULL; } */ for (i=0; iindex[i] = 0; macrost->handle = 0; } void setupNewMacros(NewMacroInfo *macrost) // RAB BetterTelnet 2.0b5 { Handle macroHandle; Ptr pos; long len; short i; len = NUM_MACROS; macrost->handle = macroHandle = myNewHandle(len); HLock(macroHandle); pos = *macroHandle; while (len) { *pos = 0; pos++; len--; } for (i = 0; i < NUM_MACROS; i++) macrost->index[i] = i; HUnlock(macroHandle); } void CheckGlobalMacros(void) { OSErr err; FSSpec macroFile; Boolean dummy1, dummy2; // RAB BetterTelnet 2.0b5 // if there's no global file, we have to get our default from the resource fork... // we load them first just in case we have OLD macros in the macros file, in which case // we have to add them to the defaults rather than replace the default GetDefaultMacros(); err = FSMakeFSSpec(TelInfo->PrefFolder.vRefNum, TelInfo->PrefFolder.parID, "\pBetterTelnet Macros", ¯oFile); if (!err) { ResolveAliasFile(¯oFile, FALSE, &dummy1, &dummy2); loadMacros(&TelInfo->newMacros, ¯oFile); } } // RAB BetterTelnet 2.0b5 - added GetDefaultMacros // note that we ASSUME the resource fork has new-style macros - don't even think // about putting the old format there. it would be useless anyway given that the // purpose of having defaults in the resource fork is to make sure the arrows et al. work // right from the get-go. void GetDefaultMacros(void) { Handle resHandle; UseResFile(TelInfo->ApplicationFile); resHandle = Get1Resource('Mcro', 128); UseResFile(TelInfo->SettingsFile); if (!resHandle) { // RAB 2.0b5 - get the blank macros, then setupNewMacros(&TelInfo->newMacros); // ignore the error, and let the lusers learn on their own return; // not to use ResEdit unless they know what they're doing :-) } DetachResource(resHandle); HLock(resHandle); disposemacros(&TelInfo->newMacros); // we are replacing, not merging ParseMacrosFromHandle(&TelInfo->newMacros, resHandle); } void SaveGlobalMacros(NewMacroInfo *macrost) { OSErr err; FSSpec macroFile; Boolean dummy1, dummy2; err = FSMakeFSSpec(TelInfo->PrefFolder.vRefNum, TelInfo->PrefFolder.parID, "\pBetterTelnet Macros", ¯oFile); if ((!err) || (err == -43)) { ResolveAliasFile(¯oFile, FALSE, &dummy1, &dummy2); saveMacros(macrost, ¯oFile); } } void setmacro(NewMacroInfo *macrost, short n, char *s) // RAB BetterTelnet 2.0b5 { // note that we don't check MACRO_MAX_LEN anymore - the new structure can handle most any // size of macro, doesn't use 8-bit length descriptors anywhere (all 16 or 32 bit) - // however, the final implementation still uses Str255-sized memory spaces. It is the // responsibility of whoever calls getmacro() to pass a reasonable value for "room" // to ensure correct truncation of oversized values. short i; Handle macroHandle; Ptr pos; long offset, offset2, offset3, ohlen, nhlen; short oslen, nslen; // ..len: o = old, n = new, h = handle, s = string macroHandle = macrost->handle; HLock(macroHandle); pos = *macroHandle; ohlen = GetHandleSize(macroHandle); // get all the lengths and offsets calculated if (n) offset = macrost->index[n]; else offset = 0; oslen = strlen(pos + offset); nslen = strlen(s); nhlen = ohlen - oslen + nslen; offset2 = offset + oslen + 1; // the end of the old string offset3 = offset + nslen + 1; // the end of the new strings if (nhlen > ohlen) { HUnlock(macroHandle); SetHandleSize(macroHandle, nhlen); // make sure we have enough room HLock(macroHandle); pos = *macroHandle; } if (ohlen > offset2) { // move data after the insertion position up or down BlockMoveData(pos + offset2, pos + offset3, ohlen - offset2); for (i = n + 1; i < NUM_MACROS; i++) // fix the offsets macrost->index[i] += offset3 - offset2; } HUnlock(macroHandle); SetHandleSize(macroHandle, nhlen); HLock(macroHandle); pos = *macroHandle; // dereference _yet_ _again_ (rrgh) strcpy(pos+offset, s); HUnlock(macroHandle); } #if 0 void oldsetmacro(short n, char *s) /* Set macro number to the value of s */ { unsigned char *p; short num, pos, escape; short len; OSErr memError; if (n<0 || n>9) return; // Restrict the maximum length of macros to MACRO_MAX_LEN bytes len = strlen(s)+1; if (len > (MACRO_MAX_LEN - 1)) { len = MACRO_MAX_LEN; s[MACRO_MAX_LEN - 1] = 0; } // If this is an empty string, remove whatever storage might have been used previously // by this macro. if (len == 1) { if (gMacros[n] != nil) { DisposeHandle(gMacros[n]); gMacros[n] = nil; } return; } // If neccessary, create storage for the macro if (gMacros[n] == nil) { gMacros[n] = myNewHandle(len); if (gMacros[n] == nil) { // Memory error return; } } // Adjust the handle to the proper size (may be making an existing macro longer) memError = mySetHandleSize(gMacros[n], len); if (memError != noErr) { return; } HLock(gMacros[n]); p = (unsigned char *)*gMacros[n]; num = 0; pos = 0; escape = 0; while ( *s) { if (escape) { escape = 0; switch (*s) { case 'i': if ( pos >0) { *p++=num; *p++=*s; pos=0; } *p++=MACRO_IP; break; case '#': if ( pos >0) { *p++=num; *p++=*s; pos=0; } *p++=MACRO_LINES; break; case 'n': if ( pos >0) { *p++=num; *p++=*s; pos=0; } *p++='\012'; break; case 'r': if ( pos >0) { *p++=num; *p++=*s; pos=0; } *p++='\015'; break; case 't': if ( pos >0) { *p++=num; *p++=*s; pos=0; } *p++='\t'; break; case '"': if ( pos >0) { *p++=num; *p++=*s; pos=0; } *p++='\"'; break; case '\\': if ( pos >0) { *p++=num; escape=1; pos=0; num=0; } else *p++='\\'; break; default: if (*s <='9' && *s >='0' && pos <3) { num= num*8+( *s -'0'); pos++; escape=1; } else { if (pos ==0 && num==0) { *p++='\\'; *p++=*s; } else { *p++=num; pos= 0; s--; /* back up the buffer. */ } } break; } } else { if (*s=='\\') { num=0; pos=0; escape=1; } else *p++=*s; } s++; } if (pos >0) *p++=num; *p=0; // The resultant macro may be shorter than the input string due to escaped characters. // So, recalculate the length of the macro and resize than handle if neccessary. len = strlen(*gMacros[n])+1; HUnlock(gMacros[n]); mySetHandleSize(gMacros[n], len); } /* setmacro */ #endif short sendmacro(struct WindRec *tw, short n) /* send macro number n */ // RAB BetterTelnet 2.0b5 - changed to support new macro system { char temp[20]; unsigned char *s, *first, *p; unsigned char myipnum[4]; Handle mh, ph; short i, num, pos, escape, length; // Invalid number if (n < 0 || n >= NUM_MACROS) { return -1; } // first we actually have to GET the macro (2.0b5) // we use getmacrointohandle for this i = -1; if (tw->sessmacros.handle) i = getmacrointohandle(&tw->sessmacros, n, &mh); if (i == -1) i = getmacrointohandle(&TelInfo->newMacros, n, &mh); if (i == -1) return 0; // Empty macro, so do nothing // if (gMacros[n] == nil) { // return 0; // } // HLock(gMacros[n]); // mp = (unsigned char *)*gMacros[n]; s = (unsigned char *)*mh; ph = myNewHandle(GetHandleSize(mh)); if (!ph) return 0; // ouch HLock(ph); first = p = (unsigned char *)*ph; netgetip(myipnum); // totally revised - we parse as we go (RAB BetterTelnet 2.0b5) // this has the pleasant side effect of getting rid of the use of 254 and 255 as special // characters, so we can use them in macros now - you can now send telnet options from a macro! num = 0; pos = 0; escape = 0; while ( *s) { if (((!(*s >= '0' && *s <= '9')) && pos && escape) || (escape && (pos >= 3))) { // do this ONCE - // it's a kludge to do this in each case *p++=num; pos = 0; escape = 0; // now the rest of the code will take care of whatever char this was } if (escape) { escape = 0; switch (*s) { case 'i': SendStringAsIfTyped(tw, (char *)first, p-first); sprintf(temp,"%d.%d.%d.%d", myipnum[0], myipnum[1], myipnum[2], myipnum[3]); SendStringAsIfTyped(tw, temp, strlen(temp)); first = p; break; case '#': SendStringAsIfTyped(tw, (char *)first, p-first); sprintf(temp,"%d", VSgetlines(tw->vs)); SendStringAsIfTyped(tw, temp, strlen(temp)); first = p; break; case 'n': *p++='\012'; break; case 'r': *p++='\015'; break; case 't': *p++='\t'; break; case '"': *p++='\"'; break; case '\\': *p++='\\'; break; default: if (*s <='9' && *s >='0' && pos <3) { num= num*8+( *s -'0'); pos++; escape=1; } else { // if (pos ==0 && num==0) { *p++='\\'; *p++=*s; // } // else { // *p++=num; // pos= 0; // s--; /* back up the buffer. */ // } } break; } } else { if (*s=='\\') { num=0; pos=0; escape=1; } else *p++=*s; } s++; } if (pos >0) *p++=num; SendStringAsIfTyped(tw, (char *)first, p-first); DisposeHandle(mh); DisposeHandle(ph); return 0; } // postcondition: returns _LOCKED_ macro handle in desthp short getmacrointohandle(NewMacroInfo *macrost, short n, Handle *desthp) { // RAB BetterTelnet 2.0b5 - for new sendmacro Handle macroHandle, desth; Ptr pos, dest; long offset, length; if (n < 0 || n >= NUM_MACROS) { return -1; } // find the macro in the new structure if (n == 0) // no offset for this offset = 0; else offset = macrost->index[n]; macroHandle = macrost->handle; HLock(macroHandle); pos = *macroHandle; pos += offset; length = strlen(pos); if (!length) return -1; // don't bother if it's null desth = myNewHandle(length + 1); if (!desth) return -1; // ouch HLock(desth); *desthp = desth; dest = *desth; strcpy(dest, pos); // here we go HUnlock(macroHandle); // that's right, we DON'T unlock the handle into which the macro // has been copied (desth), only the global macros handle! return 0; } short getmacro(NewMacroInfo *macrost, short n, char *dest, short room) // no more quoteflag! no more kludge! { // RAB BetterTelnet 2.0b5 Handle macroHandle; Ptr pos; long offset, length; if (n < 0 || n >= NUM_MACROS) { return -1; } // find the macro in the new structure if (n == 0) // no offset for this offset = 0; else offset = macrost->index[n]; macroHandle = macrost->handle; HLock(macroHandle); pos = *macroHandle; pos += offset; length = strlen(pos); if (length >= room) { // >= compensates for null termination length = room - 1; // truncate if too long strncpy(dest, pos, length); pos += length; *pos = 0; } else strcpy(dest, pos); // or just move it in HUnlock(macroHandle); return 0; } #if 0 short oldgetmacro(short n, char *dest, short room, short quoteflag) { unsigned char *s; // Invalid number if (n<0 || n>9) { return -1; } // Empty macro, so return empty string if (gMacros[n] == nil) { *dest = 0; return 0; } s = (unsigned char *)*gMacros[n]; while (*s && (room >= 5)) { // 5 = (size of \xxx) + (terminating \0) switch( *s) { case MACRO_IP : *dest++='\\'; *dest++='i'; room--; break; case MACRO_LINES : *dest++='\\'; *dest++='#'; room--; break; case '\\': *dest++='\\'; *dest++='\\'; room--; break; case '\015': *dest++='\\'; *dest++='r'; room--; break; case '\012': *dest++='\\'; *dest++='n'; room--; break; case '\t': *dest++='\\'; *dest++='t'; room--; break; default: if ( isprint(*s) && ((*s != '\042') || (!quoteflag))) // RAB BetterTelnet 2.0b3 - fix for quote bug *dest++=*s; else { *dest++='\\'; *dest++= (*s / 64) +'0'; *dest++= ((*s % 64) / 8)+'0'; *dest++= (*s % 8) +'0'; room = room - 3; } break; } room--; s++; } *dest = 0; return( 0); } #endif void Macros( void) { DialogPtr dtemp; short dItem; short i; Rect dBox; Str255 temp; Handle MacString[10], rubbish; SetCursor(theCursors[normcurs]); if (TelInfo->macrosModeless) { SelectWindow(TelInfo->macrosModeless); return; } dtemp=GetNewMyDialog( MacroDLOG, NULL, kInFront, (void *)ThirdCenterDialog); SetDialogDefaultItem(dtemp, 1); SetDialogCancelItem(dtemp, 2); SetDialogTracksCursor(dtemp, 1); dialogPane = 0; // start with Command-[0-9] // RAB BetterTelnet 2.0b5 - fix cancel button so it works again oldMacros = TelInfo->newMacros.handle; HandToHand(&oldMacros); oldMacroIndexes = TelInfo->newMacros; // now fix the strings for (i=0; i<10; i++) { GetIndString(temp, 7100, i + (10 * dialogPane) + 1); GetDialogItem(dtemp, i+3, &dItem, &rubbish, &dBox); if (!temp[0]) { HideDialogItem(dtemp, i+13); HideDialogItem(dtemp, i+3); } else { ShowDialogItem(dtemp, i+13); ShowDialogItem(dtemp, i+3); } SetDialogItemText(rubbish, temp); } for (i=0; i<10; i++) { getmacro(&TelInfo->newMacros, i, (char *) &temp, 256); /* BYU LSC */ c2pstr((char *)temp); /* BYU LSC */ GetDialogItem( dtemp, i+13, &dItem, &MacString[i], &dBox); SetDialogItemText( MacString[i], temp ); } TelInfo->macrosModeless = dtemp; } short ModalMacros(NewMacroInfo *macrost) { DialogPtr dtemp; short dItem; short i; Rect dBox; Str255 temp; Handle MacString[10], rubbish; dtemp=GetNewMyDialog( MacroDLOG + 2, NULL, kInFront, (void *)ThirdCenterDialog); SetDialogDefaultItem(dtemp, 1); SetDialogCancelItem(dtemp, 2); SetDialogTracksCursor(dtemp, 1); HideDialogItem(dtemp, 25); // no save default in session macros dialog dialogPane = 0; // start with Command-[0-9] // RAB BetterTelnet 2.0b5 - fix cancel button so it works again oldMacros = macrost->handle; HandToHand(&oldMacros); oldMacroIndexes = *macrost; // now fix the strings for (i=0; i<10; i++) { GetIndString(temp, 7100, i + (10 * dialogPane) + 1); GetDialogItem(dtemp, i+3, &dItem, &rubbish, &dBox); if (!temp[0]) { HideDialogItem(dtemp, i+13); HideDialogItem(dtemp, i+3); } else { ShowDialogItem(dtemp, i+13); ShowDialogItem(dtemp, i+3); } SetDialogItemText(rubbish, temp); } for (i=0; i<10; i++) { getmacro(macrost, i, (char *) &temp, 256); /* BYU LSC */ c2pstr((char *)temp); /* BYU LSC */ GetDialogItem( dtemp, i+13, &dItem, &MacString[i], &dBox); SetDialogItemText( MacString[i], temp ); } dItem = 0; while ((dItem != 1) && (dItem != 2)) { movableModalDialog(0, &dItem); MacroDialog(macrost, dtemp, 0, dItem); } if (dItem == 2) CancelMacros(macrost, dtemp); else CloseMacros(macrost, dtemp); return dItem; } // NB: As of 2.0fc1, theEvent can be NULL! It isn't used anywhere, so don't _let_ it be // used anywhere! void MacroDialog(NewMacroInfo *macrost, DialogPtr dtemp, EventRecord *theEvent, short dItem) { short i; Rect dBox; Str255 temp; Handle MacString[10], rubbish; switch (dItem) { case 27: // switch keyset (pane) - RAB BetterTelnet 2.0b5 for (i=0; i<10; i++) { GetDialogItem( dtemp, i+13, &dItem, &MacString[i], &dBox); GetDialogItemText( MacString[i], temp); p2cstr(temp); setmacro(macrost, i + (10 * dialogPane), (char *) &temp); } dialogPane = GetCntlVal(dtemp, 27) - 1; // now fix the strings for (i=0; i<10; i++) { GetIndString(temp, 7100, i + (10 * dialogPane) + 1); GetDialogItem(dtemp, i+3, &dItem, &rubbish, &dBox); if (!temp[0]) { HideDialogItem(dtemp, i+13); HideDialogItem(dtemp, i+3); } else { ShowDialogItem(dtemp, i+13); ShowDialogItem(dtemp, i+3); } SetDialogItemText(rubbish, temp); } for (i=0; i<10; i++) { getmacro(macrost, i + (10 * dialogPane), (char *) &temp, 256); c2pstr((char *)temp); GetDialogItem( dtemp, i+13, &dItem, &MacString[i], &dBox); SetDialogItemText( MacString[i], temp ); } break; case (MacroExport): // we _used_ to get all the macros out, but now only the current set of 10 for (i=0; i<10; i++) { GetDialogItem( dtemp, i+13, &dItem, &MacString[i], &dBox); GetDialogItemText( MacString[i], temp); p2cstr(temp); setmacro(macrost, i + (10 * dialogPane), (char *) &temp); // RAB BetterTelnet 2.0b5 (revised) } saveMacros(macrost, (FSSpec *) NULL); break; case 25: for (i=0; i<10; i++) { GetDialogItem( dtemp, i+13, &dItem, &MacString[i], &dBox); GetDialogItemText( MacString[i], temp); p2cstr(temp); setmacro(macrost, i + (10 * dialogPane), (char *) &temp); } SaveGlobalMacros(macrost); break; case (MacroImport): loadMacros(macrost, (FSSpec *) NULL); for (i=0; i<10; i++) { getmacro(macrost, i + (10 * dialogPane), (char *) &temp, 256); c2pstr((char *)temp); GetDialogItem( dtemp, i+13, &dItem, &MacString[i], &dBox); SetDialogItemText( MacString[i], temp ); } break; case 1: case 2: break; default: if (dItem >2 && dItem <13) { i=dItem-3; getmacro(macrost, i + (dialogPane * 10), (char *) &temp, 256); /* BYU LSC */ c2pstr((char *)temp); GetDialogItem( dtemp, i+13, &dItem, &MacString[i], &dBox); SetDialogItemText( MacString[i], temp ); /* BYU LSC - Revert the mother */ SelectDialogItemText( dtemp, i+13, 0, 32767); /* And select it... */ } break; } } void CancelMacros(NewMacroInfo *macrost, DialogPtr dtemp) { DisposeDialog(dtemp); DisposeHandle(macrost->handle); *macrost = oldMacroIndexes; macrost->handle = oldMacros; AdjustMenus(); DoTheMenuChecks(); } void CloseMacros(NewMacroInfo *macrost, DialogPtr dtemp) { short dItem; short i; Rect dBox; Str255 temp; Handle MacString[10]; for (i=0; i<10; i++) { GetDialogItem( dtemp, i+13, &dItem, &MacString[i], &dBox); GetDialogItemText( MacString[i], temp); p2cstr(temp); setmacro(macrost, i + (10 * dialogPane), (char *) &temp); } DisposeHandle(oldMacros); DisposeDialog(dtemp); AdjustMenus(); DoTheMenuChecks(); } #if 0 void oldsaveMacros(FSSpec *theFile) { SFReply whereReply; short refNum,exist; FSSpec macroFile; long junk; short i; char temp[256], temp2[256]; Point where; OSErr err; Str255 tempString,tempString2; where.h = 100; where.v = 100; GetIndString(tempString,MISC_STRINGS,SAVE_MACROS_STRING); GetIndString(tempString2,MISC_STRINGS,DEFAULT_MACRO_SET_NAME); if (theFile == 0) { SFPutFile( where, tempString, tempString2, 0L, &whereReply); if (!whereReply.good) return; BlockMoveData(&whereReply.fName, macroFile.name, (*whereReply.fName)+1); GetWDInfo(whereReply.vRefNum, ¯oFile.vRefNum, ¯oFile.parID, &junk); } else macroFile = *theFile; if ((err = HCreate(macroFile.vRefNum, macroFile.parID, macroFile.name, kNCSACreatorSignature, 'TEXT')) == dupFNErr) exist = 1; err = HOpenDF(macroFile.vRefNum, macroFile.parID, macroFile.name, fsWrPerm, &refNum); if (exist) SetEOF(refNum, 0L); for (i = 0; i < 10; i++) { oldgetmacro(i, temp, sizeof(temp), 1); sprintf(temp2, "key%d = \"", i); CStringToFile(refNum,(unsigned char *) temp2); if (*temp) { CStringToFile(refNum,(unsigned char *) temp); } strcpy(temp2,"\"\015"); CStringToFile(refNum,(unsigned char *) temp2); } FSClose(refNum); } #endif void saveMacros(NewMacroInfo *macrost, FSSpec *theFile) { SFReply whereReply; short refNum,exist; FSSpec macroFile; long junk, len, len2; short i; Point where; OSErr err; Str255 tempString,tempString2; Handle macroHandle; Ptr pos; if (!macrost->handle) return; // sanity check where.h = 100; where.v = 100; GetIndString(tempString,MISC_STRINGS,SAVE_MACROS_STRING); GetIndString(tempString2,MISC_STRINGS,DEFAULT_MACRO_SET_NAME); if (theFile == 0) { SFPutFile( where, tempString, tempString2, 0L, &whereReply); if (!whereReply.good) return; BlockMoveData(&whereReply.fName, macroFile.name, (*whereReply.fName)+1); GetWDInfo(whereReply.vRefNum, ¯oFile.vRefNum, ¯oFile.parID, &junk); } else macroFile = *theFile; if ((err = HCreate(macroFile.vRefNum, macroFile.parID, macroFile.name, kNCSACreatorSignature, 'TEXT')) == dupFNErr) exist = 1; err = HOpenDF(macroFile.vRefNum, macroFile.parID, macroFile.name, fsWrPerm, &refNum); if (exist) SetEOF(refNum, 0L); // the new code - RAB BetterTelnet 2.0b5 macroHandle = macrost->handle; HandToHand(¯oHandle); HLock(macroHandle); pos = *macroHandle; len = len2 = GetHandleSize(macroHandle); while (len) { if (*pos == 0) *pos = 13; pos++; len--; } pos = *macroHandle; junk = 2; FSWrite(refNum, &junk, "!\015"); FSWrite(refNum, &len2, pos); DisposeHandle(macroHandle); // it's a copy anyway, get rid of it! FSClose(refNum); } void loadMacros(NewMacroInfo *macrost, FSSpec *theFile) { SFReply sfr; long junk; SFTypeList typesok = {'TEXT'}; Point where; FSSpec macros; OSErr err; short fileRef; where.h=100;where.v=100; if (theFile == 0L) { SFGetFile( where, NULL, 0L, 1, typesok, 0L, &sfr); if (!sfr.good) return; BlockMove(&sfr.fName, macros.name, (*sfr.fName)+1); GetWDInfo(sfr.vRefNum, ¯os.vRefNum, ¯os.parID, &junk); err = HOpenDF(macros.vRefNum, macros.parID, macros.name, fsRdPerm, &fileRef); } else err = HOpenDF(theFile->vRefNum, theFile->parID, theFile->name, fsRdPerm, &fileRef); if (err != noErr) return; parseMacroFile(macrost, fileRef); FSClose(fileRef); } void parseMacroFile(NewMacroInfo *macrost, short fileRef) { unsigned char buffer[300],*bufferPtr; unsigned char newMacro[256], *newMacroPtr; OSErr fileErr = noErr; short numMacrosRead = 0; short totalLen,i; long count=1; bufferPtr = buffer; count = 2; fileErr = FSRead(fileRef,&count,bufferPtr); if ((fileErr != eofErr) && (count == 2)) if (!strncmp((char *)bufferPtr, "!\015", 2)) { disposemacros(macrost); //sets all handles to null (but disposes them first) parseNewMacros(macrost, fileRef); return; } bufferPtr += count; count = 1; GetDefaultMacros(); // get the defaults for the extended keys while ((fileErr != eofErr)&&(numMacrosRead < 10)) { fileErr = FSRead(fileRef,&count,bufferPtr); while((*bufferPtr != 0x0D)&&(fileErr != eofErr)) //while not CR or EOF { ++bufferPtr; fileErr = FSRead(fileRef,&count,bufferPtr); } totalLen = bufferPtr-buffer; bufferPtr = buffer; newMacroPtr = newMacro; while((*bufferPtr++ != '"')&&(totalLen != 0)) --totalLen; while((*bufferPtr != '"')&&(totalLen != 0)) { *newMacroPtr++ = *bufferPtr++; --totalLen; } *newMacroPtr = NULL; //make this a C string setmacro(macrost, numMacrosRead,(char *)newMacro); // just set the new macro directly bufferPtr = buffer; ++numMacrosRead; } } // RAB BetterTelnet 2.0b5 // handle should be locked and detached void ParseMacrosFromHandle(NewMacroInfo *macrost, Handle theHandle) { Ptr macroPtr; long macroLength; macroPtr = *theHandle; macroLength = GetHandleSize(theHandle) - 2; // format and sanity checks follow if ((macroLength < 1) || (*macroPtr != '!') || (*(macroPtr + 1) != '\015')) { DisposeHandle(theHandle); setupNewMacros(macrost); return; } // bah BlockMoveData(macroPtr + 2, macroPtr, macroLength); // get rid of !CR HUnlock(theHandle); SetHandleSize(theHandle, macroLength); HLock(theHandle); // now invoke the actual parser parseNewMacros2(macrost, theHandle); } // RAB BetterTelnet 2.0b5 void parseNewMacros(NewMacroInfo *macrost, short fileRef) { Handle macroHandle; Ptr macroPtr, pos; long macroLength, count, len; OSErr fileErr; short i, flag; fileErr = GetEOF(fileRef, ¯oLength); macroLength -= 2; // compensate for !CR macroHandle = myNewHandle(macroLength); if (!macroHandle) { // memory error? disposemacros(macrost); setupNewMacros(macrost); // this better work, or we crash hard return; } HLock(macroHandle); macroPtr = *macroHandle; count = macroLength; FSRead(fileRef, &count, macroPtr); parseNewMacros2(macrost, macroHandle); } void parseNewMacros2(NewMacroInfo *macrost, Handle macroHandle) { Ptr macroPtr, pos; long macroLength, len; short i, flag; macroLength = GetHandleSize(macroHandle); macroPtr = *macroHandle; len = macroLength; pos = macroPtr; i = 1; // first index is obviously always zero, so we use it as length (see below) flag = 0; while (len) { if (*pos == 13) *pos = 0; // for strlen pos++; len--; } len = macroLength; pos = macroPtr; while ((i < NUM_MACROS) && (len > 1)) { // if len = 1, this is the last char; // then the index points out of the handle! if (*pos == 0) { macrost->index[i] = (pos - macroPtr + 1); i++; } pos++; len--; } macrost->handle = macroHandle; macrost->index[0] = macroLength; // first index is length of whole shebang HUnlock(macroHandle); fixMacros(macrost); // make sure there's an entry for each macro } // This routine makes sure there is at least a null byte (and accompanying index) // for every defined macro numbered n such that n < NUM_MACROS // It lengthens the handle if necessary (backwards compatibility), // but does NOT truncate additional data (forwards compatibility). void fixMacros(NewMacroInfo *macrost) { Handle macroHandle; Ptr macroPtr, pos; long len, len2; short i, num; macroHandle = macrost->handle; HLock(macroHandle); macroPtr = *macroHandle; len = macrost->index[0]; pos = macroPtr; pos += (len - 1); if (*pos != 0) { len++; HUnlock(macroHandle); SetHandleSize(macroHandle, len); HLock(macroHandle); macroPtr = *macroHandle; pos = macroPtr + (len - 1); *pos = 0; } num = 0; for (i = 1; i < NUM_MACROS; i++) { if (macrost->index[i] == 0) { num = i; break; } } if (num) { len2 = len; len += (NUM_MACROS - num); HUnlock(macroHandle); SetHandleSize(macroHandle, len); HLock(macroHandle); macroPtr = *macroHandle; pos = macroPtr + len2; for (i = num; i < NUM_MACROS; i++, pos++) { *pos = 0; macrost->index[i] = pos - macroPtr; } } HUnlock(macroHandle); macrost->index[0] = len; } \ No newline at end of file diff --git a/source/macros/macros.proto.h b/source/macros/macros.proto.h index d664a59..3bd318a 100755 --- a/source/macros/macros.proto.h +++ b/source/macros/macros.proto.h @@ -1 +1 @@ - /* macros.c */ void MACROSunload(void); void initmacros(void); void CheckGlobalMacros(void); void setmacro(short n, char *s); short sendmacro(struct WindRec *tw, short n); short getmacro(short n, char *dest, short room); void Macros(void); void saveMacros(FSSpec *theFile); void SaveGlobalMacros(); void loadMacros(FSSpec *theFile); void parseMacroFile(short fileRef); void CloseMacros(void); void MacroDialog(EventRecord *, short); \ No newline at end of file +/* macros.c */ void MACROSunload(void); void initmacros(void); void disposemacros(NewMacroInfo *); void CheckGlobalMacros(void); void setmacro(NewMacroInfo *, short n, char *s); //void oldsetmacro(short n, char *s); short sendmacro(struct WindRec *tw, short n); short getmacro(NewMacroInfo *, short n, char *dest, short room); short getmacrointohandle(NewMacroInfo *, short, Handle *); //short oldgetmacro(short, char *, short, short); void Macros(void); void saveMacros(NewMacroInfo *, FSSpec *theFile); //void oldsaveMacros(FSSpec *theFile); void SaveGlobalMacros(NewMacroInfo *); void loadMacros(NewMacroInfo *, FSSpec *theFile); void parseMacroFile(NewMacroInfo *, short fileRef); void parseNewMacros(NewMacroInfo *, short); void ParseMacrosFromHandle(NewMacroInfo *, Handle); void parseNewMacros2(NewMacroInfo *, Handle); void CloseMacros(NewMacroInfo *, DialogPtr); void CancelMacros(NewMacroInfo *, DialogPtr); void MacroDialog(NewMacroInfo *, DialogPtr, EventRecord *, short); void parseNewMacros(NewMacroInfo *, short); void fixMacros(NewMacroInfo *); void setupNewMacros(NewMacroInfo *); void GetDefaultMacros(void); short ModalMacros(NewMacroInfo *); \ No newline at end of file diff --git a/source/main/Connections.c b/source/main/Connections.c index 470f9cc..f691fa2 100755 --- a/source/main/Connections.c +++ b/source/main/Connections.c @@ -1 +1 @@ -// Connections.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "telneterrors.h" #include "DlogUtils.proto.h" #include "movableModal.h" #include "wind.h" #include "event.proto.h" #include "rsinterf.proto.h" #include "vsdata.h" #include "vskeys.h" #include "vsinterf.proto.h" #include "vgtek.proto.h" #include "tekrgmac.proto.h" #include "vr.h" #include "vrrgmac.proto.h" #include "network.proto.h" #include "mydnr.proto.h" #include "InternalEvents.h" #include "menuseg.proto.h" #include "maclook.proto.h" #include "parse.proto.h" #include "parse.h" #include "configure.proto.h" #include "netevent.proto.h" #include "linemode.proto.h" #include "mainseg.proto.h" #include "prefs.proto.h" #include "popup.h" #include "popup.proto.h" #include "Connections.proto.h" #include "tnae.h" #include "authencrypt.h" #include "authencrypt.proto.h" #include "wdefpatch.proto.h" #include "LinkedList.proto.h" /* These are all of the variables we need... */ extern Cursor *theCursors[NUMCURS]; /* all the cursors in a nice bundle */ extern WindRec *screens; extern short scrn; extern short nNational; // Number of user-installed translation tables extern MenuHandle myMenus[]; extern Boolean authOK; extern Boolean encryptOK; extern unsigned char *gReadspace; extern short gBlocksize; static short WindByPort(short port); static void setSessStates(DialogPtr dptr); static pascal short POCdlogfilter( DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(POCdlogfilter, ModalFilter); void OpenPortSpecial(MenuHandle menuh, short item) { ConnInitParams **theParams; Boolean success; Str255 scratchPstring; GetItem(menuh, item, scratchPstring); theParams = NameToConnInitParams(scratchPstring, TRUE, 0); if (theParams == NULL) { OutOfMemory(1020); return; } success = CreateConnectionFromParams(theParams); } SIMPLE_UPP(POCdlogfilter, ModalFilter); pascal short POCdlogfilter( DialogPtr dptr, EventRecord *evt, short *item) { short key; if (evt->what == keyDown) { key = evt->message & charCodeMask; if ( ((key == 'A') || (key == 'a')) && (evt->modifiers & cmdKey) ) { *item = NCauthenticate; return(-1); } if ( ((key == 'E') || (key == 'e')) && (evt->modifiers & cmdKey) ) { *item = NCencrypt; return(-1); } } if ((evt->what == keyDown) || (evt->what == autoKey)) { key = evt->message & charCodeMask; if (key == 0x1F) { *item = 1000; return(-1); } if (key == 0x1E) { *item = 1001; return(-1); } } // if (evt->what == mouseDown) // return(PopupMousedown(dptr, evt, item)); // RAB BetterTelnet 1.2 - we let StdFilterProc handle this now // return(DLOGwOK_Cancel(dptr, evt, item)); return CallStdFilterProc(dptr, evt, item); } void PresentOpenConnectionDialog(void) { ConnInitParams **InitParams; DialogPtr dptr; short ditem, scratchshort, rolfito; Boolean success; long scratchlong; Str255 scratchPstring, terminalPopupString, scritchPstring; Handle ItemHandle; SessionPrefs **defaultSessHdl,**tempSessHdl; short numberOfTerms, sessMark, requestPort; MenuHandle SessPopupHdl, TermPopupHdl; Rect scratchRect; Point SessPopupLoc; short TerminalIndex, itemNumber = 1; popup TPopup[] = {{NCtermpopup, (MenuHandle) 0, 1}, {0, (MenuHandle) 0, 0}}; Size junk; LinkedListNode *theHead; SetCursor(theCursors[normcurs]); SetUpMovableModalMenus(); dptr = GetNewMyDialog(NewCnxnDLOG, NULL, kInFront, (void *)ThirdCenterDialog); if (dptr == NULL) { OutOfMemory(1000); return; } SetDialogDefaultItem(dptr, 1); SetDialogCancelItem(dptr, 2); SetDialogTracksCursor(dptr, 1); ditem = 3; sessMark = 1; GetIndString(scratchPstring,MISC_STRINGS,SESSION_STRING); SessPopupHdl = NewMenu(668, scratchPstring); if (SessPopupHdl == NULL) { DisposeDialog(dptr); OutOfMemory(1000); return; } UseResFile(TelInfo->SettingsFile); numberOfTerms = Count1Resources(SESSIONPREFS_RESTYPE); theHead = createSortedList(SESSIONPREFS_RESTYPE,numberOfTerms,"\p"); EnableItem(SessPopupHdl, 0); // Make sure the entire menu is enabled addListToMenu(SessPopupHdl, theHead, 1); deleteList(&theHead); SetItemMark(SessPopupHdl, 1, 18); GetDItem(dptr, NCsesspopup, &scratchshort, &ItemHandle, &scratchRect); SessPopupLoc.h = scratchRect.left; SessPopupLoc.v = scratchRect.top; // TermPopupHdl = NewMenu(666, "\p"); // if (TermPopupHdl == NULL) { // DisposeHandle((Handle)SessPopupHdl); // DisposeDialog(dptr); // OutOfMemory(1000); // return; // } SetPort(dptr); LocalToGlobal(&SessPopupLoc); // numberOfTerms = Count1Resources(TERMINALPREFS_RESTYPE); // theHead = createSortedList(TERMINALPREFS_RESTYPE,numberOfTerms,"\p"); // addListToMenu(TermPopupHdl, theHead); // deleteList(&theHead); // TPopup[0].h = TermPopupHdl; // PopupInit(dptr, TPopup); // Get default auth/encrypt settings from default session defaultSessHdl = GetDefaultSession(); HLock((Handle)defaultSessHdl); BlockMove("\p", scratchPstring, 15); GetHostNameFromSession(scratchPstring); if ((**defaultSessHdl).port != 23) { NumToString((unsigned short)(**defaultSessHdl).port, scritchPstring); pstrcat(scratchPstring, "\p:"); if ((**defaultSessHdl).portNegative) pstrcat(scratchPstring, "\p-"); pstrcat(scratchPstring, scritchPstring); } SetTEText(dptr, NChostname, scratchPstring); SelIText(dptr, NChostname, 0, 32767); SetCntrl(dptr, NCauthenticate, (**defaultSessHdl).authenticate && authOK); SetCntrl(dptr, NCencrypt, (**defaultSessHdl).encrypt && encryptOK); if (!authOK) { Hilite( dptr, NCauthenticate, 255); Hilite( dptr, NCencrypt, 255); } // TerminalIndex = findPopupMenuItem(TermPopupHdl,(**defaultSessHdl).TerminalEmulation); // TPopup[0].choice = TerminalIndex; // PopupInit(dptr, TPopup); DisposeHandle((Handle)defaultSessHdl); setSessStates(dptr); while (ditem > NCcancel) { movableModalDialog(POCdlogfilterUPP, &ditem); switch(ditem) { case NCauthenticate: case NCencrypt: GetDItem(dptr, ditem, &scratchshort, &ItemHandle, &scratchRect); if ((**(ControlHandle)ItemHandle).contrlHilite == 0) { // if control not disabled FlipCheckBox(dptr, ditem); setSessStates(dptr); } break; case NCsesspopup: GetDItem(dptr, NCsesspopup, &scratchshort, &ItemHandle, &scratchRect); SessPopupLoc.h = scratchRect.left; SessPopupLoc.v = scratchRect.top; SetPort(dptr); LocalToGlobal(&SessPopupLoc); InsertMenu(SessPopupHdl, hierMenu); CalcMenuSize(SessPopupHdl); scratchlong = PopUpMenuSelect(SessPopupHdl, SessPopupLoc.v, SessPopupLoc.h, 0); DeleteMenu(668); if (scratchlong) { scratchshort = scratchlong & 0xFFFF; // Apple sez ignore the high word SetItemMark(SessPopupHdl, sessMark, 0); sessMark = scratchshort; SetItemMark(SessPopupHdl, sessMark, 18); GetItem(SessPopupHdl, scratchshort, scratchPstring); tempSessHdl = (SessionPrefs **)Get1NamedResource(SESSIONPREFS_RESTYPE, scratchPstring); if (tempSessHdl) { // TerminalIndex = findPopupMenuItem(TermPopupHdl, // (**tempSessHdl).TerminalEmulation); // TPopup[0].choice = TerminalIndex; // DrawPopUp(dptr, NCtermpopup); //update popup strcpy((char *)scratchPstring, (char *)(**tempSessHdl).hostname); if ((**tempSessHdl).port != 23) { NumToString((unsigned short)(**tempSessHdl).port, scritchPstring); pstrcat(scratchPstring, "\p:"); if ((**tempSessHdl).portNegative) pstrcat(scratchPstring, "\p-"); pstrcat(scratchPstring, scritchPstring); } SetTEText(dptr, NChostname, scratchPstring);//update the hostname SelIText(dptr, NChostname, 0, 32767); SetCntrl(dptr, NCauthenticate, (**tempSessHdl).authenticate && authOK);//update the auth status SetCntrl(dptr, NCencrypt, (**tempSessHdl).encrypt && encryptOK); setSessStates(dptr);//encrypt cant be on w/o authenticate ReleaseResource((Handle)tempSessHdl); } } break; case 1001: SetItemMark(SessPopupHdl, sessMark, 0); sessMark--; if (sessMark < 1) sessMark = CountMItems(SessPopupHdl); SetItemMark(SessPopupHdl, sessMark, 18); GetItem(SessPopupHdl, sessMark, scratchPstring); tempSessHdl = (SessionPrefs **)Get1NamedResource(SESSIONPREFS_RESTYPE, scratchPstring); if (tempSessHdl) { strcpy((char *)scratchPstring, (char *)(**tempSessHdl).hostname); if ((**tempSessHdl).port != 23) { NumToString((unsigned short)(**tempSessHdl).port, scritchPstring); pstrcat(scratchPstring, "\p:"); if ((**tempSessHdl).portNegative) pstrcat(scratchPstring, "\p-"); pstrcat(scratchPstring, scritchPstring); } SetTEText(dptr, NChostname, scratchPstring);//update the hostname SelIText(dptr, NChostname, 0, 32767); SetCntrl(dptr, NCauthenticate, (**tempSessHdl).authenticate && authOK);//update the auth status SetCntrl(dptr, NCencrypt, (**tempSessHdl).encrypt && encryptOK); setSessStates(dptr);//encrypt cant be on w/o authenticate ReleaseResource((Handle)tempSessHdl); } break; case 1000: SetItemMark(SessPopupHdl, sessMark, 0); sessMark++; if (sessMark > CountMItems(SessPopupHdl)) sessMark = 1; SetItemMark(SessPopupHdl, sessMark, 18); GetItem(SessPopupHdl, sessMark, scratchPstring); tempSessHdl = (SessionPrefs **)Get1NamedResource(SESSIONPREFS_RESTYPE, scratchPstring); if (tempSessHdl) { strcpy((char *)scratchPstring, (char *)(**tempSessHdl).hostname); if ((**tempSessHdl).port != 23) { NumToString((unsigned short)(**tempSessHdl).port, scritchPstring); pstrcat(scratchPstring, "\p:"); if ((**tempSessHdl).portNegative) pstrcat(scratchPstring, "\p-"); pstrcat(scratchPstring, scritchPstring); } SetTEText(dptr, NChostname, scratchPstring);//update the hostname SelIText(dptr, NChostname, 0, 32767); SetCntrl(dptr, NCauthenticate, (**tempSessHdl).authenticate && authOK);//update the auth status SetCntrl(dptr, NCencrypt, (**tempSessHdl).encrypt && encryptOK); setSessStates(dptr);//encrypt cant be on w/o authenticate ReleaseResource((Handle)tempSessHdl); } break; default: break; } // switch } // while if (ditem == NCcancel) { // PopupCleanup(); DisposeMenu(SessPopupHdl); // drh Bug fix: memory leak DisposeDialog(dptr); ResetMenus(); return; } GetTEText(dptr, NChostname, scratchPstring); if (!Length(scratchPstring)) { // PopupCleanup(); DisposeMenu(SessPopupHdl); // drh Bug fix: memory leak DisposeDialog(dptr); ResetMenus(); return; } // GetItem(TPopup[0].h, TPopup[0].choice, terminalPopupString); // PopupCleanup(); for (rolfito = 0; rolfito < Length(scratchPstring); rolfito++) if (scratchPstring[rolfito + 1] == ':') scratchPstring[rolfito + 1] = ' '; MaxMem(&junk); GetItem(SessPopupHdl, sessMark, scritchPstring); InitParams = NameToConnInitParams(scratchPstring, FALSE, scritchPstring); if (InitParams == NULL) { DisposeMenu(SessPopupHdl); // drh Bug fix: memory leak DisposeDialog(dptr); OutOfMemory(1000); return; } // if ((**InitParams).terminal == NULL) //if this is not null, then the string was an alias, // { // so dont use the popup terminal // (**InitParams).terminal = (TerminalPrefs **) // Get1NamedResource(TERMINALPREFS_RESTYPE,terminalPopupString); // DetachResource((Handle)(**InitParams).terminal); // if (InitParams == NULL) { // OutOfMemory(1000); // DisposeDialog(dptr); // return; // } if (GetCntlVal(dptr, NCauthenticate)) (**(**InitParams).session).authenticate = 1; else (**(**InitParams).session).authenticate = 0; if (GetCntlVal(dptr, NCencrypt)) (**(**InitParams).session).encrypt = 1; else (**(**InitParams).session).encrypt = 0; // } HLock((Handle)InitParams); HLock((Handle)(**InitParams).session); GetTEText(dptr, NCwindowname, scratchPstring); // Copy over the user specified window name. If blank, CreateConnectionFromParams // will copy the hostname to the windowname and append a number. if (Length(scratchPstring)) BlockMove(scratchPstring, (**InitParams).WindowName, (Length(scratchPstring) > 63) ? 64 : (Length(scratchPstring) + 1)); HUnlock((Handle)(**InitParams).session); HUnlock((Handle)InitParams); DisposeMenu(SessPopupHdl); // drh Bug fix: memory leak DisposeDialog(dptr); ResetMenus(); success = CreateConnectionFromParams(InitParams); } // Set states of session checkboxes static void setSessStates (DialogPtr dptr) { if (GetCntlVal(dptr, NCauthenticate)) { Hilite(dptr, NCencrypt, (encryptOK)? 0 : 255); } else { Hilite(dptr, NCencrypt, 255); SetCntrl(dptr, NCencrypt, false); } } void OpenConnectionFromURL(char *host, char *portstring, char *user, char *password) { ConnInitParams **Params; Str255 windowName, tempString; short len; long port; Params = ReturnDefaultConnInitParams(); windowName[0] = 0; // Set up window name if user (and password) given if (user != nil) { GetIndString(windowName, MISC_STRINGS, MISC_USERPRMPT); len = strlen(user); BlockMoveData(user,& windowName[Length(windowName)+1], len); windowName[0] += len; if (password != nil) { GetIndString(tempString, MISC_STRINGS, MISC_PSWDPRMPT); BlockMoveData(&tempString[1], &windowName[Length(windowName)+1], tempString[0]); windowName[0] += tempString[0]; len = strlen(password); BlockMoveData(password, &windowName[Length(windowName)+1], len); windowName[0] += len; } if (windowName[0] != 0) { BlockMoveData(windowName, (**Params).WindowName, Length(windowName)+1); } } CtoPstr(host); BlockMoveData(host, (**(**Params).session).hostname, host[0]+1); if (portstring != nil) { CtoPstr(portstring); StringToNum((StringPtr)portstring, &port); (**(**Params).session).port = port; } (void)CreateConnectionFromParams(Params); } Boolean CreateConnectionFromParams( ConnInitParams **Params) { short scratchshort, fontnumber, otherfnum; static short numWind = 1, stagNum = 1; SessionPrefs *SessPtr; TerminalPrefs *TermPtr; short cur; Str32 numPstring; Str255 scratchPstring; Boolean scratchBoolean; WindRec *theScreen; SetCursor(theCursors[watchcurs]); /* We may be here a bit */ // Check if we have the max number of sessions open if (TelInfo->numwindows == MaxSess) return(FALSE); cur = TelInfo->numwindows; /* Adjust # of windows and get this window's number */ TelInfo->numwindows++; theScreen = &screens[cur]; theScreen->active = CNXN_NOTINUSE; // Make sure it is marked as dead (in case we // abort screen creation after initiating DNR. // That way CompleteConnectionOpening will know // we didn't make it. HLockHi((Handle)Params); HLockHi((Handle)(**Params).terminal); HLockHi((Handle)(**Params).session); SessPtr = *((**Params).session); TermPtr = *((**Params).terminal); if (Length((**Params).WindowName) == 0) { BlockMove((**(**Params).session).hostname, (**Params).WindowName, Length((**(**Params).session).hostname)+1); if (SessPtr->port != 23) { NumToString((unsigned short)SessPtr->port, numPstring); pstrcat((**Params).WindowName, "\p:"); pstrcat((**Params).WindowName, numPstring); } NumToString(numWind++, numPstring); pstrcat((**Params).WindowName, "\p ("); pstrcat((**Params).WindowName, numPstring); // tack the number onto the end. pstrcat((**Params).WindowName, "\p)"); } if (SessPtr->hostname[0] == 0) { OperationFailedAlert(5, 0, 0); DisposeHandle((Handle)(**Params).terminal); DisposeHandle((Handle)(**Params).session); DisposeHandle((Handle)Params); TelInfo->numwindows--; updateCursor(1); return(FALSE); } Mnetinit(); // RAB BetterTelnet 1.0fc4 // Get the IP for the host while we set up the connection if (DoTheDNR(SessPtr->hostname, cur) != noErr) { OutOfMemory(1010); DisposeHandle((Handle)(**Params).terminal); DisposeHandle((Handle)(**Params).session); DisposeHandle((Handle)Params); TelInfo->numwindows--; updateCursor(1); return(FALSE); } DoTheMenuChecks(); theScreen->authenticate = SessPtr->authenticate && authOK; theScreen->encrypt = SessPtr->encrypt && encryptOK; theScreen->aedata = NULL; for (scratchshort = 0; scratchshort < sizeof(theScreen->myopts); scratchshort++) { theScreen->myopts[scratchshort] = 0; theScreen->hisopts[scratchshort] = 0; } theScreen->cannon[0] = '\0'; theScreen->vtemulation = TermPtr->vtemulation; theScreen->forcesave = SessPtr->forcesave; theScreen->eightbit = TermPtr->eightbit; // Is this necessary? theScreen->portNum = SessPtr->port; theScreen->portNegative = SessPtr->portNegative; theScreen->allowBold = TermPtr->allowBold; theScreen->colorBold = TermPtr->colorBold; theScreen->realbold = TermPtr->realbold; theScreen->inversebold = TermPtr->boldFontStyle; theScreen->ignoreBeeps = SessPtr->ignoreBeeps; theScreen->otpauto = SessPtr->otpauto; theScreen->otpnoprompt = SessPtr->otpnoprompt; theScreen->otphex = SessPtr->otphex; theScreen->otpmulti = SessPtr->otpmulti; theScreen->otpsavepass = SessPtr->otpsavepass; theScreen->oldScrollback = TermPtr->oldScrollback; pstrcpy((unsigned char *)theScreen->otppassword, (unsigned char *)SessPtr->otppassword); theScreen->otpautostate = 0; theScreen->otpautobuffer[7] = 0; theScreen->emacsmeta = TermPtr->emacsmetakey; theScreen->Xterm = TermPtr->Xtermsequences; theScreen->remapCtrlD = TermPtr->remapCtrlD; theScreen->keypadmap = TermPtr->remapKeypad; theScreen->port = -1; // netxopen will take care of this theScreen->lineAllow = SessPtr->linemode; if (SessPtr->linemode) //we allow linemode initLinemode(&screens[cur]); GetFNum(TermPtr->DisplayFont, &fontnumber); GetFNum(TermPtr->BoldFont, &otherfnum); theScreen->vs = RSnewwindow(&((**Params).WindowLocation),TermPtr->numbkscroll, TermPtr->vtwidth, TermPtr->vtheight, (**Params).WindowName, TermPtr->vtwrap, fontnumber, TermPtr->fontsize, 0, 1, SessPtr->forcesave,cur, TermPtr->allowBold, TermPtr->colorBold, SessPtr->ignoreBeeps, otherfnum, TermPtr->boldFontSize, TermPtr->boldFontStyle, TermPtr->realbold, TermPtr->oldScrollback); if (theScreen->vs <0 ) { /* we have a problem opening up the virtual screen */ OutOfMemory(1011); DisposeHandle((Handle)(**Params).terminal); DisposeHandle((Handle)(**Params).session); DisposeHandle((Handle)Params); TelInfo->numwindows--; DoTheMenuChecks(); updateCursor(1); return(FALSE); } theScreen->wind = RSgetwindow( theScreen->vs); ((WindowPeek)theScreen->wind)->windowKind = WIN_CNXN; /* * Attach our extra part to display encryption status */ PatchWindowWDEF(theScreen->wind, &screens[cur]); theScreen->arrowmap = TermPtr->emacsarrows; /* MAT -- save our arrow setting */ theScreen->maxscroll= TermPtr->numbkscroll; theScreen->bsdel = SessPtr->bksp; theScreen->crmap = SessPtr->crmap; if (theScreen->portNum != 23) // RAB BetterTelnet 1.0b1, 1.0fc4 theScreen->crmap = SessPtr->alwaysBSD; // RAB BetterTelnet 1.0b1, 1.0fc4 theScreen->tekclear = SessPtr->tekclear; theScreen->ESscroll= TermPtr->clearsave; theScreen->ANSIgraphics = TermPtr->ANSIgraphics; //ANSI graphics, 2.7 theScreen->tektype = SessPtr->tektype; theScreen->wrap = TermPtr->vtwrap; theScreen->pgupdwn = TermPtr->MATmappings; /* JMB: map pgup/pgdwn/home/end? */ theScreen->qprint = 0; theScreen->ignoreff = SessPtr->ignoreff; theScreen->TELstop = SessPtr->skey; theScreen->TELgo = SessPtr->qkey; theScreen->TELip = SessPtr->ckey; BlockMove((Ptr)SessPtr->hostname, theScreen->machine, Length(SessPtr->hostname)+1); BlockMove(TermPtr->AnswerBackMessage, theScreen->answerback, 32); theScreen->termstate = VTEKTYPE; theScreen->naws = 0; /* NCSA - set default NAWS to zero */ theScreen->telstate=0; theScreen->timing=0; theScreen->curgraph=-1; /* No graphics screen */ theScreen->clientflags = 0; /* BYU */ theScreen->kblen = 0; /* nothing in the buffer */ theScreen->enabled = 1; /* Gotta be enabled to start with */ theScreen->Ittype = 0; theScreen->Isga = 0; /* I suppress go ahead = no */ theScreen->Usga = 0; /* U suppress go ahead = no */ theScreen->remote_flow = 0; /* they handle toggling remote_flow */ theScreen->allow_flow = 1; /* initially, we allow flow control */ theScreen->restart_any_flow = 0; /* initially, only an XON turns flow control back on */ theScreen->termstate=VTEKTYPE; /* BYU */ theScreen->echo = 1; theScreen->halfdup = SessPtr->halfdup; /* BYU */ theScreen->national = 0; // Default to no translation. // Now see if the desired translation is available, if not use default translation. for(scratchshort = 1; scratchshort <= nNational+1; scratchshort++) { GetItem(myMenus[National], scratchshort, scratchPstring); if (EqualString(SessPtr->TranslationTable, scratchPstring, TRUE, FALSE)) theScreen->national = scratchshort-1; } // Set up paste related variables theScreen->incount = 0; theScreen->outcount = 0; theScreen->outptr = NULL; theScreen->outhand = NULL; theScreen->outlen = 0; theScreen->pastemethod = SessPtr->pastemethod; theScreen->pastesize = SessPtr->pasteblocksize; scratchBoolean = RSsetcolor( theScreen->vs, 0, TermPtr->nfcolor); scratchBoolean = RSsetcolor( theScreen->vs, 1, TermPtr->nbcolor); scratchBoolean = RSsetcolor( theScreen->vs, 2, TermPtr->bfcolor); scratchBoolean = RSsetcolor( theScreen->vs, 3, TermPtr->bbcolor); addinmenu(cur, (**Params).WindowName, diamondMark); theScreen->active = CNXN_DNRWAIT; // Signal we are waiting for DNR. theScreen->myInitParams = (Handle)Params; HUnlock((Handle)(**Params).terminal); HUnlock((Handle)(**Params).session); // Params handle must stay locked because interrupt level DNR completion routine needs to deref it VSscrolcontrol( theScreen->vs, -1, theScreen->ESscroll); updateCursor(1); /* Done stalling the user */ return(TRUE); } void CompleteConnectionOpening(short dat, ip_addr the_IP, OSErr DNRerror, char *cname) { ConnInitParams **Params; if (screens[dat].active != CNXN_DNRWAIT) return; // Something is wrong. Params = (ConnInitParams **)screens[dat].myInitParams; if (DNRerror == noErr) { HLockHi((Handle)(**Params).session); if ((**(**Params).session).NetBlockSize < 512) (**(**Params).session).NetBlockSize = 512; //less than this can really get messy if (setReadBlockSize((**(**Params).session).NetBlockSize,dat) != 0) //couldnt get read buffer return; screens[dat].port = netxopen(the_IP,(**(**Params).session).port,/* BYU 2.4.15 - open to host name */ gApplicationPrefs->OpenTimeout);/* CCP 2.7 allow user set-able timeouts on open */ // We need the cannonical hostname for Kerberos. Make best guess if // DNR did not return a cname. if (cname) strncpy(screens[dat].cannon, cname, sizeof(screens[dat].cannon)); else strncpy(screens[dat].cannon, (char *)(**(**Params).session).hostname, sizeof(screens[dat].cannon)); screens[dat].cannon[sizeof(screens[dat].cannon)-1] = '\0'; DisposeHandle((Handle)(**Params).session); DisposeHandle((Handle)(**Params).terminal); DisposeHandle((Handle)Params); if (screens[dat].port <0) { /* Handle netxopen fail */ destroyport(dat); } screens[dat].active = CNXN_OPENING; SetMenuMarkToOpeningForAGivenScreen(dat); /* Change status mark */ } else { // We should report the real DNR error here! Str255 errorString, numberString, numberString2, scratchPstring; DialogPtr theDialog; short message, ditem = 3; HLockHi((Handle)(**Params).session); BlockMove((**(**Params).session).hostname, scratchPstring, Length((**(**Params).session).hostname)+1); if (DNRerror >= -23048 && DNRerror <= -23041) message = DNRerror + 23050; else message = 1; GetIndString(errorString,DNR_MESSAGES_ID, message); NumToString((long)0, numberString); NumToString((long)DNRerror, numberString2); ParamText(scratchPstring, errorString, numberString, numberString2); theDialog = GetNewMyDialog(DNRErrorDLOG, NULL, kInFront, (void *)ThirdCenterDialog); ShowWindow(theDialog); while (ditem > 1) ModalDialog(DLOGwOKUPP, &ditem); DisposeDialog(theDialog); DisposeHandle((Handle)(**Params).session); DisposeHandle((Handle)(**Params).terminal); DisposeHandle((Handle)Params); destroyport(dat); } } void ConnectionOpenEvent(short port) { short i; i=WindByPort(port); if (i<0) { return; } screens[ i].active= CNXN_ACTIVE; RSshow( screens[i].vs); /* BYU */ SelectWindow(screens[i].wind); /* BYU */ telnet_send_initial_options(&screens[i]); changeport(scrn,i); /* BYU */ SetMenuMarkToLiveForAGivenScreen(scrn); /* BYU */ DoTheMenuChecks(); /* BYU */ } void ConnectionDataEvent(short port) { short i, cnt; i=WindByPort(port); /* BYU */ if (i<0) {return; } /* BYU */ if (TelInfo->ScrlLock || !screens[i].enabled) /* BYU LSC */ netputuev( CONCLASS, CONDATA, port,0); else { cnt = netread(port,gReadspace,gBlocksize); /* BYU LSC */ parse( &screens[i], gReadspace, cnt); /* BYU LSC */ screens[i].incount += cnt; /* BYU LSC */ } } void ConnectionFailedEvent(short port) { short i; Str255 scratchPstring; netclose( port); i= WindByPort(port); if (i<0) { return; } BlockMove((Ptr)screens[i].machine, (Ptr)scratchPstring, Length(screens[i].machine)+1); PtoCstr(scratchPstring); DoError(807 | NET_ERRORCLASS, LEVEL2, (char *)scratchPstring); if (screens[i].active != CNXN_ACTIVE) destroyport(i); // JMB - 2.6 else removeport(&screens[i]); // JMB - 2.6 } void ConnectionClosedEvent(short port) { short i; i= WindByPort(port); if (i<0) { netclose( port); /* We close again.... */ return; } FlushNetwork(i); /* BYU */ netclose( screens[i].port); /* BYU */ removeport(&screens[i]); /* BYU */ } static short WindByPort(short port) { short i=0; while (inumwindows && (screens[i].port != port || ((screens[i].active != CNXN_ACTIVE) && (screens[i].active != CNXN_OPENING))) ) i++; if (i>=TelInfo->numwindows) { /* BYU */ putln("Can't find a window for the port # in WindByPort"); /* BYU */ if (i==0) i=999; /* BYU */ return(-i); /* BYU */ } /* BYU */ return(i); } void destroyport(short wind) { Handle h; short i, callNoWindow=0; Size junk; WindRecPtr tw; tw = &screens[wind]; SetCursor(theCursors[watchcurs]); /* We may be here a while */ if (tw->active == CNXN_ISCORPSE) { if (tw->curgraph>-1) detachGraphics( tw->curgraph); /* Detach the Tek screen */ if (tw->outlen>0) { tw->outlen=0; /* Kill the remaining send*/ HUnlock( tw->outhand); /* buffer */ HPurge ( tw->outhand); } } if (FrontWindow() == tw->wind) callNoWindow=1; if (tw->aedata != NULL) DisposePtr((Ptr)tw->aedata); /* * Get handle to the WDEF patch block, kill the window, and then * release the handle. */ h = GetPatchStuffHandle(tw->wind, tw); RSkillwindow( tw->vs); SetDefaultKCHR(); if (h) DisposeHandle(h); tw->active = CNXN_NOTINUSE; for (i=wind;inumwindows-1;i++) { screens[i]=screens[i+1]; /* Bump all of the pointers */ RePatchWindowWDEF(screens[i].wind, &screens[i]); /* hack hack hack */ } if (scrn>wind) scrn--; /* Adjust for deleting a lower #ered screen */ TelInfo->numwindows--; /* There are now fewer windows */ extractmenu( wind); /* remove from the menu bar */ DoTheMenuChecks(); MaxMem(&junk); /* BYU 2.4.11 - the call to "NoWindow()" changes "myfrontwindow", which is used by "updateCursor()", so we reversed the order of the following two lines. */ if (callNoWindow) NoWindow(); /* BYU 2.4.11 - Update cursor stuff if front window */ updateCursor(1); /* BYU 2.4.11 - Done stalling the user */ } /* destroyport */ void removeport(WindRecPtr tw) { Str255 scratchPstring; SetCursor(theCursors[watchcurs]); /* We may be here a while */ if (tw->curgraph>-1) detachGraphics( tw->curgraph); /* Detach the Tek screen */ if (tw->outlen>0) { tw->outlen=0; /* Kill the remaining send*/ HUnlock( tw->outhand); /* buffer */ HPurge ( tw->outhand); } if (VSiscapturing(tw->vs)) /* NCSA: close up the capture */ CloseCaptureFile(tw->vs); /* NCSA */ if (VSisprinting(tw->vs)) ClosePrintingFile(tw->vs); if ((gApplicationPrefs->destroyKTickets)&&(numberLiveConnections() == 1))//if this is last window DestroyTickets(); if (!gApplicationPrefs->WindowsDontGoAway) destroyport(findbyVS(tw->vs)); else { Str255 temp; GetWTitle(tw->wind, scratchPstring); sprintf((char *)temp, "(%#s)", scratchPstring); CtoPstr((char *)temp); SetWTitle(tw->wind, temp); tw->port = 32700; tw->active = CNXN_ISCORPSE; } updateCursor(1); /* Done stalling the user */ } /* removeport */ // We recognize the following input string: "xxxx yyyy" // If "xxxx" matches a session name, that session record is used. Otherwise, the default // session record is used with "xxxx" as the DNS hostname. "yyyy", if extant, is // converted to a number. If it is a valid number, it is used as the port to connect to. // WARNING: Do not pass this routing a blank string. (We check this in PresentOpenConnectionDialog.) // // CCP 2.7: If second argument is true, get terminal out of session pref; otherwise set it to NULL ConnInitParams **NameToConnInitParams(StringPtr InputString, Boolean useDefaultTerminal, StringPtr otherPstring) { ConnInitParams **theHdl; SessionPrefs **sessHdl; TerminalPrefs **termHdl; short portRequested, portHack, portNegative; Boolean foundPort, wasAlias = FALSE; long junk; theHdl = (ConnInitParams **)myNewHandleCritical(sizeof(ConnInitParams)); if (theHdl == NULL) return NULL; if (useDefaultTerminal) { foundPort = 0; portNegative = 0; } else foundPort = ProcessHostnameString(InputString, &portRequested, &portNegative); UseResFile(TelInfo->SettingsFile); if (useDefaultTerminal) { sessHdl = (SessionPrefs **)Get1NamedResource(SESSIONPREFS_RESTYPE, InputString); if (sessHdl == NULL) { // Connect to host xxxx w/default session. portHack = 1; sessHdl = GetDefaultSession(); DetachResource((Handle) sessHdl); HLock((Handle)sessHdl); BlockMove(InputString, (**sessHdl).hostname, 64); } else { portHack = 0; DetachResource((Handle) sessHdl); HLock((Handle)sessHdl); wasAlias = TRUE; } } else { sessHdl = NULL; if (gApplicationPrefs->parseAliases) sessHdl = (SessionPrefs **)Get1NamedResource(SESSIONPREFS_RESTYPE, InputString); if (sessHdl == NULL) { portHack = 1; sessHdl = (SessionPrefs **)Get1NamedResource(SESSIONPREFS_RESTYPE, otherPstring); DetachResource((Handle) sessHdl); HLock((Handle)sessHdl); BlockMove(InputString, (**sessHdl).hostname, 64); } else { portHack = 0; DetachResource((Handle) sessHdl); HLock((Handle)sessHdl); } } (**theHdl).session = sessHdl; UseResFile(TelInfo->SettingsFile); // if ((useDefaultTerminal)||(wasAlias)) // if (1) // { termHdl = (TerminalPrefs **)Get1NamedResource (TERMINALPREFS_RESTYPE, (**sessHdl).TerminalEmulation); if (termHdl == NULL) termHdl = GetDefaultTerminal(); DetachResource((Handle) termHdl); (**theHdl).terminal = termHdl; // } // else // (**theHdl).terminal = NULL; UnloadSeg(&PREFSUnload); MaxMem(&junk); //swap out space so we can make the new window CCP HUnlock((Handle)sessHdl); ((**theHdl).WindowName)[0] = 0; (**sessHdl).ip_address = 0; if (foundPort) { (**sessHdl).port = portRequested; (**sessHdl).portNegative = portNegative; } else if (portHack) (**sessHdl).port = 23; return(theHdl); } ConnInitParams **ReturnDefaultConnInitParams(void) { ConnInitParams **theHdl; theHdl = (ConnInitParams **)myNewHandle(sizeof(ConnInitParams)); (**theHdl).session = GetDefaultSession(); (**(**theHdl).session).ip_address = 0; (**theHdl).terminal = GetDefaultTerminal(); return(theHdl); } short numberLiveConnections(void) { short i; short liveConnections = 0; for(i = 0; i < MaxSess; i++) if ((screens[i].active == CNXN_ACTIVE)||(screens[i].active == CNXN_OPENING)) liveConnections++; return liveConnections; } \ No newline at end of file +// Connections.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "telneterrors.h" #include "DlogUtils.proto.h" #include "movableModal.h" #include "wind.h" #include "event.proto.h" #include "rsinterf.proto.h" #include "vsdata.h" #include "vskeys.h" #include "vsinterf.proto.h" #include "vgtek.proto.h" #include "tekrgmac.proto.h" #include "vr.h" #include "vrrgmac.proto.h" #include "network.proto.h" #include "mydnr.proto.h" #include "InternalEvents.h" #include "menuseg.proto.h" #include "maclook.proto.h" #include "parse.proto.h" #include "parse.h" #include "configure.proto.h" #include "netevent.proto.h" #include "linemode.proto.h" #include "mainseg.proto.h" #include "prefs.proto.h" #include "popup.h" #include "popup.proto.h" #include "Connections.proto.h" #include "tnae.h" #include "authencrypt.h" #include "authencrypt.proto.h" #include "wdefpatch.proto.h" #include "LinkedList.proto.h" #include "ae.proto.h" #include "sshglue.proto.h" #include "macros.proto.h" /* These are all of the variables we need... */ extern Cursor *theCursors[NUMCURS]; /* all the cursors in a nice bundle */ extern WindRec *screens; extern short scrn; extern short nNational; // Number of user-installed translation tables extern MenuHandle myMenus[]; extern Boolean authOK; extern Boolean encryptOK; extern unsigned char *gReadspace; extern short gBlocksize; static short WindByPort(short port); static void setSessStates(DialogPtr dptr); static pascal short POCdlogfilter( DialogPtr dptr, EventRecord *evt, short *item); PROTO_UPP(POCdlogfilter, ModalFilter); short getDefaultPort(short protocol) { short port; short protocolArray[] = {23, 513, 514, 512, 22, 23}; if ((protocol < 0) || (protocol > 5)) return 23; // default if something goes weird return protocolArray[protocol]; } void OpenPortSpecial(MenuHandle menuh, short item) { ConnInitParams **theParams; Boolean success; Str255 scratchPstring; GetMenuItemText(menuh, item, scratchPstring); theParams = NameToConnInitParams(scratchPstring, TRUE, 0); if (theParams == NULL) { OutOfMemory(1020); return; } success = CreateConnectionFromParams(theParams); } SIMPLE_UPP(POCdlogfilter, ModalFilter); pascal short POCdlogfilter( DialogPtr dptr, EventRecord *evt, short *item) { short key; if (evt->what == keyDown) { key = evt->message & charCodeMask; if ( ((key == 'A') || (key == 'a')) && (evt->modifiers & cmdKey) ) { *item = NCauthenticate; return(-1); } if ( ((key == 'E') || (key == 'e')) && (evt->modifiers & cmdKey) ) { *item = NCencrypt; return(-1); } } if ((evt->what == keyDown) || (evt->what == autoKey)) { key = evt->message & charCodeMask; if (key == 0x1F) { *item = 1000; return(-1); } if (key == 0x1E) { *item = 1001; return(-1); } } // if (evt->what == mouseDown) // return(PopupMousedown(dptr, evt, item)); // RAB BetterTelnet 1.2 - we let StdFilterProc handle this now // return(DLOGwOK_Cancel(dptr, evt, item)); return CallStdFilterProc(dptr, evt, item); } void PresentOpenConnectionDialog(void) { ConnInitParams **InitParams; DialogPtr dptr; short ditem, scratchshort, mystrpos; Boolean success; long scratchlong; Str255 scratchPstring, terminalPopupString, scritchPstring; Handle ItemHandle; SessionPrefs **defaultSessHdl,**tempSessHdl; short numberOfTerms, sessMark, requestPort; MenuHandle SessPopupHdl, TermPopupHdl; Rect scratchRect; Point SessPopupLoc; short TerminalIndex, itemNumber = 1; popup TPopup[] = {{NCtermpopup, (MenuHandle) 0, 1}, {0, (MenuHandle) 0, 0}}; Size junk; LinkedListNode *theHead; SetCursor(theCursors[normcurs]); SetUpMovableModalMenus(); dptr = GetNewMyDialog(NewCnxnDLOG, NULL, kInFront, (void *)ThirdCenterDialog); if (dptr == NULL) { OutOfMemory(1000); return; } SetDialogDefaultItem(dptr, 1); SetDialogCancelItem(dptr, 2); SetDialogTracksCursor(dptr, 1); ditem = 3; sessMark = 1; GetIndString(scratchPstring,MISC_STRINGS,SESSION_STRING); SessPopupHdl = NewMenu(668, scratchPstring); if (SessPopupHdl == NULL) { DisposeDialog(dptr); OutOfMemory(1000); return; } UseResFile(TelInfo->SettingsFile); numberOfTerms = Count1Resources(SESSIONPREFS_RESTYPE); theHead = createSortedList(SESSIONPREFS_RESTYPE,numberOfTerms,"\p"); EnableItem(SessPopupHdl, 0); // Make sure the entire menu is enabled addListToMenu(SessPopupHdl, theHead, 1); deleteList(&theHead); SetItemMark(SessPopupHdl, 1, 18); GetDialogItem(dptr, NCsesspopup, &scratchshort, &ItemHandle, &scratchRect); SessPopupLoc.h = scratchRect.left; SessPopupLoc.v = scratchRect.top; // TermPopupHdl = NewMenu(666, "\p"); // if (TermPopupHdl == NULL) { // DisposeHandle((Handle)SessPopupHdl); // DisposeDialog(dptr); // OutOfMemory(1000); // return; // } SetPort(dptr); LocalToGlobal(&SessPopupLoc); // numberOfTerms = Count1Resources(TERMINALPREFS_RESTYPE); // theHead = createSortedList(TERMINALPREFS_RESTYPE,numberOfTerms,"\p"); // addListToMenu(TermPopupHdl, theHead); // deleteList(&theHead); // TPopup[0].h = TermPopupHdl; // PopupInit(dptr, TPopup); // Get default auth/encrypt settings from default session defaultSessHdl = GetDefaultSession(); HLock((Handle)defaultSessHdl); BlockMove("\p", scratchPstring, 15); GetHostNameFromSession(scratchPstring); if ((**defaultSessHdl).port != getDefaultPort((**defaultSessHdl).protocol)) { NumToString((unsigned short)(**defaultSessHdl).port, scritchPstring); pstrcat(scratchPstring, "\p:"); if ((**defaultSessHdl).portNegative) pstrcat(scratchPstring, "\p-"); pstrcat(scratchPstring, scritchPstring); } SetTEText(dptr, NChostname, scratchPstring); SelectDialogItemText(dptr, NChostname, 0, 32767); SetCntrl(dptr, NCauthenticate, (**defaultSessHdl).authenticate && authOK); SetCntrl(dptr, NCencrypt, (**defaultSessHdl).encrypt && encryptOK); if (!authOK) { Hilite( dptr, NCauthenticate, 255); Hilite( dptr, NCencrypt, 255); } // TerminalIndex = findPopupMenuItem(TermPopupHdl,(**defaultSessHdl).TerminalEmulation); // TPopup[0].choice = TerminalIndex; // PopupInit(dptr, TPopup); DisposeHandle((Handle)defaultSessHdl); setSessStates(dptr); while (ditem > NCcancel) { movableModalDialog(POCdlogfilterUPP, &ditem); switch(ditem) { case NCauthenticate: case NCencrypt: GetDialogItem(dptr, ditem, &scratchshort, &ItemHandle, &scratchRect); if ((**(ControlHandle)ItemHandle).contrlHilite == 0) { // if control not disabled FlipCheckBox(dptr, ditem); setSessStates(dptr); } break; case NCsesspopup: GetDialogItem(dptr, NCsesspopup, &scratchshort, &ItemHandle, &scratchRect); SessPopupLoc.h = scratchRect.left; SessPopupLoc.v = scratchRect.top; SetPort(dptr); LocalToGlobal(&SessPopupLoc); InsertMenu(SessPopupHdl, hierMenu); CalcMenuSize(SessPopupHdl); scratchlong = PopUpMenuSelect(SessPopupHdl, SessPopupLoc.v, SessPopupLoc.h, 0); DeleteMenu(668); if (scratchlong) { scratchshort = scratchlong & 0xFFFF; // Apple sez ignore the high word SetItemMark(SessPopupHdl, sessMark, 0); sessMark = scratchshort; SetItemMark(SessPopupHdl, sessMark, 18); GetMenuItemText(SessPopupHdl, scratchshort, scratchPstring); tempSessHdl = (SessionPrefs **)Get1NamedSizedResource(SESSIONPREFS_RESTYPE, scratchPstring, sizeof(SessionPrefs)); if (tempSessHdl) { // TerminalIndex = findPopupMenuItem(TermPopupHdl, // (**tempSessHdl).TerminalEmulation); // TPopup[0].choice = TerminalIndex; // DrawPopUp(dptr, NCtermpopup); //update popup strcpy((char *)scratchPstring, (char *)(**tempSessHdl).hostname); if ((**tempSessHdl).port != getDefaultPort((**tempSessHdl).protocol)) { NumToString((unsigned short)(**tempSessHdl).port, scritchPstring); pstrcat(scratchPstring, "\p:"); if ((**tempSessHdl).portNegative) pstrcat(scratchPstring, "\p-"); pstrcat(scratchPstring, scritchPstring); } SetTEText(dptr, NChostname, scratchPstring);//update the hostname SelectDialogItemText(dptr, NChostname, 0, 32767); SetCntrl(dptr, NCauthenticate, (**tempSessHdl).authenticate && authOK);//update the auth status SetCntrl(dptr, NCencrypt, (**tempSessHdl).encrypt && encryptOK); setSessStates(dptr);//encrypt cant be on w/o authenticate ReleaseResource((Handle)tempSessHdl); } } break; case 1001: SetItemMark(SessPopupHdl, sessMark, 0); sessMark--; if (sessMark < 1) sessMark = CountMItems(SessPopupHdl); SetItemMark(SessPopupHdl, sessMark, 18); GetMenuItemText(SessPopupHdl, sessMark, scratchPstring); tempSessHdl = (SessionPrefs **)Get1NamedSizedResource(SESSIONPREFS_RESTYPE, scratchPstring, sizeof(SessionPrefs)); if (tempSessHdl) { strcpy((char *)scratchPstring, (char *)(**tempSessHdl).hostname); if ((**tempSessHdl).port != getDefaultPort((**tempSessHdl).protocol)) { NumToString((unsigned short)(**tempSessHdl).port, scritchPstring); pstrcat(scratchPstring, "\p:"); if ((**tempSessHdl).portNegative) pstrcat(scratchPstring, "\p-"); pstrcat(scratchPstring, scritchPstring); } SetTEText(dptr, NChostname, scratchPstring);//update the hostname SelectDialogItemText(dptr, NChostname, 0, 32767); SetCntrl(dptr, NCauthenticate, (**tempSessHdl).authenticate && authOK);//update the auth status SetCntrl(dptr, NCencrypt, (**tempSessHdl).encrypt && encryptOK); setSessStates(dptr);//encrypt cant be on w/o authenticate ReleaseResource((Handle)tempSessHdl); } break; case 1000: SetItemMark(SessPopupHdl, sessMark, 0); sessMark++; if (sessMark > CountMItems(SessPopupHdl)) sessMark = 1; SetItemMark(SessPopupHdl, sessMark, 18); GetMenuItemText(SessPopupHdl, sessMark, scratchPstring); tempSessHdl = (SessionPrefs **)Get1NamedSizedResource(SESSIONPREFS_RESTYPE, scratchPstring, sizeof(SessionPrefs)); if (tempSessHdl) { strcpy((char *)scratchPstring, (char *)(**tempSessHdl).hostname); if ((**tempSessHdl).port != getDefaultPort((**tempSessHdl).protocol)) { NumToString((unsigned short)(**tempSessHdl).port, scritchPstring); pstrcat(scratchPstring, "\p:"); if ((**tempSessHdl).portNegative) pstrcat(scratchPstring, "\p-"); pstrcat(scratchPstring, scritchPstring); } SetTEText(dptr, NChostname, scratchPstring);//update the hostname SelectDialogItemText(dptr, NChostname, 0, 32767); SetCntrl(dptr, NCauthenticate, (**tempSessHdl).authenticate && authOK);//update the auth status SetCntrl(dptr, NCencrypt, (**tempSessHdl).encrypt && encryptOK); setSessStates(dptr);//encrypt cant be on w/o authenticate ReleaseResource((Handle)tempSessHdl); } break; default: break; } // switch } // while if (ditem == NCcancel) { // PopupCleanup(); DisposeMenu(SessPopupHdl); // drh Bug fix: memory leak DisposeDialog(dptr); ResetMenus(); return; } GetTEText(dptr, NChostname, scratchPstring); if (!StrLength(scratchPstring)) { // PopupCleanup(); DisposeMenu(SessPopupHdl); // drh Bug fix: memory leak DisposeDialog(dptr); ResetMenus(); return; } // GetMenuItemText(TPopup[0].h, TPopup[0].choice, terminalPopupString); // PopupCleanup(); for (mystrpos = 0; mystrpos < StrLength(scratchPstring); mystrpos++) if (scratchPstring[mystrpos + 1] == ':') scratchPstring[mystrpos + 1] = ' '; MaxMem(&junk); GetMenuItemText(SessPopupHdl, sessMark, scritchPstring); InitParams = NameToConnInitParams(scratchPstring, FALSE, scritchPstring); if (InitParams == NULL) { DisposeMenu(SessPopupHdl); // drh Bug fix: memory leak DisposeDialog(dptr); OutOfMemory(1000); return; } // if ((**InitParams).terminal == NULL) //if this is not null, then the string was an alias, // { // so dont use the popup terminal // (**InitParams).terminal = (TerminalPrefs **) // Get1NamedResource(TERMINALPREFS_RESTYPE,terminalPopupString); // DetachResource((Handle)(**InitParams).terminal); // if (InitParams == NULL) { // OutOfMemory(1000); // DisposeDialog(dptr); // return; // } // } // RAB BetterTelnet 2.0b1 - lock the handles down FIRST! HLock((Handle)InitParams); HLock((Handle)(**InitParams).session); if (GetCntlVal(dptr, NCauthenticate)) (**(**InitParams).session).authenticate = 1; else (**(**InitParams).session).authenticate = 0; if (GetCntlVal(dptr, NCencrypt)) (**(**InitParams).session).encrypt = 1; else (**(**InitParams).session).encrypt = 0; GetTEText(dptr, NCwindowname, scratchPstring); // Copy over the user specified window name. If blank, CreateConnectionFromParams // will copy the hostname to the windowname and append a number. if (StrLength(scratchPstring)) BlockMove(scratchPstring, (**InitParams).WindowName, (StrLength(scratchPstring) > 63) ? 64 : (StrLength(scratchPstring) + 1)); HUnlock((Handle)(**InitParams).session); HUnlock((Handle)InitParams); DisposeMenu(SessPopupHdl); // drh Bug fix: memory leak DisposeDialog(dptr); ResetMenus(); success = CreateConnectionFromParams(InitParams); } // Set states of session checkboxes static void setSessStates (DialogPtr dptr) { if (GetCntlVal(dptr, NCauthenticate)) { Hilite(dptr, NCencrypt, (encryptOK)? 0 : 255); } else { Hilite(dptr, NCencrypt, 255); SetCntrl(dptr, NCencrypt, false); } } void OpenConnectionFromURL(char *host, char *portstring, char *user, char *password) { ConnInitParams **Params; Str255 windowName, tempString; short len; long port; Params = ReturnDefaultConnInitParams(); windowName[0] = 0; // Set up window name if user (and password) given if (user != nil) { GetIndString(windowName, MISC_STRINGS, MISC_USERPRMPT); len = strlen(user); BlockMoveData(user,& windowName[StrLength(windowName)+1], len); windowName[0] += len; if (password != nil) { GetIndString(tempString, MISC_STRINGS, MISC_PSWDPRMPT); BlockMoveData(&tempString[1], &windowName[StrLength(windowName)+1], tempString[0]); windowName[0] += tempString[0]; len = strlen(password); BlockMoveData(password, &windowName[StrLength(windowName)+1], len); windowName[0] += len; } if (windowName[0] != 0) { BlockMoveData(windowName, (**Params).WindowName, StrLength(windowName)+1); } } CtoPstr(host); BlockMoveData(host, (**(**Params).session).hostname, host[0]+1); if (portstring != nil) { CtoPstr(portstring); StringToNum((StringPtr)portstring, &port); (**(**Params).session).port = port; } (void)CreateConnectionFromParams(Params); } // RAB BetterTelnet 2.0fc1 - updated for SOCKS Boolean CreateConnectionFromParams( ConnInitParams **Params) { short scratchshort, fontnumber, otherfnum; static short numWind = 1, stagNum = 1; SessionPrefs *SessPtr; TerminalPrefs *TermPtr; short cur; Str32 numPstring; Str255 scratchPstring; Boolean scratchBoolean; WindRec *theScreen; unsigned char *hostname; SetCursor(theCursors[watchcurs]); /* We may be here a bit */ // Check if we have the max number of sessions open if (TelInfo->numwindows == MaxSess) return(FALSE); cur = TelInfo->numwindows; /* Adjust # of windows and get this window's number */ TelInfo->numwindows++; theScreen = &screens[cur]; theScreen->active = CNXN_NOTINUSE; // Make sure it is marked as dead (in case we // abort screen creation after initiating DNR) // That way CompleteConnectionOpening will know // we didn't make it. HLockHi((Handle)Params); HLockHi((Handle)(**Params).terminal); HLockHi((Handle)(**Params).session); SessPtr = *((**Params).session); TermPtr = *((**Params).terminal); if (StrLength((**Params).WindowName) == 0) { BlockMove((**(**Params).session).hostname, (**Params).WindowName, StrLength((**(**Params).session).hostname)+1); if (SessPtr->port != getDefaultPort(SessPtr->protocol)) { NumToString((unsigned short)SessPtr->port, numPstring); pstrcat((**Params).WindowName, "\p:"); pstrcat((**Params).WindowName, numPstring); } NumToString(numWind++, numPstring); pstrcat((**Params).WindowName, "\p ("); pstrcat((**Params).WindowName, numPstring); // tack the number onto the end. pstrcat((**Params).WindowName, "\p)"); } if (SessPtr->hostname[0] == 0) { OperationFailedAlert(5, 0, 0); DisposeHandle((Handle)(**Params).terminal); DisposeHandle((Handle)(**Params).session); DisposeHandle((Handle)Params); TelInfo->numwindows--; updateCursor(1); return(FALSE); } if (SessPtr->protocol == 4) // make sure we have SSH if (!ssh_glue_installed()) { OperationFailedAlert(6, 0, 0); DisposeHandle((Handle)(**Params).terminal); DisposeHandle((Handle)(**Params).session); DisposeHandle((Handle)Params); TelInfo->numwindows--; updateCursor(1); return(FALSE); } Mnetinit(); // RAB BetterTelnet 1.0fc4 // RAB BetterTelnet 2.0fc1 - we look up the SOCKS firewall first // heck, we might even be using SOCKS 4a, in which case that's ALL we directly look up if (SessPtr->usesocks) { hostname = (unsigned char *)SessPtr->sockshost; theScreen->sockslookup = 1; // tell the DNR completion we need to make another look up, // and that this one should not be reversed (see below) // but the next one can be } else { hostname = SessPtr->hostname; theScreen->sockslookup = 0; // ok to reverse lookup after // the idea here is that we need the reverse DNS // (canonical machine name) for Kerberos, so we might // as well (if using Kerberos, otherwise we don't reverse) // get it for the remote host and not the firewall } // Get the IP for the host while we set up the connection if (DoTheDNR(hostname, cur) != noErr) { OutOfMemory(1010); DisposeHandle((Handle)(**Params).terminal); DisposeHandle((Handle)(**Params).session); DisposeHandle((Handle)Params); TelInfo->numwindows--; updateCursor(1); return(FALSE); } DoTheMenuChecks(); theScreen->sessmacros = (**Params).sessmacros; theScreen->authenticate = SessPtr->authenticate && authOK; theScreen->encrypt = SessPtr->encrypt && encryptOK; theScreen->aedata = NULL; for (scratchshort = 0; scratchshort < sizeof(theScreen->myopts); scratchshort++) { theScreen->myopts[scratchshort] = 0; theScreen->hisopts[scratchshort] = 0; } theScreen->cannon[0] = '\0'; theScreen->usesocks = theScreen->socksinprogress = SessPtr->usesocks; theScreen->sockspos = 0; // for receiving socks reply theScreen->socks4a = SessPtr->socks4a; theScreen->socksport = SessPtr->socksport; pstrcpy((unsigned char *)theScreen->socksusername, (unsigned char *)SessPtr->socksusername); pstrcpy((unsigned char *)theScreen->sockshost, (unsigned char *)SessPtr->sockshost); theScreen->vtemulation = TermPtr->vtemulation; theScreen->forcesave = SessPtr->forcesave; theScreen->eightbit = TermPtr->eightbit; theScreen->portNum = SessPtr->port; theScreen->portNegative = SessPtr->portNegative; theScreen->allowBold = TermPtr->allowBold; theScreen->colorBold = TermPtr->colorBold; theScreen->realbold = TermPtr->realbold; theScreen->inversebold = TermPtr->boldFontStyle; theScreen->ignoreBeeps = SessPtr->ignoreBeeps; theScreen->otpauto = SessPtr->otpauto; theScreen->otpnoprompt = SessPtr->otpnoprompt; theScreen->otphex = SessPtr->otphex; theScreen->otpmulti = SessPtr->otpmulti; theScreen->otpsavepass = SessPtr->otpsavepass; theScreen->oldScrollback = TermPtr->oldScrollback; theScreen->protocol = SessPtr->protocol; pstrcpy((unsigned char *)theScreen->otppassword, (unsigned char *)SessPtr->otppassword); pstrcpy((unsigned char *)theScreen->username, (unsigned char *)SessPtr->username); pstrcpy((unsigned char *)theScreen->password, (unsigned char *)SessPtr->password); pstrcpy((unsigned char *)theScreen->clientuser, (unsigned char *)SessPtr->clientuser); pstrcpy((unsigned char *)theScreen->command, (unsigned char *)SessPtr->command); theScreen->otpautostate = 0; theScreen->otpautobuffer[7] = 0; theScreen->emacsmeta = TermPtr->emacsmetakey; theScreen->Xterm = TermPtr->Xtermsequences; theScreen->remapCtrlD = TermPtr->remapCtrlD; theScreen->keypadmap = TermPtr->remapKeypad; theScreen->port = -1; // netxopen will take care of this theScreen->cachedFontNum = 0; theScreen->cachedBoldFontNum = 0; theScreen->cxWeHaveAppleEvent = 0; theScreen->waWeHaveAppleEvent = 0; theScreen->waWaiting = 0; theScreen->encryption = SessPtr->encryption; theScreen->jumpScroll = TermPtr->jumpScroll; theScreen->jsNoFlush = 0; theScreen->realBlink = TermPtr->realBlink; theScreen->lmode = 0; // RAB BetterTelnet 2.0b1 - fix for a really bizarre bug theScreen->lineAllow = SessPtr->linemode; if (SessPtr->linemode) //we allow linemode initLinemode(&screens[cur]); GetFNum(TermPtr->DisplayFont, &fontnumber); GetFNum(TermPtr->BoldFont, &otherfnum); theScreen->vs = RSnewwindow(&((**Params).WindowLocation),TermPtr->numbkscroll, TermPtr->vtwidth, TermPtr->vtheight, (**Params).WindowName, TermPtr->vtwrap, fontnumber, TermPtr->fontsize, 0, 1, SessPtr->forcesave,cur, TermPtr->allowBold, TermPtr->colorBold, SessPtr->ignoreBeeps, otherfnum, TermPtr->boldFontSize, TermPtr->boldFontStyle, TermPtr->realbold, TermPtr->oldScrollback, TermPtr->jumpScroll, TermPtr->realBlink); if (theScreen->vs <0 ) { /* we have a problem opening up the virtual screen */ OutOfMemory(1011); DisposeHandle((Handle)(**Params).terminal); DisposeHandle((Handle)(**Params).session); DisposeHandle((Handle)Params); TelInfo->numwindows--; DoTheMenuChecks(); updateCursor(1); return(FALSE); } theScreen->wind = RSgetwindow( theScreen->vs); ((WindowPeek)theScreen->wind)->windowKind = WIN_CNXN; /* * Attach our extra part to display encryption status */ PatchWindowWDEF(theScreen->wind, &screens[cur]); theScreen->arrowmap = TermPtr->emacsarrows; /* MAT -- save our arrow setting */ theScreen->maxscroll= TermPtr->numbkscroll; theScreen->bsdel = SessPtr->bksp; theScreen->crmap = SessPtr->crmap; if (theScreen->portNum != getDefaultPort(theScreen->protocol)) // RAB BetterTelnet 1.0b1, 1.0fc4 theScreen->crmap = SessPtr->alwaysBSD; // RAB BetterTelnet 1.0b1, 1.0fc4 theScreen->tekclear = SessPtr->tekclear; theScreen->ESscroll= TermPtr->clearsave; theScreen->ANSIgraphics = TermPtr->ANSIgraphics; //ANSI graphics, 2.7 theScreen->tektype = SessPtr->tektype; theScreen->wrap = TermPtr->vtwrap; theScreen->pgupdwn = TermPtr->MATmappings; /* JMB: map pgup/pgdwn/home/end? */ theScreen->qprint = 0; theScreen->ignoreff = SessPtr->ignoreff; theScreen->TELstop = SessPtr->skey; theScreen->TELgo = SessPtr->qkey; theScreen->TELip = SessPtr->ckey; BlockMove((Ptr)SessPtr->hostname, theScreen->machine, StrLength(SessPtr->hostname)+1); BlockMove(TermPtr->AnswerBackMessage, theScreen->answerback, 32); theScreen->termstate = VTEKTYPE; theScreen->naws = 0; /* NCSA - set default NAWS to zero */ theScreen->telstate=0; theScreen->timing=0; theScreen->curgraph=-1; /* No graphics screen */ theScreen->clientflags = 0; /* BYU */ theScreen->kblen = 0; /* nothing in the buffer */ theScreen->enabled = 1; /* Gotta be enabled to start with */ theScreen->Ittype = 0; theScreen->Isga = 0; /* I suppress go ahead = no */ theScreen->Usga = 0; /* U suppress go ahead = no */ theScreen->remote_flow = 0; /* they handle toggling remote_flow */ theScreen->allow_flow = 1; /* initially, we allow flow control */ theScreen->restart_any_flow = 0; /* initially, only an XON turns flow control back on */ theScreen->termstate=VTEKTYPE; /* BYU */ theScreen->echo = 1; theScreen->halfdup = SessPtr->halfdup; /* BYU */ theScreen->national = 0; // Default to no translation. // Now see if the desired translation is available, if not use default translation. for(scratchshort = 1; scratchshort <= nNational+1; scratchshort++) { GetMenuItemText(myMenus[National], scratchshort, scratchPstring); if (EqualString(SessPtr->TranslationTable, scratchPstring, TRUE, FALSE)) theScreen->national = scratchshort-1; } // Set up paste related variables theScreen->incount = 0; theScreen->outcount = 0; theScreen->outptr = NULL; theScreen->outhand = NULL; theScreen->outlen = 0; theScreen->pastemethod = SessPtr->pastemethod; theScreen->pastesize = SessPtr->pasteblocksize; scratchBoolean = RSsetcolor( theScreen->vs, 0, TermPtr->nfcolor); scratchBoolean = RSsetcolor( theScreen->vs, 1, TermPtr->nbcolor); scratchBoolean = RSsetcolor( theScreen->vs, 2, TermPtr->bfcolor); scratchBoolean = RSsetcolor( theScreen->vs, 3, TermPtr->bbcolor); addinmenu(cur, (**Params).WindowName, diamondMark); theScreen->active = CNXN_DNRWAIT; // Signal we are waiting for DNR. theScreen->myInitParams = (Handle)Params; HUnlock((Handle)(**Params).terminal); HUnlock((Handle)(**Params).session); // Params handle must stay locked because interrupt level DNR completion routine needs to deref it VSscrolcontrol( theScreen->vs, -1, theScreen->ESscroll); updateCursor(1); /* Done stalling the user */ return(TRUE); } void CompleteConnectionOpening(short dat, ip_addr the_IP, OSErr DNRerror, char *cname) { ConnInitParams **Params; short socks4a, len, pos; if (screens[dat].active != CNXN_DNRWAIT) return; // Something is wrong. Params = (ConnInitParams **)screens[dat].myInitParams; if (DNRerror == noErr) { if (screens[dat].sockslookup) { // RAB BetterTelnet 2.0fc1 screens[dat].socksIP = the_IP; socks4a = 0; if (screens[dat].socks4a) { len = screens[dat].machine[0]; pos = 1; while (len) { // we still "look up" dotted quad numbers since // that doesn't involve DNS if (((screens[dat].machine[pos] < '0') || (screens[dat].machine[pos] > '9')) && (screens[dat].machine[pos] != '.')) socks4a = 1; // not a number or period, thus it's a DNS name len--; pos++; } } screens[dat].socks4a = socks4a; if (!socks4a) { // we need to do another lookup screens[dat].sockslookup = 0; if (DoTheDNR(screens[dat].machine, dat) != noErr) { OutOfMemory(1010); DisposeHandle((Handle)(**Params).terminal); DisposeHandle((Handle)(**Params).session); DisposeHandle((Handle)Params); TelInfo->numwindows--; updateCursor(1); return; } return; // wait for it to finish } } else if (screens[dat].usesocks) { // ok, it finished screens[dat].actualIP = the_IP; the_IP = screens[dat].socksIP; // we connect to the socks server (first lookup) // not the remote host (second lookup) } if (screens[dat].usesocks) // fix the port (**(**Params).session).port = screens[dat].socksport; // we set (**(**Params).session).port but not screens[dat].portNum because // the session is disposed after the connection is open while // the screen remains and could be used to save a set HLockHi((Handle)(**Params).session); if ((**(**Params).session).NetBlockSize < 512) (**(**Params).session).NetBlockSize = 512; //less than this can really get messy if (setReadBlockSize((**(**Params).session).NetBlockSize,dat) != 0) //couldnt get read buffer return; if ((screens[dat].protocol == 1) || (screens[dat].protocol == 2)) netfromport(768); screens[dat].port = netxopen(the_IP,(**(**Params).session).port,/* BYU 2.4.15 - open to host name */ gApplicationPrefs->OpenTimeout);/* CCP 2.7 allow user set-able timeouts on open */ // We need the cannonical hostname for Kerberos. Make best guess if // DNR did not return a cname. if (cname) strncpy(screens[dat].cannon, cname, sizeof(screens[dat].cannon)); else strncpy(screens[dat].cannon, (char *)(**(**Params).session).hostname, sizeof(screens[dat].cannon)); screens[dat].cannon[sizeof(screens[dat].cannon)-1] = '\0'; DisposeHandle((Handle)(**Params).session); DisposeHandle((Handle)(**Params).terminal); DisposeHandle((Handle)Params); if (screens[dat].port <0) { /* Handle netxopen fail */ destroyport(dat); } screens[dat].active = CNXN_OPENING; SetMenuMarkToOpeningForAGivenScreen(dat); /* Change status mark */ } else { // We should report the real DNR error here! Str255 errorString, numberString, numberString2, scratchPstring; DialogPtr theDialog; short message, ditem = 3; HLockHi((Handle)(**Params).session); BlockMove((**(**Params).session).hostname, scratchPstring, StrLength((**(**Params).session).hostname)+1); if (DNRerror >= -23048 && DNRerror <= -23041) message = DNRerror + 23050; else message = 1; GetIndString(errorString,DNR_MESSAGES_ID, message); NumToString((long)0, numberString); NumToString((long)DNRerror, numberString2); ParamText(scratchPstring, errorString, numberString, numberString2); theDialog = GetNewMyDialog(DNRErrorDLOG, NULL, kInFront, (void *)ThirdCenterDialog); ShowWindow(theDialog); while (ditem > 1) ModalDialog(DLOGwOKUPP, &ditem); DisposeDialog(theDialog); // RAB BetterTelnet 2.0b2 - we need to report the DNS error to AppleScript if (screens[dat].cxWeHaveAppleEvent) { AEResumeTheCurrentEvent(&screens[dat].cxAppleEvent, &screens[dat].cxAEReply, MyHandleConnectUPP, 2); screens[dat].cxWeHaveAppleEvent = 0; } DisposeHandle((Handle)(**Params).session); DisposeHandle((Handle)(**Params).terminal); DisposeHandle((Handle)Params); destroyport(dat); } } void ConnectionOpenEvent(short port) { short i, pos, pos2; static char buf[512]; i=WindByPort(port); if (i<0) { return; } if (screens[i].cxWeHaveAppleEvent) { AEResumeTheCurrentEvent(&screens[i].cxAppleEvent, &screens[i].cxAEReply, MyHandleConnectUPP, 1); screens[i].cxWeHaveAppleEvent = 0; } screens[ i].active= CNXN_ACTIVE; RSshow( screens[i].vs); /* BYU */ SelectWindow(screens[i].wind); /* BYU */ if (screens[i].socksinprogress) { // RAB BetterTelnet 2.0fc1 buf[0] = 4; buf[1] = 1; buf[2] = (screens[i].portNum >> 8) & 0xFF; buf[3] = screens[i].portNum & 0xFF; if (screens[i].socks4a) memcpy(&buf[4], "\000\000\000\001", 4); else memcpy(&buf[4], &screens[i].actualIP, 4); pos = screens[i].socksusername[0]; memcpy(&buf[8], &screens[i].socksusername[1], pos); pos += 8; buf[pos] = 0; pos++; if (screens[i].socks4a) { pos2 = screens[i].machine[0]; memcpy(&buf[pos], &screens[i].machine[1], pos2); pos += pos2; buf[pos] = 0; pos++; } Rnetwrite(screens[i].port, buf, pos); } else telnet_send_initial_options(&screens[i]); changeport(scrn,i); /* BYU */ SetMenuMarkToLiveForAGivenScreen(scrn); /* BYU */ DoTheMenuChecks(); /* BYU */ } void ConnectionDataEvent(short port) { short i, cnt, urgent, res; char p[255]; unsigned char *st; WindRec *tw; i=WindByPort(port); /* BYU */ if (i<0) {return; } /* BYU */ if (TelInfo->ScrlLock || !screens[i].enabled) /* BYU LSC */ netputuev( CONCLASS, CONDATA, port,0); else { cnt = netread(port,gReadspace,gBlocksize); /* BYU LSC */ // urgent data isn't working right now, so this is turned off /* if ((screens[i].protocol >= 1) && (screens[i].protocol <= 3)) { urgent = getUrgentFlag(port); if (urgent) { rlogin_parse( &screens[i], gReadspace, cnt); screens[i].incount += cnt; return; } } */ // RAB BetterTelnet 2.0fc1 - stuff for processing SOCKS 4 replies st = gReadspace; tw = &screens[i]; while (tw->socksinprogress && cnt) { if (tw->sockspos == 1) { res = *st; sprintf(p, "socks4: result code %d", res); putln(p); } if (tw->sockspos == 7) { tw->socksinprogress = 0; telnet_send_initial_options(tw); } tw->sockspos++; cnt--; st++; } if (screens[i].protocol != 4) // ssh handles differently parse( &screens[i], st, cnt); /* BYU LSC */ else { screens[i].jsNoFlush = 1; // RAB BetterTelnet 2.0b4 // improve relations between jump scroller and ssh ssh_glue_read(&screens[i], st, cnt); screens[i].jsNoFlush = 0; VSflushwrite(screens[i].vs); } screens[i].incount += cnt; /* BYU LSC */ } } void ConnectionFailedEvent(short port) { short i, err; Str255 scratchPstring; if (checkPortRotation(port)) return; netclose( port); i= WindByPort(port); if (i<0) { return; } if (screens[i].cxWeHaveAppleEvent) { AEResumeTheCurrentEvent(&screens[i].cxAppleEvent, &screens[i].cxAEReply, MyHandleConnectUPP, 2); screens[i].cxWeHaveAppleEvent = 0; } BlockMove((Ptr)screens[i].machine, (Ptr)scratchPstring, StrLength(screens[i].machine)+1); PtoCstr(scratchPstring); DoError(807 | NET_ERRORCLASS, LEVEL2, (char *)scratchPstring); if (screens[i].active != CNXN_ACTIVE) destroyport(i); // JMB - 2.6 else removeport(&screens[i]); // JMB - 2.6 } void ConnectionClosedEvent(short port) { short i; i= WindByPort(port); if (i<0) { netclose( port); /* We close again.... */ return; } FlushNetwork(i); /* BYU */ netclose( screens[i].port); /* BYU */ removeport(&screens[i]); /* BYU */ } static short WindByPort(short port) { short i=0; while (inumwindows && (screens[i].port != port || ((screens[i].active != CNXN_ACTIVE) && (screens[i].active != CNXN_OPENING))) ) i++; if (i>=TelInfo->numwindows) { /* BYU */ putln("Can't find a window for the port # in WindByPort"); /* BYU */ if (i==0) i=999; /* BYU */ return(-i); /* BYU */ } /* BYU */ return(i); } void destroyport(short wind) { Handle h; short i, callNoWindow=0; Size junk; WindRecPtr tw; tw = &screens[wind]; SetCursor(theCursors[watchcurs]); /* We may be here a while */ if (tw->active == CNXN_ISCORPSE) { if (tw->curgraph>-1) detachGraphics( tw->curgraph); /* Detach the Tek screen */ if (tw->outlen>0) { tw->outlen=0; /* Kill the remaining send*/ HUnlock( tw->outhand); /* buffer */ HPurge ( tw->outhand); } } if (FrontWindow() == tw->wind) callNoWindow=1; if (tw->aedata != NULL) { auth_encrypt_end((tnParams **)&tw->aedata); DisposePtr((Ptr)tw->aedata); } /* * Get handle to the WDEF patch block, kill the window, and then * release the handle. */ h = GetPatchStuffHandle(tw->wind, tw); RSkillwindow( tw->vs); SetDefaultKCHR(); if (h) DisposeHandle(h); tw->active = CNXN_NOTINUSE; for (i=wind;inumwindows-1;i++) { screens[i]=screens[i+1]; /* Bump all of the pointers */ RePatchWindowWDEF(screens[i].wind, &screens[i]); /* hack hack hack */ } if (scrn>wind) scrn--; /* Adjust for deleting a lower #ered screen */ TelInfo->numwindows--; /* There are now fewer windows */ extractmenu( wind); /* remove from the menu bar */ DoTheMenuChecks(); MaxMem(&junk); /* BYU 2.4.11 - the call to "NoWindow()" changes "myfrontwindow", which is used by "updateCursor()", so we reversed the order of the following two lines. */ if (callNoWindow) NoWindow(); /* BYU 2.4.11 - Update cursor stuff if front window */ updateCursor(1); /* BYU 2.4.11 - Done stalling the user */ } /* destroyport */ void removeport(WindRecPtr tw) { Str255 scratchPstring; SetCursor(theCursors[watchcurs]); /* We may be here a while */ disposemacros(&tw->sessmacros); if (tw->curgraph>-1) detachGraphics( tw->curgraph); /* Detach the Tek screen */ if (tw->protocol == 4) { ssh_glue_close(tw); } if (tw->outlen>0) { tw->outlen=0; /* Kill the remaining send*/ HUnlock( tw->outhand); /* buffer */ HPurge ( tw->outhand); } if (VSiscapturing(tw->vs)) /* NCSA: close up the capture */ CloseCaptureFile(tw->vs); /* NCSA */ if (VSisprinting(tw->vs)) ClosePrintingFile(tw->vs); if ((gApplicationPrefs->destroyKTickets)&&(numberLiveConnections() == 1))//if this is last window DestroyTickets(); if (!gApplicationPrefs->WindowsDontGoAway) destroyport(findbyVS(tw->vs)); else { Str255 temp; GetWTitle(tw->wind, scratchPstring); sprintf((char *)temp, "(%#s)", scratchPstring); CtoPstr((char *)temp); SetWTitle(tw->wind, temp); tw->port = 32700; tw->active = CNXN_ISCORPSE; } updateCursor(1); /* Done stalling the user */ } /* removeport */ // We recognize the following input string: "xxxx yyyy" // If "xxxx" matches a session name, that session record is used. Otherwise, the default // session record is used with "xxxx" as the DNS hostname. "yyyy", if extant, is // converted to a number. If it is a valid number, it is used as the port to connect to. // WARNING: Do not pass this routing a blank string. (We check this in PresentOpenConnectionDialog.) // // CCP 2.7: If second argument is true, get terminal out of session pref; otherwise set it to NULL ConnInitParams **NameToConnInitParams(StringPtr InputString, Boolean useDefaultTerminal, StringPtr otherPstring) { ConnInitParams **theHdl; SessionPrefs **sessHdl; TerminalPrefs **termHdl; Handle sessmacros; short portRequested, portHack, portNegative; Boolean foundPort, wasAlias = FALSE; long junk; theHdl = (ConnInitParams **)myNewHandleCritical(sizeof(ConnInitParams)); if (theHdl == NULL) return NULL; if (useDefaultTerminal) { foundPort = 0; portNegative = 0; } else foundPort = ProcessHostnameString(InputString, &portRequested, &portNegative); UseResFile(TelInfo->SettingsFile); if (useDefaultTerminal) { sessHdl = (SessionPrefs **)Get1NamedSizedResource(SESSIONPREFS_RESTYPE, InputString, sizeof(SessionPrefs)); if (sessHdl == NULL) { // Connect to host xxxx w/default session. portHack = 1; sessHdl = GetDefaultSession(); DetachResource((Handle) sessHdl); HLock((Handle)sessHdl); BlockMove(InputString, (**sessHdl).hostname, 64); sessmacros = Get1NamedResource('uMac', "\p"); } else { portHack = 0; DetachResource((Handle) sessHdl); HLock((Handle)sessHdl); wasAlias = TRUE; sessmacros = Get1NamedResource('uMac', InputString); } } else { sessHdl = NULL; if (gApplicationPrefs->parseAliases) sessHdl = (SessionPrefs **)Get1NamedSizedResource(SESSIONPREFS_RESTYPE, InputString, sizeof(SessionPrefs)); if (sessHdl == NULL) { portHack = 1; sessHdl = (SessionPrefs **)Get1NamedSizedResource(SESSIONPREFS_RESTYPE, otherPstring, sizeof(SessionPrefs)); DetachResource((Handle) sessHdl); HLock((Handle)sessHdl); BlockMove(InputString, (**sessHdl).hostname, 64); sessmacros = Get1NamedResource('uMac', otherPstring); } else { portHack = 0; DetachResource((Handle) sessHdl); HLock((Handle)sessHdl); sessmacros = Get1NamedResource('uMac', InputString); } } (**theHdl).session = sessHdl; UseResFile(TelInfo->SettingsFile); // if ((useDefaultTerminal)||(wasAlias)) // if (1) // { termHdl = (TerminalPrefs **)Get1NamedSizedResource (TERMINALPREFS_RESTYPE, (**sessHdl).TerminalEmulation, sizeof(TerminalPrefs)); if (termHdl == NULL) termHdl = GetDefaultTerminal(); DetachResource((Handle) termHdl); (**theHdl).terminal = termHdl; // } // else // (**theHdl).terminal = NULL; UnloadSeg(&PREFSUnload); MaxMem(&junk); //swap out space so we can make the new window CCP HUnlock((Handle)sessHdl); ((**theHdl).WindowName)[0] = 0; (**sessHdl).ip_address = 0; (**theHdl).sessmacros.handle = 0; if (sessmacros) { DetachResource(sessmacros); HLock(sessmacros); ParseMacrosFromHandle(&(**theHdl).sessmacros, sessmacros); } if (foundPort) { (**sessHdl).port = portRequested; (**sessHdl).portNegative = portNegative; } else if (portHack) (**sessHdl).port = getDefaultPort((**sessHdl).protocol); return(theHdl); } ConnInitParams **ReturnDefaultConnInitParams(void) { ConnInitParams **theHdl; Handle sessmacros; theHdl = (ConnInitParams **)myNewHandle(sizeof(ConnInitParams)); (**theHdl).session = GetDefaultSession(); (**(**theHdl).session).ip_address = 0; (**theHdl).terminal = GetDefaultTerminal(); UseResFile(TelInfo->SettingsFile); sessmacros = Get1NamedResource('uMac', "\p"); (**theHdl).sessmacros.handle = 0; if (sessmacros) { DetachResource(sessmacros); HLock(sessmacros); ParseMacrosFromHandle(&(**theHdl).sessmacros, sessmacros); } return(theHdl); } short numberLiveConnections(void) { short i; short liveConnections = 0; for(i = 0; i < MaxSess; i++) if ((screens[i].active == CNXN_ACTIVE)||(screens[i].active == CNXN_OPENING)) liveConnections++; return liveConnections; } \ No newline at end of file diff --git a/source/main/Connections.proto.h b/source/main/Connections.proto.h index c965d42..b0c0cf7 100755 --- a/source/main/Connections.proto.h +++ b/source/main/Connections.proto.h @@ -1 +1 @@ - /* Connections.c */ void OpenPortSpecial(MenuHandle menuh, short item); void PresentOpenConnectionDialog(void); void OpenConnectionFromURL(char *host, char *portstring, char *user, char *password); Boolean CreateConnectionFromParams(ConnInitParams **Params); void CompleteConnectionOpening(short dat, ip_addr the_IP, OSErr DNRerror, char *cname); void ConnectionOpenEvent(short port); void ConnectionDataEvent(short port); void ConnectionFailedEvent(short port); void ConnectionClosedEvent(short port); void destroyport(short wind); void removeport(WindRecPtr tw); ConnInitParams **NameToConnInitParams(StringPtr, Boolean, StringPtr); // ConnInitParams **NameToConnInitParam2(StringPtr InputString, Boolean useDefaultTerminal); // ConnInitParams **NameToConnInitParam3(StringPtr InputString, Boolean useDefaultTerminal, StringPtr otherPstring); ConnInitParams **ReturnDefaultConnInitParams(void); short numberLiveConnections(void); \ No newline at end of file + /* Connections.c */ void OpenPortSpecial(MenuHandle menuh, short item); void PresentOpenConnectionDialog(void); void OpenConnectionFromURL(char *host, char *portstring, char *user, char *password); Boolean CreateConnectionFromParams(ConnInitParams **Params); void CompleteConnectionOpening(short dat, ip_addr the_IP, OSErr DNRerror, char *cname); void ConnectionOpenEvent(short port); void ConnectionDataEvent(short port); void ConnectionFailedEvent(short port); void ConnectionClosedEvent(short port); void destroyport(short wind); void removeport(WindRecPtr tw); ConnInitParams **NameToConnInitParams(StringPtr, Boolean, StringPtr); // ConnInitParams **NameToConnInitParam2(StringPtr InputString, Boolean useDefaultTerminal); // ConnInitParams **NameToConnInitParam3(StringPtr InputString, Boolean useDefaultTerminal, StringPtr otherPstring); ConnInitParams **ReturnDefaultConnInitParams(void); short numberLiveConnections(void); short getDefaultPort(short); \ No newline at end of file diff --git a/source/main/event.c b/source/main/event.c index 73bd279..6405e0c 100755 --- a/source/main/event.c +++ b/source/main/event.c @@ -1 +1 @@ -// event.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* * Main Event loop code for NCSA Telnet for the Macintosh * * Called by: * maclook.c * * Revisions: * 7/92 Telnet2.6: added 2 support for 2 global structs, put cursors into * an array, cleaned up defines Scott Bulmahn * */ #ifdef MPW #pragma segment 4 #endif /* * Files for inclusion. */ #include "VSkeys.h" #include "wind.h" #include "event.h" //kxplate moved to its own file (CCP 2.7) #include "errors.proto.h" #include "network.proto.h" #include "mydnr.proto.h" #include "bkgr.proto.h" #include "maclook.proto.h" #include "InternalEvents.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "menuseg.proto.h" #include "vrrgmac.proto.h" #include "tekrgmac.proto.h" #include "rsinterf.proto.h" #include "rsmac.proto.h" #include "event.proto.h" #include "macros.proto.h" /* For setmacro proto */ #include "netevent.proto.h" #include "translate.proto.h" #include "parse.proto.h" #include "linemode.proto.h" #include "Connections.proto.h" #include "mainseg.proto.h" #include "movableModal.h" #include // for EMACS meta hack #include //For Notify User Icon Stuff extern short scrn; extern MenuHandle myMenus[NMENUS]; extern Boolean gKeyboardHasControlKey; extern SysEnvRec theWorld; /* BYU 2.4.12 - System Environment record */ extern WindRec *screens, *ftplog; extern Cursor *theCursors[]; extern Boolean gHaveDragMgr; static gHaveInstalledNotification = 0; NMRec *nRecPtr; #include "event.proto.h" short updateCursor(short force) { static Point lastPoint; static short optwasdown; short optDown; Point myPoint; KeyMap allthekeys; /* Someplace to put the keymap */ if (TelInfo->myfrontwindow) { /* BYU 2.4.11 */ SetPort((GrafPtr) TelInfo->myfrontwindow); /* BYU 2.4.11 */ } else { /* BYU 2.4.11 */ SetCursor(theCursors[normcurs]); /* BYU 2.4.11 */ return(0); /* BYU 2.4.11 */ } GetMouse(&myPoint); GetKeys(allthekeys); optDown = ((unsigned char *)allthekeys)[7] &4; if ( (!force) && EqualPt(myPoint,lastPoint) && (optDown ==optwasdown)) return(0); if (force) TelInfo->lastCursor=0L; if (TelInfo->ginon) { if (TelInfo->lastCursor!= theCursors[gincurs]) { SetCursor(theCursors[gincurs]); TelInfo->lastCursor = theCursors[gincurs]; } return(1); } if (TelInfo->xferon && !optDown) { if (TelInfo->lastCursor!= theCursors[xfercurs]) { SetCursor( theCursors[xfercurs]); TelInfo->lastCursor = theCursors[xfercurs]; } return(1); } switch (TelInfo->myfronttype) { case DEC_WINDOW: if (RSmouseintext( TelInfo->myfrontvs, myPoint)) { if ((PointInSelection(normalize(myPoint, TelInfo->myfrontvs, FALSE), TelInfo->myfrontvs))&&(gHaveDragMgr)) //for Drag ability { if (TelInfo->lastCursor != theCursors[normcurs]) { TelInfo->lastCursor = theCursors[normcurs]; SetCursor(theCursors[normcurs]); } } else { if (optDown) /* Option key is down */ { if (TelInfo->lastCursor != theCursors[poscurs]) { TelInfo->lastCursor = theCursors[poscurs]; SetCursor(theCursors[poscurs]); } } else { if (TelInfo->lastCursor != theCursors[textcurs]) { TelInfo->lastCursor = theCursors[textcurs]; SetCursor(theCursors[textcurs]); } } } } else { if (TelInfo->lastCursor != theCursors[normcurs]) { TelInfo->lastCursor = theCursors[normcurs]; SetCursor(theCursors[normcurs]); } } break; case TEK_WINDOW: LocalToGlobal(&myPoint); if (PtInRgn(myPoint, TelInfo->myfrontwindow->contRgn)) { /* BYU LSC */ if (TelInfo->lastCursor != theCursors[graphcurs]) { TelInfo->lastCursor = theCursors[graphcurs]; SetCursor(theCursors[graphcurs]); } } else { if (TelInfo->lastCursor != theCursors[normcurs]) { TelInfo->lastCursor = theCursors[normcurs]; SetCursor(theCursors[normcurs]); } } break; case NO_WINDOW: default: if (force) { SetCursor( theCursors[normcurs]); TelInfo->lastCursor= theCursors[normcurs]; } } lastPoint=myPoint; optwasdown=optDown; return(0); } void NoWindow( void) { TelInfo->myfrontwindow=0L; TelInfo->myfronttype=NO_WINDOW; TelInfo->myfrontRgn=0L; updateCursor(1); } /* The following code was graciously donated by Marc Tamsky. When are YOU going to donate YOUR code, eh? We know you're reading this. -- JMB */ Boolean CheckPageKeys(short code) /* NCSA: SB */ { /* NCSA: SB */ GrafPtr currFW; // current front window holder // MAT-- short ourW; // virtual screen number holder // MAT--kinda short x1, y2, x2, y1; // coordinates from window // MAT--pulled from scrollproc /* NCSA: SB */ currFW = (GrafPtr)FrontWindow(); // MAT-- ourW = RSfindvwind(currFW); // MAT-- /* NCSA: SB */ switch (code) /* NCSA: SB */ { /* NCSA: SB */ case VSPGUP: /* NCSA: SB */ RScursblinkoff(ourW); VSgetrgn(ourW, &x1, &y1, &x2, &y2); // MAT-- VSscrolback(ourW, y2 - y1); /* scroll a whole windowful */ // MAT-- RScursblinkon(ourW); return TRUE; // MAT-- break; /* NCSA: SB */ /* NCSA: SB */ case VSPGDN: // MAT--121 is a PAGE DOWN. RScursblinkoff(ourW); // MAT--in rsmac.c VSgetrgn(ourW, &x1, &y1, &x2, &y2); // MAT-- VSscrolforward(ourW, y2 - y1); /* scroll a whole windowful */ // MAT-- RScursblinkon(ourW); return TRUE; // MAT-- break; /* NCSA: SB */ // MAT-- case VSHOME: /* NCSA: SB */ RScursblinkoff(ourW); VSscroltop(ourW); /* JMB 2.6 -- Created VSscroltop just for this purpose */ return TRUE; /* NCSA: SB */ break; // MAT-- // MAT-- case VSEND: /* NCSA: SB */ RScursblinkoff(ourW); VSgetrgn(ourW, &x1, &y1, &x2, &y2); // MAT-- VSscrolforward(ourW, 32765); /* scroll a whole BUNCH! */ // MAT-- kludge time again. anyone suggest RScursblinkon(ourW); return TRUE; /* NCSA: SB */ break; // MAT-- a better way to hack this part? } // MAT-- /* NCSA: SB */ return FALSE; /* NCSA: SB - we didnt handle event, let us know about it */ } /* NCSA: SB */ /* HandleKeyDown -- By now, we have already gotten a keypress signal from the event handler, so we just need to interpret it. Get the raw code and ascii value, and then decide what to do with it. */ void HandleKeyDown(EventRecord theEvent,struct WindRec *tw) { unsigned char ascii, code; unsigned char sendch; long menuEquiv; short enterkey = 0; Boolean commanddown, optiondown, controldown,shifted; ObscureCursor(); ascii = theEvent.message & charCodeMask; code = ((theEvent.message & keyCodeMask) >> 8); commanddown = ((theEvent.modifiers & cmdKey) != 0); optiondown = ((theEvent.modifiers & optionKey) != 0); controldown = ((theEvent.modifiers & controlKey) != 0); shifted = ((theEvent.modifiers & shiftKey) != 0); if (DebugKeys(commanddown, ascii, tw->vs)) return; if ((tw->emacsmeta == 2)&&(optiondown)) goto emacsHack; //ha ha hack hack if ((code == 0x34)&&(ascii == 3)) //fix for PowerBook 540 bad KCHR ascii = 13; //(map control-c to return) else if ((controldown)&&(shifted)&&(ascii == '2')) ascii = 0;//fix bad KCHR control-@ else if ((controldown)&&(shifted)&&(ascii == '6')) ascii = 0x1e;//fix bad KCHR control-^ if (commanddown) { if (gApplicationPrefs->CommandKeys) { //if optioned, retranslate so we can do menu commands if (optiondown) { short virtualCode = 0; Ptr KCHRPtr; long newStuff; unsigned long state = 0; short modifiersCopy; modifiersCopy = theEvent.modifiers; virtualCode = (short)(code); theEvent.modifiers &= (shiftKey); //turn off option virtualCode |= theEvent.modifiers; KCHRPtr = (Ptr)GetScriptManagerVariable(smKCHRCache); newStuff = KeyTranslate(KCHRPtr,virtualCode,&state); newStuff &= 0xFF; //only look at bottom byte ascii = (unsigned char) newStuff; theEvent.modifiers = modifiersCopy; //reset option state } menuEquiv = MenuKey(ascii); //handle menu keys first if ((menuEquiv & 0xFFFF0000) != 0) { HandleMenuCommand(menuEquiv,theEvent.modifiers); return; } if ((TelInfo->numwindows < 1) || (tw->active != CNXN_ACTIVE)) return; // Check for EMACS meta key. if ((tw->emacsmeta)&&(controldown)) { unsigned char temp[2]; if (ascii <= 32) //control changed the ascii value ascii |= 0x40; //move back to a non-control if ((shifted)||(ascii == 0x5f)) //so we can get meta - { short virtualCode = 0; Ptr KCHRPtr; long newStuff; unsigned long state = 0; virtualCode = (short)(code); theEvent.modifiers &= (shiftKey); //turn of command virtualCode |= theEvent.modifiers; KCHRPtr = (Ptr)GetScriptManagerVariable(smKCHRCache); newStuff = KeyTranslate(KCHRPtr,virtualCode,&state); newStuff &= 0xFF; //only look at bottom byte ascii = (unsigned char) newStuff; } emacsHack: //if the option key KCHR is installled, we will get the right ascii value if ((tw->clientflags & PASTE_IN_PROGRESS)&&(tw->pastemethod)) //queue this { tw->kbbuf[tw->kblen++] = ESC; tw->kbbuf[tw->kblen++] = ascii; return; } if (tw->kblen > 0) { netwrite( tw->port,tw->kbbuf,tw->kblen); tw->kblen=0; } temp[0] = ESC; temp[1] = ascii; if (tw->echo && tw->halfdup) parse(tw,temp,2); netpush(tw->port); netwrite(tw->port,temp,2); return; } else if (ascii >='0' && ascii <='9' ) //now look for macros { sendmacro(tw, ascii-'0'); return; } else if (!((ascii == '`' && gApplicationPrefs->RemapTilde)||(code == BScode))) return; } else //no command key menus { if ((TelInfo->numwindows < 1) || (tw->active != CNXN_ACTIVE)) return; else if (!gKeyboardHasControlKey) //map command to control { ascii &= 0x1f; commanddown = FALSE; } else return; } } else if ((TelInfo->numwindows < 1) || (tw->active != CNXN_ACTIVE)) return; if (((ascii == '@') || (ascii == 32))&& controldown) //this, along with the fixed KCHR that mapps a Cntl-@ to ascii = NULL; //a @, takes care of Apple not posting NULL key values // map '`' to ESC if needed if (ascii == '`' && gApplicationPrefs->RemapTilde && !(commanddown)) ascii = ESC; // map Del to ^D if the user wants it if ((code == 0x75) && tw->remapCtrlD) { code = 0x34; ascii = 4; } if (code == BScode) //handle mapping BS to DEL, flipping on option { if (tw->bsdel) if ((optiondown)||(commanddown)) ascii = BS; else ascii = DEL; else if ((optiondown)||(commanddown)) ascii = DEL; else ascii = BS; } if (!tw->enabled) //if we are suspended, and we have negotiated restart_any { //with the host, then enable the screen on anything but an XOFF. We will //eat the XON later if that is what this is. (RFC 1372 --CCP 2.7) if ((tw->restart_any_flow)&&(ascii != tw->TELstop)) tw->enabled = 1; } /* Remap PgUp,PgDown,Home,End if the user wants it that way */ if ((tw->pgupdwn && (code >= KPlowest))||(!tw->vtemulation)) //do page up/down on vt100 if (CheckPageKeys(code)) return; if (code >= KPlowest) /* BYU - Handle Keypad */ { if (theWorld.keyBoardType == envStandADBKbd) //standard MacII keyboard has keypad +,- { // codes switched if (code == 0x45) code = 0x4e; else if (code == 0x4e) code = 0x45; } if ((tw->vtemulation)||(code >= 0x7B)||(code <= 0x60)) //fkeys dont work in vt100 { if ((!tw->keypadmap)||(code == 0x4c)||(code > 0x51)||(code < 0x43)) //dont remap operators { if ((tw->clientflags & PASTE_IN_PROGRESS)&&(tw->pastemethod)) //queue this { tw->kbbuf[tw->kblen++] = 0; tw->kbbuf[tw->kblen++] = kpxlate[shifted][code - KPlowest]; return; } if (tw->kblen > 0) { netwrite( tw->port,tw->kbbuf,tw->kblen); tw->kblen=0; } ascii = kpxlate[shifted][code - KPlowest]; // Should we check here for ascii being zero? VSkbsend(tw->vs, (unsigned char) ascii, tw->echo); return; } } else // we dont handle function keys in vt100 return; } // Handle whatever mapping is needed. mac_nat(&ascii, tw->national); /* LU/PM: Convert char from mac to nat */ if ((tw->clientflags & PASTE_IN_PROGRESS)&&(tw->pastemethod)) //queue this { tw->kbbuf[tw->kblen++] = ascii; return; } if (tw->lmode) // Some form of linemode is active; we dont touch it after them { process_key(ascii,tw); return; } // BSD-like mapping.... if we don't want this, set chars to zero and it wont work //CCP 2.7: this is now AFTER the linemode stuff, so that linemode can handle it differently if (ascii == tw->TELstop) { if (tw->allow_flow) //remote flow control can turn this off { tw->enabled = 0; return; } } if (ascii == tw->TELgo) { if (tw->allow_flow) //remote flow control can turn this off { tw->enabled = 1; return; } } if (ascii == tw->TELip) { char *tellUser = "\n\r[Interrupt Process]\n\r"; parse(tw,(unsigned char *)tellUser,23); netpush(tw->port); netwrite(tw->port, "\377\364",2); //IAC IP netpush(tw->port); netwrite(tw->port, "\377\375\006",3); // send Do TM tw->timing = 1; // set emulate to TMwait return; } if (tw->echo && !tw->halfdup) // Handle klude-linemode { if (ascii>31 && ascii <127 && code < KPlowest) { if (tw->kblen < (MAXKB -1)) /* Add to buffer if not full */ tw->kbbuf[tw->kblen++] = ascii; else { /* if full send buffer */ netwrite( tw->port, tw->kbbuf,tw->kblen); tw->kbbuf[0] = ascii; tw->kblen=1; } sendch=ascii; parse(tw, &sendch, 1); return; /* OK, were set...*/ } //end if printable key else { if ( code == BScode ) { if (tw->kblen>0) { tw->kblen--; parse(tw,(unsigned char *) "\010 \010",3); /* BYU LSC */ } return; } else if (ascii == KILLCHAR) { while (tw->kblen >0) { parse(tw,(unsigned char *) "\010 \010",3); /* BYU LSC */ tw->kblen--; } return; } else if (code port, tw->kbbuf,tw->kblen); /* if full send buffer */ tw->kblen=0; if (ascii !=CR) { sendch='@'+ascii; parse(tw,(unsigned char *) "^",1); /* BYU LSC */ parse(tw, &sendch, 1); } } }//end else non-printable key }//end if klude-linemode if (ascii == '\015') //CR { // If crmap is on, send CR-NULL instead of CR-LF. netpush(tw->port); if (tw->crmap) netwrite(tw->port,"\015\0",2); else netwrite(tw->port,"\015\012",2); //UNIVAC fix if (tw->echo) parse(tw,(unsigned char *) "\012\015",2); /* BYU LSC */ return; } if (tw->echo && tw->halfdup) parse(tw, &ascii, 1); if (ascii != 255) netwrite(tw->port,&ascii,1); else netwrite(tw->port, "\377\377", 2); } void HandleMouseDown(EventRecord myEvent) { GrafPtr whichWindow; short code, myRGMnum; short growErr, i; short theItem; DialogPtr dlogp; code = FindWindow(myEvent.where, &whichWindow); switch (code) { case inMenuBar: if (myEvent.modifiers & optionKey) { switchToOptionMenus(TRUE); HandleMenuCommand(MenuSelect(myEvent.where),myEvent.modifiers); switchToOptionMenus(FALSE); } else if (myEvent.modifiers & shiftKey) { switchToShiftMenus(TRUE); HandleMenuCommand(MenuSelect(myEvent.where),myEvent.modifiers); switchToShiftMenus(FALSE); } else HandleMenuCommand(MenuSelect(myEvent.where),myEvent.modifiers); break; case inSysWindow: SystemClick(&myEvent, whichWindow); break; case inGoAway: if (TrackGoAway( whichWindow, myEvent.where)) CloseAWindow((WindowPtr)whichWindow); break; case inDrag: if ((whichWindow != FrontWindow()) && (!(myEvent.modifiers & cmdKey)) && (!(myEvent.modifiers & optionKey))) { SelectWindow(whichWindow); } DragWindow(whichWindow, myEvent.where, &TelInfo->dragRect); break; case inZoomIn: case inZoomOut: if (TrackBox( whichWindow, myEvent.where, code)) RSzoom( whichWindow, code, myEvent.modifiers & shiftKey); break; /* NCSA: SB - Telnet now allows you to grow the TEK window, finally. */ /* NCSA: SB - So check to see if the click was in a TEK window */ case inGrow: growErr = RSsize( whichWindow, (long *) &myEvent.where, myEvent.modifiers); switch(growErr) { case (-4): /*bad mem problems, kill window, signal user */ OutOfMemory(-4); if ((i = WindowPtr2ScreenIndex(whichWindow)) >= 0) { netclose(screens[i].port); removeport(&screens[i]); } break; case (-2): /* no resize due to memory error, signal user */ OutOfMemory(-2); break; default: /* ok resize, or window not found */ break; } myRGMnum = RGfindbywind(whichWindow); /* NCSA: SB - is it a TEK window click? */ if (myRGMnum != -1) /* NCSA: SB - Anyone want to play some BOLO? */ { /* NCSA: SB */ RGMgrowme((short)myRGMnum, whichWindow,(long *) &myEvent.where,myEvent.modifiers); /* NCSA: TG */ } /* NCSA: SB */ break; case inContent: if (whichWindow != FrontWindow()) { SelectWindow(whichWindow); } else { if (((WindowPeek)whichWindow)->windowKind == dialogKind) { if (IsDialogEvent(&myEvent)) { if (DialogSelect(&myEvent, &dlogp, &theItem)) HandleModeless(&myEvent, dlogp, theItem); } break; } if (RSclick(whichWindow, myEvent) <0) { SetPort(whichWindow); GlobalToLocal(&myEvent.where); RGmousedown(whichWindow, &myEvent.where ); } } break; default: break; } } #pragma profile off void DoEvents( void) { Boolean gotOne; /* Did we get an event */ short vs; EventRecord myEvent; short scratchshort; DialogPtr dlogp; gotOne = WaitNextEvent(everyEvent, &myEvent, gApplicationPrefs->TimeSlice, 0L); if (!gotOne) { // RAB BetterTelnet 1.2 - null events to dialogs if (TelInfo->macrosModeless) { if (!CallStdFilterProc(TelInfo->macrosModeless, &myEvent, &scratchshort)) if (IsDialogEvent(&myEvent)) DialogSelect(&myEvent, &dlogp, &scratchshort); } } if (gotOne) { /* BYU 2.4.11 - Turn the cursor off when the human makes the slightest move. */ if (gApplicationPrefs->BlinkCursor) { if ( (vs=RSfindvwind(FrontWindow())) >= 0) if (vs == screens[scrn].vs) if (!(myEvent.modifiers & cmdKey) && ((myEvent.what == keyDown) || (myEvent.what == autoKey))) RScursblinkon(vs); else RScursblinkoff(vs); } HandleEvent(&myEvent); } else if (gApplicationPrefs->BlinkCursor && !TelInfo->suspended) { /* BYU 2.4.11 */ if ( (vs=RSfindvwind(FrontWindow())) >= 0) /* BYU 2.4.11 */ if (vs == screens[scrn].vs) /* BYU 2.4.11 */ RScursblink(vs); /* BYU 2.4.11 */ } /* BYU 2.4.11 */ if (FrontWindow() != TelInfo->macrosModeless) // RAB BetterTelnet 1.2 updateCursor(0); } static long currentScript, defaultKCHR, mungeCount; static Boolean haveChangedKCHR; //called at startup to figure out the default roman KCHR and the active script void scriptKbdInit(void) { currentScript = GetScriptManagerVariable(smKeyScript);//get active script defaultKCHR = GetScriptVariable(smRoman, smScriptKeys); //get the smRoman default KCHR mungeCount = GetScriptManagerVariable(smMunged); //Get the mungeCount haveChangedKCHR = FALSE; } void SetDefaultKCHR(void) { if (haveChangedKCHR) { SetScriptVariable(smRoman,smScriptKeys,defaultKCHR); haveChangedKCHR = FALSE; KeyScript(smRoman); } } void CheckDefaultScriptSettings(void) { long tempLong; tempLong = GetScriptManagerVariable(smMunged); if (tempLong > mungeCount) { currentScript = GetScriptManagerVariable(smKeyScript);//get the new active script if ((currentScript != smRoman)&&(haveChangedKCHR)) //roman has been switched out and we need to fix it { SetScriptVariable(smRoman,smScriptKeys,defaultKCHR); currentScript = GetScriptManagerVariable(smKeyScript);//get the new active script haveChangedKCHR = FALSE; //we dont mess with non-roman scripts } mungeCount = tempLong; //update the mungeCount } } void HandleEvent(EventRecord *myEvent) //CCP split this from DoEvents so we can call this from { //other places short i,vs; DialogPtr dlogp; short theItem, tempstatus; short commanddown; switch(myEvent->what) { case mouseDown: HandleMouseDown(*myEvent); break; case updateEvt: switch(((WindowPeek)myEvent->message)->windowKind) { case WIN_CONSOLE: case WIN_LOG: case WIN_CNXN: if (RSupdate((GrafPtr) myEvent->message)) putln("Ack, problem in update!"); break; case WIN_ICRG: if (MacRGupdate((WindowPtr) myEvent->message)) putln("Ack, problem in update!"); break; case WIN_TEK: if (RGupdate((GrafPtr) myEvent->message) ==0) TekDisable(RGgetVG((GrafPtr) myEvent->message)); else putln("Ack, problem in update!"); break; case dialogKind: CallStdFilterProc((GrafPtr) myEvent->message, myEvent, &theItem); if (IsDialogEvent(myEvent)) DialogSelect(myEvent, &dlogp, &theItem); break; default: putln("Bad windowkind!"); break; } break; case keyDown: case autoKey: commanddown = ((myEvent->modifiers & cmdKey) != 0); if (FrontWindow()) if (((WindowPeek)FrontWindow())->windowKind == dialogKind) { tempstatus = 1; if (CallStdFilterProc(FrontWindow(), myEvent, &theItem)) { HandleModeless(myEvent, FrontWindow(), theItem); break; } if (commanddown) { HandleKeyDown(*myEvent, &screens[scrn]); /* All key events are processed through here */ break; } if (IsDialogEvent(myEvent)) { if (DialogSelect(myEvent, &dlogp, &theItem)) HandleModeless(myEvent, dlogp, theItem); else tempstatus = 0; } if (tempstatus) break; } HandleKeyDown(*myEvent, &screens[scrn]); /* All key events are processed through here */ break; case diskEvt: /* check to see if disk needs to be initialized */ myEvent->where.h = 100; myEvent->where.v = 120; if (noErr != (( myEvent->message >> 16 ) & 0xffff )) { /* check hi word */ DILoad(); DIBadMount( myEvent->where, myEvent->message); /* BYU LSC */ DIUnload(); } break; case activateEvt: if ((myEvent->modifiers & activeFlag)==1) //its an activate event { if (((WindowPeek)myEvent->message)->windowKind == dialogKind) { CallStdFilterProc((GrafPtr) myEvent->message, myEvent, &theItem); if (IsDialogEvent(myEvent)) DialogSelect(myEvent, &dlogp, &theItem); if (TelInfo->macrosModeless) if ((GrafPtr)myEvent->message == TelInfo->macrosModeless) { EnableItem(myMenus[Edit],EDcut); EnableItem(myMenus[Edit],EDcopy); EnableItem(myMenus[Edit],EDpaste); EnableItem(myMenus[Edit],EDclear); } else { DisableItem(myMenus[Edit],EDcut); DisableItem(myMenus[Edit],EDcopy); DisableItem(myMenus[Edit],EDpaste); DisableItem(myMenus[Edit],EDclear); } break; } else { DisableItem(myMenus[Edit],EDcut); DisableItem(myMenus[Edit],EDclear); } i=WindowPtr2ScreenIndex((GrafPtr) myEvent->message); // We need to know who CheckDefaultScriptSettings(); //see if someone has changed the script //this next bit takes care of setting the KCHR based on the EMACS hack pref if ((currentScript == smRoman)&&(screens[i].emacsmeta == 2)) { if (!haveChangedKCHR) //if we haven't already done this { SetScriptVariable(currentScript,smScriptKeys,502); //set the KCHR for EMACS KeyScript(smRoman); //Make it active haveChangedKCHR = TRUE; } } else if (haveChangedKCHR) //new active window doesnt want EMACS hack { SetScriptVariable(currentScript,smScriptKeys,defaultKCHR); KeyScript(smRoman); haveChangedKCHR = FALSE; } AdjustMenus(); DrawMenuBar(); i=WindowPtr2ScreenIndex((GrafPtr) myEvent->message); /* We need to know who */ if (i>=0) { if ((screens[i].curgraph>-1) && (!(myEvent->modifiers & optionKey))) detachGraphics(screens[i].curgraph); changeport(scrn,i); scrn=i; } if ((i=RSfindvwind((GrafPtr) myEvent->message))>=0) { if (RSTextSelected(i)) { EnableItem(myMenus[Fil],FLprint); EnableItem(myMenus[Edit],EDcopy); EnableItem(myMenus[Edit],EDcopyt); } else { DisableItem(myMenus[Fil],FLprint); DisableItem(myMenus[Edit],EDcopy); DisableItem(myMenus[Edit],EDcopyt); } RSactivate(i); TelInfo->myfrontwindow=(WindowPeek) myEvent->message; TelInfo->myfronttype=DEC_WINDOW; TelInfo->myfrontvs = i; TelInfo->myfrontRgn =0L; updateCursor(1); } else { TelInfo->myfrontwindow=(WindowPeek) myEvent->message; TelInfo->myfronttype=TEK_WINDOW; TelInfo->myfrontRgn =0L; updateCursor(1); if ( (i = RGgetdnum((GrafPtr) myEvent->message)) >-1) { if (( i = RGgetVS( i)) >-1) { EnableItem(myMenus[Fil],FLprint); // enable printing EnableItem(myMenus[Edit],EDcopy); // - enable copying DisableItem(myMenus[Edit],EDcopyt); i = findbyVS( i); changeport(scrn,i); scrn=i; } } } } else //its a disable event { short i; DisableItem(myMenus[Edit],EDcut); DisableItem(myMenus[Edit],EDclear); DisableItem(myMenus[Edit],EDcopy); DisableItem(myMenus[Edit],EDpaste); AdjustMenus(); DoTheMenuChecks(); DrawMenuBar(); if ((i=RSfindvwind((GrafPtr) myEvent->message))>=0) RSdeactivate(i); NoWindow(); } break; case osEvt: switch(( myEvent->message >>24) &0xff) { case switchEvt: if (myEvent->message & 0x20) /*Convert clipboard here if necc. (it is not)*/; if (myEvent->message & 0x1) { /* Resume Event */ GrafPtr window; TelInfo->suspended = FALSE; /* We are no longer in suspension */ if (gHaveInstalledNotification) { NMRemove(nRecPtr); DisposeHandle(nRecPtr->nmIcon); gHaveInstalledNotification = FALSE; } DisableItem( myMenus[Edit],EDcut); DisableItem( myMenus[Edit],EDundo); DisableItem( myMenus[Edit],EDclear); window = FrontWindow(); /* Who's on first */ if ( (vs=RSfindvwind(window)) >= 0) { CheckDefaultScriptSettings();//update script settings if ((currentScript == smRoman)&&(haveChangedKCHR)) // set it back { SetScriptVariable(currentScript,smScriptKeys,502); //set the KCHR for EMACS KeyScript(smRoman); //Make it active } RSactivate(vs); TelInfo->myfrontwindow = (WindowPeek) window; TelInfo->myfronttype=DEC_WINDOW; TelInfo->myfrontvs = vs; TelInfo->myfrontRgn =0L; updateCursor(1); } else if ( (long)window != 0L) { myEvent->message = (long) window; myEvent->modifiers |= activeFlag; myEvent->what = activateEvt; myEvent->when = TickCount(); SystemEvent( myEvent); } } else { /* Suspend Event */ GrafPtr window; CheckDefaultScriptSettings();//update script settings if ((currentScript == smRoman)&&(haveChangedKCHR)) //switch out to default KCHR when while suspended { SetScriptVariable(currentScript,smScriptKeys,defaultKCHR); KeyScript(smRoman); } TelInfo->suspended=TRUE; /* We be in waitin' */ EnableItem( myMenus[Edit],EDcut); EnableItem( myMenus[Edit],EDundo); EnableItem( myMenus[Edit],EDclear); window = FrontWindow(); /* Who's on first */ if ((window = FrontWindow()) != nil) { if ( (vs=RSfindvwind(window)) >= 0) RSdeactivate(vs); else if ( (long)window != 0L) { myEvent->message = (long) window; myEvent->modifiers &= (~activeFlag); myEvent->what = activateEvt; myEvent->when = TickCount(); SystemEvent( myEvent); } } NoWindow(); } break; /* switch of myEvent->message >>24 */ default: break; } break; case kHighLevelEvent: (void) AEProcessAppleEvent(myEvent); break; } } //#pragma profile on void CloseAWindow(WindowPtr theWindow) { short i; long junk; switch(((WindowPeek)theWindow)->windowKind) { case WIN_CONSOLE: // Debugger(); // Can't close the console window break; case WIN_LOG: if (theWindow == ftplog->wind) { CheckItem(myMenus[Fil],FLlog,FALSE); TelInfo->ftplogon = FALSE; RShide(ftplog->vs); } break; case WIN_CNXN: if ((i = WindowPtr2ScreenIndex(theWindow)) >= 0) { if ( screens[i].active == CNXN_ISCORPSE) destroyport(i); else { if ( !ReallyClose( i) ) break; netclose(screens[i].port); removeport(&screens[i]); } } break; case WIN_ICRG: MacRGdestroy(MacRGfindwind(theWindow)); MaxMem(&junk); break; case WIN_TEK: destroyGraphics(RGgetVG(theWindow)); MaxMem(&junk); break; case dialogKind: CloseModelessDialog(theWindow); break; default: DebugStr("\pBad windowkind!"); break; } NoWindow(); } void NotifyUser (void) { OSErr err = noErr; if ((!TelInfo->suspended)||(!gApplicationPrefs->NotifyUser)||gHaveInstalledNotification) return; nRecPtr = (NMRecPtr) myNewPtr(sizeof(NMRec)); if (nRecPtr == NULL) return; nRecPtr->qType = nmType; nRecPtr->nmMark = 1; err = GetIconSuite(&(nRecPtr->nmIcon), kNCSAIconFamilyId, svAllSmallData); if (err != noErr) nRecPtr->nmIcon = nil; nRecPtr->nmSound = nil; nRecPtr->nmStr = nil; nRecPtr->nmResp = nil; NMInstall(nRecPtr); gHaveInstalledNotification = TRUE; } void HandleModeless(EventRecord *theEvent, DialogPtr dlogp, short theItem) { if (dlogp == TelInfo->ipModeless) if (theItem == 1) { DisposeDialog(TelInfo->ipModeless); TelInfo->ipModeless = 0; } if (dlogp == TelInfo->macrosModeless) MacroDialog(theEvent, theItem); } void CloseModelessDialog(DialogPtr dlogp) { if (dlogp == TelInfo->ipModeless) { DisposeDialog(TelInfo->ipModeless); TelInfo->ipModeless = 0; } if (dlogp == TelInfo->macrosModeless) CloseMacros(); } \ No newline at end of file +// event.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* * Main Event loop code for NCSA Telnet for the Macintosh * * Called by: * maclook.c * * Revisions: * 7/92 Telnet2.6: added 2 support for 2 global structs, put cursors into * an array, cleaned up defines Scott Bulmahn * */ /* * Files for inclusion. */ #include "VSkeys.h" #include "wind.h" #include "event.h" //kxplate moved to its own file (CCP 2.7) #include "errors.proto.h" #include "network.proto.h" #include "mydnr.proto.h" #include "bkgr.proto.h" #include "maclook.proto.h" #include "InternalEvents.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "menuseg.proto.h" #include "vrrgmac.proto.h" #include "tekrgmac.proto.h" #include "rsinterf.proto.h" #include "rsmac.proto.h" #include "event.proto.h" #include "macros.proto.h" /* For setmacro proto */ #include "netevent.proto.h" #include "translate.proto.h" #include "parse.proto.h" #include "linemode.proto.h" #include "Connections.proto.h" #include "mainseg.proto.h" #include "movableModal.h" #include // for EMACS meta hack #include //For Notify User Icon Stuff extern short scrn; extern MenuHandle myMenus[NMENUS]; extern Boolean gKeyboardHasControlKey; extern SysEnvRec theWorld; /* BYU 2.4.12 - System Environment record */ extern WindRec *screens, *ftplog; extern Cursor *theCursors[]; extern Boolean gHaveDragMgr; static gHaveInstalledNotification = 0; NMRec *nRecPtr; #include "event.proto.h" // BetterTelnet 2.0fc1 - integrated DJ's changes for real blink (if you want it :-) /* DJ: Blink global */ short gBlink = 0; // In ticks, how long between toggling the above? #define BLINK_PERIOD 30 // RAB - DON'T extern shared routines, and DON'T define them outside of proto.h's! //extern void VSRedrawAll(void); //extern void VSPulseAll(void); /* End blink */ short updateCursor(short force) { static Point lastPoint; static short optwasdown; short optDown; Point myPoint; KeyMap allthekeys; /* Someplace to put the keymap */ if (TelInfo->myfrontwindow) { /* BYU 2.4.11 */ SetPort((GrafPtr) TelInfo->myfrontwindow); /* BYU 2.4.11 */ } else { /* BYU 2.4.11 */ SetCursor(theCursors[normcurs]); /* BYU 2.4.11 */ return(0); /* BYU 2.4.11 */ } GetMouse(&myPoint); GetKeys(allthekeys); optDown = ((unsigned char *)allthekeys)[7] &4; if ( (!force) && EqualPt(myPoint,lastPoint) && (optDown ==optwasdown)) return(0); if (force) TelInfo->lastCursor=0L; if (TelInfo->ginon) { if (TelInfo->lastCursor!= theCursors[gincurs]) { SetCursor(theCursors[gincurs]); TelInfo->lastCursor = theCursors[gincurs]; } return(1); } if (TelInfo->xferon && !optDown) { if (TelInfo->lastCursor!= theCursors[xfercurs]) { SetCursor( theCursors[xfercurs]); TelInfo->lastCursor = theCursors[xfercurs]; } return(1); } switch (TelInfo->myfronttype) { case DEC_WINDOW: if (RSmouseintext( TelInfo->myfrontvs, myPoint)) { if ((PointInSelection(normalize(myPoint, TelInfo->myfrontvs, FALSE), TelInfo->myfrontvs))&&(gHaveDragMgr)) //for Drag ability { if (TelInfo->lastCursor != theCursors[normcurs]) { TelInfo->lastCursor = theCursors[normcurs]; SetCursor(theCursors[normcurs]); } } else { if (optDown) /* Option key is down */ { if (TelInfo->lastCursor != theCursors[poscurs]) { TelInfo->lastCursor = theCursors[poscurs]; SetCursor(theCursors[poscurs]); } } else { if (TelInfo->lastCursor != theCursors[textcurs]) { TelInfo->lastCursor = theCursors[textcurs]; SetCursor(theCursors[textcurs]); } } } } else { if (TelInfo->lastCursor != theCursors[normcurs]) { TelInfo->lastCursor = theCursors[normcurs]; SetCursor(theCursors[normcurs]); } } break; case TEK_WINDOW: LocalToGlobal(&myPoint); if (PtInRgn(myPoint, TelInfo->myfrontwindow->contRgn)) { /* BYU LSC */ if (TelInfo->lastCursor != theCursors[graphcurs]) { TelInfo->lastCursor = theCursors[graphcurs]; SetCursor(theCursors[graphcurs]); } } else { if (TelInfo->lastCursor != theCursors[normcurs]) { TelInfo->lastCursor = theCursors[normcurs]; SetCursor(theCursors[normcurs]); } } break; case NO_WINDOW: default: if (force) { SetCursor( theCursors[normcurs]); TelInfo->lastCursor= theCursors[normcurs]; } } lastPoint=myPoint; optwasdown=optDown; return(0); } void NoWindow( void) { TelInfo->myfrontwindow=0L; TelInfo->myfronttype=NO_WINDOW; TelInfo->myfrontRgn=0L; updateCursor(1); } /* The following code was graciously donated by Marc Tamsky. When are YOU going to donate YOUR code, eh? We know you're reading this. -- JMB */ Boolean CheckPageKeys(short code) /* NCSA: SB */ { /* NCSA: SB */ GrafPtr currFW; // current front window holder // MAT-- short ourW; // virtual screen number holder // MAT--kinda short x1, y2, x2, y1; // coordinates from window // MAT--pulled from scrollproc /* NCSA: SB */ currFW = (GrafPtr)FrontWindow(); // MAT-- ourW = RSfindvwind(currFW); // MAT-- /* NCSA: SB */ switch (code) /* NCSA: SB */ { /* NCSA: SB */ case VSPGUP: /* NCSA: SB */ RScursblinkoff(ourW); VSgetrgn(ourW, &x1, &y1, &x2, &y2); // MAT-- VSscrolback(ourW, y2 - y1); /* scroll a whole windowful */ // MAT-- RScursblinkon(ourW); return TRUE; // MAT-- break; /* NCSA: SB */ /* NCSA: SB */ case VSPGDN: // MAT--121 is a PAGE DOWN. RScursblinkoff(ourW); // MAT--in rsmac.c VSgetrgn(ourW, &x1, &y1, &x2, &y2); // MAT-- VSscrolforward(ourW, y2 - y1); /* scroll a whole windowful */ // MAT-- RScursblinkon(ourW); return TRUE; // MAT-- break; /* NCSA: SB */ // MAT-- case VSHOME: /* NCSA: SB */ RScursblinkoff(ourW); VSscroltop(ourW); /* JMB 2.6 -- Created VSscroltop just for this purpose */ return TRUE; /* NCSA: SB */ break; // MAT-- // MAT-- case VSEND: /* NCSA: SB */ RScursblinkoff(ourW); VSgetrgn(ourW, &x1, &y1, &x2, &y2); // MAT-- VSscrolforward(ourW, 32765); /* scroll a whole BUNCH! */ // MAT-- kludge time again. anyone suggest RScursblinkon(ourW); return TRUE; /* NCSA: SB */ break; // MAT-- a better way to hack this part? } // MAT-- /* NCSA: SB */ return FALSE; /* NCSA: SB - we didnt handle event, let us know about it */ } /* NCSA: SB */ /* HandleKeyDown -- By now, we have already gotten a keypress signal from the event handler, so we just need to interpret it. Get the raw code and ascii value, and then decide what to do with it. */ void HandleKeyDown(EventRecord theEvent,struct WindRec *tw) { unsigned char ascii, code; unsigned char sendch; long menuEquiv; short enterkey = 0; Boolean commanddown, optiondown, controldown,shifted; ObscureCursor(); ascii = theEvent.message & charCodeMask; code = ((theEvent.message & keyCodeMask) >> 8); commanddown = ((theEvent.modifiers & cmdKey) != 0); optiondown = ((theEvent.modifiers & optionKey) != 0); controldown = ((theEvent.modifiers & controlKey) != 0); shifted = ((theEvent.modifiers & shiftKey) != 0); if (DebugKeys(commanddown, ascii, tw->vs)) return; // RAB BetterTelnet 2.0b4 - ha ha, no hack hack // fixed emacs metakey so it works for special keys // (and got rid of the goto kludge while I was at it) if ((tw->emacsmeta == 2)&&(optiondown)) { char temp = ESC; if ((TelInfo->numwindows < 1) || (tw->active != CNXN_ACTIVE)) return; optiondown = 0; // pretend we didn't see option theEvent.modifiers &= (!optionKey);//since we have a valid ASCII anyway from the KCHR // now we fix a couple of broken items in the emacs KCHR if (code == 0x31) ascii = 32; // space fix if ((code == 0x32) && !shifted) ascii = 0x60; // backquote fix if ((code == 0x1B) && shifted) ascii = 0x5F; // underline fix if (tw->kblen > 0) { netwrite( tw->port,tw->kbbuf,tw->kblen); tw->kblen=0; } netpush(tw->port); netwrite(tw->port, &temp, 1); // send an escape, and deal with the char itself below } // goto emacsHack; //ha ha hack hack if ((code == 0x34)&&(ascii == 3)) //fix for PowerBook 540 bad KCHR ascii = 13; //(map control-c to return) else if ((controldown)&&(shifted)&&(ascii == '2')) ascii = 0;//fix bad KCHR control-@ else if ((controldown)&&(shifted)&&(ascii == '6')) ascii = 0x1e;//fix bad KCHR control-^ if (commanddown) { if (gApplicationPrefs->CommandKeys) { //if optioned, retranslate so we can do menu commands if (optiondown) { short virtualCode = 0; Ptr KCHRPtr; long newStuff; unsigned long state = 0; short modifiersCopy; modifiersCopy = theEvent.modifiers; virtualCode = (short)(code); theEvent.modifiers &= (shiftKey); //turn off option virtualCode |= theEvent.modifiers; KCHRPtr = (Ptr)GetScriptManagerVariable(smKCHRCache); newStuff = KeyTranslate(KCHRPtr,virtualCode,&state); newStuff &= 0xFF; //only look at bottom byte ascii = (unsigned char) newStuff; theEvent.modifiers = modifiersCopy; //reset option state } menuEquiv = MenuKey(ascii); //handle menu keys first if ((menuEquiv & 0xFFFF0000) != 0) { HandleMenuCommand(menuEquiv,theEvent.modifiers); return; } if ((TelInfo->numwindows < 1) || (tw->active != CNXN_ACTIVE)) return; // Check for EMACS meta key. if ((tw->emacsmeta)&&(controldown)) { unsigned char temp[2]; if (ascii <= 32) //control changed the ascii value ascii |= 0x40; //move back to a non-control if ((shifted)||(ascii == 0x5f)) //so we can get meta - { short virtualCode = 0; Ptr KCHRPtr; long newStuff; unsigned long state = 0; virtualCode = (short)(code); theEvent.modifiers &= (shiftKey); //turn of command virtualCode |= theEvent.modifiers; KCHRPtr = (Ptr)GetScriptManagerVariable(smKCHRCache); newStuff = KeyTranslate(KCHRPtr,virtualCode,&state); newStuff &= 0xFF; //only look at bottom byte ascii = (unsigned char) newStuff; } // emacsHack: //if the option key KCHR is installled, we will get the right ascii value if ((tw->clientflags & PASTE_IN_PROGRESS)&&(tw->pastemethod)) //queue this { tw->kbbuf[tw->kblen++] = ESC; tw->kbbuf[tw->kblen++] = ascii; return; } if (tw->kblen > 0) { netwrite( tw->port,tw->kbbuf,tw->kblen); tw->kblen=0; } temp[0] = ESC; temp[1] = ascii; if (tw->echo && tw->halfdup) parse(tw,temp,2); netpush(tw->port); // netwrite(tw->port,temp,2); netwrite(tw->port,temp,1); // RAB BetterTelnet 2.0b4 controldown = 0; theEvent.modifiers &= shiftKey; // return; RAB BetterTelnet 2.0b4 - deal with key below } else if (ascii >='0' && ascii <='9' ) //now look for macros { sendmacro(tw, ascii-'0' + (shifted ? 10 : 0)); return; } else if (!((ascii == '`' && gApplicationPrefs->RemapTilde)||(code == BScode))) return; } else //no command key menus { if ((TelInfo->numwindows < 1) || (tw->active != CNXN_ACTIVE)) return; // RAB BetterTelnet 2.0b4 - better remapping for old Macs // else if (!gKeyboardHasControlKey) //map command to control // { ascii &= 0x1f; commanddown = FALSE; // } // else // return; } } if ((TelInfo->numwindows < 1) || (tw->active != CNXN_ACTIVE)) return; if (((ascii == '@') || (ascii == 32))&& controldown) //this, along with the fixed KCHR that mapps a Cntl-@ to ascii = NULL; //a @, takes care of Apple not posting NULL key values // map '`' to ESC if needed if (ascii == '`' && gApplicationPrefs->RemapTilde && !(commanddown)) ascii = ESC; // map Del to ^D if the user wants it if ((code == 0x75) && tw->remapCtrlD) { code = 0x34; ascii = 4; } if (code == BScode) //handle mapping BS to DEL, flipping on option { if (tw->bsdel) if ((optiondown)||(commanddown)) ascii = BS; else ascii = DEL; else if ((optiondown)||(commanddown)) ascii = DEL; else ascii = BS; } if (!tw->enabled) //if we are suspended, and we have negotiated restart_any { //with the host, then enable the screen on anything but an XOFF. We will //eat the XON later if that is what this is. (RFC 1372 --CCP 2.7) if ((tw->restart_any_flow)&&(ascii != tw->TELstop)) { tw->enabled = 1; changeport(scrn, scrn); } } /* Remap PgUp,PgDown,Home,End if the user wants it that way */ // RAB BetterTelnet 2.0b3 - we don't check to see if we're using vt220 if (tw->pgupdwn && (code >= KPlowest)) //do page up/down on vt100 if (CheckPageKeys(code)) return; if (code >= KPlowest) /* BYU - Handle Keypad */ { if (theWorld.keyBoardType == envStandADBKbd) //standard MacII keyboard has keypad +,- { // codes switched if (code == 0x45) code = 0x4e; else if (code == 0x4e) code = 0x45; } // RAB BetterTelnet 2.0b3 - who cares if we're using VT220? // RAB BetterTelnet 2.0b4 - fix for the fix // if ((code >= 0x7B)||(code <= 0x60)) //fkeys dont work in vt100 if (1) { if ((!tw->keypadmap)||(code == 0x4c)||(code > 0x51)||(code < 0x43)) //dont remap operators { if ((tw->clientflags & PASTE_IN_PROGRESS)&&(tw->pastemethod)) //queue this { tw->kbbuf[tw->kblen++] = 0; tw->kbbuf[tw->kblen++] = kpxlate[shifted][code - KPlowest]; return; } if (tw->kblen > 0) { netwrite( tw->port,tw->kbbuf,tw->kblen); tw->kblen=0; } ascii = kpxlate[shifted][code - KPlowest]; // Should we check here for ascii being zero? VSkbsend(tw->vs, (unsigned char) ascii, tw->echo, shifted); return; } } else // we dont handle function keys in vt100 return; } // Handle whatever mapping is needed. mac_nat(&ascii, tw->national); /* LU/PM: Convert char from mac to nat */ if ((tw->clientflags & PASTE_IN_PROGRESS)&&(tw->pastemethod)) //queue this { tw->kbbuf[tw->kblen++] = ascii; return; } if (tw->lmode) // Some form of linemode is active; we dont touch it after them { process_key(ascii,tw); return; } // BSD-like mapping.... if we don't want this, set chars to zero and it wont work //CCP 2.7: this is now AFTER the linemode stuff, so that linemode can handle it differently if (ascii == tw->TELstop) { if (tw->allow_flow) //remote flow control can turn this off { tw->enabled = 0; changeport(scrn,scrn); return; } } if (ascii == tw->TELgo) { if (tw->allow_flow) //remote flow control can turn this off { tw->enabled = 1; changeport(scrn, scrn); return; } } if (ascii == tw->TELip) { char *tellUser = "\n\r[Interrupt Process]\n\r"; parse(tw,(unsigned char *)tellUser,23); netpush(tw->port); netwrite(tw->port, "\377\364",2); //IAC IP netpush(tw->port); netwrite(tw->port, "\377\375\006",3); // send Do TM tw->timing = 1; // set emulate to TMwait return; } if (tw->echo && !tw->halfdup) // Handle klude-linemode { if (ascii>31 && ascii <127 && code < KPlowest) { if (tw->kblen < (MAXKB -1)) /* Add to buffer if not full */ tw->kbbuf[tw->kblen++] = ascii; else { /* if full send buffer */ netwrite( tw->port, tw->kbbuf,tw->kblen); tw->kbbuf[0] = ascii; tw->kblen=1; } sendch=ascii; parse(tw, &sendch, 1); return; /* OK, were set...*/ } //end if printable key else { if ( code == BScode ) { if (tw->kblen>0) { tw->kblen--; parse(tw,(unsigned char *) "\010 \010",3); /* BYU LSC */ } return; } else if (ascii == KILLCHAR) { while (tw->kblen >0) { parse(tw,(unsigned char *) "\010 \010",3); /* BYU LSC */ tw->kblen--; } return; } else if (code port, tw->kbbuf,tw->kblen); /* if full send buffer */ tw->kblen=0; if (ascii !=CR) { sendch='@'+ascii; parse(tw,(unsigned char *) "^",1); /* BYU LSC */ parse(tw, &sendch, 1); } } }//end else non-printable key }//end if klude-linemode if (ascii == '\015') //CR { // If crmap is on, send CR-NULL instead of CR-LF. SendCRAsIfTyped(tw); return; /* netpush(tw->port); if (tw->crmap) netwrite(tw->port,"\015\0",2); else netwrite(tw->port,"\015\012",2); //UNIVAC fix if (tw->echo) parse(tw,(unsigned char *) "\012\015",2); // BYU LSC return; */ } if (tw->echo && tw->halfdup) parse(tw, &ascii, 1); if (ascii != 255) netwrite(tw->port,&ascii,1); else netwrite(tw->port, "\377\377", 2); } void HandleMouseDown(EventRecord myEvent) { GrafPtr whichWindow; short code, myRGMnum; short growErr, i; short theItem; DialogPtr dlogp; code = FindWindow(myEvent.where, &whichWindow); switch (code) { case inMenuBar: if (myEvent.modifiers & optionKey) { switchToOptionMenus(TRUE); HandleMenuCommand(MenuSelect(myEvent.where),myEvent.modifiers); switchToOptionMenus(FALSE); } else if (myEvent.modifiers & shiftKey) { switchToShiftMenus(TRUE); HandleMenuCommand(MenuSelect(myEvent.where),myEvent.modifiers); switchToShiftMenus(FALSE); } else HandleMenuCommand(MenuSelect(myEvent.where),myEvent.modifiers); break; case inSysWindow: SystemClick(&myEvent, whichWindow); break; case inGoAway: if (TrackGoAway( whichWindow, myEvent.where)) CloseAWindow((WindowPtr)whichWindow); break; case inDrag: if ((whichWindow != FrontWindow()) && (!(myEvent.modifiers & cmdKey)) && (!(myEvent.modifiers & optionKey))) { SelectWindow(whichWindow); } DragWindow(whichWindow, myEvent.where, &TelInfo->dragRect); break; case inZoomIn: case inZoomOut: if (TrackBox( whichWindow, myEvent.where, code)) RSzoom( whichWindow, code, myEvent.modifiers & shiftKey); break; /* NCSA: SB - Telnet now allows you to grow the TEK window, finally. */ /* NCSA: SB - So check to see if the click was in a TEK window */ case inGrow: growErr = RSsize( whichWindow, (long *) &myEvent.where, myEvent.modifiers); switch(growErr) { case (-4): /*bad mem problems, kill window, signal user */ OutOfMemory(-4); if ((i = WindowPtr2ScreenIndex(whichWindow)) >= 0) { netclose(screens[i].port); removeport(&screens[i]); } break; case (-2): /* no resize due to memory error, signal user */ OutOfMemory(-2); break; default: /* ok resize, or window not found */ break; } myRGMnum = RGfindbywind(whichWindow); /* NCSA: SB - is it a TEK window click? */ if (myRGMnum != -1) /* NCSA: SB - Anyone want to play some BOLO? */ { /* NCSA: SB */ RGMgrowme((short)myRGMnum, whichWindow,(long *) &myEvent.where,myEvent.modifiers); /* NCSA: TG */ } /* NCSA: SB */ break; case inContent: if (whichWindow != FrontWindow()) { SelectWindow(whichWindow); } else { if (((WindowPeek)whichWindow)->windowKind == dialogKind) { if (IsDialogEvent(&myEvent)) { if (DialogSelect(&myEvent, &dlogp, &theItem)) HandleModeless(&myEvent, dlogp, theItem); } break; } if (RSclick(whichWindow, myEvent) <0) { SetPort(whichWindow); GlobalToLocal(&myEvent.where); RGmousedown(whichWindow, &myEvent.where ); } } break; default: break; } } #pragma profile off void DoEvents( void) { Boolean gotOne; /* Did we get an event */ short vs; EventRecord myEvent; short scratchshort; DialogPtr dlogp; static long blinkTicks = 0; /* DJ: The last time we toggled. Static in case of long delays when we aren't called. */ gotOne = WaitNextEvent(everyEvent, &myEvent, gApplicationPrefs->TimeSlice, 0L); if (!gotOne) { // RAB BetterTelnet 1.2 - null events to dialogs if (TelInfo->macrosModeless) { if (!CallStdFilterProc(TelInfo->macrosModeless, &myEvent, &scratchshort)) if (IsDialogEvent(&myEvent)) DialogSelect(&myEvent, &dlogp, &scratchshort); } } if (gotOne) { /* BYU 2.4.11 - Turn the cursor off when the human makes the slightest move. */ if (gApplicationPrefs->BlinkCursor) { if ( (vs=RSfindvwind(FrontWindow())) >= 0) if (vs == screens[scrn].vs) if (!(myEvent.modifiers & cmdKey) && ((myEvent.what == keyDown) || (myEvent.what == autoKey))) RScursblinkon(vs); else RScursblinkoff(vs); } HandleEvent(&myEvent); } else if (gApplicationPrefs->BlinkCursor && !TelInfo->suspended) { /* BYU 2.4.11 */ if ( (vs=RSfindvwind(FrontWindow())) >= 0) /* BYU 2.4.11 */ if (vs == screens[scrn].vs) /* BYU 2.4.11 */ RScursblink(vs); /* BYU 2.4.11 */ } /* BYU 2.4.11 */ if (FrontWindow() != TelInfo->macrosModeless) // RAB BetterTelnet 1.2 updateCursor(0); /* DJ: Welcome to blink-land */ if(TickCount() - blinkTicks >= BLINK_PERIOD) { blinkTicks = TickCount(); // gBlink = 1 - gBlink; gBlink = !gBlink; // RAB - (1-x) isn't how we NOT stuff around here! VSPulseAll(); } } static long currentScript, defaultKCHR, mungeCount; static Boolean haveChangedKCHR; //called at startup to figure out the default roman KCHR and the active script void scriptKbdInit(void) { currentScript = GetScriptManagerVariable(smKeyScript);//get active script defaultKCHR = GetScriptVariable(smRoman, smScriptKeys); //get the smRoman default KCHR mungeCount = GetScriptManagerVariable(smMunged); //Get the mungeCount haveChangedKCHR = FALSE; } void SetDefaultKCHR(void) { if (haveChangedKCHR) { SetScriptVariable(smRoman,smScriptKeys,defaultKCHR); haveChangedKCHR = FALSE; KeyScript(smRoman); } } void CheckDefaultScriptSettings(void) { long tempLong; tempLong = GetScriptManagerVariable(smMunged); if (tempLong > mungeCount) { currentScript = GetScriptManagerVariable(smKeyScript);//get the new active script if ((currentScript != smRoman)&&(haveChangedKCHR)) //roman has been switched out and we need to fix it { SetScriptVariable(smRoman,smScriptKeys,defaultKCHR); currentScript = GetScriptManagerVariable(smKeyScript);//get the new active script haveChangedKCHR = FALSE; //we dont mess with non-roman scripts } mungeCount = tempLong; //update the mungeCount } } void HandleEvent(EventRecord *myEvent) //CCP split this from DoEvents so we can call this from { //other places short i,vs; DialogPtr dlogp; short theItem, tempstatus; short commanddown; switch(myEvent->what) { case mouseDown: HandleMouseDown(*myEvent); break; case updateEvt: switch(((WindowPeek)myEvent->message)->windowKind) { case WIN_CONSOLE: case WIN_LOG: case WIN_CNXN: if (RSupdate((GrafPtr) myEvent->message)) putln("Ack, problem in update!"); break; case WIN_ICRG: if (MacRGupdate((WindowPtr) myEvent->message)) putln("Ack, problem in update!"); break; case WIN_TEK: if (RGupdate((GrafPtr) myEvent->message) ==0) TekDisable(RGgetVG((GrafPtr) myEvent->message)); else putln("Ack, problem in update!"); break; case dialogKind: CallStdFilterProc((GrafPtr) myEvent->message, myEvent, &theItem); if (IsDialogEvent(myEvent)) DialogSelect(myEvent, &dlogp, &theItem); break; default: putln("Bad windowkind!"); break; } break; case keyDown: case autoKey: commanddown = ((myEvent->modifiers & cmdKey) != 0); if (FrontWindow()) if (((WindowPeek)FrontWindow())->windowKind == dialogKind) { tempstatus = 1; if (CallStdFilterProc(FrontWindow(), myEvent, &theItem)) { HandleModeless(myEvent, FrontWindow(), theItem); break; } if (commanddown) { HandleKeyDown(*myEvent, &screens[scrn]); /* All key events are processed through here */ break; } if (IsDialogEvent(myEvent)) { if (DialogSelect(myEvent, &dlogp, &theItem)) HandleModeless(myEvent, dlogp, theItem); else tempstatus = 0; } if (tempstatus) break; } HandleKeyDown(*myEvent, &screens[scrn]); /* All key events are processed through here */ break; case diskEvt: /* check to see if disk needs to be initialized */ myEvent->where.h = 100; myEvent->where.v = 120; if (noErr != (( myEvent->message >> 16 ) & 0xffff )) { /* check hi word */ DILoad(); DIBadMount( myEvent->where, myEvent->message); /* BYU LSC */ DIUnload(); } break; case activateEvt: if ((myEvent->modifiers & activeFlag)==1) //its an activate event { if (((WindowPeek)myEvent->message)->windowKind == dialogKind) { CallStdFilterProc((GrafPtr) myEvent->message, myEvent, &theItem); if (IsDialogEvent(myEvent)) DialogSelect(myEvent, &dlogp, &theItem); if (TelInfo->macrosModeless) if ((GrafPtr)myEvent->message == TelInfo->macrosModeless) { EnableItem(myMenus[Edit],EDcut); EnableItem(myMenus[Edit],EDcopy); EnableItem(myMenus[Edit],EDpaste); EnableItem(myMenus[Edit],EDclear); } else { DisableItem(myMenus[Edit],EDcut); DisableItem(myMenus[Edit],EDcopy); DisableItem(myMenus[Edit],EDpaste); DisableItem(myMenus[Edit],EDclear); } break; } else { DisableItem(myMenus[Edit],EDcut); DisableItem(myMenus[Edit],EDclear); } i=WindowPtr2ScreenIndex((GrafPtr) myEvent->message); // We need to know who CheckDefaultScriptSettings(); //see if someone has changed the script //this next bit takes care of setting the KCHR based on the EMACS hack pref if ((currentScript == smRoman)&&(screens[i].emacsmeta == 2)) { if (!haveChangedKCHR) //if we haven't already done this { SetScriptVariable(currentScript,smScriptKeys,502); //set the KCHR for EMACS KeyScript(smRoman); //Make it active haveChangedKCHR = TRUE; } } else if (haveChangedKCHR) //new active window doesnt want EMACS hack { SetScriptVariable(currentScript,smScriptKeys,defaultKCHR); KeyScript(smRoman); haveChangedKCHR = FALSE; } AdjustMenus(); DrawMenuBar(); i=WindowPtr2ScreenIndex((GrafPtr) myEvent->message); /* We need to know who */ if (i>=0) { if ((screens[i].curgraph>-1) && (!(myEvent->modifiers & optionKey))) detachGraphics(screens[i].curgraph); changeport(scrn,i); scrn=i; } if ((i=RSfindvwind((GrafPtr) myEvent->message))>=0) { if (RSTextSelected(i)) { EnableItem(myMenus[Fil],FLprint); EnableItem(myMenus[Edit],EDcopy); EnableItem(myMenus[Edit],EDcopyt); } else { DisableItem(myMenus[Fil],FLprint); DisableItem(myMenus[Edit],EDcopy); DisableItem(myMenus[Edit],EDcopyt); } RSactivate(i); TelInfo->myfrontwindow=(WindowPeek) myEvent->message; TelInfo->myfronttype=DEC_WINDOW; TelInfo->myfrontvs = i; TelInfo->myfrontRgn =0L; updateCursor(1); } else { TelInfo->myfrontwindow=(WindowPeek) myEvent->message; TelInfo->myfronttype=TEK_WINDOW; TelInfo->myfrontRgn =0L; updateCursor(1); if ( (i = RGgetdnum((GrafPtr) myEvent->message)) >-1) { if (( i = RGgetVS( i)) >-1) { EnableItem(myMenus[Fil],FLprint); // enable printing EnableItem(myMenus[Edit],EDcopy); // - enable copying DisableItem(myMenus[Edit],EDcopyt); i = findbyVS( i); changeport(scrn,i); scrn=i; } } } } else //its a disable event { short i; DisableItem(myMenus[Edit],EDcut); DisableItem(myMenus[Edit],EDclear); DisableItem(myMenus[Edit],EDcopy); DisableItem(myMenus[Edit],EDpaste); AdjustMenus(); DoTheMenuChecks(); DrawMenuBar(); if ((i=RSfindvwind((GrafPtr) myEvent->message))>=0) RSdeactivate(i); NoWindow(); } break; case osEvt: switch(( myEvent->message >>24) &0xff) { case switchEvt: if (myEvent->message & 0x20) /*Convert clipboard here if necc. (it is not)*/; if (myEvent->message & 0x1) { /* Resume Event */ GrafPtr window; TelInfo->suspended = FALSE; /* We are no longer in suspension */ if (gHaveInstalledNotification) { NMRemove(nRecPtr); DisposeHandle(nRecPtr->nmIcon); gHaveInstalledNotification = FALSE; } // DisableItem( myMenus[Edit],EDcut); // DisableItem( myMenus[Edit],EDundo); // DisableItem( myMenus[Edit],EDclear); window = FrontWindow(); /* Who's on first */ if ( (vs=RSfindvwind(window)) >= 0) { CheckDefaultScriptSettings();//update script settings if ((currentScript == smRoman)&&(haveChangedKCHR)) // set it back { SetScriptVariable(currentScript,smScriptKeys,502); //set the KCHR for EMACS KeyScript(smRoman); //Make it active } RSactivate(vs); TelInfo->myfrontwindow = (WindowPeek) window; TelInfo->myfronttype=DEC_WINDOW; TelInfo->myfrontvs = vs; TelInfo->myfrontRgn =0L; updateCursor(1); } else if ( (long)window != 0L) { myEvent->message = (long) window; myEvent->modifiers |= activeFlag; myEvent->what = activateEvt; myEvent->when = TickCount(); SystemEvent( myEvent); } } else { /* Suspend Event */ GrafPtr window; CheckDefaultScriptSettings();//update script settings if ((currentScript == smRoman)&&(haveChangedKCHR)) //switch out to default KCHR when while suspended { SetScriptVariable(currentScript,smScriptKeys,defaultKCHR); KeyScript(smRoman); } TelInfo->suspended=TRUE; /* We be in waitin' */ // EnableItem( myMenus[Edit],EDcut); // EnableItem( myMenus[Edit],EDundo); // EnableItem( myMenus[Edit],EDclear); window = FrontWindow(); /* Who's on first */ if ((window = FrontWindow()) != nil) { if ( (vs=RSfindvwind(window)) >= 0) RSdeactivate(vs); else if ( (long)window != 0L) { myEvent->message = (long) window; myEvent->modifiers &= (~activeFlag); myEvent->what = activateEvt; myEvent->when = TickCount(); SystemEvent( myEvent); } } NoWindow(); } break; /* switch of myEvent->message >>24 */ default: break; } break; case kHighLevelEvent: (void) AEProcessAppleEvent(myEvent); break; } } //#pragma profile on void CloseAWindow(WindowPtr theWindow) { short i; long junk; switch(((WindowPeek)theWindow)->windowKind) { case WIN_CONSOLE: // Debugger(); // Can't close the console window break; case WIN_LOG: if (theWindow == ftplog->wind) { CheckItem(myMenus[Fil],FLlog,FALSE); TelInfo->ftplogon = FALSE; RShide(ftplog->vs); } break; case WIN_CNXN: if ((i = WindowPtr2ScreenIndex(theWindow)) >= 0) { if ( screens[i].active == CNXN_ISCORPSE) destroyport(i); else { if ( !ReallyClose( i) ) break; netclose(screens[i].port); removeport(&screens[i]); } } break; case WIN_ICRG: MacRGdestroy(MacRGfindwind(theWindow)); MaxMem(&junk); break; case WIN_TEK: destroyGraphics(RGgetVG(theWindow)); MaxMem(&junk); break; case dialogKind: CloseModelessDialog(theWindow); break; default: DebugStr("\pBad windowkind!"); break; } NoWindow(); } void NotifyUser (void) { OSErr err = noErr; if ((!TelInfo->suspended)||(!gApplicationPrefs->NotifyUser)||gHaveInstalledNotification) return; nRecPtr = (NMRecPtr) myNewPtr(sizeof(NMRec)); if (nRecPtr == NULL) return; nRecPtr->qType = nmType; nRecPtr->nmMark = 1; err = GetIconSuite(&(nRecPtr->nmIcon), kNCSAIconFamilyId, svAllSmallData); if (err != noErr) nRecPtr->nmIcon = nil; nRecPtr->nmSound = nil; nRecPtr->nmStr = nil; nRecPtr->nmResp = nil; NMInstall(nRecPtr); gHaveInstalledNotification = TRUE; } void HandleModeless(EventRecord *theEvent, DialogPtr dlogp, short theItem) { short result; if (dlogp == TelInfo->macrosModeless) { MacroDialog(&TelInfo->newMacros, dlogp, theEvent, theItem); if (theItem == 1) { updateCursor(1); CloseMacros(&TelInfo->newMacros, dlogp); TelInfo->macrosModeless = 0; } else if (theItem == 2) { updateCursor(1); CancelMacros(&TelInfo->newMacros, dlogp); TelInfo->macrosModeless = 0; } } } void CloseModelessDialog(DialogPtr dlogp) { if (dlogp == TelInfo->ipModeless) { DisposeDialog(TelInfo->ipModeless); TelInfo->ipModeless = 0; } if (dlogp == TelInfo->macrosModeless) CloseMacros(&TelInfo->newMacros, dlogp); } \ No newline at end of file diff --git a/source/main/keypadmenus.c b/source/main/keypadmenus.c index 10b1191..ba7df80 100755 --- a/source/main/keypadmenus.c +++ b/source/main/keypadmenus.c @@ -1 +1 @@ -// keypadmenus.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "VSkeys.h" /* Baylor - for keypad menu support */ #include "wind.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "keypadmenus.proto.h" extern WindRec *screens; extern short scrn; static unsigned char KeypadMenuMap[] = { /* Baylor - which menu items map to which key */ /* no zero item */ 0, /* find, insert, remove, select, prev, next, */ VSHELP, VSHOME, VSPGUP, VSDEL, VSEND, VSPGDN, /* up, left, down, right, */ VSUP, VSLT, VSDN, VSRT, /* pf1, pf2, pf3, pf4 */ VSF1, VSF2, VSF3, VSF4, /* kp7, kp8, kp9, minus, */ VSK7, VSK8, VSK9, VSKM, /* kp4, kp5, kp6, comma, */ VSK4, VSK5, VSK6, VSKC, /* kp1, kp2, kp3, enter, */ VSK1, VSK2, VSK3, VSKE, /* kp0, period */ VSK0, VSKP }; static unsigned char FuncKeyMenuMap[] = { /* Baylor - which menu items map to which key */ /* no zero item */ 0, /* f6, f7, f8, f9, f10, */ VSF6, VSF7, VSF8, VSF9, VSF10, /* f11, f12, f13, f14, */ VSF11, VSF12, VSF13, VSF14, /* help, do */ VSF15, VSF16, /* f17, f18, f19, f20 */ VSF17, VSF18, VSF19, VSF20 }; void KeyMenu(short theItem) { VSkbsend(screens[scrn].vs, KeypadMenuMap[theItem], screens[scrn].echo); /* Baylor */ } void FuncMenu(short theItem) { VSkbsend(screens[scrn].vs, FuncKeyMenuMap[theItem], screens[scrn].echo); /* Baylor */ } \ No newline at end of file +// keypadmenus.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "VSkeys.h" /* Baylor - for keypad menu support */ #include "wind.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "keypadmenus.proto.h" extern WindRec *screens; extern short scrn; static unsigned char KeypadMenuMap[] = { /* Baylor - which menu items map to which key */ /* no zero item */ 0, /* find, insert, remove, select, prev, next, */ VSHELP, VSHOME, VSPGUP, VSDEL, VSEND, VSPGDN, /* up, left, down, right, */ VSUP, VSLT, VSDN, VSRT, /* pf1, pf2, pf3, pf4 */ VSF1, VSF2, VSF3, VSF4, /* kp7, kp8, kp9, minus, */ VSK7, VSK8, VSK9, VSKM, /* kp4, kp5, kp6, comma, */ VSK4, VSK5, VSK6, VSKC, /* kp1, kp2, kp3, enter, */ VSK1, VSK2, VSK3, VSKE, /* kp0, period */ VSK0, VSKP }; static unsigned char FuncKeyMenuMap[] = { /* Baylor - which menu items map to which key */ /* no zero item */ 0, /* f6, f7, f8, f9, f10, */ VSF6, VSF7, VSF8, VSF9, VSF10, /* f11, f12, f13, f14, */ VSF11, VSF12, VSF13, VSF14, /* help, do */ VSF15, VSF16, /* f17, f18, f19, f20 */ VSF17, VSF18, VSF19, VSF20 }; void KeyMenu(short theItem, short shifted) { VSkbsend(screens[scrn].vs, KeypadMenuMap[theItem], screens[scrn].echo, shifted); /* Baylor */ } void FuncMenu(short theItem, short shifted) { VSkbsend(screens[scrn].vs, FuncKeyMenuMap[theItem], screens[scrn].echo, shifted); /* Baylor */ } \ No newline at end of file diff --git a/source/main/keypadmenus.proto.h b/source/main/keypadmenus.proto.h index ec4bf8a..8c39617 100755 --- a/source/main/keypadmenus.proto.h +++ b/source/main/keypadmenus.proto.h @@ -1 +1 @@ -void KeyMenu(short theItem); void FuncMenu(short theItem); \ No newline at end of file +void KeyMenu(short, short); void FuncMenu(short, short); \ No newline at end of file diff --git a/source/main/maclook.c b/source/main/maclook.c index 3b79710..c16e468 100755 --- a/source/main/maclook.c +++ b/source/main/maclook.c @@ -1 +1 @@ - // maclook.c // User interface code for NCSA Telnet for the Macintosh // originally by Gaige B. Paulsen // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* * User interface for basic telnet with background file transfer * capabilities via FTP calls from host. * * This, the Macintosh version also gives each session its own window, * provides advanced keyboard translation, Tek emulation, printing/copying * of text and graphics and the pasting of text into the active session. * * Requires: * menu.c - Aux. file for handling menu calls * event.c - Aux. file for handling events * switch.c- Aux. file for handling swithcher (the J word is in Event and here ) * * * NCSA Revisions: * 7/92 Telnet 2.6: added support for the 2 global structs, and put all the * cursors into one array. Cleaned up defines Scott Bulmahn */ #ifdef MPW #pragma segment 4 #endif #define PREFMASTER /* So pref structure gets defined Scott! */ #include "netevent.proto.h" #include "wind.h" #include "event.proto.h" #include "macutil.proto.h" #include "popup.h" #include "popup.proto.h" #include "rsinterf.proto.h" #include "vsdata.h" #include "vskeys.h" #include "vsinterf.proto.h" #include "vgtek.proto.h" #include "tekrgmac.proto.h" #include "vr.h" #include "vrrgmac.proto.h" #include "network.proto.h" #include "mydnr.proto.h" #include "menuseg.proto.h" #include "prefs.proto.h" #include "maclook.proto.h" #include "DlogUtils.proto.h" #include "telneterrors.h" extern Cursor *theCursors[]; extern WindRec *screens; /* Window Records (VS) for : Current Sessions */ extern short scrn; //extern char *tempspot; /* temporary storage ~255 bytes malloc-ed */ void MiscUnload(void) {} short detachGraphics( short dnum) { short i=0; while((inumwindows) && (dnum!=screens[i].curgraph)) i++; if (i>=TelInfo->numwindows) return(-1); TelInfo->oldgraph[TelInfo->graphs++]=dnum; screens[i].curgraph=-1; screens[i].termstate=VTEKTYPE; screens[i].enabled=1; RGdetach(dnum); return(0); } /* Find screen index by Window */ short WindowPtr2ScreenIndex(WindowPtr wn) { short i=0; while((inumwindows) && (wn!= (WindowPtr)screens[i].wind)) i++; if (i>=TelInfo->numwindows) return(-1); return(i); } WindRecPtr WindowPtr2WindRecPtr(WindowPtr wn) { short winNum; winNum = WindowPtr2ScreenIndex(wn); if (winNum == -1) { return nil; } return &screens[winNum]; } /* Find screen index by VS Number */ short findbyVS( short vs) { short i=0; while((inumwindows) && (vs!=screens[i].vs)) i++; if (i>=TelInfo->numwindows) return(-1); return(i); } void setgraphcurs( void) /* Called at start of gin */ { TelInfo->ginon=1; updateCursor(1); } void unsetgraphcurs( void) /* Called at start of gin */ { TelInfo->ginon=0; updateCursor(1); } short VGalive( short dnum) { short i; i=0; while((inumwindows) && (dnum!=screens[i].curgraph)) i++; if (inumwindows) { return(1); } else { i=0; while ((igraphs) && (dnum!=TelInfo->oldgraph[i])) i++; if (igraphs) return(1); } return(0); } void destroyGraphics( short dnum) { short i; i=0; while((inumwindows) && (dnum!=screens[i].curgraph)) i++; if (inumwindows) { screens[i].curgraph=-1; screens[i].termstate=VTEKTYPE; screens[i].enabled=1; } else { i=0; while ((igraphs) && (dnum!=TelInfo->oldgraph[i])) i++; while (i<(MaxGraph-1)) TelInfo->oldgraph[i]=TelInfo->oldgraph[++i]; /* Bump everyone down one slot */ TelInfo->graphs--; /* One less graph to feed */ } VGclose( dnum); } short FindByVG(short vg) { short i=0; while((inumwindows) && (vg!=screens[i].curgraph)) i++; if (i>=TelInfo->numwindows) return(-1); return(i); } void TekEnable( short vg) { short change; change=FindByVG( vg); if (change>=0) screens[change].enabled=1; } void TekDisable( short vg) { short change; change=FindByVG( vg); if (change>=0) screens[change].enabled=0; } /* showNetNumbers - Show the current network numbers. */ void showNetNumbers( void) { char tmpout[256]; /* IP Number */ DialogPtr dptr; /* dialog box pointer */ short scratchshort; int tmp[4]; /* Integer copy of IP Number */ unsigned char tmp2[4]; if (TelInfo->ipModeless) { SelectWindow(TelInfo->ipModeless); return; } Mnetinit(); // RAB BetterTelnet 1.0fc4 netgetip(tmp2); for(scratchshort=0; scratchshort<4; scratchshort++) tmp[scratchshort] = (int)tmp2[scratchshort]; /* Get integer numbers */ sprintf(&tmpout[0],"IP Address:\r%d.%d.%d.%d",tmp[0],tmp[1],tmp[2],tmp[3]); /* create Human-readable numbers */ c2pstr(tmpout); /* BYU LSC */ // RAB BetterTelnet 1.2 - we can't use ParamText() for modeless dialogs // ParamText(0L, (StringPtr)tmpout,0L,0L); /* BYU LSC - Put Parms in Dlog */ dptr = GetNewDialog(MyIPDLOG, NULL, kInFront); SetDialogDefaultItem(dptr, 1); SetTEText(dptr, 2, (unsigned char *)tmpout); DrawDialog(dptr); /* Display Dialog */ TelInfo->ipModeless = dptr; // ModalDialog(NULL, &scratchshort); /* Wait for a click */ // DisposDialog(dptr); // Alert(MyIPDLOG, 0L); } /*******************************************************************/ /* setupkeys * Prompt the user for which keys to use for kill, stop and start. */ void setupkeys( void) { DialogPtr dtemp; Rect dBox; short dItem,kItem,sItem,eItem; Handle kbox,sbox,ebox; char *tempspot; tempspot = (char *) myNewPtr(256); if (tempspot == NULL) return; //BUGG signal error here dtemp=GetNewMyDialog( SetupDLOG, NULL, kInFront, (void *)ThirdCenterDialog); SetCursor(theCursors[normcurs]); GetDItem( dtemp, killbox, &kItem, &kbox, &dBox); GetDItem( dtemp, stopbox, &eItem, &ebox, &dBox); GetDItem( dtemp, startbox, &sItem, &sbox, &dBox); *tempspot = 0; if (screens[scrn].TELstop > 0) { sprintf(tempspot,"^%c",screens[scrn].TELstop^64); c2pstr(tempspot); /* BYU LSC */ SetIText( ebox , (StringPtr)tempspot); SelIText( dtemp, stopbox, 0, 32767); } if (screens[scrn].TELgo > 0) { sprintf(tempspot,"^%c",screens[scrn].TELgo^64); c2pstr(tempspot); /* BYU LSC */ SetIText( sbox , (StringPtr)tempspot); SelIText( dtemp, startbox, 0, 32767); } if (screens[scrn].TELip > 0) { sprintf(tempspot,"^%c",screens[scrn].TELip^64); c2pstr(tempspot); /* BYU LSC */ SetIText( kbox , (StringPtr)tempspot); SelIText( dtemp, killbox, 0, 32767); } dItem=0; /* initially no hits */ while((dItem>3) || (dItem==0)) { /* While we are in the loop */ ModalDialog(DLOGwOK_CancelUPP,&dItem); /* * intermediate check. If they hit a key, put its number in the box. */ GetIText( kbox, (StringPtr)tempspot); /* BYU LSC - Get the string */ p2cstr((StringPtr)tempspot); /* BYU LSC */ if (*tempspot < 32 && *tempspot > 0) { sprintf(tempspot,"^%c",*tempspot^64); c2pstr(tempspot); /* BYU LSC */ SetIText( kbox , (StringPtr)tempspot); /* BYU LSC */ SelIText( dtemp, killbox, 0, 32767 ); } GetIText( ebox, (StringPtr)tempspot); /* BYU LSC - Get the string */ p2cstr((StringPtr)tempspot); /* BYU LSC */ if (*tempspot < 32 && *tempspot > 0) { sprintf(tempspot,"^%c",*tempspot^64); c2pstr(tempspot); /* BYU LSC */ SetIText( ebox , (StringPtr)tempspot); /* BYU LSC */ SelIText( dtemp, stopbox, 0, 32767); } GetIText( sbox, (StringPtr)tempspot); /* BYU LSC - Get the string */ p2cstr((StringPtr)tempspot); /* BYU LSC */ if (*tempspot < 32 && *tempspot > 0) { sprintf(tempspot,"^%c",*tempspot^64); c2pstr(tempspot); /* BYU LSC */ SetIText( sbox , (StringPtr)tempspot); /* BYU LSC */ SelIText( dtemp, startbox, 0, 32767); } } if (dItem==DLOGCancel) { DisposDialog( dtemp); return; } GetIText( kbox, (StringPtr)tempspot); /* BYU LSC - Get the string */ p2cstr((StringPtr)tempspot); /* BYU LSC */ if (*tempspot != '^') screens[scrn].TELip = -1; else screens[scrn].TELip = toupper(*(tempspot+1)) ^ 64; GetIText( ebox, (StringPtr)tempspot); /* BYU LSC - Get the string */ p2cstr((StringPtr)tempspot); /* BYU LSC */ if (*tempspot != '^') screens[scrn].TELstop = -1; else screens[scrn].TELstop = toupper(*(tempspot+1)) ^ 64; GetIText( sbox, (StringPtr)tempspot); /* BYU LSC - Get the string */ p2cstr((StringPtr)tempspot); /* BYU LSC */ if (*tempspot != '^') screens[scrn].TELgo = -1; else screens[scrn].TELgo = toupper(*(tempspot+1)) ^ 64; DisposDialog( dtemp); updateCursor(1); } \ No newline at end of file + // maclook.c // User interface code for NCSA Telnet for the Macintosh // originally by Gaige B. Paulsen // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* * User interface for basic telnet with background file transfer * capabilities via FTP calls from host. * * This, the Macintosh version also gives each session its own window, * provides advanced keyboard translation, Tek emulation, printing/copying * of text and graphics and the pasting of text into the active session. * * Requires: * menu.c - Aux. file for handling menu calls * event.c - Aux. file for handling events * switch.c- Aux. file for handling swithcher (the J word is in Event and here ) * * * NCSA Revisions: * 7/92 Telnet 2.6: added support for the 2 global structs, and put all the * cursors into one array. Cleaned up defines Scott Bulmahn */ #define PREFMASTER /* So pref structure gets defined Scott! */ #include "netevent.proto.h" #include "wind.h" #include "event.proto.h" #include "macutil.proto.h" #include "popup.h" #include "popup.proto.h" #include "rsinterf.proto.h" #include "vsdata.h" #include "vskeys.h" #include "vsinterf.proto.h" #include "vgtek.proto.h" #include "tekrgmac.proto.h" #include "vr.h" #include "vrrgmac.proto.h" #include "network.proto.h" #include "mydnr.proto.h" #include "menuseg.proto.h" #include "prefs.proto.h" #include "maclook.proto.h" #include "DlogUtils.proto.h" #include "telneterrors.h" extern Cursor *theCursors[]; extern WindRec *screens; /* Window Records (VS) for : Current Sessions */ extern short scrn; //extern char *tempspot; /* temporary storage ~255 bytes malloc-ed */ void MiscUnload(void) {} short detachGraphics( short dnum) { short i=0; while((inumwindows) && (dnum!=screens[i].curgraph)) i++; if (i>=TelInfo->numwindows) return(-1); TelInfo->oldgraph[TelInfo->graphs++]=dnum; screens[i].curgraph=-1; screens[i].termstate=VTEKTYPE; screens[i].enabled=1; RGdetach(dnum); return(0); } /* Find screen index by Window */ short WindowPtr2ScreenIndex(WindowPtr wn) { short i=0; while((inumwindows) && (wn!= (WindowPtr)screens[i].wind)) i++; if (i>=TelInfo->numwindows) return(-1); return(i); } WindRecPtr WindowPtr2WindRecPtr(WindowPtr wn) { short winNum; winNum = WindowPtr2ScreenIndex(wn); if (winNum == -1) { return nil; } return &screens[winNum]; } /* Find screen index by VS Number */ short findbyVS( short vs) { short i=0; while((inumwindows) && (vs!=screens[i].vs)) i++; if (i>=TelInfo->numwindows) return(-1); return(i); } void setgraphcurs( void) /* Called at start of gin */ { TelInfo->ginon=1; updateCursor(1); } void unsetgraphcurs( void) /* Called at start of gin */ { TelInfo->ginon=0; updateCursor(1); } short VGalive( short dnum) { short i; i=0; while((inumwindows) && (dnum!=screens[i].curgraph)) i++; if (inumwindows) { return(1); } else { i=0; while ((igraphs) && (dnum!=TelInfo->oldgraph[i])) i++; if (igraphs) return(1); } return(0); } void destroyGraphics( short dnum) { short i; i=0; while((inumwindows) && (dnum!=screens[i].curgraph)) i++; if (inumwindows) { screens[i].curgraph=-1; screens[i].termstate=VTEKTYPE; screens[i].enabled=1; } else { i=0; while ((igraphs) && (dnum!=TelInfo->oldgraph[i])) i++; while (i<(MaxGraph-1)) TelInfo->oldgraph[i]=TelInfo->oldgraph[++i]; /* Bump everyone down one slot */ TelInfo->graphs--; /* One less graph to feed */ } VGclose( dnum); } short FindByVG(short vg) { short i=0; while((inumwindows) && (vg!=screens[i].curgraph)) i++; if (i>=TelInfo->numwindows) return(-1); return(i); } void TekEnable( short vg) { short change; change=FindByVG( vg); if (change>=0) screens[change].enabled=1; } void TekDisable( short vg) { short change; change=FindByVG( vg); if (change>=0) screens[change].enabled=0; } /* showNetNumbers - Show the current network numbers. */ void showNetNumbers( void) { char tmpout[256]; /* IP Number */ DialogPtr dptr; /* dialog box pointer */ short scratchshort; int tmp[4]; /* Integer copy of IP Number */ unsigned char tmp2[4]; if (TelInfo->ipModeless) { SelectWindow(TelInfo->ipModeless); return; } Mnetinit(); // RAB BetterTelnet 1.0fc4 netgetip(tmp2); for(scratchshort=0; scratchshort<4; scratchshort++) tmp[scratchshort] = (int)tmp2[scratchshort]; /* Get integer numbers */ sprintf(&tmpout[0],"IP Address:\r%d.%d.%d.%d",tmp[0],tmp[1],tmp[2],tmp[3]); /* create Human-readable numbers */ c2pstr(tmpout); /* BYU LSC */ // RAB BetterTelnet 1.2 - we can't use ParamText() for modeless dialogs // ParamText(0L, (StringPtr)tmpout,0L,0L); /* BYU LSC - Put Parms in Dlog */ dptr = GetNewDialog(MyIPDLOG, NULL, kInFront); SetTEText(dptr, 1, (unsigned char *)tmpout); DrawDialog(dptr); /* Display Dialog */ TelInfo->ipModeless = dptr; // ModalDialog(NULL, &scratchshort); /* Wait for a click */ // DisposeDialog(dptr); // Alert(MyIPDLOG, 0L); } /*******************************************************************/ /* setupkeys * Prompt the user for which keys to use for kill, stop and start. */ void setupkeys( void) { DialogPtr dtemp; Rect dBox; short dItem,kItem,sItem,eItem; Handle kbox,sbox,ebox; char *tempspot; tempspot = (char *) myNewPtr(256); if (tempspot == NULL) return; //BUGG signal error here dtemp=GetNewMyDialog( SetupDLOG, NULL, kInFront, (void *)ThirdCenterDialog); SetCursor(theCursors[normcurs]); GetDialogItem( dtemp, killbox, &kItem, &kbox, &dBox); GetDialogItem( dtemp, stopbox, &eItem, &ebox, &dBox); GetDialogItem( dtemp, startbox, &sItem, &sbox, &dBox); *tempspot = 0; if (screens[scrn].TELstop > 0) { sprintf(tempspot,"^%c",screens[scrn].TELstop^64); c2pstr(tempspot); /* BYU LSC */ SetDialogItemText( ebox , (StringPtr)tempspot); SelectDialogItemText( dtemp, stopbox, 0, 32767); } if (screens[scrn].TELgo > 0) { sprintf(tempspot,"^%c",screens[scrn].TELgo^64); c2pstr(tempspot); /* BYU LSC */ SetDialogItemText( sbox , (StringPtr)tempspot); SelectDialogItemText( dtemp, startbox, 0, 32767); } if (screens[scrn].TELip > 0) { sprintf(tempspot,"^%c",screens[scrn].TELip^64); c2pstr(tempspot); /* BYU LSC */ SetDialogItemText( kbox , (StringPtr)tempspot); SelectDialogItemText( dtemp, killbox, 0, 32767); } dItem=0; /* initially no hits */ while((dItem>3) || (dItem==0)) { /* While we are in the loop */ ModalDialog(DLOGwOK_CancelUPP,&dItem); /* * intermediate check. If they hit a key, put its number in the box. */ GetDialogItemText( kbox, (StringPtr)tempspot); /* BYU LSC - Get the string */ p2cstr((StringPtr)tempspot); /* BYU LSC */ if (*tempspot < 32 && *tempspot > 0) { sprintf(tempspot,"^%c",*tempspot^64); c2pstr(tempspot); /* BYU LSC */ SetDialogItemText( kbox , (StringPtr)tempspot); /* BYU LSC */ SelectDialogItemText( dtemp, killbox, 0, 32767 ); } GetDialogItemText( ebox, (StringPtr)tempspot); /* BYU LSC - Get the string */ p2cstr((StringPtr)tempspot); /* BYU LSC */ if (*tempspot < 32 && *tempspot > 0) { sprintf(tempspot,"^%c",*tempspot^64); c2pstr(tempspot); /* BYU LSC */ SetDialogItemText( ebox , (StringPtr)tempspot); /* BYU LSC */ SelectDialogItemText( dtemp, stopbox, 0, 32767); } GetDialogItemText( sbox, (StringPtr)tempspot); /* BYU LSC - Get the string */ p2cstr((StringPtr)tempspot); /* BYU LSC */ if (*tempspot < 32 && *tempspot > 0) { sprintf(tempspot,"^%c",*tempspot^64); c2pstr(tempspot); /* BYU LSC */ SetDialogItemText( sbox , (StringPtr)tempspot); /* BYU LSC */ SelectDialogItemText( dtemp, startbox, 0, 32767); } } if (dItem==DLOGCancel) { DisposeDialog( dtemp); return; } GetDialogItemText( kbox, (StringPtr)tempspot); /* BYU LSC - Get the string */ p2cstr((StringPtr)tempspot); /* BYU LSC */ if (*tempspot != '^') screens[scrn].TELip = -1; else screens[scrn].TELip = toupper(*(tempspot+1)) ^ 64; GetDialogItemText( ebox, (StringPtr)tempspot); /* BYU LSC - Get the string */ p2cstr((StringPtr)tempspot); /* BYU LSC */ if (*tempspot != '^') screens[scrn].TELstop = -1; else screens[scrn].TELstop = toupper(*(tempspot+1)) ^ 64; GetDialogItemText( sbox, (StringPtr)tempspot); /* BYU LSC - Get the string */ p2cstr((StringPtr)tempspot); /* BYU LSC */ if (*tempspot != '^') screens[scrn].TELgo = -1; else screens[scrn].TELgo = toupper(*(tempspot+1)) ^ 64; DisposeDialog( dtemp); updateCursor(1); } \ No newline at end of file diff --git a/source/main/mainseg.c b/source/main/mainseg.c index 6edebe0..a08d499 100755 --- a/source/main/mainseg.c +++ b/source/main/mainseg.c @@ -1 +1 @@ -// mainseg.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #ifdef MPW #pragma segment main #endif #define GLOBALMASTER /* Global structures are charged to us... see below */ #include "event.proto.h" #include "netevent.proto.h" #include "init.proto.h" #include "network.proto.h" // For netshut proto #include "wind.h" #include "MacBinary.h" #include "binsubs.proto.h" // For close_mb_files proto #include "menuseg.proto.h" #include "Connections.proto.h" #include "AddressXlation.h" //the following are for the unload protos #include "vgtek.proto.h" #include "vr.h" #include "vr.proto.h" #include "rsinterf.proto.h" #include "vsem.proto.h" #include "configure.proto.h" #include "macros.proto.h" #include "bkgr.proto.h" #include "printing.proto.h" #include "sets.proto.h" #include "rg0.proto.h" #include "rgmp.proto.h" #include "parse.proto.h" #include "linemode.proto.h" #include "tnae.h" #include "authencrypt.proto.h" #include "mainseg.proto.h" #include "IConfig.proto.h" #include "ae.proto.h" #include "prefs.proto.h" //#define PROFILER // Define to use MW profiler #ifdef PROFILER #include "profiler.h" #endif Cursor *theCursors[NUMCURS]; /* all the cursors in a nice bundle */ WindRec *screens, /* Window Records (VS) for : Current Sessions */ *ftplog; short scrn=0; TelInfoRec *TelInfo; /* This is defined here and externed everywhere else. */ void main(void) { short i; long lastCount = 0; Boolean haveNotifiedLowMemory = FALSE, memOK; MaxApplZone(); for (i=0; i<9; i++) MoreMasters(); #ifdef PERFORMANCE ThePGlobals = nil; if (!InitPerf(&ThePGlobals, 10, 8, TRUE, TRUE, "\pCODE", 0, "\p", FALSE, 0, 0, 0)) Debugger(); PerfControl(ThePGlobals, TRUE); #endif #ifdef PROFILER if (ProfilerInit(collectDetailed, microsecondsTimeBase, 1000, 30) != noErr) DebugStr("\pError starting profiler!"); ProfilerSetStatus(false); ProfilerClear(); #endif init(); /* JMB 2.6 - Call all init routines */ UnloadSeg(&init); /* Bye, bye to init routines... */ if (gApplicationPrefs->autoOpenDefault) OpenSpecial(3); TelInfo->gotDocument = 0; do { /* BYU - Do this forever */ UnloadSegments(); DoEvents(); if (!TelInfo->done) DoNetEvents(); memOK = RecoverReserveMemory(); if (memOK) haveNotifiedLowMemory = false; else if (!haveNotifiedLowMemory) { Alert(MemoryLowAlert, NULL); haveNotifiedLowMemory = true; } } while (!TelInfo->done); /* BYU mod */ #ifdef PERFORMANCE if (!PerfDump(ThePGlobals, "\pPerform.out", TRUE, 80)) DebugStr("\pDump Failed"); Debugger(); TermPerf(ThePGlobals); #endif #ifdef PROFILER if (ProfilerDump("\pProfiler.out") != noErr) { DebugStr("\pDump Failed"); } ProfilerTerm(); #endif } void quit( void) { if (TelInfo->numwindows>0) return; if (TelInfo->startedTCP) { // RAB BetterTelnet 1.0fc4 netshut(); CloseResolver(); /* BYU 2.4.16 */ } // RAB BetterTelnet 1.0fc4 close_mb_files(); /* BYU - Don't leave any files open! */ stopInternetConfig(); TelInfo->done = 1; /* BYU */ } void forcequit(void) { quit(); ExitToShell(); } // This is rather simple right now, but I'll make it smarter when I have the time. //void CheckFreeMemory(void) //{ // long space, block; // PurgeSpace(&space, &block); // if (space < (30 * 1024)) // Alert(MemoryLowAlert, NULL); //} // This unloads the segments that are safe to unload. Right now, the DNR and network // segments ARE NOT safe to unload. Do _not_ add anything to this unless you really // know what you are doing! (I MEAN IT!) void UnloadSegments(void) { UnloadSeg(&TEKMAINunload); UnloadSeg(&ICRunload); UnloadSeg(&CONFIGUREunload); UnloadSeg(&MACROSunload); UnloadSeg(&FTPServerUnload); UnloadSeg(&PrintingUnload); UnloadSeg(&SETSunload); UnloadSeg(&TEKNULLunload); UnloadSeg(&TEKMacPicunload); UnloadSeg(&LinemodeUnload); UnloadSeg(&ICUnload); UnloadSeg(&AEunload); UnloadSeg(&PREFSUnload); } \ No newline at end of file +// BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // mainseg.c #define GLOBALMASTER /* Global structures are charged to us... see below */ #include "event.proto.h" #include "netevent.proto.h" #include "init.proto.h" #include "network.proto.h" // For netshut proto #include "wind.h" #include "MacBinary.h" #include "binsubs.proto.h" // For close_mb_files proto #include "menuseg.proto.h" #include "Connections.proto.h" #include "AddressXlation.h" //the following are for the unload protos #include "vgtek.proto.h" #include "vr.h" #include "vr.proto.h" #include "rsinterf.proto.h" #include "vsem.proto.h" #include "configure.proto.h" #include "macros.proto.h" #include "bkgr.proto.h" #include "printing.proto.h" #include "sets.proto.h" #include "rg0.proto.h" #include "rgmp.proto.h" #include "parse.proto.h" #include "linemode.proto.h" #include "tnae.h" #include "authencrypt.proto.h" #include "mainseg.proto.h" #include "IConfig.proto.h" #include "ae.proto.h" #include "prefs.proto.h" #include "Appearance.h" //#define PROFILER // Define to use MW profiler #ifdef PROFILER #include "profiler.h" #endif Cursor *theCursors[NUMCURS]; /* all the cursors in a nice bundle */ WindRec *screens, /* Window Records (VS) for : Current Sessions */ *ftplog; short scrn=0; TelInfoRec *TelInfo; /* This is defined here and externed everywhere else. */ void main(void) { short i; long dummy; long lastCount = 0; Boolean haveNotifiedLowMemory = FALSE, memOK; MaxApplZone(); for (i=0; i<9; i++) MoreMasters(); #ifdef PERFORMANCE ThePGlobals = nil; if (!InitPerf(&ThePGlobals, 10, 8, TRUE, TRUE, "\pCODE", 0, "\p", FALSE, 0, 0, 0)) Debugger(); PerfControl(ThePGlobals, TRUE); #endif #ifdef PROFILER if (ProfilerInit(collectDetailed, microsecondsTimeBase, 1000, 30) != noErr) DebugStr("\pError starting profiler!"); // ProfilerSetStatus(false); ProfilerClear(); #endif if (!Gestalt('appr',&dummy)) RegisterAppearanceClient(); init(); /* JMB 2.6 - Call all init routines */ UnloadSeg(&init); /* Bye, bye to init routines... */ if (gApplicationPrefs->autoOpenDefault) OpenSpecial(3); TelInfo->gotDocument = 0; do { /* BYU - Do this forever */ UnloadSegments(); DoEvents(); if (!TelInfo->done) DoNetEvents(); memOK = RecoverReserveMemory(); if (memOK) haveNotifiedLowMemory = false; else if (!haveNotifiedLowMemory) { Alert(MemoryLowAlert, NULL); haveNotifiedLowMemory = true; } } while (!TelInfo->done); /* BYU mod */ #ifdef PERFORMANCE if (!PerfDump(ThePGlobals, "\pPerform.out", TRUE, 80)) DebugStr("\pDump Failed"); Debugger(); TermPerf(ThePGlobals); #endif #ifdef PROFILER if (ProfilerDump("\pProfiler.out") != noErr) { DebugStr("\pDump Failed"); } ProfilerTerm(); #endif } void quit( void) { if (TelInfo->numwindows>0) return; if (TelInfo->startedTCP) { // RAB BetterTelnet 1.0fc4 netshut(); CloseResolver(); /* BYU 2.4.16 */ } // RAB BetterTelnet 1.0fc4 close_mb_files(); /* BYU - Don't leave any files open! */ stopInternetConfig(); TelInfo->done = 1; /* BYU */ } void forcequit(void) { quit(); ExitToShell(); } // This is rather simple right now, but I'll make it smarter when I have the time. //void CheckFreeMemory(void) //{ // long space, block; // PurgeSpace(&space, &block); // if (space < (30 * 1024)) // Alert(MemoryLowAlert, NULL); //} // This unloads the segments that are safe to unload. Right now, the DNR and network // segments ARE NOT safe to unload. Do _not_ add anything to this unless you really // know what you are doing! (I MEAN IT!) void UnloadSegments(void) { UnloadSeg(&TEKMAINunload); UnloadSeg(&ICRunload); UnloadSeg(&CONFIGUREunload); UnloadSeg(&MACROSunload); UnloadSeg(&FTPServerUnload); UnloadSeg(&PrintingUnload); UnloadSeg(&SETSunload); UnloadSeg(&TEKNULLunload); UnloadSeg(&TEKMacPicunload); UnloadSeg(&LinemodeUnload); UnloadSeg(&ICUnload); UnloadSeg(&AEunload); UnloadSeg(&PREFSUnload); } \ No newline at end of file diff --git a/source/main/memory.c b/source/main/memory.c index 3516152..0fa45e7 100755 --- a/source/main/memory.c +++ b/source/main/memory.c @@ -1 +1 @@ -// memory.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "memory.proto.h" static Size gCushion; /* size of memory cushion */ static Size gReserve; /* size of memory reserve */ static Handle gReserveBlock = NULL; /* reserve block */ static Boolean gCritical = true; /* true if current memory request is critical */ void initMemoryBuffer(Size cushion, Size reserve) { OSErr err = noErr; static GrowZoneUPP myGrowZoneUPP; gCushion = cushion; gReserve = reserve; gReserveBlock = NewHandle(reserve); myGrowZoneUPP = NewGrowZoneProc(MyGrowZone); SetGrowZone(myGrowZoneUPP); return; } Boolean RecoverReserveMemory (void) { if (gReserveBlock == nil) return true; if (*gReserveBlock != nil) return true; ReallocateHandle(gReserveBlock, gReserve); if (MemError() != noErr) return false; return MemoryAvailable(0); } Boolean MemoryAvailable (Size len) { long total, contig; if (gReserveBlock == nil || *gReserveBlock == nil) { if (!RecoverReserveMemory()) return false; } PurgeSpace(&total, &contig); return len + gCushion < contig; } static pascal long MyGrowZone (Size cbNeeded) { long theA5, result; theA5 = SetCurrentA5(); if (gCritical && gReserveBlock != nil && *gReserveBlock != nil && gReserveBlock != GZSaveHnd()) { EmptyHandle(gReserveBlock); result = gReserve; } else { result = 0; } SetA5(theA5); return result; } Handle myNewHandle(Size len) { Handle tempHandle; if (!MemoryAvailable(len)) return NULL; gCritical = FALSE; tempHandle = NewHandleClear(len); gCritical = TRUE; return tempHandle; } Handle myNewHandleCritical(Size len) { Handle tempHandle; tempHandle = NewHandleClear(len); return tempHandle; } Ptr myNewPtr(Size len) { Ptr tempPtr; if (!MemoryAvailable(len)) return NULL; gCritical = FALSE; tempPtr = NewPtrClear(len); gCritical = TRUE; return tempPtr; } Ptr myNewPtrCritical(Size len) { Ptr tempPtr; tempPtr = NewPtrClear(len); return tempPtr; } OSErr mySetHandleSize (Handle handle, Size len) { Size oldLen; OSErr err = noErr; oldLen = GetHandleSize(handle); if (oldLen < len) { if (!MemoryAvailable(len-oldLen)) return memFullErr; } gCritical = FALSE; SetHandleSize(handle, len); gCritical = TRUE; err = MemError(); if (err == memFullErr) { /* The Memory Manager is too stupid to do this itself. */ MoveHHi(handle); CompactMem(maxSize); gCritical = FALSE; SetHandleSize(handle, len); gCritical = TRUE; err = MemError(); } if (err != noErr) return err; if (oldLen >= len) return noErr; if (MemoryAvailable(0)) return noErr; SetHandleSize(handle, oldLen); return memFullErr; } OSErr MySetHandleSizeCritical (Handle handle, Size len) { SetHandleSize(handle, len); if (MemError() == memFullErr) { /* The Memory Manager is too stupid to do this itself. */ MoveHHi(handle); CompactMem(maxSize); SetHandleSize(handle, len); } return MemError(); } \ No newline at end of file +// memory.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "memory.proto.h" static Size gCushion; /* size of memory cushion */ static Size gReserve; /* size of memory reserve */ static Handle gReserveBlock = NULL; /* reserve block */ static Boolean gCritical = true; /* true if current memory request is critical */ void initMemoryBuffer(Size cushion, Size reserve) { OSErr err = noErr; static GrowZoneUPP myGrowZoneUPP; gCushion = cushion; gReserve = reserve; gReserveBlock = NewHandle(reserve); myGrowZoneUPP = NewGrowZoneProc(MyGrowZone); SetGrowZone(myGrowZoneUPP); return; } Boolean RecoverReserveMemory (void) { if (gReserveBlock == nil) return true; if (*gReserveBlock != nil) return true; ReallocateHandle(gReserveBlock, gReserve); if (MemError() != noErr) return false; return MemoryAvailable(0); } Boolean MemoryAvailable (Size len) { long total, contig; if (gReserveBlock == nil || *gReserveBlock == nil) { if (!RecoverReserveMemory()) return false; } PurgeSpace(&total, &contig); return len + gCushion < contig; } static pascal long MyGrowZone (Size cbNeeded) { long theA5, result; theA5 = SetCurrentA5(); if (gCritical && gReserveBlock != nil && *gReserveBlock != nil && gReserveBlock != GZSaveHnd()) { EmptyHandle(gReserveBlock); result = gReserve; } else { result = 0; } SetA5(theA5); return result; } Handle myNewHandle(Size len) { Handle tempHandle; if (!MemoryAvailable(len)) return NULL; gCritical = FALSE; tempHandle = NewHandleClear(len); gCritical = TRUE; return tempHandle; } Handle myNewHandleCritical(Size len) { Handle tempHandle; tempHandle = NewHandleClear(len); return tempHandle; } Ptr myNewPtr(Size len) { Ptr tempPtr; if (!MemoryAvailable(len)) return NULL; gCritical = FALSE; tempPtr = NewPtrClear(len); gCritical = TRUE; return tempPtr; } Ptr myNewPtrCritical(Size len) { Ptr tempPtr; tempPtr = NewPtrClear(len); return tempPtr; } OSErr mySetHandleSize (Handle handle, Size len) { Size oldLen; OSErr err = noErr; oldLen = GetHandleSize(handle); if (oldLen < len) { if (!MemoryAvailable(len-oldLen)) return memFullErr; } gCritical = FALSE; SetHandleSize(handle, len); gCritical = TRUE; err = MemError(); if (err == memFullErr) { /* The Memory Manager is too stupid to do this itself. */ MoveHHi(handle); CompactMem(maxSize); gCritical = FALSE; SetHandleSize(handle, len); gCritical = TRUE; err = MemError(); } if (err != noErr) return err; if (oldLen >= len) return noErr; if (MemoryAvailable(0)) return noErr; SetHandleSize(handle, oldLen); return memFullErr; } OSErr MySetHandleSizeCritical (Handle handle, Size len) { SetHandleSize(handle, len); if (MemError() == memFullErr) { /* The Memory Manager is too stupid to do this itself. */ MoveHHi(handle); CompactMem(maxSize); SetHandleSize(handle, len); } return MemError(); } \ No newline at end of file diff --git a/source/main/menuseg.c b/source/main/menuseg.c index 10b8734..952593a 100755 --- a/source/main/menuseg.c +++ b/source/main/menuseg.c @@ -1 +1 @@ -// menuseg.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* * Menu Handling and initialization code. * * * Revisions: * 7/92 Telnet 2.6 initial version: reorganized defines, put all stray globals in a struct, and * put all cursors in a nice array. Moved some routines to other places - Scott Bulmahn * * 6/94 Added support for Keypad and Function menus - Carl Bell (Baylor U.) */ #ifdef MPW #pragma segment 4 #endif #include "wind.h" #include "menuseg.proto.h" #include "mainseg.proto.h" #include "Sets.proto.h" /* JMB: For Saved Sets functions */ #include "configure.proto.h" #include "parse.proto.h" #include "InternalEvents.h" #include "mydnr.proto.h" #include "rsinterf.proto.h" #include "network.proto.h" #include "maclook.proto.h" #include "vrrgmac.proto.h" #include "rgmp.proto.h" #include "tekrgmac.proto.h" #include "vgtek.proto.h" #include "netevent.proto.h" #include "Connections.proto.h" #include "tnae.h" #include "authencrypt.proto.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "otp.proto.h" #include "event.proto.h" #include "macros.proto.h" #include "DlogUtils.proto.h" /* For VersionNumber, OutlineItem, and DialogProc Protos */ #include "telneterrors.h" #include #include "printing.proto.h" #include "menuseg.proto.h" #include "translate.proto.h" #include "parse.proto.h" // For SendNAWSinfo proto #include "keypadmenus.proto.h" #include "LinkedList.proto.h" #include "movableModal.h" MenuHandle myMenus[NMENUS]; /* Menu Handles .... */ static short lastMenyCommandKeys = -1; //whether last menu set had command keys //char *tempspot; /* temporary storage ~255 bytes malloc-ed */ /* * External variable declarations (those which we borrow ) * */ extern short scrn; extern Cursor *theCursors[]; extern WindRec *screens, /* The screen array from Maclook */ *ftplog; /* The FTP log screen from Maclook */ extern short nNational; void CloseCaptureFile(short w) { VSclosecapture(w); /* BYU 2.4.18 */ CheckItem(myMenus[Emul], EMcapture,FALSE); /* BYU 2.4.18 */ } /* portsOpen() - Count the number of ports open. Returns 3 different answers * 0= no ports at all, 1= at least active, -1= ports/none active. */ short portsOpen(void) { short pnum; pnum=TelInfo->numwindows-1; if (pnum<0) return(0); while (pnum>=0) // if (!screens[pnum--].active && !screens[pnum+1].corpse) return(1); // corpse status now part of active flag if (screens[pnum--].active == CNXN_ACTIVE) return(1); return(-1); } void switchToOptionMenus(Boolean useOptionedStuff) { Str255 theMenuItem; short whichString; if (useOptionedStuff) whichString = CLOSE_ALL_MENU_ITEM; else whichString = CLOSE_MENU_ITEM; GetIndString(theMenuItem,MISC_STRINGS,whichString); SetItem(myMenus[Fil],FLclose,theMenuItem); } void switchToShiftMenus(Boolean useShiftStuff) { Str255 theMenuItem; short whichString; if (useShiftStuff) whichString = PREVIOUS_SESSION_STRING; else whichString = NEXT_SESSION_STRING; GetIndString(theMenuItem,MISC_STRINGS,whichString); SetItem(myMenus[Conn],COnext,theMenuItem); } void AdjustMenus(void) { short i; WindowPtr wind; if ((wind = FrontWindow()) != NULL && ((((WindowPeek)wind)->windowKind >= userKind) || (((WindowPeek)wind)->windowKind == dialogKind))) EnableItem( myMenus[Fil],FLclose); else DisableItem( myMenus[Fil],FLclose); if ((i=portsOpen()) <1) { DisableItem( myMenus[Fil],FLsave); DisableItem( myMenus[Fil],FLsavem); DisableItem( myMenus[Fil],FLprint); DisableItem( myMenus[Fil],FLselect); DisableItem( myMenus[Fil],FLupload); DisableItem( myMenus[Edit],EDcut); DisableItem( myMenus[Edit],EDundo); DisableItem( myMenus[Edit],EDclear); DisableItem( myMenus[Edit],EDcopy); DisableItem( myMenus[Edit],EDretype); DisableItem( myMenus[Edit],EDcopyt); #if 0 // RAB BetterTelnet 1.0fc8 DisableItem( myMenus[Emul],EMbs); DisableItem( myMenus[Emul],EMdel); DisableItem( myMenus[Emul],EMecho); DisableItem( myMenus[Emul],EMwrap); DisableItem( myMenus[Emul],EMcrmap); DisableItem( myMenus[Emul],EMmapkeypad); DisableItem( myMenus[Emul],EMansi); DisableItem( myMenus[Emul],EMxterm); DisableItem( myMenus[Emul],EMmapd); DisableItem( myMenus[Emul],EMbold); DisableItem( myMenus[Emul],EMboldcolor); DisableItem( myMenus[Emul],EMbeep); DisableItem( myMenus[Emul],EMeightbit); DisableItem( myMenus[Emul],EMscroll); DisableItem( myMenus[Emul],EMreset); DisableItem ( myMenus[Emul],EMjump); DisableItem ( myMenus[Emul],EMpage); DisableItem ( myMenus[Emul],EMclear); /* BYU 2.4.14 */ DisableItem ( myMenus[Emul],EMscreensize); DisableItem ( myMenus[Emul],EMsetup); DisableItem ( myMenus[Emul],EMfont); DisableItem ( myMenus[Emul],EMsize); DisableItem ( myMenus[Emul],EMcolor); DisableItem ( myMenus[Emul],EMAnsiColor); DisableItem ( myMenus[Emul],EMcapture); /* BYU 2.4.18 */ DisableItem ( myMenus[Emul],EMqprint); #endif DisableItem ( myMenus[Emul],0); // RAB BetterTelnet 1.0fc8 DisableItem( myMenus[Net ],NEftp); DisableItem( myMenus[Net ],NEip); DisableItem( myMenus[Net ],NEayt); DisableItem( myMenus[Net ],NEao); DisableItem( myMenus[Net ],NEinter); DisableItem( myMenus[Net ],NEipsync); DisableItem( myMenus[Net ],NEsync); DisableItem( myMenus[Net ],NEbrk); DisableItem( myMenus[Net ],NEec); DisableItem( myMenus[Net ],NEel); DisableItem( myMenus[Net ],NEscroll); if (TelInfo->ScrlLock) { TelInfo->ScrlLock=0; CheckItem(myMenus[Net ], NEscroll,FALSE); } } else { EnableItem ( myMenus[Fil],FLsave); EnableItem ( myMenus[Fil],FLsavem); EnableItem ( myMenus[Fil],FLupload); EnableItem ( myMenus[Emul],0); // RAB BetterTelnet 1.0fc8 #if 0 // RAB BetterTelnet 1.0fc8 EnableItem ( myMenus[Emul],EMbs); EnableItem ( myMenus[Emul],EMdel); EnableItem ( myMenus[Emul],EMecho); EnableItem ( myMenus[Emul],EMwrap); EnableItem ( myMenus[Emul],EMcrmap); EnableItem ( myMenus[Emul],EMansi); EnableItem ( myMenus[Emul],EMxterm); EnableItem ( myMenus[Emul],EMmapd); EnableItem ( myMenus[Emul],EMbold); EnableItem ( myMenus[Emul],EMbeep); EnableItem ( myMenus[Emul],EMboldcolor); EnableItem ( myMenus[Emul],EMeightbit); EnableItem ( myMenus[Emul],EMmapkeypad); #endif if (nNational > 0) { EnableItem ( myMenus[National], 0); } #if 0 EnableItem ( myMenus[Emul],EMscroll); EnableItem ( myMenus[Emul],EMreset); EnableItem ( myMenus[Emul],EMjump); EnableItem ( myMenus[Emul],EMpage); EnableItem ( myMenus[Emul],EMclear); /* BYU 2.4.14 */ EnableItem ( myMenus[Emul],EMscreensize); EnableItem ( myMenus[Emul],EMsetup); EnableItem ( myMenus[Emul],EMfont); EnableItem ( myMenus[Emul],EMsize); EnableItem ( myMenus[Emul],EMcapture); /* BYU 2.4.18 */ EnableItem ( myMenus[Emul],EMqprint); #endif if (TelInfo->haveColorQuickDraw) { EnableItem ( myMenus[Emul],EMcolor); EnableItem ( myMenus[Emul],EMAnsiColor); } else { DisableItem ( myMenus[Emul],EMcolor); DisableItem ( myMenus[Emul],EMAnsiColor); } EnableItem ( myMenus[Net ],NEftp); EnableItem ( myMenus[Net ],NEip); EnableItem ( myMenus[Net ],NEayt); EnableItem ( myMenus[Net ],NEao); EnableItem ( myMenus[Net ],NEinter); EnableItem ( myMenus[Net ],NEipsync); EnableItem ( myMenus[Net ],NEbrk); EnableItem ( myMenus[Net ],NEsync); EnableItem ( myMenus[Net ],NEec); EnableItem ( myMenus[Net ],NEel); EnableItem ( myMenus[Net ],NEscroll); } if (TelInfo->macrosModeless) if (FrontWindow() == TelInfo->macrosModeless) { EnableItem(myMenus[Edit],EDcut); EnableItem(myMenus[Edit],EDcopy); EnableItem(myMenus[Edit],EDpaste); EnableItem(myMenus[Edit],EDclear); } } /* switchMenus( which) - Switch from our current menus to the key menus (1) * or the normal menus (0). */ void switchMenus(short which, short force) { short i; Str255 theMenuItem; if ((lastMenyCommandKeys != which) || force) { lastMenyCommandKeys = which; DeleteMenu( fileMenu); /* Take them from the menu bar */ DeleteMenu( editMenu); DeleteMenu( termMenu); DeleteMenu( netMenu); DeleteMenu( keyMenu); /* Baylor */ DeleteMenu( funcMenu); /* Baylor */ DeleteMenu(NfileMenu); DeleteMenu(NeditMenu); DeleteMenu(NtermMenu); DeleteMenu(NnetMenu); if (which) { myMenus[Fil ] = GetMenu(NfileMenu); myMenus[Edit] = GetMenu(NeditMenu); myMenus[Emul] = GetMenu(NtermMenu); myMenus[Net ] = GetMenu(NnetMenu ); myMenus[Keypad] = GetMenu(keyMenu); /* Baylor */ myMenus[Function] = GetMenu(funcMenu); /* Baylor */ DelMenuItem(myMenus[Conn],COnext); InsMenuItem(myMenus[Conn],(StringPtr)"\017Next Session/N\0",0); GetIndString(theMenuItem, MISC_STRINGS, NEXT_SESSION_STRING); SetItem(myMenus[Conn],COnext,theMenuItem); } else { myMenus[Fil ] = GetMenu(fileMenu); myMenus[Edit] = GetMenu(editMenu); myMenus[Emul] = GetMenu(termMenu); myMenus[Net ] = GetMenu( netMenu); myMenus[Keypad] = GetMenu(keyMenu); /* Baylor */ myMenus[Function] = GetMenu(funcMenu); /* Baylor */ DelMenuItem(myMenus[Conn],COnext); InsMenuItem(myMenus[Conn],(StringPtr)"\015Next Session\0",0); GetIndString(theMenuItem, MISC_STRINGS, NEXT_SESSION_STRING); SetItem(myMenus[Conn],COnext,theMenuItem); } } for(i=1; iKeyPadAndFuncMenus) { /* Baylor */ InsertMenu(myMenus[Keypad], 0); /* Baylor */ InsertMenu(myMenus[Function], 0); /* Baylor */ } AdjustMenus(); /* Hilite the right stuff */ if (TelInfo->MacBinary) CheckItem(myMenus[Fil],FLbin,TRUE); /* Check MacBinary ... */ else CheckItem(myMenus[Fil],FLbin,FALSE); if (TelInfo->ftplogon) CheckItem(myMenus[Fil],FLlog,TRUE); /* and the log .... */ else CheckItem(myMenus[Fil],FLlog,FALSE); if (TelInfo->ScrlLock) /* and the Suspend network ... */ CheckItem(myMenus[Net], NEscroll,TRUE); else CheckItem(myMenus[Net], NEscroll,FALSE); if (TelInfo->numwindows>0) /* and set the BSDEL flag */ CheckItem(myMenus[Emul], EMbs+screens[scrn].bsdel,FALSE); DrawMenuBar(); /* Draw what we have done */ SetupOpSpecSubmenu(myMenus[OpSpec]); if (!TelInfo->haveColorQuickDraw) DisableItem( myMenus[Emul], EMcolor); } /* setupmenu - Set up (load) all menus and prepare menu bar. * set default check marks. */ void setupmenu(short def, DialogPtr startupBox) { short scratchshort, i; Str255 scratchPstring; lastMenyCommandKeys = def; myMenus[0] = GetMenu(appleMenu); /* Get all of our friendly menus */ myMenus[Conn] = GetMenu(connMenu); myMenus[Font] = GetMenu(fontMenu); myMenus[FontOther] = GetMenu(fontMenu2); // RAB BetterTelnet 1.0.1 myMenus[Sizem] = GetMenu(sizeMenu); myMenus[OpSpec] = GetMenu(opspecMenu); myMenus[PrefsSub] = GetMenu(prefsMenu); myMenus[National] = GetMenu(transMenu); myMenus[Keypad] = GetMenu(keyMenu); /* Baylor */ myMenus[Function] = GetMenu(funcMenu); /* Baylor */ myMenus[Fil ] = GetMenu(NfileMenu); myMenus[Edit] = GetMenu(NeditMenu); myMenus[Emul] = GetMenu(NtermMenu); myMenus[Net ] = GetMenu(NnetMenu ); AddResMenu(myMenus[0], 'DRVR'); /* Add in the DA's */ InsertMenu(myMenus[0], 0); /* Insert the Menus into the bar */ InsertMenu(myMenus[OpSpec], 0); InsertMenu(myMenus[Conn], 0); if (gApplicationPrefs->KeyPadAndFuncMenus) { /* Baylor */ InsertMenu(myMenus[Keypad], 0); /* Baylor */ InsertMenu(myMenus[Function], 0); /* Baylor */ } InsertMenu(myMenus[Font], -1); InsertMenu(myMenus[FontOther], -1); InsertMenu(myMenus[Sizem], -1); // InsertMenu(myMenus[OpSpec], -1); InsertMenu(myMenus[National], -1); InsertMenu(myMenus[PrefsSub], -1); if (!gApplicationPrefs->monospacedOut) AddResMenu(myMenus[Font], 'FONT'); /* Put the fonts in the font menu */ else addMonoSpacedFonts(myMenus[Font], startupBox); scratchshort = CountMItems(myMenus[Font]); for (i = 1; i <= scratchshort; i++) // RAB BetterTelnet 1.0.1 { GetItem(myMenus[Font],i,scratchPstring); AppendMenu(myMenus[FontOther],scratchPstring); } SetupOpSpecSubmenu(myMenus[OpSpec]); switchMenus(def, 0); } void addMonoSpacedFonts(MenuHandle theMenu, DialogPtr startupBox) { Boolean doItAll = FALSE; Handle theGoodFonts, theBadFonts; short numGoodFonts, numBadFonts,numFontsInMenu; short menuIndex; Str255 fontListName,currentFontName; //here begins the caching of fonts to save time caculating proportionality UseResFile(TelInfo->SettingsFile); theGoodFonts = Get1Resource('STR#',4000); //the good fonts if (!theGoodFonts) { UseResFile(TelInfo->ApplicationFile); theGoodFonts = Get1Resource('STR#',4000); theBadFonts = Get1Resource('STR#',5000); DetachResource(theGoodFonts); DetachResource(theBadFonts); UseResFile(TelInfo->SettingsFile); AddResource(theGoodFonts,'STR#',4000,"\pGood Fonts"); AddResource(theBadFonts,'STR#',5000,"\pBad Fonts"); } else theBadFonts = Get1Resource('STR#',5000); redoTheList: numGoodFonts = *(short *)(*theGoodFonts); if (numGoodFonts == 0) doItAll = TRUE; //we haven't created a list of fonts yet else numBadFonts = *(short *)(*theBadFonts); AddResMenu(theMenu,'FONT'); //add them all here numFontsInMenu = CountMItems(theMenu); if (numFontsInMenu != (numBadFonts + numGoodFonts)) { SetHandleSize(theGoodFonts,2); *((short *)*theGoodFonts) = 0; SetHandleSize(theBadFonts,2); *((short *)*theBadFonts) = 0; doItAll = TRUE; } if (!doItAll) //we have a list already { short goodFontIndex, badFontIndex; goodFontIndex = badFontIndex = 1; for (menuIndex = 1; menuIndex <= numFontsInMenu; menuIndex++) { //look at each font, see if its bad, good, or new GetItem(theMenu,menuIndex,currentFontName); GetIndString(fontListName,5000,badFontIndex); if (EqualString(currentFontName,fontListName,TRUE,FALSE)) { DelMenuItem(theMenu,menuIndex); //remove the bad font from the menu numFontsInMenu--; menuIndex--; badFontIndex++; } else { GetIndString(fontListName,4000,goodFontIndex); if (EqualString(currentFontName,fontListName,TRUE,FALSE)) goodFontIndex++; else //its a new font, and we didn't expect it; this means there were an equal { //number of fonts removed and added. Lets start over. short numberInMenu; numberInMenu = CountMItems(theMenu); for (;numberInMenu > 0; numberInMenu--) DelMenuItem(theMenu,numberInMenu);//clear the menu SetHandleSize(theGoodFonts,2);//clear the lists SetHandleSize(theBadFonts,2); goto redoTheList; } } } } else //create a new list { Str255 stemp; // DialogPtr dtemp; // dtemp = GetNewMyDialog(130, NULL, kInFront, (void *)SecondThirdCenterDialog); /* opening dialog */ // DrawDialog(dtemp); GetIndString(stemp, MISC_STRINGS, REBUILDING_FONT_MENU); SetTEText(startupBox, 3, stemp); for (menuIndex = 1; menuIndex <= numFontsInMenu; menuIndex++) { GetItem(theMenu,menuIndex,currentFontName); if (!isMonospacedFont(currentFontName)) { DelMenuItem(theMenu,menuIndex); //remove the bad font from the menu numFontsInMenu--; menuIndex--; PtrAndHand(currentFontName,theBadFonts,currentFontName[0]+1);//add it to the bad list (*(short *)(*theBadFonts))++; } else { PtrAndHand(currentFontName,theGoodFonts,currentFontName[0]+1);//add it to the good list (*(short *)(*theGoodFonts))++; } } // DisposDialog(dtemp); } ChangedResource(theGoodFonts); ChangedResource(theBadFonts); ReleaseResource(theGoodFonts); ReleaseResource(theBadFonts); UpdateResFile(TelInfo->SettingsFile); } Boolean isMonospacedFont(Str255 theFont) { Boolean haveNonRomanScripts,thisOneIsMonospaced = FALSE, doRomanTest = FALSE; short fond; long tempLong; //GrafPtr tempPort, savedPort; //first, open a temporary port to test CharWidth //tempPort = (GrafPtr)myNewPtrCritical(sizeof(GrafPort)); //GetPort(&savedPort); //OpenPort(tempPort); tempLong = GetScriptManagerVariable(smEnabled); //this returns number of scripts enable haveNonRomanScripts = (tempLong > 1); //if there is one, its roman GetFNum(theFont,&fond); if (haveNonRomanScripts) { long thisScriptEnabled; ScriptCode scriptNumber; scriptNumber = FontToScript(fond); if (scriptNumber != 0) //if its non-roman { thisScriptEnabled = GetScriptVariable(scriptNumber,smScriptEnabled); if (thisScriptEnabled) { //check if this font is the preferred monospaced font for its script long theSizeAndFond; short thePreferredFond; theSizeAndFond = GetScriptVariable(scriptNumber, smScriptMonoFondSize); thePreferredFond = theSizeAndFond >> 16; //high word is fond thisOneIsMonospaced = (thePreferredFond == fond); } else thisOneIsMonospaced = FALSE; //this font's script isn't enabled } else doRomanTest = TRUE; } else doRomanTest = TRUE; if (doRomanTest) { TextFont(fond); thisOneIsMonospaced = (CharWidth('W') == CharWidth('.')); } //SetPort(savedPort); //ClosePort(tempPort); //DisposePtr((Ptr)tempPort); return(thisOneIsMonospaced); } void CheckOpSpecSubmenu(void) { // short numItems; // UseResFile(TelInfo->SettingsFile); // numItems = Count1Resources(SESSIONPREFS_RESTYPE); // if ((CountMItems(myMenus[OpSpec]) - 2) != numItems) SetupOpSpecSubmenu(myMenus[OpSpec]); } void SetupOpSpecSubmenu(MenuHandle theMenu) { short scratchshort,numberofitems; LinkedListNode *theHead; scratchshort = (CountMItems(theMenu) - 2); for (; scratchshort>0; scratchshort--) DelMenuItem(theMenu, scratchshort + 2); UseResFile(TelInfo->SettingsFile); numberofitems = Count1Resources(SESSIONPREFS_RESTYPE); if (numberofitems) { theHead = createSortedList(SESSIONPREFS_RESTYPE,numberofitems,"\p"); //now we have a sorted linked list of the names addListToMenu/*2*/(theMenu, theHead, 3); deleteList(&theHead); } } /* updateMenuChecks() - update the check marks for file transfer * (MacBinary) */ void updateMenuChecks( void) { if (TelInfo->MacBinary) CheckItem(myMenus[Fil],FLbin,TRUE); /* Check MacBinary ... */ else CheckItem(myMenus[Fil],FLbin,FALSE); } /* DisplayMacBinary() - Sets the macbinary check mark according to the MacBinary flag */ void DisplayMacBinary( void) { if (TelInfo->MacBinary) CheckItem(myMenus[Fil],FLbin,TRUE); /* Check MacBinary ... */ else CheckItem(myMenus[Fil],FLbin,FALSE); } /*CheckFonts() - Place checkmarks and outlines on the appropriate * menu items for the fonts */ void CheckFonts(void) { short i, fsiz, fnum; long itemFontSize; Str255 temp, itemString; RSgetboldfont( screens[scrn].vs, &fnum); GetFontName(fnum, temp); for(i=1; i<= CountMItems( myMenus[FontOther]); i++) { GetItem( myMenus[FontOther], i, itemString); if (EqualString(temp, itemString, FALSE, FALSE)) CheckItem( myMenus[FontOther], i, TRUE); /* Check the current font */ else CheckItem( myMenus[FontOther], i, FALSE); } RSgetfont( screens[scrn].vs, &fnum, &fsiz); GetFontName(fnum, temp); for(i=1; i<= CountMItems( myMenus[Font]); i++) { GetItem( myMenus[Font], i, itemString); if (EqualString(temp, itemString, FALSE, FALSE)) CheckItem( myMenus[Font], i, TRUE); /* Check the current font */ else CheckItem( myMenus[Font], i, FALSE); } for(i=1; i<=CountMItems( myMenus[Sizem]); i++) { GetItem( myMenus[Sizem], i, itemString); /* JMB 2.6 -- Much safer to do it */ StringToNum(itemString, &itemFontSize); /* this way! */ if (fsiz == (short)itemFontSize) CheckItem( myMenus[Sizem], i, TRUE); /* Check Our Current Size */ else CheckItem( myMenus[Sizem], i, FALSE); if (RealFont( fnum, (short)itemFontSize)) /* Outline All Available REAL Sizes */ SetItemStyle( myMenus[Sizem], i, outline); else SetItemStyle( myMenus[Sizem], i, 0); } } /* applAbout - display the about dialog for the application.*/ void applAbout( void) { DialogPtr About; short itemhit; About=GetNewMyDialog( AboutDLOG, (Ptr) 0L,(WindowPtr) -1L, (void *)ThirdCenterDialog); if (About) { UItemAssign( About, 2, VersionNumberUPP); ModalDialog(NULL, &itemhit); DisposDialog(About); } } short ReallyClose( short scrn) { DialogPtr dtemp; short item; Str255 scratchPstring; SetCursor(theCursors[normcurs]); GetWTitle(screens[scrn].wind, scratchPstring); ParamText(scratchPstring, NULL, NULL, NULL); dtemp = GetNewMyDialog( CloseDLOG, NULL, kInFront, (void *)ThirdCenterDialog); item = DLOGCancel +1; while (item> DLOGCancel) ModalDialog(DLOGwOK_CancelUPP, &item); DisposDialog( dtemp); updateCursor(1); if (item == DLOGCancel) return(0); return(1); } PicHandle RGtoPICT(short i) { short j; PicHandle tpic; Rect trect; SetRect(&trect,0,0,384,384); j=VGnewwin(TEK_DEVICE_PICTURE,VGgetVS(i)); /* NCSA 2.5: get the right VS */ RGMPsize( &trect ); VGzcpy( i, j); /* Love dat zm factr */ tpic=OpenPicture(&trect); ClipRect(&trect); VGredraw(i,j); ClosePicture(); VGclose(j); return(tpic); } /* * copyGraph - Copy the current graphics screen. * dnum - the number of the drawing to copy . */ void copyGraph( short dnum) { long tlong; /* Temporary Variable */ PicHandle tpic; /* Mental picture of the thing */ tpic=RGtoPICT(dnum); /* Get the picture */ tlong=ZeroScrap(); /* Nobody else can live here */ HLock((Handle) tpic); /* Lock it for Puting */ tlong=PutScrap(GetHandleSize((Handle) tpic),'PICT', (Ptr) *tpic); /* Store as a PICT */ HUnlock((Handle) tpic); /* Unlock so we can toss it */ KillPicture(tpic); /* Kill the picture..... */ } /* * copyText - Copy the current selection on the virtual screen * vs - the number of the virtual screen to copy from */ void copyText( short vs) { char **charh; /* where to store the characters */ long tlong; /* Necessary temporary variable */ tlong=ZeroScrap(); /* This Scrap aint big enough for the both of us */ charh=RSGetTextSel(vs,0); /* Get the text selection */ if (charh == (char **)-1L) OutOfMemory(400); else if (charh != (char **)0L) { /* BYU LSC - Can't do anything without characters */ HLock(charh); /* Lock for putting */ tlong=PutScrap(GetHandleSize(charh),'TEXT',*charh); /* Put it as a TEXT resource */ HUnlock(charh); /* Unlock for disposal */ DisposHandle(charh); /* Kill the chars */ } } /* * copyTable - Copy the current selection on the virtual screen * vs - the number of the virtual screen to copy from */ void copyTable( short vs) { char **charh; /* where to store the characters */ long tlong; /* Necessary temporary variable */ tlong=ZeroScrap(); /* This Scrap aint big enough for the both of us */ charh=RSGetTextSel(vs, gApplicationPrefs->CopyTableThresh); /* Get the text selection */ if (charh>(char **)0L) { /* BYU LSC - Can't do anything without characters */ HLock(charh); /* Lock for putting */ tlong=PutScrap(GetHandleSize(charh),'TEXT',*charh); /* Put it as a TEXT resource */ HUnlock(charh); /* Unlock for disposal */ DisposHandle(charh); /* Kill the chars */ } else putln("No characters to copy darn it!"); } /* * paste - Paste the resource from the scrap into the current WIND, if * and only if it is really text */ void paste( void) { long off, /* offset */ length; /* the lenght of what is on the Scrap */ if (screens[scrn].clientflags & PASTE_IN_PROGRESS) { // One paste at a time, please SysBeep(4); return; } /* Flush the buffer if necessary */ //CCP fix for linemode if (screens[scrn].kblen>0) { netpush(screens[scrn].port); netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen); screens[scrn].kblen=0; } if (GetScrap(0L, 'TEXT', &off)<=0L) /* If there are no TEXT res's */ return; /* then we can't paste it */ screens[scrn].outhand=myNewHandle(0L); /* create a handle to put chars in */ length= GetScrap( screens[scrn].outhand, 'TEXT',&off); /* Store the scrap into the handle */ screens[scrn].outlen = length; /* Set the length */ HLock(screens[scrn].outhand); /* Lock the Handle down for safety */ screens[scrn].outptr=*screens[scrn].outhand; /* Set the pointer */ screens[scrn].clientflags |= PASTE_IN_PROGRESS; screens[scrn].isUploading = 0; screens[scrn].incount = 0; screens[scrn].outcount = 0; trbuf_mac_nat((unsigned char *)screens[scrn].outptr,screens[scrn].outlen, screens[scrn].national); /* LU: translate to national chars */ pasteText( scrn); /* BYU LSC - routine to paste to net, w/echo if neccessary */ } void uploadFile(void) // RAB: routine added in BetterTelnet 1.0fc9 { long length; StandardFileReply sfr; OSErr err; short refNum; if (screens[scrn].clientflags & PASTE_IN_PROGRESS) { // One paste at a time, please SysBeep(4); return; } StandardGetFile(0, -1, 0, &sfr); if (!sfr.sfGood) return; err = FSpOpenDF(&sfr.sfFile, fsCurPerm, &refNum); if (err) return; /* Flush the buffer if necessary */ //CCP fix for linemode if (screens[scrn].kblen>0) { netpush(screens[scrn].port); netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen); screens[scrn].kblen=0; } screens[scrn].outhand=myNewHandle(16384); // for now, upload block is 16K screens[scrn].outptr = *screens[scrn].outhand; HLock(screens[scrn].outhand); /* Lock the Handle down for safety */ length = 16384; FSRead(refNum, &length, screens[scrn].outptr); if (length == 0) { FSClose(refNum); HUnlock(screens[scrn].outhand); DisposeHandle(screens[scrn].outhand); return; } screens[scrn].outlen = length; /* Set the length */ HUnlock(screens[scrn].outhand); SetHandleSize(screens[scrn].outhand, length); // now REALLY set the length HLock(screens[scrn].outhand); screens[scrn].clientflags |= PASTE_IN_PROGRESS; if (length == 16384) { screens[scrn].isUploading = 1; screens[scrn].uploadRefNum = refNum; } else { FSClose(refNum); screens[scrn].isUploading = 0; } screens[scrn].incount = 0; screens[scrn].outcount = 0; trbuf_mac_nat((unsigned char *)screens[scrn].outptr,screens[scrn].outlen, screens[scrn].national); /* LU: translate to national chars */ pasteText(scrn); /* BYU LSC - routine to paste to net, w/echo if neccessary */ } void autoPaste(short vs) // RAB: routine added in BetterTelnet 1.0fc6 { char **charh; if (screens[scrn].clientflags & PASTE_IN_PROGRESS) { // One paste at a time, please SysBeep(4); return; } /* Flush the buffer if necessary */ //CCP fix for linemode if (screens[scrn].kblen>0) { netpush(screens[scrn].port); netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen); screens[scrn].kblen=0; } charh=RSGetTextSel(vs,0); /* Get the text selection */ if (charh == (char **)-1L) OutOfMemory(400); else if (charh != (char **)0L) { /* BYU LSC - Can't do anything without characters */ HLock(charh); screens[scrn].outhand=charh; screens[scrn].outlen = GetHandleSize(charh); /* Set the length */ screens[scrn].outptr=*screens[scrn].outhand; /* Set the pointer */ screens[scrn].clientflags |= PASTE_IN_PROGRESS; screens[scrn].isUploading = 0; screens[scrn].incount = 0; screens[scrn].outcount = 0; trbuf_mac_nat((unsigned char *)screens[scrn].outptr,screens[scrn].outlen, screens[scrn].national); /* LU: translate to national chars */ pasteText( scrn); /* BYU LSC - routine to paste to net, w/echo if neccessary */ } } void displayStatus(short n) { DialogPtr dptr; short item; Str255 scratchPstring,anotherString; SetCursor(theCursors[normcurs]); switch(screens[n].active) { case CNXN_ISCORPSE: GetWTitle(screens[n].wind, scratchPstring); GetIndString(anotherString,MISC_STRINGS,AWAITING_DISMISSAL_STRING); ParamText( scratchPstring, anotherString, NULL, NULL); break; case CNXN_OPENING: GetIndString(anotherString,MISC_STRINGS,BEING_OPENED_STRING); ParamText( screens[n].machine,anotherString, NULL, NULL); break; default: GetIndString(anotherString,MISC_STRINGS,BEING_LOOKED_UP); ParamText( screens[n].machine,anotherString, NULL, NULL); } dptr = GetNewMyDialog( StatusDLOG, NULL, kInFront, (void *)ThirdCenterDialog); item = DLOGCancel+1; while (item > DLOGCancel) ModalDialog(DLOGwOK_CancelUPP, &item); updateCursor(1); if (item == DLOGCancel) { netclose(screens[n].port); destroyport( n); } DisposDialog(dptr); } /* * changeport - handle the menu updates for changing from one port to another */ void changeport(short oldprt, short newprt) { //sprintf(tempspot,"oldscrn: %d, newscrn: %d",oldprt,newprt); putln(tempspot); if (screens[oldprt].active == CNXN_ACTIVE) CheckItem(myMenus[Conn], oldprt + FIRST_CNXN_ITEM, FALSE); /* Adjust Conn menu */ CheckItem(myMenus[Conn], newprt + FIRST_CNXN_ITEM, TRUE); CheckItem(myMenus[Emul], EMbs,FALSE); /* Adjust BS */ CheckItem(myMenus[Emul], EMdel,FALSE); CheckItem(myMenus[Emul], EMbs+screens[newprt].bsdel,TRUE); /* and DEL */ if (screens[newprt].tektype < 0) { // TEK is inhibited DisableItem(myMenus[Emul],EMclear); DisableItem(myMenus[Emul],EMpage); } else { EnableItem(myMenus[Emul],EMclear); EnableItem(myMenus[Emul],EMpage); if (screens[newprt].tekclear) /* BYU 2.4.8 */ CheckItem(myMenus[Emul],EMclear,TRUE); /* BYU 2.4.8 */ else /* BYU 2.4.8 */ CheckItem(myMenus[Emul],EMclear,FALSE); /* BYU 2.4.8 */ } if (screens[newprt].ESscroll) CheckItem(myMenus[Emul],EMscroll,TRUE); else CheckItem(myMenus[Emul],EMscroll,FALSE); if (screens[newprt].echo) /* LOCAL ECHO */ CheckItem(myMenus[Emul],EMecho,TRUE); else /* REMOTE ECHO */ CheckItem(myMenus[Emul],EMecho,FALSE); if (screens[newprt].wrap) /* wrap on */ CheckItem(myMenus[Emul],EMwrap,TRUE); else /* wrap off */ CheckItem(myMenus[Emul],EMwrap,FALSE); if (screens[newprt].crmap) CheckItem(myMenus[Emul],EMcrmap,TRUE); else CheckItem(myMenus[Emul],EMcrmap,FALSE); if (screens[newprt].ANSIgraphics) CheckItem(myMenus[Emul],EMansi,TRUE); else CheckItem(myMenus[Emul],EMansi,FALSE); if (screens[newprt].Xterm) CheckItem(myMenus[Emul],EMxterm,TRUE); else CheckItem(myMenus[Emul],EMxterm,FALSE); if (screens[newprt].remapCtrlD) CheckItem(myMenus[Emul],EMmapd,TRUE); else CheckItem(myMenus[Emul],EMmapd,FALSE); if (screens[newprt].allowBold) CheckItem(myMenus[Emul],EMbold,TRUE); else CheckItem(myMenus[Emul],EMbold,FALSE); if (screens[newprt].colorBold) CheckItem(myMenus[Emul],EMboldcolor,TRUE); else CheckItem(myMenus[Emul],EMboldcolor,FALSE); if (screens[newprt].ignoreBeeps) CheckItem(myMenus[Emul],EMbeep,TRUE); else CheckItem(myMenus[Emul],EMbeep,FALSE); if (screens[newprt].inversebold) CheckItem(myMenus[Emul],EMinverse,TRUE); else CheckItem(myMenus[Emul],EMinverse,FALSE); if (screens[newprt].qprint) CheckItem(myMenus[Emul],EMqprint,TRUE); else CheckItem(myMenus[Emul],EMqprint,FALSE); if (screens[newprt].ignoreff) CheckItem(myMenus[Emul],EMff,TRUE); else CheckItem(myMenus[Emul],EMff,FALSE); if (screens[newprt].eightbit) CheckItem(myMenus[Emul],EMeightbit,TRUE); else CheckItem(myMenus[Emul],EMeightbit,FALSE); if (screens[newprt].keypadmap) CheckItem(myMenus[Emul],EMmapkeypad,TRUE); else CheckItem(myMenus[Emul],EMmapkeypad,FALSE); if (VSiscapturing(screens[newprt].vs)) /* BYU 2.4.18 */ CheckItem(myMenus[Emul], EMcapture,TRUE); /* BYU 2.4.18 */ else /* BYU 2.4.18 */ CheckItem(myMenus[Emul], EMcapture,FALSE); /* BYU 2.4.18 */ if (screens[newprt].arrowmap) /* JMB */ CheckItem(myMenus[Emul],EMarrowmap, TRUE); /* JMB */ else /* JMB */ CheckItem(myMenus[Emul],EMarrowmap, FALSE); /* JMB */ if (screens[newprt].pgupdwn) /* JMB */ CheckItem(myMenus[Emul],EMpgupdwn, TRUE); /* JMB */ else /* JMB */ CheckItem(myMenus[Emul],EMpgupdwn, FALSE); /* JMB */ scrn=newprt; CheckFonts(); CheckNational(screens[newprt].national); } // Returns TRUE if the user cancelled the quit Boolean HandleQuit(void) { short i; Boolean liveConnections = FALSE, die = TRUE; if (TelInfo->numwindows>0) { for(i = 0; i < MaxSess; i++) { if ((screens[i].active == CNXN_ACTIVE)||(screens[i].active == CNXN_OPENING)) liveConnections = TRUE; } if (liveConnections) if (!gApplicationPrefs->dontWarnOnQuit) die = AskUserAlert(REALLY_QUIT_QUESTION, FALSE); if (die) { for (i = TelInfo->numwindows - 1; i >= 0; i--) { netclose(screens[i].port); destroyport(i); } } else return (TRUE); } if (gApplicationPrefs->destroyKTickets) DestroyTickets(); quit(); return (FALSE); } /* * HandleMenuCommand - preform a command denoted by the arguments. * mResult - the result of the menu event * modifiers- modifiers from the menu event */ void HandleMenuCommand( long mResult, short modifiers) { register short i; short theItem, theMenu; Boolean doWrap; theMenu = mResult >> 16; theItem = mResult & 0xffff; switch(theMenu) { case appleMenu: if (theItem==1) /* About Dialog */ applAbout(); else { Str255 name; GetItem(myMenus[0], theItem, name); /* Desk accessory */ OpenDeskAcc(name); } break; case fileMenu: case NfileMenu: switch(theItem) { case FLopen: PresentOpenConnectionDialog(); /* Open a connection */ break; case FLclose: /* Close a connection */ if (!FrontWindow()) break; // RAB BetterTelnet 1.2 - bug fix if (!(modifiers & optionKey)) CloseAWindow(FrontWindow()); else { Boolean die = TRUE; if (numberLiveConnections()) die = AskUserAlert(CLOSE_ALL_WINDOWS_Q, FALSE); if (die) { for (i = TelInfo->numwindows - 1; i >= 0; i--) { netclose(screens[i].port); destroyport(i); } } else break; } break; case FLload: /* Load a set */ LoadSet(); break; case FLsave: /* Save a set */ if (TelInfo->numwindows<1) break; SaveSet(0, (modifiers & optionKey)); break; case FLsavem: if (TelInfo->numwindows<1) break; SaveSet(1, (modifiers & optionKey)); break; case FLbin: /* Toggle MacBinary on/off */ TelInfo->MacBinary = !TelInfo->MacBinary; if (TelInfo->MacBinary) { CheckItem(myMenus[Fil], FLbin,TRUE); } else { CheckItem(myMenus[Fil], FLbin,FALSE); } break; case FLlog: /* Toggle FTP window on/off*/ TelInfo->ftplogon=!TelInfo->ftplogon; if(TelInfo->ftplogon) { CheckItem(myMenus[Fil],FLlog,TRUE); RSshow(ftplog->vs); SelectWindow(ftplog->wind); } else { CheckItem(myMenus[Fil],FLlog,FALSE); RShide(ftplog->vs); } break; case FLotp: otpinterface(0, 0, 0, 0, 0, 0, 0); break; case FLprint: /* Print Selection (or gr) */ PrintSelection(); break; case FLselect: SaveSelectionToFile(); break; case FLupload: if (TelInfo->numwindows<1) break; uploadFile(); break; case FLpset: /* Set up for printer */ PrintPageSetup(); break; case FLquit: (void) HandleQuit(); break; } break; case editMenu: case NeditMenu: if (!SystemEdit(theItem-1)) { /* Is this mine? */ switch(theItem) { case EDcopy: /* Copy */ i = MacRGfindwind(FrontWindow()); /* is ICR window? */ if (i >= 0) MacRGcopy(FrontWindow()); /* copy the ICR window */ else { i=RGgetdnum(FrontWindow()); if (i>-1) /* Copy Graphics */ copyGraph( i); else /* Copy Text */ if ( (i=RSfindvwind(FrontWindow())) >-1) copyText( i); } break; case EDcopyt: /* Copy Table */ /* * tech note #180 trick to get MultiFinder to pay attention */ if (!SystemEdit(EDcopy-1)) { /* tell it we did a copy */ i=RGgetdnum(FrontWindow()); if (i>-1) /* Copy Graphics */ copyGraph( i); else /* Copy Text */ if ( (i=RSfindvwind(FrontWindow())) >-1) copyTable( i); } break; case EDpaste: /* Paste */ if (TelInfo->numwindows<1) break; else paste(); /* Paste if there is a wind to do to*/ break; case EDretype: if (TelInfo->numwindows<1) break; i = MacRGfindwind(FrontWindow()); /* is ICR window? */ if (i >= 0) break; else { i=RGgetdnum(FrontWindow()); if (i>-1) /* Copy Graphics */ break; else /* Copy Text */ if ( (i=RSfindvwind(FrontWindow())) >-1) autoPaste( i); } break; case EDmacros: /* Set them Macros */ Macros(); break; case EDmacros+2: Cenviron(); break; case EDmacros+5: Cftp(); break; case EDmacros+4: EditConfigType(SESSIONPREFS_RESTYPE, &EditSession); CheckOpSpecSubmenu(); break; case EDmacros+3: EditConfigType(TERMINALPREFS_RESTYPE, &EditTerminal); break; case EDmacros+6: EditConfigType(FTPUSER, &EditFTPUser); default: break; } } break; case connMenu: case NconnMenu: if (theItem == COnext) { if (TelInfo->numwindows >1) { short scratchshort; if (!(modifiers & shiftKey)) //go forward { scratchshort = WindowPtr2ScreenIndex(FrontWindow()) + 1; // Skip over inactive connections while( (screens[scratchshort].active != CNXN_ACTIVE) && (screens[scratchshort].active != CNXN_ISCORPSE) && (scratchshort <= TelInfo->numwindows+1)) scratchshort++; if ((scratchshort < 0) || (scratchshort >= TelInfo->numwindows)) scratchshort = 0; } else //go backward { scratchshort = WindowPtr2ScreenIndex(FrontWindow()) - 1; // Skip over inactive connections while( (screens[scratchshort].active != CNXN_ACTIVE) && (screens[scratchshort].active != CNXN_ISCORPSE) && (scratchshort >= 0)) scratchshort--; if ((scratchshort < 0) || (scratchshort >= TelInfo->numwindows)) scratchshort = TelInfo->numwindows - 1; } SelectWindow(screens[scratchshort].wind); } break; } if (theItem == COtitle) { ChangeWindowName(FrontWindow()); break; } if (theItem >= FIRST_CNXN_ITEM) { if ((theItem - FIRST_CNXN_ITEM-1)>(TelInfo->numwindows+1)) break; /* rotten danish */ if (screens[theItem - FIRST_CNXN_ITEM].active != CNXN_ACTIVE) { displayStatus(theItem - FIRST_CNXN_ITEM); /* Tell them about it..... */ break; } else { HiliteWindow(screens[scrn].wind, FALSE); changeport(scrn,(theItem - FIRST_CNXN_ITEM)); if (!(modifiers & optionKey)) SelectWindow(screens[scrn].wind); else HiliteWindow(screens[scrn].wind, TRUE); } } break; case netMenu: case NnetMenu: switch(theItem) { case NEftp: /* Send FTP command */ case NEip: /* Send IP Number */ if (TelInfo->numwindows<1) break; { char tmpout[30]; /* Basically the same except for */ unsigned char tmp[4]; /* The ftp -n phrase in NEftp */ if (screens[scrn].echo && (screens[scrn].kblen>0)) { netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen);/* if not empty send buffer */ screens[scrn].kblen=0; } netgetip(tmp); if (theItem == NEftp) { if ((gFTPServerPrefs->ServerState == 1) && !(modifiers & shiftKey)) sprintf(tmpout,"ftp -n %d.%d.%d.%d\015\012",tmp[0],tmp[1],tmp[2],tmp[3]); else sprintf(tmpout,"ftp %d.%d.%d.%d\015\012",tmp[0],tmp[1],tmp[2],tmp[3]); } else sprintf(tmpout,"%d.%d.%d.%d",tmp[0],tmp[1],tmp[2],tmp[3]); netwrite(screens[scrn].port,tmpout,strlen(tmpout)); if (screens[scrn].echo) VSwrite(screens[scrn].vs,tmpout, strlen(tmpout)); } break; case NEayt: /* Send "Are You There?"*/ if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\366",2); break; case NEao: /* Send "Abort Output"*/ if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\365",2); screens[ scrn].timing = 1; /* set emulate to TMwait */ netwrite(screens[scrn].port, "\377\375\006",3); /* send TM */ break; case NEinter: /* Send "Interrupt Process"*/ if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\364",2); screens[ scrn].timing = 1; /* set emulate to TMwait */ netwrite(screens[scrn].port, "\377\375\006",3); /* send TM */ break; case NEbrk: if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\363",2); // IAC BRK break; case NEsync: if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netUrgent(); // This must be sent TCP Urgent. netwrite(screens[scrn].port, "\377\362",2); // IAC DM break; case NEipsync: if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\364", 2); // IAC IP netpush(screens[scrn].port); netUrgent(); // This must also be sent TCP Urgent. netwrite(screens[scrn].port, "\377\362", 2); // IAC DM netpush(screens[scrn].port); screens[scrn].timing = 1; // set emulate to TMwait netwrite(screens[scrn].port, "\377\375\006", 3); // send Timing Mark break; case NEec: /* Send "Erase Character"*/ if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\367",2); break; case NEel: /* Send "Erase Line"*/ if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\370",2); break; case NEscroll: /* Suspend Network */ TelInfo->ScrlLock=!TelInfo->ScrlLock; if (TelInfo->ScrlLock) CheckItem(myMenus[Net], NEscroll,TRUE); else CheckItem(myMenus[Net], NEscroll,FALSE); break; case NEnet: /* Show Network Numbers */ showNetNumbers(); break; default: break; } break; case termMenu: case NtermMenu: switch(theItem) { case EMbs: /* Backspace for backspace */ if (TelInfo->numwindows<1) break; CheckItem(myMenus[Emul], EMbs+screens[scrn].bsdel,FALSE); screens[scrn].bsdel=0; CheckItem(myMenus[Emul], EMbs+screens[scrn].bsdel,TRUE); break; case EMdel: /* Delete for backspace */ if (TelInfo->numwindows<1) break; CheckItem(myMenus[Emul], EMbs+screens[scrn].bsdel,FALSE); screens[scrn].bsdel=1; CheckItem(myMenus[Emul], EMbs+screens[scrn].bsdel,TRUE); break; case EMecho: /* Toggle Local Echo (if poss.) */ if (TelInfo->numwindows < 1) break; if (screens[scrn].echo && (screens[scrn].kblen>0)) { netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen); /* if not empty send buffer */ screens[scrn].kblen=0; } screens[scrn].echo= !screens[scrn].echo; /* toggle */ if (screens[scrn].echo) { /* LOCAL ECHO */ if (!(modifiers & optionKey)) send_dont(screens[scrn].port,1); CheckItem(myMenus[Emul],EMecho,TRUE); } else { /* REMOTE ECHO */ if (!(modifiers & optionKey)) send_do(screens[scrn].port,1); CheckItem(myMenus[Emul],EMecho,FALSE); } break; case EMwrap: /* wrap mode */ if (TelInfo->numwindows < 1) break; if (!screens[scrn].wrap) { /* is off, turn on */ screens[scrn].wrap = 1; CheckItem( myMenus[Emul],EMwrap, TRUE); VSwrite(screens[scrn].vs, "\033[?7h",5); /* kick emulator */ } else { screens[scrn].wrap = 0; CheckItem( myMenus[Emul],EMwrap, FALSE); VSwrite(screens[scrn].vs, "\033[?7l",5); } break; case EMarrowmap: /* JMB */ if (TelInfo->numwindows < 1) break; /* JMB */ screens[scrn].arrowmap = !screens[scrn].arrowmap; /* JMB */ if (screens[scrn].arrowmap) /* JMB */ CheckItem( myMenus[Emul], EMarrowmap, TRUE); /* JMB */ else /* JMB */ CheckItem( myMenus[Emul], EMarrowmap, FALSE); /* JMB */ break; /* JMB */ case EMcrmap: if (TelInfo->numwindows < 1) break; screens[scrn].crmap = !screens[scrn].crmap; if (screens[scrn].crmap) CheckItem( myMenus[Emul], EMcrmap, TRUE); else CheckItem( myMenus[Emul], EMcrmap, FALSE); break; case EMansi: if (TelInfo->numwindows < 1) break; screens[scrn].ANSIgraphics = !screens[scrn].ANSIgraphics; if (screens[scrn].ANSIgraphics) CheckItem( myMenus[Emul], EMansi, TRUE); else CheckItem( myMenus[Emul], EMansi, FALSE); break; case EMxterm: if (TelInfo->numwindows < 1) break; screens[scrn].Xterm = !screens[scrn].Xterm; if (screens[scrn].Xterm) CheckItem( myMenus[Emul], EMxterm, TRUE); else CheckItem( myMenus[Emul], EMxterm, FALSE); break; case EMmapd: if (TelInfo->numwindows < 1) break; screens[scrn].remapCtrlD = !screens[scrn].remapCtrlD; if (screens[scrn].remapCtrlD) CheckItem( myMenus[Emul], EMmapd, TRUE); else CheckItem( myMenus[Emul], EMmapd, FALSE); break; case EMbold: if (TelInfo->numwindows < 1) break; screens[scrn].allowBold = !screens[scrn].allowBold; if (screens[scrn].allowBold) CheckItem( myMenus[Emul], EMbold, TRUE); else CheckItem( myMenus[Emul], EMbold, FALSE); RSchangebold(screens[scrn].vs, screens[scrn].allowBold, screens[scrn].colorBold, screens[scrn].inversebold); break; case EMboldcolor: if (TelInfo->numwindows < 1) break; screens[scrn].colorBold = !screens[scrn].colorBold; if (screens[scrn].colorBold) CheckItem( myMenus[Emul], EMboldcolor, TRUE); else CheckItem( myMenus[Emul], EMboldcolor, FALSE); RSchangebold(screens[scrn].vs, screens[scrn].allowBold, screens[scrn].colorBold, screens[scrn].inversebold); break; case EMinverse: if (TelInfo->numwindows < 1) break; screens[scrn].inversebold = !screens[scrn].inversebold; if (screens[scrn].inversebold) CheckItem( myMenus[Emul], EMinverse, TRUE); else CheckItem( myMenus[Emul], EMinverse, FALSE); RSchangebold(screens[scrn].vs, screens[scrn].allowBold, screens[scrn].colorBold, screens[scrn].inversebold); break; case EMbeep: if (TelInfo->numwindows < 1) break; screens[scrn].ignoreBeeps = !screens[scrn].ignoreBeeps; if (screens[scrn].ignoreBeeps) CheckItem( myMenus[Emul], EMbeep, TRUE); else CheckItem( myMenus[Emul], EMbeep, FALSE); VSbeepcontrol(screens[scrn].vs, screens[scrn].ignoreBeeps); break; case EMeightbit: if (TelInfo->numwindows < 1) break; screens[scrn].eightbit = !screens[scrn].eightbit; if (screens[scrn].eightbit) CheckItem( myMenus[Emul], EMeightbit, TRUE); else CheckItem( myMenus[Emul], EMeightbit, FALSE); break; case EMmapkeypad: if (TelInfo->numwindows < 1) break; screens[scrn].keypadmap = !screens[scrn].keypadmap; if (screens[scrn].keypadmap) CheckItem( myMenus[Emul], EMmapkeypad, TRUE); else CheckItem( myMenus[Emul], EMmapkeypad, FALSE); break; case EMpgupdwn: if (TelInfo->numwindows < 1) break; /* JMB */ screens[scrn].pgupdwn = !screens[scrn].pgupdwn; /* JMB */ if (screens[scrn].pgupdwn) /* JMB */ CheckItem( myMenus[Emul], EMpgupdwn, TRUE); /* JMB */ else /* JMB */ CheckItem( myMenus[Emul], EMpgupdwn, FALSE); /* JMB */ break; /* JMB */ case EMscroll: /* Scrollback on CLS */ if (TelInfo->numwindows<1) break; screens[scrn].ESscroll = !screens[scrn].ESscroll; VSscrolcontrol( screens[scrn].vs, -1, screens[scrn].ESscroll); if (screens[scrn].ESscroll) CheckItem(myMenus[Emul],EMscroll, TRUE); else CheckItem(myMenus[Emul],EMscroll, FALSE); break; case EMpage: /* TEK page command */ if (TelInfo->numwindows<1) break; parse( &screens[scrn], (unsigned char *) "\033\014",2); /* BYU LSC */ break; case EMclear: /* BYU 2.4.8 - Clear on TEK page */ if (TelInfo->numwindows<1) break; screens[scrn].tekclear = !screens[scrn].tekclear; if (screens[scrn].tekclear) CheckItem(myMenus[Emul],EMclear, TRUE); else CheckItem(myMenus[Emul],EMclear, FALSE); break; case EMscreensize: if (TelInfo->numwindows<1) break; /* NCSA: SB */ SetScreenDimensions((short)scrn, modifiers); /* NCSA: SB */ break; case EMreset: /* Reset Screen */ //RESTORE WRAP AFTER THE RESET!!! BUGG if (TelInfo->numwindows<1) break; doWrap = screens[scrn].wrap; VSreset(screens[scrn].vs); /* Reset it */ screens[scrn].timing=0; if (doWrap) VSwrite(screens[scrn].vs, "\033[?7h",5); else CheckItem( myMenus[Emul],EMwrap, FALSE); break; case EMjump: /* Jump Scroll */ if (TelInfo->numwindows<1) break; FlushNetwork(scrn); /* Flush it */ break; case EMsetup: /* need dialog to enter new key values */ setupkeys(); break; case EMcolor: /* Set color */ if (TelInfo->numwindows<1) break; if (TelInfo->haveColorQuickDraw) RScprompt(screens[scrn].vs); break; case EMAnsiColor: if (TelInfo->haveColorQuickDraw) { SetUpMovableModalMenus(); AnsiPrompt(0, 0); ResetMenus(); RSUpdatePalette(); } return; case EMqprint: screens[scrn].qprint = !screens[scrn].qprint; CheckItem(myMenus[Emul], EMqprint, screens[scrn].qprint); VSsetprintmode(screens[scrn].vs, screens[scrn].qprint); break; case EMff: screens[scrn].ignoreff = !screens[scrn].ignoreff; CheckItem(myMenus[Emul], EMff, screens[scrn].ignoreff); break; case EMcapture: /* BYU 2.4.18 - Capture session to file */ if (VSiscapturing(screens[scrn].vs)) { /* BYU 2.4.18 */ CloseCaptureFile(screens[scrn].vs); /* BYU 2.4.18 */ } else { /* BYU 2.4.18 */ if(VSopencapture(scrn, screens[scrn].vs)) /* BYU 2.4.18 */ CheckItem(myMenus[Emul], EMcapture,TRUE); /* BYU 2.4.18 */ } /* BYU 2.4.18 */ break; /* BYU 2.4.18 */ default: break; } break; case fontMenu: if (TelInfo->numwindows>0) { short itemFontNum; Str255 temp; GetItem( myMenus[Font], theItem, temp); GetFNum( temp, &itemFontNum); RSchangefont( screens[scrn].vs, itemFontNum, 0); CheckFonts(); } break; case fontMenu2: if (TelInfo->numwindows>0) { short itemFontNum; Str255 temp; GetItem( myMenus[FontOther], theItem, temp); GetFNum( temp, &itemFontNum); RSchangeboldfont( screens[scrn].vs, itemFontNum); CheckFonts(); } break; case sizeMenu: if (TelInfo->numwindows>0) { long itemFontSize; short currentSize, junk; Str255 temp; short numOfItems; numOfItems = CountMItems(myMenus[Sizem]); if (numOfItems == theItem) //use picked 'other...' { RSgetfont(screens[scrn].vs, &junk, ¤tSize); itemFontSize = SetOtherFontSize(currentSize); } else { GetItem( myMenus[Sizem], theItem, temp); /* JMB 2.6 -- Much safer to do it */ StringToNum(temp, &itemFontSize); /* this way! */ } RSchangefont( screens[scrn].vs, -1, itemFontSize); CheckFonts(); } break; case opspecMenu: // JMB switch (theItem) { case 1: EditConfigType(SESSIONPREFS_RESTYPE, &EditSession); CheckOpSpecSubmenu(); break; default: OpenPortSpecial(myMenus[OpSpec], theItem); } break; // JMB case prefsMenu: switch(theItem) { case prfGlobal: Cenviron(); break; case prfFTP: Cftp(); break; case prfSess: EditConfigType(SESSIONPREFS_RESTYPE, &EditSession); CheckOpSpecSubmenu(); break; case prfTerm: EditConfigType(TERMINALPREFS_RESTYPE, &EditTerminal); break; case prfFTPUser: EditConfigType(FTPUSER, &EditFTPUser); } break; case transMenu: if (TelInfo->numwindows>0) { CheckNational(theItem-1); // Set up the menu transBuffer(screens[scrn].national, theItem-1); // Translate the scrollback buffer // and redraw the screen VSredraw(screens[scrn].vs,0,0,VSmaxwidth(screens[scrn].vs),VSgetlines(screens[scrn].vs)-1); /* LU */ screens[scrn].national = theItem-1; } break; case keyMenu: KeyMenu(theItem); break; case funcMenu: FuncMenu(theItem); break; default: break; } HiliteMenu(0); } /* HandleMenuCommand */ // Take the user's new translation choice and make sure the proper tables exist to do // the translations. If there is a problem, return the default translation as the chouce. void CheckNational(short choice) { short i; for(i=1; i<=(nNational+1);i++) if ((choice+1) == i) /* Check the Current NatLang */ CheckItem( myMenus[National], i, TRUE); else CheckItem( myMenus[National], i, FALSE); } /* * extractmenu - remove a connection from the menu. */ void extractmenu(short screen) { DelMenuItem(myMenus[Conn], screen + FIRST_CNXN_ITEM); AdjustMenus(); } /* * addinmenu - add a connection's name to the menu in position pnum. (name is * an str255 pointed at by temps). */ void addinmenu( short screen, Str255 temps, char mark) { InsMenuItem(myMenus[Conn], "\pDoh", (screen-1) + FIRST_CNXN_ITEM); SetItem(myMenus[Conn], screen + FIRST_CNXN_ITEM, temps); // Avoid metas SetItemMark( myMenus[Conn], screen + FIRST_CNXN_ITEM, mark); AdjustMenus(); } /* Set the item mark for to opening connection */ void SetMenuMarkToOpeningForAGivenScreen( short scrn) { unsigned char c=0xa5; SetItemMark( myMenus[Conn], scrn + FIRST_CNXN_ITEM, c ); } /* Set the item mark for to opened connection */ void SetMenuMarkToLiveForAGivenScreen( short scrn) { SetItemMark( myMenus[Conn], scrn + FIRST_CNXN_ITEM, noMark); AdjustMenus(); } void DoTheMenuChecks(void) { short active; short windownum; if (TelInfo->numwindows>0) { EnableItem( myMenus[Conn],0); if (gApplicationPrefs->KeyPadAndFuncMenus) { /* Baylor */ EnableItem(myMenus[Keypad], 0); /* Baylor */ EnableItem(myMenus[Function], 0); /* Baylor */ } DrawMenuBar(); } else { DisableItem(myMenus[Conn],0); if (gApplicationPrefs->KeyPadAndFuncMenus) { /* Baylor */ DisableItem(myMenus[Keypad], 0); /* Baylor */ DisableItem(myMenus[Function], 0); /* Baylor */ } DrawMenuBar(); } active =0; for (windownum=0;windownumnumwindows;windownum++) if (screens[windownum].active == CNXN_ACTIVE) active++; if (active<2) DisableItem(myMenus[Conn],COnext); else EnableItem(myMenus[Conn],COnext); if (!active) { DisableItem(myMenus[Edit],EDpaste); DisableItem(myMenus[Emul],0); DrawMenuBar(); } else { EnableItem(myMenus[Edit],EDpaste); EnableItem( myMenus[Emul],0); DrawMenuBar(); } if (TelInfo->macrosModeless) if (FrontWindow() == TelInfo->macrosModeless) { EnableItem(myMenus[Edit],EDcut); EnableItem(myMenus[Edit],EDcopy); EnableItem(myMenus[Edit],EDpaste); EnableItem(myMenus[Edit],EDclear); } } /*--------------------------------------------------------------------------*/ /* SetupMenusForSelection */ /* If there is a selection on screen, then let the user copy and print. */ /* If not, then, oh well....just disable the menus and forget about it */ /* ...and to think that this good stuff USED to be in rsmac.c. */ /* This is called from RSselect after the user clicks in the window, and */ /* was moved here for modularity - SMB */ /*--------------------------------------------------------------------------*/ void SetMenusForSelection (short selected) /* NCSA: SB */ { /* NCSA: SB */ if (!selected) /* NCSA: SB */ { /* NCSA: SB */ DisableItem(myMenus[Fil],FLprint); /* NCSA: SB */ DisableItem(myMenus[Fil],FLselect); DisableItem(myMenus[Edit],EDcopy); /* NCSA: SB */ DisableItem(myMenus[Edit],EDretype); // RAB BetterTelnet 1.0fc6 DisableItem(myMenus[Edit],EDcopyt); /* NCSA: SB */ } /* NCSA: SB */ else /* NCSA: SB */ { /* NCSA: SB */ EnableItem(myMenus[Fil],FLprint); /* NCSA: SB */ EnableItem(myMenus[Fil],FLselect); EnableItem(myMenus[Edit],EDcopy); /* NCSA: SB */ EnableItem(myMenus[Edit],EDretype); // RAB BetterTelnet 1.0fc6 EnableItem(myMenus[Edit],EDcopyt); /* NCSA: SB */ } /* NCSA: SB */ } /* NCSA: SB */ long SetOtherFontSize(short currentSize) { DialogPtr dtemp; Str255 currentSizeStr, newSizeStr; long newSize; Boolean GoodValue; short ditem; dtemp=GetNewMyDialog( OtherFontDLOG, NULL, kInFront, (void *)ThirdCenterDialog); InitCursor(); GoodValue = 0; while (!GoodValue) { GoodValue = TRUE; NumToString((long) currentSize, currentSizeStr); SetTEText(dtemp, FontSizeTE, currentSizeStr); ditem = 0; while(ditem != DLOGOk && ditem != DLOGCancel) ModalDialog(DLOGwOK_CancelUPP, &ditem); if (ditem == DLOGCancel) { DisposeDialog( dtemp); return currentSize; } GetTEText(dtemp, FontSizeTE, newSizeStr); StringToNum(newSizeStr, &newSize); if (newSize < 4) GoodValue = FALSE; if (!GoodValue) SysBeep(4); } DisposeDialog( dtemp); return (newSize); } /*----------------------------------------------------------------------*/ /* NCSA: SB - SetColumnWidth */ /* Allow the user to FINALLY pick how many columns he wants on the */ /* screen. Set up a dialog box to pick the # of columns, and then */ /* size-up the Telnet screen accordingly. NOTE: The user still needs */ /* to do a "resize", unless he is using NAWS */ /*----------------------------------------------------------------------*/ void SetScreenDimensions(short scrn, short modifiers) { DialogPtr dtemp; Str255 ColumnsSTR, LinesSTR; long columns, lines; short ditem, notgood; dtemp=GetNewMyDialog( SizeDLOG, NULL, kInFront, (void *)ThirdCenterDialog); SetCursor(theCursors[normcurs]); notgood = 1; lines = VSgetlines(screens[scrn].vs); columns = VSgetcols(screens[scrn].vs) + 1; while (notgood) { notgood = 0; /* Default to good */ NumToString(columns, ColumnsSTR); NumToString(lines, LinesSTR); SetTEText(dtemp, ColumnsNumber, ColumnsSTR); SetTEText(dtemp, LinesNumber, LinesSTR); SelIText( dtemp, ColumnsNumber, 0, 32767); ditem = 3; while(ditem>2) ModalDialog(DLOGwOK_CancelUPP, &ditem); if (ditem == DLOGCancel) { DisposeDialog( dtemp); return; } GetTEText(dtemp, ColumnsNumber, ColumnsSTR); StringToNum(ColumnsSTR, &columns); GetTEText(dtemp, LinesNumber, LinesSTR); StringToNum(LinesSTR, &lines); if (columns < 10) { columns = 10; notgood = 1; } else if (columns > 132) { columns = 132; notgood = 1; } if (lines < 10) { lines = 10; notgood = 1; } else if (lines > 200) { lines = 200; notgood = 1; } if (notgood) SysBeep(4); } DisposeDialog( dtemp); if (VSsetlines( screens[scrn].vs, lines) < 0) OutOfMemory(-4); else { RScalcwsize( screens[scrn].vs, columns); if ((screens[scrn].naws) && !(modifiers & optionKey)) SendNAWSinfo(&screens[scrn], (short)columns, (short)lines); } updateCursor(1); } void ChangeWindowName(WindowPtr theWindow) { DialogPtr dptr; short itemHit; Str255 theName; if( theWindow != NULL) { InitCursor(); dptr = GetNewMySmallDialog(WinTitlDLOG, NULL, kInFront, (void *)ThirdCenterDialog ); GetWTitle(theWindow, theName); SetTEText( dptr, kWinNameTE, theName); SelIText( dptr, kWinNameTE, 0, 250 ); itemHit = 0; while(itemHit != DLOGOk && itemHit != DLOGCancel) ModalDialog(DLOGwOK_CancelUPP, &itemHit); if(itemHit == DLOGOk) { GetTEText(dptr, kWinNameTE, theName); set_new_window_name(theName, theWindow); } DisposDialog(dptr); } } void set_new_window_name(Str255 theName, WindowPtr theWindow) { short i; if(theName[0]) { i = WindowPtr2ScreenIndex(theWindow); if (i >= 0) { i += FIRST_CNXN_ITEM; SetWTitle(theWindow, theName); SetItem(myMenus[Conn], i, theName); } } } void OpenSpecial(short theItem) { OpenPortSpecial(myMenus[OpSpec], theItem); } void SaveSelectionToFile(void) { short i; if (TelInfo->numwindows<1) return; i = MacRGfindwind(FrontWindow()); /* is ICR window? */ if (i >= 0) return; else { i=RGgetdnum(FrontWindow()); if (i>-1) /* Copy Graphics */ return; else /* Copy Text */ if ( (i=RSfindvwind(FrontWindow())) >-1) SaveThisSelection( i); } } void SaveThisSelection(short vs) { char **charh; OSErr err; StandardFileReply sfr; short refNum, exist; long tempCount; charh=RSGetTextSel(vs,0); /* Get the text selection */ if (charh == (char **)-1L) OutOfMemory(400); else if (charh != (char **)0L) { /* BYU LSC - Can't do anything without characters */ HLock(charh); /* Lock for putting */ StandardPutFile("\p", "\puntitled", &sfr); if (sfr.sfGood) { if ((err = FSpCreate(&sfr.sfFile, gApplicationPrefs->CaptureFileCreator, 'TEXT', sfr.sfScript)) == dupFNErr) exist = 1; err = FSpOpenDF(&sfr.sfFile, fsWrPerm, &refNum); if (exist) SetEOF(refNum, 0L); tempCount = GetHandleSize(charh); err = FSWrite(refNum, &tempCount, *charh); FSClose(refNum); } HUnlock(charh); /* Unlock for disposal */ DisposHandle(charh); /* Kill the chars */ } } \ No newline at end of file +// menuseg.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* * Menu Handling and initialization code. * * * Revisions: * 7/92 Telnet 2.6 initial version: reorganized defines, put all stray globals in a struct, and * put all cursors in a nice array. Moved some routines to other places - Scott Bulmahn * * 6/94 Added support for Keypad and Function menus - Carl Bell (Baylor U.) */ #include "wind.h" #include "menuseg.proto.h" #include "mainseg.proto.h" #include "Sets.proto.h" /* JMB: For Saved Sets functions */ #include "configure.proto.h" #include "parse.proto.h" #include "InternalEvents.h" #include "mydnr.proto.h" #include "rsinterf.proto.h" #include "network.proto.h" #include "maclook.proto.h" #include "vrrgmac.proto.h" #include "rgmp.proto.h" #include "tekrgmac.proto.h" #include "vgtek.proto.h" #include "netevent.proto.h" #include "Connections.proto.h" #include "tnae.h" #include "authencrypt.proto.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "otp.proto.h" #include "event.proto.h" #include "macros.proto.h" #include "DlogUtils.proto.h" /* For VersionNumber, OutlineItem, and DialogProc Protos */ #include "telneterrors.h" #include #include "printing.proto.h" #include "menuseg.proto.h" #include "translate.proto.h" #include "parse.proto.h" // For SendNAWSinfo proto #include "keypadmenus.proto.h" #include "LinkedList.proto.h" #include "movableModal.h" MenuHandle myMenus[NMENUS]; /* Menu Handles .... */ static short lastMenyCommandKeys = -1; //whether last menu set had command keys //char *tempspot; /* temporary storage ~255 bytes malloc-ed */ /* * External variable declarations (those which we borrow ) * */ extern short scrn; extern Cursor *theCursors[]; extern WindRec *screens, /* The screen array from Maclook */ *ftplog; /* The FTP log screen from Maclook */ extern short nNational; void CloseCaptureFile(short w) { VSclosecapture(w); /* BYU 2.4.18 */ CheckItem(myMenus[Emul], EMcapture,FALSE); /* BYU 2.4.18 */ } /* portsOpen() - Count the number of ports open. Returns 3 different answers * 0= no ports at all, 1= at least active, -1= ports/none active. */ short portsOpen(void) { short pnum; pnum=TelInfo->numwindows-1; if (pnum<0) return(0); while (pnum>=0) // if (!screens[pnum--].active && !screens[pnum+1].corpse) return(1); // corpse status now part of active flag if (screens[pnum--].active == CNXN_ACTIVE) return(1); return(-1); } void switchToOptionMenus(Boolean useOptionedStuff) { Str255 theMenuItem; short whichString; if (useOptionedStuff) whichString = CLOSE_ALL_MENU_ITEM; else whichString = CLOSE_MENU_ITEM; GetIndString(theMenuItem,MISC_STRINGS,whichString); SetMenuItemText(myMenus[Fil],FLclose,theMenuItem); } void switchToShiftMenus(Boolean useShiftStuff) { Str255 theMenuItem; short whichString; if (useShiftStuff) whichString = PREVIOUS_SESSION_STRING; else whichString = NEXT_SESSION_STRING; GetIndString(theMenuItem,MISC_STRINGS,whichString); SetMenuItemText(myMenus[Conn],COnext,theMenuItem); } void AdjustMenus(void) { short i; WindowPtr wind; if ((wind = FrontWindow()) != NULL && ((((WindowPeek)wind)->windowKind >= userKind) || (((WindowPeek)wind)->windowKind == dialogKind))) EnableItem( myMenus[Fil],FLclose); else DisableItem( myMenus[Fil],FLclose); if ((i=portsOpen()) <1) { DisableItem( myMenus[Fil],FLsave); DisableItem( myMenus[Fil],FLsavem); DisableItem( myMenus[Fil],FLprint); DisableItem( myMenus[Fil],FLselect); DisableItem( myMenus[Fil],FLupload); DisableItem( myMenus[Edit],EDcut); DisableItem( myMenus[Edit],EDundo); DisableItem( myMenus[Edit],EDclear); DisableItem( myMenus[Edit],EDcopy); DisableItem( myMenus[Edit],EDretype); DisableItem( myMenus[Edit],EDcopyt); #if 0 // RAB BetterTelnet 1.0fc8 DisableItem( myMenus[Emul],EMbs); DisableItem( myMenus[Emul],EMdel); DisableItem( myMenus[Emul],EMecho); DisableItem( myMenus[Emul],EMwrap); DisableItem( myMenus[Emul],EMcrmap); DisableItem( myMenus[Emul],EMmapkeypad); DisableItem( myMenus[Emul],EMansi); DisableItem( myMenus[Emul],EMxterm); DisableItem( myMenus[Emul],EMmapd); DisableItem( myMenus[Emul],EMbold); DisableItem( myMenus[Emul],EMboldcolor); DisableItem( myMenus[Emul],EMbeep); DisableItem( myMenus[Emul],EMeightbit); DisableItem( myMenus[Emul],EMscroll); DisableItem( myMenus[Emul],EMreset); DisableItem ( myMenus[Emul],EMjump); DisableItem ( myMenus[Emul],EMpage); DisableItem ( myMenus[Emul],EMclear); /* BYU 2.4.14 */ DisableItem ( myMenus[Emul],EMscreensize); DisableItem ( myMenus[Emul],EMsetup); DisableItem ( myMenus[Emul],EMfont); DisableItem ( myMenus[Emul],EMsize); DisableItem ( myMenus[Emul],EMcolor); DisableItem ( myMenus[Emul],EMAnsiColor); DisableItem ( myMenus[Emul],EMcapture); /* BYU 2.4.18 */ DisableItem ( myMenus[Emul],EMqprint); #endif DisableItem ( myMenus[Emul],0); // RAB BetterTelnet 1.0fc8 DisableItem( myMenus[Net ],NEftp); DisableItem( myMenus[Net ],NEip); DisableItem( myMenus[Net ],NEayt); DisableItem( myMenus[Net ],NEao); DisableItem( myMenus[Net ],NEinter); DisableItem( myMenus[Net ],NEipsync); DisableItem( myMenus[Net ],NEsync); DisableItem( myMenus[Net ],NEbrk); DisableItem( myMenus[Net ],NEec); DisableItem( myMenus[Net ],NEel); DisableItem( myMenus[Net ],NEscroll); DisableItem( myMenus[Net ],NEeof); DisableItem( myMenus[Net ],NEabort); DisableItem( myMenus[Net ],NEsusp); if (TelInfo->ScrlLock) { TelInfo->ScrlLock=0; CheckItem(myMenus[Net ], NEscroll,FALSE); } } else { EnableItem ( myMenus[Fil],FLsave); EnableItem ( myMenus[Fil],FLsavem); EnableItem ( myMenus[Fil],FLupload); EnableItem ( myMenus[Emul],0); // RAB BetterTelnet 1.0fc8 #if 0 // RAB BetterTelnet 1.0fc8 EnableItem ( myMenus[Emul],EMbs); EnableItem ( myMenus[Emul],EMdel); EnableItem ( myMenus[Emul],EMecho); EnableItem ( myMenus[Emul],EMwrap); EnableItem ( myMenus[Emul],EMcrmap); EnableItem ( myMenus[Emul],EMansi); EnableItem ( myMenus[Emul],EMxterm); EnableItem ( myMenus[Emul],EMmapd); EnableItem ( myMenus[Emul],EMbold); EnableItem ( myMenus[Emul],EMbeep); EnableItem ( myMenus[Emul],EMboldcolor); EnableItem ( myMenus[Emul],EMeightbit); EnableItem ( myMenus[Emul],EMmapkeypad); #endif if (nNational > 0) { EnableItem ( myMenus[National], 0); } #if 0 EnableItem ( myMenus[Emul],EMscroll); EnableItem ( myMenus[Emul],EMreset); EnableItem ( myMenus[Emul],EMjump); EnableItem ( myMenus[Emul],EMpage); EnableItem ( myMenus[Emul],EMclear); /* BYU 2.4.14 */ EnableItem ( myMenus[Emul],EMscreensize); EnableItem ( myMenus[Emul],EMsetup); EnableItem ( myMenus[Emul],EMfont); EnableItem ( myMenus[Emul],EMsize); EnableItem ( myMenus[Emul],EMcapture); /* BYU 2.4.18 */ EnableItem ( myMenus[Emul],EMqprint); #endif if (TelInfo->haveColorQuickDraw) { EnableItem ( myMenus[Emul],EMcolor); EnableItem ( myMenus[Emul],EMAnsiColor); } else { DisableItem ( myMenus[Emul],EMcolor); DisableItem ( myMenus[Emul],EMAnsiColor); } EnableItem ( myMenus[Net ],NEftp); EnableItem ( myMenus[Net ],NEip); EnableItem ( myMenus[Net ],NEayt); EnableItem ( myMenus[Net ],NEao); EnableItem ( myMenus[Net ],NEinter); EnableItem ( myMenus[Net ],NEipsync); EnableItem ( myMenus[Net ],NEbrk); EnableItem ( myMenus[Net ],NEsync); EnableItem ( myMenus[Net ],NEec); EnableItem ( myMenus[Net ],NEel); EnableItem ( myMenus[Net ],NEscroll); EnableItem( myMenus[Net ],NEeof); EnableItem( myMenus[Net ],NEabort); EnableItem( myMenus[Net ],NEsusp); } if (TelInfo->macrosModeless) if (FrontWindow() == TelInfo->macrosModeless) { EnableItem(myMenus[Edit],EDcut); EnableItem(myMenus[Edit],EDcopy); EnableItem(myMenus[Edit],EDpaste); EnableItem(myMenus[Edit],EDclear); } } /* switchMenus( which) - Switch from our current menus to the key menus (1) * or the normal menus (0). */ void switchMenus(short which, short force) { short i; Str255 theMenuItem; if ((lastMenyCommandKeys != which) || force) { lastMenyCommandKeys = which; DeleteMenu( fileMenu); /* Take them from the menu bar */ DeleteMenu( editMenu); DeleteMenu( termMenu); DeleteMenu( netMenu); DeleteMenu( keyMenu); /* Baylor */ DeleteMenu( funcMenu); /* Baylor */ DeleteMenu(NfileMenu); DeleteMenu(NeditMenu); DeleteMenu(NtermMenu); DeleteMenu(NnetMenu); if (which) { myMenus[Fil ] = GetMenu(NfileMenu); myMenus[Edit] = GetMenu(NeditMenu); myMenus[Emul] = GetMenu(NtermMenu); myMenus[Net ] = GetMenu(NnetMenu ); myMenus[Keypad] = GetMenu(keyMenu); /* Baylor */ myMenus[Function] = GetMenu(funcMenu); /* Baylor */ DeleteMenuItem(myMenus[Conn],COnext); InsertMenuItem(myMenus[Conn],(StringPtr)"\017Next Session/N\0",0); GetIndString(theMenuItem, MISC_STRINGS, NEXT_SESSION_STRING); SetMenuItemText(myMenus[Conn],COnext,theMenuItem); } else { myMenus[Fil ] = GetMenu(fileMenu); myMenus[Edit] = GetMenu(editMenu); myMenus[Emul] = GetMenu(termMenu); myMenus[Net ] = GetMenu( netMenu); myMenus[Keypad] = GetMenu(keyMenu); /* Baylor */ myMenus[Function] = GetMenu(funcMenu); /* Baylor */ DeleteMenuItem(myMenus[Conn],COnext); InsertMenuItem(myMenus[Conn],(StringPtr)"\015Next Session\0",0); GetIndString(theMenuItem, MISC_STRINGS, NEXT_SESSION_STRING); SetMenuItemText(myMenus[Conn],COnext,theMenuItem); } } for(i=1; iKeyPadAndFuncMenus) { /* Baylor */ InsertMenu(myMenus[Keypad], 0); /* Baylor */ InsertMenu(myMenus[Function], 0); /* Baylor */ } AdjustMenus(); /* Hilite the right stuff */ if (TelInfo->MacBinary) CheckItem(myMenus[Fil],FLbin,TRUE); /* Check MacBinary ... */ else CheckItem(myMenus[Fil],FLbin,FALSE); if (TelInfo->ftplogon) CheckItem(myMenus[Fil],FLlog,TRUE); /* and the log .... */ else CheckItem(myMenus[Fil],FLlog,FALSE); if (TelInfo->ScrlLock) /* and the Suspend network ... */ CheckItem(myMenus[Net], NEscroll,TRUE); else CheckItem(myMenus[Net], NEscroll,FALSE); if (TelInfo->numwindows>0) /* and set the BSDEL flag */ CheckItem(myMenus[Emul], EMbs+screens[scrn].bsdel,FALSE); DrawMenuBar(); /* Draw what we have done */ SetupOpSpecSubmenu(myMenus[OpSpec]); if (!TelInfo->haveColorQuickDraw) DisableItem( myMenus[Emul], EMcolor); } /* setupmenu - Set up (load) all menus and prepare menu bar. * set default check marks. */ void setupmenu(short def, DialogPtr startupBox) { short scratchshort, i; Str255 scratchPstring; static Str255 stemp; GetIndString(stemp, MISC_STRINGS, REBUILDING_FONT_MENU + 1); SetTEText(startupBox, 3, stemp); lastMenyCommandKeys = def; myMenus[0] = GetMenu(appleMenu); /* Get all of our friendly menus */ myMenus[Conn] = GetMenu(connMenu); myMenus[Font] = GetMenu(fontMenu); myMenus[FontOther] = GetMenu(fontMenu2); // RAB BetterTelnet 1.0.1 myMenus[Sizem] = GetMenu(sizeMenu); myMenus[OpSpec] = GetMenu(opspecMenu); myMenus[PrefsSub] = GetMenu(prefsMenu); myMenus[National] = GetMenu(transMenu); myMenus[Keypad] = GetMenu(keyMenu); /* Baylor */ myMenus[Function] = GetMenu(funcMenu); /* Baylor */ myMenus[Fil ] = GetMenu(NfileMenu); myMenus[Edit] = GetMenu(NeditMenu); myMenus[Emul] = GetMenu(NtermMenu); myMenus[Net ] = GetMenu(NnetMenu ); AppendResMenu(myMenus[0], 'DRVR'); /* Add in the DA's */ InsertMenu(myMenus[0], 0); /* Insert the Menus into the bar */ InsertMenu(myMenus[OpSpec], 0); InsertMenu(myMenus[Conn], 0); if (gApplicationPrefs->KeyPadAndFuncMenus) { /* Baylor */ InsertMenu(myMenus[Keypad], 0); /* Baylor */ InsertMenu(myMenus[Function], 0); /* Baylor */ } InsertMenu(myMenus[Font], -1); InsertMenu(myMenus[FontOther], -1); InsertMenu(myMenus[Sizem], -1); // InsertMenu(myMenus[OpSpec], -1); InsertMenu(myMenus[National], -1); InsertMenu(myMenus[PrefsSub], -1); if (!gApplicationPrefs->monospacedOut) AppendResMenu(myMenus[Font], 'FONT'); /* Put the fonts in the font menu */ else addMonoSpacedFonts(myMenus[Font], startupBox); scratchshort = CountMItems(myMenus[Font]); for (i = 1; i <= scratchshort; i++) // RAB BetterTelnet 1.0.1 { GetMenuItemText(myMenus[Font],i,scratchPstring); AppendMenu(myMenus[FontOther],scratchPstring); } SetupOpSpecSubmenu(myMenus[OpSpec]); switchMenus(def, 0); GetIndString(stemp, MISC_STRINGS, REBUILDING_FONT_MENU + 2); SetTEText(startupBox, 3, stemp); } void addMonoSpacedFonts(MenuHandle theMenu, DialogPtr startupBox) { Boolean doItAll = FALSE; Handle theGoodFonts, theBadFonts; short numGoodFonts, numBadFonts,numFontsInMenu; short menuIndex; Str255 fontListName,currentFontName; //here begins the caching of fonts to save time caculating proportionality UseResFile(TelInfo->SettingsFile); theGoodFonts = Get1Resource('STR#',4000); //the good fonts if (!theGoodFonts) { UseResFile(TelInfo->ApplicationFile); theGoodFonts = Get1Resource('STR#',4000); theBadFonts = Get1Resource('STR#',5000); DetachResource(theGoodFonts); DetachResource(theBadFonts); UseResFile(TelInfo->SettingsFile); AddResource(theGoodFonts,'STR#',4000,"\pGood Fonts"); AddResource(theBadFonts,'STR#',5000,"\pBad Fonts"); } else theBadFonts = Get1Resource('STR#',5000); redoTheList: numGoodFonts = *(short *)(*theGoodFonts); if (numGoodFonts == 0) doItAll = TRUE; //we haven't created a list of fonts yet else numBadFonts = *(short *)(*theBadFonts); AppendResMenu(theMenu,'FONT'); //add them all here numFontsInMenu = CountMItems(theMenu); if (numFontsInMenu != (numBadFonts + numGoodFonts)) { SetHandleSize(theGoodFonts,2); *((short *)*theGoodFonts) = 0; SetHandleSize(theBadFonts,2); *((short *)*theBadFonts) = 0; doItAll = TRUE; } if (!doItAll) //we have a list already { short goodFontIndex, badFontIndex; goodFontIndex = badFontIndex = 1; for (menuIndex = 1; menuIndex <= numFontsInMenu; menuIndex++) { //look at each font, see if its bad, good, or new GetMenuItemText(theMenu,menuIndex,currentFontName); GetIndString(fontListName,5000,badFontIndex); if (EqualString(currentFontName,fontListName,TRUE,FALSE)) { DeleteMenuItem(theMenu,menuIndex); //remove the bad font from the menu numFontsInMenu--; menuIndex--; badFontIndex++; } else { GetIndString(fontListName,4000,goodFontIndex); if (EqualString(currentFontName,fontListName,TRUE,FALSE)) goodFontIndex++; else //its a new font, and we didn't expect it; this means there were an equal { //number of fonts removed and added. Let's start over. short numberInMenu; numberInMenu = CountMItems(theMenu); for (;numberInMenu > 0; numberInMenu--) DeleteMenuItem(theMenu,numberInMenu);//clear the menu SetHandleSize(theGoodFonts,2);//clear the lists SetHandleSize(theBadFonts,2); goto redoTheList; } } } } else //create a new list { Str255 stemp; // DialogPtr dtemp; // dtemp = GetNewMyDialog(130, NULL, kInFront, (void *)SecondThirdCenterDialog); /* opening dialog */ // DrawDialog(dtemp); GetIndString(stemp, MISC_STRINGS, REBUILDING_FONT_MENU); SetTEText(startupBox, 3, stemp); for (menuIndex = 1; menuIndex <= numFontsInMenu; menuIndex++) { GetMenuItemText(theMenu,menuIndex,currentFontName); if (!isMonospacedFont(currentFontName)) { DeleteMenuItem(theMenu,menuIndex); //remove the bad font from the menu numFontsInMenu--; menuIndex--; PtrAndHand(currentFontName,theBadFonts,currentFontName[0]+1);//add it to the bad list (*(short *)(*theBadFonts))++; } else { PtrAndHand(currentFontName,theGoodFonts,currentFontName[0]+1);//add it to the good list (*(short *)(*theGoodFonts))++; } } TextFont(1); // reset to application font - RAB BetterTelnet 1.5a1 // DisposeDialog(dtemp); } ChangedResource(theGoodFonts); ChangedResource(theBadFonts); ReleaseResource(theGoodFonts); ReleaseResource(theBadFonts); UpdateResFile(TelInfo->SettingsFile); } Boolean isMonospacedFont(Str255 theFont) { Boolean haveNonRomanScripts,thisOneIsMonospaced = FALSE, doRomanTest = FALSE; short fond; long tempLong; //GrafPtr tempPort, savedPort; //first, open a temporary port to test CharWidth //tempPort = (GrafPtr)myNewPtrCritical(sizeof(GrafPort)); //GetPort(&savedPort); //OpenPort(tempPort); tempLong = GetScriptManagerVariable(smEnabled); //this returns number of scripts enable haveNonRomanScripts = (tempLong > 1); //if there is one, its roman GetFNum(theFont,&fond); if (haveNonRomanScripts) { long thisScriptEnabled; ScriptCode scriptNumber; scriptNumber = FontToScript(fond); if (scriptNumber != 0) //if its non-roman { thisScriptEnabled = GetScriptVariable(scriptNumber,smScriptEnabled); if (thisScriptEnabled) { //check if this font is the preferred monospaced font for its script long theSizeAndFond; short thePreferredFond; theSizeAndFond = GetScriptVariable(scriptNumber, smScriptMonoFondSize); thePreferredFond = theSizeAndFond >> 16; //high word is fond thisOneIsMonospaced = (thePreferredFond == fond); } else thisOneIsMonospaced = FALSE; //this font's script isn't enabled } else doRomanTest = TRUE; } else doRomanTest = TRUE; if (doRomanTest) { TextFont(fond); thisOneIsMonospaced = (CharWidth('W') == CharWidth('.')); } //SetPort(savedPort); //ClosePort(tempPort); //DisposePtr((Ptr)tempPort); return(thisOneIsMonospaced); } void CheckOpSpecSubmenu(void) { // short numItems; // UseResFile(TelInfo->SettingsFile); // numItems = Count1Resources(SESSIONPREFS_RESTYPE); // if ((CountMItems(myMenus[OpSpec]) - 2) != numItems) SetupOpSpecSubmenu(myMenus[OpSpec]); } void SetupOpSpecSubmenu(MenuHandle theMenu) { short scratchshort,numberofitems; LinkedListNode *theHead; scratchshort = (CountMItems(theMenu) - 2); for (; scratchshort>0; scratchshort--) DeleteMenuItem(theMenu, scratchshort + 2); UseResFile(TelInfo->SettingsFile); numberofitems = Count1Resources(SESSIONPREFS_RESTYPE); if (numberofitems) { theHead = createSortedList(SESSIONPREFS_RESTYPE,numberofitems,"\p"); //now we have a sorted linked list of the names addListToMenu/*2*/(theMenu, theHead, 3); deleteList(&theHead); } } /* updateMenuChecks() - update the check marks for file transfer * (MacBinary) */ void updateMenuChecks( void) { if (TelInfo->MacBinary) CheckItem(myMenus[Fil],FLbin,TRUE); /* Check MacBinary ... */ else CheckItem(myMenus[Fil],FLbin,FALSE); } /* DisplayMacBinary() - Sets the macbinary check mark according to the MacBinary flag */ void DisplayMacBinary( void) { if (TelInfo->MacBinary) CheckItem(myMenus[Fil],FLbin,TRUE); /* Check MacBinary ... */ else CheckItem(myMenus[Fil],FLbin,FALSE); } /*CheckFonts() - Place checkmarks and outlines on the appropriate * menu items for the fonts */ void CheckFonts(void) { short i, fsiz, fnum; long itemFontSize; Str255 temp, itemString; RSgetboldfont( screens[scrn].vs, &fnum); GetFontName(fnum, temp); if (TelInfo->checkedBoldFontNum) CheckItem(myMenus[FontOther], TelInfo->checkedBoldFontNum, FALSE); if (TelInfo->checkedFontNum) CheckItem(myMenus[Font], TelInfo->checkedFontNum, FALSE); TelInfo->checkedFontNum = 0; TelInfo->checkedBoldFontNum = 0; if (screens[scrn].cachedBoldFontNum) { CheckItem(myMenus[FontOther], screens[scrn].cachedBoldFontNum, TRUE); TelInfo->checkedBoldFontNum = screens[scrn].cachedBoldFontNum; } else for(i=1; i<= CountMItems( myMenus[FontOther]); i++) { GetMenuItemText( myMenus[FontOther], i, itemString); if (EqualString(temp, itemString, FALSE, FALSE)) { TelInfo->checkedBoldFontNum = i; screens[scrn].cachedBoldFontNum = i; CheckItem( myMenus[FontOther], i, TRUE); /* Check the current font */ } // else // CheckItem( myMenus[FontOther], i, FALSE); } RSgetfont( screens[scrn].vs, &fnum, &fsiz); GetFontName(fnum, temp); if (screens[scrn].cachedFontNum) { CheckItem(myMenus[Font], screens[scrn].cachedFontNum, TRUE); TelInfo->checkedFontNum = screens[scrn].cachedFontNum; } else for(i=1; i<= CountMItems( myMenus[Font]); i++) { GetMenuItemText( myMenus[Font], i, itemString); if (EqualString(temp, itemString, FALSE, FALSE)) { TelInfo->checkedFontNum = i; screens[scrn].cachedFontNum = i; CheckItem( myMenus[Font], i, TRUE); /* Check the current font */ } // else // CheckItem( myMenus[Font], i, FALSE); } for(i=1; i<=CountMItems( myMenus[Sizem]); i++) { GetMenuItemText( myMenus[Sizem], i, itemString); /* JMB 2.6 -- Much safer to do it */ StringToNum(itemString, &itemFontSize); /* this way! */ if (fsiz == (short)itemFontSize) CheckItem( myMenus[Sizem], i, TRUE); /* Check Our Current Size */ else CheckItem( myMenus[Sizem], i, FALSE); if (RealFont( fnum, (short)itemFontSize)) /* Outline All Available REAL Sizes */ SetItemStyle( myMenus[Sizem], i, outline); else SetItemStyle( myMenus[Sizem], i, 0); } } /* applAbout - display the about dialog for the application.*/ void applAbout( void) { DialogPtr About; short itemhit; About=GetNewMyDialog( AboutDLOG, (Ptr) 0L,(WindowPtr) -1L, (void *)ThirdCenterDialog); if (About) { UItemAssign( About, 2, VersionNumberUPP); ModalDialog(NULL, &itemhit); DisposeDialog(About); } } short ReallyClose( short scrn) { DialogPtr dtemp; short item; Str255 scratchPstring; SetCursor(theCursors[normcurs]); GetWTitle(screens[scrn].wind, scratchPstring); ParamText(scratchPstring, NULL, NULL, NULL); dtemp = GetNewMyDialog( CloseDLOG, NULL, kInFront, (void *)ThirdCenterDialog); item = DLOGCancel +1; while (item> DLOGCancel) ModalDialog(DLOGwOK_CancelUPP, &item); DisposeDialog( dtemp); updateCursor(1); if (item == DLOGCancel) return(0); return(1); } PicHandle RGtoPICT(short i) { short j; PicHandle tpic; Rect trect; SetRect(&trect,0,0,384,384); j=VGnewwin(TEK_DEVICE_PICTURE,VGgetVS(i)); /* NCSA 2.5: get the right VS */ RGMPsize( &trect ); VGzcpy( i, j); /* Love dat zm factr */ tpic=OpenPicture(&trect); ClipRect(&trect); VGredraw(i,j); ClosePicture(); VGclose(j); return(tpic); } /* * copyGraph - Copy the current graphics screen. * dnum - the number of the drawing to copy . */ void copyGraph( short dnum) { long tlong; /* Temporary Variable */ PicHandle tpic; /* Mental picture of the thing */ tpic=RGtoPICT(dnum); /* Get the picture */ tlong=ZeroScrap(); /* Nobody else can live here */ HLock((Handle) tpic); /* Lock it for Puting */ tlong=PutScrap(GetHandleSize((Handle) tpic),'PICT', (Ptr) *tpic); /* Store as a PICT */ HUnlock((Handle) tpic); /* Unlock so we can toss it */ KillPicture(tpic); /* Kill the picture..... */ } /* * copyText - Copy the current selection on the virtual screen * vs - the number of the virtual screen to copy from */ void copyText( short vs) { char **charh; /* where to store the characters */ long tlong; /* Necessary temporary variable */ tlong=ZeroScrap(); /* This Scrap aint big enough for the both of us */ charh=RSGetTextSel(vs,0); /* Get the text selection */ if (charh == (char **)-1L) OutOfMemory(400); else if (charh != (char **)0L) { /* BYU LSC - Can't do anything without characters */ HLock(charh); /* Lock for putting */ tlong=PutScrap(GetHandleSize(charh),'TEXT',*charh); /* Put it as a TEXT resource */ HUnlock(charh); /* Unlock for disposal */ DisposeHandle(charh); /* Kill the chars */ } } /* * copyTable - Copy the current selection on the virtual screen * vs - the number of the virtual screen to copy from */ void copyTable( short vs) { char **charh; /* where to store the characters */ long tlong; /* Necessary temporary variable */ tlong=ZeroScrap(); /* This Scrap aint big enough for the both of us */ charh=RSGetTextSel(vs, gApplicationPrefs->CopyTableThresh); /* Get the text selection */ if (charh>(char **)0L) { /* BYU LSC - Can't do anything without characters */ HLock(charh); /* Lock for putting */ tlong=PutScrap(GetHandleSize(charh),'TEXT',*charh); /* Put it as a TEXT resource */ HUnlock(charh); /* Unlock for disposal */ DisposeHandle(charh); /* Kill the chars */ } else putln("No characters to copy darn it!"); } /* * paste - Paste the resource from the scrap into the current WIND, if * and only if it is really text */ void paste( void) { long off, /* offset */ length; /* the lenght of what is on the Scrap */ if (screens[scrn].clientflags & PASTE_IN_PROGRESS) { // One paste at a time, please SysBeep(4); return; } /* Flush the buffer if necessary */ //CCP fix for linemode if (screens[scrn].kblen>0) { netpush(screens[scrn].port); netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen); screens[scrn].kblen=0; } if (GetScrap(0L, 'TEXT', &off)<=0L) /* If there are no TEXT res's */ return; /* then we can't paste it */ screens[scrn].outhand=myNewHandle(0L); /* create a handle to put chars in */ length= GetScrap( screens[scrn].outhand, 'TEXT',&off); /* Store the scrap into the handle */ screens[scrn].outlen = length; /* Set the length */ HLock(screens[scrn].outhand); /* Lock the Handle down for safety */ screens[scrn].outptr=*screens[scrn].outhand; /* Set the pointer */ screens[scrn].clientflags |= PASTE_IN_PROGRESS; screens[scrn].isUploading = 0; screens[scrn].incount = 0; screens[scrn].outcount = 0; trbuf_mac_nat((unsigned char *)screens[scrn].outptr,screens[scrn].outlen, screens[scrn].national); /* LU: translate to national chars */ pasteText( scrn); /* BYU LSC - routine to paste to net, w/echo if neccessary */ } void uploadFile(void) // RAB: routine added in BetterTelnet 1.0fc9 { long length; StandardFileReply sfr; OSErr err; short refNum; if (screens[scrn].clientflags & PASTE_IN_PROGRESS) { // One paste at a time, please SysBeep(4); return; } StandardGetFile(0, -1, 0, &sfr); if (!sfr.sfGood) return; err = FSpOpenDF(&sfr.sfFile, fsCurPerm, &refNum); if (err) return; /* Flush the buffer if necessary */ //CCP fix for linemode if (screens[scrn].kblen>0) { netpush(screens[scrn].port); netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen); screens[scrn].kblen=0; } screens[scrn].outhand=myNewHandle(16384); // for now, upload block is 16K screens[scrn].outptr = *screens[scrn].outhand; HLock(screens[scrn].outhand); /* Lock the Handle down for safety */ length = 16384; FSRead(refNum, &length, screens[scrn].outptr); if (length == 0) { FSClose(refNum); HUnlock(screens[scrn].outhand); DisposeHandle(screens[scrn].outhand); return; } screens[scrn].outlen = length; /* Set the length */ HUnlock(screens[scrn].outhand); SetHandleSize(screens[scrn].outhand, length); // now REALLY set the length HLock(screens[scrn].outhand); screens[scrn].clientflags |= PASTE_IN_PROGRESS; if (length == 16384) { screens[scrn].isUploading = 1; screens[scrn].uploadRefNum = refNum; } else { FSClose(refNum); screens[scrn].isUploading = 0; } screens[scrn].incount = 0; screens[scrn].outcount = 0; trbuf_mac_nat((unsigned char *)screens[scrn].outptr,screens[scrn].outlen, screens[scrn].national); /* LU: translate to national chars */ pasteText(scrn); /* BYU LSC - routine to paste to net, w/echo if neccessary */ } void autoPaste(short vs) // RAB: routine added in BetterTelnet 1.0fc6 { char **charh; if (screens[scrn].clientflags & PASTE_IN_PROGRESS) { // One paste at a time, please SysBeep(4); return; } /* Flush the buffer if necessary */ //CCP fix for linemode if (screens[scrn].kblen>0) { netpush(screens[scrn].port); netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen); screens[scrn].kblen=0; } charh=RSGetTextSel(vs,0); /* Get the text selection */ if (charh == (char **)-1L) OutOfMemory(400); else if (charh != (char **)0L) { /* BYU LSC - Can't do anything without characters */ HLock(charh); screens[scrn].outhand=charh; screens[scrn].outlen = GetHandleSize(charh); /* Set the length */ screens[scrn].outptr=*screens[scrn].outhand; /* Set the pointer */ screens[scrn].clientflags |= PASTE_IN_PROGRESS; screens[scrn].isUploading = 0; screens[scrn].incount = 0; screens[scrn].outcount = 0; trbuf_mac_nat((unsigned char *)screens[scrn].outptr,screens[scrn].outlen, screens[scrn].national); /* LU: translate to national chars */ pasteText( scrn); /* BYU LSC - routine to paste to net, w/echo if neccessary */ } } void displayStatus(short n) { DialogPtr dptr; short item; Str255 scratchPstring,anotherString; SetCursor(theCursors[normcurs]); switch(screens[n].active) { case CNXN_ISCORPSE: GetWTitle(screens[n].wind, scratchPstring); GetIndString(anotherString,MISC_STRINGS,AWAITING_DISMISSAL_STRING); ParamText( scratchPstring, anotherString, NULL, NULL); break; case CNXN_OPENING: GetIndString(anotherString,MISC_STRINGS,BEING_OPENED_STRING); ParamText( screens[n].machine,anotherString, NULL, NULL); break; default: GetIndString(anotherString,MISC_STRINGS,BEING_LOOKED_UP); ParamText( screens[n].machine,anotherString, NULL, NULL); } dptr = GetNewMyDialog( StatusDLOG, NULL, kInFront, (void *)ThirdCenterDialog); item = DLOGCancel+1; while (item > DLOGCancel) ModalDialog(DLOGwOK_CancelUPP, &item); updateCursor(1); if (item == DLOGCancel) { netclose(screens[n].port); destroyport( n); } DisposeDialog(dptr); } /* * changeport - handle the menu updates for changing from one port to another */ void changeport(short oldprt, short newprt) { //sprintf(tempspot,"oldscrn: %d, newscrn: %d",oldprt,newprt); putln(tempspot); if (screens[oldprt].active == CNXN_ACTIVE) CheckItem(myMenus[Conn], oldprt + FIRST_CNXN_ITEM, FALSE); /* Adjust Conn menu */ CheckItem(myMenus[Conn], newprt + FIRST_CNXN_ITEM, TRUE); CheckItem(myMenus[Emul], EMbs,FALSE); /* Adjust BS */ CheckItem(myMenus[Emul], EMdel,FALSE); CheckItem(myMenus[Emul], EMbs+screens[newprt].bsdel,TRUE); /* and DEL */ if (screens[newprt].tektype < 0) { // TEK is inhibited DisableItem(myMenus[Emul],EMclear); DisableItem(myMenus[Emul],EMpage); } else { EnableItem(myMenus[Emul],EMclear); EnableItem(myMenus[Emul],EMpage); if (screens[newprt].tekclear) /* BYU 2.4.8 */ CheckItem(myMenus[Emul],EMclear,TRUE); /* BYU 2.4.8 */ else /* BYU 2.4.8 */ CheckItem(myMenus[Emul],EMclear,FALSE); /* BYU 2.4.8 */ } if (screens[newprt].ESscroll) CheckItem(myMenus[Emul],EMscroll,TRUE); else CheckItem(myMenus[Emul],EMscroll,FALSE); if (screens[newprt].echo) /* LOCAL ECHO */ CheckItem(myMenus[Emul],EMecho,TRUE); else /* REMOTE ECHO */ CheckItem(myMenus[Emul],EMecho,FALSE); if (screens[newprt].enabled) CheckItem(myMenus[Emul],EMsuspend,FALSE); else CheckItem(myMenus[Emul],EMsuspend,TRUE); if (screens[newprt].wrap) /* wrap on */ CheckItem(myMenus[Emul],EMwrap,TRUE); else /* wrap off */ CheckItem(myMenus[Emul],EMwrap,FALSE); if (screens[newprt].crmap) CheckItem(myMenus[Emul],EMcrmap,TRUE); else CheckItem(myMenus[Emul],EMcrmap,FALSE); if (screens[newprt].ANSIgraphics) CheckItem(myMenus[Emul],EMansi,TRUE); else CheckItem(myMenus[Emul],EMansi,FALSE); if (screens[newprt].Xterm) CheckItem(myMenus[Emul],EMxterm,TRUE); else CheckItem(myMenus[Emul],EMxterm,FALSE); if (screens[newprt].remapCtrlD) CheckItem(myMenus[Emul],EMmapd,TRUE); else CheckItem(myMenus[Emul],EMmapd,FALSE); if (screens[newprt].allowBold) CheckItem(myMenus[Emul],EMbold,TRUE); else CheckItem(myMenus[Emul],EMbold,FALSE); if (screens[newprt].colorBold) CheckItem(myMenus[Emul],EMboldcolor,TRUE); else CheckItem(myMenus[Emul],EMboldcolor,FALSE); if (screens[newprt].ignoreBeeps) CheckItem(myMenus[Emul],EMbeep,TRUE); else CheckItem(myMenus[Emul],EMbeep,FALSE); if (screens[newprt].inversebold) CheckItem(myMenus[Emul],EMinverse,TRUE); else CheckItem(myMenus[Emul],EMinverse,FALSE); if (screens[newprt].qprint) CheckItem(myMenus[Emul],EMqprint,TRUE); else CheckItem(myMenus[Emul],EMqprint,FALSE); if (screens[newprt].ignoreff) CheckItem(myMenus[Emul],EMff,TRUE); else CheckItem(myMenus[Emul],EMff,FALSE); if (screens[newprt].eightbit) CheckItem(myMenus[Emul],EMeightbit,TRUE); else CheckItem(myMenus[Emul],EMeightbit,FALSE); if (screens[newprt].keypadmap) CheckItem(myMenus[Emul],EMmapkeypad,TRUE); else CheckItem(myMenus[Emul],EMmapkeypad,FALSE); if (VSiscapturing(screens[newprt].vs)) /* BYU 2.4.18 */ CheckItem(myMenus[Emul], EMcapture,TRUE); /* BYU 2.4.18 */ else /* BYU 2.4.18 */ CheckItem(myMenus[Emul], EMcapture,FALSE); /* BYU 2.4.18 */ if (screens[newprt].arrowmap) /* JMB */ CheckItem(myMenus[Emul],EMarrowmap, TRUE); /* JMB */ else /* JMB */ CheckItem(myMenus[Emul],EMarrowmap, FALSE); /* JMB */ if (screens[newprt].pgupdwn) /* JMB */ CheckItem(myMenus[Emul],EMpgupdwn, TRUE); /* JMB */ else /* JMB */ CheckItem(myMenus[Emul],EMpgupdwn, FALSE); /* JMB */ scrn=newprt; CheckFonts(); CheckNational(screens[newprt].national); } // Returns TRUE if the user cancelled the quit Boolean HandleQuit(void) { short i; Boolean liveConnections = FALSE, die = TRUE; if (TelInfo->numwindows>0) { for(i = 0; i < MaxSess; i++) { if ((screens[i].active == CNXN_ACTIVE)||(screens[i].active == CNXN_OPENING)) liveConnections = TRUE; } if (liveConnections) if (!gApplicationPrefs->dontWarnOnQuit) die = AskUserAlert(REALLY_QUIT_QUESTION, FALSE); if (die) { for (i = TelInfo->numwindows - 1; i >= 0; i--) { netclose(screens[i].port); destroyport(i); } } else return (TRUE); } if (gApplicationPrefs->destroyKTickets) DestroyTickets(); quit(); return (FALSE); } /* * HandleMenuCommand - preform a command denoted by the arguments. * mResult - the result of the menu event * modifiers- modifiers from the menu event */ void HandleMenuCommand( long mResult, short modifiers) { register short i; short theItem, theMenu; Boolean doWrap; theMenu = mResult >> 16; theItem = mResult & 0xffff; switch(theMenu) { case appleMenu: if (theItem==1) /* About Dialog */ applAbout(); else { Str255 name; GetMenuItemText(myMenus[0], theItem, name); /* Desk accessory */ OpenDeskAcc(name); } break; case fileMenu: case NfileMenu: switch(theItem) { case FLopen: PresentOpenConnectionDialog(); /* Open a connection */ break; case FLclose: /* Close a connection */ if (!FrontWindow()) break; // RAB BetterTelnet 1.2 - bug fix if (!(modifiers & optionKey)) CloseAWindow(FrontWindow()); else { Boolean die = TRUE; if (numberLiveConnections()) die = AskUserAlert(CLOSE_ALL_WINDOWS_Q, FALSE); if (die) { for (i = TelInfo->numwindows - 1; i >= 0; i--) { netclose(screens[i].port); destroyport(i); } } else break; } break; case FLload: /* Load a set */ LoadSet(); break; case FLsave: /* Save a set */ if (TelInfo->numwindows<1) break; SaveSet(0, (modifiers & optionKey)); break; case FLsavem: if (TelInfo->numwindows<1) break; SaveSet(1, (modifiers & optionKey)); break; case FLbin: /* Toggle MacBinary on/off */ TelInfo->MacBinary = !TelInfo->MacBinary; if (TelInfo->MacBinary) { CheckItem(myMenus[Fil], FLbin,TRUE); } else { CheckItem(myMenus[Fil], FLbin,FALSE); } break; case FLlog: /* Toggle FTP window on/off*/ TelInfo->ftplogon=!TelInfo->ftplogon; if(TelInfo->ftplogon) { CheckItem(myMenus[Fil],FLlog,TRUE); RSshow(ftplog->vs); SelectWindow(ftplog->wind); } else { CheckItem(myMenus[Fil],FLlog,FALSE); RShide(ftplog->vs); } break; case FLotp: otpinterface(0, 0, 0, 0, 0, 0, 0); break; case FLprint: /* Print Selection (or gr) */ PrintSelection(); break; case FLselect: SaveSelectionToFile(); break; case FLupload: if (TelInfo->numwindows<1) break; uploadFile(); break; case FLpset: /* Set up for printer */ PrintPageSetup(); break; case FLquit: (void) HandleQuit(); break; } break; case editMenu: case NeditMenu: if (!SystemEdit(theItem-1)) { /* Is this mine? */ switch(theItem) { case EDcut: if (TelInfo->macrosModeless) if (TelInfo->macrosModeless == FrontWindow()) { DialogCut(TelInfo->macrosModeless); ZeroScrap(); TEToScrap(); break; } break; case EDclear: if (TelInfo->macrosModeless) if (TelInfo->macrosModeless == FrontWindow()) { DialogDelete(TelInfo->macrosModeless); break; } break; case EDcopy: /* Copy */ if (TelInfo->macrosModeless) if (TelInfo->macrosModeless == FrontWindow()) { DialogCopy(TelInfo->macrosModeless); ZeroScrap(); TEToScrap(); break; } i = MacRGfindwind(FrontWindow()); /* is ICR window? */ if (i >= 0) MacRGcopy(FrontWindow()); /* copy the ICR window */ else { i=RGgetdnum(FrontWindow()); if (i>-1) /* Copy Graphics */ copyGraph( i); else /* Copy Text */ if ( (i=RSfindvwind(FrontWindow())) >-1) copyText( i); } break; case EDcopyt: /* Copy Table */ /* * tech note #180 trick to get MultiFinder to pay attention */ if (!SystemEdit(EDcopy-1)) { /* tell it we did a copy */ i=RGgetdnum(FrontWindow()); if (i>-1) /* Copy Graphics */ copyGraph( i); else /* Copy Text */ if ( (i=RSfindvwind(FrontWindow())) >-1) copyTable( i); } break; case EDpaste: /* Paste */ if (TelInfo->macrosModeless) if (TelInfo->macrosModeless == FrontWindow()) { TEFromScrap(); DialogPaste(TelInfo->macrosModeless); break; } if (TelInfo->numwindows<1) break; else paste(); /* Paste if there is a wind to do to*/ break; case EDretype: if (TelInfo->numwindows<1) break; i = MacRGfindwind(FrontWindow()); /* is ICR window? */ if (i >= 0) break; else { i=RGgetdnum(FrontWindow()); if (i>-1) /* Copy Graphics */ break; else /* Copy Text */ if ( (i=RSfindvwind(FrontWindow())) >-1) autoPaste( i); } break; case EDmacros: /* Set them Macros */ Macros(); break; case EDmacros+2: Cenviron(); break; case EDmacros+5: Cftp(); break; case EDmacros+4: EditConfigType(SESSIONPREFS_RESTYPE, &EditSession); CheckOpSpecSubmenu(); break; case EDmacros+3: EditConfigType(TERMINALPREFS_RESTYPE, &EditTerminal); break; case EDmacros+6: EditConfigType(FTPUSER, &EditFTPUser); default: break; } } break; case connMenu: case NconnMenu: if (theItem == COnext) { if (TelInfo->numwindows >1) { short scratchshort; if (!(modifiers & shiftKey)) //go forward { scratchshort = WindowPtr2ScreenIndex(FrontWindow()) + 1; // Skip over inactive connections while( (screens[scratchshort].active != CNXN_ACTIVE) && (screens[scratchshort].active != CNXN_ISCORPSE) && (scratchshort <= TelInfo->numwindows+1)) scratchshort++; if ((scratchshort < 0) || (scratchshort >= TelInfo->numwindows)) scratchshort = 0; } else //go backward { scratchshort = WindowPtr2ScreenIndex(FrontWindow()) - 1; // Skip over inactive connections while( (screens[scratchshort].active != CNXN_ACTIVE) && (screens[scratchshort].active != CNXN_ISCORPSE) && (scratchshort >= 0)) scratchshort--; if ((scratchshort < 0) || (scratchshort >= TelInfo->numwindows)) scratchshort = TelInfo->numwindows - 1; } SelectWindow(screens[scratchshort].wind); } break; } if (theItem == COtitle) { ChangeWindowName(FrontWindow()); break; } if (theItem >= FIRST_CNXN_ITEM) { if ((theItem - FIRST_CNXN_ITEM-1)>(TelInfo->numwindows+1)) break; /* rotten danish */ if (screens[theItem - FIRST_CNXN_ITEM].active != CNXN_ACTIVE) { displayStatus(theItem - FIRST_CNXN_ITEM); /* Tell them about it..... */ break; } else { HiliteWindow(screens[scrn].wind, FALSE); changeport(scrn,(theItem - FIRST_CNXN_ITEM)); if (!(modifiers & optionKey)) SelectWindow(screens[scrn].wind); else HiliteWindow(screens[scrn].wind, TRUE); } } break; case netMenu: case NnetMenu: switch(theItem) { case NEftp: /* Send FTP command */ case NEip: /* Send IP Number */ if (TelInfo->numwindows<1) break; { char tmpout[30]; /* Basically the same except for */ unsigned char tmp[4]; /* The ftp -n phrase in NEftp */ if (screens[scrn].echo && (screens[scrn].kblen>0)) { netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen);/* if not empty send buffer */ screens[scrn].kblen=0; } netgetip(tmp); if (theItem == NEftp) { if ((gFTPServerPrefs->ServerState == 1) && !(modifiers & shiftKey)) sprintf(tmpout,"ftp -n %d.%d.%d.%d\015\012",tmp[0],tmp[1],tmp[2],tmp[3]); else sprintf(tmpout,"ftp %d.%d.%d.%d\015\012",tmp[0],tmp[1],tmp[2],tmp[3]); } else sprintf(tmpout,"%d.%d.%d.%d",tmp[0],tmp[1],tmp[2],tmp[3]); netwrite(screens[scrn].port,tmpout,strlen(tmpout)); if (screens[scrn].echo) VSwrite(screens[scrn].vs,tmpout, strlen(tmpout)); } break; case NEayt: /* Send "Are You There?"*/ if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\366",2); break; case NEao: /* Send "Abort Output"*/ if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\365",2); screens[ scrn].timing = 1; /* set emulate to TMwait */ netwrite(screens[scrn].port, "\377\375\006",3); /* send TM */ break; case NEinter: /* Send "Interrupt Process"*/ if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\364",2); screens[ scrn].timing = 1; /* set emulate to TMwait */ netwrite(screens[scrn].port, "\377\375\006",3); /* send TM */ break; case NEbrk: if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\363",2); // IAC BRK break; case NEsync: if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netUrgent(); // This must be sent TCP Urgent. netwrite(screens[scrn].port, "\377\362",2); // IAC DM break; case NEipsync: if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\364", 2); // IAC IP netpush(screens[scrn].port); netUrgent(); // This must also be sent TCP Urgent. netwrite(screens[scrn].port, "\377\362", 2); // IAC DM netpush(screens[scrn].port); screens[scrn].timing = 1; // set emulate to TMwait netwrite(screens[scrn].port, "\377\375\006", 3); // send Timing Mark break; case NEeof: // End Of File if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\354", 2); netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\375\006", 3); break; case NEsusp: if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\355", 2); netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\375\006", 3); break; case NEabort: // Abort if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\356", 2); netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\375\006", 3); break; case NEec: /* Send "Erase Character"*/ if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\367",2); break; case NEel: /* Send "Erase Line"*/ if (TelInfo->numwindows<1) break; netpush(screens[scrn].port); netwrite(screens[scrn].port, "\377\370",2); break; case NEscroll: /* Suspend Network */ TelInfo->ScrlLock=!TelInfo->ScrlLock; if (TelInfo->ScrlLock) CheckItem(myMenus[Net], NEscroll,TRUE); else CheckItem(myMenus[Net], NEscroll,FALSE); break; case NEnet: /* Show Network Numbers */ showNetNumbers(); break; default: break; } break; case termMenu: case NtermMenu: switch(theItem) { case EMsuspend: if (TelInfo->numwindows < 1) break; screens[scrn].enabled = !screens[scrn].enabled; if (screens[scrn].enabled) CheckItem( myMenus[Emul], EMsuspend, FALSE); else CheckItem( myMenus[Emul], EMsuspend, TRUE); break; case EMclrlines: // clear saved lines if (TelInfo->numwindows < 1) break; VSrealloc(screens[scrn].vs); break; case EMbs: /* Backspace for backspace */ if (TelInfo->numwindows<1) break; CheckItem(myMenus[Emul], EMbs+screens[scrn].bsdel,FALSE); screens[scrn].bsdel=0; CheckItem(myMenus[Emul], EMbs+screens[scrn].bsdel,TRUE); break; case EMdel: /* Delete for backspace */ if (TelInfo->numwindows<1) break; CheckItem(myMenus[Emul], EMbs+screens[scrn].bsdel,FALSE); screens[scrn].bsdel=1; CheckItem(myMenus[Emul], EMbs+screens[scrn].bsdel,TRUE); break; case EMecho: /* Toggle Local Echo (if poss.) */ if (TelInfo->numwindows < 1) break; if (screens[scrn].echo && (screens[scrn].kblen>0)) { netwrite( screens[scrn].port, screens[scrn].kbbuf, screens[scrn].kblen); /* if not empty send buffer */ screens[scrn].kblen=0; } screens[scrn].echo= !screens[scrn].echo; /* toggle */ if (screens[scrn].echo) { /* LOCAL ECHO */ if (!(modifiers & optionKey) && (screens[scrn].protocol == 0)) send_dont(screens[scrn].port,1); CheckItem(myMenus[Emul],EMecho,TRUE); } else { /* REMOTE ECHO */ if (!(modifiers & optionKey) && (screens[scrn].protocol == 0)) send_do(screens[scrn].port,1); CheckItem(myMenus[Emul],EMecho,FALSE); } break; case EMwrap: /* wrap mode */ if (TelInfo->numwindows < 1) break; if (!screens[scrn].wrap) { /* is off, turn on */ screens[scrn].wrap = 1; CheckItem( myMenus[Emul],EMwrap, TRUE); VSwrite(screens[scrn].vs, "\033[?7h",5); /* kick emulator */ } else { screens[scrn].wrap = 0; CheckItem( myMenus[Emul],EMwrap, FALSE); VSwrite(screens[scrn].vs, "\033[?7l",5); } break; case EMarrowmap: /* JMB */ if (TelInfo->numwindows < 1) break; /* JMB */ screens[scrn].arrowmap = !screens[scrn].arrowmap; /* JMB */ if (screens[scrn].arrowmap) /* JMB */ CheckItem( myMenus[Emul], EMarrowmap, TRUE); /* JMB */ else /* JMB */ CheckItem( myMenus[Emul], EMarrowmap, FALSE); /* JMB */ break; /* JMB */ case EMcrmap: if (TelInfo->numwindows < 1) break; screens[scrn].crmap = !screens[scrn].crmap; if (screens[scrn].crmap) CheckItem( myMenus[Emul], EMcrmap, TRUE); else CheckItem( myMenus[Emul], EMcrmap, FALSE); break; case EMansi: if (TelInfo->numwindows < 1) break; screens[scrn].ANSIgraphics = !screens[scrn].ANSIgraphics; if (screens[scrn].ANSIgraphics) CheckItem( myMenus[Emul], EMansi, TRUE); else CheckItem( myMenus[Emul], EMansi, FALSE); break; case EMxterm: if (TelInfo->numwindows < 1) break; screens[scrn].Xterm = !screens[scrn].Xterm; if (screens[scrn].Xterm) CheckItem( myMenus[Emul], EMxterm, TRUE); else CheckItem( myMenus[Emul], EMxterm, FALSE); break; case EMmapd: if (TelInfo->numwindows < 1) break; screens[scrn].remapCtrlD = !screens[scrn].remapCtrlD; if (screens[scrn].remapCtrlD) CheckItem( myMenus[Emul], EMmapd, TRUE); else CheckItem( myMenus[Emul], EMmapd, FALSE); break; case EMbold: if (TelInfo->numwindows < 1) break; screens[scrn].allowBold = !screens[scrn].allowBold; if (screens[scrn].allowBold) CheckItem( myMenus[Emul], EMbold, TRUE); else CheckItem( myMenus[Emul], EMbold, FALSE); RSchangebold(screens[scrn].vs, screens[scrn].allowBold, screens[scrn].colorBold, screens[scrn].inversebold); break; case EMboldcolor: if (TelInfo->numwindows < 1) break; screens[scrn].colorBold = !screens[scrn].colorBold; if (screens[scrn].colorBold) CheckItem( myMenus[Emul], EMboldcolor, TRUE); else CheckItem( myMenus[Emul], EMboldcolor, FALSE); RSchangebold(screens[scrn].vs, screens[scrn].allowBold, screens[scrn].colorBold, screens[scrn].inversebold); break; case EMinverse: if (TelInfo->numwindows < 1) break; screens[scrn].inversebold = !screens[scrn].inversebold; if (screens[scrn].inversebold) CheckItem( myMenus[Emul], EMinverse, TRUE); else CheckItem( myMenus[Emul], EMinverse, FALSE); RSchangebold(screens[scrn].vs, screens[scrn].allowBold, screens[scrn].colorBold, screens[scrn].inversebold); break; case EMbeep: if (TelInfo->numwindows < 1) break; screens[scrn].ignoreBeeps = !screens[scrn].ignoreBeeps; if (screens[scrn].ignoreBeeps) CheckItem( myMenus[Emul], EMbeep, TRUE); else CheckItem( myMenus[Emul], EMbeep, FALSE); VSbeepcontrol(screens[scrn].vs, screens[scrn].ignoreBeeps); break; case EMeightbit: if (TelInfo->numwindows < 1) break; screens[scrn].eightbit = !screens[scrn].eightbit; if (screens[scrn].eightbit) CheckItem( myMenus[Emul], EMeightbit, TRUE); else CheckItem( myMenus[Emul], EMeightbit, FALSE); break; case EMmapkeypad: if (TelInfo->numwindows < 1) break; screens[scrn].keypadmap = !screens[scrn].keypadmap; if (screens[scrn].keypadmap) CheckItem( myMenus[Emul], EMmapkeypad, TRUE); else CheckItem( myMenus[Emul], EMmapkeypad, FALSE); break; case EMpgupdwn: if (TelInfo->numwindows < 1) break; /* JMB */ screens[scrn].pgupdwn = !screens[scrn].pgupdwn; /* JMB */ if (screens[scrn].pgupdwn) /* JMB */ CheckItem( myMenus[Emul], EMpgupdwn, TRUE); /* JMB */ else /* JMB */ CheckItem( myMenus[Emul], EMpgupdwn, FALSE); /* JMB */ break; /* JMB */ case EMscroll: /* Scrollback on CLS */ if (TelInfo->numwindows<1) break; screens[scrn].ESscroll = !screens[scrn].ESscroll; VSscrolcontrol( screens[scrn].vs, -1, screens[scrn].ESscroll); if (screens[scrn].ESscroll) CheckItem(myMenus[Emul],EMscroll, TRUE); else CheckItem(myMenus[Emul],EMscroll, FALSE); break; case EMpage: /* TEK page command */ if (TelInfo->numwindows<1) break; parse( &screens[scrn], (unsigned char *) "\033\014",2); /* BYU LSC */ break; case EMclear: /* BYU 2.4.8 - Clear on TEK page */ if (TelInfo->numwindows<1) break; screens[scrn].tekclear = !screens[scrn].tekclear; if (screens[scrn].tekclear) CheckItem(myMenus[Emul],EMclear, TRUE); else CheckItem(myMenus[Emul],EMclear, FALSE); break; case EMscreensize: if (TelInfo->numwindows<1) break; /* NCSA: SB */ SetScreenDimensions((short)scrn, modifiers); /* NCSA: SB */ break; case EMreset: /* Reset Screen */ //RESTORE WRAP AFTER THE RESET!!! BUGG if (TelInfo->numwindows<1) break; doWrap = screens[scrn].wrap; VSreset(screens[scrn].vs); /* Reset it */ screens[scrn].timing=0; if (doWrap) VSwrite(screens[scrn].vs, "\033[?7h",5); else CheckItem( myMenus[Emul],EMwrap, FALSE); break; case EMjump: /* Jump Scroll */ if (TelInfo->numwindows<1) break; FlushNetwork(scrn); /* Flush it */ break; case EMsetup: /* need dialog to enter new key values */ setupkeys(); break; case EMcolor: /* Set color */ if (TelInfo->numwindows<1) break; if (TelInfo->haveColorQuickDraw) RScprompt(screens[scrn].vs); break; case EMAnsiColor: if (TelInfo->haveColorQuickDraw) { SetUpMovableModalMenus(); AnsiPrompt(0, 0); ResetMenus(); RSUpdatePalette(); } return; case EMqprint: screens[scrn].qprint = !screens[scrn].qprint; CheckItem(myMenus[Emul], EMqprint, screens[scrn].qprint); VSsetprintmode(screens[scrn].vs, screens[scrn].qprint); break; case EMff: screens[scrn].ignoreff = !screens[scrn].ignoreff; CheckItem(myMenus[Emul], EMff, screens[scrn].ignoreff); break; case EMcapture: /* BYU 2.4.18 - Capture session to file */ if (VSiscapturing(screens[scrn].vs)) { /* BYU 2.4.18 */ CloseCaptureFile(screens[scrn].vs); /* BYU 2.4.18 */ } else { /* BYU 2.4.18 */ if(VSopencapture(scrn, screens[scrn].vs)) /* BYU 2.4.18 */ CheckItem(myMenus[Emul], EMcapture,TRUE); /* BYU 2.4.18 */ } /* BYU 2.4.18 */ break; /* BYU 2.4.18 */ default: break; } break; case fontMenu: if (TelInfo->numwindows>0) { short itemFontNum; Str255 temp; GetMenuItemText( myMenus[Font], theItem, temp); GetFNum( temp, &itemFontNum); RSchangefont( screens[scrn].vs, itemFontNum, 0); screens[scrn].cachedFontNum = theItem; CheckFonts(); } break; case fontMenu2: if (TelInfo->numwindows>0) { short itemFontNum; Str255 temp; GetMenuItemText( myMenus[FontOther], theItem, temp); GetFNum( temp, &itemFontNum); RSchangeboldfont( screens[scrn].vs, itemFontNum); screens[scrn].cachedBoldFontNum = theItem; CheckFonts(); } break; case sizeMenu: if (TelInfo->numwindows>0) { long itemFontSize; short currentSize, junk; Str255 temp; short numOfItems; numOfItems = CountMItems(myMenus[Sizem]); if (numOfItems == theItem) //use picked 'other...' { RSgetfont(screens[scrn].vs, &junk, ¤tSize); itemFontSize = SetOtherFontSize(currentSize); } else { GetMenuItemText( myMenus[Sizem], theItem, temp); /* JMB 2.6 -- Much safer to do it */ StringToNum(temp, &itemFontSize); /* this way! */ } RSchangefont( screens[scrn].vs, -1, itemFontSize); CheckFonts(); } break; case opspecMenu: // JMB switch (theItem) { case 1: EditConfigType(SESSIONPREFS_RESTYPE, &EditSession); CheckOpSpecSubmenu(); break; default: OpenPortSpecial(myMenus[OpSpec], theItem); } break; // JMB case prefsMenu: switch(theItem) { case prfGlobal: Cenviron(); break; case prfFTP: Cftp(); break; case prfSess: EditConfigType(SESSIONPREFS_RESTYPE, &EditSession); CheckOpSpecSubmenu(); break; case prfTerm: EditConfigType(TERMINALPREFS_RESTYPE, &EditTerminal); break; case prfFTPUser: EditConfigType(FTPUSER, &EditFTPUser); } break; case transMenu: if (TelInfo->numwindows>0) { CheckNational(theItem-1); // Set up the menu transBuffer(screens[scrn].national, theItem-1); // Translate the scrollback buffer // and redraw the screen VSredraw(screens[scrn].vs,0,0,VSmaxwidth(screens[scrn].vs),VSgetlines(screens[scrn].vs)-1); /* LU */ screens[scrn].national = theItem-1; } break; case keyMenu: KeyMenu(theItem, modifiers & shiftKey); break; case funcMenu: FuncMenu(theItem, modifiers & shiftKey); break; default: break; } HiliteMenu(0); } /* HandleMenuCommand */ // Take the user's new translation choice and make sure the proper tables exist to do // the translations. If there is a problem, return the default translation as the chouce. void CheckNational(short choice) { short i; for(i=1; i<=(nNational+1);i++) if ((choice+1) == i) /* Check the Current NatLang */ CheckItem( myMenus[National], i, TRUE); else CheckItem( myMenus[National], i, FALSE); } /* * extractmenu - remove a connection from the menu. */ void extractmenu(short screen) { DeleteMenuItem(myMenus[Conn], screen + FIRST_CNXN_ITEM); AdjustMenus(); } /* * addinmenu - add a connection's name to the menu in position pnum. (name is * an str255 pointed at by temps). */ void addinmenu( short screen, Str255 temps, char mark) { InsertMenuItem(myMenus[Conn], "\pDoh", (screen-1) + FIRST_CNXN_ITEM); SetMenuItemText(myMenus[Conn], screen + FIRST_CNXN_ITEM, temps); // Avoid metas SetItemMark( myMenus[Conn], screen + FIRST_CNXN_ITEM, mark); AdjustMenus(); } /* Set the item mark for to opening connection */ void SetMenuMarkToOpeningForAGivenScreen( short scrn) { unsigned char c=0xa5; SetItemMark( myMenus[Conn], scrn + FIRST_CNXN_ITEM, c ); } /* Set the item mark for to opened connection */ void SetMenuMarkToLiveForAGivenScreen( short scrn) { SetItemMark( myMenus[Conn], scrn + FIRST_CNXN_ITEM, noMark); AdjustMenus(); } void DoTheMenuChecks(void) { short active; short windownum; if (TelInfo->numwindows>0) { EnableItem( myMenus[Conn],0); if (gApplicationPrefs->KeyPadAndFuncMenus) { /* Baylor */ EnableItem(myMenus[Keypad], 0); /* Baylor */ EnableItem(myMenus[Function], 0); /* Baylor */ } DrawMenuBar(); } else { DisableItem(myMenus[Conn],0); if (gApplicationPrefs->KeyPadAndFuncMenus) { /* Baylor */ DisableItem(myMenus[Keypad], 0); /* Baylor */ DisableItem(myMenus[Function], 0); /* Baylor */ } DrawMenuBar(); } active =0; for (windownum=0;windownumnumwindows;windownum++) if (screens[windownum].active == CNXN_ACTIVE) active++; if (active<2) DisableItem(myMenus[Conn],COnext); else EnableItem(myMenus[Conn],COnext); if (!active) { DisableItem(myMenus[Edit],EDpaste); DisableItem(myMenus[Emul],0); DrawMenuBar(); } else { EnableItem(myMenus[Edit],EDpaste); EnableItem( myMenus[Emul],0); DrawMenuBar(); } if (TelInfo->macrosModeless) if (FrontWindow() == TelInfo->macrosModeless) { EnableItem(myMenus[Edit],EDcut); EnableItem(myMenus[Edit],EDcopy); EnableItem(myMenus[Edit],EDpaste); EnableItem(myMenus[Edit],EDclear); } } /*--------------------------------------------------------------------------*/ /* SetupMenusForSelection */ /* If there is a selection on screen, then let the user copy and print. */ /* If not, then, oh well....just disable the menus and forget about it */ /* ...and to think that this good stuff USED to be in rsmac.c. */ /* This is called from RSselect after the user clicks in the window, and */ /* was moved here for modularity - SMB */ /*--------------------------------------------------------------------------*/ void SetMenusForSelection (short selected) /* NCSA: SB */ { /* NCSA: SB */ if (!selected) /* NCSA: SB */ { /* NCSA: SB */ DisableItem(myMenus[Fil],FLprint); /* NCSA: SB */ DisableItem(myMenus[Fil],FLselect); DisableItem(myMenus[Edit],EDcopy); /* NCSA: SB */ DisableItem(myMenus[Edit],EDretype); // RAB BetterTelnet 1.0fc6 DisableItem(myMenus[Edit],EDcopyt); /* NCSA: SB */ } /* NCSA: SB */ else /* NCSA: SB */ { /* NCSA: SB */ EnableItem(myMenus[Fil],FLprint); /* NCSA: SB */ EnableItem(myMenus[Fil],FLselect); EnableItem(myMenus[Edit],EDcopy); /* NCSA: SB */ EnableItem(myMenus[Edit],EDretype); // RAB BetterTelnet 1.0fc6 EnableItem(myMenus[Edit],EDcopyt); /* NCSA: SB */ } /* NCSA: SB */ } /* NCSA: SB */ long SetOtherFontSize(short currentSize) { DialogPtr dtemp; Str255 currentSizeStr, newSizeStr; long newSize; Boolean GoodValue; short ditem; dtemp=GetNewMyDialog( OtherFontDLOG, NULL, kInFront, (void *)ThirdCenterDialog); InitCursor(); GoodValue = 0; while (!GoodValue) { GoodValue = TRUE; NumToString((long) currentSize, currentSizeStr); SetTEText(dtemp, FontSizeTE, currentSizeStr); ditem = 0; while(ditem != DLOGOk && ditem != DLOGCancel) ModalDialog(DLOGwOK_CancelUPP, &ditem); if (ditem == DLOGCancel) { DisposeDialog( dtemp); return currentSize; } GetTEText(dtemp, FontSizeTE, newSizeStr); StringToNum(newSizeStr, &newSize); if (newSize < 4) GoodValue = FALSE; if (!GoodValue) SysBeep(4); } DisposeDialog( dtemp); return (newSize); } /*----------------------------------------------------------------------*/ /* NCSA: SB - SetColumnWidth */ /* Allow the user to FINALLY pick how many columns he wants on the */ /* screen. Set up a dialog box to pick the # of columns, and then */ /* size-up the Telnet screen accordingly. NOTE: The user still needs */ /* to do a "resize", unless he is using NAWS */ /*----------------------------------------------------------------------*/ void SetScreenDimensions(short scrn, short modifiers) { DialogPtr dtemp; Str255 ColumnsSTR, LinesSTR; long columns, lines; short ditem, notgood; dtemp=GetNewMyDialog( SizeDLOG, NULL, kInFront, (void *)ThirdCenterDialog); SetCursor(theCursors[normcurs]); notgood = 1; lines = VSgetlines(screens[scrn].vs); columns = VSgetcols(screens[scrn].vs) + 1; while (notgood) { notgood = 0; /* Default to good */ NumToString(columns, ColumnsSTR); NumToString(lines, LinesSTR); SetTEText(dtemp, ColumnsNumber, ColumnsSTR); SetTEText(dtemp, LinesNumber, LinesSTR); SelectDialogItemText( dtemp, ColumnsNumber, 0, 32767); ditem = 3; while(ditem>2) ModalDialog(DLOGwOK_CancelUPP, &ditem); if (ditem == DLOGCancel) { DisposeDialog( dtemp); return; } GetTEText(dtemp, ColumnsNumber, ColumnsSTR); StringToNum(ColumnsSTR, &columns); GetTEText(dtemp, LinesNumber, LinesSTR); StringToNum(LinesSTR, &lines); if (columns < 10) { columns = 10; notgood = 1; } else if (columns > 132) { columns = 132; notgood = 1; } if (lines < 10) { lines = 10; notgood = 1; } else if (lines > 200) { lines = 200; notgood = 1; } if (notgood) SysBeep(4); } DisposeDialog( dtemp); if (VSsetlines( screens[scrn].vs, lines) < 0) OutOfMemory(-4); else { RScalcwsize( screens[scrn].vs, columns); if ((screens[scrn].naws) && !(modifiers & optionKey)) SendNAWSinfo(&screens[scrn], (short)columns, (short)lines); } updateCursor(1); } void ChangeWindowName(WindowPtr theWindow) { DialogPtr dptr; short itemHit; Str255 theName; if( theWindow != NULL) { InitCursor(); dptr = GetNewMySmallDialog(WinTitlDLOG, NULL, kInFront, (void *)ThirdCenterDialog ); GetWTitle(theWindow, theName); SetTEText( dptr, kWinNameTE, theName); SelectDialogItemText( dptr, kWinNameTE, 0, 250 ); itemHit = 0; while(itemHit != DLOGOk && itemHit != DLOGCancel) ModalDialog(DLOGwOK_CancelUPP, &itemHit); if(itemHit == DLOGOk) { GetTEText(dptr, kWinNameTE, theName); set_new_window_name(theName, theWindow); } DisposeDialog(dptr); } } void set_new_window_name(Str255 theName, WindowPtr theWindow) { short i; if(theName[0]) { i = WindowPtr2ScreenIndex(theWindow); if (i >= 0) { i += FIRST_CNXN_ITEM; SetWTitle(theWindow, theName); SetMenuItemText(myMenus[Conn], i, theName); } } } void OpenSpecial(short theItem) { OpenPortSpecial(myMenus[OpSpec], theItem); } void SaveSelectionToFile(void) { short i; if (TelInfo->numwindows<1) return; i = MacRGfindwind(FrontWindow()); /* is ICR window? */ if (i >= 0) return; else { i=RGgetdnum(FrontWindow()); if (i>-1) /* Copy Graphics */ return; else /* Copy Text */ if ( (i=RSfindvwind(FrontWindow())) >-1) SaveThisSelection( i); } } void SaveThisSelection(short vs) { char **charh; OSErr err; StandardFileReply sfr; short refNum, exist; long tempCount; charh=RSGetTextSel(vs,0); /* Get the text selection */ if (charh == (char **)-1L) OutOfMemory(400); else if (charh != (char **)0L) { /* BYU LSC - Can't do anything without characters */ HLock(charh); /* Lock for putting */ StandardPutFile("\p", "\puntitled", &sfr); if (sfr.sfGood) { if ((err = FSpCreate(&sfr.sfFile, gApplicationPrefs->CaptureFileCreator, 'TEXT', sfr.sfScript)) == dupFNErr) exist = 1; err = FSpOpenDF(&sfr.sfFile, fsWrPerm, &refNum); if (exist) SetEOF(refNum, 0L); tempCount = GetHandleSize(charh); err = FSWrite(refNum, &tempCount, *charh); FSClose(refNum); } HUnlock(charh); /* Unlock for disposal */ DisposeHandle(charh); /* Kill the chars */ } } \ No newline at end of file diff --git a/source/network/MyMacTCPstructures.h b/source/network/MyMacTCPstructures.h index 3e916bc..a2b2add 100755 --- a/source/network/MyMacTCPstructures.h +++ b/source/network/MyMacTCPstructures.h @@ -1 +1 @@ -#define noError 0 #define TCPBUFSIZ (1024*8) #define MAX_FDS_ELEMS 32 #define MAX_SWDS_ELEMS 16 typedef struct exfds { short inuse; /* Is this being used? */ wdsEntry fds; /* The real data */ } exfds; typedef struct StreamRec { // 470 bytes StreamPtr stream; /* Apple's lovely Stream Pointer */ char *buffer; /* Where the immovable TCP buffer is */ short push; /* TRUE if we should push next data block */ char *sbuffer; /* Where the send buffer is */ wdsEntry fds[MAX_FDS_ELEMS]; /* Free Data Structure list */ exfds exFDS[MAX_FDS_ELEMS]; /* exFDS entries */ short maxFDSused; /* Max of the FDS's that have been used */ // int mseg; /* BYU 2.4.15 */ // int service; /* BYU 2.4.15 */ short portType; /* UDATA, PDATA, PFTP, CNXN, NO_TYPE */ Ptr aedata; /* Ptr to Encryption data */ } StreamRec, *StreamRPtr; typedef struct MyTCPpb { // 106 Bytes TCPiopb pb; long SavedA5; } MyTCPpb, *MyTCPpbPtr; \ No newline at end of file +#define noError 0 #define TCPBUFSIZ (1024*8) #define MAX_FDS_ELEMS 32 #define MAX_SWDS_ELEMS 16 typedef struct exfds { short inuse; /* Is this being used? */ wdsEntry fds; /* The real data */ } exfds; typedef struct MyTCPpb { // 106 Bytes TCPiopb pb; long SavedA5; } MyTCPpb, *MyTCPpbPtr; typedef struct StreamRec { // 470 bytes StreamPtr stream; /* Apple's lovely Stream Pointer */ char *buffer; /* Where the immovable TCP buffer is */ short push; /* TRUE if we should push next data block */ short urgentMode; // we are receiving urgent data // (RAB BetterTelnet 2.0b2) short nextRecvUrgent; // and the next packet is urgent too char *sbuffer; /* Where the send buffer is */ wdsEntry fds[MAX_FDS_ELEMS]; /* Free Data Structure list */ exfds exFDS[MAX_FDS_ELEMS]; /* exFDS entries */ short maxFDSused; /* Max of the FDS's that have been used */ // int mseg; /* BYU 2.4.15 */ // int service; /* BYU 2.4.15 */ short portType; /* UDATA, PDATA, PFTP, CNXN, NO_TYPE */ Ptr aedata; /* Ptr to Encryption data */ MyTCPpbPtr pbp; // RAB BetterTelnet 2.0b2 - // save params for async port rotation } StreamRec, *StreamRPtr; \ No newline at end of file diff --git a/source/network/mydnr.c b/source/network/mydnr.c index 900a2c5..4a99492 100755 --- a/source/network/mydnr.c +++ b/source/network/mydnr.c @@ -1 +1 @@ -/* * Util.c * utility library for use with the Network kernel * * version 2, full session layer, TK started 6/17/87 */ // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #ifdef MPW #pragma segment DNR #endif #include "InternalEvents.h" #include "wind.h" #include "bkgr.proto.h" #include "netevent.proto.h" #include "mydnr.proto.h" #include "Connections.proto.h" #include "AddressXlation.h" extern long MyA5; extern WindRec *screens; #ifdef __MWERKS__ #pragma profile off #endif typedef struct { short screen; long MyA5; OSErr theError; Str63 hostname; struct hostInfo *hinfo; } DNRDelayStruct; // for async name resolution pascal void DNRDone(struct hostInfo *hostInfoPtr, DNRDelayStruct *info); pascal void DNRDoneInit(struct hostInfo *hostInfoPtr, DNRDelayStruct *info); PROTO_UPP(DNRDoneInit, Result); // for reverse name lookup pascal void DNRDone2(struct hostInfo *hostInfoPtr, DNRDelayStruct *info); pascal void DNRDone2Init(struct hostInfo *hostInfoPtr, DNRDelayStruct *info); PROTO_UPP(DNRDone2Init, Result); /********************************************************************** * DotToNum - turn an address in dotted decimal into an internet address * returns True if the conversion was successful. This routine is * somewhat limited, in that it will accept only four octets, and does * not permit the abbreviated forms for class A and B networks. <- Steve Dorner **********************************************************************/ Boolean DotToNum(BytePtr string,ip_addr *nPtr) { unsigned long address=0; short b=0; BytePtr cp; short dotcount=0; /* * allow leading spaces */ for (cp=string+1;cp<=string+*string;cp++) if (*cp!=' ') break; /* * the address */ for (;cp<=string+*string;cp++) { if (*cp=='.') { if (++dotcount > 3) return (FALSE); /* only 4 octets allowed */ address <<= 8; address |= b; b=0; } else if (isdigit(*cp)) { b *= 10; b += (*cp - '0'); if (b>255) return (FALSE); /* keep it under 256 */ } else if (*cp==' ') /* allow trailing spaces */ break; else return (FALSE); /* periods or digits ONLY */ } /* * final checks, assignment */ if (dotcount!=3) return (FALSE); address <<= 8; address |= b; *nPtr = (ip_addr) address; return(TRUE); } /**************************************************************************/ /* For FTP to look up the transfer options to use when running */ Boolean TranslateIPtoDNSname(ip_addr ipnum, StringPtr machineName) { UNUSED_ARG(ipnum) UNUSED_ARG(machineName) // NEED TO IMPLEMENT THIS BUGG return(FALSE); } /*********************************************************************/ pascal void DNRDone(struct hostInfo *hostInfoPtr, DNRDelayStruct *info) { UNUSED_ARG(hostInfoPtr) netputevent(USERCLASS,DOMAIN_DONE,info->screen, (long)info); } SIMPLE_UPP(DNRDoneInit, Result); pascal void DNRDoneInit(struct hostInfo *hostInfoPtr, DNRDelayStruct *info) { long saveA5; DNRDelayStruct *mptr; struct hostInfo *hptr; mptr = info; hptr = hostInfoPtr; #ifndef __powerpc__ saveA5 = SetA5(mptr->MyA5); #endif DNRDone(hptr, mptr); #ifndef __powerpc__ SetA5(saveA5); #endif } // The following code for reverse DNS lookups was contributed by Dan Hyde. Thanks! // (added in BetterTelnet 1.0fc9 - RAB) /*********************************************************************/ pascal void DNRDone2(struct hostInfo *hostInfoPtr, DNRDelayStruct *info) { UNUSED_ARG(hostInfoPtr) netputevent(USERCLASS,DOMAIN_DONE2,info->screen, (long)info); } SIMPLE_UPP(DNRDone2Init, Result); pascal void DNRDone2Init(struct hostInfo *hostInfoPtr, DNRDelayStruct *info) { long saveA5; DNRDelayStruct *mptr; struct hostInfo *hptr; mptr = info; hptr = hostInfoPtr; #ifndef __powerpc__ saveA5 = SetA5(mptr->MyA5); #endif DNRDone2(hptr, mptr); #ifndef __powerpc__ SetA5(saveA5); #endif } /*********************************************************************/ // // On request, I'm modifying this to do reverse name lookup, too. // The idea is that we should convert the hostname passed to an IP // address (or series of them), and then convert the IP address to a // name. This gives us the particular machine name of a multihomed // hostname, e.g., login.itd.umich.edu, and allows other parts of // this code build the correct .rcmd string for kerberos use. // Dan Hyde, October 1996 // OSErr DoTheDNR(StringPtr hostname, short window) { DNRDelayStruct *Info; struct hostInfo *HInfo; ip_addr ip; Info = (DNRDelayStruct *)myNewPtr(sizeof(DNRDelayStruct)); HInfo = (struct hostInfo *)myNewPtr(sizeof(struct hostInfo)); if ((Info == NULL) || (HInfo == NULL)) return(memFullErr); Info->screen = window; #ifndef __powerpc__ Info->MyA5 = MyA5; #endif Info->hinfo = HInfo; BlockMove(hostname, Info->hostname, Length(hostname)+1); if (DotToNum(hostname, &ip)) { Info->hinfo->rtnCode = noErr; Info->hinfo->addr[0] = ip; DNRDone(HInfo, Info); return(noErr); } PtoCstr(Info->hostname); Info->theError = StrToAddr((char *)Info->hostname, HInfo, DNRDoneInitUPP, (Ptr)Info); if ((Info->theError != cacheFault) && (Info->theError != inProgress)) DNRDone(HInfo, Info); return(noErr); } // The event queue routines send us the screen number that DNRDone sent. We demangle // this mess of data and call CompleteConnectionOpening to do all of the port and screen // stuff that we shouldn't know about at this level. We are merely a non-interrupt level // flow control point. (i.e. I would do this from DNRDone, but that's interrupt time) // RAB BetterTelnet 1.0fc9 - added glue to Dan Hyde's reverse DNS code // Note that, unlike in Dan Hyde's version, reverse DNS is only done here // when Kerberos authentication is turned on. void HandleDomainDoneMessage(short screen, long data2) { DNRDelayStruct *Info = (DNRDelayStruct *)data2; ip_addr the_IP; struct hostInfo *HInfo; OSErr theErr; // The error, if any HInfo = Info->hinfo; the_IP = Info->hinfo->addr[0]; theErr = Info->hinfo->rtnCode; if (!screens[screen].authenticate) { CompleteConnectionOpening(screen, the_IP, theErr, Info->hinfo->cname); // We also dispose of the DNR memory allocations DisposePtr((Ptr)Info->hinfo); DisposePtr((Ptr)Info); } else { // Did things fail? if (theErr || (!the_IP)) { // pass the buck HandleDomainDone2Message(screen, data2); } else { /* Do reverse name lookup */ Info->theError = AddrToName(the_IP, HInfo, DNRDone2InitUPP, (Ptr)Info); if ((Info->theError != cacheFault) && (Info->theError != inProgress)) { DNRDone2(HInfo, Info); } } } } void HandleDomainDone2Message(short screen, long data2) { DNRDelayStruct *Info = (DNRDelayStruct *)data2; ip_addr the_IP; OSErr theErr; // The error, if any the_IP = Info->hinfo->addr[0]; theErr = Info->hinfo->rtnCode; CompleteConnectionOpening(screen, the_IP, theErr, Info->hinfo->cname); // We also dispose of the DNR memory allocations DisposePtr((Ptr)Info->hinfo); DisposePtr((Ptr)Info); } \ No newline at end of file +/* * Util.c * utility library for use with the Network kernel * * version 2, full session layer, TK started 6/17/87 */ // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "InternalEvents.h" #include "wind.h" #include "bkgr.proto.h" #include "netevent.proto.h" #include "mydnr.proto.h" #include "Connections.proto.h" #include "AddressXlation.h" extern long MyA5; extern WindRec *screens; #ifdef __MWERKS__ #pragma profile off #endif typedef struct { short screen; long MyA5; OSErr theError; Str63 hostname; struct hostInfo *hinfo; } DNRDelayStruct; // for async name resolution pascal void DNRDone(struct hostInfo *hostInfoPtr, DNRDelayStruct *info); pascal void DNRDoneInit(struct hostInfo *hostInfoPtr, DNRDelayStruct *info); PROTO_UPP(DNRDoneInit, Result); // for reverse name lookup pascal void DNRDone2(struct hostInfo *hostInfoPtr, DNRDelayStruct *info); pascal void DNRDone2Init(struct hostInfo *hostInfoPtr, DNRDelayStruct *info); PROTO_UPP(DNRDone2Init, Result); /********************************************************************** * DotToNum - turn an address in dotted decimal into an internet address * returns True if the conversion was successful. This routine is * somewhat limited, in that it will accept only four octets, and does * not permit the abbreviated forms for class A and B networks. <- Steve Dorner **********************************************************************/ Boolean DotToNum(BytePtr string,ip_addr *nPtr) { unsigned long address=0; short b=0; BytePtr cp; short dotcount=0; /* * allow leading spaces */ for (cp=string+1;cp<=string+*string;cp++) if (*cp!=' ') break; /* * the address */ for (;cp<=string+*string;cp++) { if (*cp=='.') { if (++dotcount > 3) return (FALSE); /* only 4 octets allowed */ address <<= 8; address |= b; b=0; } else if (isdigit(*cp)) { b *= 10; b += (*cp - '0'); if (b>255) return (FALSE); /* keep it under 256 */ } else if (*cp==' ') /* allow trailing spaces */ break; else return (FALSE); /* periods or digits ONLY */ } /* * final checks, assignment */ if (dotcount!=3) return (FALSE); address <<= 8; address |= b; *nPtr = (ip_addr) address; return(TRUE); } /**************************************************************************/ /* For FTP to look up the transfer options to use when running */ Boolean TranslateIPtoDNSname(ip_addr ipnum, StringPtr machineName) { UNUSED_ARG(ipnum) UNUSED_ARG(machineName) // NEED TO IMPLEMENT THIS BUGG return(FALSE); } /*********************************************************************/ pascal void DNRDone(struct hostInfo *hostInfoPtr, DNRDelayStruct *info) { UNUSED_ARG(hostInfoPtr) netputevent(USERCLASS,DOMAIN_DONE,info->screen, (long)info); } SIMPLE_UPP(DNRDoneInit, Result); pascal void DNRDoneInit(struct hostInfo *hostInfoPtr, DNRDelayStruct *info) { long saveA5; DNRDelayStruct *mptr; struct hostInfo *hptr; mptr = info; hptr = hostInfoPtr; #ifndef __powerpc__ saveA5 = SetA5(mptr->MyA5); #endif DNRDone(hptr, mptr); #ifndef __powerpc__ SetA5(saveA5); #endif } // The following code for reverse DNS lookups was contributed by Dan Hyde. Thanks! // (added in BetterTelnet 1.0fc9 - RAB) /*********************************************************************/ pascal void DNRDone2(struct hostInfo *hostInfoPtr, DNRDelayStruct *info) { UNUSED_ARG(hostInfoPtr) netputevent(USERCLASS,DOMAIN_DONE2,info->screen, (long)info); } SIMPLE_UPP(DNRDone2Init, Result); pascal void DNRDone2Init(struct hostInfo *hostInfoPtr, DNRDelayStruct *info) { long saveA5; DNRDelayStruct *mptr; struct hostInfo *hptr; mptr = info; hptr = hostInfoPtr; #ifndef __powerpc__ saveA5 = SetA5(mptr->MyA5); #endif DNRDone2(hptr, mptr); #ifndef __powerpc__ SetA5(saveA5); #endif } /*********************************************************************/ // // On request, I'm modifying this to do reverse name lookup, too. // The idea is that we should convert the hostname passed to an IP // address (or series of them), and then convert the IP address to a // name. This gives us the particular machine name of a multihomed // hostname, e.g., login.itd.umich.edu, and allows other parts of // this code build the correct .rcmd string for kerberos use. // Dan Hyde, October 1996 // OSErr DoTheDNR(StringPtr hostname, short window) { DNRDelayStruct *Info; struct hostInfo *HInfo; ip_addr ip; Info = (DNRDelayStruct *)myNewPtr(sizeof(DNRDelayStruct)); HInfo = (struct hostInfo *)myNewPtr(sizeof(struct hostInfo)); if ((Info == NULL) || (HInfo == NULL)) return(memFullErr); Info->screen = window; #ifndef __powerpc__ Info->MyA5 = MyA5; #endif Info->hinfo = HInfo; BlockMove(hostname, Info->hostname, StrLength(hostname)+1); if (DotToNum(hostname, &ip)) { Info->hinfo->rtnCode = noErr; Info->hinfo->addr[0] = ip; DNRDone(HInfo, Info); return(noErr); } PtoCstr(Info->hostname); Info->theError = StrToAddr((char *)Info->hostname, HInfo, DNRDoneInitUPP, (Ptr)Info); if ((Info->theError != cacheFault) && (Info->theError != inProgress)) DNRDone(HInfo, Info); return(noErr); } // The event queue routines send us the screen number that DNRDone sent. We demangle // this mess of data and call CompleteConnectionOpening to do all of the port and screen // stuff that we shouldn't know about at this level. We are merely a non-interrupt level // flow control point. (i.e. I would do this from DNRDone, but that's interrupt time) // RAB BetterTelnet 1.0fc9 - added glue to Dan Hyde's reverse DNS code // Note that, unlike in Dan Hyde's version, reverse DNS is only done here // when Kerberos authentication is turned on. void HandleDomainDoneMessage(short screen, long data2) { DNRDelayStruct *Info = (DNRDelayStruct *)data2; ip_addr the_IP; struct hostInfo *HInfo; OSErr theErr; // The error, if any HInfo = Info->hinfo; the_IP = Info->hinfo->addr[0]; theErr = Info->hinfo->rtnCode; if (!screens[screen].authenticate || screens[screen].sockslookup) { CompleteConnectionOpening(screen, the_IP, theErr, Info->hinfo->cname); // We also dispose of the DNR memory allocations DisposePtr((Ptr)Info->hinfo); DisposePtr((Ptr)Info); } else { // Did things fail? if (theErr || (!the_IP)) { // pass the buck HandleDomainDone2Message(screen, data2); } else { /* Do reverse name lookup */ Info->theError = AddrToName(the_IP, HInfo, DNRDone2InitUPP, (Ptr)Info); if ((Info->theError != cacheFault) && (Info->theError != inProgress)) { DNRDone2(HInfo, Info); } } } } void HandleDomainDone2Message(short screen, long data2) { DNRDelayStruct *Info = (DNRDelayStruct *)data2; ip_addr the_IP; OSErr theErr; // The error, if any the_IP = Info->hinfo->addr[0]; theErr = Info->hinfo->rtnCode; CompleteConnectionOpening(screen, the_IP, theErr, Info->hinfo->cname); // We also dispose of the DNR memory allocations DisposePtr((Ptr)Info->hinfo); DisposePtr((Ptr)Info); } \ No newline at end of file diff --git a/source/network/netevent.c b/source/network/netevent.c index a117d25..4b4ff01 100755 --- a/source/network/netevent.c +++ b/source/network/netevent.c @@ -1 +1 @@ -/* * netevent.c * Originally by Gaige B. Paulsen */ // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* Network event handler for NCSA Telnet for the Macintosh * * Called by: * event.c * maclook.c * * NCSA Revisions: * 7/92 Telnet 2.6: added the 2 global structures, and cleaned up defines -- Scott Bulmahn */ #ifdef MPW #pragma segment Network #endif #include "netevent.proto.h" #include "InternalEvents.h" #include "wind.h" #include "mydnr.proto.h" #include "bkgr.proto.h" #include "maclook.proto.h" #include "network.proto.h" #include "menuseg.proto.h" #include "rsinterf.proto.h" #include "vrrgmac.proto.h" #include "tekrgmac.proto.h" #include "vsdata.h" #include "vskeys.h" #include "translate.proto.h" #include "parse.proto.h" #include "Connections.proto.h" #include "event.proto.h" #include "vsinterf.proto.h" #include "telneterrors.h" extern WindRec *screens; /* The screen array from Maclook */ //extern char *tempspot; /* 256 bytes for temp strings */ extern short scrn; short FileInTransit, gBlocksize[MaxSess], /* how large do we make the blocks when we read? */ gQueueError = 0, // Set to 1 if the queue fills up. gQueueLength = 0, // Used to monitor queue length for debugging purposes. gQueueInUse = 0; // Ditto. QHdr gEventsQueue, gEventsFreeQueue; unsigned char *gReadspace = 0; /* main buffer space */ #define PFTP 1 #define PRCP 2 #define PDATA 3 #ifdef __MWERKS__ #pragma profile off #endif // Our "give time" routine void Stask( void) { } // Every time we open or close a network connection, we add or remove a few elements // to/from the queue to assure that there will always be some free elements laying // around. This allows us to avoid Dequeue'ing at interrupt time, which causes // nasty mutex problems since we walk the queue in netgetevent at non-interrupt time. void ChangeQueueLength(short delta) { internal_event *theEvent; if (delta > 0) while (delta != 0) { theEvent = (internal_event *) myNewPtrCritical(sizeof(internal_event)); Enqueue((QElemPtr)theEvent, &gEventsFreeQueue); gQueueLength++; delta--; } else while (delta != 0) { theEvent = (internal_event *)gEventsFreeQueue.qHead; Dequeue((QElemPtr)theEvent, &gEventsFreeQueue); if (theEvent) DisposePtr((Ptr)theEvent); gQueueLength--; delta++; } } /***********************************************************************/ /* netgetevent * Retrieves the next event (and clears it) which matches bits in * the given mask. Returns the event number or -1 on no event present. * Also returns the exact class and the associated integer in reference * parameters. */ short netgetevent( // short mask, short *class, short *data1, long *data2 ) { internal_event *theEvent; short event; //#define QUEUE_STATS #ifdef QUEUE_STATS char qs[255]; static long timer = 0; if (TickCount() - timer > 60*30) { sprintf(qs, "QueueLength: %d, InUse: %d", gQueueLength, gQueueInUse); timer = TickCount(); putln(qs); } #endif QUEUE_STATS if (gQueueError) // Yikes, we actually ran out of queue elements! DebugStr("\pOut of Queue Elements, please quit as quickly as possible!"); // Spin until we hit the end of the queue or if we Dequeue an element that is not // already dequeued. If we don't do this check on Dequeue, someone else could come // in and dequeue an element that we are about to dequeue. Thus, WHAM! we both have // that queue element. while ((theEvent = (internal_event *)gEventsQueue.qHead) != NULL) { if (Dequeue((QElemPtr)theEvent, &gEventsQueue) == noErr) break; } // while ((theEvent != NULL) && !(theEvent->eclass & mask)) // theEvent = (internal_event *)theEvent->qLink; if (theEvent == NULL) return(-1); // (void) Dequeue((QElemPtr)theEvent, &gEventsQueue); *class = theEvent->eclass; *data1 = theEvent->data1; *data2 = theEvent->data2; event = theEvent->event; Enqueue((QElemPtr)theEvent, &gEventsFreeQueue); gQueueInUse--; return(event); } /***********************************************************************/ /* netputevent * add an event to the queue. * Will probably get the memory for the entry from the free list. * Returns 0 if there was room, 1 if an event was lost. */ short netputevent(short theclass, short what, short data1, long data2) { internal_event *theEvent; while ((theEvent = (internal_event *)gEventsFreeQueue.qHead) != NULL) { if (Dequeue((QElemPtr)theEvent, &gEventsFreeQueue) == noErr) break; } if (theEvent == NULL) { gQueueError = 1; // Darn, we filled the queue, alert the user. return(-1); } else gQueueInUse++; theEvent->qType = 0; theEvent->eclass = theclass; theEvent->event = what; theEvent->data1 = data1; theEvent->data2 = data2; Enqueue((QElemPtr)theEvent, &gEventsQueue); return(0); } /***************************************************************************/ /* netputuev * put a unique event into the queue * First searches the queue for like events */ short netputuev(short tclass, short what, short data1, long data2) { internal_event *theEvent = (internal_event *)gEventsQueue.qHead; while((theEvent != NULL) && ((theEvent->eclass != tclass) || (theEvent->event != what) || (theEvent->data1 != data1) || (theEvent->data2 != data2))) theEvent = (internal_event *)theEvent->qLink; if (theEvent != NULL) return(0); return(netputevent(tclass, what, data1, data2)); } void FlushNetwork(short scrn) { short cnt; RSskip(screens[scrn].vs, 1); /* Don't do any output */ cnt = gBlocksize[scrn]; /* just needs to be positive to begin with */ while (cnt>0) { cnt = netread(screens[scrn].port,gReadspace,gBlocksize[scrn]); parse( &screens[scrn ], gReadspace, cnt); } RSskip(screens[scrn].vs, 0); /* Do output now */ SetPort( screens[scrn].wind); InvalRect(&screens[scrn].wind->portRect); /* Don't forget to redraw */ } void pasteText(short scrn) { short amount; long uploadLength; if (!screens[scrn].outlen) return; if (netpush(screens[scrn].port) != 0) { /* BYU 2.4.16 - wait until not busy */ netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */ return; /* BYU 2.4.16 */ } /* BYU 2.4.16 */ if (screens[scrn].incount) { /* BYU 2.4.16 */ screens[scrn].incount = 0; /* BYU 2.4.16 */ screens[scrn].outcount = 0; /* BYU 2.4.16 */ netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */ return; /* BYU 2.4.16 */ } /* BYU 2.4.16 */ if (screens[scrn].outcount < 2) { /* BYU 2.4.16 */ screens[scrn].outcount++; /* BYU 2.4.16 */ netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */ return; /* BYU 2.4.16 */ } if (netqlen(screens[scrn].port) > 0) { /* BYU 2.4.16 - wait until not full */ netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */ return; /* BYU 2.4.16 */ } /* BYU 2.4.16 */ if (!screens[scrn].pastemethod) { // Do this all at once? amount = netwrite(screens[scrn].port, screens[scrn].outptr, screens[scrn].outlen); } else { // Nope, do it in blocks if (screens[scrn].pastesize <= screens[scrn].outlen) amount = screens[scrn].pastesize; else amount = screens[scrn].outlen; amount = netwrite(screens[scrn].port, screens[scrn].outptr, amount); } if (screens[scrn].echo) parse( &screens[scrn],(unsigned char *) screens[scrn].outptr,amount); screens[scrn].outlen -= amount; screens[scrn].outptr += (long) amount; if ((screens[scrn].isUploading) && (screens[scrn].outlen <= 0)) { HLock(screens[scrn].outhand); // Lock the Handle down for safety screens[scrn].outptr = *screens[scrn].outhand; uploadLength = 16384; FSRead(screens[scrn].uploadRefNum, &uploadLength, screens[scrn].outptr); if (uploadLength > 0) { screens[scrn].outlen = uploadLength; // Set the length HUnlock(screens[scrn].outhand); SetHandleSize(screens[scrn].outhand, uploadLength); // now REALLY set the length HLock(screens[scrn].outhand); screens[scrn].clientflags |= PASTE_IN_PROGRESS; if (uploadLength == 16384) { screens[scrn].isUploading = 1; } else { FSClose(screens[scrn].uploadRefNum); screens[scrn].isUploading = 0; } screens[scrn].incount = 0; screens[scrn].outcount = 0; trbuf_mac_nat((unsigned char *)screens[scrn].outptr,screens[scrn].outlen, screens[scrn].national); // LU: translate to national chars netputevent(USERCLASS, PASTELEFT, scrn, 0); return; } } if ( screens[scrn].outlen <=0) { int left; WindRec *tw = &screens[scrn]; tw->clientflags &= ~PASTE_IN_PROGRESS; if (screens[scrn].isUploading) FSClose(screens[scrn].uploadRefNum); HUnlock(tw->outhand); DisposHandle(tw->outhand); tw->outptr = (char *) 0L; tw->outhand = (char **) 0L; //this next loop is to unload the queue of stuff typed during the paste for (left = 0; left < tw->kblen; left++) { if ((tw->kbbuf[left]) == 0) //this signals a VSkey { left++; //send the VS key VSkbsend(tw->vs, (unsigned char) tw->kbbuf[left], tw->echo); } else { netpush(tw->port); if (tw->kbbuf[left+1] != 0x15) //not a KILLCHAR { if (tw->kbbuf[left] == '\015') // remap CR-> CR LF { netwrite(tw->port,"\015\012",2); if (tw->echo) parse(tw,(unsigned char *) "\012\015",2); return; } netwrite(tw->port,&(tw->kbbuf[left]),1); if (tw->echo && (tw->kbbuf[left]>31) && (tw->kbbuf[left] <127)) parse(tw,(unsigned char *)&(tw->kbbuf[left]),1); else if (tw->echo) { tw->kbbuf[left] += '@'; parse(tw,(unsigned char *) "^",1); /* BYU LSC */ parse(tw, (unsigned char *)&(tw->kbbuf[left]), 1); } } else left++; //user cancelled one keystroke with another } } } else netputevent( USERCLASS, PASTELEFT, scrn,0); } void DoNetEvents(void) { long ftptime = 0; short event, class, data1; long data2, pos; if ((event = netgetevent(&class, &data1, &data2)) < 0) return; if ( (TickCount() - ftptime > 60*2) && FileInTransit) { ftptime = TickCount(); Sftpstat(&pos); /* get transfer status */ if (pos <= 0) ftpmess("FTP Status: transferring\015\012"); else { char *temp; temp = myNewPtr(50); //enough room for this string if (temp == NULL) return; //Not enough memory to print status if (FileInTransit+2) sprintf((char *) temp,"FTP Status: %ld bytes remaining.\015\012", pos); /* BYU LSC */ else sprintf((char *) temp,"FTP Status: %ld bytes transferred.\015\012", pos); /* BYU LSC */ ftpmess((char *) temp); /* BYU LSC */ DisposePtr(temp); } } switch(class) { case SCLASS: switch (event) { case FTPACT: ftpd(0, data1); break; case CLOSEDONE: /* Used in the drivers */ netclose(data1); break; case CLOSEDONE+1: /* Used in the drivers */ netclose(data1); break; default: break; } break; case CONCLASS: /* Connection type event */ switch(GetPortType(data1)) { case PFTP: rftpd(event,data1); /* BYU 2.4.16 */ break; case PDATA: ftpd(event,data1); break; default: case CNXN_TYPE: switch (event) { case CONOPEN: /* connection opened or closed */ ConnectionOpenEvent(data1); break; case CONDATA: /* data arrived for me */ ConnectionDataEvent(data1); break; case CONFAIL: ConnectionFailedEvent(data1); break; case CONCLOSE: ConnectionClosedEvent(data1); break; default: break; } break; /* Case port type = CNXN_TYPE */ } break; /* CONCLASS */ case USERCLASS: switch (event) { case DOMAIN_DONE: // data1 = screen #, data2 = ptr to info structure HandleDomainDoneMessage(data1, data2); break; case DOMAIN_DONE2: // data1 = screen #, data2 = ptr to info structure HandleDomainDone2Message(data1, data2); break; case FTPBEGIN: FileInTransit=data1; ftptime=TickCount(); break; case FTPEND: ftpmess("FTP Transfer Concluding\015\012"); ftpmess("\015\012"); FileInTransit=0; break; case FTPCOPEN: { ip_addrbytes ftpinfo; Str255 remoteMachineName; char *temp; if (gFTPServerPrefs->ResetMacBinary) TelInfo->MacBinary = gFTPServerPrefs->UseMacBinaryII; updateMenuChecks(); TelInfo->xferon=1; updateCursor(1); ftpmess("-----------------------------------------------------------------------------\015\012"); ftpmess("FTP server initiated from host: "); temp = myNewPtr(80); ftpinfo.a.addr = Sftphost(); if (temp != NULL) //enough memory to tell the log about the ftp session { if (!TranslateIPtoDNSname(ftpinfo.a.addr, remoteMachineName)) sprintf((char *) &temp[4],"%u.%u.%u.%u\015\012", (unsigned char)ftpinfo.a.byte[0], (unsigned char)ftpinfo.a.byte[1], (unsigned char)ftpinfo.a.byte[2], (unsigned char)ftpinfo.a.byte[3]); else { PtoCstr(remoteMachineName); sprintf((char *) &temp[4],"%s\015\012",remoteMachineName); } ftpmess((char *) &temp[4]); /* BYU LSC */ DisposePtr(temp); } } break; case FTPCLOSE: TelInfo->xferon=0; updateCursor(1); if (gFTPServerPrefs->ResetMacBinary) TelInfo->MacBinary = gFTPServerPrefs->UseMacBinaryII; updateMenuChecks(); ftpmess("FTP server ending session\015\012"); ftpmess("-----------------------------------------------------------------------------\015\012"); ftpmess("\015\012"); break; case RG_REDRAW: /* RGredraw event */ if (VGalive(data1) && RGsupdate(data1)) TekEnable(data1); break; case PASTELEFT: pasteText(data1); break; default: break; } break; /* USERCLASS */ default: break; } /* switch (CLASS) */ } /* DoNetEvents */ /* setblocksize() Make sure that we have space for the block of data that is to be read each time the netread() is called. 2.7: Different gBlockSize for each scrn, same gReadSpace -- CCP */ short setReadBlockSize(short tosize, short scrn) { short currentSize; gBlocksize[scrn] = tosize; /* keep size of block */ if (tosize < 512) /* minimum buffer */ gBlocksize[scrn] = 512; if (gReadspace == NULL) { gReadspace = (unsigned char *) myNewPtrCritical(tosize+100); if (gReadspace == NULL) return -1; //ick--lets handle this better } else { currentSize = (short) GetPtrSize((Ptr)gReadspace); if (currentSize < (tosize+100)) //increase buffer size, if possible { DisposePtr((Ptr)gReadspace); gReadspace = (unsigned char *)myNewPtrCritical(tosize + 100); if (gReadspace == NULL) { if (NULL == (gReadspace = (unsigned char *)myNewPtrCritical(currentSize))) //try to get old size return(-1); //ick--lets handle this better gBlocksize[scrn] = currentSize; } } } return(0); } \ No newline at end of file +/* * netevent.c * Originally by Gaige B. Paulsen */ // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* Network event handler for NCSA Telnet for the Macintosh * * Called by: * event.c * maclook.c * * NCSA Revisions: * 7/92 Telnet 2.6: added the 2 global structures, and cleaned up defines -- Scott Bulmahn */ #include "netevent.proto.h" #include "InternalEvents.h" #include "wind.h" #include "mydnr.proto.h" #include "bkgr.proto.h" #include "maclook.proto.h" #include "network.proto.h" #include "menuseg.proto.h" #include "rsinterf.proto.h" #include "vrrgmac.proto.h" #include "tekrgmac.proto.h" #include "vsdata.h" #include "vskeys.h" #include "translate.proto.h" #include "parse.proto.h" #include "Connections.proto.h" #include "event.proto.h" #include "vsinterf.proto.h" #include "telneterrors.h" extern WindRec *screens; /* The screen array from Maclook */ //extern char *tempspot; /* 256 bytes for temp strings */ extern short scrn; short FileInTransit, gBlocksize[MaxSess], /* how large do we make the blocks when we read? */ gQueueError = 0, // Set to 1 if the queue fills up. gQueueLength = 0, // Used to monitor queue length for debugging purposes. gQueueInUse = 0; // Ditto. QHdr gEventsQueue, gEventsFreeQueue; unsigned char *gReadspace = 0; /* main buffer space */ #define PFTP 1 #define PRCP 2 #define PDATA 3 #ifdef __MWERKS__ #pragma profile off #endif // Our "give time" routine void Stask( void) { } // Every time we open or close a network connection, we add or remove a few elements // to/from the queue to assure that there will always be some free elements laying // around. This allows us to avoid Dequeue'ing at interrupt time, which causes // nasty mutex problems since we walk the queue in netgetevent at non-interrupt time. void ChangeQueueLength(short delta) { internal_event *theEvent; if (delta > 0) while (delta != 0) { theEvent = (internal_event *) myNewPtrCritical(sizeof(internal_event)); Enqueue((QElemPtr)theEvent, &gEventsFreeQueue); gQueueLength++; delta--; } else while (delta != 0) { theEvent = (internal_event *)gEventsFreeQueue.qHead; Dequeue((QElemPtr)theEvent, &gEventsFreeQueue); if (theEvent) DisposePtr((Ptr)theEvent); gQueueLength--; delta++; } } /***********************************************************************/ /* netgetevent * Retrieves the next event (and clears it) which matches bits in * the given mask. Returns the event number or -1 on no event present. * Also returns the exact class and the associated integer in reference * parameters. */ short netgetevent( // short mask, short *class, short *data1, long *data2 ) { internal_event *theEvent; short event; //#define QUEUE_STATS #ifdef QUEUE_STATS char qs[255]; static long timer = 0; if (TickCount() - timer > 60*30) { sprintf(qs, "QueueLength: %d, InUse: %d", gQueueLength, gQueueInUse); timer = TickCount(); putln(qs); } #endif QUEUE_STATS if (gQueueError) // Yikes, we actually ran out of queue elements! DebugStr("\pOut of Queue Elements, please quit as quickly as possible!"); // Spin until we hit the end of the queue or if we Dequeue an element that is not // already dequeued. If we don't do this check on Dequeue, someone else could come // in and dequeue an element that we are about to dequeue. Thus, WHAM! we both have // that queue element. while ((theEvent = (internal_event *)gEventsQueue.qHead) != NULL) { if (Dequeue((QElemPtr)theEvent, &gEventsQueue) == noErr) break; } // while ((theEvent != NULL) && !(theEvent->eclass & mask)) // theEvent = (internal_event *)theEvent->qLink; if (theEvent == NULL) return(-1); // (void) Dequeue((QElemPtr)theEvent, &gEventsQueue); *class = theEvent->eclass; *data1 = theEvent->data1; *data2 = theEvent->data2; event = theEvent->event; Enqueue((QElemPtr)theEvent, &gEventsFreeQueue); gQueueInUse--; return(event); } /***********************************************************************/ /* netputevent * add an event to the queue. * Will probably get the memory for the entry from the free list. * Returns 0 if there was room, 1 if an event was lost. */ short netputevent(short theclass, short what, short data1, long data2) { internal_event *theEvent; while ((theEvent = (internal_event *)gEventsFreeQueue.qHead) != NULL) { if (Dequeue((QElemPtr)theEvent, &gEventsFreeQueue) == noErr) break; } if (theEvent == NULL) { gQueueError = 1; // Darn, we filled the queue, alert the user. return(-1); } else gQueueInUse++; theEvent->qType = 0; theEvent->eclass = theclass; theEvent->event = what; theEvent->data1 = data1; theEvent->data2 = data2; Enqueue((QElemPtr)theEvent, &gEventsQueue); return(0); } /***************************************************************************/ /* netputuev * put a unique event into the queue * First searches the queue for like events */ short netputuev(short tclass, short what, short data1, long data2) { internal_event *theEvent = (internal_event *)gEventsQueue.qHead; while((theEvent != NULL) && ((theEvent->eclass != tclass) || (theEvent->event != what) || (theEvent->data1 != data1) || (theEvent->data2 != data2))) theEvent = (internal_event *)theEvent->qLink; if (theEvent != NULL) return(0); return(netputevent(tclass, what, data1, data2)); } void FlushNetwork(short scrn) { short cnt; RSskip(screens[scrn].vs, 1); /* Don't do any output */ cnt = gBlocksize[scrn]; /* just needs to be positive to begin with */ while (cnt>0) { cnt = netread(screens[scrn].port,gReadspace,gBlocksize[scrn]); parse( &screens[scrn ], gReadspace, cnt); } RSskip(screens[scrn].vs, 0); /* Do output now */ SetPort( screens[scrn].wind); InvalRect(&screens[scrn].wind->portRect); /* Don't forget to redraw */ } void pasteText(short scrn) { short amount; long uploadLength; if (!screens[scrn].outlen) return; if (netpush(screens[scrn].port) != 0) { /* BYU 2.4.16 - wait until not busy */ netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */ return; /* BYU 2.4.16 */ } /* BYU 2.4.16 */ if (screens[scrn].incount) { /* BYU 2.4.16 */ screens[scrn].incount = 0; /* BYU 2.4.16 */ screens[scrn].outcount = 0; /* BYU 2.4.16 */ netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */ return; /* BYU 2.4.16 */ } /* BYU 2.4.16 */ if (screens[scrn].outcount < 2) { /* BYU 2.4.16 */ screens[scrn].outcount++; /* BYU 2.4.16 */ netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */ return; /* BYU 2.4.16 */ } if (netqlen(screens[scrn].port) > 0) { /* BYU 2.4.16 - wait until not full */ netputevent( USERCLASS, PASTELEFT, scrn,0); /* BYU 2.4.16 */ return; /* BYU 2.4.16 */ } /* BYU 2.4.16 */ if (!screens[scrn].pastemethod) { // Do this all at once? amount = netwrite(screens[scrn].port, screens[scrn].outptr, screens[scrn].outlen); } else { // Nope, do it in blocks if (screens[scrn].pastesize <= screens[scrn].outlen) amount = screens[scrn].pastesize; else amount = screens[scrn].outlen; amount = netwrite(screens[scrn].port, screens[scrn].outptr, amount); } if (screens[scrn].echo) parse( &screens[scrn],(unsigned char *) screens[scrn].outptr,amount); screens[scrn].outlen -= amount; screens[scrn].outptr += (long) amount; if ((screens[scrn].isUploading) && (screens[scrn].outlen <= 0)) { HLock(screens[scrn].outhand); // Lock the Handle down for safety screens[scrn].outptr = *screens[scrn].outhand; uploadLength = 16384; FSRead(screens[scrn].uploadRefNum, &uploadLength, screens[scrn].outptr); if (uploadLength > 0) { screens[scrn].outlen = uploadLength; // Set the length HUnlock(screens[scrn].outhand); SetHandleSize(screens[scrn].outhand, uploadLength); // now REALLY set the length HLock(screens[scrn].outhand); screens[scrn].clientflags |= PASTE_IN_PROGRESS; if (uploadLength == 16384) { screens[scrn].isUploading = 1; } else { FSClose(screens[scrn].uploadRefNum); screens[scrn].isUploading = 0; } screens[scrn].incount = 0; screens[scrn].outcount = 0; trbuf_mac_nat((unsigned char *)screens[scrn].outptr,screens[scrn].outlen, screens[scrn].national); // LU: translate to national chars netputevent(USERCLASS, PASTELEFT, scrn, 0); return; } } if ( screens[scrn].outlen <=0) { int left; WindRec *tw = &screens[scrn]; tw->clientflags &= ~PASTE_IN_PROGRESS; if (screens[scrn].isUploading) FSClose(screens[scrn].uploadRefNum); HUnlock(tw->outhand); DisposeHandle(tw->outhand); tw->outptr = (char *) 0L; tw->outhand = (char **) 0L; //this next loop is to unload the queue of stuff typed during the paste for (left = 0; left < tw->kblen; left++) { if ((tw->kbbuf[left]) == 0) //this signals a VSkey { left++; //send the VS key VSkbsend(tw->vs, (unsigned char) tw->kbbuf[left], tw->echo, 0); } else { netpush(tw->port); if (tw->kbbuf[left+1] != 0x15) //not a KILLCHAR { if (tw->kbbuf[left] == '\015') // remap CR-> CR LF { netwrite(tw->port,"\015\012",2); if (tw->echo) parse(tw,(unsigned char *) "\012\015",2); return; } netwrite(tw->port,&(tw->kbbuf[left]),1); if (tw->echo && (tw->kbbuf[left]>31) && (tw->kbbuf[left] <127)) parse(tw,(unsigned char *)&(tw->kbbuf[left]),1); else if (tw->echo) { tw->kbbuf[left] += '@'; parse(tw,(unsigned char *) "^",1); /* BYU LSC */ parse(tw, (unsigned char *)&(tw->kbbuf[left]), 1); } } else left++; //user cancelled one keystroke with another } } } else netputevent( USERCLASS, PASTELEFT, scrn,0); } void DoNetEvents(void) { long ftptime = 0; short event, class, data1; long data2, pos; if ((event = netgetevent(&class, &data1, &data2)) < 0) return; if ( (TickCount() - ftptime > 60*2) && FileInTransit) { ftptime = TickCount(); Sftpstat(&pos); /* get transfer status */ if (pos <= 0) ftpmess("FTP Status: transferring\015\012"); else { char *temp; temp = myNewPtr(50); //enough room for this string if (temp == NULL) return; //Not enough memory to print status if (FileInTransit+2) sprintf((char *) temp,"FTP Status: %ld bytes remaining.\015\012", pos); /* BYU LSC */ else sprintf((char *) temp,"FTP Status: %ld bytes transferred.\015\012", pos); /* BYU LSC */ ftpmess((char *) temp); /* BYU LSC */ DisposePtr(temp); } } switch(class) { case SCLASS: switch (event) { case FTPACT: ftpd(0, data1); break; case CLOSEDONE: /* Used in the drivers */ netclose(data1); break; case CLOSEDONE+1: /* Used in the drivers */ netclose(data1); break; default: break; } break; case CONCLASS: /* Connection type event */ switch(GetPortType(data1)) { case PFTP: rftpd(event,data1); /* BYU 2.4.16 */ break; case PDATA: ftpd(event,data1); break; default: case CNXN_TYPE: switch (event) { case CONOPEN: /* connection opened or closed */ ConnectionOpenEvent(data1); break; case CONDATA: /* data arrived for me */ ConnectionDataEvent(data1); break; case CONFAIL: ConnectionFailedEvent(data1); break; case CONCLOSE: ConnectionClosedEvent(data1); break; default: break; } break; /* Case port type = CNXN_TYPE */ } break; /* CONCLASS */ case USERCLASS: switch (event) { case DOMAIN_DONE: // data1 = screen #, data2 = ptr to info structure HandleDomainDoneMessage(data1, data2); break; case DOMAIN_DONE2: // data1 = screen #, data2 = ptr to info structure HandleDomainDone2Message(data1, data2); break; case FTPBEGIN: FileInTransit=data1; ftptime=TickCount(); break; case FTPEND: ftpmess("FTP Transfer Concluding\015\012"); ftpmess("\015\012"); FileInTransit=0; break; case FTPCOPEN: { ip_addrbytes ftpinfo; Str255 remoteMachineName; char *temp; if (gFTPServerPrefs->ResetMacBinary) TelInfo->MacBinary = gFTPServerPrefs->UseMacBinaryII; updateMenuChecks(); TelInfo->xferon=1; updateCursor(1); ftpmess("-----------------------------------------------------------------------------\015\012"); ftpmess("FTP server initiated from host: "); temp = myNewPtr(80); ftpinfo.a.addr = Sftphost(); if (temp != NULL) //enough memory to tell the log about the ftp session { if (!TranslateIPtoDNSname(ftpinfo.a.addr, remoteMachineName)) sprintf((char *) &temp[4],"%u.%u.%u.%u\015\012", (unsigned char)ftpinfo.a.byte[0], (unsigned char)ftpinfo.a.byte[1], (unsigned char)ftpinfo.a.byte[2], (unsigned char)ftpinfo.a.byte[3]); else { PtoCstr(remoteMachineName); sprintf((char *) &temp[4],"%s\015\012",remoteMachineName); } ftpmess((char *) &temp[4]); /* BYU LSC */ DisposePtr(temp); } } break; case FTPCLOSE: TelInfo->xferon=0; updateCursor(1); if (gFTPServerPrefs->ResetMacBinary) TelInfo->MacBinary = gFTPServerPrefs->UseMacBinaryII; updateMenuChecks(); ftpmess("FTP server ending session\015\012"); ftpmess("-----------------------------------------------------------------------------\015\012"); ftpmess("\015\012"); break; case RG_REDRAW: /* RGredraw event */ if (VGalive(data1) && RGsupdate(data1)) TekEnable(data1); break; case PASTELEFT: pasteText(data1); break; default: break; } break; /* USERCLASS */ default: break; } /* switch (CLASS) */ } /* DoNetEvents */ /* setblocksize() Make sure that we have space for the block of data that is to be read each time the netread() is called. 2.7: Different gBlockSize for each scrn, same gReadSpace -- CCP */ short setReadBlockSize(short tosize, short scrn) { short currentSize; gBlocksize[scrn] = tosize; /* keep size of block */ if (tosize < 512) /* minimum buffer */ gBlocksize[scrn] = 512; if (gReadspace == NULL) { gReadspace = (unsigned char *) myNewPtrCritical(tosize+100); if (gReadspace == NULL) return -1; //ick--lets handle this better } else { currentSize = (short) GetPtrSize((Ptr)gReadspace); if (currentSize < (tosize+100)) //increase buffer size, if possible { DisposePtr((Ptr)gReadspace); gReadspace = (unsigned char *)myNewPtrCritical(tosize + 100); if (gReadspace == NULL) { if (NULL == (gReadspace = (unsigned char *)myNewPtrCritical(currentSize))) //try to get old size return(-1); //ick--lets handle this better gBlocksize[scrn] = currentSize; } } } return(0); } \ No newline at end of file diff --git a/source/network/network.c b/source/network/network.c index 067da80..c8b28e9 100755 --- a/source/network/network.c +++ b/source/network/network.c @@ -1 +1 @@ -// network.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* * NCSA Revisions: * 10/87 Initial source release, Tim Krauskopf * 2/88 typedef support for other compilers (TK) * 8/88 Gaige Paulsen - support for MacTCP drivers * 1/89 TK - conversion to new drivers, minor update for new calling convention * 6/89 TK - update to MacTCP 1.0 include files and use of GetMyIPAddr() * 7/92 Scott Bulmahn - add support for 2 global structs, put cursors into an array * 11/92 Jim Browne - Fixed more bugs than I care to mention. * */ #ifdef MPW #pragma segment Network #endif #include "InternalEvents.h" #include "wind.h" #include "maclook.proto.h" #include "menuseg.proto.h" #include "mainseg.proto.h" #include "MyMacTCPstructures.h" #include "network.proto.h" #include "netevent.proto.h" #include "tnae.h" #include "authencrypt.h" #include "authencrypt.proto.h" #include "AddressXLation.h" #include "errors.proto.h" #include "telneterrors.h" #ifdef THINK_C #pragma options(!profile) #endif #ifdef __MWERKS__ #pragma profile off #endif //#define NET_DEBUG_MUCHINFO //#define NET_DEBUG #ifdef NET_DEBUG char net_debug_string[256]; #define net_debug_print(x) putln(net_debug_string) #else #define net_debug_print(x) #endif //PROTO_UPP(Notify, TCPNotify); //static TCPIOCompletionProcPtr OpenCompleteInit(TCPiopb *pbp); //PROTO_UPP(OpenCompleteInit, TCPIOCompletion); //static TCPIOCompletionProcPtr CloseCompleteInit(TCPiopb *pbp); //PROTO_UPP(CloseCompleteInit, TCPIOCompletion); //static TCPIOCompletionProcPtr SendCompleteInit(TCPiopb *pbp); //PROTO_UPP(SendCompleteInit, TCPIOCompletion); static TCPIOCompletionUPP OpenCompleteInitUPP = nil; static TCPIOCompletionUPP CloseCompleteInitUPP = nil; static TCPIOCompletionUPP SendCompleteInitUPP = nil; static TCPNotifyUPP NotifyUPP = nil; static void OpenComplete(MyTCPpbPtr pbp); static void SendComplete(MyTCPpbPtr pbp); static void CloseComplete(MyTCPpbPtr pbp); pascal void Notify(StreamPtr streamPtr, unsigned short code, Ptr uptr, unsigned short terminReason, struct ICMPReport *icmpMsg); static wdsEntry *getSWDS(void); static void returnSWDS(wdsEntry *wds); static void MyPBreturn(MyTCPpbPtr pbp); static MyTCPpb *getPB(short driver,short call, StreamPtr stream, short usernum); static void clearPB(MyTCPpbPtr pbp, short driver, short call, StreamPtr stream); static OSErr xPBControlSync(MyTCPpbPtr pbp); static OSErr xPBControlAsync(MyTCPpbPtr pbp, TCPIOCompletionUPP completionUPP); static short makestream(void); static void reclaim(StreamRPtr p); static short giveback(StreamRPtr p, wdsEntry *wds); static void compressfds(wdsEntry *fds); static void NetWriteZero(Ptr pointer,long size); //put this here to keep from loading and unlaoding config segment extern Cursor *theCursors[]; extern WindRec *screens; long MyA5; short TCPd = 0; /* refnum of TCP drivers */ QHdr gFreePBQueue; QHdr gFreeSWDSQueue; short numSWDS=0; /* Number of SWDS's ever alloc'd (PM Only) */ StreamRPtr streams[NPORTS]; ip_port nnfromport = 0; Boolean nextIsUrgent = FALSE; //CCP 2.7 (See NetUrgent ()) void NetWriteZero(Ptr pointer,long size) { while (size--) *pointer++ = 0; } /**************************************************************************/ wdsEntry *getSWDS(void) { short n=0; wdsEntry * wds; if (gFreeSWDSQueue.qHead == NULL) wds = (wdsEntry *) myNewPtrCritical( sizeof(wdsEntry) * MAX_SWDS_ELEMS); else { wds = (wdsEntry *) gFreeSWDSQueue.qHead; Dequeue(gFreeSWDSQueue.qHead, &gFreeSWDSQueue); } if (wds == NULL) { /* sorry, cant allocate WDS (BIG PROBLEM) */ DoError(508 | NET_ERRORCLASS, LEVEL3, NULL); // <- Is 508 correct? forcequit(); // return ((wdsEntry*) 0L); <- ?? perhaps } return(wds); } /**************************************************************************/ void returnSWDS(wdsEntry *wds) { Enqueue((QElemPtr)wds, &gFreeSWDSQueue); } /**************************************************************************/ void MyPBreturn(MyTCPpbPtr pbp) { Enqueue((QElemPtr)pbp, &gFreePBQueue); } /**************************************************************************/ MyTCPpb *getPB(short driver,short call, StreamPtr stream, short usernum) { UNUSED_ARG(usernum) MyTCPpb *pbp; if (gFreePBQueue.qHead == NULL) pbp = (MyTCPpbPtr) myNewPtrCritical( sizeof(MyTCPpb) ); else { pbp = (MyTCPpbPtr) gFreePBQueue.qHead; Dequeue(gFreePBQueue.qHead, &gFreePBQueue); } if (pbp == NULL) { /* sorry, cant allocate TCP buffer (BIG PROBLEM) */ DoError(508 | NET_ERRORCLASS, LEVEL3, NULL); forcequit(); } memset((char *) pbp, '\0', sizeof(MyTCPpb)); pbp->pb.ioCRefNum = driver; pbp->pb.tcpStream = stream; pbp->pb.csCode = call; return(pbp); } /**************************************************************************/ void clearPB(MyTCPpbPtr pbp, short driver, short call, StreamPtr stream) { NetWriteZero((Ptr)pbp, sizeof(MyTCPpb)); /* BYU LSC - Default to all zeros */ pbp->pb.ioCRefNum = driver; pbp->pb.tcpStream = stream; pbp->pb.csCode = call; } /**************************************************************************/ OSErr xPBControlSync(MyTCPpbPtr pbp) { pbp->pb.ioCompletion = 0L; /* Charlie will puke if he ever sees */ return PBControl((ParmBlkPtr)(pbp),false); /* his funtions here. -- JMB */ } /**************************************************************************/ OSErr xPBControlAsync(MyTCPpbPtr pbp, TCPIOCompletionUPP completionUPP) { #ifndef __powerpc__ pbp->SavedA5 = MyA5; #endif pbp->pb.ioCompletion = completionUPP; return(PBControl((ParmBlkPtr)(pbp),true)); /* async */ } void SetPortType(short port, short type) { if (port >= 0 && port < NPORTS && (streams[port] != NULL)) streams[port]->portType = type; } short GetPortType(short port) { if (port >= 0 && port < NPORTS && (streams[port] != NULL)) return(streams[port]->portType); else return(-1); } /**************************************************************************/ /* Returns an empty stream */ short makestream(void) { short pnum, i; StreamRPtr p; MyTCPpbPtr pbp; for ( pnum=0; (streams[pnum]!= NULL) && pnum= NPORTS) return(-2); if (!(p = streams[pnum] = (StreamRPtr) myNewPtrCritical(sizeof(StreamRec)))) return(-1); if ((p->buffer = (char *) myNewPtrCritical( TCPBUFSIZ)) == NULL) { DisposePtr((Ptr)p); streams[pnum] = 0; return(-1); } if ((p->sbuffer = (char *) myNewPtrCritical( TCPBUFSIZ)) == NULL) { DisposePtr((Ptr)p->buffer); DisposePtr((Ptr)p); streams[pnum] = 0; return(-1); } for (i=0; ifds[ i].length =0; p->fds[ i].ptr = 0L; p->exFDS[ i].inuse=0; p->exFDS[ i].fds.length=0;p->exFDS[ i].fds.ptr=0L; } p->fds[0].length = TCPBUFSIZ; p->fds[0].ptr = p->sbuffer; p->maxFDSused=0; p->aedata = NULL; pbp=getPB( TCPd, TCPCreate, (long) 0, 7); /* BYU LSC important - Make create call */ pbp->pb.csParam.create.rcvBuff = p->buffer; pbp->pb.csParam.create.rcvBuffLen = TCPBUFSIZ; pbp->pb.csParam.create.notifyProc = NotifyUPP; if (xPBControlSync(pbp) != noError) DoError (512 | NET_ERRORCLASS, LEVEL2, NULL); p->stream = pbp->pb.tcpStream; net_debug_print("Made new stream"); MyPBreturn(pbp); return(pnum); } /**************************************************************************/ /* reclaim( p) - reclaims buffer space to stream (from pointer p) into the FDS list */ void reclaim(StreamRPtr p) { short n=0, offset=0; while (offset < MAX_FDS_ELEMS && p->fds[offset].ptr != 0L) offset++; if (offset >= MAX_FDS_ELEMS) /* offset too large -- cant reclaim */ return; for (n=0 ; nexFDS[ n].inuse) { p->fds[ offset++]=p->exFDS[ n].fds; p->exFDS[ n].inuse = 0; } } } /************************************************************************** giveback( p, wds) - gives WDS entries back to the stream by putting them in the mutually exclusive buffer. p -> stream wds -> wds array */ short giveback(StreamRPtr p, wdsEntry *wds) { short n=0, m=0; while ( n< MAX_SWDS_ELEMS && wds[n].ptr !=0L) { while (m< MAX_FDS_ELEMS && p->exFDS[ m].inuse) m++; if (m >= MAX_FDS_ELEMS) // This was off by one - JMB 2.6 return(-1); /* No room in the RECLAIMation center */ else { p->exFDS[ m].inuse =1; p->exFDS[ m].fds = wds[n]; m++; } n++; } return 0; } /**************************************************************************/ /* compressfds( fds) compress an fds data structure to make everyone happy */ void compressfds(wdsEntry *fds) { short n,m,compressed; compressed = 0; while ( !compressed) { compressed=1; for (n=0; n< MAX_FDS_ELEMS; n++) { /* Slow Forwards */ if (fds[n].ptr) { /* Do if N exists */ for ( m = MAX_FDS_ELEMS -1; m>=0; m--) { /* Fast Backwards */ if (fds[m].ptr && (fds[m].ptr+fds[m].length == fds[n].ptr)) { fds[n].length+=fds[m].length; fds[n].ptr = fds[m].ptr; fds[m].ptr=0L; fds[m].length=0; compressed=0; } #ifdef CHECKBOTHWAYZ else if (fds[n].ptr+fds[n].length == fds[m].ptr) { fds[m].length+=fds[n].length; fds[n].ptr=0L; fds[n].length=0; compressed=0; } #endif CHECKBOTHWAYZ } } } } m=0;n=0; /* Close the gaps */ while (n+m < MAX_FDS_ELEMS) { while (fds[n+m].ptr ==0L && n+m< MAX_FDS_ELEMS) m++; /* increase gap to valid entry */ if (n+m= NPORTS) /* BYU 2.4.15 */ return(-2); if (NULL == (p = streams[pnum])) return(-2); pbp=getPB( TCPd, TCPStatus, p->stream, 1); /* Make status call */ if (xPBControlSync(pbp) != noError) /* status call bombed */ DoError (509 | NET_ERRORCLASS, LEVEL1, "Mnetread"); if (pbp->pb.csParam.status.connectionState !=8) { #ifdef NET_DEBUG sprintf(net_debug_string, "CState: %d is %d",(int)pnum, (int)pbp->pb.csParam.status.connectionState); net_debug_print(net_debug_string); #endif MyPBreturn(pbp); return(-1); /* Connection not established */ } inQ = pbp->pb.csParam.status.amtUnreadData; reqdamt = n >inQ ? inQ : n; clearPB( pbp, TCPd, TCPRcv, p->stream); pbp->pb.csParam.receive.rcvBuff = buffer; pbp->pb.csParam.receive.rcvBuffLen = reqdamt; if (reqdamt<1) { /* Drop out if no data */ MyPBreturn(pbp); return(0); } if ((i = xPBControlSync(pbp)) != noError) { DoError (524 | NET_ERRORCLASS, LEVEL1, NULL); return(-1); } reqdamt = pbp->pb.csParam.receive.rcvBuffLen; if (reqdamtaedata && ((tnParams *)p->aedata)->decrypting) { unsigned char *cp = (unsigned char *)buffer; short len = reqdamt; while (len-- > 0) { *cp = decrypt((tnParams *)p->aedata, (long)(*cp)); cp++; } } MyPBreturn(pbp); return(reqdamt); } //makes the next buffer be sent as urgent data void netUrgent(void) { nextIsUrgent = TRUE; } /************************************************************************/ /* netwrite * write something into the output queue, netsleep routine will come * around and send the data, etc. * */ short netwrite(short pnum, void *buffer, short nsend) { StreamRPtr p; wdsEntry *swds; short remaining, queued, n,m; MyTCPpbPtr pbp; OSErr err; #ifdef NET_DEBUG_MUCHINFO sprintf(net_debug_string, "port: %d\tbuffer: %lx\tnsend %d", pnum, (unsigned int)buffer, (int)nsend); net_debug_print(net_debug_string); #endif if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */ return(-2); if ( (p = streams[pnum]) == NULL) return(-2); if ( !nsend ) return(0); swds = getSWDS(); if (swds == NULL) return(nsend); // Duh, Mr. Bulmahn. - JMB 2.6 reclaim( p); compressfds( p->fds); n=0; remaining = nsend; // if (p->fds[0].ptr == 0) DebugStr("\pArgh! fds[0] is NULL!"); while (p->fds[n].ptr !=0 && remaining>0 ) { // if (n >= MAX_SWDS_ELEMS) DebugStr("\pOverflowing SWDS in while loop!"); swds[n].ptr = p->fds[n].ptr; if ( p->fds[n].length > remaining) { swds[n].length = remaining; p->fds[n].length -= remaining; p->fds[n].ptr += remaining; remaining=0; } else { swds[n].length = p->fds[n].length; remaining -= p->fds[n].length; p->fds[n].length = 0; p->fds[n].ptr = 0; } n++; } if (n>p->maxFDSused) p->maxFDSused=n; compressfds( p->fds); queued = nsend-remaining; for(m=0; maedata && ((tnParams *)p->aedata)->encrypting) encrypt((tnParams *)p->aedata, (unsigned char *)swds[m].ptr, swds[m].length); buffer=(void *)((char *)buffer + swds[m].length); } swds[m].ptr = 0L; swds[m].length=0; pbp=getPB( TCPd, TCPSend, p->stream, 2); /* Make send call */ pbp->pb.csParam.send.wdsPtr = (Ptr) swds; pbp->pb.csParam.send.pushFlag = p->push; pbp->pb.csParam.open.ulpTimeoutValue = (SInt8)gApplicationPrefs->SendTimeout;// timeout value pbp->pb.csParam.open.ulpTimeoutAction = 1; // Abort pbp->pb.csParam.open.validityFlags = 0xC0; // Timeout and action are valid if (nextIsUrgent) { nextIsUrgent = FALSE; pbp->pb.csParam.send.urgentFlag = TRUE; } p->push=0; if ((err = xPBControlAsync(pbp, SendCompleteInitUPP)) != noError) { char temp_xvvyz[256]; sprintf(temp_xvvyz, "netwrite: %d", err); DoError(510 | NET_ERRORCLASS, LEVEL2, temp_xvvyz); return(-1); } return(queued); } /**************************************************************************/ /* Mnetpush * attempt to push the rest of the data from the queue * and then return whether the queue is empty or not (0 = empty) * returns the number of bytes in the queue. */ short netpush(short pnum) { StreamRPtr p; MyTCPpbPtr pbp; short inQ; OSErr err; if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */ return(-2); if (NULL == (p = streams[pnum])) return(-2); pbp=getPB( TCPd, TCPStatus, p->stream, 3); /* Make status call */ //#ifdef NET_DEBUG_MUCHINFO // sprintf(net_debug_string, "TCPd == %d", TCPd); // net_debug_print(net_debug_string); //#endif if ((err = xPBControlSync(pbp)) != noError) { /* status call bombed */ char temp_xvvyz[256]; sprintf(temp_xvvyz, "netpush: %d", err); DoError(509 | NET_ERRORCLASS, LEVEL2, temp_xvvyz); } inQ = pbp->pb.csParam.status.amtUnackedData; MyPBreturn( pbp); p->push=1; return(inQ); } /**************************************************************************/ /* Mnetqlen * return the number of bytes waiting to be read from the incoming queue. */ short netqlen(short pnum) { StreamRPtr p; MyTCPpbPtr pbp; short inQ; if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */ return(-2); if (NULL == (p = streams[pnum])) return(-2); pbp=getPB( TCPd, TCPStatus, p->stream, 4); /* Make status call */ if (xPBControlSync(pbp) != noError) /* status call failed */ DoError(509 | NET_ERRORCLASS, LEVEL2, "Mnetqlen"); inQ = pbp->pb.csParam.status.amtUnreadData; MyPBreturn( pbp); p->push = 1; return(inQ); } /**************************************************************************/ /* Mnetroom() * return how much room is available in output buffer for a connection */ short netroom(short pnum) { StreamRPtr p; short inQ, n; if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */ return(-2); if (NULL == (p = streams[pnum])) return(-2); reclaim( p); compressfds( p->fds); #ifdef OLDM pbp=getPB( TCPd, TCPStatus, p->stream, 5); /* Make status call */ if (xPBControlSync(pbp) != noError) DoError(509 | NET_ERRORCLASS, LEVEL1, "Mnetroom"); inQ = pbp->csParam.status.sendWindow - pbp->csParam.status.amtUnackedData; MyPBreturn( pbp); #else /*#pragma unused(pbp) /* BYU LSC */ #endif inQ = n = 0; while (p->fds[n].ptr) { inQ += p->fds[n].length; /* add up free list space */ n++; } return(inQ); } /**************************************************************************/ void netgetip(unsigned char *st) { struct GetAddrParamBlock mypb; /* long netmask; */ net_debug_print("Attempting getmyipaddr"); NetWriteZero((Ptr)&mypb, sizeof(struct GetAddrParamBlock)); mypb.ioCRefNum = TCPd; /* BYU LSC - TCP driver has to be open by now */ mypb.csCode = ipctlGetAddr; if (PBControl((ParmBlkPtr)&mypb, false) != noError) { DoError(511 | NET_ERRORCLASS, LEVEL2, NULL); return; } BlockMove(&mypb.ourAddress, st, 4); /* BYU LSC - copy the address */ /* netmask is here if we want it, too */ } void netfromport /* next "open" will use this port */ ( short port) { nnfromport = (ip_port)port; } /**************************************************************************/ /* Mnetest? * is a particular session established yet? * Returns 0 if the connection is in the established state. */ short netest(short pnum) { StreamRPtr p; MyTCPpbPtr pbp; short inQ; if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */ return(-2); if (NULL == (p = streams[pnum])) return(-2); pbp=getPB( TCPd, TCPStatus, p->stream, 6); /* Make status call */ if (xPBControlSync(pbp) != noError) { DoError(509 | NET_ERRORCLASS, LEVEL2, "Mnetest"); inQ = -1; } else inQ = pbp->pb.csParam.status.connectionState !=8; MyPBreturn( pbp); return(inQ); } /**************************************************************************/ /* Mnetlisten * Listen to a TCP port number and make the connection automatically when * the SYN packet comes in. The TCP layer will notify the higher layers * with a CONOPEN event. Save the port number returned to refer to this * connection. * * usage: portnum = netlisten(service); * short service; * */ short netlisten(ip_port serv) { short pnum; StreamRPtr p; MyTCPpbPtr pbp; pnum = makestream(); if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */ return(-2); if (NULL == (p = streams[pnum])) return(-2); pbp=getPB( TCPd, TCPPassiveOpen, p->stream, 8); /* Make Listen call */ pbp->pb.csParam.open.localPort = serv; if (xPBControlAsync(pbp, OpenCompleteInitUPP) != noError) DoError(513 | NET_ERRORCLASS, LEVEL2, NULL); return(pnum); /* BYU 2.4.16 */ } /***********************************************************************/ /* Mnetgetftp * Provides the information that ftp needs to open a stream back to the * originator of the command connection. The other side's IP number * and the port numbers to be used to calculate the default data connection * number. Returns values in an integer array for convenient use in * PORT commands. */ short netgetftp(short pnum, ip_addr *addr, ip_port *localPort, ip_port *remotePort) { StreamRPtr p; MyTCPpbPtr pbp; if (pnum < 0) return(-2); if (NULL == (p = streams[pnum])) return(-2); pbp=getPB( TCPd, TCPStatus, p->stream, 9); /* Make status call */ if (xPBControlSync(pbp) != noError) DoError(514 | NET_ERRORCLASS, LEVEL2, NULL); *addr = pbp->pb.csParam.status.remoteHost; *localPort = pbp->pb.csParam.status.localPort; *remotePort = pbp->pb.csParam.status.remotePort; MyPBreturn( pbp); return 0; } /**************************************************************************/ /* Open a network socket for the user. */ short netxopen( ip_addr machine, ip_port service, short timeout ) // in seconds { short pnum; StreamRPtr p; MyTCPpbPtr pbp; pnum = makestream(); if (pnum < 0) return(-2); if (NULL == (p = streams[pnum])) return(-2); pbp=getPB( TCPd, TCPActiveOpen, p->stream, 10); /* Make Listen call */ pbp->pb.csParam.open.remoteHost = machine; /* IP # */ pbp->pb.csParam.open.remotePort = service; /* Port */ pbp->pb.csParam.open.localPort = nnfromport; /* My Port */ pbp->pb.csParam.open.ulpTimeoutValue = (SInt8)timeout; // timeout value pbp->pb.csParam.open.ulpTimeoutAction = 1; // Abort pbp->pb.csParam.open.validityFlags = 0xC0; // Timeout and action are valid nnfromport=0; /* Next one is random */ if (xPBControlAsync(pbp, OpenCompleteInitUPP) != noError) { DoError(515 | NET_ERRORCLASS, LEVEL2, NULL); return(-1); } SetPortType(pnum, NO_TYPE); // Is allocated to the user #ifdef NET_DEBUG sprintf(net_debug_string, "TCPOpen on port #%d", pnum); net_debug_print(net_debug_string); #endif return(pnum); /* BYU 2.4.16 */ } /**************************************************************************/ /* Mnetclose * Do appropriate actions to return connection state to SCLOSED which * enables the memory for that port to be reused. * * Specifically: * o If status is closed, then release the data structures * o If status is not close, perform bkgrd close which generates CLOSEDONE, * which should make the session layer call us again */ short netclose(short pnum) { StreamRPtr p; MyTCPpbPtr pbp; OSErr errorCode; short status; static short count=0; errorCode = 0; if (pnum < 0 || pnum >= NPORTS) /* is a valid port? */ return(-1); if ((p = streams[pnum]) == NULL) /* nothing there */ return (1); pbp=getPB( TCPd, TCPStatus, p->stream, 11); /* Make status call */ if ((errorCode = xPBControlSync(pbp)) != noError) { if ( errorCode == invalidStreamPtr) { DoError (516 | NET_ERRORCLASS, LEVEL2, "Mnetclose"); return(-1); } else { status=0; count =0; } } else { status = pbp->pb.csParam.status.connectionState; /* The connection Status */ if (count++ ==10) { status= 0; count =0; } } #ifdef NET_DEBUG sprintf(net_debug_string, "Mnetclose:error code=%i status=%d",(int)errorCode, status); net_debug_print(net_debug_string); #endif if (status < 18 && status >2 ) { /* We aren't closed yet ! */ #ifdef NET_DEBUG sprintf(net_debug_string, "TCPClose being attempted state ...[%d]",status); /* Prolly because outstanding close */ net_debug_print(net_debug_string); #endif clearPB( pbp, TCPd, TCPClose, p->stream); /* Make Close call */ if ((errorCode=xPBControlAsync(pbp, CloseCompleteInitUPP)) != noError) { /* TCP close failed */ DoError(517 | NET_ERRORCLASS, LEVEL2, "Mnetclose"); return (errorCode); } /* Go ahead and return... PB is in use by Async Close call. */ return (0); /* Return with OK */ } /* IF we got here, we must be at closed state, so free memory */ #ifdef NET_DEBUG sprintf(net_debug_string, "TCP being released, status = %d", status); net_debug_print(net_debug_string); #endif clearPB( pbp,TCPd, TCPRelease, p->stream); /* Make Release call */ if (xPBControlSync(pbp) != noError) { /* TCP failed to be released. Let us know... */ DoError (518 | NET_ERRORCLASS, LEVEL2, "Mnetclose"); return (-1); } DisposPtr( p->buffer); /* Free Receive Buffer */ DisposPtr( p->sbuffer); /* Free Send Buffer */ DisposPtr((Ptr) p); /* Free Stream Structure */ streams[pnum]=0L; netportencryptstate(pnum, 0); MyPBreturn(pbp); return(0); } /**************************************************************************/ /* Nuke the connection, NOW! */ short netabort(short pnum) { StreamRPtr p; MyTCPpbPtr pbp; OSErr errorCode = noErr; if (pnum < 0 || pnum >= NPORTS) /* is a valid port? */ return(-1); if ((p = streams[pnum]) != NULL) /* something there */ { pbp=getPB( TCPd, TCPAbort, p->stream, 12); /* Make Close call */ if ((errorCode=xPBControlSync(pbp)) != noError) /* TCP abort failed. Bad news */ DoError (519 | NET_ERRORCLASS, LEVEL1, NULL); clearPB( pbp,TCPd, TCPRelease, p->stream); /* Make Close call */ if (xPBControlSync(pbp) != noError) { DoError (518 | NET_ERRORCLASS, LEVEL2, NULL); return(-1); } } else return(1); DisposPtr( p->buffer); /* Free Receive Buffer */ DisposPtr( p->sbuffer); /* Free Send Buffer */ DisposPtr((Ptr) p); /* Free Stream Structure */ streams[pnum]=0L; MyPBreturn(pbp); return(0); } /**************************************************************************/ /* Mnetinit * Calls all of the various initialization routines that set up queueing * variables, static values, reads configuration files, etc. */ void Mnetinit( void) { short i; OSErr err; if (TelInfo->startedTCP) return; // demand-load TCP (RAB BetterTelnet 1.0fc4) TelInfo->startedTCP = 1; // RAB BetterTelnet 1.0fc4 #ifndef __powerpc__ MyA5 = SetCurrentA5(); #endif OpenResolver(NULL); // open DNS and discard any errors (RAB BetterTelnet 1.0fc4) for (i=0; istream))) pnum++; if (pnum >=NPORTS) return(-1); else return(pnum); } /**************************************************************************/ pascal void Notify(StreamPtr streamPtr, unsigned short code, Ptr uptr, unsigned short terminReason, struct ICMPReport *icmpMsg) { UNUSED_ARG(uptr) UNUSED_ARG(terminReason) UNUSED_ARG(icmpMsg) StreamRPtr p; short pnum; pnum = findbystream(streamPtr); if (pnum < 0 || (p = streams[pnum]) == 0L) return; switch( code) { case TCPTerminate: case TCPClosing: netputevent(CONCLASS, CONCLOSE, pnum,0); break; case TCPULPTimeout: netputevent(CONCLASS, CONFAIL, pnum,0); break; case TCPDataArrival: case TCPUrgent: netputuev(CONCLASS, CONDATA, pnum,0); break; case TCPICMPReceived: default: break; } return; } /**************************************************************************/ static void OpenCompleteInit(TCPiopb *pbp) { long saveA5; MyTCPpbPtr myptr; myptr = (MyTCPpbPtr)pbp; #ifndef _powerpc_ saveA5 = SetA5(myptr->SavedA5); #endif OpenComplete(myptr); #ifndef _powerpc_ SetA5(saveA5); #endif } /**************************************************************************/ void OpenComplete(MyTCPpbPtr pbp) { StreamRPtr p; short pnum; pnum= findbystream(pbp->pb.tcpStream); if (pnum < 0 || (p = streams[pnum]) == 0L) { MyPBreturn(pbp); //BUGG: Shouldn't we return here so we don't MyPBreturn twice? return; //I'll assume so (CCP) } if (pbp->pb.ioResult !=noError) netputevent(CONCLASS, CONFAIL, pnum,pbp->pb.ioResult); /* Failure ... */ else netputevent(CONCLASS, CONOPEN, pnum,0); /* Success ! */ MyPBreturn( pbp); } /**************************************************************************/ void SendComplete(MyTCPpbPtr pbp) { StreamRPtr p; short pnum; wdsEntry *swds; swds = (wdsEntry *) pbp->pb.csParam.send.wdsPtr; pnum = findbystream(pbp->pb.tcpStream); if (pnum < 0 || (p = streams[pnum]) == 0L) { MyPBreturn(pbp); return; } MyPBreturn( pbp); giveback( p, (wdsEntry *) pbp->pb.csParam.send.wdsPtr); /* BYU LSC - Give this back.... NOW */ returnSWDS( swds); } /**************************************************************************/ static void SendCompleteInit(TCPiopb *pbp) { long saveA5; MyTCPpbPtr myptr; myptr = (MyTCPpbPtr)pbp; #ifndef _powerpc_ saveA5 = SetA5(myptr->SavedA5); #endif SendComplete(myptr); #ifndef _powerpc_ SetA5(saveA5); #endif } /**************************************************************************/ void CloseComplete(MyTCPpbPtr pbp) { StreamRPtr p; short pnum; pnum= findbystream(pbp->pb.tcpStream); if (pnum < 0 || (p = streams[pnum]) == 0L) { netputevent(SCLASS, CLOSEDONE+1, pnum,0); MyPBreturn(pbp); return; } if (pbp->pb.ioResult !=noError) netputevent(SCLASS, CLOSEDONE+1, pnum,0); else netputevent(SCLASS, CLOSEDONE, pnum,0); /* Success ! */ MyPBreturn( pbp); } /**************************************************************************/ static void CloseCompleteInit(TCPiopb *pbp) { long saveA5; MyTCPpbPtr myptr; myptr = (MyTCPpbPtr)pbp; #ifndef _powerpc_ saveA5 = SetA5(myptr->SavedA5); #endif CloseComplete(myptr); #ifndef _powerpc_ SetA5(saveA5); #endif } short netportencryptstate (short port, Ptr edata) { StreamRPtr p; if (port < 0 || port >= NPORTS) return(-2); if ((p = streams[port]) == NULL) return(-2); p->aedata = edata; return 0; } void networkUPPinit(void) { OpenCompleteInitUPP = NewTCPIOCompletionProc(OpenCompleteInit); CloseCompleteInitUPP = NewTCPIOCompletionProc(CloseCompleteInit); SendCompleteInitUPP = NewTCPIOCompletionProc(SendCompleteInit); NotifyUPP = NewTCPNotifyProc(Notify); } \ No newline at end of file +// network.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* * NCSA Revisions: * 10/87 Initial source release, Tim Krauskopf * 2/88 typedef support for other compilers (TK) * 8/88 Gaige Paulsen - support for MacTCP drivers * 1/89 TK - conversion to new drivers, minor update for new calling convention * 6/89 TK - update to MacTCP 1.0 include files and use of GetMyIPAddr() * 7/92 Scott Bulmahn - add support for 2 global structs, put cursors into an array * 11/92 Jim Browne - Fixed more bugs than I care to mention. * */ #include "InternalEvents.h" #include "wind.h" #include "maclook.proto.h" #include "menuseg.proto.h" #include "mainseg.proto.h" #include "MyMacTCPstructures.h" #include "network.proto.h" #include "netevent.proto.h" #include "tnae.h" #include "authencrypt.h" #include "authencrypt.proto.h" #include "AddressXLation.h" #include "Connections.proto.h" #include "sshglue.proto.h" #include "errors.proto.h" #include "telneterrors.h" #ifdef THINK_C #pragma options(!profile) #endif #ifdef __MWERKS__ #pragma profile off #endif //#define NET_DEBUG_MUCHINFO //#define NET_DEBUG #ifdef NET_DEBUG char net_debug_string[256]; #define net_debug_print(x) putln(net_debug_string) #else #define net_debug_print(x) #endif //PROTO_UPP(Notify, TCPNotify); //static TCPIOCompletionProcPtr OpenCompleteInit(TCPiopb *pbp); //PROTO_UPP(OpenCompleteInit, TCPIOCompletion); //static TCPIOCompletionProcPtr CloseCompleteInit(TCPiopb *pbp); //PROTO_UPP(CloseCompleteInit, TCPIOCompletion); //static TCPIOCompletionProcPtr SendCompleteInit(TCPiopb *pbp); //PROTO_UPP(SendCompleteInit, TCPIOCompletion); static TCPIOCompletionUPP OpenCompleteInitUPP = nil; static TCPIOCompletionUPP CloseCompleteInitUPP = nil; static TCPIOCompletionUPP SendCompleteInitUPP = nil; static TCPNotifyUPP NotifyUPP = nil; static void OpenComplete(MyTCPpbPtr pbp); static void SendComplete(MyTCPpbPtr pbp); static void CloseComplete(MyTCPpbPtr pbp); short WindByPort2(short); pascal void Notify(StreamPtr streamPtr, unsigned short code, Ptr uptr, unsigned short terminReason, struct ICMPReport *icmpMsg); static wdsEntry *getSWDS(void); static void returnSWDS(wdsEntry *wds); static void MyPBreturn(MyTCPpbPtr pbp); static MyTCPpb *getPB(short driver,short call, StreamPtr stream, short usernum); static void clearPB(MyTCPpbPtr pbp, short driver, short call, StreamPtr stream); static OSErr xPBControlSync(MyTCPpbPtr pbp); static OSErr xPBControlAsync(MyTCPpbPtr pbp, TCPIOCompletionUPP completionUPP); static short makestream(void); static void reclaim(StreamRPtr p); static short giveback(StreamRPtr p, wdsEntry *wds); static void compressfds(wdsEntry *fds); static void NetWriteZero(Ptr pointer,long size); //put this here to keep from loading and unlaoding config segment extern Cursor *theCursors[]; extern WindRec *screens; long MyA5; short TCPd = 0; /* refnum of TCP drivers */ QHdr gFreePBQueue; QHdr gFreeSWDSQueue; short numSWDS=0; /* Number of SWDS's ever alloc'd (PM Only) */ StreamRPtr streams[NPORTS]; ip_port nnfromport = 0; Boolean nextIsUrgent = FALSE; //CCP 2.7 (See NetUrgent ()) void NetWriteZero(Ptr pointer,long size) { while (size--) *pointer++ = 0; } /**************************************************************************/ wdsEntry *getSWDS(void) { short n=0; wdsEntry * wds; if (gFreeSWDSQueue.qHead == NULL) wds = (wdsEntry *) myNewPtrCritical( sizeof(wdsEntry) * MAX_SWDS_ELEMS); else { wds = (wdsEntry *) gFreeSWDSQueue.qHead; Dequeue(gFreeSWDSQueue.qHead, &gFreeSWDSQueue); } if (wds == NULL) { /* sorry, cant allocate WDS (BIG PROBLEM) */ DoError(508 | NET_ERRORCLASS, LEVEL3, NULL); // <- Is 508 correct? forcequit(); // return ((wdsEntry*) 0L); <- ?? perhaps } return(wds); } /**************************************************************************/ void returnSWDS(wdsEntry *wds) { Enqueue((QElemPtr)wds, &gFreeSWDSQueue); } /**************************************************************************/ void MyPBreturn(MyTCPpbPtr pbp) { Enqueue((QElemPtr)pbp, &gFreePBQueue); } /**************************************************************************/ MyTCPpb *getPB(short driver,short call, StreamPtr stream, short usernum) { UNUSED_ARG(usernum) MyTCPpb *pbp; if (gFreePBQueue.qHead == NULL) pbp = (MyTCPpbPtr) myNewPtrCritical( sizeof(MyTCPpb) ); else { pbp = (MyTCPpbPtr) gFreePBQueue.qHead; Dequeue(gFreePBQueue.qHead, &gFreePBQueue); } if (pbp == NULL) { /* sorry, cant allocate TCP buffer (BIG PROBLEM) */ DoError(508 | NET_ERRORCLASS, LEVEL3, NULL); forcequit(); } memset((char *) pbp, '\0', sizeof(MyTCPpb)); pbp->pb.ioCRefNum = driver; pbp->pb.tcpStream = stream; pbp->pb.csCode = call; return(pbp); } /**************************************************************************/ void clearPB(MyTCPpbPtr pbp, short driver, short call, StreamPtr stream) { NetWriteZero((Ptr)pbp, sizeof(MyTCPpb)); /* BYU LSC - Default to all zeros */ pbp->pb.ioCRefNum = driver; pbp->pb.tcpStream = stream; pbp->pb.csCode = call; } /**************************************************************************/ OSErr xPBControlSync(MyTCPpbPtr pbp) { pbp->pb.ioCompletion = 0L; /* Charlie will puke if he ever sees */ return PBControlSync((ParmBlkPtr)(pbp)); /* his funtions here. -- JMB */ } /**************************************************************************/ OSErr xPBControlAsync(MyTCPpbPtr pbp, TCPIOCompletionUPP completionUPP) { #ifndef __powerpc__ pbp->SavedA5 = MyA5; #endif pbp->pb.ioCompletion = completionUPP; return(PBControlAsync((ParmBlkPtr)(pbp))); /* async */ } void SetPortType(short port, short type) { if (port >= 0 && port < NPORTS && (streams[port] != NULL)) streams[port]->portType = type; } short GetPortType(short port) { if (port >= 0 && port < NPORTS && (streams[port] != NULL)) return(streams[port]->portType); else return(-1); } /**************************************************************************/ /* Returns an empty stream */ short makestream(void) { short pnum, i; StreamRPtr p; MyTCPpbPtr pbp; for ( pnum=0; (streams[pnum]!= NULL) && pnum= NPORTS) return(-2); if (!(p = streams[pnum] = (StreamRPtr) myNewPtrCritical(sizeof(StreamRec)))) return(-1); if ((p->buffer = (char *) myNewPtrCritical( TCPBUFSIZ)) == NULL) { DisposePtr((Ptr)p); streams[pnum] = 0; return(-1); } if ((p->sbuffer = (char *) myNewPtrCritical( TCPBUFSIZ)) == NULL) { DisposePtr((Ptr)p->buffer); DisposePtr((Ptr)p); streams[pnum] = 0; return(-1); } for (i=0; ifds[ i].length =0; p->fds[ i].ptr = 0L; p->exFDS[ i].inuse=0; p->exFDS[ i].fds.length=0;p->exFDS[ i].fds.ptr=0L; } p->fds[0].length = TCPBUFSIZ; p->fds[0].ptr = p->sbuffer; p->maxFDSused=0; p->aedata = NULL; pbp=getPB( TCPd, TCPCreate, (long) 0, 7); /* BYU LSC important - Make create call */ pbp->pb.csParam.create.rcvBuff = p->buffer; pbp->pb.csParam.create.rcvBuffLen = TCPBUFSIZ; pbp->pb.csParam.create.notifyProc = NotifyUPP; if (xPBControlSync(pbp) != noError) ; // DoError (512 | NET_ERRORCLASS, LEVEL2, NULL); p->stream = pbp->pb.tcpStream; p->urgentMode = 0; // RAB BetterTelnet 2.0b2 p->nextRecvUrgent = 0; // RAB BetterTelnet 2.0b2 net_debug_print("Made new stream"); MyPBreturn(pbp); return(pnum); } /**************************************************************************/ /* reclaim( p) - reclaims buffer space to stream (from pointer p) into the FDS list */ void reclaim(StreamRPtr p) { short n=0, offset=0; while (offset < MAX_FDS_ELEMS && p->fds[offset].ptr != 0L) offset++; if (offset >= MAX_FDS_ELEMS) /* offset too large -- cant reclaim */ return; for (n=0 ; nexFDS[ n].inuse) { p->fds[ offset++]=p->exFDS[ n].fds; p->exFDS[ n].inuse = 0; } } } /************************************************************************** giveback( p, wds) - gives WDS entries back to the stream by putting them in the mutually exclusive buffer. p -> stream wds -> wds array */ short giveback(StreamRPtr p, wdsEntry *wds) { short n=0, m=0; while ( n< MAX_SWDS_ELEMS && wds[n].ptr !=0L) { while (m< MAX_FDS_ELEMS && p->exFDS[ m].inuse) m++; if (m >= MAX_FDS_ELEMS) // This was off by one - JMB 2.6 return(-1); /* No room in the RECLAIMation center */ else { p->exFDS[ m].inuse =1; p->exFDS[ m].fds = wds[n]; m++; } n++; } return 0; } /**************************************************************************/ /* compressfds( fds) compress an fds data structure to make everyone happy */ void compressfds(wdsEntry *fds) { short n,m,compressed; compressed = 0; while ( !compressed) { compressed=1; for (n=0; n< MAX_FDS_ELEMS; n++) { /* Slow Forwards */ if (fds[n].ptr) { /* Do if N exists */ for ( m = MAX_FDS_ELEMS -1; m>=0; m--) { /* Fast Backwards */ if (fds[m].ptr && (fds[m].ptr+fds[m].length == fds[n].ptr)) { fds[n].length+=fds[m].length; fds[n].ptr = fds[m].ptr; fds[m].ptr=0L; fds[m].length=0; compressed=0; } #ifdef CHECKBOTHWAYZ else if (fds[n].ptr+fds[n].length == fds[m].ptr) { fds[m].length+=fds[n].length; fds[n].ptr=0L; fds[n].length=0; compressed=0; } #endif CHECKBOTHWAYZ } } } } m=0;n=0; /* Close the gaps */ while (n+m < MAX_FDS_ELEMS) { while (fds[n+m].ptr ==0L && n+m< MAX_FDS_ELEMS) m++; /* increase gap to valid entry */ if (n+m= NPORTS) /* BYU 2.4.15 */ return(-2); if (NULL == (p = streams[pnum])) return(-2); pbp=getPB( TCPd, TCPStatus, p->stream, 1); /* Make status call */ if (xPBControlSync(pbp) != noError) /* status call bombed */ // DoError (509 | NET_ERRORCLASS, LEVEL1, "Mnetread"); ; if (pbp->pb.csParam.status.connectionState !=8) { #ifdef NET_DEBUG sprintf(net_debug_string, "CState: %d is %d",(int)pnum, (int)pbp->pb.csParam.status.connectionState); net_debug_print(net_debug_string); #endif MyPBreturn(pbp); return(-1); /* Connection not established */ } inQ = pbp->pb.csParam.status.amtUnreadData; reqdamt = n >inQ ? inQ : n; clearPB( pbp, TCPd, TCPRcv, p->stream); pbp->pb.csParam.receive.rcvBuff = buffer; pbp->pb.csParam.receive.rcvBuffLen = reqdamt; if (reqdamt<1) { /* Drop out if no data */ MyPBreturn(pbp); return(0); } if ((i = xPBControlSync(pbp)) != noError) { // DoError (524 | NET_ERRORCLASS, LEVEL1, NULL); return(-1); } reqdamt = pbp->pb.csParam.receive.rcvBuffLen; if (reqdamturgentMode = 0; if (pbp->pb.csParam.receive.urgentFlag) p->urgentMode = 1; if (p->nextRecvUrgent) p->urgentMode = 1; if (p->urgentMode) { if (pbp->pb.csParam.receive.markFlag) p->nextRecvUrgent = 0; else p->nextRecvUrgent = 1; } /* Decrypt data */ if (p->aedata && ((tnParams *)p->aedata)->decrypting) { unsigned char *cp = (unsigned char *)buffer; short len = reqdamt; while (len-- > 0) { *cp = decrypt((tnParams *)p->aedata, (long)(*cp)); cp++; } } MyPBreturn(pbp); return(reqdamt); } //makes the next buffer be sent as urgent data void netUrgent(void) { nextIsUrgent = TRUE; } /************************************************************************/ short WindByPort2(short port) { short i=0; while (inumwindows && (screens[i].port != port || ((screens[i].active != CNXN_ACTIVE) && (screens[i].active != CNXN_OPENING))) ) i++; if (i>=TelInfo->numwindows) { /* BYU */ putln("Can't find a window for the port # in WindByPort2"); /* BYU */ if (i==0) i=999; /* BYU */ return(-i); /* BYU */ } /* BYU */ return(i); } short netwrite(short pnum, void *buffer, short nsend) { short i; i = WindByPort2(pnum); if (i < 0) return Rnetwrite(pnum, buffer, nsend); if (screens[i].protocol == 4) { ssh_glue_write(&screens[i], buffer, nsend); return nsend; } return Rnetwrite(pnum, buffer, nsend); } /* netwrite * write something into the output queue, netsleep routine will come * around and send the data, etc. * */ short Rnetwrite(short pnum, void *buffer, short nsend) { StreamRPtr p; wdsEntry *swds; short remaining, queued, n,m; MyTCPpbPtr pbp; OSErr err; #ifdef NET_DEBUG_MUCHINFO sprintf(net_debug_string, "port: %d\tbuffer: %lx\tnsend %d", pnum, (unsigned int)buffer, (int)nsend); net_debug_print(net_debug_string); #endif if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */ return(-2); if ( (p = streams[pnum]) == NULL) return(-2); if ( !nsend ) return(0); swds = getSWDS(); if (swds == NULL) return(nsend); // Duh, Mr. Bulmahn. - JMB 2.6 reclaim( p); compressfds( p->fds); n=0; remaining = nsend; // if (p->fds[0].ptr == 0) DebugStr("\pArgh! fds[0] is NULL!"); if (p->fds[0].ptr == 0) return 0; // argh! while (p->fds[n].ptr !=0 && remaining>0 ) { // if (n >= MAX_SWDS_ELEMS) DebugStr("\pOverflowing SWDS in while loop!"); swds[n].ptr = p->fds[n].ptr; if ( p->fds[n].length > remaining) { swds[n].length = remaining; p->fds[n].length -= remaining; p->fds[n].ptr += remaining; remaining=0; } else { swds[n].length = p->fds[n].length; remaining -= p->fds[n].length; p->fds[n].length = 0; p->fds[n].ptr = 0; } n++; } if (n>p->maxFDSused) p->maxFDSused=n; compressfds( p->fds); queued = nsend-remaining; for(m=0; maedata && ((tnParams *)p->aedata)->encrypting) encrypt((tnParams *)p->aedata, (unsigned char *)swds[m].ptr, swds[m].length); buffer=(void *)((char *)buffer + swds[m].length); } swds[m].ptr = 0L; swds[m].length=0; pbp=getPB( TCPd, TCPSend, p->stream, 2); /* Make send call */ pbp->pb.csParam.send.wdsPtr = (Ptr) swds; pbp->pb.csParam.send.pushFlag = p->push; pbp->pb.csParam.open.ulpTimeoutValue = (SInt8)gApplicationPrefs->SendTimeout;// timeout value pbp->pb.csParam.open.ulpTimeoutAction = 1; // Abort pbp->pb.csParam.open.validityFlags = 0xC0; // Timeout and action are valid if (nextIsUrgent) { nextIsUrgent = FALSE; pbp->pb.csParam.send.urgentFlag = TRUE; } p->push=0; if ((err = xPBControlAsync(pbp, SendCompleteInitUPP)) != noError) { char temp_xvvyz[256]; sprintf(temp_xvvyz, "netwrite: %d", err); // DoError(510 | NET_ERRORCLASS, LEVEL2, temp_xvvyz); return(-1); } return(queued); } /**************************************************************************/ /* Mnetpush * attempt to push the rest of the data from the queue * and then return whether the queue is empty or not (0 = empty) * returns the number of bytes in the queue. */ short netpush(short pnum) { StreamRPtr p; MyTCPpbPtr pbp; short inQ; OSErr err; if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */ return(-2); if (NULL == (p = streams[pnum])) return(-2); pbp=getPB( TCPd, TCPStatus, p->stream, 3); /* Make status call */ //#ifdef NET_DEBUG_MUCHINFO // sprintf(net_debug_string, "TCPd == %d", TCPd); // net_debug_print(net_debug_string); //#endif if ((err = xPBControlSync(pbp)) != noError) { /* status call bombed */ char temp_xvvyz[256]; sprintf(temp_xvvyz, "netpush: %d", err); // DoError(509 | NET_ERRORCLASS, LEVEL2, temp_xvvyz); } inQ = pbp->pb.csParam.status.amtUnackedData; MyPBreturn( pbp); p->push=1; return(inQ); } /**************************************************************************/ /* Mnetqlen * return the number of bytes waiting to be read from the incoming queue. */ short netqlen(short pnum) { StreamRPtr p; MyTCPpbPtr pbp; short inQ; if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */ return(-2); if (NULL == (p = streams[pnum])) return(-2); pbp=getPB( TCPd, TCPStatus, p->stream, 4); /* Make status call */ if (xPBControlSync(pbp) != noError) /* status call failed */ // DoError(509 | NET_ERRORCLASS, LEVEL2, "Mnetqlen"); ; inQ = pbp->pb.csParam.status.amtUnreadData; MyPBreturn( pbp); p->push = 1; return(inQ); } /**************************************************************************/ /* Mnetroom() * return how much room is available in output buffer for a connection */ short netroom(short pnum) { StreamRPtr p; short inQ, n; if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */ return(-2); if (NULL == (p = streams[pnum])) return(-2); reclaim( p); compressfds( p->fds); #ifdef OLDM pbp=getPB( TCPd, TCPStatus, p->stream, 5); /* Make status call */ if (xPBControlSync(pbp) != noError) ; // DoError(509 | NET_ERRORCLASS, LEVEL1, "Mnetroom"); inQ = pbp->csParam.status.sendWindow - pbp->csParam.status.amtUnackedData; MyPBreturn( pbp); #else /*#pragma unused(pbp) /* BYU LSC */ #endif inQ = n = 0; while (p->fds[n].ptr) { inQ += p->fds[n].length; /* add up free list space */ n++; } return(inQ); } /**************************************************************************/ void netgetip(unsigned char *st) { struct GetAddrParamBlock mypb; /* long netmask; */ net_debug_print("Attempting getmyipaddr"); NetWriteZero((Ptr)&mypb, sizeof(struct GetAddrParamBlock)); mypb.ioCRefNum = TCPd; /* BYU LSC - TCP driver has to be open by now */ mypb.csCode = ipctlGetAddr; if (PBControlSync((ParmBlkPtr)&mypb) != noError) { DoError(511 | NET_ERRORCLASS, LEVEL2, NULL); return; } BlockMove(&mypb.ourAddress, st, 4); /* BYU LSC - copy the address */ /* netmask is here if we want it, too */ } // chas BetterTelnet 2.0b4 - for k5 short netgetport(short pnum) { StreamRPtr p; MyTCPpbPtr pbp; short port; if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */ return(-2); if (NULL == (p = streams[pnum])) return(-2); pbp=getPB( TCPd, TCPStatus, p->stream, 4); /* Make status call */ if (xPBControlSync(pbp) != noError) /* status call failed */ DoError(509 | NET_ERRORCLASS, LEVEL2, "Mnetgetport"); port = pbp->pb.csParam.status.localPort; MyPBreturn( pbp); return port; } void netfromport /* next "open" will use this port */ ( short port) { nnfromport = (ip_port)port; } /**************************************************************************/ /* Mnetest? * is a particular session established yet? * Returns 0 if the connection is in the established state. */ short netest(short pnum) { StreamRPtr p; MyTCPpbPtr pbp; short inQ; if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */ return(-2); if (NULL == (p = streams[pnum])) return(-2); pbp=getPB( TCPd, TCPStatus, p->stream, 6); /* Make status call */ if (xPBControlSync(pbp) != noError) { DoError(509 | NET_ERRORCLASS, LEVEL2, "Mnetest"); inQ = -1; } else inQ = pbp->pb.csParam.status.connectionState !=8; MyPBreturn( pbp); return(inQ); } /**************************************************************************/ /* Mnetlisten * Listen to a TCP port number and make the connection automatically when * the SYN packet comes in. The TCP layer will notify the higher layers * with a CONOPEN event. Save the port number returned to refer to this * connection. * * usage: portnum = netlisten(service); * short service; * */ short netlisten(ip_port serv) { short pnum; StreamRPtr p; MyTCPpbPtr pbp; pnum = makestream(); if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */ return(-2); if (NULL == (p = streams[pnum])) return(-2); pbp=getPB( TCPd, TCPPassiveOpen, p->stream, 8); /* Make Listen call */ pbp->pb.csParam.open.localPort = serv; if (xPBControlAsync(pbp, OpenCompleteInitUPP) != noError) DoError(513 | NET_ERRORCLASS, LEVEL2, NULL); return(pnum); /* BYU 2.4.16 */ } /***********************************************************************/ /* Mnetgetftp * Provides the information that ftp needs to open a stream back to the * originator of the command connection. The other side's IP number * and the port numbers to be used to calculate the default data connection * number. Returns values in an integer array for convenient use in * PORT commands. */ short netgetftp(short pnum, ip_addr *addr, ip_port *localPort, ip_port *remotePort) { StreamRPtr p; MyTCPpbPtr pbp; if (pnum < 0) return(-2); if (NULL == (p = streams[pnum])) return(-2); pbp=getPB( TCPd, TCPStatus, p->stream, 9); /* Make status call */ if (xPBControlSync(pbp) != noError) DoError(514 | NET_ERRORCLASS, LEVEL2, NULL); *addr = pbp->pb.csParam.status.remoteHost; *localPort = pbp->pb.csParam.status.localPort; *remotePort = pbp->pb.csParam.status.remotePort; MyPBreturn( pbp); return 0; } /**************************************************************************/ /* Open a network socket for the user. */ short netxopen( ip_addr machine, ip_port service, short timeout ) // in seconds { short pnum, err; StreamRPtr p; MyTCPpbPtr pbp; pnum = makestream(); if (pnum < 0) return(-2); if (NULL == (p = streams[pnum])) return(-2); pbp=getPB( TCPd, TCPActiveOpen, p->stream, 10); /* Make Listen call */ pbp->pb.csParam.open.remoteHost = machine; /* IP # */ pbp->pb.csParam.open.remotePort = service; /* Port */ pbp->pb.csParam.open.localPort = nnfromport; /* My Port */ pbp->pb.csParam.open.ulpTimeoutValue = (SInt8)timeout; // timeout value pbp->pb.csParam.open.ulpTimeoutAction = 1; // Abort pbp->pb.csParam.open.validityFlags = 0xC0; // Timeout and action are valid nnfromport=0; /* Next one is random */ // RAB BetterTelnet 2.0b2 // we handle port rotation for privileged ports for rlogin here // just in case the call returns synchronously err = -23017; while (err == -23017) { err = xPBControlAsync(pbp, OpenCompleteInitUPP); if (err == -23017) pbp->pb.csParam.open.localPort++; } if (err != noError) { DoError(515 | NET_ERRORCLASS, LEVEL2, NULL); return(-1); } SetPortType(pnum, NO_TYPE); // Is allocated to the user #ifdef NET_DEBUG sprintf(net_debug_string, "TCPOpen on port #%d", pnum); net_debug_print(net_debug_string); #endif return(pnum); /* BYU 2.4.16 */ } /**************************************************************************/ /* Mnetclose * Do appropriate actions to return connection state to SCLOSED which * enables the memory for that port to be reused. * * Specifically: * o If status is closed, then release the data structures * o If status is not close, perform bkgrd close which generates CLOSEDONE, * which should make the session layer call us again */ short netclose(short pnum) { StreamRPtr p; MyTCPpbPtr pbp; OSErr errorCode; short status; static short count=0; errorCode = 0; if (pnum < 0 || pnum >= NPORTS) /* is a valid port? */ return(-1); if ((p = streams[pnum]) == NULL) /* nothing there */ return (1); pbp=getPB( TCPd, TCPStatus, p->stream, 11); /* Make status call */ if ((errorCode = xPBControlSync(pbp)) != noError) { if ( errorCode == invalidStreamPtr) { // DoError (516 | NET_ERRORCLASS, LEVEL2, "Mnetclose"); return(-1); } else { status=0; count =0; } } else { status = pbp->pb.csParam.status.connectionState; /* The connection Status */ if (count++ ==10) { status= 0; count =0; } } #ifdef NET_DEBUG sprintf(net_debug_string, "Mnetclose:error code=%i status=%d",(int)errorCode, status); net_debug_print(net_debug_string); #endif if (status < 18 && status >2 ) { /* We aren't closed yet ! */ #ifdef NET_DEBUG sprintf(net_debug_string, "TCPClose being attempted state ...[%d]",status); /* Prolly because outstanding close */ net_debug_print(net_debug_string); #endif clearPB( pbp, TCPd, TCPClose, p->stream); /* Make Close call */ if ((errorCode=xPBControlAsync(pbp, CloseCompleteInitUPP)) != noError) { /* TCP close failed */ // DoError(517 | NET_ERRORCLASS, LEVEL2, "Mnetclose"); return (errorCode); } /* Go ahead and return... PB is in use by Async Close call. */ return (0); /* Return with OK */ } /* IF we got here, we must be at closed state, so free memory */ #ifdef NET_DEBUG sprintf(net_debug_string, "TCP being released, status = %d", status); net_debug_print(net_debug_string); #endif clearPB( pbp,TCPd, TCPRelease, p->stream); /* Make Release call */ if (xPBControlSync(pbp) != noError) { /* TCP failed to be released. Let us know... */ // DoError (518 | NET_ERRORCLASS, LEVEL2, "Mnetclose"); return (-1); } DisposePtr( p->buffer); /* Free Receive Buffer */ DisposePtr( p->sbuffer); /* Free Send Buffer */ DisposePtr((Ptr) p); /* Free Stream Structure */ streams[pnum]=0L; netportencryptstate(pnum, 0); MyPBreturn(pbp); return(0); } /**************************************************************************/ /* Nuke the connection, NOW! */ short netabort(short pnum) { StreamRPtr p; MyTCPpbPtr pbp; OSErr errorCode = noErr; if (pnum < 0 || pnum >= NPORTS) /* is a valid port? */ return(-1); if ((p = streams[pnum]) != NULL) /* something there */ { pbp=getPB( TCPd, TCPAbort, p->stream, 12); /* Make Close call */ if ((errorCode=xPBControlSync(pbp)) != noError) ; /* TCP abort failed. Bad news */ // DoError (519 | NET_ERRORCLASS, LEVEL1, NULL); clearPB( pbp,TCPd, TCPRelease, p->stream); /* Make Close call */ if (xPBControlSync(pbp) != noError) { // DoError (518 | NET_ERRORCLASS, LEVEL2, NULL); return(-1); } } else return(1); DisposePtr( p->buffer); /* Free Receive Buffer */ DisposePtr( p->sbuffer); /* Free Send Buffer */ DisposePtr((Ptr) p); /* Free Stream Structure */ streams[pnum]=0L; MyPBreturn(pbp); return(0); } /**************************************************************************/ /* Mnetinit * Calls all of the various initialization routines that set up queueing * variables, static values, reads configuration files, etc. */ void Mnetinit( void) { short i; OSErr err; if (TelInfo->startedTCP) return; // demand-load TCP (RAB BetterTelnet 1.0fc4) TelInfo->startedTCP = 1; // RAB BetterTelnet 1.0fc4 #ifndef __powerpc__ MyA5 = SetCurrentA5(); #endif OpenResolver(NULL); // open DNS and discard any errors (RAB BetterTelnet 1.0fc4) for (i=0; istream))) pnum++; if (pnum >=NPORTS) return(-1); else return(pnum); } /**************************************************************************/ pascal void Notify(StreamPtr streamPtr, unsigned short code, Ptr uptr, unsigned short terminReason, struct ICMPReport *icmpMsg) { UNUSED_ARG(uptr) UNUSED_ARG(terminReason) UNUSED_ARG(icmpMsg) StreamRPtr p; short pnum; pnum = findbystream(streamPtr); if (pnum < 0 || (p = streams[pnum]) == 0L) return; switch( code) { case TCPTerminate: case TCPClosing: netputevent(CONCLASS, CONCLOSE, pnum,0); break; case TCPULPTimeout: netputevent(CONCLASS, CONFAIL, pnum,0); break; case TCPDataArrival: case TCPUrgent: netputuev(CONCLASS, CONDATA, pnum,0); break; case TCPICMPReceived: default: break; } return; } /**************************************************************************/ static void OpenCompleteInit(TCPiopb *pbp) { long saveA5; MyTCPpbPtr myptr; myptr = (MyTCPpbPtr)pbp; #ifndef _powerpc_ saveA5 = SetA5(myptr->SavedA5); #endif OpenComplete(myptr); #ifndef _powerpc_ SetA5(saveA5); #endif } /**************************************************************************/ void OpenComplete(MyTCPpbPtr pbp) { StreamRPtr p; short pnum; pnum= findbystream(pbp->pb.tcpStream); if (pnum < 0 || (p = streams[pnum]) == 0L) { MyPBreturn(pbp); //BUGG: Shouldn't we return here so we don't MyPBreturn twice? return; //I'll assume so (CCP) } if (pbp->pb.ioResult == -23017) { netputevent(CONCLASS, CONFAIL, pnum, -23017); streams[pnum]->pbp = pbp; // save the params return; // and return } else streams[pnum]->pbp = 0; if (pbp->pb.ioResult !=noError) netputevent(CONCLASS, CONFAIL, pnum,pbp->pb.ioResult); /* Failure ... */ else netputevent(CONCLASS, CONOPEN, pnum,0); /* Success ! */ MyPBreturn( pbp); } /**************************************************************************/ void SendComplete(MyTCPpbPtr pbp) { StreamRPtr p; short pnum; wdsEntry *swds; swds = (wdsEntry *) pbp->pb.csParam.send.wdsPtr; pnum = findbystream(pbp->pb.tcpStream); if (pnum < 0 || (p = streams[pnum]) == 0L) { MyPBreturn(pbp); return; } MyPBreturn( pbp); giveback( p, (wdsEntry *) pbp->pb.csParam.send.wdsPtr); /* BYU LSC - Give this back.... NOW */ returnSWDS( swds); } /**************************************************************************/ static void SendCompleteInit(TCPiopb *pbp) { long saveA5; MyTCPpbPtr myptr; myptr = (MyTCPpbPtr)pbp; #ifndef _powerpc_ saveA5 = SetA5(myptr->SavedA5); #endif SendComplete(myptr); #ifndef _powerpc_ SetA5(saveA5); #endif } /**************************************************************************/ void CloseComplete(MyTCPpbPtr pbp) { StreamRPtr p; short pnum; pnum= findbystream(pbp->pb.tcpStream); if (pnum < 0 || (p = streams[pnum]) == 0L) { netputevent(SCLASS, CLOSEDONE+1, pnum,0); MyPBreturn(pbp); return; } if (pbp->pb.ioResult !=noError) netputevent(SCLASS, CLOSEDONE+1, pnum,0); else netputevent(SCLASS, CLOSEDONE, pnum,0); /* Success ! */ MyPBreturn( pbp); } /**************************************************************************/ static void CloseCompleteInit(TCPiopb *pbp) { long saveA5; MyTCPpbPtr myptr; myptr = (MyTCPpbPtr)pbp; #ifndef _powerpc_ saveA5 = SetA5(myptr->SavedA5); #endif CloseComplete(myptr); #ifndef _powerpc_ SetA5(saveA5); #endif } short netportencryptstate (short port, Ptr edata) { StreamRPtr p; if (port < 0 || port >= NPORTS) return(-2); if ((p = streams[port]) == NULL) return(-2); p->aedata = edata; return 0; } void networkUPPinit(void) { OpenCompleteInitUPP = NewTCPIOCompletionProc(OpenCompleteInit); CloseCompleteInitUPP = NewTCPIOCompletionProc(CloseCompleteInit); SendCompleteInitUPP = NewTCPIOCompletionProc(SendCompleteInit); NotifyUPP = NewTCPNotifyProc(Notify); } // This takes care of most async cases of port rotation when we need to assign // our own range of port numbers for a privileged port for rlogin // (RAB BetterTelnet 2.0b2) short checkPortRotation(short port) { short err; MyTCPpbPtr pbp; pbp = streams[port]->pbp; if (!pbp) return 0; err = -23017; while (err == -23017) { pbp->pb.csParam.open.localPort++; err = xPBControlAsync(pbp, OpenCompleteInitUPP); } if (err != noError) { DoError(515 | NET_ERRORCLASS, LEVEL2, NULL); return 0; } else return 1; // yay, we did it } short getUrgentFlag(short pnum) { short i; StreamRPtr p; if (pnum < 0 || pnum >= NPORTS) /* BYU 2.4.15 */ return 0; if (NULL == (p = streams[pnum])) return 0; return (p->urgentMode); } \ No newline at end of file diff --git a/source/network/network.proto.h b/source/network/network.proto.h index 165f542..a455c10 100755 --- a/source/network/network.proto.h +++ b/source/network/network.proto.h @@ -1 +1 @@ -void SetPortType(short port, short type); short GetPortType(short port); short netread(short pnum, void *buffer, short n); short netwrite(short pnum, void *buffer, short nsend); short netpush(short pnum); short netqlen(short pnum); short netroom(short pnum); void netgetip(unsigned char *st); void netfromport /* next "open" will use this port */ ( short port ); short netest(short pnum); short netlisten(ip_port serv); short netgetftp(short pnum, ip_addr *addr, ip_port *localPort, ip_port *remotePort); short netxopen( ip_addr machine, ip_port service, short timeout); short netclose(short pnum); short netabort(short pnum); void Mnetinit( void); void netshut(void); short findbystream(StreamPtr streamPtr); short netportencryptstate (short port, Ptr edata); void networkUPPinit(void); void netUrgent(void); \ No newline at end of file +void SetPortType(short port, short type); short GetPortType(short port); short netread(short pnum, void *buffer, short n); short netwrite(short pnum, void *buffer, short nsend); short Rnetwrite(short pnum, void *buffer, short nsend); short netpush(short pnum); short netqlen(short pnum); short netroom(short pnum); void netgetip(unsigned char *st); short netgetport(short); void netfromport /* next "open" will use this port */ ( short port ); short netest(short pnum); short netlisten(ip_port serv); short netgetftp(short pnum, ip_addr *addr, ip_port *localPort, ip_port *remotePort); short netxopen( ip_addr machine, ip_port service, short timeout); short netclose(short pnum); short netabort(short pnum); void Mnetinit( void); void netshut(void); short findbystream(StreamPtr streamPtr); short netportencryptstate (short port, Ptr edata); void networkUPPinit(void); void netUrgent(void); short checkPortRotation(short); short getUrgentFlag(short); \ No newline at end of file diff --git a/source/parse/authencrypt.c b/source/parse/authencrypt.c index 96cfc9d..d0b4e17 100755 --- a/source/parse/authencrypt.c +++ b/source/parse/authencrypt.c @@ -1 +1 @@ -/* * Authencrypt.c * Authentication module for NCSA/Telnet and Brown tn3270. */ // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "tnae.h" #include "authencrypt.h" #include "authencrypt.proto.h" #include "KrbDriver.h" #include "DlogUtils.proto.h" #define NAUTHTYPES 10 /* Max number of auth types */ struct codemodule *authmodules = 0; /* list of authentication code modules */ static char nullbuf[] = {IAC, SB, OPT_AUTHENTICATION, TNQ_IS, AUTH_NULL, AUTH_CLIENT_TO_SERVER|AUTH_HOW_ONE_WAY, IAC, SE}; #ifdef powerc enum { uppModule = kCStackBased | RESULT_SIZE(SIZE_CODE(sizeof(long))) | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))) | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr))) }; #endif #ifdef __MWERKS__ #pragma profile off #endif static void scanFolder(short vRef, long dirID); static void loadCode(HParamBlockRec *pb, long dirid, Str255 name, OSType type, codemodule **header); short hicall (long cscode, krbHiParmBlock *khipb, short kdriver); /* * auth_encrypt_init * Initialize processing for auth/encrypt options. * Find all the modules that support auth/encrypt and add them to our * typepairs and modules table. Load those modules and initialize them. * * Return true if any auth module found. */ Boolean auth_encrypt_init () { short vref; long dirid = 0, fold; SysEnvRec theWorld; /* * Find and load/initialize files with code modules. * First, Try to find the Extensions folder, else use the system folder. */ if (Gestalt('fold', &fold) || ((fold & 1) != 1) || FindFolder(kOnSystemDisk, kExtensionFolderType, false, &vref, &dirid)) { if (SysEnvirons (1, &theWorld) == 0) vref = theWorld.sysVRefNum; else vref = -1; } scanFolder(vref, dirid); // Now scan the folder that Telnet lives in scanFolder(TelInfo->ApFolder.vRefNum, TelInfo->ApFolder.parID); if (authmodules) return true; return false; } static void scanFolder(short vRef, long dirID) { short i; HParamBlockRec pb; Str255 name; OSErr s; for (i = 1; ; i++ ) { pb.fileParam.ioCompletion = 0; pb.fileParam.ioVRefNum = vRef; pb.fileParam.ioFVersNum = 0; pb.fileParam.ioFDirIndex = i; pb.fileParam.ioDirID = dirID; pb.fileParam.ioNamePtr = name; if ((s = PBHGetFInfo(&pb, false)) != noErr) break; /* Check for module types that we are interested in. */ if (pb.fileParam.ioFlFndrInfo.fdType == moduleType) { loadCode(&pb, dirID, name, authType, &authmodules); } } } void loadCode (HParamBlockRec *pb, long dirid, Str255 name, OSType type, codemodule **header) { int i; short rf, oldrf; struct codemodule *code = 0; Handle h; oldrf = CurResFile(); rf = HOpenResFile(pb->fileParam.ioVRefNum, dirid, name, fsRdPerm); if (rf == -1) return; SetResLoad(true); /* * Find all resources of indicated type. */ for (i = 1; ; i++) { if (!((h = Get1IndResource(type, i)))) break; code = (struct codemodule *)myNewPtr(sizeof(struct codemodule)); if (code) { DetachResource(h); HNoPurge(h); HLockHi(h); code->entry = (module)*h; /* * Initialize the module. * It should preset the type/pairs list and return the number of * pairs entered. */ #ifdef powerc code->npairs = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, TNFUNC_INIT_CODE, &code->pairs); code->encryptok = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, TNFUNC_QUERY_ENCRYPT, 0); #else code->npairs = (*code->entry)(TNFUNC_INIT_CODE, &code->pairs); code->encryptok = (*code->entry)(TNFUNC_QUERY_ENCRYPT, 0); #endif qlink(header, code); } else ReleaseResource(h); } CloseResFile(rf); /* ddd for debugging with The Debugger ***/ UseResFile(oldrf); } /* * auth_suboption * Called by the Telnet client when an authentication sub-option is received. * The reply option (if any) is placed into sendbuffer and *sendlength adjusted * by the amount of data placed into sendbuffer. */ void auth_suboption (tnParams **aedata, unsigned char *subbuffer, long sublength, unsigned char *sendbuffer, unsigned long *sendlength, char *cname, Boolean hisencrypt, Boolean myencrypt) { int i; OSErr s; unsigned short pair; unsigned char *cp, *buflimit; struct codemodule *code = 0; tnParams *tn; /* temp params struct */ buflimit = subbuffer + sublength; /* * Initialize session's tnParams if not initialized yet. * Return null auth if no memory and TNQ_SEND. */ if (!(*aedata)) { *aedata = (tnParams *)myNewPtr(sizeof(tnParams)); if (!(*aedata)) { if (subbuffer[SB_SUBOPTION] == TNQ_SEND) { BlockMove((Ptr)nullbuf, (Ptr)sendbuffer, sizeof(nullbuf)); *sendlength -= sizeof(nullbuf); } return; } } tn = *aedata; switch (subbuffer[SB_SUBOPTION]) { case TNQ_IS: case TNQ_NAME: /* The client should not get one of these */ break; case TNQ_SEND: /* * For telnet clients, the buffer contains: * AUTHENTICATION SEND type modifier [type modifier] [...] IAC SE * DDD is IAC SE in the buffer??? * We scan the type/modifier pairs until we find one we can do. * Since they are are in priority order, the first one we * find that we can do wins. */ for (cp = &subbuffer[SB_TYPE]; cp < buflimit; cp += 2) { pair = (cp[0] << 8) | cp[1]; for (code = authmodules; code; code = code->next) { for (i = 0; i < code->npairs; i++) { if (pair == code->pairs[i]) goto brk; } } } brk: if (!code) { /* * If no methods match, send null authentication. */ BlockMove((Ptr)nullbuf, (Ptr)sendbuffer, sizeof(nullbuf)); *sendlength -= sizeof(nullbuf); return; } /* * If no auth data, initialize it now. */ if (!(tn->authdata)) { #ifdef powerc s = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, TNFUNC_INIT_SESSION_AUTH, &tn->authdata); if ((s == 0) && !tn->encryptdata) s = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, TNFUNC_INIT_SESSION_ENCRYPT, &tn->encryptdata); #else s = (*code->entry)(TNFUNC_INIT_SESSION_AUTH, &tn->authdata); if ((s == 0) && !tn->encryptdata) s = (*code->entry)(TNFUNC_INIT_SESSION_ENCRYPT, &tn->encryptdata); #endif if (s) { /* if no memory, etc */ BlockMove((Ptr)nullbuf, (Ptr)sendbuffer, sizeof(nullbuf)); *sendlength -= sizeof(nullbuf); return; } tn->entry = code->entry; } /* * Process the SEND option */ tn->subbuffer = subbuffer; tn->sublength = sublength; tn->sendbuffer = sendbuffer; tn->sendlength = sendlength; tn->cname = cname; tn->hisencrypt = hisencrypt; tn->myencrypt = myencrypt; #ifdef powerc s = CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, TNFUNC_AUTH_SEND, tn); #else s = (*tn->entry)(TNFUNC_AUTH_SEND, tn); #endif if (s) { /* ddd null probably wrong here ??? */ BlockMove((Ptr)nullbuf, (Ptr)sendbuffer, sizeof(nullbuf)); *sendlength -= sizeof(nullbuf); } return; case TNQ_REPLY: /* * Process the reply. */ if (!(tn->authdata)) { DebugStr("\pauth_suboption: tnq_reply no authdata"); return; } tn->subbuffer = subbuffer; tn->sublength = sublength; tn->sendbuffer = sendbuffer; tn->sendlength = sendlength; tn->cname = cname; tn->hisencrypt = hisencrypt; tn->myencrypt = myencrypt; #ifdef powerc s = CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, TNFUNC_AUTH_REPLY, tn); #else s = (*tn->entry)(TNFUNC_AUTH_REPLY, tn); #endif switch (s) { case TNREP_OK: return; case TNREP_AUTH_OK: break; case TNREP_AUTH_ERR: break; } return; } } /* * encrypt_suboption * Called by the Telnet client when an encryption sub-option is received. * The reply option (if any) is placed into sendbuffer and *sendlength adjusted * by the amount of data placed into sendbuffer. */ short encrypt_suboption (tnParams **aedata, unsigned char *subbuffer, long sublength, unsigned char *sendbuffer, unsigned long *sendlength, char *cname, Boolean hisencrypt, Boolean myencrypt) { short s; tnParams *tn; struct codemodule *code = 0; /* * Initialize session's tnParams if not there. * Return null auth if no memory and TNQ_SEND. */ if (!(*aedata)) { *aedata = (tnParams *)myNewPtr(sizeof(tnParams)); if (!(*aedata)) { return 0; } } tn = *aedata; if (!tn->encryptdata) { for (code = authmodules; code; code = code->next) { if (code->encryptok) break; } if (!code) return 0; #ifdef powerc s = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, TNFUNC_INIT_SESSION_ENCRYPT, &tn->encryptdata); #else s = (*code->entry)(TNFUNC_INIT_SESSION_ENCRYPT, &tn->encryptdata); #endif if (s) return TNREP_ERROR; tn->entry = code->entry; } tn->subbuffer = subbuffer; tn->sublength = sublength; tn->sendbuffer = sendbuffer; tn->sendlength = sendlength; tn->cname = cname; tn->hisencrypt = hisencrypt; tn->myencrypt = myencrypt; #ifdef powerc s = CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, TNFUNC_ENCRYPT_SB, tn); #else s = (*tn->entry)(TNFUNC_ENCRYPT_SB, tn); #endif return s; } unsigned char decrypt (tnParams *tn, long value) { tn->data = value; #ifdef powerc CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, TNFUNC_DECRYPT, tn); #else (*tn->entry)(TNFUNC_DECRYPT, tn); #endif return (unsigned char)tn->data; } void encrypt (tnParams *tn, unsigned char *buf, long len) { tn->data = len; tn->ebuf = buf; #ifdef powerc CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, TNFUNC_ENCRYPT, tn); #else (*tn->entry)(TNFUNC_ENCRYPT, tn); #endif } /* * qlink * Add an entry to the end of a linked list */ void qlink (void **flist, void *fentry) { struct dummy { struct dummy *next; } **list, *entry; list = flist; entry = fentry; /* * Find address of last entry in the list. */ while (*list) list = &(*list)->next; /* * Link entry */ *list = entry; entry->next = 0; } /* * qunlink * Remove an entry from linked list * Returns the entry or NULL if not found. */ void *qunlink (void **flist, void *fentry) { struct dummy { struct dummy *next; } **list, *entry; list = flist; entry = fentry; /* * Find entry and unlink it */ while (*list) { if ((*list) == entry) { *list = entry->next; return entry; } list = &(*list)->next; } return NULL; } short hicall (long cscode, krbHiParmBlock *khipb, short kdriver) { short s; ParamBlockRec pb; WriteZero((Ptr)&pb, sizeof(ParamBlockRec)); *(long *)pb.cntrlParam.csParam = (long)khipb; pb.cntrlParam.ioCompletion = nil; pb.cntrlParam.ioCRefNum = kdriver; pb.cntrlParam.csCode = cscode; if (s = PBControl(&pb, false)) return s; if (s = pb.cntrlParam.ioResult) return s; return 0; } void DestroyTickets(void) { OSErr err; //short authRefNumkrb; krbHiParmBlock khpb, *khipb = &khpb; short kdriver; if (!(err = OpenDriver("\p.Kerberos", &kdriver))) { WriteZero((Ptr)khipb, sizeof(krbHiParmBlock)); if (err = hicall(cKrbDeleteAllSessions, khipb, kdriver)) return; } //else if (!(err=openAuthMan(&authRefNum,&authAPIversion))) // if (err=expireV4Ticket(authRefNum,NULL,NULL,NULL)) // return; } \ No newline at end of file +/* * Authencrypt.c * Authentication module for NCSA/Telnet and Brown tn3270. */ // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "tnae.h" #include "authencrypt.h" #include "authencrypt.proto.h" #include "KrbDriver.h" #include "DlogUtils.proto.h" #include "network.proto.h" #include "MixedMode.h" #define NAUTHTYPES 10 /* Max number of auth types */ struct codemodule *authmodules = 0; /* list of authentication code modules */ static char nullbuf[] = {IAC, SB, OPT_AUTHENTICATION, TNQ_IS, AUTH_NULL, AUTH_CLIENT_TO_SERVER|AUTH_HOW_ONE_WAY, IAC, SE}; #ifdef powerc enum { uppModule = kCStackBased | RESULT_SIZE(SIZE_CODE(sizeof(long))) | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))) | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr))) }; #endif #ifdef __MWERKS__ #pragma profile off #endif static void scanFolder(short vRef, long dirID); static void loadCode(HParamBlockRec *pb, long dirid, Str255 name, OSType type, codemodule **header); short hicall (long cscode, krbHiParmBlock *khipb, short kdriver); /* * auth_encrypt_init * Initialize processing for auth/encrypt options. * Find all the modules that support auth/encrypt and add them to our * typepairs and modules table. Load those modules and initialize them. * * Return true if any auth module found. */ Boolean auth_encrypt_init () { short vref; long dirid = 0, fold; SysEnvRec theWorld; /* * Find and load/initialize files with code modules. * First, Try to find the Extensions folder, else use the system folder. */ if (Gestalt('fold', &fold) || ((fold & 1) != 1) || FindFolder(kOnSystemDisk, kExtensionFolderType, false, &vref, &dirid)) { if (SysEnvirons (1, &theWorld) == 0) vref = theWorld.sysVRefNum; else vref = -1; } scanFolder(vref, dirid); // Now scan the folder that Telnet lives in scanFolder(TelInfo->ApFolder.vRefNum, TelInfo->ApFolder.parID); if (authmodules) return true; return false; } /* * auth_encrypt_end * Allow authentication plugins to free memory, etc */ void auth_encrypt_end(tnParams **aedata) { int i; OSErr s; tnParams *tn = *aedata; #ifdef powerc s = CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, TNFUNC_END_SESSION, tn); #else s = (tn->entry)(TNFUNC_END_SESSION, tn); #endif } static void scanFolder(short vRef, long dirID) { short i; HParamBlockRec pb; Str255 name; OSErr s; for (i = 1; ; i++ ) { pb.fileParam.ioCompletion = 0; pb.fileParam.ioVRefNum = vRef; pb.fileParam.ioFVersNum = 0; pb.fileParam.ioFDirIndex = i; pb.fileParam.ioDirID = dirID; pb.fileParam.ioNamePtr = name; if ((s = PBHGetFInfoSync(&pb)) != noErr) break; /* Check for module types that we are interested in. */ if (pb.fileParam.ioFlFndrInfo.fdType == moduleType) { OSType *authType = authTypes; while(*authType != 0) { loadCode(&pb, dirID, name, *authType, &authmodules); ++authType; } } } } void loadCode (HParamBlockRec *pb, long dirid, Str255 name, OSType type, codemodule **header) { int i; short rf, oldrf; struct codemodule *code = 0; Handle h; oldrf = CurResFile(); rf = HOpenResFile(pb->fileParam.ioVRefNum, dirid, name, fsRdPerm); if (rf == -1) return; SetResLoad(true); /* * Find all resources of indicated type. */ for (i = 1; ; i++) { if (!((h = Get1IndResource(type, i)))) break; code = (struct codemodule *)myNewPtr(sizeof(struct codemodule)); if (code) { DetachResource(h); HNoPurge(h); HLockHi(h); code->entry = (module)*h; code->authType = type; /* * Initialize the module. * It should preset the type/pairs list and return the number of * pairs entered. */ #ifdef powerc code->npairs = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, TNFUNC_INIT_CODE, &code->pairs); code->encryptok = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, TNFUNC_QUERY_ENCRYPT, 0); #else code->npairs = (*code->entry)(TNFUNC_INIT_CODE, &code->pairs); code->encryptok = (*code->entry)(TNFUNC_QUERY_ENCRYPT, 0); #endif qlink(header, code); } else ReleaseResource(h); } CloseResFile(rf); /* ddd for debugging with The Debugger ***/ UseResFile(oldrf); } /* * auth_suboption * Called by the Telnet client when an authentication sub-option is received. * The reply option (if any) is placed into sendbuffer and *sendlength adjusted * by the amount of data placed into sendbuffer. */ void auth_suboption (tnParams **aedata, unsigned char *subbuffer, long sublength, unsigned char *sendbuffer, unsigned long *sendlength, char *cname, Boolean hisencrypt, Boolean myencrypt, unsigned short port) { int i; OSErr s; unsigned short pair; unsigned char *cp, *buflimit; struct codemodule *code = 0; tnParams *tn; /* temp params struct */ buflimit = subbuffer + sublength; /* * Initialize session's tnParams if not initialized yet. * Return null auth if no memory and TNQ_SEND. */ if (!(*aedata)) { *aedata = (tnParams *)myNewPtr(sizeof(tnParams)); if (!(*aedata)) { if (subbuffer[SB_SUBOPTION] == TNQ_SEND) { BlockMove((Ptr)nullbuf, (Ptr)sendbuffer, sizeof(nullbuf)); *sendlength -= sizeof(nullbuf); } return; } } tn = *aedata; switch (subbuffer[SB_SUBOPTION]) { case TNQ_IS: case TNQ_NAME: /* The client should not get one of these */ break; case TNQ_SEND: /* * For telnet clients, the buffer contains: * AUTHENTICATION SEND type modifier [type modifier] [...] IAC SE * DDD is IAC SE in the buffer??? * We scan the type/modifier pairs until we find one we can do. * Since they are are in priority order, the first one we * find that we can do wins. */ for (cp = &subbuffer[SB_TYPE]; cp < buflimit; cp += 2) { pair = (cp[0] << 8) | cp[1]; for (code = authmodules; code; code = code->next) { for (i = 0; i < code->npairs; i++) { if (pair == code->pairs[i]) goto brk; } } } brk: if (!code) { /* * If no methods match, send null authentication. */ BlockMove((Ptr)nullbuf, (Ptr)sendbuffer, sizeof(nullbuf)); *sendlength -= sizeof(nullbuf); return; } /* * If no auth data, initialize it now. */ if (!(tn->authdata)) { netgetip(tn->ipaddr); tn->port = netgetport(port); switch (code->authType) { case 'TNae': #ifdef powerc s = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, TNFUNC_INIT_SESSION_AUTH, &tn->authdata); if ((s == 0) && !tn->encryptdata) s = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, TNFUNC_INIT_SESSION_ENCRYPT, &tn->encryptdata); #else s = (*code->entry)(TNFUNC_INIT_SESSION_AUTH, &tn->authdata); if ((s == 0) && !tn->encryptdata) s = (*code->entry)(TNFUNC_INIT_SESSION_ENCRYPT, &tn->encryptdata); #endif break; default: #ifdef powerc s = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, TNFUNC_INIT_SESSION_AUTH, tn); if ((s == 0) && !tn->encryptdata) s = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, TNFUNC_INIT_SESSION_ENCRYPT, tn); #else s = (*code->entry)(TNFUNC_INIT_SESSION_AUTH, tn); if ((s == 0) && !tn->encryptdata) s = (*code->entry)(TNFUNC_INIT_SESSION_ENCRYPT, tn); #endif } if (s) { /* if no memory, etc */ BlockMove((Ptr)nullbuf, (Ptr)sendbuffer, sizeof(nullbuf)); *sendlength -= sizeof(nullbuf); return; } tn->entry = code->entry; } /* * Process the SEND option */ tn->subbuffer = subbuffer; tn->sublength = sublength; tn->sendbuffer = sendbuffer; tn->sendlength = sendlength; tn->cname = cname; tn->hisencrypt = hisencrypt; tn->myencrypt = myencrypt; #ifdef powerc s = CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, TNFUNC_AUTH_SEND, tn); #else s = (*tn->entry)(TNFUNC_AUTH_SEND, tn); #endif if (s) { /* ddd null probably wrong here ??? */ BlockMove((Ptr)nullbuf, (Ptr)sendbuffer, sizeof(nullbuf)); *sendlength -= sizeof(nullbuf); } return; case TNQ_REPLY: /* * Process the reply. */ if (!(tn->authdata)) { DebugStr("\pauth_suboption: tnq_reply no authdata"); return; } tn->subbuffer = subbuffer; tn->sublength = sublength; tn->sendbuffer = sendbuffer; tn->sendlength = sendlength; tn->cname = cname; tn->hisencrypt = hisencrypt; tn->myencrypt = myencrypt; #ifdef powerc s = CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, TNFUNC_AUTH_REPLY, tn); #else s = (*tn->entry)(TNFUNC_AUTH_REPLY, tn); #endif switch (s) { case TNREP_OK: return; case TNREP_AUTH_OK: break; case TNREP_AUTH_ERR: break; } return; } } /* * encrypt_suboption * Called by the Telnet client when an encryption sub-option is received. * The reply option (if any) is placed into sendbuffer and *sendlength adjusted * by the amount of data placed into sendbuffer. */ short encrypt_suboption (tnParams **aedata, unsigned char *subbuffer, long sublength, unsigned char *sendbuffer, unsigned long *sendlength, char *cname, Boolean hisencrypt, Boolean myencrypt) { short s; tnParams *tn; struct codemodule *code = 0; /* * Initialize session's tnParams if not there. * Return null auth if no memory and TNQ_SEND. */ if (!(*aedata)) { *aedata = (tnParams *)myNewPtr(sizeof(tnParams)); if (!(*aedata)) { return 0; } } tn = *aedata; if (!tn->encryptdata) { for (code = authmodules; code; code = code->next) { if (code->encryptok) break; } if (!code) return 0; switch (code->authType) { case 'TNae': #ifdef powerc s = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, TNFUNC_INIT_SESSION_ENCRYPT, &tn->encryptdata); #else s = (*code->entry)(TNFUNC_INIT_SESSION_ENCRYPT, &tn->encryptdata); #endif break; default: #ifdef powerc s = CallUniversalProc((UniversalProcPtr)code->entry, uppModule, TNFUNC_INIT_SESSION_ENCRYPT, tn); #else s = (*code->entry)(TNFUNC_INIT_SESSION_ENCRYPT, tn); #endif } if (s) return TNREP_ERROR; tn->entry = code->entry; } tn->subbuffer = subbuffer; tn->sublength = sublength; tn->sendbuffer = sendbuffer; tn->sendlength = sendlength; tn->cname = cname; tn->hisencrypt = hisencrypt; tn->myencrypt = myencrypt; #ifdef powerc s = CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, TNFUNC_ENCRYPT_SB, tn); #else s = (*tn->entry)(TNFUNC_ENCRYPT_SB, tn); #endif return s; } unsigned char decrypt (tnParams *tn, long value) { tn->data = value; #ifdef powerc CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, TNFUNC_DECRYPT, tn); #else (*tn->entry)(TNFUNC_DECRYPT, tn); #endif return (unsigned char)tn->data; } void encrypt (tnParams *tn, unsigned char *buf, long len) { tn->data = len; tn->ebuf = buf; #ifdef powerc CallUniversalProc((UniversalProcPtr)tn->entry, uppModule, TNFUNC_ENCRYPT, tn); #else (*tn->entry)(TNFUNC_ENCRYPT, tn); #endif } /* * qlink * Add an entry to the end of a linked list */ void qlink (void **flist, void *fentry) { struct dummy { struct dummy *next; } **list, *entry; list = flist; entry = fentry; /* * Find address of last entry in the list. */ while (*list) list = &(*list)->next; /* * Link entry */ *list = entry; entry->next = 0; } /* * qunlink * Remove an entry from linked list * Returns the entry or NULL if not found. */ void *qunlink (void **flist, void *fentry) { struct dummy { struct dummy *next; } **list, *entry; list = flist; entry = fentry; /* * Find entry and unlink it */ while (*list) { if ((*list) == entry) { *list = entry->next; return entry; } list = &(*list)->next; } return NULL; } short hicall (long cscode, krbHiParmBlock *khipb, short kdriver) { short s; ParamBlockRec pb; WriteZero((Ptr)&pb, sizeof(ParamBlockRec)); *(long *)pb.cntrlParam.csParam = (long)khipb; pb.cntrlParam.ioCompletion = nil; pb.cntrlParam.ioCRefNum = kdriver; pb.cntrlParam.csCode = cscode; if (s = PBControlSync(&pb)) return s; if (s = pb.cntrlParam.ioResult) return s; return 0; } void DestroyTickets(void) { OSErr err; //short authRefNumkrb; krbHiParmBlock khpb, *khipb = &khpb; short kdriver; if (!(err = OpenDriver("\p.Kerberos", &kdriver))) { WriteZero((Ptr)khipb, sizeof(krbHiParmBlock)); if (err = hicall(cKrbDeleteAllSessions, khipb, kdriver)) return; } //else if (!(err=openAuthMan(&authRefNum,&authAPIversion))) // if (err=expireV4Ticket(authRefNum,NULL,NULL,NULL)) // return; } \ No newline at end of file diff --git a/source/parse/authencrypt.h b/source/parse/authencrypt.h index fa3575d..96ca3a3 100755 --- a/source/parse/authencrypt.h +++ b/source/parse/authencrypt.h @@ -1 +1 @@ -typedef struct codemodule { struct codemodule *next; /* pointer to next in list */ module entry; /* module entry point */ short npairs; /* number of type/modifier pairs */ Boolean encryptok; /* module does option 38 encryption */ unsigned short pairs[NTMPAIRS]; /* type/modifier pairs */ } codemodule; \ No newline at end of file +typedef struct codemodule { struct codemodule *next; /* pointer to next in list */ module entry; /* module entry point */ short npairs; /* number of type/modifier pairs */ Boolean encryptok; /* module does option 38 encryption */ unsigned short pairs[NTMPAIRS]; /* type/modifier pairs */ OSType authType; } codemodule; \ No newline at end of file diff --git a/source/parse/authencrypt.proto.h b/source/parse/authencrypt.proto.h index 65ec035..0fd097e 100755 --- a/source/parse/authencrypt.proto.h +++ b/source/parse/authencrypt.proto.h @@ -1 +1 @@ -/* * :main:authencrypt.c */ Boolean auth_encrypt_init(void); void auth_suboption(tnParams **aedata, unsigned char *subbuffer, long sublength, unsigned char *sendbuffer, unsigned long *sendlength, char *cname, Boolean hisencrypt, Boolean myencrypt); short encrypt_suboption(tnParams **aedata, unsigned char *subbuffer, long sublength, unsigned char *sendbuffer, unsigned long *sendlength, char *cname, Boolean hisencrypt, Boolean myencrypt); unsigned char decrypt(tnParams *tn, long value); void encrypt(tnParams *tn, unsigned char *buf, long len); void qlink(void **flist, void *fentry); void *qunlink(void **flist, void *fentry); void DestroyTickets(void); \ No newline at end of file +/* * :main:authencrypt.c */ Boolean auth_encrypt_init(void); void auth_suboption(tnParams **aedata, unsigned char *subbuffer, long sublength, unsigned char *sendbuffer, unsigned long *sendlength, char *cname, Boolean hisencrypt, Boolean myencrypt, unsigned short port); void auth_encrypt_end(tnParams **aedata); short encrypt_suboption(tnParams **aedata, unsigned char *subbuffer, long sublength, unsigned char *sendbuffer, unsigned long *sendlength, char *cname, Boolean hisencrypt, Boolean myencrypt); unsigned char decrypt(tnParams *tn, long value); void encrypt(tnParams *tn, unsigned char *buf, long len); void qlink(void **flist, void *fentry); void *qunlink(void **flist, void *fentry); void DestroyTickets(void); \ No newline at end of file diff --git a/source/parse/md5.proto.h b/source/parse/md5.proto.h index 9abfe46..d4024b9 100755 --- a/source/parse/md5.proto.h +++ b/source/parse/md5.proto.h @@ -1 +1 @@ -void otpmd5init (struct otpmdx_ctx *context); void otpmd5update (struct otpmdx_ctx *context, unsigned char *input, unsigned short inputLen); void otpmd5final (unsigned char *digest, struct otpmdx_ctx *context); \ No newline at end of file +void otpmd5init (struct otpmdx_ctx *context); void otpmd5update (struct otpmdx_ctx *context, unsigned char *input, unsigned short inputLen); void otpmd5final (unsigned char *digest, struct otpmdx_ctx *context); void MD5Transform (unsigned long *, unsigned char *); \ No newline at end of file diff --git a/source/parse/otp.c b/source/parse/otp.c index a061ae7..4e1cd45 100755 --- a/source/parse/otp.c +++ b/source/parse/otp.c @@ -1 +1 @@ -// BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // otp.c // by Rolf Braun // code to support OTP (One-Time Passwords), OPIE (One-time Passwords In Everything), // and Bellcore's original S/Key system. #include "otp.proto.h" #include "md4.proto.h" #include "md5.proto.h" #include "DlogUtils.proto.h" #include "rsinterf.proto.h" #include "tekrgmac.proto.h" #include "vrrgmac.proto.h" #include "errors.proto.h" #include "wind.h" #include "network.proto.h" #include "movableModal.h" #include "parse.proto.h" struct otpmdx_ctx { unsigned long state[4]; unsigned long count[2]; unsigned char buffer[64]; }; extern short scrn; extern WindRec *screens; static char inputPassword[256]; PROTO_UPP(OTPModalFilter, ModalFilter); pascal short OTPModalFilter (DialogPtr dptr, EventRecord *evt, short *item); SIMPLE_UPP(OTPModalFilter, ModalFilter); pascal short OTPModalFilter(DialogPtr dptr, EventRecord *evt, short *item) { short key, tempLen; if ((evt->what == keyDown) || (evt->what == autoKey)) if ((((DialogPeek)dptr)->editField + 1) == 5) { key = evt->message & charCodeMask; if (key == 8) { inputPassword[0] = 0; SetTEText(dptr, 5, "\p"); *item = 0; return -1; } if (key == 9) return 0; if (key < 32) { *item = 0; StdFilterProc(dptr, evt, item); return -1; } tempLen = strlen(inputPassword); if (tempLen < 250) { inputPassword[tempLen] = key; inputPassword[tempLen+1] = 0; } evt->message = (evt->message & 0xFFFFFF00) + ''; return 0; } *item = 0; StdFilterProc(dptr, evt, item); if (*item != 0) return -1; return 0; } void otpgetselection(char *selection) { short i; Handle charh; *selection = 0; // Here we check for a valid text selection. if (TelInfo->numwindows<1) return; // No windows? No problem! if (MacRGfindwind(FrontWindow()) >= 0) return; // ICR is not text. if (RGgetdnum(FrontWindow()) > -1) return; // Tektronix is also not text. if ((i = RSfindvwind(FrontWindow())) < 0) return; // It had better be a text window... if (!RSTextSelected(i)) return; // ...with something selected! charh = RSGetTextSel(i, 0); // Get the text selection if (charh == (char **)-1L) OutOfMemory(400); if (charh != (char **)0L) { if ((GetHandleSize(charh) != 0) && (GetHandleSize(charh) < 250)) { HLock(charh); BlockMove(*charh, selection + 1, GetHandleSize(charh)); selection[0] = GetHandleSize(charh); } DisposeHandle(charh); } } void otpinterface(short mode, char *parsechallenge, struct WindRec *tw, short usehexin, short noprompt, char *passwordin, short savepass) { short ditem, usehex, i; DialogPtr dptr; static Str255 challenge, response, tempstring; usehex = usehexin; if (mode) { strcpy((char *)challenge, parsechallenge); c2pstr((char *)challenge); } else otpgetselection((char *) challenge); if (mode && noprompt) if (passwordin[0]) { pstrcpy(tempstring, (unsigned char *)passwordin); p2cstr(tempstring); p2cstr(challenge); otpgenerator((char *)challenge, (char *)response, (char *)tempstring, usehex); SendStringAsIfTyped(tw, (char *)response, strlen((char *)response)); // If crmap is on, send CR-NULL instead of CR-LF. if (tw->crmap) SendStringAsIfTyped(tw,"\015\0",2); else SendStringAsIfTyped(tw,"\015\012",2); //UNIVAC fix return; } SetUpMovableModalMenus(); dptr = GetNewDialog(8000, 0, (WindowPtr)-1); SetDialogDefaultItem(dptr, 1); SetDialogCancelItem(dptr, 3); SetDialogTracksCursor(dptr, 1); SetTEText(dptr, 4, challenge); if (mode && usehex) SetCntrl(dptr, 8, 1); else SetCntrl(dptr, 7, 1); ditem = 0; inputPassword[0] = 0; if (gApplicationPrefs->globalSavePass) { strcpy(inputPassword, TelInfo->otpword); for (i = 1; i < 250; i++) tempstring[i] = ''; tempstring[0] = strlen(inputPassword); SetTEText(dptr, 5, tempstring); } if (mode) if (passwordin[0]) { pstrcpy((unsigned char *)inputPassword, (unsigned char *)passwordin); p2cstr((unsigned char *)inputPassword); for (i = 1; i < 250; i++) tempstring[i] = ''; tempstring[0] = strlen(inputPassword); SetTEText(dptr, 5, tempstring); } if (mode || challenge[0]) SelIText(dptr, 5, 0, 32767); while ((ditem != 1) && (ditem != 3)) { movableModalDialog(OTPModalFilterUPP, &ditem); switch (ditem) { case 7: SetCntrl(dptr, 7, 1); SetCntrl(dptr, 8, 0); goto generate; case 8: SetCntrl(dptr, 7, 0); SetCntrl(dptr, 8, 1); case 2: generate: GetTEText(dptr, 4, challenge); usehex = GetCntlVal(dptr, 8); p2cstr(challenge); otpgenerator((char *)challenge, (char *)response, inputPassword, usehex); c2pstr((char *)response); SetTEText(dptr, 6, response); } } if (ditem == 1) { GetTEText(dptr, 4, challenge); usehex = GetCntlVal(dptr, 8); p2cstr(challenge); otpgenerator((char *)challenge, (char *)response, inputPassword, usehex); if ((strlen(inputPassword) < 63) && gApplicationPrefs->globalSavePass) strcpy(TelInfo->otpword, inputPassword); if (savepass && (strlen(inputPassword) < 63)) { // RAB BetterTelnet 1.2.1 strcpy(passwordin, inputPassword); c2pstr(passwordin); } } DisposeDialog(dptr); ResetMenus(); if (TelInfo->numwindows<1) return; // No windows? No problem! if (ditem == 1) { if (mode) { SendStringAsIfTyped(tw, (char *)response, strlen((char *)response)); // If crmap is on, send CR-NULL instead of CR-LF. if (tw->crmap) SendStringAsIfTyped(tw,"\015\0",2); else SendStringAsIfTyped(tw,"\015\012",2); //UNIVAC fix } else { SendStringAsIfTyped(&screens[scrn], (char *)response, strlen((char *)response)); // If crmap is on, send CR-NULL instead of CR-LF. if (screens[scrn].crmap) SendStringAsIfTyped(&screens[scrn],"\015\0",2); else SendStringAsIfTyped(&screens[scrn],"\015\012",2); //UNIVAC fix } } } void otpgenerator(char *challenge, char *response, char *password, short usehex) { short algorithm; unsigned long sequence; char key[8]; char *cptr; char *seed; static char buffer[256]; *response = 0; cptr = challenge; if (strncmp(challenge, "otp-", 4)) { if (strncmp(challenge, "s/key ", 6)) return; else { cptr += 6; algorithm = 0; } } else { cptr += 4; if (strncmp(cptr, "md4 ", 4)) { if (strncmp(cptr, "md5 ", 4)) { if (strncmp(cptr, "sha1 ", 5)) return; else algorithm = 2; cptr++; } else algorithm = 1; } else algorithm = 0; cptr += 4; } if ((sequence = strtoul(cptr, &cptr, 10)) > 9999) return; while(*cptr && isspace(*cptr)) cptr++; if (!*cptr) return; seed = cptr; while (*cptr && !isspace(*cptr)) cptr++; *cptr = 0; if ((sequence < 1) || (sequence > 9999)) return; if ((strlen(seed) + strlen(password)) > 250) return; strcpy(buffer, seed); strcat(buffer, password); otphashlen(algorithm, buffer, key); while (sequence-- != 0) otphash(algorithm, key); if (usehex) otpbtoh(key, response); else otpbtoe(key, response); } void otphashlen(short algorithm, char *buffer, char *key) { static struct otpmdx_ctx mdx; unsigned long mdx_tmp[4]; unsigned long sha1_tmp[5]; static SHA1_CTX sha1data; unsigned long *results = (unsigned long *) key; if (algorithm == 2) { SHA1Init(&sha1data); SHA1Update(&sha1data, (unsigned char *)buffer, strlen(buffer)); SHA1Final((unsigned char *)sha1_tmp, &sha1data); results[0] = sha1_tmp[0] ^ sha1_tmp[2] ^ sha1_tmp[4]; results[1] = sha1_tmp[1] ^ sha1_tmp[3]; return; } if (algorithm == 1) { otpmd5init(&mdx); otpmd5update(&mdx, (unsigned char *)buffer, strlen(buffer)); otpmd5final((unsigned char *)mdx_tmp, &mdx); } else { otpmd4init(&mdx); otpmd4update(&mdx, (unsigned char *)buffer, strlen(buffer)); otpmd4final((unsigned char *)mdx_tmp, &mdx); } results[0] = mdx_tmp[0] ^ mdx_tmp[2]; results[1] = mdx_tmp[1] ^ mdx_tmp[3]; } void otphash(short algorithm, char *key) { static struct otpmdx_ctx mdx; unsigned long mdx_tmp[4]; unsigned long sha1_tmp[5]; static SHA1_CTX sha1data; unsigned long *results = (unsigned long *) key; if (algorithm == 2) { SHA1Init(&sha1data); SHA1Update(&sha1data, (unsigned char *)key, 8); SHA1Final((unsigned char *)sha1_tmp, &sha1data); results[0] = sha1_tmp[0] ^ sha1_tmp[2] ^ sha1_tmp[4]; results[1] = sha1_tmp[1] ^ sha1_tmp[3]; return; } if (algorithm) { otpmd5init(&mdx); otpmd5update(&mdx, (unsigned char *)key, 8); otpmd5final((unsigned char *)mdx_tmp, &mdx); } else { otpmd4init(&mdx); otpmd4update(&mdx, (unsigned char *)key, 8); otpmd4final((unsigned char *)mdx_tmp, &mdx); } results[0] = mdx_tmp[0] ^ mdx_tmp[2]; results[1] = mdx_tmp[1] ^ mdx_tmp[3]; } static char hextochar[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; char* otpbtoh (char *in, char *out) { short i; char *c = out; for (i = 0; i < 4; i++) { *(c++) = hextochar[((*in) >> 4) & 0x0f]; *(c++) = hextochar[(*in++) & 0x0f]; *(c++) = hextochar[((*in) >> 4) & 0x0f]; *(c++) = hextochar[(*in++) & 0x0f]; *(c++) = ' '; } *(--c) = 0; return out; } static char otpenglish[2048][4] = { "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD", "AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA", "AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK", "ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE", "AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM", "BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET", "BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO", "BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT", "BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT", "CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY", "CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN", "DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG", "DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB", "DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO", "ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE", "EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW", "FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR", "FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP", "GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO", "GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD", "HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM", "HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT", "HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE", "HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL", "INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT", "ITS", "IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET", "JIG", "JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT", "KAY", "KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC", "LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", "LEG", "LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT", "LO", "LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG", "LYE", "MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY", "ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT", "MOB", "MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG", "MUM", "MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED", "NEE", "NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON", "NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF", "OAK", "OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL", "OK", "OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT", "OUR", "OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL", "PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG", "PEN", "PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT", "PLY", "PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB", "PUG", "PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW", "RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM", "RIO", "RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB", "RUE", "RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM", "SAN", "SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW", "SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY", "SLY", "SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY", "SUB", "SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN", "TAP", "TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM", "TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP", "TOW", "TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP", "US", "USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS", "WAY", "WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK", "WON", "WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", "YEA", "YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT", "ACHE", "ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS", "ADEN", "AFAR", "AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE", "AIDS", "AIRY", "AJAR", "AKIN", "ALAN", "ALEC", "ALGA", "ALIA", "ALLY", "ALMA", "ALOE", "ALSO", "ALTO", "ALUM", "ALVA", "AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS", "AMRA", "ANDY", "ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB", "ARCH", "AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS", "ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW", "AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL", "BAIT", "BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM", "BAND", "BANE", "BANG", "BANK", "BARB", "BARD", "BARE", "BARK", "BARN", "BARR", "BASE", "BASH", "BASK", "BASS", "BATE", "BATH", "BAWD", "BAWL", "BEAD", "BEAK", "BEAM", "BEAN", "BEAR", "BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER", "BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT", "BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE", "BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB", "BLAT", "BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE", "BLUM", "BLUR", "BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY", "BOGY", "BOHR", "BOIL", "BOLD", "BOLO", "BOLT", "BOMB", "BONA", "BOND", "BONE", "BONG", "BONN", "BONY", "BOOK", "BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE", "BOSS", "BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN", "BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF", "BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN", "BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE", "CADY", "CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM", "CAME", "CANE", "CANT", "CARD", "CARE", "CARL", "CARR", "CART", "CASE", "CASH", "CASK", "CAST", "CAVE", "CEIL", "CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT", "CHAW", "CHEF", "CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB", "CHUG", "CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY", "CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK", "COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA", "COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", "COON", "COOT", "CORD", "CORE", "CORK", "CORN", "COST", "COVE", "COWL", "CRAB", "CRAG", "CRAM", "CRAY", "CREW", "CRIB", "CROW", "CRUD", "CUBA", "CUBE", "CUFF", "CULL", "CULT", "CUNY", "CURB", "CURD", "CURE", "CURL", "CURT", "CUTS", "DADE", "DALE", "DAME", "DANA", "DANE", "DANG", "DANK", "DARE", "DARK", "DARN", "DART", "DASH", "DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS", "DEAD", "DEAF", "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM", "DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", "DIAL", "DICE", "DIED", "DIET", "DIME", "DINE", "DING", "DINT", "DIRE", "DIRT", "DISC", "DISH", "DISK", "DIVE", "DOCK", "DOES", "DOLE", "DOLL", "DOLT", "DOME", "DONE", "DOOM", "DOOR", "DORA", "DOSE", "DOTE", "DOUG", "DOUR", "DOVE", "DOWN", "DRAB", "DRAG", "DRAM", "DRAW", "DREW", "DRUB", "DRUG", "DRUM", "DUAL", "DUCK", "DUCT", "DUEL", "DUET", "DUKE", "DULL", "DUMB", "DUNE", "DUNK", "DUSK", "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST", "EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", "EDNA", "EGAN", "ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", "EMMA", "ENDS", "ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", "FACE", "FACT", "FADE", "FAIL", "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG", "FARM", "FAST", "FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL", "FEET", "FELL", "FELT", "FEND", "FERN", "FEST", "FEUD", "FIEF", "FIGS", "FILE", "FILL", "FILM", "FIND", "FINE", "FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS", "FIVE", "FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW", "FLIT", "FLOC", "FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", "FOGY", "FOIL", "FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD", "FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL", "FRAU", "FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", "FROM", "FUEL", "FULL", "FUME", "FUND", "FUNK", "FURY", "FUSE", "FUSS", "GAFF", "GAGE", "GAIL", "GAIN", "GAIT", "GALA", "GALE", "GALL", "GALT", "GAME", "GANG", "GARB", "GARY", "GASH", "GATE", "GAUL", "GAUR", "GAVE", "GAWK", "GEAR", "GELD", "GENE", "GENT", "GERM", "GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT", "GINA", "GIRD", "GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB", "GLOB", "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", "GOAT", "GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", "GOOD", "GOOF", "GORE", "GORY", "GOSH", "GOUT", "GOWN", "GRAB", "GRAD", "GRAY", "GREG", "GREW", "GREY", "GRID", "GRIM", "GRIN", "GRIT", "GROW", "GRUB", "GULF", "GULL", "GUNK", "GURU", "GUSH", "GUST", "GWEN", "GWYN", "HAAG", "HAAS", "HACK", "HAIL", "HAIR", "HALE", "HALF", "HALL", "HALO", "HALT", "HAND", "HANG", "HANK", "HANS", "HARD", "HARK", "HARM", "HART", "HASH", "HAST", "HATE", "HATH", "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", "HEAT", "HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", "HELM", "HERB", "HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", "HICK", "HIDE", "HIGH", "HIKE", "HILL", "HILT", "HIND", "HINT", "HIRE", "HISS", "HIVE", "HOBO", "HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT", "HOME", "HONE", "HONK", "HOOD", "HOOF", "HOOK", "HOOT", "HORN", "HOSE", "HOST", "HOUR", "HOVE", "HOWE", "HOWL", "HOYT", "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO", "HULK", "HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE", "HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", "INTO", "IONS", "IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", "ITCH", "ITEM", "IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN", "JEFF", "JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE", "JOAN", "JOBS", "JOCK", "JOEL", "JOEY", "JOHN", "JOIN", "JOKE", "JOLT", "JOVE", "JUDD", "JUDE", "JUDO", "JUDY", "JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO", "JURY", "JUST", "JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", "KATE", "KEEL", "KEEN", "KENO", "KENT", "KERN", "KERR", "KEYS", "KICK", "KILL", "KIND", "KING", "KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", "KNIT", "KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE", "LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE", "LAMB", "LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS", "LAST", "LATE", "LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD", "LEAF", "LEAK", "LEAN", "LEAR", "LEEK", "LEER", "LEFT", "LEND", "LENS", "LENT", "LEON", "LESK", "LESS", "LEST", "LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES", "LIEU", "LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB", "LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE", "LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA", "LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE", "LOSS", "LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE", "LUKE", "LULU", "LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH", "LUST", "LYLE", "LYNN", "LYON", "LYRA", "MACE", "MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE", "MALE", "MALI", "MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE", "MARK", "MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE", "MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET", "MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE", "MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND", "MINE", "MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE", "MITT", "MOAN", "MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL", "MOLT", "MONA", "MONK", "MONT", "MOOD", "MOON", "MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS", "MOST", "MOTH", "MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL", "MURK", "MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL", "NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT", "NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS", "NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH", "NODE", "NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE", "NOTE", "NOUN", "NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY", "OBOE", "ODIN", "OHIO", "OILY", "OINT", "OKAY", "OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN", "OMIT", "ONCE", "ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO", "OTIS", "OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY", "OWNS", "QUAD", "QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE", "RAID", "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", "RATE", "RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", "RECK", "REED", "REEF", "REEK", "REEL", "REID", "REIN", "RENA", "REND", "RENT", "REST", "RICE", "RICH", "RICK", "RIDE", "RIFT", "RILL", "RIME", "RING", "RINK", "RISE", "RISK", "RITE", "ROAD", "ROAM", "ROAR", "ROBE", "ROCK", "RODE", "ROIL", "ROLL", "ROME", "ROOD", "ROOF", "ROOK", "ROOM", "ROOT", "ROSA", "ROSE", "ROSS", "ROSY", "ROTH", "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY", "RUDE", "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", "RUSH", "RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", "SAID", "SAIL", "SALE", "SALK", "SALT", "SAME", "SAND", "SANE", "SANG", "SANK", "SARA", "SAUL", "SAVE", "SAYS", "SCAN", "SCAR", "SCAT", "SCOT", "SEAL", "SEAM", "SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN", "SEES", "SELF", "SELL", "SEND", "SENT", "SETS", "SEWN", "SHAG", "SHAM", "SHAW", "SHAY", "SHED", "SHIM", "SHIN", "SHOD", "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK", "SIDE", "SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", "SINE", "SING", "SINK", "SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", "SKID", "SKIM", "SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", "SLED", "SLEW", "SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG", "SLUM", "SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB", "SNUG", "SOAK", "SOAR", "SOCK", "SODA", "SOFA", "SOFT", "SOIL", "SOLD", "SOME", "SONG", "SOON", "SOOT", "SORE", "SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG", "STAN", "STAR", "STAY", "STEM", "STEW", "STIR", "STOW", "STUB", "STUN", "SUCH", "SUDS", "SUIT", "SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF", "SWAB", "SWAG", "SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", "TACK", "TACT", "TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE", "TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", "TEET", "TELL", "TEND", "TENT", "TERM", "TERN", "TESS", "TEST", "THAN", "THAT", "THEE", "THEM", "THEN", "THEY", "THIN", "THIS", "THUD", "THUG", "TICK", "TIDE", "TIDY", "TIED", "TIER", "TILE", "TILL", "TILT", "TIME", "TINA", "TINE", "TINT", "TINY", "TIRE", "TOAD", "TOGO", "TOIL", "TOLD", "TOLL", "TONE", "TONG", "TONY", "TOOK", "TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR", "TOUT", "TOWN", "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM", "TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", "TUCK", "TUFT", "TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", "TWIG", "TWIN", "TWIT", "ULAN", "UNIT", "URGE", "USED", "USER", "USES", "UTAH", "VAIL", "VAIN", "VALE", "VARY", "VASE", "VAST", "VEAL", "VEDA", "VEIL", "VEIN", "VEND", "VENT", "VERB", "VERY", "VETO", "VICE", "VIEW", "VINE", "VISE", "VOID", "VOLT", "VOTE", "WACK", "WADE", "WAGE", "WAIL", "WAIT", "WAKE", "WALE", "WALK", "WALL", "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM", "WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", "WAYS", "WEAK", "WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", "WELD", "WELL", "WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", "WHAT", "WHEE", "WHEN", "WHET", "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL", "WIND", "WINE", "WING", "WINK", "WINO", "WIRE", "WISE", "WISH", "WITH", "WOLF", "WONT", "WOOD", "WOOL", "WORD", "WORE", "WORK", "WORM", "WORN", "WOVE", "WRIT", "WYNN", "YALE", "YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH", "YEAR", "YELL", "YOGA", "YOKE" }; char *otpbtoe(char *c, char *engout) { char cp[9]; /* add in room for the parity 2 bits */ short p, i; engout[0] = '\0'; memcpy(cp, c, 8); /* compute parity */ for (p = 0, i = 0; i < 64; i += 2) p += otpextract(cp, i, 2); cp[8] = (char)(p << 6); strncat(engout, otpenglish[otpextract(cp, 0, 11)], 4); strcat(engout, " "); strncat(engout, otpenglish[otpextract(cp, 11, 11)], 4); strcat(engout, " "); strncat(engout, otpenglish[otpextract(cp, 22, 11)], 4); strcat(engout, " "); strncat(engout, otpenglish[otpextract(cp, 33, 11)], 4); strcat(engout, " "); strncat(engout, otpenglish[otpextract(cp, 44, 11)], 4); strcat(engout, " "); strncat(engout, otpenglish[otpextract(cp, 55, 11)], 4); return (engout); } unsigned long otpextract(char *s, short start, short length) { unsigned long x; unsigned char cl; unsigned char cc; unsigned char cr; cl = s[start / 8]; cc = s[start / 8 + 1]; cr = s[start / 8 + 2]; x = ((unsigned long) (cl << 8 | cc) << 8 | cr); x = x >> (24 - (length + (start % 8))); x = (x & (0xffff >> (16 - length))); return (x); } \ No newline at end of file +// BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // otp.c // by Rolf Braun // code to support OTP (One-Time Passwords), OPIE (One-time Passwords In Everything), // and Bellcore's original S/Key system. #include "otp.proto.h" #include "md4.proto.h" #include "md5.proto.h" #include "DlogUtils.proto.h" #include "rsinterf.proto.h" #include "tekrgmac.proto.h" #include "vrrgmac.proto.h" #include "errors.proto.h" #include "wind.h" #include "network.proto.h" #include "movableModal.h" #include "parse.proto.h" struct otpmdx_ctx { unsigned long state[4]; unsigned long count[2]; unsigned char buffer[64]; }; extern short scrn; extern WindRec *screens; static char inputPassword[256]; PROTO_UPP(OTPModalFilter, ModalFilter); pascal short OTPModalFilter (DialogPtr dptr, EventRecord *evt, short *item); SIMPLE_UPP(OTPModalFilter, ModalFilter); pascal short OTPModalFilter(DialogPtr dptr, EventRecord *evt, short *item) { short key, tempLen; if ((evt->what == keyDown) || (evt->what == autoKey)) if ((((DialogPeek)dptr)->editField + 1) == 5) { key = evt->message & charCodeMask; if (key == 8) { inputPassword[0] = 0; SetTEText(dptr, 5, "\p"); *item = 0; return -1; } if (key == 9) return 0; if (key < 32) { *item = 0; StdFilterProc(dptr, evt, item); return -1; } tempLen = strlen(inputPassword); if (tempLen < 250) { inputPassword[tempLen] = key; inputPassword[tempLen+1] = 0; } evt->message = (evt->message & 0xFFFFFF00) + ''; return 0; } *item = 0; StdFilterProc(dptr, evt, item); if (*item != 0) return -1; return 0; } void otpgetselection(char *selection) { short i; Handle charh; *selection = 0; // Here we check for a valid text selection. if (TelInfo->numwindows<1) return; // No windows? No problem! if (MacRGfindwind(FrontWindow()) >= 0) return; // ICR is not text. if (RGgetdnum(FrontWindow()) > -1) return; // Tektronix is also not text. if ((i = RSfindvwind(FrontWindow())) < 0) return; // It had better be a text window... if (!RSTextSelected(i)) return; // ...with something selected! charh = RSGetTextSel(i, 0); // Get the text selection if (charh == (char **)-1L) OutOfMemory(400); if (charh != (char **)0L) { if ((GetHandleSize(charh) != 0) && (GetHandleSize(charh) < 250)) { HLock(charh); BlockMove(*charh, selection + 1, GetHandleSize(charh)); selection[0] = GetHandleSize(charh); } DisposeHandle(charh); } } void otpinterface(short mode, char *parsechallenge, struct WindRec *tw, short usehexin, short noprompt, char *passwordin, short savepass) { short ditem, usehex, i; DialogPtr dptr; static Str255 challenge, response, tempstring; usehex = usehexin; if (mode) { strcpy((char *)challenge, parsechallenge); c2pstr((char *)challenge); } else otpgetselection((char *) challenge); if (mode && noprompt) if (passwordin[0]) { pstrcpy(tempstring, (unsigned char *)passwordin); p2cstr(tempstring); p2cstr(challenge); otpgenerator((char *)challenge, (char *)response, (char *)tempstring, usehex); SendStringAsIfTyped(tw, (char *)response, strlen((char *)response)); // If crmap is on, send CR-NULL instead of CR-LF. /* if (tw->crmap) SendStringAsIfTyped(tw,"\015\0",2); else SendStringAsIfTyped(tw,"\015\012",2); //UNIVAC fix return; */ SendCRAsIfTyped(tw); } SetUpMovableModalMenus(); dptr = GetNewDialog(8000, 0, (WindowPtr)-1); SetDialogDefaultItem(dptr, 1); SetDialogCancelItem(dptr, 3); SetDialogTracksCursor(dptr, 1); SetTEText(dptr, 4, challenge); if (mode && usehex) SetCntrl(dptr, 8, 1); else SetCntrl(dptr, 7, 1); ditem = 0; inputPassword[0] = 0; if (gApplicationPrefs->globalSavePass) { strcpy(inputPassword, TelInfo->otpword); for (i = 1; i < 250; i++) tempstring[i] = ''; tempstring[0] = strlen(inputPassword); SetTEText(dptr, 5, tempstring); } if (mode) if (passwordin[0]) { pstrcpy((unsigned char *)inputPassword, (unsigned char *)passwordin); p2cstr((unsigned char *)inputPassword); for (i = 1; i < 250; i++) tempstring[i] = ''; tempstring[0] = strlen(inputPassword); SetTEText(dptr, 5, tempstring); } if (mode || challenge[0]) SelectDialogItemText(dptr, 5, 0, 32767); while ((ditem != 1) && (ditem != 3)) { movableModalDialog(OTPModalFilterUPP, &ditem); switch (ditem) { case 7: SetCntrl(dptr, 7, 1); SetCntrl(dptr, 8, 0); goto generate; case 8: SetCntrl(dptr, 7, 0); SetCntrl(dptr, 8, 1); case 2: generate: GetTEText(dptr, 4, challenge); usehex = GetCntlVal(dptr, 8); p2cstr(challenge); otpgenerator((char *)challenge, (char *)response, inputPassword, usehex); c2pstr((char *)response); SetTEText(dptr, 6, response); } } if (ditem == 1) { GetTEText(dptr, 4, challenge); usehex = GetCntlVal(dptr, 8); p2cstr(challenge); otpgenerator((char *)challenge, (char *)response, inputPassword, usehex); if ((strlen(inputPassword) < 63) && gApplicationPrefs->globalSavePass) strcpy(TelInfo->otpword, inputPassword); if (savepass && (strlen(inputPassword) < 63)) { // RAB BetterTelnet 1.2.1 strcpy(passwordin, inputPassword); c2pstr(passwordin); } } DisposeDialog(dptr); ResetMenus(); if (TelInfo->numwindows<1) return; // No windows? No problem! if (ditem == 1) { if (mode) { SendStringAsIfTyped(tw, (char *)response, strlen((char *)response)); /* // If crmap is on, send CR-NULL instead of CR-LF. if (tw->crmap) SendStringAsIfTyped(tw,"\015\0",2); else SendStringAsIfTyped(tw,"\015\012",2); //UNIVAC fix */ SendCRAsIfTyped(tw); } else { SendStringAsIfTyped(&screens[scrn], (char *)response, strlen((char *)response)); // If crmap is on, send CR-NULL instead of CR-LF. /* if (screens[scrn].crmap) SendStringAsIfTyped(&screens[scrn],"\015\0",2); else SendStringAsIfTyped(&screens[scrn],"\015\012",2); //UNIVAC fix */ SendCRAsIfTyped(&screens[scrn]); } } } void otpgenerator(char *challenge, char *response, char *password, short usehex) { short algorithm; unsigned long sequence; char key[8]; char *cptr; char *seed; static char buffer[256]; *response = 0; cptr = challenge; if (strncmp(challenge, "otp-", 4)) { if (strncmp(challenge, "s/key ", 6)) return; else { cptr += 6; algorithm = 0; } } else { cptr += 4; if (strncmp(cptr, "md4 ", 4)) { if (strncmp(cptr, "md5 ", 4)) { if (strncmp(cptr, "sha1 ", 5)) return; else algorithm = 2; cptr++; } else algorithm = 1; } else algorithm = 0; cptr += 4; } if ((sequence = strtoul(cptr, &cptr, 10)) > 9999) return; while(*cptr && isspace(*cptr)) cptr++; if (!*cptr) return; seed = cptr; while (*cptr && !isspace(*cptr)) cptr++; *cptr = 0; if ((sequence < 1) || (sequence > 9999)) return; if ((strlen(seed) + strlen(password)) > 250) return; strcpy(buffer, seed); strcat(buffer, password); otphashlen(algorithm, buffer, key); while (sequence-- != 0) otphash(algorithm, key); if (usehex) otpbtoh(key, response); else otpbtoe(key, response); } void otphashlen(short algorithm, char *buffer, char *key) { static struct otpmdx_ctx mdx; unsigned long mdx_tmp[4]; unsigned long sha1_tmp[5]; static SHA1_CTX sha1data; unsigned long *results = (unsigned long *) key; if (algorithm == 2) { SHA1Init(&sha1data); SHA1Update(&sha1data, (unsigned char *)buffer, strlen(buffer)); SHA1Final((unsigned char *)sha1_tmp, &sha1data); results[0] = sha1_tmp[0] ^ sha1_tmp[2] ^ sha1_tmp[4]; results[1] = sha1_tmp[1] ^ sha1_tmp[3]; return; } if (algorithm == 1) { otpmd5init(&mdx); otpmd5update(&mdx, (unsigned char *)buffer, strlen(buffer)); otpmd5final((unsigned char *)mdx_tmp, &mdx); } else { otpmd4init(&mdx); otpmd4update(&mdx, (unsigned char *)buffer, strlen(buffer)); otpmd4final((unsigned char *)mdx_tmp, &mdx); } results[0] = mdx_tmp[0] ^ mdx_tmp[2]; results[1] = mdx_tmp[1] ^ mdx_tmp[3]; } void otphash(short algorithm, char *key) { static struct otpmdx_ctx mdx; unsigned long mdx_tmp[4]; unsigned long sha1_tmp[5]; static SHA1_CTX sha1data; unsigned long *results = (unsigned long *) key; if (algorithm == 2) { SHA1Init(&sha1data); SHA1Update(&sha1data, (unsigned char *)key, 8); SHA1Final((unsigned char *)sha1_tmp, &sha1data); results[0] = sha1_tmp[0] ^ sha1_tmp[2] ^ sha1_tmp[4]; results[1] = sha1_tmp[1] ^ sha1_tmp[3]; return; } if (algorithm) { otpmd5init(&mdx); otpmd5update(&mdx, (unsigned char *)key, 8); otpmd5final((unsigned char *)mdx_tmp, &mdx); } else { otpmd4init(&mdx); otpmd4update(&mdx, (unsigned char *)key, 8); otpmd4final((unsigned char *)mdx_tmp, &mdx); } results[0] = mdx_tmp[0] ^ mdx_tmp[2]; results[1] = mdx_tmp[1] ^ mdx_tmp[3]; } static char hextochar[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; char* otpbtoh (char *in, char *out) { short i; char *c = out; for (i = 0; i < 4; i++) { *(c++) = hextochar[((*in) >> 4) & 0x0f]; *(c++) = hextochar[(*in++) & 0x0f]; *(c++) = hextochar[((*in) >> 4) & 0x0f]; *(c++) = hextochar[(*in++) & 0x0f]; *(c++) = ' '; } *(--c) = 0; return out; } static char otpenglish[2048][4] = { "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD", "AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA", "AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK", "ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE", "AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM", "BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET", "BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO", "BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT", "BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT", "CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY", "CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN", "DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG", "DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB", "DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO", "ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE", "EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW", "FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR", "FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP", "GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO", "GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD", "HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM", "HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT", "HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE", "HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL", "INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT", "ITS", "IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET", "JIG", "JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT", "KAY", "KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC", "LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", "LEG", "LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT", "LO", "LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG", "LYE", "MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY", "ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT", "MOB", "MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG", "MUM", "MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED", "NEE", "NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON", "NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF", "OAK", "OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL", "OK", "OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT", "OUR", "OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL", "PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG", "PEN", "PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT", "PLY", "PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB", "PUG", "PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW", "RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM", "RIO", "RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB", "RUE", "RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM", "SAN", "SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW", "SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY", "SLY", "SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY", "SUB", "SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN", "TAP", "TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM", "TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP", "TOW", "TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP", "US", "USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS", "WAY", "WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK", "WON", "WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", "YEA", "YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT", "ACHE", "ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS", "ADEN", "AFAR", "AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE", "AIDS", "AIRY", "AJAR", "AKIN", "ALAN", "ALEC", "ALGA", "ALIA", "ALLY", "ALMA", "ALOE", "ALSO", "ALTO", "ALUM", "ALVA", "AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS", "AMRA", "ANDY", "ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB", "ARCH", "AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS", "ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW", "AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL", "BAIT", "BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM", "BAND", "BANE", "BANG", "BANK", "BARB", "BARD", "BARE", "BARK", "BARN", "BARR", "BASE", "BASH", "BASK", "BASS", "BATE", "BATH", "BAWD", "BAWL", "BEAD", "BEAK", "BEAM", "BEAN", "BEAR", "BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER", "BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT", "BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE", "BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB", "BLAT", "BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE", "BLUM", "BLUR", "BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY", "BOGY", "BOHR", "BOIL", "BOLD", "BOLO", "BOLT", "BOMB", "BONA", "BOND", "BONE", "BONG", "BONN", "BONY", "BOOK", "BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE", "BOSS", "BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN", "BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF", "BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN", "BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE", "CADY", "CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM", "CAME", "CANE", "CANT", "CARD", "CARE", "CARL", "CARR", "CART", "CASE", "CASH", "CASK", "CAST", "CAVE", "CEIL", "CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT", "CHAW", "CHEF", "CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB", "CHUG", "CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY", "CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK", "COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA", "COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", "COON", "COOT", "CORD", "CORE", "CORK", "CORN", "COST", "COVE", "COWL", "CRAB", "CRAG", "CRAM", "CRAY", "CREW", "CRIB", "CROW", "CRUD", "CUBA", "CUBE", "CUFF", "CULL", "CULT", "CUNY", "CURB", "CURD", "CURE", "CURL", "CURT", "CUTS", "DADE", "DALE", "DAME", "DANA", "DANE", "DANG", "DANK", "DARE", "DARK", "DARN", "DART", "DASH", "DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS", "DEAD", "DEAF", "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM", "DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", "DIAL", "DICE", "DIED", "DIET", "DIME", "DINE", "DING", "DINT", "DIRE", "DIRT", "DISC", "DISH", "DISK", "DIVE", "DOCK", "DOES", "DOLE", "DOLL", "DOLT", "DOME", "DONE", "DOOM", "DOOR", "DORA", "DOSE", "DOTE", "DOUG", "DOUR", "DOVE", "DOWN", "DRAB", "DRAG", "DRAM", "DRAW", "DREW", "DRUB", "DRUG", "DRUM", "DUAL", "DUCK", "DUCT", "DUEL", "DUET", "DUKE", "DULL", "DUMB", "DUNE", "DUNK", "DUSK", "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST", "EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", "EDNA", "EGAN", "ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", "EMMA", "ENDS", "ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", "FACE", "FACT", "FADE", "FAIL", "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG", "FARM", "FAST", "FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL", "FEET", "FELL", "FELT", "FEND", "FERN", "FEST", "FEUD", "FIEF", "FIGS", "FILE", "FILL", "FILM", "FIND", "FINE", "FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS", "FIVE", "FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW", "FLIT", "FLOC", "FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", "FOGY", "FOIL", "FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD", "FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL", "FRAU", "FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", "FROM", "FUEL", "FULL", "FUME", "FUND", "FUNK", "FURY", "FUSE", "FUSS", "GAFF", "GAGE", "GAIL", "GAIN", "GAIT", "GALA", "GALE", "GALL", "GALT", "GAME", "GANG", "GARB", "GARY", "GASH", "GATE", "GAUL", "GAUR", "GAVE", "GAWK", "GEAR", "GELD", "GENE", "GENT", "GERM", "GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT", "GINA", "GIRD", "GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB", "GLOB", "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", "GOAT", "GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", "GOOD", "GOOF", "GORE", "GORY", "GOSH", "GOUT", "GOWN", "GRAB", "GRAD", "GRAY", "GREG", "GREW", "GREY", "GRID", "GRIM", "GRIN", "GRIT", "GROW", "GRUB", "GULF", "GULL", "GUNK", "GURU", "GUSH", "GUST", "GWEN", "GWYN", "HAAG", "HAAS", "HACK", "HAIL", "HAIR", "HALE", "HALF", "HALL", "HALO", "HALT", "HAND", "HANG", "HANK", "HANS", "HARD", "HARK", "HARM", "HART", "HASH", "HAST", "HATE", "HATH", "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", "HEAT", "HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", "HELM", "HERB", "HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", "HICK", "HIDE", "HIGH", "HIKE", "HILL", "HILT", "HIND", "HINT", "HIRE", "HISS", "HIVE", "HOBO", "HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT", "HOME", "HONE", "HONK", "HOOD", "HOOF", "HOOK", "HOOT", "HORN", "HOSE", "HOST", "HOUR", "HOVE", "HOWE", "HOWL", "HOYT", "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO", "HULK", "HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE", "HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", "INTO", "IONS", "IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", "ITCH", "ITEM", "IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN", "JEFF", "JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE", "JOAN", "JOBS", "JOCK", "JOEL", "JOEY", "JOHN", "JOIN", "JOKE", "JOLT", "JOVE", "JUDD", "JUDE", "JUDO", "JUDY", "JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO", "JURY", "JUST", "JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", "KATE", "KEEL", "KEEN", "KENO", "KENT", "KERN", "KERR", "KEYS", "KICK", "KILL", "KIND", "KING", "KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", "KNIT", "KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE", "LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE", "LAMB", "LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS", "LAST", "LATE", "LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD", "LEAF", "LEAK", "LEAN", "LEAR", "LEEK", "LEER", "LEFT", "LEND", "LENS", "LENT", "LEON", "LESK", "LESS", "LEST", "LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES", "LIEU", "LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB", "LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE", "LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA", "LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE", "LOSS", "LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE", "LUKE", "LULU", "LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH", "LUST", "LYLE", "LYNN", "LYON", "LYRA", "MACE", "MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE", "MALE", "MALI", "MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE", "MARK", "MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE", "MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET", "MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE", "MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND", "MINE", "MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE", "MITT", "MOAN", "MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL", "MOLT", "MONA", "MONK", "MONT", "MOOD", "MOON", "MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS", "MOST", "MOTH", "MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL", "MURK", "MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL", "NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT", "NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS", "NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH", "NODE", "NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE", "NOTE", "NOUN", "NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY", "OBOE", "ODIN", "OHIO", "OILY", "OINT", "OKAY", "OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN", "OMIT", "ONCE", "ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO", "OTIS", "OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY", "OWNS", "QUAD", "QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE", "RAID", "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", "RATE", "RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", "RECK", "REED", "REEF", "REEK", "REEL", "REID", "REIN", "RENA", "REND", "RENT", "REST", "RICE", "RICH", "RICK", "RIDE", "RIFT", "RILL", "RIME", "RING", "RINK", "RISE", "RISK", "RITE", "ROAD", "ROAM", "ROAR", "ROBE", "ROCK", "RODE", "ROIL", "ROLL", "ROME", "ROOD", "ROOF", "ROOK", "ROOM", "ROOT", "ROSA", "ROSE", "ROSS", "ROSY", "ROTH", "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY", "RUDE", "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", "RUSH", "RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", "SAID", "SAIL", "SALE", "SALK", "SALT", "SAME", "SAND", "SANE", "SANG", "SANK", "SARA", "SAUL", "SAVE", "SAYS", "SCAN", "SCAR", "SCAT", "SCOT", "SEAL", "SEAM", "SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN", "SEES", "SELF", "SELL", "SEND", "SENT", "SETS", "SEWN", "SHAG", "SHAM", "SHAW", "SHAY", "SHED", "SHIM", "SHIN", "SHOD", "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK", "SIDE", "SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", "SINE", "SING", "SINK", "SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", "SKID", "SKIM", "SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", "SLED", "SLEW", "SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG", "SLUM", "SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB", "SNUG", "SOAK", "SOAR", "SOCK", "SODA", "SOFA", "SOFT", "SOIL", "SOLD", "SOME", "SONG", "SOON", "SOOT", "SORE", "SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG", "STAN", "STAR", "STAY", "STEM", "STEW", "STIR", "STOW", "STUB", "STUN", "SUCH", "SUDS", "SUIT", "SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF", "SWAB", "SWAG", "SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", "TACK", "TACT", "TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE", "TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", "TEET", "TELL", "TEND", "TENT", "TERM", "TERN", "TESS", "TEST", "THAN", "THAT", "THEE", "THEM", "THEN", "THEY", "THIN", "THIS", "THUD", "THUG", "TICK", "TIDE", "TIDY", "TIED", "TIER", "TILE", "TILL", "TILT", "TIME", "TINA", "TINE", "TINT", "TINY", "TIRE", "TOAD", "TOGO", "TOIL", "TOLD", "TOLL", "TONE", "TONG", "TONY", "TOOK", "TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR", "TOUT", "TOWN", "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM", "TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", "TUCK", "TUFT", "TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", "TWIG", "TWIN", "TWIT", "ULAN", "UNIT", "URGE", "USED", "USER", "USES", "UTAH", "VAIL", "VAIN", "VALE", "VARY", "VASE", "VAST", "VEAL", "VEDA", "VEIL", "VEIN", "VEND", "VENT", "VERB", "VERY", "VETO", "VICE", "VIEW", "VINE", "VISE", "VOID", "VOLT", "VOTE", "WACK", "WADE", "WAGE", "WAIL", "WAIT", "WAKE", "WALE", "WALK", "WALL", "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM", "WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", "WAYS", "WEAK", "WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", "WELD", "WELL", "WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", "WHAT", "WHEE", "WHEN", "WHET", "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL", "WIND", "WINE", "WING", "WINK", "WINO", "WIRE", "WISE", "WISH", "WITH", "WOLF", "WONT", "WOOD", "WOOL", "WORD", "WORE", "WORK", "WORM", "WORN", "WOVE", "WRIT", "WYNN", "YALE", "YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH", "YEAR", "YELL", "YOGA", "YOKE" }; char *otpbtoe(char *c, char *engout) { char cp[9]; /* add in room for the parity 2 bits */ short p, i; engout[0] = '\0'; memcpy(cp, c, 8); /* compute parity */ for (p = 0, i = 0; i < 64; i += 2) p += otpextract(cp, i, 2); cp[8] = (char)(p << 6); strncat(engout, otpenglish[otpextract(cp, 0, 11)], 4); strcat(engout, " "); strncat(engout, otpenglish[otpextract(cp, 11, 11)], 4); strcat(engout, " "); strncat(engout, otpenglish[otpextract(cp, 22, 11)], 4); strcat(engout, " "); strncat(engout, otpenglish[otpextract(cp, 33, 11)], 4); strcat(engout, " "); strncat(engout, otpenglish[otpextract(cp, 44, 11)], 4); strcat(engout, " "); strncat(engout, otpenglish[otpextract(cp, 55, 11)], 4); return (engout); } unsigned long otpextract(char *s, short start, short length) { unsigned long x; unsigned char cl; unsigned char cc; unsigned char cr; cl = s[start / 8]; cc = s[start / 8 + 1]; cr = s[start / 8 + 2]; x = ((unsigned long) (cl << 8 | cc) << 8 | cr); x = x >> (24 - (length + (start % 8))); x = (x & (0xffff >> (16 - length))); return (x); } \ No newline at end of file diff --git a/source/parse/parse.c b/source/parse/parse.c index 4f5cadf..05f858f 100755 --- a/source/parse/parse.c +++ b/source/parse/parse.c @@ -1 +1 @@ -// parse.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #ifdef MPW #pragma segment Parse #endif #include "parse.h" // For our #defines #include "wind.h" /* For WindRec structure */ /* For putln proto */ #include "network.proto.h" /* For net functions */ #include "linemode.proto.h" #include "vgtek.proto.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "maclook.proto.h" #include "tekrgmac.proto.h" #include "menuseg.proto.h" #include "translate.proto.h" #include "vr.h" #include "vr.proto.h" #include "tnae.h" #include "authencrypt.h" #include "authencrypt.proto.h" #include "wdefpatch.proto.h" #include "otp.proto.h" //#define OPTS_DEBUG #ifdef OPTS_DEBUG #include "optsdebug.h" #define opts_debug_print(x) putln(x) static char munger[255]; #else #define opts_debug_print(x) #endif #include "Profiler.h" extern short scrn; extern WindRec *screens; #include "parse.proto.h" static char *getcname(struct WindRec *tw); static void encryptStatechange(struct WindRec *tw); static void process_suboption(struct WindRec *tw, unsigned char *start, unsigned char *end); static void send_will(short port, short option); static void send_wont(short port, short option); static void telnet_do(struct WindRec *tw, short option); static void telnet_dont(struct WindRec *tw, short option); static void telnet_will(struct WindRec *tw, short option); static void telnet_wont(struct WindRec *tw, short option); void Parseunload(void) {} void SendStringAsIfTyped(struct WindRec *tw, char *string, short len) { // trbuf_nat_mac((unsigned char *)string, len, tw->national); trbuf_mac_nat((unsigned char *)string, len, tw->national); // drh - bug fix netpush(tw->port); if (tw->kblen > 0) { /* need to flush buffer */ netwrite(tw->port, tw->kbbuf, tw->kblen); tw->kblen=0; } netwrite(tw->port, string, len); if (tw->echo) parse(tw, (unsigned char *)string, len); } /*********************************************************************/ /* parse * look at the string which has just come in from outside and * check for special sequences that we are interested in. * * Tries to pass through routine strings immediately, waiting for special * characters ESC and 255 to change modes. */ void parse (struct WindRec *tw, unsigned char *st, short cnt) { short i,temptw; unsigned char *mark,*orig; // ProfilerSetStatus(true); orig = st; /* remember beginning point */ mark = st + cnt; /* set to end of input string */ /* * raw mode for debugging, passes through escape sequences and other * special characters as <27> symbols */ if (tw->termstate == DUMBTYPE) { for (i=0; i < cnt; i++,st++) /* put on screen raw */ if (*st == 27 || *st > 126) { sprintf((char *)tw->parsedat,"<%d>",*st); VSwrite(tw->vs,(char *)tw->parsedat,strlen((char *)tw->parsedat)); /* send to virtual screen */ } else VSwrite(tw->vs,(char *) st,1); /* BYU LSC */ } else { /* * traverse string, looking for any special characters which indicate that * we need to change modes. */ while (st < mark) { switch (tw->telstate) { case GS: case ESCFOUND: if (tw->tektype >= 0) { /* we'll allow the TEK */ if ((*st == 12) || (tw->telstate == GS)) { /* esc-FF */ if ((*st == 12) && ((tw->termstate == VTEKTYPE) || (!tw->tekclear))) { if (tw->termstate == VTEKTYPE) putln("Entering Tek mode"); else if (tw->curgraph > -1) detachGraphics(tw->curgraph); if (tw->curgraph <= -1) { // No current TEK window temptw = VGnewwin(TEK_DEVICE_WINDOW,tw->vs); if (temptw > -1) { Str255 scratchPstring; tw->curgraph = temptw; VGgiveinfo(temptw); GetWTitle(tw->wind, scratchPstring); PtoCstr(scratchPstring); RGattach(temptw,tw->vs,(char *)scratchPstring, tw->tektype); } else tw->telstate = TS_NORM; // Can't create TEK window } if (tw->telstate != TS_NORM) tw->termstate = TEKTYPE; } if (tw->telstate == GS) { st++; VGwrite(tw->curgraph,"\035",1); } else if (tw->telstate != TS_NORM) VGwrite(tw->curgraph,"\037\033\014",3); tw->telstate = TS_NORM; break; } // FF or GS } // tw->tektype >= 0 if (*st == '^') { /* ESC- ^ */ tw->termstate = RASTYPE; tw->telstate = TS_NORM; VRwrite("\033^",2); /* Put it through */ orig = ++st; break; } if (tw->termstate == TEKTYPE) VGwrite(tw->curgraph,"\033",1); else if (tw->termstate == RASTYPE) VRwrite("\033",1); else VSwrite(tw->vs,"\033",1); /* send the missing ESC */ tw->telstate = TS_NORM; break; /*------------------------------------------------------------------------------* * IACFOUND: This is the start of the Telnet option negotiation. If Telnet * * gets an IAC character, then negotiation data follows, and is ready to be * * parsed. * *------------------------------------------------------------------------------*/ case IACFOUND: /* telnet option negotiation- START */ if (*st == TEL_IAC) { /* real data = 255 */ orig = st; // MP: translation mod (break will make it miss // this assignment later on in the case, Jim!) st++; /* real 255 will get sent */ tw->telstate = TS_NORM; break; } else { switch (*st++) { case TEL_EOF: /* BYU LSC */ case TEL_EL: /* thanx Quincey!!! */ case TEL_EC: case TEL_AYT: case TEL_AO: case TEL_IP: case TEL_BREAK: case TEL_DM: case TEL_NOP: case TEL_SE: case TEL_GA: #ifdef OPTS_DEBUG sprintf(munger,"RECV: %s",telstates[tw->telstate]); opts_debug_print(munger); #endif tw->telstate = TS_NORM; orig=st; break; case TEL_DOTEL: tw->telstate = TS_DO; orig = st; break; case TEL_WILLTEL: tw->telstate = TS_WILL; orig = st; break; case TEL_DONTTEL: tw->telstate = TS_DONT; orig = st; break; case TEL_WONTTEL: tw->telstate = TS_WONT; orig = st; break; /*------------------------------------------------------------------------------* * SUBNEGOTIATION -- If there is an SB token found, then Telnet needs to do * * some subnegotiating. The subnegotiation data follows, and needs to be put * * somewhere safe. Make sure and update the state, so that we know that * * Telnet is doing some subnegotiations and not just horsing around * *------------------------------------------------------------------------------*/ case TEL_SB: tw->telstate = TS_SB; /* Guess what I'm doing... */ orig=st; tw->parseIndex = 0; /* No data yet! Clear any possible garbage */ break; default: // Means we got IAC where xx isn't recognized orig = st; tw->telstate = TS_NORM; #ifdef OPTS_DEBUG sprintf(munger,"RECVD: IAC %c",*(st-1)); opts_debug_print(munger); #endif break; } // switch (*st++) } // else from it (*st == TEL_IAC) break; // case IACFOUND case TS_DO: telnet_do(tw, *st++); orig = st; tw->telstate = TS_NORM; break; case TS_DONT: telnet_dont(tw, *st++); orig = st; tw->telstate = TS_NORM; break; case TS_WILL: telnet_will(tw, *st++); orig = st; tw->telstate = TS_NORM; break; case TS_WONT: telnet_wont(tw, *st++); orig = st; tw->telstate = TS_NORM; break; case TS_SB: if (*st == TEL_IAC) { st++; if (*st == TEL_SE) //subnegotiation over { st++; process_suboption(tw, st, mark); orig = st; tw->telstate = TS_NORM; } else { if (*st == TEL_IAC) //doubled IAC tw->parsedat[tw->parseIndex++] = *st++; else { //process this, then go IAC found tw->parsedat[tw->parseIndex++] = TEL_IAC; //why do we add this to tw->parsedat[tw->parseIndex++] = *st; //the parsedat? We don't process_suboption(tw, st, mark); //need it for the options tw->substat = IACFOUND; } } } else // Collect subnegotiation data tw->parsedat[tw->parseIndex++] = *st++; break; default: tw->telstate = TS_NORM; break; } // switch(tw->telstate) /* * quick scan of the remaining string, skip chars while they are * uninteresting */ if (tw->telstate == TS_NORM) { /* * skip along as fast as possible until an interesting character is found */ if (!tw->eightbit) { /* BYU 2.4.10 */ while (st < mark) { /* BYU 2.4.10 */ if (*st == IAC) /* BYU 2.4.10 */ break; /* BYU 2.4.10 */ else { /* BYU 2.4.10 */ *st &= 0x7f; /* BYU 2.4.10 */ if (*st == ESC || *st == GS) /* BYU 2.4.10 */ break; /* BYU 2.4.10 */ st++; /* BYU 2.4.10 */ } } /* BYU 2.4.10 */ } else /* BYU 2.4.10 */ while (st < mark && *st != ESC && *st < 255 && *st != GS) // MP: translation mod st++; /* BYU 2.4.10 */ /* * send the string where it belongs */ if (!tw->timing) { if (tw->termstate == TEKTYPE) { short i; i = VGwrite( tw->curgraph,(char *) orig, st-orig); /* BYU LSC */ if (i < (st - orig)) { detachGraphics(tw->curgraph); st = orig + i; } } else if (tw->termstate == RASTYPE) { short i; i= VRwrite((char *) orig, st-orig); /* BYU LSC */ if (i <(st-orig)) { tw->termstate = VTEKTYPE; st = orig +i; /* Next char to parse */ } } else { if (tw->otpauto) otpauto(tw, (char *) orig, st-orig); VSwrite( tw->vs,(char *) orig,st-orig); /* BYU LSC - send to virtual VT102 */ } } orig = st; /* forget what we have sent already */ if (st < mark) switch (*st) { case TEL_IAC: /* telnet IAC */ tw->telstate = IACFOUND; st++; break; case GS: if (tw->telstate != GS) { tw->telstate = GS; } else tw->telstate = TS_NORM; st++; break; case ESC: /* ESCape code */ if (st == mark-1 || *(st+1) == 12 || *(st+1) == '^' ) { tw->telstate = ESCFOUND; } st++; /* strip or accept ESC char */ break; default: if (*st++ > 127) { if (st==mark) /*new addition */ VSwrite(tw->vs,(char *) orig,1); /* BYU LSC */ } break; } // switch(*st) } // tw->telstate == TS_NORM } // while (st < mark) } // tw->termstate != DUMBTYPE // ProfilerSetStatus(false); } /* parse */ void SendNAWSinfo(WindRec *s, short horiz, short vert) { char blah[20]; unsigned char height, width; height = vert & 0xff; width = horiz & 0xff; /* 931112, ragge, NADA, KTH, ugly patch to not send IAC as window size */ if(height == 0xFF) height = 0xFE; if(width == 0xFF) width = 0xFE; netpush (s->port); /* NCSA: syntax for command is: IAC SB NAWS widthHI widthLO heightHI heightLO IAC SE */ netwrite(s->port,"\377\372\037\000",4); sprintf(blah,"%c\000", width); netwrite(s->port,blah,2); sprintf(blah,"%c\377\360", height); netwrite(s->port,blah,3); opts_debug_print("SENT: IAC SB NAWS IAC SE"); } /* * Implementation specific Kerberos routines */ /* * getcname * Return a pointer to the cannonical host name */ static char *getcname (WindRec *tw) { char *cp; static char *b, buf[100]; cp = 0; if (tw->cannon[0]) cp = tw->cannon; // Doing the following is bad because we disposed of our init params! // else if ((*(*(ConnInitParams **)(tw->myInitParams))->session)->hostname) // cp = (char *)(*(*(ConnInitParams **)(tw->myInitParams))->session)->hostname; /* make a local copy to avoid locking handles */ if (cp) { b = buf; while (*cp) *b++ = *cp++; *b++ = '\0'; return buf; } return cp; } /* * encryptStatechange * Called when the encryption state changes */ #define kOurHit 32 static void encryptStatechange (struct WindRec *tw) { MyWDEFPatch(zoomDocProc, tw->wind, wDraw, kOurHit); } void telnet_send_initial_options(WindRec *tw) { if (tw->authenticate) { send_will(tw->port, OPT_AUTHENTICATION); (tw->myopts)[OPT_AUTHENTICATION-MHOPTS_BASE] = 1; if (tw->encrypt) { send_will(tw->port, OPT_ENCRYPT); /* will encrypt */ (tw->myopts)[OPT_ENCRYPT-MHOPTS_BASE] = 1; } } if ((tw->portNum == 23) || tw->portNegative) { send_do(tw->port, N_ECHO); // Do ECHO tw->echo = 1; send_do(tw->port, N_SGA); // Do SGA tw->Usga=1; send_wont(tw->port, N_XDISPLOC); send_will(tw->port, N_NAWS); } else { tw->echo = 1; tw->Usga = 1; } } static void process_suboption(struct WindRec *tw, unsigned char *start, unsigned char *end) { unsigned long sendlength; unsigned char sendbuffer[1500]; short s; char IACSB[] = { TEL_IAC, TEL_SB, 0, 0}; char IACSE[] = { TEL_IAC, TEL_SE}; switch(tw->parsedat[0]) { /*------------------------------------------------------------------------------* * SUBNegotiate Termtype: send the term type data now * *------------------------------------------------------------------------------*/ case N_TERMTYP: if (tw->parsedat[1]==1) { char s[60], termtmp[40]; BlockMove(tw->answerback, termtmp, 32); PtoCstr((StringPtr)termtmp); #ifdef OPTS_DEBUG sprintf(munger,"RECV: SB TERMINAL-TYPE SEND\r\nSEND: SB TERMINAL-TYPE IS %s\r\n",termtmp); opts_debug_print(munger); #endif IACSB[2] = '\030'; IACSB[3] = 0; netpush(tw->port); netwrite(tw->port,IACSB,4); netpush(tw->port); sprintf(s,"%s%c%c",termtmp, TEL_IAC, TEL_SE); netwrite(tw->port, s, strlen(s)); } break; /*------------------------------------------------------------------------------* * SUBNegotiate ENCRYPTION: * *------------------------------------------------------------------------------*/ case N_ENCRYPT: sendlength = sizeof(sendbuffer); s = encrypt_suboption((tnParams **)&tw->aedata, tw->parsedat, tw->parseIndex, sendbuffer, &sendlength, getcname(tw), tw->hisopts[OPT_ENCRYPT - MHOPTS_BASE], tw->myopts[OPT_ENCRYPT - MHOPTS_BASE]); netportencryptstate(tw->port, (Ptr)tw->aedata); encryptStatechange(tw); /* * If we turned on encryption, we must decrypt the rest of the buffer. */ if (s == TNREP_START_DECRYPT) { unsigned char *cp = start; while (cp < end) { *cp = decrypt((tnParams *)tw->aedata, (long)(*cp)); cp++; } } if (sizeof(sendbuffer) - sendlength) netwrite(tw->port, sendbuffer, sizeof(sendbuffer)-sendlength); /* * transfer the encrypting flag here, after the buffer * with encrypt-start has gone out. */ if (((tnParams *)tw->aedata)->startencrypting) { ((tnParams *)tw->aedata)->startencrypting = false; ((tnParams *)tw->aedata)->encrypting = true; } break; /*------------------------------------------------------------------------------* * SUBNegotiate Authentication: send the authentication data now * *------------------------------------------------------------------------------*/ case N_AUTHENTICATION: sendlength = sizeof(sendbuffer); auth_suboption((tnParams **)&tw->aedata, tw->parsedat, tw->parseIndex, sendbuffer, &sendlength, getcname(tw), tw->hisopts[OPT_ENCRYPT-MHOPTS_BASE], tw->myopts[OPT_ENCRYPT-MHOPTS_BASE]); if (sizeof(sendbuffer) - sendlength) { netwrite(tw->port, sendbuffer, sizeof(sendbuffer)-sendlength); } break; /*------------------------------------------------------------------------------* * SUBNegotiate Linemode: set up local characters, modes, and such * *------------------------------------------------------------------------------*/ case N_LINEMODE: linemode_suboption(tw); break; /*------------------------------------------------------------------------------* * SUBNegotiate REMOTE_FLOW_CONTROL: determine whether we control flow, and * * what restarts flow * *------------------------------------------------------------------------------*/ case N_REMOTEFLOW: switch (tw->parsedat[1]) { case FLOW_OFF: #ifdef OPTS_DEBUG sprintf(munger,"RECV: SB REMOTE_FLOW FLOW_OFF"); opts_debug_print(munger); #endif tw->allow_flow = FALSE; break; case FLOW_ON: #ifdef OPTS_DEBUG sprintf(munger,"RECV: SB REMOTE_FLOW FLOW_ON"); opts_debug_print(munger); #endif tw->allow_flow = TRUE; break; case FLOW_RESTART_ANY: #ifdef OPTS_DEBUG sprintf(munger,"RECV: SB REMOTE_FLOW FLOW_RESTART_ANY"); opts_debug_print(munger); #endif tw->restart_any_flow = TRUE; break; case FLOW_RESTART_XON: #ifdef OPTS_DEBUG sprintf(munger,"RECV: SB REMOTE_FLOW FLOW_RESTART_XON"); opts_debug_print(munger); #endif tw->restart_any_flow = FALSE; break; default: break; } default: //dont know this subnegotiation!! break; } } static void telnet_do(struct WindRec *tw, short option) { #ifdef OPTS_DEBUG sprintf(munger,"RECV: %s %s",telstates[TEL_DOTEL-TEL_SE],teloptions[option]); opts_debug_print(munger); #endif switch(option) { case N_SGA: /* Sure we'll supress GA */ if (!tw->Isga) { tw->Isga=1; send_will(tw->port, N_SGA); } break; case N_TERMTYP: /* And we'll even tell you about ourselves */ if (!tw->Ittype) { tw->Ittype=1; send_will(tw->port, N_TERMTYP); } break; case N_NAWS: /* NCSA: sure, I like changing the window size! */ tw->naws =1; /* NCSA: this session is now NAWS */ send_will(tw->port, N_NAWS); SendNAWSinfo(tw, VSmaxwidth(tw->vs) + 1, VSgetlines(tw->vs)); #ifdef OPTS_DEBUG opts_debug_print("SENT: IAC TEL_SB N_NAWS IAC TEL_SE"); #endif break; /* NCSA */ case N_LINEMODE: /* Sure I'll do line mode... */ if (tw->lineAllow) { send_will(tw->port, N_LINEMODE); doLinemode(tw); } else send_wont(tw->port, N_LINEMODE); break; case N_AUTHENTICATION: /* do auth */ if (!tw->myopts[OPT_AUTHENTICATION-MHOPTS_BASE]) { if (tw->authenticate) { (tw->myopts)[OPT_AUTHENTICATION-MHOPTS_BASE] = 1; send_will(tw->port, N_AUTHENTICATION); } else { send_wont(tw->port, N_AUTHENTICATION); } } break; case N_ENCRYPT: /* do encrypt */ if (!tw->myopts[OPT_ENCRYPT-MHOPTS_BASE]) { if (tw->encrypt) { (tw->myopts)[OPT_ENCRYPT-MHOPTS_BASE] = 1; send_will(tw->port, N_ENCRYPT); } else { send_wont(tw->port, N_ENCRYPT); } } break; case N_REMOTEFLOW: if (!tw->remote_flow) { tw->remote_flow = TRUE; send_will(tw->port, option); } break; default: /* But, we won't do .... */ send_wont(tw->port, option); break; } } static void telnet_dont(struct WindRec *tw, short option) { #ifdef OPTS_DEBUG sprintf(munger,"RECV: %s %s",telstates[TEL_DONTTEL-TEL_SE],teloptions[option]); opts_debug_print(munger); #endif switch (option) { case N_ENCRYPT: /* dont encrypt */ case N_AUTHENTICATION: /* dont authenticate */ tw->myopts[option - MHOPTS_BASE] = 0; send_wont(tw->port, option); break; case N_LINEMODE: /* Ok. turn it off if its on */ if (tw->lmode) { send_wont(tw->port, N_LINEMODE); if (tw->kblen > 0) { netpush(tw->port); netwrite(tw->port, tw->kbbuf, tw->kblen); } tw->lmode = 0; tw->lmodeBits = 0; tw->litNext = 0; } break; } } static void telnet_will(struct WindRec *tw, short option) { #ifdef OPTS_DEBUG sprintf(munger,"RECV: %s %s",telstates[TEL_WILLTEL-TEL_SE],teloptions[option]); opts_debug_print(munger); #endif switch(option) { case N_ECHO: /* Echo on the other end*/ #ifdef OPTS_DEBUG if (!tw->echo) opts_debug_print("tw->echo is False."); #endif if (!tw->echo) break; tw->echo = 0; /* Ok, in that case they can echo... */ changeport(scrn,scrn); send_do(tw->port, N_ECHO); break; case N_SGA: /* Supress GA */ #ifdef OPTS_DEBUG if (tw->Usga) opts_debug_print("tw->Usga is True."); #endif if (tw->Usga) break; tw->Usga = 1; /* Go Ahead and supress GA */ send_do(tw->port, N_SGA); break; case N_TIMING: /* Timing Mark */ tw->timing = 0; break; case N_AUTHENTICATION: /* will auth */ if (!tw->hisopts[OPT_AUTHENTICATION-MHOPTS_BASE]) { if (tw->authenticate) { (tw->hisopts)[OPT_AUTHENTICATION-MHOPTS_BASE] = 1; send_do(tw->port, N_AUTHENTICATION); } else { send_dont(tw->port, N_AUTHENTICATION); } } break; case N_ENCRYPT: /* will encrypt */ if (!tw->hisopts[OPT_ENCRYPT-MHOPTS_BASE]) { if (tw->encrypt) { (tw->hisopts)[OPT_ENCRYPT-MHOPTS_BASE] = 1; send_do(tw->port, N_ENCRYPT); } else { send_dont(tw->port, N_ENCRYPT); } } break; case N_REMOTEFLOW: /* they want to toggle flow control */ if (!tw->remote_flow) { tw->remote_flow = 1; #ifdef OPTS_DEBUG opts_debug_print("tw->remote_flow is True."); #endif send_do(tw->port, N_REMOTEFLOW); } default: send_dont(tw->port, option); } } static void telnet_wont(struct WindRec *tw, short option) { #ifdef OPTS_DEBUG sprintf(munger,"RECV: %s %s",telstates[TEL_WONTTEL-TEL_SE],teloptions[option]); opts_debug_print(munger); #endif switch(option) { /* which option? */ case N_ECHO: /* echo */ if (tw->echo) break; tw->echo = 1; /* Ok, I will echo if I have to... */ changeport(scrn,scrn); send_dont(tw->port,N_ECHO); break; case N_SGA: if (!tw->Usga) break; tw->Usga = 0; send_dont(tw->port,N_SGA); break; case N_TIMING: /* Timing Mark */ tw->timing = 0; break; case N_ENCRYPT: /* wont encrypt */ case N_AUTHENTICATION: /* wont authenticate */ tw->hisopts[option-MHOPTS_BASE] = 0; send_dont(tw->port, option); break; default: break; } } void send_do(short port, short option) { char data[] = { IAC, TEL_DOTEL, 0}; data[2] = option; netpush(port); netwrite(port, data, 3); #ifdef OPTS_DEBUG sprintf(munger,"SENT: DO %s",teloptions[option]); opts_debug_print(munger); #endif } void send_dont(short port, short option) { char data[] = { IAC, TEL_DONTTEL, 0}; data[2] = option; netpush(port); netwrite(port, data, 3); #ifdef OPTS_DEBUG sprintf(munger,"SENT: DONT %s",teloptions[option]); opts_debug_print(munger); #endif } static void send_will(short port, short option) { char data[] = { IAC, TEL_WILLTEL, 0}; data[2] = option; netpush(port); netwrite(port, data, 3); #ifdef OPTS_DEBUG sprintf(munger,"SENT: WILL %s",teloptions[option]); opts_debug_print(munger); #endif } static void send_wont(short port, short option) { char data[] = { IAC, TEL_WONTTEL, 0}; data[2] = option; netpush(port); netwrite(port, data, 3); #ifdef OPTS_DEBUG sprintf(munger,"SENT: WONT %s",teloptions[option]); opts_debug_print(munger); #endif } void otpauto(struct WindRec *tw, char *string, short len) { short i; short templen; char *tempstring; templen = len; tempstring = string; while (templen) { switch (tw->otpautostate) { case 0: // waiting for otp prompt for (i = 0; i < 8; i++) tw->otpautobuffer[i] = tw->otpautobuffer[i + 1]; tw->otpautobuffer[8] = *tempstring; if (!strncmp(tw->otpautobuffer, "otp-sha1 ", 9)) { tw->otpautostate = 1; strncpy(tw->otpautostring, "otp-sha1 ", 9); tw->otpautolength = 9; } else if (!strncmp(tw->otpautobuffer + 1, "otp-md5 ", 8)) { tw->otpautostate = 1; strncpy(tw->otpautostring, "otp-md5 ", 8); tw->otpautolength = 8; } else if (!strncmp(tw->otpautobuffer + 1, "otp-md4 ", 8)) { tw->otpautostate = 1; strncpy(tw->otpautostring, "otp-md4 ", 8); tw->otpautolength = 8; } else if (!strncmp(tw->otpautobuffer + 3, "s/key ", 6)) { tw->otpautostate = 1; strncpy(tw->otpautostring, "s/key ", 6); tw->otpautolength = 6; } break; case 1: // checking for sequence number if ((*tempstring >= '0') && (*tempstring <= '9')) { tw->otpautostate = 2; tw->otpautostring[tw->otpautolength] = *tempstring; tw->otpautolength++; } else tw->otpautostate = 0; break; case 2: // moving through sequence number if (tw->otpautolength > 250) { tw->otpautostate = 0; break; } if ((*tempstring >= '0') && (*tempstring <= '9')) { tw->otpautostring[tw->otpautolength] = *tempstring; tw->otpautolength++; break; } if (*tempstring == ' '){ tw->otpautostate = 3; tw->otpautostring[tw->otpautolength] = ' '; tw->otpautolength++; break; } tw->otpautostate = 0; break; case 3: // moving through string if (tw->otpautolength > 250) { tw->otpautostate = 0; break; } if ((*tempstring <= ' ') || (*tempstring == ']')) { tw->otpautostring[tw->otpautolength] = 0; tw->otpautostate = 0; tw->otpauto = tw->otpmulti; otpinterface(1, tw->otpautostring, tw, tw->otphex, tw->otpnoprompt, tw->otppassword, tw->otpsavepass); } else { tw->otpautostring[tw->otpautolength] = *tempstring; tw->otpautolength++; } break; } templen--; tempstring++; } } \ No newline at end of file +// parse.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "parse.h" // For our #defines #include "wind.h" /* For WindRec structure */ /* For putln proto */ #include "ae.proto.h" #include "network.proto.h" /* For net functions */ #include "linemode.proto.h" #include "vgtek.proto.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "maclook.proto.h" #include "tekrgmac.proto.h" #include "menuseg.proto.h" #include "translate.proto.h" #include "vr.h" #include "vr.proto.h" #include "tnae.h" #include "authencrypt.h" #include "authencrypt.proto.h" #include "wdefpatch.proto.h" #include "otp.proto.h" #include "sshglue.proto.h" //#define OPTS_DEBUG #ifdef OPTS_DEBUG #include "optsdebug.h" #define opts_debug_print(x) putln(x) static char munger[255]; #else #define opts_debug_print(x) #endif #include "Profiler.h" extern short scrn; extern WindRec *screens; #include "parse.proto.h" static char *getcname(struct WindRec *tw); static void encryptStatechange(struct WindRec *tw); static void process_suboption(struct WindRec *tw, unsigned char *start, unsigned char *end); static void send_will(short port, short option); static void send_wont(short port, short option); static void telnet_do(struct WindRec *tw, short option); static void telnet_dont(struct WindRec *tw, short option); static void telnet_will(struct WindRec *tw, short option); static void telnet_wont(struct WindRec *tw, short option); void Parseunload(void) {} void SendStringAsIfTyped(struct WindRec *tw, char *string, short len) { // trbuf_nat_mac((unsigned char *)string, len, tw->national); trbuf_mac_nat((unsigned char *)string, len, tw->national); // drh - bug fix netpush(tw->port); if (tw->kblen > 0) { /* need to flush buffer */ netwrite(tw->port, tw->kbbuf, tw->kblen); tw->kblen=0; } netwrite(tw->port, string, len); if (tw->echo) parse(tw, (unsigned char *)string, len); } // RAB BetterTelnet 2.0b3 // I added this routine because I was sick of special-casing the CR code // all over the place. void SendCRAsIfTyped(struct WindRec *tw) { if (tw->echo) parse(tw,(unsigned char *) "\012\015",2); /* BYU LSC */ if ((tw->protocol >= 1) && (tw->protocol <= 4)) { // for rlogin/rsh, ssh netwrite(tw->port,"\015",1); return; } if (tw->crmap) netwrite(tw->port,"\015\0",2); else netwrite(tw->port,"\015\012",2); //UNIVAC fix } // RAB BetterTelnet 2.0b2 - rlogin_parse() // parses urgent data for rlogin commands void rlogin_parse (struct WindRec *tw, unsigned char *st, short cnt) { short i; unsigned char *ptr; ptr = st; i = 0; while (i < cnt) { sprintf(munger, "rlogin: RECV urgent data <%d>", *ptr); opts_debug_print(munger); i++; ptr++; } } /*********************************************************************/ /* parse * look at the string which has just come in from outside and * check for special sequences that we are interested in. * * Tries to pass through routine strings immediately, waiting for special * characters ESC and 255 to change modes. */ void parse (struct WindRec *tw, unsigned char *st, short cnt) { short i,temptw; unsigned char *mark,*orig; // ProfilerSetStatus(true); orig = st; /* remember beginning point */ mark = st + cnt; /* set to end of input string */ /* * raw mode for debugging, passes through escape sequences and other * special characters as <27> symbols */ if (tw->termstate == DUMBTYPE) { for (i=0; i < cnt; i++,st++) /* put on screen raw */ if (*st == 27 || *st > 126) { sprintf((char *)tw->parsedat,"<%d>",*st); VSwrite(tw->vs,(char *)tw->parsedat,strlen((char *)tw->parsedat)); /* send to virtual screen */ } else VSwrite(tw->vs,(char *) st,1); /* BYU LSC */ } else { /* * traverse string, looking for any special characters which indicate that * we need to change modes. */ while (st < mark) { switch (tw->telstate) { case GS: case ESCFOUND: if (tw->tektype >= 0) { /* we'll allow the TEK */ if ((*st == 12) || (tw->telstate == GS)) { /* esc-FF */ if ((*st == 12) && ((tw->termstate == VTEKTYPE) || (!tw->tekclear))) { if (tw->termstate == VTEKTYPE) putln("Entering Tek mode"); else if (tw->curgraph > -1) detachGraphics(tw->curgraph); if (tw->curgraph <= -1) { // No current TEK window temptw = VGnewwin(TEK_DEVICE_WINDOW,tw->vs); if (temptw > -1) { Str255 scratchPstring; tw->curgraph = temptw; VGgiveinfo(temptw); GetWTitle(tw->wind, scratchPstring); PtoCstr(scratchPstring); RGattach(temptw,tw->vs,(char *)scratchPstring, tw->tektype); } else tw->telstate = TS_NORM; // Can't create TEK window } if (tw->telstate != TS_NORM) tw->termstate = TEKTYPE; } if (tw->telstate == GS) { st++; VGwrite(tw->curgraph,"\035",1); } else if (tw->telstate != TS_NORM) VGwrite(tw->curgraph,"\037\033\014",3); tw->telstate = TS_NORM; break; } // FF or GS } // tw->tektype >= 0 if (*st == '^') { /* ESC- ^ */ tw->termstate = RASTYPE; tw->telstate = TS_NORM; VRwrite("\033^",2); /* Put it through */ orig = ++st; break; } if (tw->termstate == TEKTYPE) VGwrite(tw->curgraph,"\033",1); else if (tw->termstate == RASTYPE) VRwrite("\033",1); else VSwrite(tw->vs,"\033",1); /* send the missing ESC */ tw->telstate = TS_NORM; break; /*------------------------------------------------------------------------------* * IACFOUND: This is the start of the Telnet option negotiation. If Telnet * * gets an IAC character, then negotiation data follows, and is ready to be * * parsed. * *------------------------------------------------------------------------------*/ case IACFOUND: /* telnet option negotiation- START */ if (*st == TEL_IAC) { /* real data = 255 */ orig = st; // MP: translation mod (break will make it miss // this assignment later on in the case, Jim!) st++; /* real 255 will get sent */ tw->telstate = TS_NORM; break; } else { switch (*st++) { case TEL_EOF: /* BYU LSC */ case TEL_EL: /* thanx Quincey!!! */ case TEL_EC: case TEL_AYT: case TEL_AO: case TEL_IP: case TEL_BREAK: case TEL_DM: case TEL_NOP: case TEL_SE: case TEL_GA: #ifdef OPTS_DEBUG sprintf(munger,"RECV: %s",telstates[tw->telstate]); opts_debug_print(munger); #endif tw->telstate = TS_NORM; orig=st; break; case TEL_DOTEL: tw->telstate = TS_DO; orig = st; break; case TEL_WILLTEL: tw->telstate = TS_WILL; orig = st; break; case TEL_DONTTEL: tw->telstate = TS_DONT; orig = st; break; case TEL_WONTTEL: tw->telstate = TS_WONT; orig = st; break; /*------------------------------------------------------------------------------* * SUBNEGOTIATION -- If there is an SB token found, then Telnet needs to do * * some subnegotiating. The subnegotiation data follows, and needs to be put * * somewhere safe. Make sure and update the state, so that we know that * * Telnet is doing some subnegotiations and not just horsing around * *------------------------------------------------------------------------------*/ case TEL_SB: tw->telstate = TS_SB; /* Guess what I'm doing... */ orig=st; tw->parseIndex = 0; /* No data yet! Clear any possible garbage */ break; default: // Means we got IAC where xx isn't recognized orig = st; tw->telstate = TS_NORM; #ifdef OPTS_DEBUG sprintf(munger,"RECVD: IAC %c",*(st-1)); opts_debug_print(munger); #endif break; } // switch (*st++) } // else from it (*st == TEL_IAC) break; // case IACFOUND case TS_DO: telnet_do(tw, *st++); orig = st; tw->telstate = TS_NORM; break; case TS_DONT: telnet_dont(tw, *st++); orig = st; tw->telstate = TS_NORM; break; case TS_WILL: telnet_will(tw, *st++); orig = st; tw->telstate = TS_NORM; break; case TS_WONT: telnet_wont(tw, *st++); orig = st; tw->telstate = TS_NORM; break; case TS_SB: if (*st == TEL_IAC) { st++; if (*st == TEL_SE) //subnegotiation over { st++; process_suboption(tw, st, mark); orig = st; tw->telstate = TS_NORM; } else { if (*st == TEL_IAC) //doubled IAC tw->parsedat[tw->parseIndex++] = *st++; else { //process this, then go IAC found tw->parsedat[tw->parseIndex++] = TEL_IAC; //why do we add this to tw->parsedat[tw->parseIndex++] = *st; //the parsedat? We don't process_suboption(tw, st, mark); //need it for the options tw->substat = IACFOUND; } } } else // Collect subnegotiation data tw->parsedat[tw->parseIndex++] = *st++; break; default: tw->telstate = TS_NORM; break; } // switch(tw->telstate) /* * quick scan of the remaining string, skip chars while they are * uninteresting */ if (tw->telstate == TS_NORM) { /* * skip along as fast as possible until an interesting character is found */ if (!tw->eightbit) { /* BYU 2.4.10 */ while (st < mark) { /* BYU 2.4.10 */ if ((*st == IAC) && (tw->protocol == 0)) // RAB BetterTelnet 2.0b2 break; /* BYU 2.4.10 */ else { /* BYU 2.4.10 */ *st &= 0x7f; /* BYU 2.4.10 */ if (*st == ESC || *st == GS) /* BYU 2.4.10 */ break; /* BYU 2.4.10 */ st++; /* BYU 2.4.10 */ } } /* BYU 2.4.10 */ } else /* BYU 2.4.10 */ while (st < mark && *st != ESC && ((*st < 255) || (tw->protocol != 0)) && *st != GS) // MP: translation mod // RAB BetterTelnet 2.0b2 st++; /* BYU 2.4.10 */ /* * send the string where it belongs */ if (!tw->timing) { if (tw->termstate == TEKTYPE) { short i; i = VGwrite( tw->curgraph,(char *) orig, st-orig); /* BYU LSC */ if (i < (st - orig)) { detachGraphics(tw->curgraph); st = orig + i; } } else if (tw->termstate == RASTYPE) { short i; i= VRwrite((char *) orig, st-orig); /* BYU LSC */ if (i <(st-orig)) { tw->termstate = VTEKTYPE; st = orig +i; /* Next char to parse */ } } else { if (tw->otpauto) otpauto(tw, (char *) orig, st-orig); if (tw->waWaiting) handlewait(tw, (char *) orig, st-orig); VSwritefast( tw->vs,(char *) orig,st-orig); /* BYU LSC - send to virtual VT102 */ } } orig = st; /* forget what we have sent already */ if (st < mark) switch (*st) { case TEL_IAC: /* telnet IAC */ if (tw->protocol == 0) tw->telstate = IACFOUND; // RAB BetterTelnet 2.0b2 st++; break; case GS: if (tw->telstate != GS) { tw->telstate = GS; } else tw->telstate = TS_NORM; st++; break; case ESC: /* ESCape code */ if (st == mark-1 || *(st+1) == 12 || *(st+1) == '^' ) { tw->telstate = ESCFOUND; } st++; /* strip or accept ESC char */ break; default: if (*st++ > 127) { if (st==mark) /*new addition */ VSwrite(tw->vs,(char *) orig,1); /* BYU LSC */ } break; } // switch(*st) } // tw->telstate == TS_NORM } // while (st < mark) if (!tw->jsNoFlush) VSflushwrite(tw->vs); } // tw->termstate != DUMBTYPE // ProfilerSetStatus(false); } /* parse */ void SendNAWSinfo(WindRec *s, short horiz, short vert) { char blah[20]; unsigned char height, width; if (s->protocol != 0) return; height = vert & 0xff; width = horiz & 0xff; /* 931112, ragge, NADA, KTH, ugly patch to not send IAC as window size */ if(height == 0xFF) height = 0xFE; if(width == 0xFF) width = 0xFE; netpush (s->port); /* NCSA: syntax for command is: IAC SB NAWS widthHI widthLO heightHI heightLO IAC SE */ netwrite(s->port,"\377\372\037\000",4); sprintf(blah,"%c\000", width); netwrite(s->port,blah,2); sprintf(blah,"%c\377\360", height); netwrite(s->port,blah,3); opts_debug_print("SENT: IAC SB NAWS IAC SE"); } /* * Implementation specific Kerberos routines */ /* * getcname * Return a pointer to the cannonical host name */ static char *getcname (WindRec *tw) { char *cp; static char *b, buf[100]; cp = 0; if (tw->cannon[0]) cp = tw->cannon; // Doing the following is bad because we disposed of our init params! // else if ((*(*(ConnInitParams **)(tw->myInitParams))->session)->hostname) // cp = (char *)(*(*(ConnInitParams **)(tw->myInitParams))->session)->hostname; /* make a local copy to avoid locking handles */ if (cp) { b = buf; while (*cp) *b++ = *cp++; *b++ = '\0'; return buf; } return cp; } /* * encryptStatechange * Called when the encryption state changes */ #define kOurHit 32 static void encryptStatechange (struct WindRec *tw) { MyWDEFPatch(zoomDocProc, tw->wind, wDraw, kOurHit); } void telnet_send_initial_options(WindRec *tw) { // RAB BetterTelnet 2.0b2 - revised to support multiple protocols if ((tw->protocol >= 1) && (tw->protocol <= 3)) { // initial rlogin stuff netwrite(tw->port, "\000", 1); if ((tw->protocol == 3) || (!tw->clientuser[0])) // rexec sends username, rlogin/rsh need client username // but we use server username if we don't have a client // username... netwrite(tw->port, &tw->username[1], tw->username[0]); else netwrite(tw->port, &tw->clientuser[1], tw->clientuser[0]); netwrite(tw->port, "\000", 1); if (tw->protocol == 3) // rexec sends password, rlogin/rsh send server username netwrite(tw->port, &tw->password[1], tw->password[0]); else netwrite (tw->port, &tw->username[1], tw->username[0]); netwrite(tw->port, "\000", 1); if (tw->protocol == 1) { // rlogin sends terminal type & speed, rsh/rexec send command netwrite(tw->port, &tw->answerback[1], tw->answerback[0]); netwrite(tw->port, "/9600\000", 6); } else { netwrite(tw->port, &tw->command[1], tw->command[0]); netwrite(tw->port, "\000", 1); } tw->echo = 0; // NO local echo for rlogin! tw->Usga = 1; return; } if (tw->protocol == 4) { // initial ssh stuff ssh_glue_initial(tw); tw->echo = 0; // NO local echo for ssh either! tw->Usga = 1; return; } if (tw->protocol != 0) { tw->echo = 1; tw->Usga = 1; return; } if (tw->authenticate) { send_will(tw->port, OPT_AUTHENTICATION); (tw->myopts)[OPT_AUTHENTICATION-MHOPTS_BASE] = 1; if (tw->encrypt) { send_will(tw->port, OPT_ENCRYPT); /* will encrypt */ (tw->myopts)[OPT_ENCRYPT-MHOPTS_BASE] = 1; } } if ((tw->portNum == 23) || tw->portNegative) { send_do(tw->port, N_ECHO); // Do ECHO tw->echo = 1; send_do(tw->port, N_SGA); // Do SGA tw->Usga=1; send_wont(tw->port, N_XDISPLOC); send_will(tw->port, N_NAWS); } else { tw->echo = 1; tw->Usga = 1; } } static void process_suboption(struct WindRec *tw, unsigned char *start, unsigned char *end) { unsigned long sendlength; unsigned char sendbuffer[1500]; short s; char IACSB[] = { TEL_IAC, TEL_SB, 0, 0}; char IACSE[] = { TEL_IAC, TEL_SE}; switch(tw->parsedat[0]) { /*------------------------------------------------------------------------------* * SUBNegotiate Termtype: send the term type data now * *------------------------------------------------------------------------------*/ case N_TERMTYP: if (tw->parsedat[1]==1) { char s[60], termtmp[40]; BlockMove(tw->answerback, termtmp, 32); PtoCstr((StringPtr)termtmp); #ifdef OPTS_DEBUG sprintf(munger,"RECV: SB TERMINAL-TYPE SEND\r\nSEND: SB TERMINAL-TYPE IS %s\r\n",termtmp); opts_debug_print(munger); #endif IACSB[2] = '\030'; IACSB[3] = 0; netpush(tw->port); netwrite(tw->port,IACSB,4); netpush(tw->port); sprintf(s,"%s%c%c",termtmp, TEL_IAC, TEL_SE); netwrite(tw->port, s, strlen(s)); } break; /*------------------------------------------------------------------------------* * SUBNegotiate ENCRYPTION: * *------------------------------------------------------------------------------*/ case N_ENCRYPT: sendlength = sizeof(sendbuffer); s = encrypt_suboption((tnParams **)&tw->aedata, tw->parsedat, tw->parseIndex, sendbuffer, &sendlength, getcname(tw), tw->hisopts[OPT_ENCRYPT - MHOPTS_BASE], tw->myopts[OPT_ENCRYPT - MHOPTS_BASE]); netportencryptstate(tw->port, (Ptr)tw->aedata); /* * If we turned on encryption, we must decrypt the rest of the buffer. */ if (s == TNREP_START_DECRYPT) { unsigned char *cp = start; while (cp < end) { *cp = decrypt((tnParams *)tw->aedata, (long)(*cp)); cp++; } } if (sizeof(sendbuffer) - sendlength) netwrite(tw->port, sendbuffer, sizeof(sendbuffer)-sendlength); /* * transfer the encrypting flag here, after the buffer * with encrypt-start has gone out. */ if (((tnParams *)tw->aedata)->startencrypting) { ((tnParams *)tw->aedata)->startencrypting = false; ((tnParams *)tw->aedata)->encrypting = true; } encryptStatechange(tw); break; /*------------------------------------------------------------------------------* * SUBNegotiate Authentication: send the authentication data now * *------------------------------------------------------------------------------*/ case N_AUTHENTICATION: sendlength = sizeof(sendbuffer); auth_suboption((tnParams **)&tw->aedata, tw->parsedat, tw->parseIndex, sendbuffer, &sendlength, getcname(tw), tw->hisopts[OPT_ENCRYPT-MHOPTS_BASE], tw->myopts[OPT_ENCRYPT-MHOPTS_BASE], tw->port); if (sizeof(sendbuffer) - sendlength) { netwrite(tw->port, sendbuffer, sizeof(sendbuffer)-sendlength); } break; /*------------------------------------------------------------------------------* * SUBNegotiate Linemode: set up local characters, modes, and such * *------------------------------------------------------------------------------*/ case N_LINEMODE: linemode_suboption(tw); break; /*------------------------------------------------------------------------------* * SUBNegotiate REMOTE_FLOW_CONTROL: determine whether we control flow, and * * what restarts flow * *------------------------------------------------------------------------------*/ case N_REMOTEFLOW: switch (tw->parsedat[1]) { case FLOW_OFF: #ifdef OPTS_DEBUG sprintf(munger,"RECV: SB REMOTE_FLOW FLOW_OFF"); opts_debug_print(munger); #endif tw->allow_flow = FALSE; break; case FLOW_ON: #ifdef OPTS_DEBUG sprintf(munger,"RECV: SB REMOTE_FLOW FLOW_ON"); opts_debug_print(munger); #endif tw->allow_flow = TRUE; break; case FLOW_RESTART_ANY: #ifdef OPTS_DEBUG sprintf(munger,"RECV: SB REMOTE_FLOW FLOW_RESTART_ANY"); opts_debug_print(munger); #endif tw->restart_any_flow = TRUE; break; case FLOW_RESTART_XON: #ifdef OPTS_DEBUG sprintf(munger,"RECV: SB REMOTE_FLOW FLOW_RESTART_XON"); opts_debug_print(munger); #endif tw->restart_any_flow = FALSE; break; default: break; } default: //dont know this subnegotiation!! break; } } static void telnet_do(struct WindRec *tw, short option) { #ifdef OPTS_DEBUG sprintf(munger,"RECV: %s %s",telstates[TEL_DOTEL-TEL_SE],teloptions[option]); opts_debug_print(munger); #endif switch(option) { case N_SGA: /* Sure we'll supress GA */ if (!tw->Isga) { tw->Isga=1; send_will(tw->port, N_SGA); } break; case N_TERMTYP: /* And we'll even tell you about ourselves */ if (!tw->Ittype) { tw->Ittype=1; send_will(tw->port, N_TERMTYP); } break; case N_NAWS: /* NCSA: sure, I like changing the window size! */ tw->naws =1; /* NCSA: this session is now NAWS */ send_will(tw->port, N_NAWS); SendNAWSinfo(tw, VSmaxwidth(tw->vs) + 1, VSgetlines(tw->vs)); #ifdef OPTS_DEBUG opts_debug_print("SENT: IAC TEL_SB N_NAWS IAC TEL_SE"); #endif break; /* NCSA */ case N_LINEMODE: /* Sure I'll do line mode... */ if (tw->lineAllow) { send_will(tw->port, N_LINEMODE); doLinemode(tw); } else send_wont(tw->port, N_LINEMODE); break; case N_AUTHENTICATION: /* do auth */ if (!tw->myopts[OPT_AUTHENTICATION-MHOPTS_BASE]) { if (tw->authenticate) { (tw->myopts)[OPT_AUTHENTICATION-MHOPTS_BASE] = 1; send_will(tw->port, N_AUTHENTICATION); } else { send_wont(tw->port, N_AUTHENTICATION); } } break; case N_ENCRYPT: /* do encrypt */ if (!tw->myopts[OPT_ENCRYPT-MHOPTS_BASE]) { if (tw->encrypt) { (tw->myopts)[OPT_ENCRYPT-MHOPTS_BASE] = 1; send_will(tw->port, N_ENCRYPT); } else { send_wont(tw->port, N_ENCRYPT); } } break; case N_REMOTEFLOW: if (!tw->remote_flow) { tw->remote_flow = TRUE; send_will(tw->port, option); } break; default: /* But, we won't do .... */ send_wont(tw->port, option); break; } } static void telnet_dont(struct WindRec *tw, short option) { #ifdef OPTS_DEBUG sprintf(munger,"RECV: %s %s",telstates[TEL_DONTTEL-TEL_SE],teloptions[option]); opts_debug_print(munger); #endif switch (option) { case N_ENCRYPT: /* dont encrypt */ case N_AUTHENTICATION: /* dont authenticate */ tw->myopts[option - MHOPTS_BASE] = 0; send_wont(tw->port, option); break; case N_LINEMODE: /* Ok. turn it off if its on */ if (tw->lmode) { send_wont(tw->port, N_LINEMODE); if (tw->kblen > 0) { netpush(tw->port); netwrite(tw->port, tw->kbbuf, tw->kblen); } tw->lmode = 0; tw->lmodeBits = 0; tw->litNext = 0; } break; } } static void telnet_will(struct WindRec *tw, short option) { #ifdef OPTS_DEBUG sprintf(munger,"RECV: %s %s",telstates[TEL_WILLTEL-TEL_SE],teloptions[option]); opts_debug_print(munger); #endif switch(option) { case N_ECHO: /* Echo on the other end*/ #ifdef OPTS_DEBUG if (!tw->echo) opts_debug_print("tw->echo is False."); #endif if (!tw->echo) break; tw->echo = 0; /* Ok, in that case they can echo... */ changeport(scrn,scrn); send_do(tw->port, N_ECHO); break; case N_SGA: /* Supress GA */ #ifdef OPTS_DEBUG if (tw->Usga) opts_debug_print("tw->Usga is True."); #endif if (tw->Usga) break; tw->Usga = 1; /* Go Ahead and supress GA */ send_do(tw->port, N_SGA); break; case N_TIMING: /* Timing Mark */ tw->timing = 0; break; case N_AUTHENTICATION: /* will auth */ if (!tw->hisopts[OPT_AUTHENTICATION-MHOPTS_BASE]) { if (tw->authenticate) { (tw->hisopts)[OPT_AUTHENTICATION-MHOPTS_BASE] = 1; send_do(tw->port, N_AUTHENTICATION); } else { send_dont(tw->port, N_AUTHENTICATION); } } break; case N_ENCRYPT: /* will encrypt */ if (!tw->hisopts[OPT_ENCRYPT-MHOPTS_BASE]) { if (tw->encrypt) { (tw->hisopts)[OPT_ENCRYPT-MHOPTS_BASE] = 1; send_do(tw->port, N_ENCRYPT); } else { send_dont(tw->port, N_ENCRYPT); } } break; case N_REMOTEFLOW: /* they want to toggle flow control */ if (!tw->remote_flow) { tw->remote_flow = 1; #ifdef OPTS_DEBUG opts_debug_print("tw->remote_flow is True."); #endif send_do(tw->port, N_REMOTEFLOW); } default: send_dont(tw->port, option); } } static void telnet_wont(struct WindRec *tw, short option) { #ifdef OPTS_DEBUG sprintf(munger,"RECV: %s %s",telstates[TEL_WONTTEL-TEL_SE],teloptions[option]); opts_debug_print(munger); #endif switch(option) { /* which option? */ case N_ECHO: /* echo */ if (tw->echo) break; tw->echo = 1; /* Ok, I will echo if I have to... */ changeport(scrn,scrn); send_dont(tw->port,N_ECHO); break; case N_SGA: if (!tw->Usga) break; tw->Usga = 0; send_dont(tw->port,N_SGA); break; case N_TIMING: /* Timing Mark */ tw->timing = 0; break; case N_ENCRYPT: /* wont encrypt */ case N_AUTHENTICATION: /* wont authenticate */ tw->hisopts[option-MHOPTS_BASE] = 0; send_dont(tw->port, option); break; default: break; } } void send_do(short port, short option) { char data[] = { IAC, TEL_DOTEL, 0}; data[2] = option; netpush(port); netwrite(port, data, 3); #ifdef OPTS_DEBUG sprintf(munger,"SENT: DO %s",teloptions[option]); opts_debug_print(munger); #endif } void send_dont(short port, short option) { char data[] = { IAC, TEL_DONTTEL, 0}; data[2] = option; netpush(port); netwrite(port, data, 3); #ifdef OPTS_DEBUG sprintf(munger,"SENT: DONT %s",teloptions[option]); opts_debug_print(munger); #endif } static void send_will(short port, short option) { char data[] = { IAC, TEL_WILLTEL, 0}; data[2] = option; netpush(port); netwrite(port, data, 3); #ifdef OPTS_DEBUG sprintf(munger,"SENT: WILL %s",teloptions[option]); opts_debug_print(munger); #endif } static void send_wont(short port, short option) { char data[] = { IAC, TEL_WONTTEL, 0}; data[2] = option; netpush(port); netwrite(port, data, 3); #ifdef OPTS_DEBUG sprintf(munger,"SENT: WONT %s",teloptions[option]); opts_debug_print(munger); #endif } void otpauto(struct WindRec *tw, char *string, short len) { short i; short templen; char *tempstring; templen = len; tempstring = string; while (templen) { switch (tw->otpautostate) { case 0: // waiting for otp prompt for (i = 0; i < 8; i++) tw->otpautobuffer[i] = tw->otpautobuffer[i + 1]; tw->otpautobuffer[8] = *tempstring; if (!strncmp(tw->otpautobuffer, "otp-sha1 ", 9)) { tw->otpautostate = 1; strncpy(tw->otpautostring, "otp-sha1 ", 9); tw->otpautolength = 9; } else if (!strncmp(tw->otpautobuffer + 1, "otp-md5 ", 8)) { tw->otpautostate = 1; strncpy(tw->otpautostring, "otp-md5 ", 8); tw->otpautolength = 8; } else if (!strncmp(tw->otpautobuffer + 1, "otp-md4 ", 8)) { tw->otpautostate = 1; strncpy(tw->otpautostring, "otp-md4 ", 8); tw->otpautolength = 8; } else if (!strncmp(tw->otpautobuffer + 3, "s/key ", 6)) { tw->otpautostate = 1; strncpy(tw->otpautostring, "s/key ", 6); tw->otpautolength = 6; } break; case 1: // checking for sequence number if ((*tempstring >= '0') && (*tempstring <= '9')) { tw->otpautostate = 2; tw->otpautostring[tw->otpautolength] = *tempstring; tw->otpautolength++; } else tw->otpautostate = 0; break; case 2: // moving through sequence number if (tw->otpautolength > 250) { tw->otpautostate = 0; break; } if ((*tempstring >= '0') && (*tempstring <= '9')) { tw->otpautostring[tw->otpautolength] = *tempstring; tw->otpautolength++; break; } if (*tempstring == ' '){ tw->otpautostate = 3; tw->otpautostring[tw->otpautolength] = ' '; tw->otpautolength++; break; } tw->otpautostate = 0; break; case 3: // moving through string if (tw->otpautolength > 250) { tw->otpautostate = 0; break; } if ((*tempstring <= ' ') || (*tempstring == ']')) { tw->otpautostring[tw->otpautolength] = 0; tw->otpautostate = 0; tw->otpauto = tw->otpmulti; otpinterface(1, tw->otpautostring, tw, tw->otphex, tw->otpnoprompt, tw->otppassword, tw->otpsavepass); } else { tw->otpautostring[tw->otpautolength] = *tempstring; tw->otpautolength++; } break; } templen--; tempstring++; } } // RAB BetterTelnet 2.0b1 - added handlewait() for scripting // RAB BetterTelnet 2.0b2 - implemented Knuth-Morris-Platt plaintext search algorithm void handlewait(struct WindRec *tw, char *string, short len) { short templen; char *tempstring; templen = len; tempstring = string; while (templen) { while ((tw->waWaitPos > 0) && (tw->waWaitString[tw->waWaitPos] != *tempstring)) tw->waWaitPos = tw->waPrefixFunction[tw->waWaitPos - 1]; // Knuth-Morris-Platt if (*tempstring == tw->waWaitString[tw->waWaitPos]) { tw->waWaitPos++; if (tw->waWaitPos >= tw->waWaitLength) { tw->waWaiting = 0; tw->enabled = tw->waWasEnabled; changeport(scrn, scrn); if (tw->waWeHaveAppleEvent) { tw->waWeHaveAppleEvent = 0; AEResumeTheCurrentEvent(&tw->waAppleEvent, &tw->waAEReply, MyHandleWaitUPP, 1); } } } else tw->waWaitPos = 0; templen--; tempstring++; } } \ No newline at end of file diff --git a/source/parse/parse.h b/source/parse/parse.h index 78b0818..f4c39dc 100755 --- a/source/parse/parse.h +++ b/source/parse/parse.h @@ -1 +1 @@ - /* These are the different Telnet option negotiation tags */ #define TEL_EOF 236 /* BYU LSC */ #define TEL_SUSP 237 #define TEL_ABORT 238 //CCP for linemode rfc #define TEL_SE 240 /* end sub-negitiation */ // 360 #define TEL_NOP 241 /* No Operation */ #define TEL_DM 242 /* data mark */ #define TEL_BREAK 243 #define TEL_IP 244 /* the ole' Interrupt Process */ #define TEL_AO 245 /* Abort Output */ #define TEL_AYT 246 /* Are You There???? */ #define TEL_EC 247 /* Erase Char */ #define TEL_EL 248 /* Erase Line */ #define TEL_GA 249 /* Telnet Go-Ahead */ #define TEL_SB 250 /* start a Subnegotion */ // 372 #define TEL_WILLTEL 251 /* Negotiate: Will do this option */ // 373 #define TEL_WONTTEL 252 /* Negotiate: Wont do this option */ // 374 #define TEL_DOTEL 253 /* Negotiate: Do this option */ // 375 #define TEL_DONTTEL 254 /* Negotiate: Dont do this option */ // 376 #define TEL_IAC 255 /* these are the rest of the defines needed for the option negitiations */ #define TS_NORM 0 /* parsing data normal */ #define TS_SB 1 /* Subnegotiation data follows */ #define TS_SE 2 #define TS_WILL 3 #define TS_WONT 4 #define TS_DO 7 #define TS_DONT 8 #define ESCFOUND 5 /* we have found an ESC sequence */ #define IACFOUND 6 /* negotiation data follows */ #define SEXECUTE 200 #define IAC 255 /* signals negotiation data is coming */ #define GS 29 /* we can drop into TEK from here */ /* these are some of the various options that we can negotiate about */ #define N_BINARY 0 /* binary data transfer */ #define N_ECHO 1 /* for local echo stuff */ #define N_SGA 3 /* Go ahead */ #define N_STATUS 5 #define N_TIMING 6 /* timing mark */ #define N_TERMTYP 24 /* set the terminal type */ #define N_NAWS 31 /* Negotiate About Window Size */ #define N_TERMSPEED 32 /* how fast can we go? */ #define N_REMOTEFLOW 33 /* do Remote Flow Control */ //flow control suboptions #define FLOW_OFF 0 // dont allow flow control #define FLOW_ON 1 // allow flow control #define FLOW_RESTART_ANY 2 // restart flow on any character #define FLOW_RESTART_XON 3 // restart flow only on XON #define N_LINEMODE 34 /* Ah yes, the infamous Line Mode option */ #define L_MODE 1 #define L_FORWARDMASK 2 #define L_SLC 3 #define N_XDISPLOC 35 #define N_AUTHENTICATION 37 /* Authentication */ #define N_ENCRYPT 38 /* Encryption */ /* Values for LINEMODE MODE */ #define L_EDIT 1 #define L_TRAPSIG 2 #define L_MODE_ACK 4 #define L_SOFT_TAB 8 #define L_LIT_ECHO 16 #define L_MODE_MASK 31 /* these are the local keys, defined right before our very eyes!! */ /* used for line-mode negotiations */ #define SLC_NOSUPPORT 0 #define SLC_CANTCHANGE 1 #define SLC_VALUE 2 #define SLC_DEFAULT 3 #define SLC_LEVELBITS 3 #define SLC_FLUSHOUT 32 #define SLC_FLUSHIN 64 #define SLC_AWK 128 #define SLC_MAX 30 #define SLC_SYNCH 1 #define SLC_BRK 2 #define SLC_IP 3 #define SLC_AO 4 #define SLC_AYT 5 #define SLC_EOR 6 #define SLC_ABORT 7 #define SLC_EOF 8 #define SLC_SUSP 9 #define SLC_EC 10 #define SLC_EL 11 #define SLC_EW 12 #define SLC_RP 13 #define SLC_LNEXT 14 #define SLC_XON 15 #define SLC_XOFF 16 #define SLC_FORW1 17 #define SLC_FORW2 18 #define DEFAULT_SLC_AO 21 #define DEFAULT_SLC_IP 3 #define DEFAULT_SLC_EC 127 #define DEFAULT_SLC_EL 21 #define DEFAULT_SLC_EOF 4 #define DEFAULT_SLC_ABORT 3 #define DEFAULT_SLC_SUSP 26 #define DEFAULT_SLC_EW 23 #define DEFAULT_SLC_RP 18 #define DEFAULT_SLC_LNEXT 22 #define DEFAULT_SLC_XON 17 #define DEFAULT_SLC_XOFF 19 #define DEFAULT_SLC_FORW1 22 #define DEFAULT_SLC_FORW2 254 #define substate tw->substat \ No newline at end of file +#define OPTS_DEBUG /* These are the different Telnet option negotiation tags */ #define TEL_EOF 236 /* BYU LSC */ #define TEL_SUSP 237 #define TEL_ABORT 238 //CCP for linemode rfc #define TEL_SE 240 /* end sub-negitiation */ // 360 #define TEL_NOP 241 /* No Operation */ #define TEL_DM 242 /* data mark */ #define TEL_BREAK 243 #define TEL_IP 244 /* the ole' Interrupt Process */ #define TEL_AO 245 /* Abort Output */ #define TEL_AYT 246 /* Are You There???? */ #define TEL_EC 247 /* Erase Char */ #define TEL_EL 248 /* Erase Line */ #define TEL_GA 249 /* Telnet Go-Ahead */ #define TEL_SB 250 /* start a Subnegotion */ // 372 #define TEL_WILLTEL 251 /* Negotiate: Will do this option */ // 373 #define TEL_WONTTEL 252 /* Negotiate: Wont do this option */ // 374 #define TEL_DOTEL 253 /* Negotiate: Do this option */ // 375 #define TEL_DONTTEL 254 /* Negotiate: Dont do this option */ // 376 #define TEL_IAC 255 /* these are the rest of the defines needed for the option negitiations */ #define TS_NORM 0 /* parsing data normal */ #define TS_SB 1 /* Subnegotiation data follows */ #define TS_SE 2 #define TS_WILL 3 #define TS_WONT 4 #define TS_DO 7 #define TS_DONT 8 #define ESCFOUND 5 /* we have found an ESC sequence */ #define IACFOUND 6 /* negotiation data follows */ #define SEXECUTE 200 #define IAC 255 /* signals negotiation data is coming */ #define GS 29 /* we can drop into TEK from here */ /* these are some of the various options that we can negotiate about */ #define N_BINARY 0 /* binary data transfer */ #define N_ECHO 1 /* for local echo stuff */ #define N_SGA 3 /* Go ahead */ #define N_STATUS 5 #define N_TIMING 6 /* timing mark */ #define N_TERMTYP 24 /* set the terminal type */ #define N_NAWS 31 /* Negotiate About Window Size */ #define N_TERMSPEED 32 /* how fast can we go? */ #define N_REMOTEFLOW 33 /* do Remote Flow Control */ //flow control suboptions #define FLOW_OFF 0 // dont allow flow control #define FLOW_ON 1 // allow flow control #define FLOW_RESTART_ANY 2 // restart flow on any character #define FLOW_RESTART_XON 3 // restart flow only on XON #define N_LINEMODE 34 /* Ah yes, the infamous Line Mode option */ #define L_MODE 1 #define L_FORWARDMASK 2 #define L_SLC 3 #define N_XDISPLOC 35 #define N_AUTHENTICATION 37 /* Authentication */ #define N_ENCRYPT 38 /* Encryption */ /* Values for LINEMODE MODE */ #define L_EDIT 1 #define L_TRAPSIG 2 #define L_MODE_ACK 4 #define L_SOFT_TAB 8 #define L_LIT_ECHO 16 #define L_MODE_MASK 31 /* these are the local keys, defined right before our very eyes!! */ /* used for line-mode negotiations */ #define SLC_NOSUPPORT 0 #define SLC_CANTCHANGE 1 #define SLC_VALUE 2 #define SLC_DEFAULT 3 #define SLC_LEVELBITS 3 #define SLC_FLUSHOUT 32 #define SLC_FLUSHIN 64 #define SLC_AWK 128 #define SLC_MAX 30 #define SLC_SYNCH 1 #define SLC_BRK 2 #define SLC_IP 3 #define SLC_AO 4 #define SLC_AYT 5 #define SLC_EOR 6 #define SLC_ABORT 7 #define SLC_EOF 8 #define SLC_SUSP 9 #define SLC_EC 10 #define SLC_EL 11 #define SLC_EW 12 #define SLC_RP 13 #define SLC_LNEXT 14 #define SLC_XON 15 #define SLC_XOFF 16 #define SLC_FORW1 17 #define SLC_FORW2 18 #define DEFAULT_SLC_AO 21 #define DEFAULT_SLC_IP 3 #define DEFAULT_SLC_EC 127 #define DEFAULT_SLC_EL 21 #define DEFAULT_SLC_EOF 4 #define DEFAULT_SLC_ABORT 28 #define DEFAULT_SLC_SUSP 26 #define DEFAULT_SLC_EW 23 #define DEFAULT_SLC_RP 18 #define DEFAULT_SLC_LNEXT 22 #define DEFAULT_SLC_XON 17 #define DEFAULT_SLC_XOFF 19 #define DEFAULT_SLC_FORW1 22 #define DEFAULT_SLC_FORW2 254 #define DEFAULT_SLC_BRK 255 #define substate tw->substat \ No newline at end of file diff --git a/source/parse/parse.proto.h b/source/parse/parse.proto.h index cb5c4e3..0f4fb14 100755 --- a/source/parse/parse.proto.h +++ b/source/parse/parse.proto.h @@ -1 +1 @@ - /* parse.c */ void SendStringAsIfTyped(struct WindRec *tw, char *string, short len); void Parseunload(void); void parse(struct WindRec *tw, unsigned char *st, short cnt); void SendNAWSinfo(WindRec *s, short horiz, short vert); void telnet_send_initial_options(WindRec *tw); void send_do(short port, short option); void send_dont(short port, short option); void otpauto(struct WindRec *, char *, short); \ No newline at end of file + /* parse.c */ void SendStringAsIfTyped(struct WindRec *tw, char *string, short len); void SendCRAsIfTyped(struct WindRec *tw); void Parseunload(void); void parse(struct WindRec *tw, unsigned char *st, short cnt); void rlogin_parse(struct WindRec *, unsigned char *, short); void SendNAWSinfo(WindRec *s, short horiz, short vert); void telnet_send_initial_options(WindRec *tw); void send_do(short port, short option); void send_dont(short port, short option); void otpauto(struct WindRec *, char *, short); void handlewait(struct WindRec *, char *, short); \ No newline at end of file diff --git a/source/parse/tnae.h b/source/parse/tnae.h index fca93a8..883af15 100755 --- a/source/parse/tnae.h +++ b/source/parse/tnae.h @@ -1 +1 @@ -#define authType 'TNae' /* auth/encrypt module resource type */ #define moduleType 'TNae' /* auth/encrypt module file type */ #define NTMPAIRS 10 /* max type/modifier pairs */ #define IAC 255 #define SB 250 #define SE 240 #define BOGUS 0x50015001 /* * Kerberos, encryption */ #define OPT_AUTHENTICATION 37 #define OPT_ENCRYPT 38 #define KRB_REJECT 1 /* Rejected (reason might follow) */ #define KRB_AUTH 0 /* Authentication data follows */ #define KRB_ACCEPT 2 /* Accepted */ #define KRB_CHALLENGE 3 /* Challenge for mutual auth */ #define KRB_RESPONSE 4 /* Response for mutual auth */ #define TNQ_IS 0 /* Option is ... */ #define TNQ_SEND 1 /* send option */ #define TNQ_REPLY 2 /* suboption reply */ #define TNQ_NAME 3 /* suboption name */ /* * AUTHENTICATION option types */ #define AUTH_NULL 0 /* no authentication */ #define AUTH_KERBEROS_V4 1 /* Kerberos version 4 */ #define AUTH_KERBEROS_V5 2 /* Kerberos version 5 */ /* * AUTHENTICATION option modifiers */ #define AUTH_WHO_MASK 1 #define AUTH_CLIENT_TO_SERVER 0 #define AUTH_SERVER_TO_CLIENT 1 #define AUTH_HOW_MASK 2 #define AUTH_HOW_ONE_WAY 0 #define AUTH_HOW_MUTUAL 2 /* * suboption buffer offsets */ #define SB_OPTION 0 /* option byte */ #define SB_SUBOPTION 1 /* is, send, reply, name */ #define SB_TYPE 2 /* authentication type */ #define SB_MODIFIER 3 /* type modifier */ #define SB_DATATYPE 4 /* type of data */ #define SB_DATA 5 /* offset to first data byte */ /* * ENCRYPTION suboptions */ #define ENCRYPT_IS 0 /* I pick encryption type ... */ #define ENCRYPT_SUPPORT 1 /* I support encryption types ... */ #define ENCRYPT_REPLY 2 /* Initial setup response */ #define ENCRYPT_START 3 /* Am starting to send encrypted */ #define ENCRYPT_END 4 /* Am ending encrypted */ #define ENCRYPT_REQSTART 5 /* Request you start encrypting */ #define ENCRYPT_REQEND 6 /* Request you send encrypting */ #define ENCRYPT_ENC_KEYID 7 #define ENCRYPT_DEC_KEYID 8 #define ENCRYPT_CNT 9 #define ENCTYPE_ANY 0 #define ENCTYPE_DES_CFB64 1 #define ENCTYPE_DES_OFB64 2 #define ENCTYPE_CNT 3 /* * authentication or encryption module entry point */ typedef long (*module)(long func, void *parameters); /* * TNAE functions. */ enum { TNFUNC_INIT_SESSION_AUTH = 1, /* init auth session data */ TNFUNC_INIT_SESSION_ENCRYPT, /* init encrypt session data */ TNFUNC_QUERY_ENCRYPT, /* query encryption capability */ TNFUNC_INIT_CODE, /* init code module */ TNFUNC_AUTH_SEND, /* process auth send sub-option */ TNFUNC_AUTH_REPLY, /* process auth reply sub-option */ TNFUNC_ENCRYPT_SB, /* process encryption sub-options */ TNFUNC_DECRYPT, /* decrypt data */ TNFUNC_ENCRYPT /* encrypt data */ }; /* * TN code module return codes */ enum { TNREP_OK = 0, /* no error */ TNREP_START_DECRYPT, /* start decrypting (not an error) */ TNREP_AUTH_OK, /* authentication ok */ TNREP_AUTH_ERR, /* authentication rejected */ TNREP_ERROR, /* generic error */ TNREP_NOMEM /* no memory */ }; /* * Parameters */ typedef struct tnParams_ { void *authdata; /* auth data */ void *encryptdata; /* encrypt data */ /* parameters for auth/encrypt_suboption */ unsigned char *subbuffer; /* sub options buffer */ unsigned long sublength; unsigned char *sendbuffer; /* buffer to return option data */ unsigned long *sendlength; /* length of return buffer */ Boolean hisencrypt; /* his encrypt option state */ Boolean myencrypt; /* my encrypt option state */ char *cname; /* pointer to cannonical hostname */ /* used by authencrypt.c */ module entry; /* auth/encrypt code module entry point */ /* data and flags for client */ Boolean encrypting; /* we are encrypting */ Boolean startencrypting; /* time to start encrypting */ Boolean decrypting; /* we are decrypting */ long data; /* for encrypt/decrypt */ unsigned char *ebuf; /* encrypt buf */ } tnParams; \ No newline at end of file +static OSType authTypes[] = { 'tnAE', 'TNae', 0 }; #define moduleType 'TNae' /* auth/encrypt module file type */ #define NTMPAIRS 10 /* max type/modifier pairs */ #define IAC 255 #define SB 250 #define SE 240 #define BOGUS 0x50015001 /* * Kerberos, encryption */ #define OPT_AUTHENTICATION 37 #define OPT_ENCRYPT 38 #define KRB_REJECT 1 /* Rejected (reason might follow) */ #define KRB_AUTH 0 /* Authentication data follows */ #define KRB_ACCEPT 2 /* Accepted */ #define KRB_CHALLENGE 3 /* Challenge for mutual auth */ #define KRB_RESPONSE 4 /* Response for mutual auth */ #define TNQ_IS 0 /* Option is ... */ #define TNQ_SEND 1 /* send option */ #define TNQ_REPLY 2 /* suboption reply */ #define TNQ_NAME 3 /* suboption name */ /* * AUTHENTICATION option types */ #define AUTH_NULL 0 /* no authentication */ #define AUTH_KERBEROS_V4 1 /* Kerberos version 4 */ #define AUTH_KERBEROS_V5 2 /* Kerberos version 5 */ /* * AUTHENTICATION option modifiers */ #define AUTH_WHO_MASK 1 #define AUTH_CLIENT_TO_SERVER 0 #define AUTH_SERVER_TO_CLIENT 1 #define AUTH_HOW_MASK 2 #define AUTH_HOW_ONE_WAY 0 #define AUTH_HOW_MUTUAL 2 /* * suboption buffer offsets */ #define SB_OPTION 0 /* option byte */ #define SB_SUBOPTION 1 /* is, send, reply, name */ #define SB_TYPE 2 /* authentication type */ #define SB_MODIFIER 3 /* type modifier */ #define SB_DATATYPE 4 /* type of data */ #define SB_DATA 5 /* offset to first data byte */ /* * ENCRYPTION suboptions */ #define ENCRYPT_IS 0 /* I pick encryption type ... */ #define ENCRYPT_SUPPORT 1 /* I support encryption types ... */ #define ENCRYPT_REPLY 2 /* Initial setup response */ #define ENCRYPT_START 3 /* Am starting to send encrypted */ #define ENCRYPT_END 4 /* Am ending encrypted */ #define ENCRYPT_REQSTART 5 /* Request you start encrypting */ #define ENCRYPT_REQEND 6 /* Request you send encrypting */ #define ENCRYPT_ENC_KEYID 7 #define ENCRYPT_DEC_KEYID 8 #define ENCRYPT_CNT 9 #define ENCTYPE_ANY 0 #define ENCTYPE_DES_CFB64 1 #define ENCTYPE_DES_OFB64 2 #define ENCTYPE_CNT 3 /* * authentication or encryption module entry point */ typedef long (*module)(long func, void *parameters); /* * TNAE functions. */ enum { TNFUNC_INIT_SESSION_AUTH = 1, /* init auth session data */ TNFUNC_INIT_SESSION_ENCRYPT, /* init encrypt session data */ TNFUNC_QUERY_ENCRYPT, /* query encryption capability */ TNFUNC_INIT_CODE, /* init code module */ TNFUNC_AUTH_SEND, /* process auth send sub-option */ TNFUNC_AUTH_REPLY, /* process auth reply sub-option */ TNFUNC_ENCRYPT_SB, /* process encryption sub-options */ TNFUNC_DECRYPT, /* decrypt data */ TNFUNC_ENCRYPT, /* encrypt data */ TNFUNC_END_SESSION /* cleanup session data */ }; /* * TN code module return codes */ enum { TNREP_OK = 0, /* no error */ TNREP_START_DECRYPT, /* start decrypting (not an error) */ TNREP_AUTH_OK, /* authentication ok */ TNREP_AUTH_ERR, /* authentication rejected */ TNREP_ERROR, /* generic error */ TNREP_NOMEM /* no memory */ }; /* * Parameters */ typedef struct tnParams_ { void *authdata; /* auth data */ void *encryptdata; /* encrypt data */ /* parameters for auth/encrypt_suboption */ unsigned char *subbuffer; /* sub options buffer */ unsigned long sublength; unsigned char *sendbuffer; /* buffer to return option data */ unsigned long *sendlength; /* length of return buffer */ Boolean hisencrypt; /* his encrypt option state */ Boolean myencrypt; /* my encrypt option state */ char *cname; /* pointer to cannonical hostname */ /* used by authencrypt.c */ module entry; /* auth/encrypt code module entry point */ /* data and flags for client */ Boolean encrypting; /* we are encrypting */ Boolean startencrypting; /* time to start encrypting */ Boolean decrypting; /* we are decrypting */ long data; /* for encrypt/decrypt */ unsigned char *ebuf; /* encrypt buf */ unsigned char ipaddr[4]; /* for authentication forwarding in kerberos5 */ unsigned short port; /* for authentication forwarding in kerberos5 */ } tnParams; \ No newline at end of file diff --git a/source/parse/translate.c b/source/parse/translate.c index 92fc4b5..a744f4e 100755 --- a/source/parse/translate.c +++ b/source/parse/translate.c @@ -1 +1 @@ -/* * translate.c * written by Roland Mnsson, Lund University Computing Center, Sweden * roland_m@ldc.lu.se * July 1992 * * Modified by Pascal Maes * UCL/ELEC * Place du Levant, 3 * B-1348 Louvain-la-Neuve * Modified 7/93 by Jim Browne for NCSA. */ // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #ifdef MPW #pragma segment 4 #endif #include "wind.h" #include "vsdata.h" #include "translate.proto.h" #include "vsinterf.proto.h" #include "LinkedList.proto.h" //#define DEBUG_TRANSLATION /*************** external variables ***************/ extern WindRec *screens; /* The screen array from maclook.c */ extern short scrn; /* The current screen from maclook.c */ /*************** global variables ***************/ BytePtr DefaultTable, FTPinTable, FTPoutTable; Handle transTablesHdl; short nNational; #if 0 Boolean get_trsl (short id, Byte **table) { Handle h; long size; h = GetResource (TRSL,id); if ((h==NULL) || (ResError()!=noErr)) { DoError(106 | RESOURCE_ERRORCLASS, LEVEL2, NULL); return (FALSE); } size = GetHandleSize(h); if (size != 256) { DoError(107 | RESOURCE_ERRORCLASS, LEVEL2, NULL); return (FALSE); } HLockHi(h); *table = (Byte *) *h; return (TRUE); } #endif short transBuffer(short oldtable, short newtable) /* translate entire buffer */ { VSscrn *vsscreen; VSline *vslin,*p; short lineNo,maxLineNo; short width; /* allocated witdth of window (80/132) */ char tmp[80]; /* only for debugging */ vsscreen = VSwhereis (screens[scrn].vs); vslin = vsscreen->buftop; #ifdef DEBUG_TRANSLATION putln ("in transBuffer, well and alive"); sprintf (tmp,"VSgetlines(screens[scrn].vs):%d", VSgetlines(screens[scrn].vs)); putln (tmp); sprintf (tmp,"VSmaxwidth(screens[scrn].vs):%d", VSmaxwidth(screens[scrn].vs)); putln (tmp); sprintf (tmp,"vsscreen->lines:%d\n",vsscreen->lines); putln (tmp); sprintf (tmp,"vsscreen->maxlines:%d\n",vsscreen->maxlines); putln (tmp); sprintf (tmp,"vsscreen->numlines:%d\n",vsscreen->numlines); putln (tmp); sprintf (tmp,"vsscreen->allwidth:%d\n",vsscreen->allwidth); putln (tmp); sprintf (tmp,"vsscreen->maxwidth:%d\n",vsscreen->maxwidth); putln (tmp); sprintf (tmp,"vsscreen:%08x\n",vsscreen); putln (tmp); sprintf (tmp,"vslin:%08x\n",vslin); putln (tmp); sprintf (tmp,"next:%08x\n",vslin->next); putln (tmp); sprintf (tmp,"prev:%08x\n",vslin->prev); putln (tmp); sprintf (tmp,"text:%08x\n\n",vslin->text); putln (tmp); #endif width = VSmaxwidth(screens[scrn].vs)+1; /* VSmaxwidth returns 79 or 131 */ p = vslin; maxLineNo = vsscreen->numlines+VSgetlines(screens[scrn].vs); /* VSgetlines returns 24 or whatever */ for (lineNo=1; lineNo<=maxLineNo; lineNo++) { /*sprintf(tmp,"lineNo:%d, p:%08x, starts with:%c%c%c%c",lineNo,p,*(p->text),*(p->text+1),*(p->text+2),*(p->text+3)); putln(tmp);*/ if (p==NULL) { putln ("p is NULL"); return (-1); } if (p->text==NULL) { putln ("p->text is NULL"); return (-1); } // First convert the line back to Mac US format, and then to the new format. trbuf_nat_mac((unsigned char *)p->text,width, oldtable); trbuf_mac_nat((unsigned char *)p->text,width, newtable); p = p->next; } sprintf (tmp, "transBuffer:did convert %d lines", lineNo-1); putln (tmp); return (0); } BytePtr GetTranslationResource(short id) { Handle h; h = GetResource(MY_TRSL, id); if ((h == NULL) || (ResError() != noErr)) { // Do nasty mean error here. BUGG } DetachResource(h); HLockHi(h); return((BytePtr) *h); } // table #'s 1...n correspond to tables in our master array, table #0 is the default table BytePtr ReturnTablePtr(short table, Boolean out) { if (table > nNational || table < 1) return(DefaultTable + ((out == TRUE) * 256)); return((BytePtr)(*transTablesHdl + ((table - 1) * 512) + ((out == TRUE) * 256))); } // The Default table (i.e. no translation) and the two FTP tables are stored in the // Application's resource fork as resources of type TRSL. The // tables added and removed by the user are stored in the prefs file as resources of // type taBL. This routine loads the default table and the two FTP tables into memory. // Failures can only be caused by an incorrect application resource fork. void Setup_Default_Tables(void) { DefaultTable = GetTranslationResource(TRSL_DEFAULT_TABLE); FTPinTable = GetTranslationResource(TRSL_FTP_TABLE); FTPoutTable = FTPinTable + 256; } /* * Be very careful with calling putln from this procedure, since * putln uses the translation tables. If the tables are not setup * garbage output will appear. This is not harmful, but very * annoying. */ void trInit (MenuHandle whichMenu) { short i, numTables; Handle h; LinkedListNode *theHead; nNational = 0; Setup_Default_Tables(); transTablesHdl = myNewHandle(0); UseResFile(TelInfo->ApplicationFile); numTables = CountResources(USER_TRSL); if (numTables) { Str255 NoneString; theHead = createSortedList2(USER_TRSL,numTables,NULL); //now we have a sorted linked list of the names GetIndString(NoneString,MISC_STRINGS,NONE_STRING); AppendMenu(whichMenu,NoneString); addListToMenu/*3*/(whichMenu, theHead, 2); deleteList(&theHead); for (i = 2; i <= numTables + 1; i++) //start adding things from the second menu item (first is none) { Str255 menuItemName; GetItem(whichMenu, i,menuItemName); h = GetNamedResource(USER_TRSL,menuItemName); if (ResError() == noErr && (GetHandleSize(h) == 512)) { nNational++; // Append the table's data to the master array of table data HUnlock(transTablesHdl); mySetHandleSize(transTablesHdl, (nNational * 512));//we're at init time; we have the mem HLockHi(transTablesHdl); HLock(h); BlockMove(*h, (*transTablesHdl) + ((nNational - 1) * 512), 512); } // Release the resource ReleaseResource(h); } } UseResFile(TelInfo->SettingsFile); } /* Converts a char from 8-bit National to 8-bit Macintosh */ void trbuf_nat_mac(unsigned char *buf, short len, short table) { short i; unsigned char *p; BytePtr table_data; table_data = ReturnTablePtr(table, FALSE); for (i=0,p=buf; ibuftop; #ifdef DEBUG_TRANSLATION putln ("in transBuffer, well and alive"); sprintf (tmp,"VSgetlines(screens[scrn].vs):%d", VSgetlines(screens[scrn].vs)); putln (tmp); sprintf (tmp,"VSmaxwidth(screens[scrn].vs):%d", VSmaxwidth(screens[scrn].vs)); putln (tmp); sprintf (tmp,"vsscreen->lines:%d\n",vsscreen->lines); putln (tmp); sprintf (tmp,"vsscreen->maxlines:%d\n",vsscreen->maxlines); putln (tmp); sprintf (tmp,"vsscreen->numlines:%d\n",vsscreen->numlines); putln (tmp); sprintf (tmp,"vsscreen->allwidth:%d\n",vsscreen->allwidth); putln (tmp); sprintf (tmp,"vsscreen->maxwidth:%d\n",vsscreen->maxwidth); putln (tmp); sprintf (tmp,"vsscreen:%08x\n",vsscreen); putln (tmp); sprintf (tmp,"vslin:%08x\n",vslin); putln (tmp); sprintf (tmp,"next:%08x\n",vslin->next); putln (tmp); sprintf (tmp,"prev:%08x\n",vslin->prev); putln (tmp); sprintf (tmp,"text:%08x\n\n",vslin->text); putln (tmp); #endif width = VSmaxwidth(screens[scrn].vs)+1; /* VSmaxwidth returns 79 or 131 */ p = vslin; maxLineNo = vsscreen->numlines+VSgetlines(screens[scrn].vs); /* VSgetlines returns 24 or whatever */ for (lineNo=1; lineNo<=maxLineNo; lineNo++) { /*sprintf(tmp,"lineNo:%d, p:%08x, starts with:%c%c%c%c",lineNo,p,*(p->text),*(p->text+1),*(p->text+2),*(p->text+3)); putln(tmp);*/ if (p==NULL) { putln ("p is NULL"); return (-1); } if (p->text==NULL) { putln ("p->text is NULL"); return (-1); } // First convert the line back to Mac US format, and then to the new format. trbuf_nat_mac((unsigned char *)p->text,width, oldtable); trbuf_mac_nat((unsigned char *)p->text,width, newtable); p = p->next; } sprintf (tmp, "transBuffer:did convert %d lines", lineNo-1); putln (tmp); return (0); } BytePtr GetTranslationResource(short id) { Handle h; h = GetResource(MY_TRSL, id); if ((h == NULL) || (ResError() != noErr)) { // Do nasty mean error here. BUGG } DetachResource(h); HLockHi(h); return((BytePtr) *h); } // table #'s 1...n correspond to tables in our master array, table #0 is the default table BytePtr ReturnTablePtr(short table, Boolean out) { if (table > nNational || table < 1) return(DefaultTable + ((out == TRUE) * 256)); return((BytePtr)(*transTablesHdl + ((table - 1) * 512) + ((out == TRUE) * 256))); } // The Default table (i.e. no translation) and the two FTP tables are stored in the // Application's resource fork as resources of type TRSL. The // tables added and removed by the user are stored in the prefs file as resources of // type taBL. This routine loads the default table and the two FTP tables into memory. // Failures can only be caused by an incorrect application resource fork. void Setup_Default_Tables(void) { DefaultTable = GetTranslationResource(TRSL_DEFAULT_TABLE); FTPinTable = GetTranslationResource(TRSL_FTP_TABLE); FTPoutTable = FTPinTable + 256; } /* * Be very careful with calling putln from this procedure, since * putln uses the translation tables. If the tables are not setup * garbage output will appear. This is not harmful, but very * annoying. */ void trInit (MenuHandle whichMenu) { short i, numTables; Handle h; LinkedListNode *theHead; nNational = 0; Setup_Default_Tables(); transTablesHdl = myNewHandle(0); UseResFile(TelInfo->ApplicationFile); numTables = CountResources(USER_TRSL); if (numTables) { Str255 NoneString; theHead = createSortedList2(USER_TRSL,numTables,NULL); //now we have a sorted linked list of the names GetIndString(NoneString,MISC_STRINGS,NONE_STRING); AppendMenu(whichMenu,NoneString); addListToMenu/*3*/(whichMenu, theHead, 2); deleteList(&theHead); for (i = 2; i <= numTables + 1; i++) //start adding things from the second menu item (first is none) { Str255 menuItemName; GetMenuItemText(whichMenu, i,menuItemName); h = GetNamedResource(USER_TRSL,menuItemName); if (ResError() == noErr && (GetHandleSize(h) == 512)) { nNational++; // Append the table's data to the master array of table data HUnlock(transTablesHdl); mySetHandleSize(transTablesHdl, (nNational * 512));//we're at init time; we have the mem HLockHi(transTablesHdl); HLock(h); BlockMove(*h, (*transTablesHdl) + ((nNational - 1) * 512), 512); } // Release the resource ReleaseResource(h); } } UseResFile(TelInfo->SettingsFile); } /* Converts a char from 8-bit National to 8-bit Macintosh */ void trbuf_nat_mac(unsigned char *buf, short len, short table) { short i; unsigned char *p; BytePtr table_data; table_data = ReturnTablePtr(table, FALSE); for (i=0,p=buf; iprredirect = 1; if (VSIw->qprint && VSIw->printqueued) { GetEOF(VSIw->refNum, &myEOF); if (myEOF >= 3) SetEOF(VSIw->refNum, myEOF - 3); SetFPos(VSIw->refNum, 2, 0L); return; } if (VSIw->qprint) VSIw->printqueued = 1; VSIw->prbuf = 0x00000000; VSIw->prbuf2 = 0x00; sprintf (VSIw->fname,"NCSA Telnet tempfile #%d",VSIwn); c2pstr(VSIw->fname); /* BYU 2.4.18 */ if ((sts = HCreate(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname, '????', 'TEXT')) != noErr) { if (sts != dupFNErr) { SysBeep(1); VSIw->prredirect = 0; sprintf(tmp,"Create: ERROR %d",sts); putln(tmp); return; } } if ((sts = HOpenDF(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname, fsRdWrPerm, &(VSIw->refNum))) != noErr) { SysBeep(1); VSIw->prredirect = 0; sprintf(tmp,"FSOpen: ERROR %d",sts); putln(tmp); HDelete(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname); return; } if (SetEOF(VSIw->refNum, 0L)) { SysBeep(1); VSIw->prredirect = 0; putln("VSPRON:SETEOF ERROR"); HDelete(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname); return; } } /* LU - we just got the escape sequence to turn OFF redirection. Take what we have and dump it to the printer */ void VSprOFF(void) { Str255 Title; TPrStatus prStatus; /* Status record */ TPPrPort prPort; /* the Printer port */ OSErr sts; GrafPtr savePort; char tmp[100]; /* only for debugging */ short temp; /* NCSA: SB - the screen # */ THPrint PrRecHandle; putln ("printer redirection OFF"); if (VSIw->prredirect==0) /* no redirection started! */ return; VSIw->prredirect = 0; if (VSIw->qprint) return; GetPort (&savePort); /* save old port */ PrOpen(); PrRecHandle = PrintSetupRecord(); GetWTitle ((GrafPtr) RSgetwindow(VSIwn),Title); SetCursor(theCursors[normcurs]); if (PrJobDialog(PrRecHandle)) { /* Cancel the print if FALSE */ if ((sts=PrError()) != noErr){ sprintf(tmp,"PrJobDialog: ERROR %d",sts); putln(tmp); } prPort=PrOpenDoc(PrRecHandle,0L,0L); if ((sts=PrError()) != noErr) { SysBeep(1); sprintf(tmp,"PrOpenDoc: ERROR %d",sts); putln(tmp); } else { temp = findbyVS(VSIwn); /* NCSA: SB */ if (temp < 0) { PrClose(); /* NCSA: SB */ DisposeHandle((Handle)PrRecHandle); return; /* NCSA: SB */ } printPages (prPort, PrRecHandle, Title, VSmaxwidth(VSIwn), NULL, VSIw->refNum, 0L,temp); PrCloseDoc(prPort); if ((sts=PrError()) != noErr) { sprintf(tmp,"PrCloseDoc: ERROR %d",sts); putln(tmp); } if (((*PrRecHandle)->prJob.bJDocLoop == bSpoolLoop) && (PrError()==0)) { PrPicFile(PrRecHandle,0L,0L,0L,&prStatus); /* Spool if necessary */ if ((sts=PrError()) != noErr) { sprintf(tmp,"PrPicFile: ERROR %d",sts); putln(tmp); } } } } PrClose(); DisposeHandle((Handle)PrRecHandle); SetPort (savePort); /* restore old port */ if ((sts=FSClose (VSIw->refNum)) != noErr) { SysBeep(1); sprintf(tmp,"FSClose: ERROR %d",sts); putln(tmp); } VSIw->refNum = -1; if ((sts=HDelete(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname)) != noErr) { SysBeep(1); sprintf(tmp,"HDelete: ERROR %d",sts); putln(tmp); } updateCursor(1); } #define ENDOFPRT '\033[4i' /* [4i (0x1b5b3469) */ #define ENDOFPRT2 '[?4i' // only valid if (prbuf2 == '\033') void VSpr(unsigned char **pc, short *pctr) { long count; /* number of chars to print to file */ char *start; /* original start of buffer */ OSErr sts; char tmp[100]; /* only for debugging */ short rdy; /* true if [4i or [?4i */ count=0; start=(char *)*pc; rdy=0; while ((*pctr>0) && (!rdy)) { VSIw->prbuf2=(VSIw->prbuf>>24); VSIw->prbuf=(VSIw->prbuf<<8) + **pc; if (VSIw->prbuf==ENDOFPRT) { /* i.e. no more redirection */ rdy=1; count--; /* will be incremented again below */ } if ((VSIw->prbuf==ENDOFPRT2) && (VSIw->prbuf2 == '\033')) { /* i.e. no more redirection */ rdy=1; count--; /* will be incremented again below */ count--; } count++; if (**pc == 0) { // RAB BetterTelnet 1.0fc7 // We don't want NULLs here! count--; trbuf_nat_mac ((unsigned char *)start,count, screens[findbyVS(VSIwn)].national); FSWrite(VSIw->refNum,&count,start); start += (count + 1); count = 0; } (*pc)++; (*pctr)--; } trbuf_nat_mac ((unsigned char *)start,count, screens[findbyVS(VSIwn)].national); if ((sts=FSWrite(VSIw->refNum,&count,start)) != noErr) { SysBeep(1); sprintf(tmp,"FSWrite: ERROR %d",sts); putln(tmp); } if (rdy || sts) VSprOFF(); } /* LU - that is the end of the new routines needed for printer redirection */ /* LU - now we just patch up VSem() to use this code, and were done! */ void VSem ( unsigned char *c, /* pointer to character string */ short ctr /* length of character string */ ) /* basic routine for placing characters on a virtual screen, and interpreting control characters and escape sequences. Simple interpretation of controls & escapes is done here, while the harder stuff is done by calling VSIxx routines in vsintern.c. */ { register short sx; register short escflg; /* state of escape sequence interpretation */ short insert, attrib, extra, offend; char *current, *start; unsigned short *acurrent; escflg = VSIw->escflg; while (ctr > 0) { if (VSIw->prredirect) /* PR - printer redirection? */ VSpr(&c,&ctr); /* PR -if yes, call VSpr */ /* PR - when we return from VSpr there may (ctr!=0) */ /* PR - or may not (ctr==0) be chars left in *c to print */ while ((escflg == 0) && (ctr > 0) && (*c < 32)) { switch (*c) { case 0x1b: /* esc */ escflg++; break; case 0x0e: /* shift out */ if (VSIw->G1) VSIw->attrib = VSgraph(VSIw->attrib); else VSIw->attrib = VSnotgraph(VSIw->attrib); VSIw->charset = 1; break; case 0x0f: /* shift in */ if (VSIw->G0) VSIw->attrib = VSgraph(VSIw->attrib); else VSIw->attrib = VSnotgraph(VSIw->attrib); VSIw->charset = 0; break; case 0x07: /* bell */ if (!VSIw->ignoreBeeps) RSbell(VSIwn); break; case 0x08: /* backspace */ VSIw->x--; if (VSIw->x < 0) /* hit left margin */ VSIw->x = 0; break; case 0x0c: /* ff */ VSIindex(); break; case 0x09: /* ht */ /* Later change for versatile tabbing */ VSItab(); VScapture(c,1); break; case 0x0a: /* lf */ VSIindex(); break; case 0x0d: /* cr */ VSIw->x = 0; VScapture(c,1); break; case 0x0b: /* vt */ VSIindex(); break; } c++; ctr--; } if ((escflg == 0) && (ctr > 0) && (*c & 0x80) && (*c < 0xA0) && (screens[findbyVS(VSIwn)].vtemulation == 1)) // VT220 eightbit starts here { switch (*c) { case 0x84: /* ind */ //same as ESC D VSIindex(); goto ShortCut; case 0x85: /* nel */ //same as ESC E VSIw->x = 0; VSIindex(); goto ShortCut; case 0x88: /* hts */ //same as ESC H VSIw->tabs[VSIw->x] = 'x'; goto ShortCut; case 0x8d: /* ri */ //same as ESC M VSIrindex(); goto ShortCut; case 0x9b: /* csi */ //same as ESC [ VSIapclear(); escflg = 2; c++; //CCP ctr--; break; case 0x86: /* ssa */ // - same as ESC F */ case 0x87: /* esa */ // - same as ESC G */ case 0x8e: /* ss2 */ // - same as ESC N */ case 0x8f: /* ss3 */ // - same as ESC O */ case 0x90: /* dcs */ // - same as ESC P */ case 0x93: /* sts */ // - same as ESC S */ case 0x96: /* spa */ // - same as ESC V */ case 0x97: /* epa */ // - same as ESC W */ case 0x9d: /* osc */ // - same as ESC ] */ case 0x9e: /* pm */ // - same as ESC ^ */ case 0x9f: /* apc */ // - same as ESC _ */ default: goto ShortCut; } }//end if vt220 while ((ctr > 0) && (escflg == 0) && (*c >= 32) &&!((*c & 0x80) && (*c < 0xA0) && (screens[findbyVS(VSIwn)].vtemulation == 1))) { //loop around, printing lines of text one at a time start = &VSIw->linest[VSIw->y]->text[VSIw->x]; /* start of area needing redrawing */ current = start; /* where to put next char */ if (VSIw->oldScrollback) acurrent = &VSIw->attrst[VSIw->y]->text[VSIw->x]; else acurrent = &VSIw->linest[VSIw->y]->attr[VSIw->x]; /* where to put corresponding attribute byte */ attrib = VSIw->attrib; /* current writing attribute */ insert = VSIw->IRM; /* insert mode (boolean) */ offend = 0; /* wrapped to next line (boolean) */ extra = 0; /* overwriting last character of line */ sx = VSIw->x; /* starting column of area needing redrawing */ if (VSIw->x > VSIw->maxwidth) { if (VSIw->DECAWM) { // wrap to next line VSIw->x = 0; VSIindex(); } else //stay at right margin VSIw->x = VSIw->maxwidth; current = start = &VSIw->linest[VSIw->y]->text[VSIw->x]; if (VSIw->oldScrollback) acurrent = &VSIw->attrst[VSIw->y]->text[VSIw->x]; else acurrent = &VSIw->linest[VSIw->y]->attr[VSIw->x]; sx = VSIw->x; } /* if */ while ((ctr > 0) && (*c >= 32) && (offend == 0) && !((*c & 0x80) && (*c < 0xA0) && (screens[findbyVS(VSIwn)].vtemulation == 1))) {//Write characters on a single line trbuf_nat_mac(c,1, screens[findbyVS(VSIwn)].national); //translate to national chars if (insert) //make room for the char VSIinschar(1); *current = *c; *acurrent = attrib; c++; ctr--; if (VSIw->x < VSIw->maxwidth) //advance the cursor position { acurrent++; current++; VSIw->x++; } else //hit right margin { if (VSIw->DECAWM) //autowrap to start of next line { VSIw->x++; offend = 1; // terminate inner loop } else //stay at right margin { VSIw->x = VSIw->maxwidth; extra = 1; // cursor position doesn't advance } } } //we've got a line full of text in the virtual screen //now update the screen to show what we've done extra += VSIw->x - sx; if (insert) RSinsstring(VSIwn, VSIw->x - extra, VSIw->y,VSIw->attrib, extra, start); else { short x2,y2,offset, sxCopy=sx,yCopy = VSIw->y, extraCopy = extra; if (!VSIclip(&sxCopy, &yCopy, &x2, &y2, &extraCopy, &offset)) RSdraw(VSIwn, sxCopy,yCopy, VSIw->attrib,extraCopy,(char *) (start + offset)); } //if (RSisInFront(VSIwn)) //CCP if we are front window, validate the screen // RSvalidateRect(VSIwn); VScapture((unsigned char *) start, extra); } /* while */ while((ctr > 0) && (escflg == 1)) { /* basic escape sequence processing */ switch (*c) { case 0x08: VSIw->x--; if (VSIw->x < 0) VSIw->x = 0; break; case '[': /* csi */ VSIapclear(); escflg++; break; case '7': VSIsave(); goto ShortCut; /* BYU 2.4.12 */ case '8': VSIrestore(); goto ShortCut; /* BYU 2.4.12 */ case 'c': VSIreset(); break; case 'D': VSIindex(); goto ShortCut; /* BYU 2.4.12 */ case 'E': VSIw->x = 0; VSIindex(); goto ShortCut; /* BYU 2.4.12 */ case 'M': VSIrindex(); goto ShortCut; /* BYU 2.4.12 */ case '>': VSIw->DECPAM = 0; goto ShortCut; /* BYU 2.4.12 */ case '=': VSIw->DECPAM = 1; goto ShortCut; /* BYU 2.4.12 */ case 'Z': VTsendident(); goto ShortCut; /* BYU 2.4.12 */ case ' ': /* BYU 2.4.12 */ case '*': /* BYU 2.4.12 */ case '#': escflg = 3; break; case '(': escflg = 4; break; case ')': escflg = 5; break; case 'H': VSIw->tabs[VSIw->x] = 'x'; goto ShortCut; /* BYU 2.4.12 */ #ifdef CISB case 'I': bp_ESC_I(); break; #endif CISB case ']': // WNR - XTerm if (screens[findbyVS(VSIwn)].Xterm) // WNR - XTerm escflg = 6; // WNR - XTerm break; // WNR - XTerm default: goto ShortCut; /* BYU 2.4.12 */ } /* switch */ c++; ctr--; } /* while */ while ((escflg == 2) && (ctr > 0)) { /* "control sequence" processing */ switch (*c) { case 0x08: VSIw->x--; if (VSIw->x < 0) VSIw->x = 0; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* parse numeric parameter */ if (VSIw->parms[VSIw->parmptr] < 0) VSIw->parms[VSIw->parmptr] = 0; VSIw->parms[VSIw->parmptr] = VSIw->parms[VSIw->parmptr] * 10; VSIw->parms[VSIw->parmptr] += *c - '0'; break; case '?': /* DEC-private control sequence */ VSIw->parms[VSIw->parmptr++] = -2; break; case ';': /* parameter separator */ VSIw->parmptr++; break; case 'A': /* cursor up */ #if 1 /* BYU */ if (VSIw->parms[0]<1) VSIw->y--; /* BYU */ else VSIw->y-=VSIw->parms[0]; /* BYU */ if ( VSIw->y < 0 ) VSIw->y=0; /* BYU */ if (VSIw->y < VSIw->top) /* NCSA: SB */ VSIw->y = VSIw->top; /* NCSA: SB */ #else /* BYU */ if (VSIw->y < VSIw->top) { /* outside scrolling region */ if (VSIw->parms[0] < 1) VSIw->y--; else VSIw->y -= VSIw->parms[0]; } else { /* don't leave scrolling region */ if (VSIw->parms[0] < 1) VSIw->y--; else VSIw->y -= VSIw->parms[0]; if (VSIw->y < VSIw->top) VSIw->y = VSIw->top; } #endif /* BYU */ VSIrange(); goto ShortCut; /* BYU 2.4.12 */ case 'B': /* cursor down */ #if 1 /* BYU */ if (VSIw->parms[0]<1) VSIw->y++; /* BYU */ else VSIw->y+=VSIw->parms[0]; /* BYU */ if (VSIw->y > VSIw->bottom) /* NCSA: SB */ VSIw->y = VSIw->bottom; /* NCSA: SB */ #else /* BYU */ if (VSIw->y > VSIw->bottom) { /* outside scrolling region */ if (VSIw->parms[0] < 1) VSIw->y++; else VSIw->y += VSIw->parms[0]; } else { /* don't leave scrolling region */ if (VSIw->parms[0] < 1) VSIw->y++; else VSIw->y += VSIw->parms[0]; if (VSIw->y > VSIw->bottom) VSIw->y = VSIw->bottom; } #endif /* BYU */ VSIrange(); goto ShortCut; /* BYU 2.4.12 */ case 'C': /* cursor right */ if (VSIw->parms[0] < 1) VSIw->x++; else VSIw->x += VSIw->parms[0]; VSIrange(); if (VSIw->x > VSIw->maxwidth) VSIw->x = VSIw->maxwidth; goto ShortCut; /* BYU 2.4.12 */ case 'D': /* cursor left */ if (VSIw->parms[0] < 1) VSIw->x--; else VSIw->x -= VSIw->parms[0]; VSIrange(); goto ShortCut; /* BYU 2.4.12 */ case 'f': case 'H': /* absolute cursor positioning */ VSIw->x = VSIw->parms[1] - 1; if (VSIw->DECORG) /* origin mode -- position relative to top of scrolling region */ VSIw->y = VSIw->parms[0] - 1 + VSIw->top; else VSIw->y = VSIw->parms[0] - 1; /* Don't use actual VSIrange 'cause it will wrap us to first column if we are past screen edge. This causes "resize" to break */ if (VSIw->x < 0) /* JMB 2.6 */ VSIw->x = 0; /* JMB 2.6 */ if (VSIw->x > (VSIw->maxwidth)) /* JMB 2.6 */ VSIw->x = VSIw->maxwidth; /* JMB 2.6 */ if (VSIw->y < 0) /* JMB 2.6 */ VSIw->y = 0; /* JMB 2.6 */ if (VSIw->y > VSIw->lines) /* JMB 2.6 */ VSIw->y = VSIw->lines; /* JMB 2.6 */ if ((VSIw->forcesave)&&(VSIw->y == 0)&&(VSIw->x == 0)) //CCP better FORCESAVE VSIw->possibleForce = TRUE; goto ShortCut; /* BYU 2.4.12 */ case 'i': /* PR: media copy */ if (VSIw->parms[VSIw->parmptr]==5) { /* PR */ /*c++; ctr--; */ /* PR */ VSprON(); /* PR - set status and open temp file etc */ /* PR - chars will be redirected at top of loop */ /* PR - in this procedure */ } /* PR */ escflg = 0; /* PR */ break; /* PR */ case 'K': /* erase to beginning/end/whole of line */ switch (VSIw->parms[0]) { case -1: case 0: VSIeeol(); break; case 1: VSIebol(); break; case 2: VSIel(-1); break; default: goto ShortCut; /* BYU 2.4.12 */ } /* switch */ goto ShortCut; /* BYU 2.4.12 */ case 'J': /* erase to beginning/end/whole of screen */ switch (VSIw->parms[0]) { case -1: case 0: VSIeeos(); break; case 1: VSIebos(); break; case 2: VSIes(); break; default: goto ShortCut; /* BYU 2.4.12 */ } /* switch */ goto ShortCut; /* BYU 2.4.12 */ case 'm': /* set/clear attributes */ { short temp = 0; while (temp <= VSIw->parmptr) { short p; if (VSIw->parms[VSIw->parmptr] < 0) VSIw->parms[VSIw->parmptr] = 0; p = VSIw->parms[temp]; if (p == 0) VSIw->attrib &= 0x80; //all off else if (p<8) VSIw->attrib |= VSa(p);//set an attribute else if (p>21 && p<28) VSIw->attrib &= ~VSa(p-20); //clear an attribute else if (screens[findbyVS(VSIwn)].ANSIgraphics) { if (p>=30 && p<38) VSIw->attrib = (VSIw->attrib&~0x0700) | ((p-30)<<8) | 0x0800; else if (p>=40 && p<48) VSIw->attrib = (VSIw->attrib&~0x7000) | ((p-40)<<12) | 0x8000; } temp++; } /* while */ } goto ShortCut; /* BYU 2.4.12 */ case 'q': /* flash dem LEDs. What LEDs? */ goto ShortCut; /* BYU 2.4.12 */ case 'c': VTsendident(); goto ShortCut; /* BYU 2.4.12 */ case 'n': switch (VSIw->parms[0]) { case 5: VTsendstat(); break; case 6: VTsendpos(); break; } /* switch */ goto ShortCut; /* BYU 2.4.12 */ case 'L': if (VSIw->parms[0] < 1) VSIw->parms[0] = 1; VSIinslines(VSIw->parms[0], -1); goto ShortCut; /* BYU 2.4.12 */ case 'M': if (VSIw->parms[0] < 1) VSIw->parms[0] = 1; VSIdellines(VSIw->parms[0], -1); goto ShortCut; /* BYU 2.4.12 */ case '@': if (VSIw->parms[0] < 1) VSIw->parms[0] = 1; VSIinschar(VSIw->parms[0]); VSredrawLine(VSIwn); //redraws current line goto ShortCut; case 'P': if (VSIw->parms[0] < 1) VSIw->parms[0] = 1; VSIdelchars(VSIw->parms[0]); goto ShortCut; /* BYU 2.4.12 */ case 'r': /* set scrolling region */ if (VSIw->parms[0] < 0) VSIw->top = 0; else VSIw->top = VSIw->parms[0] - 1; if (VSIw->parms[1] < 0) VSIw->bottom = VSIw->lines; else VSIw->bottom = VSIw->parms[1] - 1; if (VSIw->top < 0) VSIw->top = 0; if (VSIw->top > VSIw->lines - 1) VSIw->top = VSIw->lines - 1; if (VSIw->bottom < 1) VSIw->bottom = VSIw->lines; if (VSIw->bottom > VSIw->lines) VSIw->bottom = VSIw->lines; if (VSIw->top >= VSIw->bottom) /* NCSA: SB */ { /* NCSA: SB */ if (VSIw->bottom >=1) /* NCSA: SB */ VSIw->top = VSIw->bottom -1; /* NCSA: SB */ else VSIw->bottom = VSIw->top +1; /* NCSA: SB */ } /* NCSA: SB */ VSIw->x = 0; VSIw->y = 0; if (VSIw->DECORG) VSIw->y = VSIw->top; /* origin mode relative */ goto ShortCut; /* BYU 2.4.12 */ case 'h': /* set options */ VSIsetoption(1); goto ShortCut; /* BYU 2.4.12 */ case 'l': /* reset options */ VSIsetoption(0); goto ShortCut; /* BYU 2.4.12 */ case 'g': if (VSIw->parms[0] == 3) /* clear all tabs */ VSItabclear(); else if (VSIw->parms[0] <= 0) /* clear tab at current position */ VSIw->tabs[VSIw->x] = ' '; goto ShortCut; /* BYU 2.4.12 */ case '!': /* BYU 2.4.12 - More private DEC stuff? */ case '\'': /* BYU 2.4.12 - More private DEC stuff? */ case '\"': /* BYU 2.4.12 - More private DEC stuff? */ escflg++; /* BYU 2.4.12 */ break; /* BYU 2.4.12 */ default: /* Dang blasted strays... */ goto ShortCut; /* BYU 2.4.12 */ } /* switch */ c++; ctr--; } /* while */ while ((escflg == 3) && (ctr > 0)) { /* "#" handling */ /* no support for double-width and double-height characters yet */ switch (*c) { case 0x08: VSIw->x--; if (VSIw->x < 0) VSIw->x = 0; break; case '8': /* alignment display */ VTalign(); goto ShortCut; /* BYU 2.4.12 */ default: goto ShortCut; /* BYU 2.4.12 */ } /* switch */ c++; ctr--; } /* while */ while ((escflg == 4) && (ctr > 0)) { /* "(" handling (selection of G0 character set) */ switch (*c) { case 0x08: VSIw->x--; if (VSIw->x < 0) VSIw->x = 0; break; case 'A': /* UK */ case 'B': /* US */ case '1': /* "soft" */ VSIw->G0 = 0; if (!VSIw->charset) VSIw->attrib = VSnotgraph(VSIw->attrib); goto ShortCut; /* BYU 2.4.12 */ case '0': /* DEC special graphics */ case '2': /* "soft" */ VSIw->G0 = 1; if (!VSIw->charset) VSIw->attrib = VSgraph(VSIw->attrib); goto ShortCut; /* BYU 2.4.12 */ default: goto ShortCut; /* BYU 2.4.12 */ } /* switch */ c++; ctr--; } /* while */ while ((escflg == 5) && (ctr > 0)) { /* ")" handling (selection of G1 character set) */ switch (*c) { case 0x08: VSIw->x--; if (VSIw->x < 0) VSIw->x = 0; break; case 'A': /* UK */ case 'B': /* US */ case '1': /* "soft" */ VSIw->G1 = 0; if (VSIw->charset) VSIw->attrib = VSnotgraph(VSIw->attrib); goto ShortCut; /* BYU 2.4.12 */ case '0': /* DEC special graphics */ case '2': /* "soft" */ VSIw->G1 = 1; if (VSIw->charset) VSIw->attrib = VSgraph(VSIw->attrib); goto ShortCut; /* BYU 2.4.12 */ default: goto ShortCut; /* BYU 2.4.12 */ } /* switch */ c++; ctr--; } /* while */ // Handle XTerm rename functions, code contributed by Bill Rausch // Modified by JMB to handle ESC]2; case as well. if( (escflg >= 6) && (ctr > 0) ) { static char *tmp; static Str255 newname; if( (escflg == 6) && ((*c == '0') || (*c == '2'))) { escflg++; c++; ctr--; } if( (escflg == 7 ) && (ctr > 0) && (*c == ';') ) { ctr--; c++; escflg++; newname[0] = 0; tmp = (char *)&newname[1]; } while( (escflg == 8) && (ctr > 0) && (*c != 07) && (*c != 033)) { if(*newname < 255) { *tmp++ = *c; (*newname)++; } c++; ctr--; } if( (escflg == 8) && (*c == 07 || *c == 033) && (ctr > 0) ) { set_new_window_name( newname, RSgetwindow(VSIwn) ); if(*c != 07) { /* This will be undone in the ShortCut below. */ c--; ctr++; } goto ShortCut; } } /* if */ /* while( (escflg == 8) && (ctr > 0) && (*c != 07) ) { *tmp++ = *c++; ctr--; (*newname)++; } if( (escflg == 8) && (*c == 07) && (ctr > 0) ) { set_new_window_name( newname, RSgetwindow(VSIwn) ); goto ShortCut; } } /* if */ if ((escflg > 2) && (ctr > 0)) { ShortCut: /* BYU 2.4.12 - well, sacrificing style for speed */ if ((VSIw->possibleForce)&&(*c != 'H')) //CCP better forcesave VSIw->possibleForce = FALSE; escflg = 0; c++; ctr--; } /* if */ } /* while (ctr > 0) */ VSIw->escflg = escflg; } /* VSem */ \ No newline at end of file +// BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // #pragma profile on /* * * Virtual Screen Kernel Emulation Routines * (vsem.c) * * National Center for Supercomputing Applications * by Gaige B. Paulsen * * This file contains the private emulation calls for the NCSA * Virtual Screen Kernel. * *----------------------------------------------------------------------------------- * This also now contains Roland Mansson's code for printer redirection * Thanks for all of the work, Roland! *----------------------------------------------------------------------------------- * * Version Date Notes * ------- ------ --------------------------------------------------- * 0.01 861102 Initial coding -GBP * 0.10 861111 Added/Modified VT emulator -GBP * 0.50 861113 First compiled edition -GBP * 2.1 871130 NCSA Telnet 2.1 -GBP * 2.2 880715 NCSA Telnet 2.2 -GBP * 2.6 12/92 Telnet 2.6: Fixed some VS stuff, and added LU changes */ #include "wind.h" #include "vsdata.h" #include "vskeys.h" #include "rsinterf.proto.h" #include "rsmac.proto.h" #include "vsintern.proto.h" #include "vsinterf.proto.h" #include "translate.proto.h" #include "maclook.proto.h" #include "printing.proto.h" #include "event.proto.h" #include "menuseg.proto.h" #include "vsem.proto.h" extern THPrint PrRecHandle; /* LU - our print record handle from menu.c */ extern Cursor *theCursors[]; extern long TempItemsDirID; extern short TempItemsVRefNum; extern WindRec *screens; #ifdef DEBUG_CAPTURE extern VSscrndata *VSscreens; #endif void VSunload(void) {} /* LU - this is the start of the main LU changes for doing printer redirection */ /* Once again I would like to thank Roland Mansson, of the Lund University Computing Center (Sweden) for all of his work on Telnet. Not only for the national char support, but also for the printer redirection support, a new version of PrintPages, and everything else. Thanks a lot, and keep up the good work!!! -SMB */ /* LU - we have gotten the escape sequence to turn on printer redirection, so do so */ void VSprON(void) { char tmp[100]; /* only for debugging */ OSErr sts; long myEOF; putln ("printer redirection ON"); VSIw->prredirect = 1; if (VSIw->qprint && VSIw->printqueued) { GetEOF(VSIw->refNum, &myEOF); if (myEOF >= 3) SetEOF(VSIw->refNum, myEOF - 3); SetFPos(VSIw->refNum, 2, 0L); return; } if (VSIw->qprint) VSIw->printqueued = 1; VSIw->prbuf = 0x00000000; VSIw->prbuf2 = 0x00; sprintf (VSIw->fname,"NCSA Telnet tempfile #%d",VSIwn); c2pstr(VSIw->fname); /* BYU 2.4.18 */ if ((sts = HCreate(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname, '????', 'TEXT')) != noErr) { if (sts != dupFNErr) { SysBeep(1); VSIw->prredirect = 0; sprintf(tmp,"Create: ERROR %d",sts); putln(tmp); return; } } if ((sts = HOpenDF(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname, fsRdWrPerm, &(VSIw->refNum))) != noErr) { SysBeep(1); VSIw->prredirect = 0; sprintf(tmp,"FSOpen: ERROR %d",sts); putln(tmp); HDelete(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname); return; } if (SetEOF(VSIw->refNum, 0L)) { SysBeep(1); VSIw->prredirect = 0; putln("VSPRON:SETEOF ERROR"); HDelete(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname); return; } } /* LU - we just got the escape sequence to turn OFF redirection. Take what we have and dump it to the printer */ void VSprOFF(void) { Str255 Title; TPrStatus prStatus; /* Status record */ TPPrPort prPort; /* the Printer port */ OSErr sts; GrafPtr savePort; char tmp[100]; /* only for debugging */ short temp; /* NCSA: SB - the screen # */ THPrint PrRecHandle; putln ("printer redirection OFF"); if (VSIw->prredirect==0) /* no redirection started! */ return; VSIw->prredirect = 0; if (VSIw->qprint) return; GetPort (&savePort); /* save old port */ PrOpen(); PrRecHandle = PrintSetupRecord(); GetWTitle ((GrafPtr) RSgetwindow(VSIwn),Title); SetCursor(theCursors[normcurs]); if (PrJobDialog(PrRecHandle)) { /* Cancel the print if FALSE */ if ((sts=PrError()) != noErr){ sprintf(tmp,"PrJobDialog: ERROR %d",sts); putln(tmp); } prPort=PrOpenDoc(PrRecHandle,0L,0L); if ((sts=PrError()) != noErr) { SysBeep(1); sprintf(tmp,"PrOpenDoc: ERROR %d",sts); putln(tmp); } else { temp = findbyVS(VSIwn); /* NCSA: SB */ if (temp < 0) { PrClose(); /* NCSA: SB */ DisposeHandle((Handle)PrRecHandle); return; /* NCSA: SB */ } printPages (prPort, PrRecHandle, Title, VSmaxwidth(VSIwn), NULL, VSIw->refNum, 0L,temp); PrCloseDoc(prPort); if ((sts=PrError()) != noErr) { sprintf(tmp,"PrCloseDoc: ERROR %d",sts); putln(tmp); } if (((*PrRecHandle)->prJob.bJDocLoop == bSpoolLoop) && (PrError()==0)) { PrPicFile(PrRecHandle,0L,0L,0L,&prStatus); /* Spool if necessary */ if ((sts=PrError()) != noErr) { sprintf(tmp,"PrPicFile: ERROR %d",sts); putln(tmp); } } } } PrClose(); DisposeHandle((Handle)PrRecHandle); SetPort (savePort); /* restore old port */ if ((sts=FSClose (VSIw->refNum)) != noErr) { SysBeep(1); sprintf(tmp,"FSClose: ERROR %d",sts); putln(tmp); } VSIw->refNum = -1; if ((sts=HDelete(TempItemsVRefNum, TempItemsDirID, (StringPtr)VSIw->fname)) != noErr) { SysBeep(1); sprintf(tmp,"HDelete: ERROR %d",sts); putln(tmp); } updateCursor(1); } #define ENDOFPRT '\033[4i' /* [4i (0x1b5b3469) */ #define ENDOFPRT2 '[?4i' // only valid if (prbuf2 == '\033') void VSpr(unsigned char **pc, short *pctr) { long count; /* number of chars to print to file */ char *start; /* original start of buffer */ OSErr sts; char tmp[100]; /* only for debugging */ short rdy; /* true if [4i or [?4i */ count=0; start=(char *)*pc; rdy=0; while ((*pctr>0) && (!rdy)) { VSIw->prbuf2=(VSIw->prbuf>>24); VSIw->prbuf=(VSIw->prbuf<<8) + **pc; if (VSIw->prbuf==ENDOFPRT) { /* i.e. no more redirection */ rdy=1; count--; /* will be incremented again below */ } if ((VSIw->prbuf==ENDOFPRT2) && (VSIw->prbuf2 == '\033')) { /* i.e. no more redirection */ rdy=1; count--; /* will be incremented again below */ count--; } count++; if (**pc == 0) { // RAB BetterTelnet 1.0fc7 // We don't want NULLs here! count--; trbuf_nat_mac ((unsigned char *)start,count, screens[findbyVS(VSIwn)].national); FSWrite(VSIw->refNum,&count,start); start += (count + 1); count = 0; } (*pc)++; (*pctr)--; } trbuf_nat_mac ((unsigned char *)start,count, screens[findbyVS(VSIwn)].national); if ((sts=FSWrite(VSIw->refNum,&count,start)) != noErr) { SysBeep(1); sprintf(tmp,"FSWrite: ERROR %d",sts); putln(tmp); } if (rdy || sts) VSprOFF(); } /* LU - that is the end of the new routines needed for printer redirection */ /* LU - now we just patch up VSem() to use this code, and were done! */ void VSem ( unsigned char *c, /* pointer to character string */ short ctr /* length of character string */ ) /* basic routine for placing characters on a virtual screen, and interpreting control characters and escape sequences. Simple interpretation of controls & escapes is done here, while the harder stuff is done by calling VSIxx routines in vsintern.c. */ { register short sx; register short escflg; /* state of escape sequence interpretation */ short insert, attrib, extra, offend, notyet; char *current, *start; unsigned short *acurrent; escflg = VSIw->escflg; #ifdef DEBUG_CAPTURE if (TelInfo->debug) if (VSscreens[VSIwn].captureRN) { while (ctr != 0) { VScapture(c, (ctr > 255) ? 255 : ctr); c += ((ctr > 255) ? 255 : ctr); ctr -= ((ctr > 255) ? 255 : ctr); } // if debug capturing, capture and DON'T DISPLAY afterwards // in case the control codes being captured crash the emulator return; } #endif while (ctr > 0) { if (VSIw->prredirect) /* PR - printer redirection? */ VSpr(&c,&ctr); /* PR -if yes, call VSpr */ /* PR - when we return from VSpr there may (ctr!=0) */ /* PR - or may not (ctr==0) be chars left in *c to print */ while ((escflg == 0) && (ctr > 0) && (*c < 32)) { switch (*c) { case 0x1b: /* esc */ escflg++; break; case 0x0e: /* shift out */ if (VSIw->G1) VSIw->attrib = VSgraph(VSIw->attrib); else VSIw->attrib = VSnotgraph(VSIw->attrib); VSIw->charset = 1; break; case 0x0f: /* shift in */ if (VSIw->G0) VSIw->attrib = VSgraph(VSIw->attrib); else VSIw->attrib = VSnotgraph(VSIw->attrib); VSIw->charset = 0; break; case 0x07: /* bell */ if (!VSIw->ignoreBeeps) RSbell(VSIwn); break; case 0x08: /* backspace */ VSIw->x--; if (VSIw->x < 0) /* hit left margin */ VSIw->x = 0; break; case 0x0c: /* ff */ VSIindex(); break; case 0x09: /* ht */ /* Later change for versatile tabbing */ VSItab(); VScapture(c,1); break; case 0x0a: /* lf */ VSIindex(); break; case 0x0d: /* cr */ VSIw->x = 0; VScapture(c,1); break; case 0x0b: /* vt */ VSIindex(); break; } c++; ctr--; } if ((escflg == 0) && (ctr > 0) && (*c & 0x80) && (*c < 0xA0) && (screens[findbyVS(VSIwn)].vtemulation == 1)) // VT220 eightbit starts here { switch (*c) { case 0x84: /* ind */ //same as ESC D VSIindex(); goto ShortCut; case 0x85: /* nel */ //same as ESC E VSIw->x = 0; VSIindex(); goto ShortCut; case 0x88: /* hts */ //same as ESC H VSIw->tabs[VSIw->x] = 'x'; goto ShortCut; case 0x8d: /* ri */ //same as ESC M VSIrindex(); goto ShortCut; case 0x9b: /* csi */ //same as ESC [ VSIapclear(); escflg = 2; c++; //CCP ctr--; break; case 0x86: /* ssa */ // - same as ESC F */ case 0x87: /* esa */ // - same as ESC G */ case 0x8e: /* ss2 */ // - same as ESC N */ case 0x8f: /* ss3 */ // - same as ESC O */ case 0x90: /* dcs */ // - same as ESC P */ case 0x93: /* sts */ // - same as ESC S */ case 0x96: /* spa */ // - same as ESC V */ case 0x97: /* epa */ // - same as ESC W */ case 0x9d: /* osc */ // - same as ESC ] */ case 0x9e: /* pm */ // - same as ESC ^ */ case 0x9f: /* apc */ // - same as ESC _ */ default: goto ShortCut; } }//end if vt220 while ((ctr > 0) && (escflg == 0) && (*c >= 32) &&!((*c & 0x80) && (*c < 0xA0) && (screens[findbyVS(VSIwn)].vtemulation == 1))) { //loop around, printing lines of text one at a time start = &VSIw->linest[VSIw->y]->text[VSIw->x]; /* start of area needing redrawing */ current = start; /* where to put next char */ if (VSIw->oldScrollback) acurrent = &VSIw->attrst[VSIw->y]->text[VSIw->x]; else acurrent = &VSIw->linest[VSIw->y]->attr[VSIw->x]; /* where to put corresponding attribute byte */ attrib = VSIw->attrib; /* current writing attribute */ insert = VSIw->IRM; /* insert mode (boolean) */ offend = 0; /* wrapped to next line (boolean) */ extra = 0; /* overwriting last character of line */ sx = VSIw->x; /* starting column of area needing redrawing */ if (VSIw->x > VSIw->maxwidth) { if (VSIw->DECAWM) { // wrap to next line VSIw->x = 0; VSIindex(); } else //stay at right margin VSIw->x = VSIw->maxwidth; current = start = &VSIw->linest[VSIw->y]->text[VSIw->x]; if (VSIw->oldScrollback) acurrent = &VSIw->attrst[VSIw->y]->text[VSIw->x]; else acurrent = &VSIw->linest[VSIw->y]->attr[VSIw->x]; sx = VSIw->x; } /* if */ while ((ctr > 0) && (*c >= 32) && (offend == 0) && !((*c & 0x80) && (*c < 0xA0) && (screens[findbyVS(VSIwn)].vtemulation == 1))) {//Write characters on a single line trbuf_nat_mac(c,1, screens[findbyVS(VSIwn)].national); //translate to national chars if (insert) //make room for the char VSIinschar(1); *current = *c; *acurrent = attrib; c++; ctr--; if (VSIw->x < VSIw->maxwidth) //advance the cursor position { acurrent++; current++; VSIw->x++; } else //hit right margin { if (VSIw->DECAWM) //autowrap to start of next line { VSIw->x++; offend = 1; // terminate inner loop } else //stay at right margin { VSIw->x = VSIw->maxwidth; extra = 1; // cursor position doesn't advance } } } //we've got a line full of text in the virtual screen //now update the screen to show what we've done extra += VSIw->x - sx; if (insert) RSinsstring(VSIwn, VSIw->x - extra, VSIw->y,VSIw->attrib, extra, start); else { short x2,y2,offset, sxCopy=sx,yCopy = VSIw->y, extraCopy = extra; if (!VSIclip(&sxCopy, &yCopy, &x2, &y2, &extraCopy, &offset)) RSdraw(VSIwn, sxCopy,yCopy, VSIw->attrib,extraCopy,(char *) (start + offset)); } //if (RSisInFront(VSIwn)) //CCP if we are front window, validate the screen // RSvalidateRect(VSIwn); VScapture((unsigned char *) start, extra); } /* while */ while((ctr > 0) && (escflg == 1)) { /* basic escape sequence processing */ switch (*c) { case 0x08: VSIw->x--; if (VSIw->x < 0) VSIw->x = 0; break; case '[': /* csi */ VSIapclear(); escflg++; notyet = 1; break; case '7': VSIsave(); goto ShortCut; /* BYU 2.4.12 */ case '8': VSIrestore(); goto ShortCut; /* BYU 2.4.12 */ case 'c': VSIreset(); break; case 'D': VSIindex(); goto ShortCut; /* BYU 2.4.12 */ case 'E': VSIw->x = 0; VSIindex(); goto ShortCut; /* BYU 2.4.12 */ case 'M': VSIrindex(); goto ShortCut; /* BYU 2.4.12 */ case '>': VSIw->DECPAM = 0; goto ShortCut; /* BYU 2.4.12 */ case '=': VSIw->DECPAM = 1; goto ShortCut; /* BYU 2.4.12 */ case 'Z': VTsendident(); goto ShortCut; /* BYU 2.4.12 */ case ' ': /* BYU 2.4.12 */ case '*': /* BYU 2.4.12 */ case '#': escflg = 3; break; case '(': escflg = 4; break; case ')': escflg = 5; break; case 'H': VSIw->tabs[VSIw->x] = 'x'; goto ShortCut; /* BYU 2.4.12 */ #ifdef CISB case 'I': bp_ESC_I(); break; #endif CISB case ']': // WNR - XTerm if (screens[findbyVS(VSIwn)].Xterm) // WNR - XTerm escflg = 6; // WNR - XTerm break; // WNR - XTerm default: goto ShortCut; /* BYU 2.4.12 */ } /* switch */ c++; ctr--; } /* while */ while ((escflg == 2) && (ctr > 0)) { /* "control sequence" processing */ switch (*c) { case 0x08: VSIw->x--; if (VSIw->x < 0) VSIw->x = 0; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* parse numeric parameter */ if (VSIw->parms[VSIw->parmptr] < 0) VSIw->parms[VSIw->parmptr] = 0; VSIw->parms[VSIw->parmptr] = VSIw->parms[VSIw->parmptr] * 10; VSIw->parms[VSIw->parmptr] += *c - '0'; break; case '?': /* DEC-private control sequence */ VSIw->parms[VSIw->parmptr++] = -2; break; case ';': /* parameter separator */ VSIw->parmptr++; break; case 'A': /* cursor up */ #if 1 /* BYU */ if (VSIw->parms[0]<1) VSIw->y--; /* BYU */ else VSIw->y-=VSIw->parms[0]; /* BYU */ if ( VSIw->y < 0 ) VSIw->y=0; /* BYU */ if (VSIw->y < VSIw->top) /* NCSA: SB */ VSIw->y = VSIw->top; /* NCSA: SB */ #else /* BYU */ if (VSIw->y < VSIw->top) { /* outside scrolling region */ if (VSIw->parms[0] < 1) VSIw->y--; else VSIw->y -= VSIw->parms[0]; } else { /* don't leave scrolling region */ if (VSIw->parms[0] < 1) VSIw->y--; else VSIw->y -= VSIw->parms[0]; if (VSIw->y < VSIw->top) VSIw->y = VSIw->top; } #endif /* BYU */ VSIrange(); VSIflush(); // RAB BetterTelnet 2.0b3 goto ShortCut; /* BYU 2.4.12 */ case 'B': /* cursor down */ #if 1 /* BYU */ if (VSIw->parms[0]<1) VSIw->y++; /* BYU */ else VSIw->y+=VSIw->parms[0]; /* BYU */ if (VSIw->y > VSIw->bottom) /* NCSA: SB */ VSIw->y = VSIw->bottom; /* NCSA: SB */ #else /* BYU */ if (VSIw->y > VSIw->bottom) { /* outside scrolling region */ if (VSIw->parms[0] < 1) VSIw->y++; else VSIw->y += VSIw->parms[0]; } else { /* don't leave scrolling region */ if (VSIw->parms[0] < 1) VSIw->y++; else VSIw->y += VSIw->parms[0]; if (VSIw->y > VSIw->bottom) VSIw->y = VSIw->bottom; } #endif /* BYU */ VSIrange(); VSIflush(); // RAB BetterTelnet 2.0b3 goto ShortCut; /* BYU 2.4.12 */ case 'C': /* cursor right */ if (VSIw->parms[0] < 1) VSIw->x++; else VSIw->x += VSIw->parms[0]; VSIrange(); if (VSIw->x > VSIw->maxwidth) VSIw->x = VSIw->maxwidth; goto ShortCut; /* BYU 2.4.12 */ case 'D': /* cursor left */ if (VSIw->parms[0] < 1) VSIw->x--; else VSIw->x -= VSIw->parms[0]; VSIrange(); goto ShortCut; /* BYU 2.4.12 */ case 'f': case 'H': /* absolute cursor positioning */ VSIw->x = VSIw->parms[1] - 1; if (VSIw->DECORG) /* origin mode -- position relative to top of scrolling region */ VSIw->y = VSIw->parms[0] - 1 + VSIw->top; else VSIw->y = VSIw->parms[0] - 1; /* Don't use actual VSIrange 'cause it will wrap us to first column if we are past screen edge. This causes "resize" to break */ if (VSIw->x < 0) /* JMB 2.6 */ VSIw->x = 0; /* JMB 2.6 */ if (VSIw->x > (VSIw->maxwidth)) /* JMB 2.6 */ VSIw->x = VSIw->maxwidth; /* JMB 2.6 */ if (VSIw->y < 0) /* JMB 2.6 */ VSIw->y = 0; /* JMB 2.6 */ if (VSIw->y > VSIw->lines) /* JMB 2.6 */ VSIw->y = VSIw->lines; /* JMB 2.6 */ if ((VSIw->forcesave)&&(VSIw->y == 0)&&(VSIw->x == 0)) //CCP better FORCESAVE VSIw->possibleForce = TRUE; if (VSIw->y != VSIw->bottom) VSIflush(); // RAB BetterTelnet 2.0b3 goto ShortCut; /* BYU 2.4.12 */ case 'i': /* PR: media copy */ if (VSIw->parms[VSIw->parmptr]==5) { /* PR */ /*c++; ctr--; */ /* PR */ VSprON(); /* PR - set status and open temp file etc */ /* PR - chars will be redirected at top of loop */ /* PR - in this procedure */ } /* PR */ escflg = 0; /* PR */ break; /* PR */ case 'K': /* erase to beginning/end/whole of line */ switch (VSIw->parms[0]) { case -1: case 0: VSIeeol(); break; case 1: VSIebol(); break; case 2: VSIel(-1); break; default: goto ShortCut; /* BYU 2.4.12 */ } /* switch */ goto ShortCut; /* BYU 2.4.12 */ case 'J': /* erase to beginning/end/whole of screen */ switch (VSIw->parms[0]) { case -1: case 0: VSIeeos(); break; case 1: VSIebos(); break; case 2: VSIes(); break; default: goto ShortCut; /* BYU 2.4.12 */ } /* switch */ goto ShortCut; /* BYU 2.4.12 */ case 'm': /* set/clear attributes */ { short temp = 0; while (temp <= VSIw->parmptr) { short p; if (VSIw->parms[VSIw->parmptr] < 0) VSIw->parms[VSIw->parmptr] = 0; p = VSIw->parms[temp]; if (p == 0) VSIw->attrib &= 0x80; //all off else if (p<8) { if (notyet) { notyet = 0; // VSIw->attrib &= 0x80; } VSIw->attrib |= VSa(p);//set an attribute } else if (p>21 && p<28) VSIw->attrib &= ~VSa(p-20); //clear an attribute else if (screens[findbyVS(VSIwn)].ANSIgraphics) { if (p>=30 && p<38) VSIw->attrib = (VSIw->attrib&~0x0700) | ((p-30)<<8) | 0x0800; else if (p>=40 && p<48) VSIw->attrib = (VSIw->attrib&~0x7000) | ((p-40)<<12) | 0x8000; } temp++; } /* while */ } goto ShortCut; /* BYU 2.4.12 */ case 'q': /* flash dem LEDs. What LEDs? */ goto ShortCut; /* BYU 2.4.12 */ case 'c': VTsendident(); goto ShortCut; /* BYU 2.4.12 */ case 'n': switch (VSIw->parms[0]) { case 5: VTsendstat(); break; case 6: VTsendpos(); break; } /* switch */ goto ShortCut; /* BYU 2.4.12 */ case 'L': if (VSIw->parms[0] < 1) VSIw->parms[0] = 1; VSIinslines(VSIw->parms[0], -1); goto ShortCut; /* BYU 2.4.12 */ case 'M': VSIflush(); // RAB BetterTelnet 2.0b3 if (VSIw->parms[0] < 1) VSIw->parms[0] = 1; VSIdellines(VSIw->parms[0], -1); goto ShortCut; /* BYU 2.4.12 */ case '@': if (VSIw->parms[0] < 1) VSIw->parms[0] = 1; VSIinschar(VSIw->parms[0]); VSredrawLine(VSIwn); //redraws current line goto ShortCut; case 'P': if (VSIw->parms[0] < 1) VSIw->parms[0] = 1; VSIdelchars(VSIw->parms[0]); goto ShortCut; /* BYU 2.4.12 */ case 'r': if ((VSIw->parms[0] - 1 == VSIw->top) && (VSIw->parms[1] - 1 == VSIw->bottom)) goto ShortCut; // RAB BetterTelnet 2.0b3 VSIflush(); // RAB BetterTelnet 2.0b3 /* set scrolling region */ if (VSIw->parms[0] < 0) VSIw->top = 0; else VSIw->top = VSIw->parms[0] - 1; if (VSIw->parms[1] < 0) VSIw->bottom = VSIw->lines; else VSIw->bottom = VSIw->parms[1] - 1; if (VSIw->top < 0) VSIw->top = 0; if (VSIw->top > VSIw->lines - 1) VSIw->top = VSIw->lines - 1; if (VSIw->bottom < 1) VSIw->bottom = VSIw->lines; if (VSIw->bottom > VSIw->lines) VSIw->bottom = VSIw->lines; if (VSIw->top >= VSIw->bottom) /* NCSA: SB */ { /* NCSA: SB */ if (VSIw->bottom >=1) /* NCSA: SB */ VSIw->top = VSIw->bottom -1; /* NCSA: SB */ else VSIw->bottom = VSIw->top +1; /* NCSA: SB */ } /* NCSA: SB */ VSIw->x = 0; VSIw->y = 0; if (VSIw->DECORG) VSIw->y = VSIw->top; /* origin mode relative */ goto ShortCut; /* BYU 2.4.12 */ case 'h': /* set options */ VSIsetoption(1); goto ShortCut; /* BYU 2.4.12 */ case 'l': /* reset options */ VSIsetoption(0); goto ShortCut; /* BYU 2.4.12 */ case 'g': if (VSIw->parms[0] == 3) /* clear all tabs */ VSItabclear(); else if (VSIw->parms[0] <= 0) /* clear tab at current position */ VSIw->tabs[VSIw->x] = ' '; goto ShortCut; /* BYU 2.4.12 */ case '!': /* BYU 2.4.12 - More private DEC stuff? */ case '\'': /* BYU 2.4.12 - More private DEC stuff? */ case '\"': /* BYU 2.4.12 - More private DEC stuff? */ escflg++; /* BYU 2.4.12 */ break; /* BYU 2.4.12 */ default: /* Dang blasted strays... */ goto ShortCut; /* BYU 2.4.12 */ } /* switch */ c++; ctr--; } /* while */ while ((escflg == 3) && (ctr > 0)) { /* "#" handling */ /* no support for double-width and double-height characters yet */ switch (*c) { case 0x08: VSIw->x--; if (VSIw->x < 0) VSIw->x = 0; break; case '8': /* alignment display */ VTalign(); goto ShortCut; /* BYU 2.4.12 */ default: goto ShortCut; /* BYU 2.4.12 */ } /* switch */ c++; ctr--; } /* while */ while ((escflg == 4) && (ctr > 0)) { /* "(" handling (selection of G0 character set) */ switch (*c) { case 0x08: VSIw->x--; if (VSIw->x < 0) VSIw->x = 0; break; case 'A': /* UK */ case 'B': /* US */ case '1': /* "soft" */ VSIw->G0 = 0; if (!VSIw->charset) VSIw->attrib = VSnotgraph(VSIw->attrib); goto ShortCut; /* BYU 2.4.12 */ case '0': /* DEC special graphics */ case '2': /* "soft" */ VSIw->G0 = 1; if (!VSIw->charset) VSIw->attrib = VSgraph(VSIw->attrib); goto ShortCut; /* BYU 2.4.12 */ default: goto ShortCut; /* BYU 2.4.12 */ } /* switch */ c++; ctr--; } /* while */ while ((escflg == 5) && (ctr > 0)) { /* ")" handling (selection of G1 character set) */ switch (*c) { case 0x08: VSIw->x--; if (VSIw->x < 0) VSIw->x = 0; break; case 'A': /* UK */ case 'B': /* US */ case '1': /* "soft" */ VSIw->G1 = 0; if (VSIw->charset) VSIw->attrib = VSnotgraph(VSIw->attrib); goto ShortCut; /* BYU 2.4.12 */ case '0': /* DEC special graphics */ case '2': /* "soft" */ VSIw->G1 = 1; if (VSIw->charset) VSIw->attrib = VSgraph(VSIw->attrib); goto ShortCut; /* BYU 2.4.12 */ default: goto ShortCut; /* BYU 2.4.12 */ } /* switch */ c++; ctr--; } /* while */ // Handle XTerm rename functions, code contributed by Bill Rausch // Modified by JMB to handle ESC]2; case as well. if( (escflg >= 6) && (ctr > 0) ) { static char *tmp; static Str255 newname; if( (escflg == 6) && ((*c == '0') || (*c == '2'))) { escflg++; c++; ctr--; } if( (escflg == 7 ) && (ctr > 0) && (*c == ';') ) { ctr--; c++; escflg++; newname[0] = 0; tmp = (char *)&newname[1]; } while( (escflg == 8) && (ctr > 0) && (*c != 07) && (*c != 033)) { if(*newname < 255) { *tmp++ = *c; (*newname)++; } c++; ctr--; } if( (escflg == 8) && (*c == 07 || *c == 033) && (ctr > 0) ) { set_new_window_name( newname, RSgetwindow(VSIwn) ); if(*c != 07) { /* This will be undone in the ShortCut below. */ c--; ctr++; } goto ShortCut; } } /* if */ /* while( (escflg == 8) && (ctr > 0) && (*c != 07) ) { *tmp++ = *c++; ctr--; (*newname)++; } if( (escflg == 8) && (*c == 07) && (ctr > 0) ) { set_new_window_name( newname, RSgetwindow(VSIwn) ); goto ShortCut; } } /* if */ if ((escflg > 2) && (ctr > 0)) { ShortCut: /* BYU 2.4.12 - well, sacrificing style for speed */ if ((VSIw->possibleForce)&&(*c != 'H')) //CCP better forcesave VSIw->possibleForce = FALSE; escflg = 0; c++; ctr--; } /* if */ } /* while (ctr > 0) */ VSIw->escflg = escflg; } /* VSem */ \ No newline at end of file diff --git a/source/printing/printing.c b/source/printing/printing.c index 856256c..1ca5dc0 100755 --- a/source/printing/printing.c +++ b/source/printing/printing.c @@ -1 +1 @@ -/* * printing.c * * This now contains the PrintPages() code from Roland Mansson, from Lund * University Computing Center. This allows for printer redirection, and also * printing page numbers (and other goodies). Thanks for all of your work! * * Code to handle printing. */ // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #ifdef MPW #pragma segment Printing #endif #include "wind.h" #include "rsinterf.proto.h" /* For RSGetSelText */ #include "netevent.proto.h" #include "vgtek.proto.h" #include "rgmp.proto.h" #include "event.proto.h" #include "tekrgmac.proto.h" #include "vsdata.h" #include "vsinterf.proto.h" extern Cursor *theCursors[]; extern WindRec *screens; /* The screen array from Maclook */ extern short scrn; PROTO_UPP(printsleep, PrIdle); extern void printsleep(void); THPrint gPrRecHandle = NULL; #define PGRECT (*PrRecHandle)->prInfo.rPage /* Macro for making the pagerect more accessible */ #define VMARGINS 4 #define PAPRECT (*PrRecHandle)->rPaper /* Macro for making the paperrect more accessible */ #define bDevCItoh 1 /* from Printing.h */ #define ascLF 10 #define ascFF 12 #define ascCR 13 #include "printing.proto.h" void PrintingUnload(void) {} /* userabort - check to see if the user wants to abort */ short userabort(void) { EventRecord theEvent; while (GetNextEvent(24,&theEvent)) { if ((theEvent.modifiers & cmdKey) && (theEvent.message & 0xff) =='.') return(-1); } return(0); } /* printsleep() - Provide the network keep alive while we are in print * mode. Also set the abort flag if necessary. */ SIMPLE_UPP(printsleep, PrIdle); void printsleep(void) { short CurrentResFile; CurrentResFile = CurResFile(); /* Save the current resource file just in case. */ Stask(); /* act like the postman */ if (userabort()) (*gPrRecHandle)->prJob.fFromUsr=TRUE; UseResFile(CurrentResFile); /* Restore this in case we were bad and changed it. */ } /* printGraph - Print the graphics on the current window * vg - which graphics window to print */ void printGraph(short dnum) /* Which drawing to print */ { short h,v; /* used for centering (h=horiz. , v=vert.) */ short wh,wv; /* Window horiz and vert */ TPrStatus prStatus; /* Printing status record */ Rect prRect; /* the rectangle to print in */ TPPrPort prPort; /* the printing port */ short j; /* VG identifier for pass-through */ THPrint PrRecHandle; /* our print record handle */ PrRecHandle = PrintSetupRecord(); SetCursor(theCursors[normcurs]); if (PrJobDialog(PrRecHandle)) { /* Cancel the print if FALSE */ prPort=PrOpenDoc(PrRecHandle,0L,0L); /* Open Printer Port */ if (PrError() == 0) { /* If we can't, then die */ PrOpenPage(prPort, 0L); /* Open a page */ (*PrRecHandle)->prJob.pIdleProc = printsleepUPP; /* our sleep/cancel*/ prRect=PGRECT; /* Get the page rectangle */ h=prRect.right - prRect.left; /* Get the width */ v=prRect.bottom- prRect.top; /* Get the height */ if (3*h<4*v) { /* Center the little bugger */ wh = h; wv = (3 * h)/ 4; } else { /* On the page rectangle */ wv = v; wh = (4 * v)/ 3; } prRect.top = (v- wv) /2; prRect.left = (h- wh) /2; prRect.bottom = prRect.top + wv; prRect.right = prRect.left + wh; j=VGnewwin(TEK_DEVICE_PICTURE,VGgetVS(dnum)); /* NCSA 2.5: fixed the print call */ RGMPsize( &prRect ); VGzcpy( dnum, j); /* Love dat zm factr */ VGredraw(dnum,j); /* Copy the picture in i to j */ VGclose(j); /* OK, we're done, give it to someone else */ PrClosePage(prPort); /* Page out.... */ } PrCloseDoc(prPort); /* Done with the document */ putln("Doc is closed... the printing begins...."); if (PrError()==0) /* BYU 2.4.20 - changed for HP DeskWriter*/ PrPicFile(PrRecHandle,0L,0L,0L,&prStatus); /* Print the spooled file if applicable */ } /* if PrJobDialog */ DisposeHandle((Handle)PrRecHandle); updateCursor(1); } /* LU - this is the NEW PrintPages code. This handles page numbering, and also allows us to dump the redirected output to the printer. Written by Roland Mansson, Lund University Computing Center. Thank HIM for this code... */ /* Some patches had to be made to get it to compile under THINK C, and to work */ /* with some of the changes we have recently made. - SMB */ /* printPages(prPort,charh,title, columns) - * Prints on the printer through port with * using <columns>. */ void printPages(TPPrPort prPort, THPrint PrRecHandle, Str255 Title, short columns, char **charh, short refNum, short useTitle, short theScreen) { char *charp, *start; long charlen,count=0L; short v, h, scount, lines, pgcount, pgtmplen, maxlines; char pagetemp[20]; FMetricRec info; short pFheight, pFwidth; unsigned char buf[256]; /* to build a line in from the file */ unsigned char nextchar; /* next unprocessed char in file */ short rdy; short indent; /* indent to give reasonable left marginal */ OSErr sts; long dummyCount; char tmp[100]; /* only for debugging */ char stupidarray[160]; /* used in menuseg for finding string widths */ for (v=0; v<150; v++) stupidarray[v]='W'; /* Set up the width array */ indent = ((*PrRecHandle)->prInfo.iHRes * 180)/254; /* 1.8 centimeters left margin */ if (-PAPRECT.left > indent) indent = 0; else indent += PAPRECT.left; // if ( ((*PrRecHandle)->prStl.wDev>>8) == bDevCItoh ) { // /* Think about this: put def. font in rsrc fork- STR255 */ // TextFont(monaco); /* gives monaco on ImageWriters */ // v=9; // } // else { /* NCSA: SB - use current font */ TextFont((*(screens[theScreen].wind)).txFont); /* NCSA: SB */ TextFace((*(screens[theScreen].wind)).txFace); /* NCSA: SB */ v = (*(screens[theScreen].wind)).txSize; /* NCSA: SB */ // } /* NCSA: SB */ do { TextSize(v); FontMetrics( &info ); pFheight = FixRound( info.ascent + info.descent + info.leading); pFwidth = FixRound( info.widMax); //pFwidth = CharWidth('W'); /* Re-assign to largest char */ v--; } while ( TextWidth(stupidarray,0,columns+1) > (PGRECT.right - PGRECT.left - indent)); sprintf (tmp,"Fheight:%d, Fwidth:%d, TextSize:%d",pFheight,pFwidth,v+1); putln (tmp); if (charh!=NULL) { HLock(charh); start=charp=*charh; charlen= GetHandleSize(charh); } else { if ((sts=GetFPos(refNum, &charlen)) != noErr) { sprintf(tmp,"GetFPos: ERROR %d",(short)sts); putln(tmp); } charlen-=3; /* skip last 3 chars, as they are part of ESC seq */ if ((sts=SetFPos(refNum,(short) fsFromStart,0L)) != noErr) /* rewind to beginning of file */ { sprintf(tmp,"SetFPos: ERROR %d",sts); putln(tmp); } start = (char *)buf; /* always (the array doesn't move) */ dummyCount=1; if ((sts=FSRead(refNum,&dummyCount,&nextchar)) != noErr) /* get first char */ { sprintf(tmp,"FSRead: ERROR %d",sts); putln(tmp); } } h=PGRECT.right - PGRECT.left - indent; /* Get the width */ v=PGRECT.bottom- PGRECT.top; /* Get the height */ maxlines = v/pFheight-1; pgcount = 0; while (count<charlen) { pgcount++; lines = 1; PrOpenPage(prPort, 0L); /* Open the Printer Page */ if ((sts=PrError()) != noErr) { sprintf(tmp,"PrOpenPage: ERROR %d",sts); putln(tmp); } (*PrRecHandle)->prJob.pIdleProc= printsleepUPP; /* our netsleep */ sprintf (tmp,"printing page:%d",pgcount); putln(tmp); if (useTitle) { Str255 SessionNameString; GetIndString(SessionNameString,MISC_STRINGS,SESSION_NAME_STRING); MoveTo( indent, lines*pFheight); DrawString(SessionNameString); /* BYU LSC */ DrawString( Title); /* BYU LSC */ sprintf(pagetemp, "Page %d", pgcount); pgtmplen=strlen(pagetemp); MoveTo( PGRECT.right-(pgtmplen * pFwidth)-1, lines++*pFheight); DrawText( pagetemp, 0, pgtmplen); lines++; /* one blank line after title line */ } if (charh!=NULL) { /* print from handle */ while (lines <= maxlines && count<charlen) { scount=0; while ((count<charlen) && (*charp++!='\r')) { count++; scount++; } MoveTo(indent,lines++*pFheight); if (scount>0) DrawText(start, 0, scount); count++; start=charp; } } else { /* print from file */ while (lines <= maxlines && count<charlen) { rdy = 0; scount = 0; while ((count<charlen) && (!rdy)) { if (scount > 250) nextchar = ascLF; switch (nextchar) { case ascCR: rdy=1; break; case ascLF: rdy=1; break; case ascFF: rdy=1; break; default: buf[scount++]=nextchar; count++; dummyCount=1; if ((sts=FSRead (refNum,&dummyCount,&nextchar)) != noErr) { sprintf(tmp,"FSRead: ERROR %d",sts); putln(tmp); } break; } } MoveTo(indent,lines*pFheight); if (scount>0) DrawText(start, 0, scount); if (nextchar==ascLF) lines++; /* LF -> new line */ if (nextchar==ascFF) if (screens[theScreen].ignoreff) // RAB BetterTelnet 1.0fc8 lines++; else lines = maxlines+1; /* FF -> new page */ dummyCount=1; if ((sts=FSRead (refNum,&dummyCount,&nextchar)) != noErr) { sprintf(tmp,"FSRead: ERROR %d",sts); putln(tmp); } count++; } } PrClosePage(prPort); /* Close the Printer page */ if ((sts=PrError()) != noErr) { sprintf(tmp,"PrClosePage: ERROR %d",sts); putln(tmp); } } if (charh!=NULL) HUnlock(charh); } /* printText - Print the text selected on the screen * vs - which vs to print from */ void printText ( short vs, /* Which screen to print */ Str255 Title, /* The title string */ short scrn ) { char **charh; /* The character handle */ TPrStatus prStatus; /* Status record */ TPPrPort prPort; /* the Printer port */ THPrint PrRecHandle; /* our print record handle */ charh = RSGetTextSel(vs,0); /* Get the characters to print */ if ( charh==0L) return; /* don't print anything.... */ PrRecHandle = PrintSetupRecord(); SetCursor(theCursors[normcurs]); if (PrJobDialog(PrRecHandle)) { /* Cancel the print if FALSE */ prPort=PrOpenDoc(PrRecHandle,0L,0L); if (PrError() == 0) { printPages( prPort, PrRecHandle, Title, VSmaxwidth(vs), charh, (short) -1, TRUE,scrn); } PrCloseDoc(prPort); if (((*PrRecHandle)->prJob.bJDocLoop == bSpoolLoop) && (PrError()==0)) PrPicFile(PrRecHandle,0L,0L,0L,&prStatus); /* Spool the print */ } HPurge(charh); /* Kill the printed chars */ updateCursor(1); DisposeHandle((Handle)PrRecHandle); } void PrintPageSetup(void) { THPrint PrRecHandle; /* our print record handle */ PrOpen(); PrRecHandle = (THPrint)GetResource('JOHN',169); /* AISD: JSA */ if ( PrRecHandle != NULL ) { /* AISD: JSA */ PrStlDialog(PrRecHandle); /* AISD: JSA */ ChangedResource((Handle)PrRecHandle); /* AISD: JSA */ UpdateResFile(TelInfo->SettingsFile); /* AISD: JSA */ } /* AISD: JSA */ else { /* AISD: JSA */ PrRecHandle=(THPrint)myNewHandle((long)sizeof(TPrint)); /* AISD: JSA */ PrintDefault(PrRecHandle); /* AISD: JSA */ PrStlDialog(PrRecHandle); /* AISD: JSA */ UseResFile(TelInfo->SettingsFile); /* AISD: JSA */ AddResource((Handle)PrRecHandle,'JOHN',169,"\p"); /* AISD: JSA */ UpdateResFile(TelInfo->SettingsFile); /* AISD: JSA */ } /* AISD: JSA */ ReleaseResource((Handle)PrRecHandle); /* AISD: JSA */ PrClose(); } void PrintSelection(void) { short i; PrOpen(); i=RGgetdnum(FrontWindow()); if (i>-1) printGraph( i); /* Print Graphics */ else if ( (i=RSfindvwind(FrontWindow())) >-1 ) { Str255 Title; GetWTitle( FrontWindow(), Title); printText(i, Title,scrn); /* Print Text selection */ } PrClose(); } THPrint PrintSetupRecord(void) { THPrint PrRecHandle; PrRecHandle = (THPrint)GetResource('JOHN',169); /* AISD: JSA */ if ( PrRecHandle != NULL ) { PrValidate(PrRecHandle); DetachResource((Handle)PrRecHandle); } else { PrRecHandle=(THPrint)myNewHandle((long)sizeof(TPrint)); PrintDefault(PrRecHandle); } gPrRecHandle = PrRecHandle; return (PrRecHandle); } \ No newline at end of file +/* * printing.c * * This now contains the PrintPages() code from Roland Mansson, from Lund * University Computing Center. This allows for printer redirection, and also * printing page numbers (and other goodies). Thanks for all of your work! * * Code to handle printing. */ // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 #include "wind.h" #include "rsinterf.proto.h" /* For RSGetSelText */ #include "netevent.proto.h" #include "vgtek.proto.h" #include "rgmp.proto.h" #include "event.proto.h" #include "tekrgmac.proto.h" #include "vsdata.h" #include "vsinterf.proto.h" extern Cursor *theCursors[]; extern WindRec *screens; /* The screen array from Maclook */ extern short scrn; PROTO_UPP(printsleep, PrIdle); extern void printsleep(void); THPrint gPrRecHandle = NULL; #define PGRECT (*PrRecHandle)->prInfo.rPage /* Macro for making the pagerect more accessible */ #define VMARGINS 4 #define PAPRECT (*PrRecHandle)->rPaper /* Macro for making the paperrect more accessible */ #define bDevCItoh 1 /* from Printing.h */ #define ascLF 10 #define ascFF 12 #define ascCR 13 #include "printing.proto.h" void PrintingUnload(void) {} /* userabort - check to see if the user wants to abort */ short userabort(void) { EventRecord theEvent; while (GetNextEvent(24,&theEvent)) { if ((theEvent.modifiers & cmdKey) && (theEvent.message & 0xff) =='.') return(-1); } return(0); } /* printsleep() - Provide the network keep alive while we are in print * mode. Also set the abort flag if necessary. */ SIMPLE_UPP(printsleep, PrIdle); void printsleep(void) { short CurrentResFile; CurrentResFile = CurResFile(); /* Save the current resource file just in case. */ Stask(); /* act like the postman */ if (userabort()) (*gPrRecHandle)->prJob.fFromUsr=TRUE; UseResFile(CurrentResFile); /* Restore this in case we were bad and changed it. */ } /* printGraph - Print the graphics on the current window * vg - which graphics window to print */ void printGraph(short dnum) /* Which drawing to print */ { short h,v; /* used for centering (h=horiz. , v=vert.) */ short wh,wv; /* Window horiz and vert */ TPrStatus prStatus; /* Printing status record */ Rect prRect; /* the rectangle to print in */ TPPrPort prPort; /* the printing port */ short j; /* VG identifier for pass-through */ THPrint PrRecHandle; /* our print record handle */ PrRecHandle = PrintSetupRecord(); SetCursor(theCursors[normcurs]); if (PrJobDialog(PrRecHandle)) { /* Cancel the print if FALSE */ prPort=PrOpenDoc(PrRecHandle,0L,0L); /* Open Printer Port */ if (PrError() == 0) { /* If we can't, then die */ PrOpenPage(prPort, 0L); /* Open a page */ (*PrRecHandle)->prJob.pIdleProc = printsleepUPP; /* our sleep/cancel*/ prRect=PGRECT; /* Get the page rectangle */ h=prRect.right - prRect.left; /* Get the width */ v=prRect.bottom- prRect.top; /* Get the height */ if (3*h<4*v) { /* Center the little bugger */ wh = h; wv = (3 * h)/ 4; } else { /* On the page rectangle */ wv = v; wh = (4 * v)/ 3; } prRect.top = (v- wv) /2; prRect.left = (h- wh) /2; prRect.bottom = prRect.top + wv; prRect.right = prRect.left + wh; j=VGnewwin(TEK_DEVICE_PICTURE,VGgetVS(dnum)); /* NCSA 2.5: fixed the print call */ RGMPsize( &prRect ); VGzcpy( dnum, j); /* Love dat zm factr */ VGredraw(dnum,j); /* Copy the picture in i to j */ VGclose(j); /* OK, we're done, give it to someone else */ PrClosePage(prPort); /* Page out.... */ } PrCloseDoc(prPort); /* Done with the document */ putln("Doc is closed... the printing begins...."); if (PrError()==0) /* BYU 2.4.20 - changed for HP DeskWriter*/ PrPicFile(PrRecHandle,0L,0L,0L,&prStatus); /* Print the spooled file if applicable */ } /* if PrJobDialog */ DisposeHandle((Handle)PrRecHandle); updateCursor(1); } /* LU - this is the NEW PrintPages code. This handles page numbering, and also allows us to dump the redirected output to the printer. Written by Roland Mansson, Lund University Computing Center. Thank HIM for this code... */ /* Some patches had to be made to get it to compile under THINK C, and to work */ /* with some of the changes we have recently made. - SMB */ /* printPages(prPort,charh,title, columns) - * Prints <charh> on the printer through port <prPort> with <title> * using <columns>. */ void printPages(TPPrPort prPort, THPrint PrRecHandle, Str255 Title, short columns, char **charh, short refNum, short useTitle, short theScreen) { char *charp, *start; long charlen,count=0L; short v, h, scount, lines, pgcount, pgtmplen, maxlines; char pagetemp[20]; FMetricRec info; short pFheight, pFwidth; unsigned char buf[256]; /* to build a line in from the file */ unsigned char nextchar; /* next unprocessed char in file */ short rdy; short indent; /* indent to give reasonable left marginal */ OSErr sts; long dummyCount; char tmp[100]; /* only for debugging */ char stupidarray[160]; /* used in menuseg for finding string widths */ for (v=0; v<150; v++) stupidarray[v]='W'; /* Set up the width array */ indent = ((*PrRecHandle)->prInfo.iHRes * 180)/254; /* 1.8 centimeters left margin */ if (-PAPRECT.left > indent) indent = 0; else indent += PAPRECT.left; // if ( ((*PrRecHandle)->prStl.wDev>>8) == bDevCItoh ) { // /* Think about this: put def. font in rsrc fork- STR255 */ // TextFont(monaco); /* gives monaco on ImageWriters */ // v=9; // } // else { /* NCSA: SB - use current font */ TextFont((*(screens[theScreen].wind)).txFont); /* NCSA: SB */ TextFace((*(screens[theScreen].wind)).txFace); /* NCSA: SB */ v = (*(screens[theScreen].wind)).txSize; /* NCSA: SB */ // } /* NCSA: SB */ do { TextSize(v); FontMetrics( &info ); pFheight = FixRound( info.ascent + info.descent + info.leading); pFwidth = FixRound( info.widMax); //pFwidth = CharWidth('W'); /* Re-assign to largest char */ v--; } while ( TextWidth(stupidarray,0,columns+1) > (PGRECT.right - PGRECT.left - indent)); sprintf (tmp,"Fheight:%d, Fwidth:%d, TextSize:%d",pFheight,pFwidth,v+1); putln (tmp); if (charh!=NULL) { HLock(charh); start=charp=*charh; charlen= GetHandleSize(charh); } else { if ((sts=GetFPos(refNum, &charlen)) != noErr) { sprintf(tmp,"GetFPos: ERROR %d",(short)sts); putln(tmp); } charlen-=3; /* skip last 3 chars, as they are part of ESC seq */ if ((sts=SetFPos(refNum,(short) fsFromStart,0L)) != noErr) /* rewind to beginning of file */ { sprintf(tmp,"SetFPos: ERROR %d",sts); putln(tmp); } start = (char *)buf; /* always (the array doesn't move) */ dummyCount=1; if ((sts=FSRead(refNum,&dummyCount,&nextchar)) != noErr) /* get first char */ { sprintf(tmp,"FSRead: ERROR %d",sts); putln(tmp); } } h=PGRECT.right - PGRECT.left - indent; /* Get the width */ v=PGRECT.bottom- PGRECT.top; /* Get the height */ maxlines = v/pFheight-1; pgcount = 0; while (count<charlen) { pgcount++; lines = 1; PrOpenPage(prPort, 0L); /* Open the Printer Page */ if ((sts=PrError()) != noErr) { sprintf(tmp,"PrOpenPage: ERROR %d",sts); putln(tmp); } (*PrRecHandle)->prJob.pIdleProc= printsleepUPP; /* our netsleep */ sprintf (tmp,"printing page:%d",pgcount); putln(tmp); if (useTitle) { Str255 SessionNameString; GetIndString(SessionNameString,MISC_STRINGS,SESSION_NAME_STRING); MoveTo( indent, lines*pFheight); DrawString(SessionNameString); /* BYU LSC */ DrawString( Title); /* BYU LSC */ sprintf(pagetemp, "Page %d", pgcount); pgtmplen=strlen(pagetemp); MoveTo( PGRECT.right-(pgtmplen * pFwidth)-1, lines++*pFheight); DrawText( pagetemp, 0, pgtmplen); lines++; /* one blank line after title line */ } if (charh!=NULL) { /* print from handle */ while (lines <= maxlines && count<charlen) { scount=0; while ((count<charlen) && (*charp++!='\r')) { count++; scount++; } MoveTo(indent,lines++*pFheight); if (scount>0) DrawText(start, 0, scount); count++; start=charp; } } else { /* print from file */ while (lines <= maxlines && count<charlen) { rdy = 0; scount = 0; while ((count<charlen) && (!rdy)) { if (scount > 250) nextchar = ascLF; switch (nextchar) { case ascCR: rdy=1; break; case ascLF: rdy=1; break; case ascFF: rdy=1; break; default: buf[scount++]=nextchar; count++; dummyCount=1; if ((sts=FSRead (refNum,&dummyCount,&nextchar)) != noErr) { sprintf(tmp,"FSRead: ERROR %d",sts); putln(tmp); } break; } } MoveTo(indent,lines*pFheight); if (scount>0) DrawText(start, 0, scount); if (nextchar==ascLF) lines++; /* LF -> new line */ if (nextchar==ascFF) if (screens[theScreen].ignoreff) // RAB BetterTelnet 1.0fc8 lines++; else lines = maxlines+1; /* FF -> new page */ dummyCount=1; if ((sts=FSRead (refNum,&dummyCount,&nextchar)) != noErr) { sprintf(tmp,"FSRead: ERROR %d",sts); putln(tmp); } count++; } } PrClosePage(prPort); /* Close the Printer page */ if ((sts=PrError()) != noErr) { sprintf(tmp,"PrClosePage: ERROR %d",sts); putln(tmp); } } if (charh!=NULL) HUnlock(charh); } /* printText - Print the text selected on the screen * vs - which vs to print from */ void printText ( short vs, /* Which screen to print */ Str255 Title, /* The title string */ short scrn ) { char **charh; /* The character handle */ TPrStatus prStatus; /* Status record */ TPPrPort prPort; /* the Printer port */ THPrint PrRecHandle; /* our print record handle */ charh = RSGetTextSel(vs,0); /* Get the characters to print */ if ( charh==0L) return; /* don't print anything.... */ PrRecHandle = PrintSetupRecord(); SetCursor(theCursors[normcurs]); if (PrJobDialog(PrRecHandle)) { /* Cancel the print if FALSE */ prPort=PrOpenDoc(PrRecHandle,0L,0L); if (PrError() == 0) { printPages( prPort, PrRecHandle, Title, VSmaxwidth(vs), charh, (short) -1, TRUE,scrn); } PrCloseDoc(prPort); if (((*PrRecHandle)->prJob.bJDocLoop == bSpoolLoop) && (PrError()==0)) PrPicFile(PrRecHandle,0L,0L,0L,&prStatus); /* Spool the print */ } HPurge(charh); /* Kill the printed chars */ updateCursor(1); DisposeHandle((Handle)PrRecHandle); } void PrintPageSetup(void) { THPrint PrRecHandle; /* our print record handle */ PrOpen(); PrRecHandle = (THPrint)GetResource('JOHN',169); /* AISD: JSA */ if ( PrRecHandle != NULL ) { /* AISD: JSA */ PrStlDialog(PrRecHandle); /* AISD: JSA */ ChangedResource((Handle)PrRecHandle); /* AISD: JSA */ UpdateResFile(TelInfo->SettingsFile); /* AISD: JSA */ } /* AISD: JSA */ else { /* AISD: JSA */ PrRecHandle=(THPrint)myNewHandle((long)sizeof(TPrint)); /* AISD: JSA */ PrintDefault(PrRecHandle); /* AISD: JSA */ PrStlDialog(PrRecHandle); /* AISD: JSA */ UseResFile(TelInfo->SettingsFile); /* AISD: JSA */ AddResource((Handle)PrRecHandle,'JOHN',169,"\p"); /* AISD: JSA */ UpdateResFile(TelInfo->SettingsFile); /* AISD: JSA */ } /* AISD: JSA */ ReleaseResource((Handle)PrRecHandle); /* AISD: JSA */ PrClose(); } void PrintSelection(void) { short i; PrOpen(); i=RGgetdnum(FrontWindow()); if (i>-1) printGraph( i); /* Print Graphics */ else if ( (i=RSfindvwind(FrontWindow())) >-1 ) { Str255 Title; GetWTitle( FrontWindow(), Title); printText(i, Title,scrn); /* Print Text selection */ } PrClose(); } THPrint PrintSetupRecord(void) { THPrint PrRecHandle; PrRecHandle = (THPrint)GetResource('JOHN',169); /* AISD: JSA */ if ( PrRecHandle != NULL ) { PrValidate(PrRecHandle); DetachResource((Handle)PrRecHandle); } else { PrRecHandle=(THPrint)myNewHandle((long)sizeof(TPrint)); PrintDefault(PrRecHandle); } gPrRecHandle = PrRecHandle; return (PrRecHandle); } \ No newline at end of file diff --git a/source/ssh/sshglue.c b/source/ssh/sshglue.c new file mode 100755 index 0000000..1d54094 --- /dev/null +++ b/source/ssh/sshglue.c @@ -0,0 +1 @@ +// BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 // sshglue.c // glue code to support secure shell //#define WE_HAVE_SSH 1 #include "wind.h" #include "sshglue.proto.h" // prototypes for glued functions #ifdef WE_HAVE_SSH void ssh_protocol_initial(WindRec*); void ssh_packet_read(struct WindRec*, unsigned char*, short); void ssh_protocol_write(struct WindRec*, unsigned char*, short); void ssh_protocol_close(WindRec*); void ssh_randomize(void); #endif void ssh_glue_initial(WindRec* tw) { #ifdef WE_HAVE_SSH ssh_protocol_initial(tw); #endif } void ssh_glue_read(struct WindRec *tw, unsigned char *st, short cnt) { #ifdef WE_HAVE_SSH ssh_packet_read(tw, st, cnt); #endif } void ssh_glue_write(struct WindRec *tw, unsigned char *st, short cnt) { #ifdef WE_HAVE_SSH ssh_protocol_write(tw, st, cnt); #endif } void ssh_glue_close(WindRec* tw) { #ifdef WE_HAVE_SSH ssh_protocol_close(tw); #endif } void ssh_glue_randomize(void) { #ifdef WE_HAVE_SSH ssh_randomize(); #endif } short ssh_glue_installed(void) { #ifdef WE_HAVE_SSH return 1; #else return 0; #endif } \ No newline at end of file diff --git a/source/ssh/sshglue.proto.h b/source/ssh/sshglue.proto.h new file mode 100755 index 0000000..87a2726 --- /dev/null +++ b/source/ssh/sshglue.proto.h @@ -0,0 +1 @@ +void ssh_glue_initial(WindRec*); short ssh_glue_installed(void); void ssh_glue_write(struct WindRec*, unsigned char*, short); void ssh_glue_read(struct WindRec*, unsigned char*, short); void ssh_glue_close(WindRec*); void ssh_glue_randomize(void); \ No newline at end of file diff --git a/source/tek/rg0.c b/source/tek/rg0.c index 5680900..3a5a34e 100755 --- a/source/tek/rg0.c +++ b/source/tek/rg0.c @@ -1 +1 @@ -// BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* rgnull.c by Aaron Contorer for NCSA Copyright 1987, board of trustees, University of Illinois routines for "null" device -- calling these routines has no effect, but they are compatible with all RG calls. */ #ifdef MPW #pragma segment TEKNULL #endif #include "rg0.proto.h" void TEKNULLunload(void){} short RG0newwin(void) { return(0); } char *RG0devname(void) { return(nil); } void RG0oneshort(short x) { UNUSED_ARG(x) } void RG0void(void) {} short RG0returnshort(short x) { UNUSED_ARG(x) return 0; } short RG0pencolor(short w, short color) { UNUSED_ARG(w) UNUSED_ARG(color) return 0; } short RG0point(short w, short x, short y) { UNUSED_ARG(w) UNUSED_ARG(x) UNUSED_ARG(y) return 0; } short RG0drawline(short w, short a, short b, short c, short d) { UNUSED_ARG(w) UNUSED_ARG(a) UNUSED_ARG(b) UNUSED_ARG(c) UNUSED_ARG(d) return 0; } void RG0dataline(short w, short data, short count) { UNUSED_ARG(w) UNUSED_ARG(data) UNUSED_ARG(count) } void RG0charmode(short w, short rotation, short size) { UNUSED_ARG(w) UNUSED_ARG(rotation) UNUSED_ARG(size) } void RG0info(short w, short a, short b, short c, short d, short v) { UNUSED_ARG(w) UNUSED_ARG(a) UNUSED_ARG(b) UNUSED_ARG(c) UNUSED_ARG(d) UNUSED_ARG(v) } \ No newline at end of file +// BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* rgnull.c by Aaron Contorer for NCSA Copyright 1987, board of trustees, University of Illinois routines for "null" device -- calling these routines has no effect, but they are compatible with all RG calls. */ #include "rg0.proto.h" void TEKNULLunload(void){} short RG0newwin(void) { return(0); } char *RG0devname(void) { return(nil); } void RG0oneshort(short x) { UNUSED_ARG(x) } void RG0void(void) {} short RG0returnshort(short x) { UNUSED_ARG(x) return 0; } short RG0pencolor(short w, short color) { UNUSED_ARG(w) UNUSED_ARG(color) return 0; } short RG0point(short w, short x, short y) { UNUSED_ARG(w) UNUSED_ARG(x) UNUSED_ARG(y) return 0; } short RG0drawline(short w, short a, short b, short c, short d) { UNUSED_ARG(w) UNUSED_ARG(a) UNUSED_ARG(b) UNUSED_ARG(c) UNUSED_ARG(d) return 0; } void RG0dataline(short w, short data, short count) { UNUSED_ARG(w) UNUSED_ARG(data) UNUSED_ARG(count) } void RG0charmode(short w, short rotation, short size) { UNUSED_ARG(w) UNUSED_ARG(rotation) UNUSED_ARG(size) } void RG0info(short w, short a, short b, short c, short d, short v) { UNUSED_ARG(w) UNUSED_ARG(a) UNUSED_ARG(b) UNUSED_ARG(c) UNUSED_ARG(d) UNUSED_ARG(v) } \ No newline at end of file diff --git a/source/tek/rgmp.c b/source/tek/rgmp.c index eade487..920412e 100755 --- a/source/tek/rgmp.c +++ b/source/tek/rgmp.c @@ -1 +1 @@ -// BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* rgmp.c by Gaige B. Paulsen spawned from rgp.c by Aaron Contorer for NCSA Copyright 1987, board of trustees, University of Illinois Routines for Macintosh Picture output. Only one Real device is available */ #ifdef MPW #pragma segment TEKMacPic #endif #define INXMAX 4096 #define INYMAX 4096 #include "rgmp.proto.h" void TEKMacPicunload(void) {} char RGMPbusy; /* is device already in use */ short RGMPwidth, RGMPheight, RGMPxoffset=0, RGMPyoffset=0; int RGMPcolor[]= { 30, /* black */ 33, /* white */ 205, /* red */ 341, /* green */ 409, /* blue */ 273, /* cyan */ 137, /* magenta */ 69 /* yellow */ }; short RGMPnewwin(void) { RGMPbusy=1; /* RGMPwidth=4096; RGMPheight=4096; */ RGMPxoffset=0; RGMPyoffset=0; return(0); } char *RGMPdevname(void) { return("Macintosh PICTURE output"); } void RGMPinit(void) { RGMPbusy=0; /* RGMPwidth=4096; RGMPheight=4096; */ RGMPxoffset=0; RGMPyoffset=0; } short RGMPpencolor(short w, short color) { UNUSED_ARG(w) ForeColor( (long) RGMPcolor[color] ); return 0; } short RGMPclose(short w) { UNUSED_ARG(w) RGMPbusy=0; return 0; } short RGMPpoint(short w, short x, short y) { UNUSED_ARG(w) MoveTo(x,y); LineTo(x,y); return 0; } short RGMPdrawline(short w, short x0, short y0, short x1, short y1) { UNUSED_ARG(w) x0 = RGMPxoffset + (short) ((long) x0 * RGMPwidth / INXMAX); y0 = RGMPyoffset + RGMPheight - (short) ((long) y0 * RGMPheight / INYMAX); x1 = RGMPxoffset + (short) ((long) x1 * RGMPwidth/INXMAX); y1 = RGMPyoffset + RGMPheight - (short) ((long) y1 * RGMPheight / INYMAX); MoveTo(x0,y0); LineTo(x1,y1); return 0; } void RGMPinfo(short w, short v, short a, short b, short c, short d) { UNUSED_ARG(w) UNUSED_ARG(v) UNUSED_ARG(a) UNUSED_ARG(b) UNUSED_ARG(c) UNUSED_ARG(d) } void RGMPdataline(short blah, short blam, short bluh) { UNUSED_ARG(blah) UNUSED_ARG(blam) UNUSED_ARG(bluh) } void RGMPcharmode(short w, short rotation, short size) { UNUSED_ARG(w) UNUSED_ARG(rotation) UNUSED_ARG(size) } short RGMPsize(Rect *incoming) { RGMPheight= incoming->bottom-incoming->top; RGMPwidth = incoming->right - incoming->left; RGMPyoffset= incoming->top; RGMPxoffset= incoming->left; return(0); } \ No newline at end of file +// BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* rgmp.c by Gaige B. Paulsen spawned from rgp.c by Aaron Contorer for NCSA Copyright 1987, board of trustees, University of Illinois Routines for Macintosh Picture output. Only one Real device is available */ #define INXMAX 4096 #define INYMAX 4096 #include "rgmp.proto.h" void TEKMacPicunload(void) {} char RGMPbusy; /* is device already in use */ short RGMPwidth, RGMPheight, RGMPxoffset=0, RGMPyoffset=0; int RGMPcolor[]= { 30, /* black */ 33, /* white */ 205, /* red */ 341, /* green */ 409, /* blue */ 273, /* cyan */ 137, /* magenta */ 69 /* yellow */ }; short RGMPnewwin(void) { RGMPbusy=1; /* RGMPwidth=4096; RGMPheight=4096; */ RGMPxoffset=0; RGMPyoffset=0; return(0); } char *RGMPdevname(void) { return("Macintosh PICTURE output"); } void RGMPinit(void) { RGMPbusy=0; /* RGMPwidth=4096; RGMPheight=4096; */ RGMPxoffset=0; RGMPyoffset=0; } short RGMPpencolor(short w, short color) { UNUSED_ARG(w) ForeColor( (long) RGMPcolor[color] ); return 0; } short RGMPclose(short w) { UNUSED_ARG(w) RGMPbusy=0; return 0; } short RGMPpoint(short w, short x, short y) { UNUSED_ARG(w) MoveTo(x,y); LineTo(x,y); return 0; } short RGMPdrawline(short w, short x0, short y0, short x1, short y1) { UNUSED_ARG(w) x0 = RGMPxoffset + (short) ((long) x0 * RGMPwidth / INXMAX); y0 = RGMPyoffset + RGMPheight - (short) ((long) y0 * RGMPheight / INYMAX); x1 = RGMPxoffset + (short) ((long) x1 * RGMPwidth/INXMAX); y1 = RGMPyoffset + RGMPheight - (short) ((long) y1 * RGMPheight / INYMAX); MoveTo(x0,y0); LineTo(x1,y1); return 0; } void RGMPinfo(short w, short v, short a, short b, short c, short d) { UNUSED_ARG(w) UNUSED_ARG(v) UNUSED_ARG(a) UNUSED_ARG(b) UNUSED_ARG(c) UNUSED_ARG(d) } void RGMPdataline(short blah, short blam, short bluh) { UNUSED_ARG(blah) UNUSED_ARG(blam) UNUSED_ARG(bluh) } void RGMPcharmode(short w, short rotation, short size) { UNUSED_ARG(w) UNUSED_ARG(rotation) UNUSED_ARG(size) } short RGMPsize(Rect *incoming) { RGMPheight= incoming->bottom-incoming->top; RGMPwidth = incoming->right - incoming->left; RGMPyoffset= incoming->top; RGMPxoffset= incoming->left; return(0); } \ No newline at end of file diff --git a/source/tek/tekrgmac.c b/source/tek/tekrgmac.c index 7f8aacb..3b43ebc 100755 --- a/source/tek/tekrgmac.c +++ b/source/tek/tekrgmac.c @@ -1 +1 @@ -// BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* rgmac.c by Gaige B. Paulsen spawned from rgp.c by Aaron Contorer for NCSA Copyright 1987, board of trustees, University of Illinois Routines for Macintosh Window output. */ #ifdef MPW #pragma segment TEKMAIN #endif #include "tekrgmac.proto.h" #include "maclook.proto.h" #include "vgtek.proto.h" #include "mydnr.proto.h" #include "rsinterf.proto.h" #include "netevent.proto.h" #include "rg0.proto.h" #include "rgmp.proto.h" #include "InternalEvents.h" #include "tekdefs.h" /* NCSA: sb - all the TEK defines are now here */ //#define TEK_DEBUG1 #ifdef TEK_DEBUG1 #define TEK_DEBUG_PRINT(x) putln(x) char TEK_DEBUG_STRING [512]; #else #define TEK_DEBUG_PRINT(x) #endif /*--------------------------------------------------------------------------*/ /* Some variable definitions are needed before we give the code */ /* */ /*--------------------------------------------------------------------------*/ long RGMlastclick; short RGMcolor[]= { 30, /* black */ 33, /* white */ 205, /* red */ 341, /* green */ 409, /* blue */ 273, /* cyan */ 137, /* magenta */ 69 /* yellow */ }; struct RGMwindows *RGMwind[ MAXWIND ]; char *RGMdevname(void) { return("Macintosh Windows"); } short RGMnewwin(void) { short i = 0; while ((i < MAXWIND) && (RGMwind[i] != nil)) i++; if (i >= MAXWIND) return(-1); RGMwind[i] = (struct RGMwindows *) myNewPtr(sizeof(struct RGMwindows)); if (RGMwind[i] == nil) { return -1; } RGMwind[i]->id = 'RGMW'; RGMwind[i]->wind = GetNewWindow(256, NULL, kInFront); if (RGMwind[i]->wind == 0L) { DisposePtr((Ptr)RGMwind[i]); RGMwind[i] = nil; return -1; } ((WindowPeek)RGMwind[i]->wind)->windowKind = WIN_TEK; RGMwind[i]->vg = -1; /* BYU */ RGMwind[i]->vs = -1; /* BYU */ RGMwind[i]->xorigin = 0; RGMwind[i]->yorigin = 0; RGMwind[i]->xscale = WINXMAX; /* BYU LSC - need the "W" here */ RGMwind[i]->yscale = WINYMAX; /* BYU LSC - need the "W" here */ RGMwind[i]->width = 400; /* BYU LSC - was 256 (size of old window resource */ RGMwind[i]->height = 300; /* BYU LSC - was 342 (size of old window resource */ RGMwind[i]->ingin = 0; /* BYU LSC */ ValidRect(&RGMwind[i]->wind->portRect); return(i); } void RGMinit(void) { short i; for (i = 0; i < MAXWIND; i++) RGMwind[i] = nil; } short RGMgin(short w) { if (RGsetwind(w)) return(-1); setgraphcurs(); RGMwind[w]->ingin=1; } short RGMpencolor(short w, short color) { if (RGsetwind(w) ) return(-1); ForeColor((long) RGMcolor[color] ); #ifdef TEK_DEBUG_1 sprintf(TEK_DEBUG_STRING, "TEK: Setting pen color to %d", color); putln(TEK_DEBUG_STRING); #endif } short RGMclrscr(short w) { if (RGsetwind(w) ) return(-1); PaintRect(&RGMwind[w]->wind->portRect); TEK_DEBUG_PRINT("TEK: Clearing screen"); } short RGMclose(short w) { if (RGsetwind(w) ) return(-1); DisposeWindow(RGMwind[w]->wind); DisposePtr((Ptr)RGMwind[w]->name); DisposePtr((Ptr)RGMwind[w]); RGMwind[w] = nil; } short RGMpoint(short w, short x, short y) { if (RGsetwind(w) ) return(-1); MoveTo(x,y); LineTo(x,y); } short RGMdrawline(short w, short x0, short y0, short x1, short y1) { long xl0, yl0, xl1, yl1; if (RGsetwind(w) ) return(-1); xl0 = ((long)x0 * RGMwind[w]->width) / INXMAX; yl0 = (long)RGMwind[w]->height - (((long)y0 * RGMwind[w]->height) / INYMAX); xl1 = ((long)x1 * RGMwind[w]->width) / INXMAX; yl1 = (long)RGMwind[w]->height - (((long)y1 * RGMwind[w]->height) / INYMAX); MoveTo((short)xl0, (short)yl0); LineTo((short)xl1, (short)yl1); } void RGMinfo(short w, short v, short a, short b, short c, short d) { UNUSED_ARG(a) UNUSED_ARG(b) UNUSED_ARG(c) UNUSED_ARG(d) RGMwind[w]->vg=v; } void RGMpagedone(short w) { UNUSED_ARG(w) } void RGMdataline(short w, short data, short count) { UNUSED_ARG(w) UNUSED_ARG(data) UNUSED_ARG(count) } void RGMcharmode(short w, short rotation, short size) { UNUSED_ARG(w) UNUSED_ARG(rotation) UNUSED_ARG(size) } void RGMgmode(void) {} void RGMtmode(void) {} void RGMshowcur(void) { } void RGMlockcur(void) { } void RGMhidecur(void) { } void RGMbell(short w) { UNUSED_ARG(w) } void RGMuncover(short w) { UNUSED_ARG(w) } short RGMoutfunc(short (*f )()) { UNUSED_ARG(f) return(0); // Unused } short RGsetwind(short dnum) { if (dnum<0 || dnum>=MAXWIND) return(-1); if (RGMwind[dnum] == nil) return -1; SetPort( RGMwind[dnum]->wind); return(0); } short RGfindbyVG(short vg) { short i = 0; while (i < MAXWIND) { if (RGMwind[i] != nil) { if (RGMwind[i]->vg == vg) break; } i++; } if (i >= MAXWIND) return(-1); return(i); } short RGattach(short vg, short virt, char *name, short TEKtype) { short dnum; unsigned long time; char myname[256],ts[256]; if ((dnum = RGfindbyVG(vg)) < 0) return(-1); RGMwind[dnum]->vs = virt; RGMwind[dnum]->name = (unsigned char *) myNewPtr((long) 256); /* BYU LSC */ if (RGMwind[dnum]->name == 0L) return(-2); myname[0] = ''; if (TEKtype) strcpy(&myname[1], "[4105] "); else strcpy(&myname[1], "[4014] "); strncpy(&myname[strlen(myname)],name,120); GetDateTime(&time); IUTimeString(time,FALSE,(StringPtr) ts); /* BYU LSC - Put time in the temp string */ p2cstr((StringPtr)ts); /* BYU LSC */ strncat(myname," ",2); /* BYU - was 4 - Space, please */ strncat(myname,ts,64); /* BYU - Place the time string at the end */ strcpy((char *) RGMwind[dnum]->name,myname); /* BYU LSC */ if (RGMwind[dnum]->wind != (GrafPtr) 0) { /* BYU LSC */ c2pstr(myname); /* BYU LSC */ SetWTitle(RGMwind[dnum]->wind,(StringPtr)myname); /* BYU LSC */ } return(0); } short RGdetach( short vg) { short dnum; /* BYU */ char myname[256]; /* BYU LSC */ if ((dnum = RGfindbyVG(vg)) < 0) return(-1); /* BYU */ if (dnum >= MAXWIND) return(-1); /* BYU */ if (RGMwind[dnum]->vs != -1) { /* BYU */ if (RGMwind[dnum]->wind != (GrafPtr) 0) { /* BYU */ #if 1 strncpy((char *) RGMwind[dnum]->name, /* BYU LSC */ (char *) &RGMwind[dnum]->name[1],255); /* BYU LSC */ strncpy(myname, (char *) RGMwind[dnum]->name,256); /* BYU LSC */ c2pstr(myname); /* BYU LSC */ SetWTitle(RGMwind[dnum]->wind,(StringPtr)myname); /* BYU LSC */ #else strncpy((char *) RGMwind[dnum]->name, /* BYU LSC */ (char *) &RGMwind[dnum]->name[1],255); /* BYU LSC */ SetWTitle(RGMwind[dnum]->wind,RGMwind[dnum]->name); /* BYU LSC */ #endif } /* BYU */ } /* BYU */ return(0); /* BYU */ } short RGfindbywind( GrafPtr wind) { short i = 0; while (i < MAXWIND) { if (RGMwind[i] != nil) { if (RGMwind[i]->wind == wind) break; } i++; } if (i >= MAXWIND) return(-1); return(i); } short RGupdate( GrafPtr wind) { short i = 0, done; if ((i = RGfindbywind(wind)) < 0) return(-1); SetPort(wind); BeginUpdate(wind); VGstopred(RGMwind[i]->vg); VGpage(RGMwind[i]->vg); done = VGpred(RGMwind[i]->vg,RGMwind[i]->vg); EndUpdate(wind); if (!done) netputevent(USERCLASS,RG_REDRAW,RGMwind[i]->vg,0); return(done); } short RGsupdate( short i) { short rg; rg = RGfindbyVG(i); if (rg < 0) return(0); SetPort(RGMwind[rg]->wind); if (!VGpred(RGMwind[rg]->vg,RGMwind[rg]->vg)) { netputevent(USERCLASS,RG_REDRAW,i,0); } else return(1); return(0); } short RGgetVG(GrafPtr wind) { short i; i = RGfindbywind(wind); return(RGMwind[i]->vg); } short RGgetdnum(GrafPtr wind) { return(RGfindbywind(wind)); } short RGgetVS(short dnum) { return(RGMwind[dnum]->vs); } short inSplash(Point *p1, Point *p2) { if ((p1->h - p2->h > 3) || (p2->h - p1->h > 3)) return(0); if ((p1->v - p2->v > 3) || (p2->v - p1->v > 3)) return(0); return(1); } void VidSync( void) { long a; a = TickCount(); /* BYU LSC */ while (a == TickCount()) /* loop*/; /* BYU LSC */ } void RGmousedown ( GrafPtr wind, Point *wherein ) { unsigned long lx,ly; /* NCSA: SB */ char thispaceforent[6]; short i; Point where; char dum[32]; where = *wherein; if ((i = RGfindbywind(wind)) < 0) return; if (!RGMwind[i]->ingin) { Point anchor,current,last; #if 0 /* BYU LSC - was "#ifndef MPW" */ long TickCount(); #endif MPW long tc; short x0,y0,x1,y1; Rect rect; SetPort(wind); last = where; current = where; anchor = where; PenPat(PATTERN(qd.gray)); PenMode(patXor); SetRect(&rect,0,0,0,0); while (StillDown()) { GetMouse(¤t); if (inSplash(¤t,&anchor)) continue; tc = TickCount(); while(TickCount() == tc) /* loop */; VidSync(); FrameRect(&rect); if (anchor.v < current.v) { rect.top = anchor.v; rect.bottom = current.v; } else { rect.top = current.v; rect.bottom = anchor.v; } if (anchor.h < current.h) { rect.left = anchor.h; rect.right = current.h; } else { rect.right = anchor.h; rect.left = current.h; } FrameRect(&rect); last = current; } FrameRect(&rect); PenPat(PATTERN(qd.black)); PenMode(patCopy); if (!inSplash(&anchor,¤t)) { x0 = (short) ((long) rect.left * RGMwind[i]->xscale / RGMwind[i]->width ); y0 = (short) (RGMwind[i]->yscale - (long) rect.top * RGMwind[i]->yscale / RGMwind[i]->height); x1 = (short) ((long) rect.right * RGMwind[i]->xscale / RGMwind[i]->width); y1 = (short) (RGMwind[i]->yscale - (long) rect.bottom * RGMwind[i]->yscale / RGMwind[i]->height); x1 = (x1 < x0+2) ? x0 + 4 : x1; y0 = (y0 < y1+2) ? y1 + 4 : y0; VGzoom( i, x0 + RGMwind[i]->xorigin, y1 + RGMwind[i]->yorigin, x1 + RGMwind[i]->xorigin, y0 + RGMwind[i]->yorigin); VGpage(RGMwind[i]->vg); RGMwind[i]->xscale = x1 - x0; RGMwind[i]->yscale = y0 - y1; RGMwind[i]->xorigin = x0 + RGMwind[i]->xorigin; RGMwind[i]->yorigin = y1 + RGMwind[i]->yorigin; while(!VGpred(RGMwind[i]->vg,RGMwind[i]->vg)) Stask(); RGMlastclick = 0L; } else { if (RGMlastclick && ((RGMlastclick + GetDblTime()) > TickCount())) { RGMwind[i]->xscale = WINXMAX; /* BYU LSC - need the "W" here */ RGMwind[i]->yscale = WINYMAX; /* BYU LSC - need the "W" here */ RGMwind[i]->xorigin = 0; RGMwind[i]->yorigin = 0; VGzoom(i,0,0,WINXMAX-1,WINYMAX-1); /* BYU LSC - need the "W" here */ VGpage( RGMwind[i]->vg); while(!VGpred(RGMwind[i]->vg,RGMwind[i]->vg)) Stask(); RGMlastclick = 0L; } else RGMlastclick = TickCount(); } return; } /* NCSA: SB */ /* NCSA: SB - These computations are being truncated and turned into signed ints. */ /* NCSA: SB - Just make sure everything is cast correctly, and were fine */ lx = ((unsigned long)RGMwind[i]->xscale * (unsigned long)where.h) /* NCSA: SB */ / (unsigned long)RGMwind[i]->width; /* NCSA: SB */ ly = (unsigned long)RGMwind[i]->yscale - /* NCSA: SB */ ((unsigned long)RGMwind[i]->yscale * (unsigned long)where.v) / (unsigned long)RGMwind[i]->height; /* NCSA: SB */ VGgindata(RGMwind[i]->vg,(unsigned short) lx,(unsigned short)ly,' ',thispaceforent); /* NCSA: SB */ #if 0 /* BYU LSC - not needed */ sprintf(dum,"GIN i: %d, vs: %d\015",i,RGMwind[i]->vs); /* BYU 2.4.18 - changed \n to \015 */ putln(dum); #endif /* BYU LSC - not needed */ RSsendstring(RGMwind[i]->vs,thispaceforent,5); sprintf(dum," \r\n"); RSsendstring(RGMwind[i]->vs,dum,3); /* RGMwind[i]->ingin = 0; */ unsetgraphcurs(); RGMlastclick = TickCount(); } /*--------------------------------------------------------------------------*/ /* NCSA: SB - RGMgrowme */ /* This allows the TEK window to be grown like any other real window. */ /* The grow box is not shown on the screen, but it acts accordingly - SMB */ /*--------------------------------------------------------------------------*/ void RGMgrowme(short myRGMnum,GrafPtr window, long *where, short modifiers) { UNUSED_ARG(modifiers) long size; Rect SizRect; SetRect(&SizRect, 50, 50, 1500, 1500); /* NCSA: SB - max size - arbitrary */ if (where) { size = GrowWindow(window, *(Point *) where, &SizRect); if (size != 0L) { SizeWindow(window, size & 0xffff, (size >> 16) & 0xffff, FALSE); RGMwind[myRGMnum]->width = window->portRect.right - window->portRect.left; RGMwind[myRGMnum]->height = window->portRect.bottom - window->portRect.top; VGpage(RGMwind[myRGMnum]->vg); InvalRect(&window->portRect); RGupdate(window); } else return; /* user skipped growing */ } } \ No newline at end of file +// BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* rgmac.c by Gaige B. Paulsen spawned from rgp.c by Aaron Contorer for NCSA Copyright 1987, board of trustees, University of Illinois Routines for Macintosh Window output. */ #include "tekrgmac.proto.h" #include "maclook.proto.h" #include "vgtek.proto.h" #include "mydnr.proto.h" #include "rsinterf.proto.h" #include "netevent.proto.h" #include "rg0.proto.h" #include "rgmp.proto.h" #include "InternalEvents.h" #include "tekdefs.h" /* NCSA: sb - all the TEK defines are now here */ //#define TEK_DEBUG1 #ifdef TEK_DEBUG1 #define TEK_DEBUG_PRINT(x) putln(x) char TEK_DEBUG_STRING [512]; #else #define TEK_DEBUG_PRINT(x) #endif /*--------------------------------------------------------------------------*/ /* Some variable definitions are needed before we give the code */ /* */ /*--------------------------------------------------------------------------*/ long RGMlastclick; short RGMcolor[]= { 30, /* black */ 33, /* white */ 205, /* red */ 341, /* green */ 409, /* blue */ 273, /* cyan */ 137, /* magenta */ 69 /* yellow */ }; struct RGMwindows *RGMwind[ MAXWIND ]; char *RGMdevname(void) { return("Macintosh Windows"); } short RGMnewwin(void) { short i = 0; while ((i < MAXWIND) && (RGMwind[i] != nil)) i++; if (i >= MAXWIND) return(-1); RGMwind[i] = (struct RGMwindows *) myNewPtr(sizeof(struct RGMwindows)); if (RGMwind[i] == nil) { return -1; } RGMwind[i]->id = 'RGMW'; RGMwind[i]->wind = GetNewWindow(256, NULL, kInFront); if (RGMwind[i]->wind == 0L) { DisposePtr((Ptr)RGMwind[i]); RGMwind[i] = nil; return -1; } ((WindowPeek)RGMwind[i]->wind)->windowKind = WIN_TEK; RGMwind[i]->vg = -1; /* BYU */ RGMwind[i]->vs = -1; /* BYU */ RGMwind[i]->xorigin = 0; RGMwind[i]->yorigin = 0; RGMwind[i]->xscale = WINXMAX; /* BYU LSC - need the "W" here */ RGMwind[i]->yscale = WINYMAX; /* BYU LSC - need the "W" here */ RGMwind[i]->width = 400; /* BYU LSC - was 256 (size of old window resource */ RGMwind[i]->height = 300; /* BYU LSC - was 342 (size of old window resource */ RGMwind[i]->ingin = 0; /* BYU LSC */ ValidRect(&RGMwind[i]->wind->portRect); return(i); } void RGMinit(void) { short i; for (i = 0; i < MAXWIND; i++) RGMwind[i] = nil; } short RGMgin(short w) { if (RGsetwind(w)) return(-1); setgraphcurs(); RGMwind[w]->ingin=1; } short RGMpencolor(short w, short color) { if (RGsetwind(w) ) return(-1); ForeColor((long) RGMcolor[color] ); #ifdef TEK_DEBUG_1 sprintf(TEK_DEBUG_STRING, "TEK: Setting pen color to %d", color); putln(TEK_DEBUG_STRING); #endif } short RGMclrscr(short w) { if (RGsetwind(w) ) return(-1); PaintRect(&RGMwind[w]->wind->portRect); TEK_DEBUG_PRINT("TEK: Clearing screen"); } short RGMclose(short w) { if (RGsetwind(w) ) return(-1); DisposeWindow(RGMwind[w]->wind); DisposePtr((Ptr)RGMwind[w]->name); DisposePtr((Ptr)RGMwind[w]); RGMwind[w] = nil; } short RGMpoint(short w, short x, short y) { if (RGsetwind(w) ) return(-1); MoveTo(x,y); LineTo(x,y); } short RGMdrawline(short w, short x0, short y0, short x1, short y1) { long xl0, yl0, xl1, yl1; if (RGsetwind(w) ) return(-1); xl0 = ((long)x0 * RGMwind[w]->width) / INXMAX; yl0 = (long)RGMwind[w]->height - (((long)y0 * RGMwind[w]->height) / INYMAX); xl1 = ((long)x1 * RGMwind[w]->width) / INXMAX; yl1 = (long)RGMwind[w]->height - (((long)y1 * RGMwind[w]->height) / INYMAX); MoveTo((short)xl0, (short)yl0); LineTo((short)xl1, (short)yl1); } void RGMinfo(short w, short v, short a, short b, short c, short d) { UNUSED_ARG(a) UNUSED_ARG(b) UNUSED_ARG(c) UNUSED_ARG(d) RGMwind[w]->vg=v; } void RGMpagedone(short w) { UNUSED_ARG(w) } void RGMdataline(short w, short data, short count) { UNUSED_ARG(w) UNUSED_ARG(data) UNUSED_ARG(count) } void RGMcharmode(short w, short rotation, short size) { UNUSED_ARG(w) UNUSED_ARG(rotation) UNUSED_ARG(size) } void RGMgmode(void) {} void RGMtmode(void) {} void RGMshowcur(void) { } void RGMlockcur(void) { } void RGMhidecur(void) { } void RGMbell(short w) { UNUSED_ARG(w) } void RGMuncover(short w) { UNUSED_ARG(w) } short RGMoutfunc(short (*f )()) { UNUSED_ARG(f) return(0); // Unused } short RGsetwind(short dnum) { if (dnum<0 || dnum>=MAXWIND) return(-1); if (RGMwind[dnum] == nil) return -1; SetPort( RGMwind[dnum]->wind); return(0); } short RGfindbyVG(short vg) { short i = 0; while (i < MAXWIND) { if (RGMwind[i] != nil) { if (RGMwind[i]->vg == vg) break; } i++; } if (i >= MAXWIND) return(-1); return(i); } short RGattach(short vg, short virt, char *name, short TEKtype) { short dnum; unsigned long time; char myname[256],ts[256]; if ((dnum = RGfindbyVG(vg)) < 0) return(-1); RGMwind[dnum]->vs = virt; RGMwind[dnum]->name = (unsigned char *) myNewPtr((long) 256); /* BYU LSC */ if (RGMwind[dnum]->name == 0L) return(-2); myname[0] = ''; if (TEKtype) strcpy(&myname[1], "[4105] "); else strcpy(&myname[1], "[4014] "); strncpy(&myname[strlen(myname)],name,120); GetDateTime(&time); IUTimeString(time,FALSE,(StringPtr) ts); /* BYU LSC - Put time in the temp string */ p2cstr((StringPtr)ts); /* BYU LSC */ strncat(myname," ",2); /* BYU - was 4 - Space, please */ strncat(myname,ts,64); /* BYU - Place the time string at the end */ strcpy((char *) RGMwind[dnum]->name,myname); /* BYU LSC */ if (RGMwind[dnum]->wind != (GrafPtr) 0) { /* BYU LSC */ c2pstr(myname); /* BYU LSC */ SetWTitle(RGMwind[dnum]->wind,(StringPtr)myname); /* BYU LSC */ } return(0); } short RGdetach( short vg) { short dnum; /* BYU */ char myname[256]; /* BYU LSC */ if ((dnum = RGfindbyVG(vg)) < 0) return(-1); /* BYU */ if (dnum >= MAXWIND) return(-1); /* BYU */ if (RGMwind[dnum]->vs != -1) { /* BYU */ if (RGMwind[dnum]->wind != (GrafPtr) 0) { /* BYU */ #if 1 strncpy((char *) RGMwind[dnum]->name, /* BYU LSC */ (char *) &RGMwind[dnum]->name[1],255); /* BYU LSC */ strncpy(myname, (char *) RGMwind[dnum]->name,256); /* BYU LSC */ c2pstr(myname); /* BYU LSC */ SetWTitle(RGMwind[dnum]->wind,(StringPtr)myname); /* BYU LSC */ #else strncpy((char *) RGMwind[dnum]->name, /* BYU LSC */ (char *) &RGMwind[dnum]->name[1],255); /* BYU LSC */ SetWTitle(RGMwind[dnum]->wind,RGMwind[dnum]->name); /* BYU LSC */ #endif } /* BYU */ } /* BYU */ return(0); /* BYU */ } short RGfindbywind( GrafPtr wind) { short i = 0; while (i < MAXWIND) { if (RGMwind[i] != nil) { if (RGMwind[i]->wind == wind) break; } i++; } if (i >= MAXWIND) return(-1); return(i); } short RGupdate( GrafPtr wind) { short i = 0, done; if ((i = RGfindbywind(wind)) < 0) return(-1); SetPort(wind); BeginUpdate(wind); VGstopred(RGMwind[i]->vg); VGpage(RGMwind[i]->vg); done = VGpred(RGMwind[i]->vg,RGMwind[i]->vg); EndUpdate(wind); if (!done) netputevent(USERCLASS,RG_REDRAW,RGMwind[i]->vg,0); return(done); } short RGsupdate( short i) { short rg; rg = RGfindbyVG(i); if (rg < 0) return(0); SetPort(RGMwind[rg]->wind); if (!VGpred(RGMwind[rg]->vg,RGMwind[rg]->vg)) { netputevent(USERCLASS,RG_REDRAW,i,0); } else return(1); return(0); } short RGgetVG(GrafPtr wind) { short i; i = RGfindbywind(wind); return(RGMwind[i]->vg); } short RGgetdnum(GrafPtr wind) { return(RGfindbywind(wind)); } short RGgetVS(short dnum) { return(RGMwind[dnum]->vs); } short inSplash(Point *p1, Point *p2) { if ((p1->h - p2->h > 3) || (p2->h - p1->h > 3)) return(0); if ((p1->v - p2->v > 3) || (p2->v - p1->v > 3)) return(0); return(1); } void VidSync( void) { long a; a = TickCount(); /* BYU LSC */ while (a == TickCount()) /* loop*/; /* BYU LSC */ } void RGmousedown ( GrafPtr wind, Point *wherein ) { unsigned long lx,ly; /* NCSA: SB */ char thispaceforent[6]; short i; Point where; char dum[32]; where = *wherein; if ((i = RGfindbywind(wind)) < 0) return; if (!RGMwind[i]->ingin) { Point anchor,current,last; #if 0 /* BYU LSC - was "#ifndef MPW" */ long TickCount(); #endif MPW long tc; short x0,y0,x1,y1; Rect rect; SetPort(wind); last = where; current = where; anchor = where; PenPat(PATTERN(qd.gray)); PenMode(patXor); SetRect(&rect,0,0,0,0); while (StillDown()) { GetMouse(¤t); if (inSplash(¤t,&anchor)) continue; tc = TickCount(); while(TickCount() == tc) /* loop */; VidSync(); FrameRect(&rect); if (anchor.v < current.v) { rect.top = anchor.v; rect.bottom = current.v; } else { rect.top = current.v; rect.bottom = anchor.v; } if (anchor.h < current.h) { rect.left = anchor.h; rect.right = current.h; } else { rect.right = anchor.h; rect.left = current.h; } FrameRect(&rect); last = current; } FrameRect(&rect); PenPat(PATTERN(qd.black)); PenMode(patCopy); if (!inSplash(&anchor,¤t)) { x0 = (short) ((long) rect.left * RGMwind[i]->xscale / RGMwind[i]->width ); y0 = (short) (RGMwind[i]->yscale - (long) rect.top * RGMwind[i]->yscale / RGMwind[i]->height); x1 = (short) ((long) rect.right * RGMwind[i]->xscale / RGMwind[i]->width); y1 = (short) (RGMwind[i]->yscale - (long) rect.bottom * RGMwind[i]->yscale / RGMwind[i]->height); x1 = (x1 < x0+2) ? x0 + 4 : x1; y0 = (y0 < y1+2) ? y1 + 4 : y0; VGzoom( i, x0 + RGMwind[i]->xorigin, y1 + RGMwind[i]->yorigin, x1 + RGMwind[i]->xorigin, y0 + RGMwind[i]->yorigin); VGpage(RGMwind[i]->vg); RGMwind[i]->xscale = x1 - x0; RGMwind[i]->yscale = y0 - y1; RGMwind[i]->xorigin = x0 + RGMwind[i]->xorigin; RGMwind[i]->yorigin = y1 + RGMwind[i]->yorigin; while(!VGpred(RGMwind[i]->vg,RGMwind[i]->vg)) Stask(); RGMlastclick = 0L; } else { if (RGMlastclick && ((RGMlastclick + GetDblTime()) > TickCount())) { RGMwind[i]->xscale = WINXMAX; /* BYU LSC - need the "W" here */ RGMwind[i]->yscale = WINYMAX; /* BYU LSC - need the "W" here */ RGMwind[i]->xorigin = 0; RGMwind[i]->yorigin = 0; VGzoom(i,0,0,WINXMAX-1,WINYMAX-1); /* BYU LSC - need the "W" here */ VGpage( RGMwind[i]->vg); while(!VGpred(RGMwind[i]->vg,RGMwind[i]->vg)) Stask(); RGMlastclick = 0L; } else RGMlastclick = TickCount(); } return; } /* NCSA: SB */ /* NCSA: SB - These computations are being truncated and turned into signed ints. */ /* NCSA: SB - Just make sure everything is cast correctly, and were fine */ lx = ((unsigned long)RGMwind[i]->xscale * (unsigned long)where.h) /* NCSA: SB */ / (unsigned long)RGMwind[i]->width; /* NCSA: SB */ ly = (unsigned long)RGMwind[i]->yscale - /* NCSA: SB */ ((unsigned long)RGMwind[i]->yscale * (unsigned long)where.v) / (unsigned long)RGMwind[i]->height; /* NCSA: SB */ VGgindata(RGMwind[i]->vg,(unsigned short) lx,(unsigned short)ly,' ',thispaceforent); /* NCSA: SB */ #if 0 /* BYU LSC - not needed */ sprintf(dum,"GIN i: %d, vs: %d\015",i,RGMwind[i]->vs); /* BYU 2.4.18 - changed \n to \015 */ putln(dum); #endif /* BYU LSC - not needed */ RSsendstring(RGMwind[i]->vs,thispaceforent,5); sprintf(dum," \r\n"); RSsendstring(RGMwind[i]->vs,dum,3); /* RGMwind[i]->ingin = 0; */ unsetgraphcurs(); RGMlastclick = TickCount(); } /*--------------------------------------------------------------------------*/ /* NCSA: SB - RGMgrowme */ /* This allows the TEK window to be grown like any other real window. */ /* The grow box is not shown on the screen, but it acts accordingly - SMB */ /*--------------------------------------------------------------------------*/ void RGMgrowme(short myRGMnum,GrafPtr window, long *where, short modifiers) { UNUSED_ARG(modifiers) long size; Rect SizRect; SetRect(&SizRect, 50, 50, 1500, 1500); /* NCSA: SB - max size - arbitrary */ if (where) { size = GrowWindow(window, *(Point *) where, &SizRect); if (size != 0L) { SizeWindow(window, size & 0xffff, (size >> 16) & 0xffff, FALSE); RGMwind[myRGMnum]->width = window->portRect.right - window->portRect.left; RGMwind[myRGMnum]->height = window->portRect.bottom - window->portRect.top; VGpage(RGMwind[myRGMnum]->vg); InvalRect(&window->portRect); RGupdate(window); } else return; /* user skipped growing */ } } \ No newline at end of file diff --git a/source/tek/tekstor.c b/source/tek/tekstor.c index afee67f..eb3f69d 100755 --- a/source/tek/tekstor.c +++ b/source/tek/tekstor.c @@ -1 +1 @@ -// tekstor.c // BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* This has been rewritten to use one damn handle to hold all of the data. -- JMB */ #ifdef MPW #pragma segment TEKMAIN #endif #include "vgtek.proto.h" #include "rg0.proto.h" #include "rgmp.proto.h" #include "tekrgmac.proto.h" #include "tekdefs.h" /* NCSA: sb - all defines are now here, for easy access */ #include "tekstor.proto.h" // thiselnum runs from 0 to (handlesize-1), which is in accordance with C style // arrays. The handle is indexed 0...(handlesize-1) as well. This is why you see // the various +-1's. -- JMB 8/93 TEKSTOREP newTEKstore(void) { TEKSTOREP s; s = (TEKSTOREP) myNewPtr(sizeof(TEKSTORE)); if (s == NULL) return (NULL); if (!(s->dataHandle = myNewHandle(0L))) return (NULL); s->thiselnum = 0; return(s); } void freeTEKstore(TEKSTOREP s) { DisposeHandle(s->dataHandle); DisposePtr((Ptr) s); } short addTEKstore(TEKSTOREP s, char d) { Size handlesize; OSErr memErr; handlesize = GetHandleSize(s->dataHandle); memErr = mySetHandleSize(s->dataHandle, ++handlesize); if (memErr) return (-1); (*(s->dataHandle))[handlesize-1] = d; // Save in last position return(0); } void topTEKstore(TEKSTOREP s) { s->thiselnum = 0; } short nextTEKitem(TEKSTOREP s) { if (s->thiselnum == (GetHandleSize(s->dataHandle))) return(-1); // At end of data return((short) ((*(s->dataHandle))[(s->thiselnum)++]) ); } short TEKunstore(TEKSTOREP s) { Size handlesize; OSErr memErr; if ((handlesize = GetHandleSize(s->dataHandle)) == 0) return (-1); // Nothing in store memErr = mySetHandleSize(s->dataHandle, --handlesize); if (memErr) return(-1); if (s->thiselnum >= handlesize) s->thiselnum = handlesize - 1; return(0); } #ifdef AARON_CONTORER_HAS_A_BRAIN // Never true #define MINPOOL 0x0200 /* smallest allowable pool */ #define MAXPOOL 0x2000 /* largest allowable pool */ STOREP newstore(void) /* create a new, empty store and return a pointer to it. Returns NULL if not enough memory to create a new store. */ { STOREP s; s=(STOREP) myNewPtr((long) sizeof(STORE)); /* BYU LSC */ if (s==NULL) { return(NULL); } else { s->lasth = s->thish = s->firsth = (HANDLEP) myNewPtr((long) sizeof(HANDLE)); /* BYU LSC */ if (s->firsth==NULL) { DisposPtr((Ptr) s); return(NULL); } else { s->firsth->pool = myNewPtr((long) MINPOOL); /* BYU LSC */ if (s->firsth->pool==NULL) { DisposPtr((Ptr) s->firsth); DisposPtr((Ptr) s); return(NULL); } else { s->lastelnum = s->thiselnum = -1; s->firsth->poolsize = MINPOOL; s->firsth->next = NULL; } } } return(s); } void freestore(STOREP s) /* Frees all pools and other memory space associated with store s. */ { HANDLEP h,h2; h = s->firsth; while (h != NULL) { h2 = h; DisposPtr(h->pool); h = h->next; DisposPtr((Ptr) h2); } DisposPtr((Ptr) s); } int addstore(STOREP s, char d) /* Adds character d to the end of store s. Returns 0 if successful, -1 if unable to add character (no memory). */ { int n; /* temp storage */ long size; /* BYU LSC */ HANDLEP h; n = ++(s->lastelnum); size = s->lasth->poolsize; if (n < s->lasth->poolsize) { s->lasth->pool[n] = d; } else { /* Pool full; allocate a new one. */ if (size<MAXPOOL) size <<= 1; h = (HANDLEP)myNewPtr((long) sizeof(HANDLE)); /* BYU LSC */ if (h==NULL) { (s->lastelnum)--; return(-1); } else { h->pool = myNewPtr(size); if (h->pool==NULL) { DisposPtr((Ptr) h); (s->lastelnum)--; return(-1); } else { h->poolsize = size; h->next = NULL; s->lasth->next = h; s->lasth = h; s->lastelnum = 0; h->pool[0] = d; } } } /* end of new pool allocation */ return(0); } /* end addstore() */ topstore(STOREP s) /* Reset stats so that a call to nextitem(s) will be retrieving the first item in store s. */ { s->thish = s->firsth; s->thiselnum = -1; } int nextitem(STOREP s) /* Increment the current location in store s. Then return the character at that location. Returns -1 if no more characters. */ { HANDLEP h; if (s->thish==s->lasth && s->thiselnum==s->lastelnum) return(-1); else { h = s->thish; if (++(s->thiselnum) < s->thish->poolsize) { return((int)(s->thish->pool[s->thiselnum])); } else { /* move to next pool */ h = h->next; s->thish = h; s->thiselnum = 0; return((int)(h->pool[0])); } } } /* end nextitem() */ int unstore(STOREP s) /* Removes ("pops") the last item from the specified store. Returns that item (in range 0-255), or returns -1 if there are no items in the store. */ { HANDLEP nextolast; if (s->lastelnum > -1) { /* last pool not empty */ return((int)(s->lasth->pool[(s->lastelnum)--])); } else { /* last pool empty */ if (s->lasth == s->firsth) return(-1); else { /* move back one pool */ nextolast = s->firsth; while (nextolast->next != s->lasth) nextolast = nextolast->next; DisposPtr((Ptr) nextolast->next); s->lasth = nextolast; s->lastelnum = nextolast->poolsize - 2; if (s->thish == nextolast->next) { s->thish = nextolast; s->thiselnum = s->lastelnum; } nextolast->next = NULL; return((int)(nextolast->pool[s->lastelnum+1])); } } } #endif \ No newline at end of file +// tekstor.c // BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* This has been rewritten to use one damn handle to hold all of the data. -- JMB */ #include "vgtek.proto.h" #include "rg0.proto.h" #include "rgmp.proto.h" #include "tekrgmac.proto.h" #include "tekdefs.h" /* NCSA: sb - all defines are now here, for easy access */ #include "tekstor.proto.h" // thiselnum runs from 0 to (handlesize-1), which is in accordance with C style // arrays. The handle is indexed 0...(handlesize-1) as well. This is why you see // the various +-1's. -- JMB 8/93 TEKSTOREP newTEKstore(void) { TEKSTOREP s; s = (TEKSTOREP) myNewPtr(sizeof(TEKSTORE)); if (s == NULL) return (NULL); if (!(s->dataHandle = myNewHandle(0L))) return (NULL); s->thiselnum = 0; return(s); } void freeTEKstore(TEKSTOREP s) { DisposeHandle(s->dataHandle); DisposePtr((Ptr) s); } short addTEKstore(TEKSTOREP s, char d) { Size handlesize; OSErr memErr; handlesize = GetHandleSize(s->dataHandle); memErr = mySetHandleSize(s->dataHandle, ++handlesize); if (memErr) return (-1); (*(s->dataHandle))[handlesize-1] = d; // Save in last position return(0); } void topTEKstore(TEKSTOREP s) { s->thiselnum = 0; } short nextTEKitem(TEKSTOREP s) { if (s->thiselnum == (GetHandleSize(s->dataHandle))) return(-1); // At end of data return((short) ((*(s->dataHandle))[(s->thiselnum)++]) ); } short TEKunstore(TEKSTOREP s) { Size handlesize; OSErr memErr; if ((handlesize = GetHandleSize(s->dataHandle)) == 0) return (-1); // Nothing in store memErr = mySetHandleSize(s->dataHandle, --handlesize); if (memErr) return(-1); if (s->thiselnum >= handlesize) s->thiselnum = handlesize - 1; return(0); } #ifdef AARON_CONTORER_HAS_A_BRAIN // Never true #define MINPOOL 0x0200 /* smallest allowable pool */ #define MAXPOOL 0x2000 /* largest allowable pool */ STOREP newstore(void) /* create a new, empty store and return a pointer to it. Returns NULL if not enough memory to create a new store. */ { STOREP s; s=(STOREP) myNewPtr((long) sizeof(STORE)); /* BYU LSC */ if (s==NULL) { return(NULL); } else { s->lasth = s->thish = s->firsth = (HANDLEP) myNewPtr((long) sizeof(HANDLE)); /* BYU LSC */ if (s->firsth==NULL) { DisposePtr((Ptr) s); return(NULL); } else { s->firsth->pool = myNewPtr((long) MINPOOL); /* BYU LSC */ if (s->firsth->pool==NULL) { DisposePtr((Ptr) s->firsth); DisposePtr((Ptr) s); return(NULL); } else { s->lastelnum = s->thiselnum = -1; s->firsth->poolsize = MINPOOL; s->firsth->next = NULL; } } } return(s); } void freestore(STOREP s) /* Frees all pools and other memory space associated with store s. */ { HANDLEP h,h2; h = s->firsth; while (h != NULL) { h2 = h; DisposePtr(h->pool); h = h->next; DisposePtr((Ptr) h2); } DisposePtr((Ptr) s); } int addstore(STOREP s, char d) /* Adds character d to the end of store s. Returns 0 if successful, -1 if unable to add character (no memory). */ { int n; /* temp storage */ long size; /* BYU LSC */ HANDLEP h; n = ++(s->lastelnum); size = s->lasth->poolsize; if (n < s->lasth->poolsize) { s->lasth->pool[n] = d; } else { /* Pool full; allocate a new one. */ if (size<MAXPOOL) size <<= 1; h = (HANDLEP)myNewPtr((long) sizeof(HANDLE)); /* BYU LSC */ if (h==NULL) { (s->lastelnum)--; return(-1); } else { h->pool = myNewPtr(size); if (h->pool==NULL) { DisposePtr((Ptr) h); (s->lastelnum)--; return(-1); } else { h->poolsize = size; h->next = NULL; s->lasth->next = h; s->lasth = h; s->lastelnum = 0; h->pool[0] = d; } } } /* end of new pool allocation */ return(0); } /* end addstore() */ topstore(STOREP s) /* Reset stats so that a call to nextitem(s) will be retrieving the first item in store s. */ { s->thish = s->firsth; s->thiselnum = -1; } int nextitem(STOREP s) /* Increment the current location in store s. Then return the character at that location. Returns -1 if no more characters. */ { HANDLEP h; if (s->thish==s->lasth && s->thiselnum==s->lastelnum) return(-1); else { h = s->thish; if (++(s->thiselnum) < s->thish->poolsize) { return((int)(s->thish->pool[s->thiselnum])); } else { /* move to next pool */ h = h->next; s->thish = h; s->thiselnum = 0; return((int)(h->pool[0])); } } } /* end nextitem() */ int unstore(STOREP s) /* Removes ("pops") the last item from the specified store. Returns that item (in range 0-255), or returns -1 if there are no items in the store. */ { HANDLEP nextolast; if (s->lastelnum > -1) { /* last pool not empty */ return((int)(s->lasth->pool[(s->lastelnum)--])); } else { /* last pool empty */ if (s->lasth == s->firsth) return(-1); else { /* move back one pool */ nextolast = s->firsth; while (nextolast->next != s->lasth) nextolast = nextolast->next; DisposePtr((Ptr) nextolast->next); s->lasth = nextolast; s->lastelnum = nextolast->poolsize - 2; if (s->thish == nextolast->next) { s->thish = nextolast; s->thiselnum = s->lastelnum; } nextolast->next = NULL; return((int)(nextolast->pool[s->lastelnum+1])); } } } #endif \ No newline at end of file diff --git a/source/tek/vgtek.c b/source/tek/vgtek.c index 4d8bc4b..91652bd 100755 --- a/source/tek/vgtek.c +++ b/source/tek/vgtek.c @@ -1 +1 @@ -// BetterTelnet // copyright 1997 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* * vgtek.c by Aaron Contorer 1987 for NCSA * bugfixes by Tim Krauskopf 1988 for NCSA * TEK4105 support by Dave Whittington 1990 (for NCSA, of course) * * Takes Tektronix codes as input; sends output to real graphics devices. * * CHANGES TO MAKE: * create a function to make sure a window is attached to a real window. * Calling program will call this whenever switching between active windows. * Pass virtual window number to RG driver so it can call back. */ #ifdef MPW #pragma segment TEKMAIN #endif #include "event.proto.h" #include "maclook.proto.h" #include "wind.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "vgfont.h" #include "vgtek.proto.h" #include "rg0.proto.h" #include "rgmp.proto.h" #include "tekrgmac.proto.h" #include "tekdefs.h" /* NCSA: sb - all defines are now here, for easy access */ #include "tekstor.proto.h" static RGLINK RG[TEK_DEVICE_MAX] = { RGMnewwin, RGMdevname, RGMinit, RGMgin, RGMpencolor, RGMclrscr, RGMclose, RGMpoint, RGMdrawline, RGMinfo, RGMpagedone, RGMdataline, RGMcharmode, RGMgmode, RGMtmode, RGMshowcur, RGMlockcur, RGMhidecur, RGMbell, RGMuncover, RGMPnewwin, RGMPdevname, RGMPinit, RG0returnshort, RGMPpencolor, RG0returnshort, RGMPclose, RGMPpoint, RGMPdrawline, RGMPinfo, RG0oneshort, RGMPdataline, RGMPcharmode, RG0void, RG0void, RG0void, RG0void, RG0void, RG0oneshort, RG0oneshort }; extern WindRec *screens; static fontnum(short vw, short n); static storexy(short vw, short x, short y); static joinup(short hi, short lo, short e); static newcoord(short vw); static linefeed(short vw); static clipvec(short vw, short xa, short ya, short xb, short yb); static short VGcheck(short dnum); static struct VGWINTYPE *VGwin[MAXVG]; /* BYU - virtual window descriptors */ static char state[MAXVG],savstate[MAXVG]; /* save state in a parallel array for speed */ static TEKSTOREP VGstore[MAXVG]; /* the store where data for this window is kept */ static char storing[MAXVG]; /* are we currently saving data from this window */ static short drawing[MAXVG]; /* redrawing or not? */ static short charxset[NUMSIZES] = {56,51,34,31,112,168}; static short charyset[NUMSIZES] = {88,82,53,48,176,264}; /*******************************************************************/ void TEKMAINunload(void) {} short donothing(void) /* BYU LSC */ { return 0; } /* * Set font for window 'vw' to size 'n'. * Sizes are 0..3 in Tek 4014 standard. * Sizes 4 & 5 are used internally for Tek 4105 emulation. */ static fontnum(short vw, short n) { if ((n < 0) || (n >= NUMSIZES)) return(-1); VGwin[vw]->fontnum = n; VGwin[vw]->charx = charxset[n]; VGwin[vw]->chary = charyset[n]; return(0); } static storexy(short vw, short x, short y) /* set graphics x and y position */ { VGwin[vw]->curx = x; VGwin[vw]->cury = y; } static joinup(short hi, short lo, short e) /* returns the number represented by the 3 pieces */ { #if 1 return (((hi & 31) << 7) | ((lo & 31) << 2) | (e & 3)); #else return (((hi /* & 31 */ ) << 7) | ((lo /* & 31 */ ) << 2) | (e /* & 3 */)); #endif } /* end joinup() */ static newcoord(short vw) /* * Replace x,y with nx,ny */ { VGwin[vw]->hiy = VGwin[vw]->nhiy; VGwin[vw]->hix = VGwin[vw]->nhix; VGwin[vw]->loy = VGwin[vw]->nloy; VGwin[vw]->lox = VGwin[vw]->nlox; VGwin[vw]->ey = VGwin[vw]->ney; VGwin[vw]->ex = VGwin[vw]->nex; VGwin[vw]->curx = joinup(VGwin[vw]->nhix,VGwin[vw]->nlox,VGwin[vw]->nex); VGwin[vw]->cury = joinup(VGwin[vw]->nhiy,VGwin[vw]->nloy,VGwin[vw]->ney); } static linefeed(short vw) /* * Perform a linefeed & cr (CHARTALL units) in specified window. */ { /* short y = joinup(VGwin[vw]->hiy,VGwin[vw]->loy,VGwin[vw]->ey);*/ short y = VGwin[vw]->cury; short x; if (y > VGwin[vw]->chary) y -= VGwin[vw]->chary; else { y = 3119 - VGwin[vw]->chary; VGwin[vw]->textcol = 2048 - VGwin[vw]->textcol; } x = VGwin[vw]->textcol; storexy(vw,x,y); } /* * Draw a vector in vw's window from x0,y0 to x1,y1. * Zoom the vector to the current visible window, * and clip it before drawing it. * Uses Liang-Barsky algorithm from ACM Transactions on Graphics, * Vol. 3, No. 1, January 1984, p. 7. * * Note: since QuickDraw on the Mac already handles clipping, we * will not do any processing here. * 14may91dsw * */ static clipvec(short vw, short xa, short ya, short xb, short yb) { short t,b,l,r; struct VGWINTYPE *vp; long hscale, vscale; vp = VGwin[vw]; /* BYU mod */ hscale = INXMAX / (long) vp->winwide; vscale = INYMAX / (long) vp->wintall; t = vp->wintop; b = vp->winbot; l = vp->winleft; r = vp->winright; (*RG[vp->RGdevice].drawline) (vp->RGnum, (short) ((long)(xa - l) * INXMAX / (long) vp->winwide), (short) ((long)(ya- b) * INYMAX / (long) vp->wintall), (short) ((long)(xb - l) * INXMAX / (long) vp->winwide), (short) ((long)(yb- b) * INYMAX / (long) vp->wintall) ); } /* end clipvec() */ /* * Draw a stroked character at the current cursor location. * Uses simple 8-directional moving, 8-directional drawing. * * Modified 17jul90dsw: TEK4105 character set added. */ short drawc(short vw, short c) /* character to draw */ { short x,y,savex,savey; short strokex,strokey; short n; /* number of times to perform command */ char *pstroke; /* pointer into stroke data */ short hmag,vmag; short xdir,ydir; short height; xdir = 1; ydir = 0; if (c == 10) { linefeed(vw); return(0); } if (c == 7) { (*RG[VGwin[vw]->RGdevice].bell) (VGwin[vw]->RGnum); TEKunstore(VGstore[vw]); return(0); } savey = y = VGwin[vw]->cury; savex = x = VGwin[vw]->curx; if (c == 8) { if (savex <= VGwin[vw]->textcol) return(0); savex -= VGwin[vw]->charx; if (savex < VGwin[vw]->textcol) savex = VGwin[vw]->textcol; VGwin[vw]->cury = savey; VGwin[vw]->curx = savex; return(0); } if (VGwin[vw]->TEKtype) { height = VGwin[vw]->TEKSize; if (c > 126) { height = 1; (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,VGwin[vw]->pencolor); } else (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,VGwin[vw]->TEKIndex); hmag = (height*8); vmag = (height*8); xdir = 0; switch(VGwin[vw]->TEKRot) { case 0: xdir = 1; break; case 90: ydir = 1; break; case 180: xdir = -1; break; case 270: ydir = -1; break; } } else { hmag = VGwin[vw]->charx / 10; vmag = VGwin[vw]->chary / 10; } if ((c < 32) || (c > 137)) return(0); // Is this return value correct? c -= 32; pstroke = (VGwin[vw]->TEKtype) ? VGTEKfont[c] : VGfont[c]; while (*pstroke) { strokex = x; strokey = y; n = (*(pstroke++) - 48); /* run length */ c = *(pstroke++); /* direction code */ switch(c) /* horizontal movement: positive = right */ { case 'e': case 'd': case 'c': case 'y': case 'h': case 'n': x += (n * hmag) * xdir; y += (n * hmag) * ydir; break; case 'q': case 'a': case 'z': case 'r': case 'f': case 'v': x -= (n * hmag) * xdir; y -= (n * hmag) * ydir; } switch(c) /* vertical movement: positive = up */ { case 'q': case 'w': case 'e': case 'r': case 't': case 'y': x -= (n * vmag) * ydir; y += (n * vmag) * xdir; break; case 'z': case 'x': case 'c': case 'v': case 'b': case 'n': x += (n * vmag) * ydir; y -= (n * vmag) * xdir; } switch(c) /* draw or move */ { case 'r': case 't': case 'y': case 'f': case 'h': case 'v': case 'b': case 'n': clipvec (vw,strokex,strokey,x,y); break; } } /* end while not at end of string */ /* Update cursor location to next char position */ savex += VGwin[vw]->charx * xdir; savey += VGwin[vw]->charx * ydir; if ((savex < 0) || (savex > 4095) || (savey < 0) || (savey > 3119)) { savex = savex < 0 ? 0 : savex > 4095 ? 4095 : savex; savey = savey < 0 ? 0 : savey > 3119 ? 3119 : savey; } if (VGwin[vw]->TEKtype) (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,VGwin[vw]->pencolor); VGwin[vw]->cury = savey; VGwin[vw]->curx = savex; } /*********************************************************** ************************************************************ *** *** ** All routines given below may be called by the user ** ** program. No routines given above may be called from ** ** the user program. ** *** *** ************************************************************ ***********************************************************/ /* Initialize the whole VG environment. Should be called ONCE * at program startup before using the VG routines. */ void VGinit(void) { short i; for (i = 0; i < MAXVG; i++) { VGwin[i] = nil; } for (i=0; i<TEK_DEVICE_MAX; i++) (*RG[i].init)(); /* BYU LSC */ } short VGgetVS(short theVGnum) /* NCSA 2.5: give us the VS */ { /* NCSA 2.5 */ if (VGcheck(theVGnum)) { return -1; } return VGwin[theVGnum]->theVS; /* NCSA 2.5 */ } /* NCSA 2.5 */ static short VGcheck(short dnum) { if ((dnum >= MAXVG) || (dnum < 0)) return -1; if (VGwin[dnum] == nil) return -1; return 0; } /* * create a new VG window and return its number. * New window will be attached to specified real device. * Returns -1 if unable to create a new VG window. * * Modified 16jul90dsw: Support selection of 4105 or 4014. */ short VGnewwin ( short device, /* number of RG device to use */ short theVS ) { short vw = 0; short theScrn; while ((vw < MAXVG) && (VGwin[vw] != nil)) vw++; if (vw == MAXVG) return(-1); VGwin[vw] = (struct VGWINTYPE *) myNewPtr(sizeof(struct VGWINTYPE)); if (VGwin[vw] == nil) { return -1; } VGstore[vw] = newTEKstore(); if (VGstore[vw] == nil) { DisposePtr((Ptr)VGwin[vw]); VGwin[vw] = nil; return -1; } VGwin[vw]->id = 'VGWN'; VGwin[vw]->RGdevice = device; VGwin[vw]->RGnum = (*RG[device].newwin)(); theScrn = findbyVS(theVS); VGwin[vw]->TEKtype = screens[theScrn].tektype; // 0 = 4014, 1 = 4105 if (VGwin[vw]->RGnum < 0) { /* no windows available on device */ DisposePtr((Ptr)VGwin[vw]); VGwin[vw] = nil; freeTEKstore(VGstore[vw]); return(-1); } VGwin[vw]->mode = ALPHA; VGwin[vw]->TEKPanel = (pointlist) NULL; VGwin[vw]->theVS = theVS; state[vw] = DONE; storing[vw] = TRUE; VGwin[vw]->textcol = 0; drawing[vw] = 1; fontnum(vw,0); (*RG[device].pencolor)(VGwin[vw]->RGnum,1); storexy(vw,0,3071); #if 1 /* BYU LSC */ VGzoom(vw,0,0,4095,3119); /* BYU LSC - important */ #else /* BYU LSC */ VGzoom(vw,0,0,INXMAX-1,INYMAX-1); #endif /* BYU LSC */ return(vw); } /* Release its real graphics device and its store. */ void VGclose(short vw) { if (VGcheck(vw)) { return; } (*RG[VGwin[vw]->RGdevice].close)(VGwin[vw]->RGnum); freeTEKstore(VGstore[vw]); DisposePtr((Ptr)VGwin[vw]); VGwin[vw] = nil; } /* Detach window from its current device and attach it to the * specified device. Returns negative number if unable to do so. * Sample application: switching an image from #9 to Hercules. * Must redraw after calling this. */ short VGdevice(short vw, short dev) { short newwin; if (VGcheck(vw)) { return -1; } newwin = (*RG[dev].newwin)(); if (newwin<0) return(newwin); /* unable to open new window */ (*RG[VGwin[vw]->RGdevice].close)(VGwin[vw]->RGnum); VGwin[vw]->RGdevice = dev; VGwin[vw]->RGnum = newwin; VGwin[vw]->pencolor = 1; VGwin[vw]->TEKBackground = 0; fontnum(vw,1); return(0); } /* Clear the store associated with window vw. * All contents are lost. * User program can call this whenever desired. * Automatically called after receipt of Tek page command. */ void VGclrstor(short vw) { if (VGcheck(vw)) { return; } freeTEKstore(VGstore[vw]); VGstore[vw] = newTEKstore(); /* Don't have to check for errors -- */ /* there was definitely enough memory. */ } /* Successively call the function pointed to by 'func' for each * character stored from window vw. Each character will * be passed in integer form as the only parameter. A value of -1 * will be passed on the last call to indicate the end of the data. */ void VGdumpstore(short vw, short (*func )(short)) { short data; TEKSTOREP st; if (VGcheck(vw)) { return; } st = VGstore[vw]; topTEKstore(st); while ((data = nextTEKitem(st)) != -1) (*func)(data); (*func)(-1); } /* This is the main Tek emulator process. Pass it the window and * the latest input character, and it will take care of the rest. * Calls RG functions as well as local zoom and character drawing * functions. * * Modified 16jul90dsw: * Added 4105 support. */ void VGdraw(short vw, char c) /* the latest input char */ { char cmd; char value; char goagain; /* true means go thru the function a second time */ char temp[80]; RgnHandle PanelRgn; struct VGWINTYPE *vp; pointlist temppoint; if (VGcheck(vw)) { return; } vp = VGwin[vw]; /* BYU */ temp[0] = c; temp[1] = (char) 0; /*** MAIN LOOP ***/ do { c &= 0x7f; /* BYU 2.4.15 */ cmd = (c >> 5) & 0x03; value = c & 0x1f; goagain = FALSE; switch(state[vw]) { case HIY: /* beginning of a vector */ vp->nhiy = vp->hiy; vp->nhix = vp->hix; vp->nloy = vp->loy; vp->nlox = vp->lox; vp->ney = vp->ey; vp->nex = vp->ex; switch(cmd) { case 0: if (value == 27) /* escape sequence */ { state[vw] = ESCOUT; savstate[vw] = HIY; } else if (value < 27) /* ignore */ { break; } else { state[vw] = CANCEL; goagain = TRUE; } break; case 1: /* hiy */ vp->nhiy = value; state[vw] = EXTRA; break; case 2: /* lox */ vp->nlox = value; state[vw] = DONE; break; case 3: /* extra or loy */ vp->nloy = value; state[vw] = LOY; break; } break; case ESCOUT: if ((value != 13) && (value != 10) && (value != 27) && (value != '~')) { state[vw] = savstate[vw]; /* skip all EOL-type characters */ goagain = TRUE; } break; case EXTRA: /* got hiy; expecting extra or loy */ switch(cmd) { case 0: if (value == 27) /* escape sequence */ { state[vw] = ESCOUT; savstate[vw] = EXTRA; } else if (value < 27) /* ignore */ { break; } else { state[vw] = DONE; goagain = TRUE; } break; case 1: /* hix */ vp->nhix = value; state[vw] = LOX; break; case 2: /* lox */ vp->nlox = value; state[vw] = DONE; break; case 3: /* extra or loy */ vp->nloy = value; state[vw] = LOY; break; } break; case LOY: /* got extra or loy; next may be loy or something else */ switch(cmd) { case 0: if (value == 27) /* escape sequence */ { state[vw] = ESCOUT; savstate[vw] = LOY; } else if (value < 27) /* ignore */ { break; } else { state[vw] = DONE; goagain = TRUE; } break; case 1: /* hix */ vp->nhix = value; state[vw] = LOX; break; case 2: /* lox */ vp->nlox = value; state[vw] = DONE; break; case 3: /* this is loy; previous loy was really extra */ vp->ney = (vp->nloy >> 2) & 3; vp->nex = vp->nloy & 3; vp->nloy = value; state[vw] = HIX; break; } break; case HIX: /* hix or lox */ switch(cmd) { case 0: if (value == 27) /* escape sequence */ { state[vw] = ESCOUT; savstate[vw] = HIX; } else if (value < 27) /* ignore */ { break; } else { state[vw] = DONE; goagain = TRUE; } break; case 1: /* hix */ vp->nhix = value; state[vw] = LOX; break; case 2: /* lox */ vp->nlox = value; state[vw] = DONE; break; } break; case LOX: /* must be lox */ switch(cmd) { case 0: if (value == 27) /* escape sequence */ { state[vw] = ESCOUT; savstate[vw] = LOX; } else if (value < 27) /* ignore */ { break; } else { state[vw] = DONE; goagain = TRUE; } break; case 2: vp->nlox = value; state[vw] = DONE; break; } break; case ENTERVEC: if (c == 7) vp->mode = DRAW; if (c < 32) { state[vw] = DONE; goagain = TRUE; vp->mode = DONE; break; } state[vw] = HIY; vp->mode = TEMPMOVE; vp->modesave = DRAW; goagain = TRUE; break; case RS: switch (c) { case ' ': /* pen up */ vp->modesave = vp->mode; vp->mode = TEMPMOVE; break; case 'P': /* pen down */ vp->mode = DRAW; break; case 'D': /* move up */ vp->cury++; break; case 'E': vp->cury++; vp->curx++; break; case 'A': vp->curx++; break; case 'I': vp->curx++; vp->cury--; break; case 'H': vp->cury--; break; case 'J': vp->curx--; vp->cury--; break; case 'B': vp->curx--; break; case 'F': vp->cury++; vp->curx--; break; case 27: savstate[vw] = RS; state[vw] = ESCOUT; break; default: /* storexy(vw,vp->curx,vp->cury);*/ state[vw] = CANCEL; goagain = TRUE; break; } if (vp->mode == DRAW) clipvec(vw,vp->curx,vp->cury,vp->curx,vp->cury); break; case CMD0: /* *->CMD0: get 1st letter of cmd */ switch(c) { case 29: /* GS, start draw */ state[vw] = DONE; goagain = TRUE; break; case '%': state[vw] = TERMSTAT; break; case '8': fontnum(vw,0); state[vw] = DONE; break; case '9': fontnum(vw,1); state[vw] = DONE; break; case ':': fontnum(vw,2); state[vw] = DONE; break; case ';': fontnum(vw,3); state[vw] = DONE; break; case 12: /* form feed = clrscr */ if (screens[findbyVS(vp->theVS)].tekclear) { VGpage(vw); VGclrstor(vw); } break; case 'L': state[vw] = SOMEL; break; case 'K': state[vw] = IGNORE; break; case 'M': state[vw] = SOMEM; break; case 'R': state[vw] = SOMER; break; case 'T': state[vw] = SOMET; break; case 26: (*RG[vp->RGdevice].gin)(vp->RGnum); TEKunstore(VGstore[vw]); TEKunstore(VGstore[vw]); break; case 10: case 13: case 27: case '~': savstate[vw] = DONE; state[vw] = ESCOUT; break; /* completely ignore these after ESC */ default: state[vw] = DONE; } break; case TERMSTAT: switch(c) { case '!': state[vw] = INTEGER; /* Drop the next integer */ savstate[vw] = DONE; break; } break; case SOMER: switch(c) { case 'A': state[vw] = INTEGER; savstate[vw] = VIEWAT; break; default: state[vw] = DONE; } break; case VIEWAT: state[vw] = INTEGER; savstate[vw] = VIEWAT2; goagain = TRUE; break; case VIEWAT2: vp->TEKBackground = vp->intin < 0 ? 0 : vp->intin > 7 ? 7 : vp->intin; state[vw] = INTEGER; savstate[vw] = DONE; goagain = TRUE; break; case SOMET: /* Got ESC T; now handle 3rd char. */ switch(c) { case 'C': /* GCURSOR */ vp->intin = 3; state[vw] = STARTDISC; break; case 'D': vp->intin = 2; state[vw] = STARTDISC; break; case 'F': /* set dialog area color map */ state[vw] = JUNKARRAY; break; case 'G': /* set surface color map */ state[vw] = INTEGER; savstate[vw] = JUNKARRAY; break; default: state[vw] = DONE; } break; case JUNKARRAY: /* This character is the beginning of an integer array to be discarded. Get array size. */ savstate[vw] = STARTDISC; state[vw] = INTEGER; break; case STARTDISC: /* Begin discarding integers. */ vp->count = vp->intin + 1; goagain = TRUE; state[vw] = DISCARDING; break; case DISCARDING: /* We are in the process of discarding an integer array. */ goagain = TRUE; if (!(--(vp->count))) state[vw] = DONE; else if (vp->count == 1) { state[vw] = INTEGER; savstate[vw] = DONE; } else { state[vw] = INTEGER; savstate[vw] = DISCARDING; } break; case INTEGER: if (c & 0x40) { vp->intin = c & 0x3f; state[vw] = INTEGER1; } else { vp->intin = c & 0x0f; if (!(c & 0x10)) vp->intin *= -1; state[vw] = savstate[vw]; } break; case INTEGER1: if (c & 0x40) { vp->intin = (vp->intin << 6) | (c & 0x3f); state[vw] = INTEGER2; } else { vp->intin = (vp->intin << 4) | (c & 0x0f); if (!(c & 0x10)) vp->intin *= -1; state[vw] = savstate[vw]; } break; case INTEGER2: vp->intin = (vp->intin << 4) | (c & 0x0f); if (!(c & 0x10)) vp->intin *= -1; state[vw] = savstate[vw]; break; case IGNORE: /* ignore next char; it's not supported */ state[vw] = DONE; break; case IGNORE2: /* ignore next 2 chars */ state[vw] = IGNORE; break; case SOMEL: /* now process 2nd letter */ switch(c) { case 'E': /* END PANEL 25jul90dsw */ if (vp->TEKtype) { if (vp->TEKPanel) { if ((vp->current->x != vp->savx) || (vp->current->y != vp->savy)) { temppoint = (pointlist) myNewPtr(sizeof(point)); temppoint->x = vp->savx; temppoint->y = vp->savy; temppoint->next = (pointlist) NULL; vp->current->next = temppoint; } temppoint = vp->current = vp->TEKPanel; vp->savx = vp->curx = vp->current->x; vp->savy = vp->cury = vp->current->y; vp->current = vp->current->next; DisposPtr((Ptr) temppoint); PanelRgn = NewRgn(); OpenRgn(); while (vp->current) { clipvec(vw,vp->curx,vp->cury, vp->current->x,vp->current->y); temppoint = vp->current; vp->curx = vp->current->x; vp->cury = vp->current->y; vp->current = vp->current->next; DisposPtr((Ptr) temppoint); } CloseRgn(PanelRgn); if (vp->TEKPattern <= 0) (*RG[vp->RGdevice].pencolor)(vp->RGnum,-vp->TEKPattern); PaintRgn(PanelRgn); /* if (vp->TEKOutline) FrameRgn(PanelRgn); */ DisposeRgn(PanelRgn); (*RG[vp->RGdevice].pencolor)(vp->RGnum,vp->pencolor); vp->TEKPanel = (pointlist) NULL; vp->curx = vp->savx; vp->cury = vp->savy; } } state[vw] = DONE; break; case 'F': /* MOVE */ vp->modesave = vp->mode; vp->mode = TEMPMOVE; state[vw] = HIY; break; case 'G': /* DRAW */ vp->modesave = vp->mode; vp->mode = TEMPDRAW; state[vw] = HIY; break; case 'H': /* MARKER */ vp->modesave = vp->mode; vp->mode = TEMPMARK; state[vw] = HIY; break; case 'I': /* DAINDEX 24jul90dsw*/ state[vw] = STARTDISC; vp->intin = 3; break; case 'L': state[vw] = INTEGER; savstate[vw] = DONE; break; case 'P': /* BEGIN PANEL 17jul90dsw */ if (vp->TEKtype) /* 4105 only */ { state[vw] = HIY; vp->mode = PANEL; } else state[vw] = DONE; break; case 'T': /* GTEXT 17jul90dsw */ if (vp->TEKtype) /* 4105 only */ { savstate[vw] = GTEXT; state[vw] = INTEGER; } else state[vw] = DONE; break; default: state[vw] = DONE; } break; case SOMEM: switch(c) { case 'C': /* set graphtext size */ savstate[vw] = GTSIZE0; state[vw] = INTEGER; break; case 'L': /* set line index */ savstate[vw] = COLORINT; state[vw] = INTEGER; break; case 'M': /* MARKERTYPE 17jul90dsw */ if (vp->TEKtype) { savstate[vw] = MARKER; state[vw] = INTEGER; } else state[vw] = DONE; break; case 'N': /* GTPATH 17jul90dsw */ if (vp->TEKtype) { savstate[vw] = GTPATH; state[vw] = INTEGER; } else state[vw] = DONE; break; case 'P': /* FillPattern 17jul90dsw */ if (vp->TEKtype) { savstate[vw] = FPATTERN; state[vw] = INTEGER; } else state[vw] = DONE; break; case 'R': /* GTROT 17jul90dsw */ if (vp->TEKtype) { savstate[vw] = GTROT; state[vw] = INTEGER; } else state[vw] = DONE; break; case 'T': /* GTINDEX 17jul90dsw */ if (vp->TEKtype) { savstate[vw] = GTINDEX; state[vw] = INTEGER; } else state[vw] = DONE; break; case 'V': if (vp->TEKtype) { state[vw] = INTEGER; savstate[vw] = DONE; } else state[vw] = DONE; break; default: state[vw] = DONE; } break; case COLORINT: /* set line index; have integer */ vp->pencolor = vp->intin; (*RG[vp->RGdevice].pencolor)(vp->RGnum,vp->intin); state[vw] = CANCEL; goagain = TRUE; /* we ignored current char; now process it */ break; case GTSIZE0: /* discard the first integer; get the 2nd */ state[vw] = INTEGER; /* get the important middle integer */ savstate[vw] = GTSIZE1; goagain = TRUE; break; case GTSIZE1: /* integer is the height */ if (vp->TEKtype) { if (vp->intin < 88) vp->TEKSize = 1; else if ((vp->intin > 87) && (vp->intin < 149)) vp->TEKSize = 2; else if ((vp->intin > 148) && (vp->intin < 209)) vp->TEKSize = 3; else if (vp->intin > 208) vp->TEKSize = vp->intin / 61; VGwin[vw]->charx = (vp->TEKSize * 52); VGwin[vw]->chary = (vp->TEKSize * 64); } else { if (vp->intin < 88) fontnum(vw,0); else if (vp->intin < 149) fontnum(vw,4); else fontnum(vw,5); } state[vw] = INTEGER; /* discard last integer */ savstate[vw] = DONE; goagain = TRUE; break; case GTEXT: /* TEK4105 GraphText output. 17jul90dsw */ if (vp->intin > 0) { drawc(vw,(short) c); /* Draw the character */ vp->intin--; /* One less character in the string... */ } else { goagain = TRUE; state[vw] = DONE; newcoord(vw); } break; case MARKER: /* TEK4105 Set marker type. 17jul90dsw */ vp->TEKMarker = vp->intin; if (vp->TEKMarker > 10) vp->TEKMarker = 10; if (vp->TEKMarker < 0) vp->TEKMarker = 0; state[vw] = DONE; goagain = TRUE; break; case GTPATH: vp->TEKPath = vp->intin; state[vw] = DONE; goagain = TRUE; break; case FPATTERN: vp->TEKPattern = (vp->intin < -7) ? -7 : (vp->intin > 149) ? 149 : vp->intin; state[vw] = DONE; goagain = TRUE; break; case GTROT: vp->TEKRot = vp->intin; state[vw] = INTEGER; savstate[vw] = GTROT1; goagain = TRUE; break; case GTROT1: vp->TEKRot = (vp->TEKRot) << (vp->intin); vp->TEKRot = ((vp->TEKRot + 45) / 90) * 90; state[vw] = DONE; goagain = TRUE; break; case GTINDEX: vp->TEKIndex = (vp->intin < 0) ? 0 : (vp->intin > 7) ? 7 : vp->intin; state[vw] = DONE; goagain = TRUE; break; case PANEL: vp->TEKOutline = (vp->intin == 0) ? 0 : 1; temppoint = (pointlist) myNewPtr(sizeof(point)); if (vp->TEKPanel) { if ((vp->current->x != vp->savx) && (vp->current->y != vp->savy)) { temppoint->x = vp->savx; temppoint->y = vp->savy; vp->current->next = temppoint; vp->current = temppoint; temppoint = (pointlist) myNewPtr(sizeof(point)); } vp->current->next = temppoint; } else vp->TEKPanel = temppoint; vp->current = temppoint; vp->current->x = vp->savx = joinup(vp->nhix,vp->nlox,vp->nex); vp->current->y = vp->savy = joinup(vp->nhiy,vp->nloy,vp->ney); vp->current->next = (pointlist) NULL; state[vw] = INTEGER; savstate[vw] = PANEL; vp->mode = DONE; newcoord(vw); state[vw] = DONE; goagain = TRUE; break; case DONE: /* ready for anything */ switch(c) { case 31: /* US - enter ALPHA mode */ vp->mode = ALPHA; state[vw] = CANCEL; break; case 30: state[vw] = RS; break; case 28: vp->mode = MARK; state[vw] = HIY; break; case 29: /* GS - enter VECTOR mode */ state[vw] = ENTERVEC; break; case 27: state[vw] = CMD0; break; default: if (vp->mode == ALPHA) { state[vw] = DONE; if (! vp->TEKtype) drawc(vw,(short) c); else { VSwrite(vp->theVS,&c,1); TEKunstore(VGstore[vw]); } return; } else if ((vp->mode == DRAW) && cmd) { state[vw] = HIY; goagain = TRUE; } else if ((vp->mode == MARK) && cmd) { state[vw] = HIY; goagain = TRUE; } else if ((vp->mode == DRAW) && ((c == 13) || (c == 10))) { /* break drawing mode on CRLF */ vp->mode = ALPHA; state[vw] = CANCEL; } else { state[vw] = DONE; /* do nothing */ return; } } } if (state[vw] == DONE) { if (vp->mode == PANEL) { vp->mode = DONE; state[vw] = INTEGER; savstate[vw] = PANEL; } else if ((vp->TEKPanel) && ((vp->mode == DRAW) || (vp->mode == TEMPDRAW) || (vp->mode == MARK) || (vp->mode == TEMPMARK) || (vp->mode == TEMPMOVE))) { temppoint = (pointlist) myNewPtr(sizeof(point)); vp->current->next = temppoint; vp->current = temppoint; vp->current->x = joinup(vp->nhix,vp->nlox,vp->nex); vp->current->y = joinup(vp->nhiy,vp->nloy,vp->ney); vp->current->next = (pointlist) NULL; if ((vp->mode == TEMPDRAW) || (vp->mode == TEMPMOVE) || (vp->mode == TEMPMARK)) vp->mode = vp->modesave; newcoord(vw); } else if (vp->mode == TEMPMOVE) { vp->mode = vp->modesave; newcoord(vw); } else if ((vp->mode == DRAW) || (vp->mode == TEMPDRAW)) { clipvec(vw,vp->curx,vp->cury, joinup(vp->nhix,vp->nlox,vp->nex), joinup(vp->nhiy,vp->nloy,vp->ney)); newcoord(vw); if (vp->mode == TEMPDRAW) vp->mode = vp->modesave; } else if ((vp->mode == MARK) || (vp->mode == TEMPMARK)) { newcoord(vw); if (vp->TEKtype) drawc(vw,127 + vp->TEKMarker); newcoord(vw); if (vp->mode == TEMPMARK) vp->mode = vp->modesave; } } if (state[vw] == CANCEL) state[vw] = DONE; } while (goagain); return; } /* Clear screen and have a few other effects: * - Return graphics to home position (0,3071) * - Switch to alpha mode * This is a standard Tek command; don't look at me. */ void VGpage(short vw) { if (VGcheck(vw)) { return; } if (VGwin[vw]->TEKtype) (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,VGwin[vw]->TEKBackground); else (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,0); (*RG[VGwin[vw]->RGdevice].clrscr)(VGwin[vw]->RGnum); (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,1); VGwin[vw]->mode = ALPHA; state[vw] = DONE; VGwin[vw]->textcol = 0; fontnum(vw,0); storexy(vw,0,3071); } /* Redraw window 'vw' in pieces to window 'dest'. * Must call this function repeatedly to draw whole image. * Only draws part of the image at a time, to yield CPU power. * Returns 0 if needs to be called more, or 1 if the image * is complete. Another call would result in the redraw beginning again. * User should clear screen before beginning redraw. */ short VGpred(short vw, short dest) { short data; TEKSTOREP st; short count = 0; if (VGcheck(vw)) { return -1; } st = VGstore[vw]; if (drawing[vw]) /* wasn't redrawing */ { topTEKstore(VGstore[vw]); drawing[vw] = 0; /* redraw incomplete */ } while (++count < PREDCOUNT && ((data = nextTEKitem(st)) != -1)) VGdraw(dest,data); if (data == -1) drawing[vw] = 1; /* redraw complete */ return(drawing[vw]); } /* Abort VGpred redrawing of specified window. Must call this routine if you decide not to complete the redraw. */ void VGstopred(short vw) { if (VGcheck(vw)) { return; } drawing[vw] = 1; } /* Redraw the contents of window 'vw' to window 'dest'. * Does not yield CPU until done. * User should clear the screen before calling this, to avoid * a messy display. */ void VGredraw(short vw, short dest) { short data; if (VGcheck(vw)) { return; } topTEKstore(VGstore[vw]); while ((data = nextTEKitem(VGstore[vw])) != -1) VGdraw(dest,data); } /* Send interesting information about the virtual window down to * its RG, so that the RG can make VG calls and display zoom values */ void VGgiveinfo(short vw) { if (VGcheck(vw)) { return; } (*RG[VGwin[vw]->RGdevice].info)(VGwin[vw]->RGnum, vw, VGwin[vw]->winbot, VGwin[vw]->winleft, VGwin[vw]->wintop, VGwin[vw]->winright); } /* Set new borders for zoom/pan region. * x0,y0 is lower left; x1,y1 is upper right. * User should redraw after calling this. */ void VGzoom(short vw, short x0, short y0, short x1, short y1) { if (VGcheck(vw)) { return; } VGwin[vw]->winbot = y0; VGwin[vw]->winleft = x0; VGwin[vw]->wintop = y1; VGwin[vw]->winright = x1; VGwin[vw]->wintall = y1 - y0 + 1; VGwin[vw]->winwide = x1 - x0 + 1; VGgiveinfo(vw); } void VGwhatzoom(short vw, short *px0, short *py0, short *px1, short *py1) { if (VGcheck(vw)) { return; } *py0 = VGwin[vw]->winbot; *px0 = VGwin[vw]->winleft; *py1 = VGwin[vw]->wintop; *px1 = VGwin[vw]->winright; } /* Set zoom/pan borders for window 'dest' equal to those for window 'src'. * User should redraw window 'dest' after calling this. */ void VGzcpy(short src, short dest) { VGzoom(dest,VGwin[src]->winleft, VGwin[src]->winbot, VGwin[src]->winright, VGwin[src]->wintop); } /* Close virtual window. /* Draw the data pointed to by 'data' of length 'count' * on window vw, and add it to the store for that window. * This is THE way for user program to pass Tektronix data. */ short VGwrite(short vw, char *data, short count) { char *c = data; char *end = &(data[count]); char storeit; if (VGcheck(vw)) { return -1; } storeit = storing[vw]; while (c != end) { if (*c == 24) /* ASC CAN character */ return(c-data+1); if (storeit) addTEKstore(VGstore[vw],*c); VGdraw(vw,*c++); } return(count); } /* Return a pointer to a human-readable string * which describes the specified real device */ char * VGrgname(short rgdev) { return(*RG[rgdev].devname)(); } /* Put the specified real device into text mode */ void VGtmode(short rgdev) { (*RG[rgdev].tmode)(); } /* Translate data for output as GIN report. * * User indicates VW number and x,y coordinates of the GIN cursor. * Coordinate space is 0-4095, 0-4095 with 0,0 at the bottom left of * the real window and 4095,4095 at the upper right of the real window. * 'c' is the character to be returned as the keypress. * 'a' is a pointer to an array of 5 characters. The 5 chars must * be transmitted by the user to the remote host as the GIN report. */ void VGgindata( short vw, unsigned short x, /* NCSA: SB - UNSIGNED data */ unsigned short y, /* NCSA: SB - " " */ char c, char *a) { long x2,y2; if (VGcheck(vw)) { return; } x2 = ((x * VGwin[vw]->winwide) / INXMAX + VGwin[vw]->winleft) >> 2; y2 = ((y * VGwin[vw]->wintall) / INYMAX + VGwin[vw]->winbot) >> 2; a[0] = c; a[1] = 0x20 | ((x2 & 0x03E0) >> 5); a[2] = 0x20 | (x2 & 0x001F); a[3] = 0x20 | ((y2 & 0x03E0) >> 5); a[4] = 0x20 | (y2 & 0x001F); } \ No newline at end of file +// BetterTelnet // copyright 1997, 1998, 1999 Rolf Braun // This is free software under the GNU General Public License (GPL). See the file COPYING // which comes with the source code and documentation distributions for details. // based on NCSA Telnet 2.7b5 /* * vgtek.c by Aaron Contorer 1987 for NCSA * bugfixes by Tim Krauskopf 1988 for NCSA * TEK4105 support by Dave Whittington 1990 (for NCSA, of course) * * Takes Tektronix codes as input; sends output to real graphics devices. * * CHANGES TO MAKE: * create a function to make sure a window is attached to a real window. * Calling program will call this whenever switching between active windows. * Pass virtual window number to RG driver so it can call back. */ #include "event.proto.h" #include "maclook.proto.h" #include "wind.h" #include "vsdata.h" #include "vsinterf.proto.h" #include "vgfont.h" #include "vgtek.proto.h" #include "rg0.proto.h" #include "rgmp.proto.h" #include "tekrgmac.proto.h" #include "tekdefs.h" /* NCSA: sb - all defines are now here, for easy access */ #include "tekstor.proto.h" static RGLINK RG[TEK_DEVICE_MAX] = { RGMnewwin, RGMdevname, RGMinit, RGMgin, RGMpencolor, RGMclrscr, RGMclose, RGMpoint, RGMdrawline, RGMinfo, RGMpagedone, RGMdataline, RGMcharmode, RGMgmode, RGMtmode, RGMshowcur, RGMlockcur, RGMhidecur, RGMbell, RGMuncover, RGMPnewwin, RGMPdevname, RGMPinit, RG0returnshort, RGMPpencolor, RG0returnshort, RGMPclose, RGMPpoint, RGMPdrawline, RGMPinfo, RG0oneshort, RGMPdataline, RGMPcharmode, RG0void, RG0void, RG0void, RG0void, RG0void, RG0oneshort, RG0oneshort }; extern WindRec *screens; static fontnum(short vw, short n); static storexy(short vw, short x, short y); static joinup(short hi, short lo, short e); static newcoord(short vw); static linefeed(short vw); static clipvec(short vw, short xa, short ya, short xb, short yb); static short VGcheck(short dnum); static struct VGWINTYPE *VGwin[MAXVG]; /* BYU - virtual window descriptors */ static char state[MAXVG],savstate[MAXVG]; /* save state in a parallel array for speed */ static TEKSTOREP VGstore[MAXVG]; /* the store where data for this window is kept */ static char storing[MAXVG]; /* are we currently saving data from this window */ static short drawing[MAXVG]; /* redrawing or not? */ static short charxset[NUMSIZES] = {56,51,34,31,112,168}; static short charyset[NUMSIZES] = {88,82,53,48,176,264}; /*******************************************************************/ void TEKMAINunload(void) {} short donothing(void) /* BYU LSC */ { return 0; } /* * Set font for window 'vw' to size 'n'. * Sizes are 0..3 in Tek 4014 standard. * Sizes 4 & 5 are used internally for Tek 4105 emulation. */ static fontnum(short vw, short n) { if ((n < 0) || (n >= NUMSIZES)) return(-1); VGwin[vw]->fontnum = n; VGwin[vw]->charx = charxset[n]; VGwin[vw]->chary = charyset[n]; return(0); } static storexy(short vw, short x, short y) /* set graphics x and y position */ { VGwin[vw]->curx = x; VGwin[vw]->cury = y; } static joinup(short hi, short lo, short e) /* returns the number represented by the 3 pieces */ { #if 1 return (((hi & 31) << 7) | ((lo & 31) << 2) | (e & 3)); #else return (((hi /* & 31 */ ) << 7) | ((lo /* & 31 */ ) << 2) | (e /* & 3 */)); #endif } /* end joinup() */ static newcoord(short vw) /* * Replace x,y with nx,ny */ { VGwin[vw]->hiy = VGwin[vw]->nhiy; VGwin[vw]->hix = VGwin[vw]->nhix; VGwin[vw]->loy = VGwin[vw]->nloy; VGwin[vw]->lox = VGwin[vw]->nlox; VGwin[vw]->ey = VGwin[vw]->ney; VGwin[vw]->ex = VGwin[vw]->nex; VGwin[vw]->curx = joinup(VGwin[vw]->nhix,VGwin[vw]->nlox,VGwin[vw]->nex); VGwin[vw]->cury = joinup(VGwin[vw]->nhiy,VGwin[vw]->nloy,VGwin[vw]->ney); } static linefeed(short vw) /* * Perform a linefeed & cr (CHARTALL units) in specified window. */ { /* short y = joinup(VGwin[vw]->hiy,VGwin[vw]->loy,VGwin[vw]->ey);*/ short y = VGwin[vw]->cury; short x; if (y > VGwin[vw]->chary) y -= VGwin[vw]->chary; else { y = 3119 - VGwin[vw]->chary; VGwin[vw]->textcol = 2048 - VGwin[vw]->textcol; } x = VGwin[vw]->textcol; storexy(vw,x,y); } /* * Draw a vector in vw's window from x0,y0 to x1,y1. * Zoom the vector to the current visible window, * and clip it before drawing it. * Uses Liang-Barsky algorithm from ACM Transactions on Graphics, * Vol. 3, No. 1, January 1984, p. 7. * * Note: since QuickDraw on the Mac already handles clipping, we * will not do any processing here. * 14may91dsw * */ static clipvec(short vw, short xa, short ya, short xb, short yb) { short t,b,l,r; struct VGWINTYPE *vp; long hscale, vscale; vp = VGwin[vw]; /* BYU mod */ hscale = INXMAX / (long) vp->winwide; vscale = INYMAX / (long) vp->wintall; t = vp->wintop; b = vp->winbot; l = vp->winleft; r = vp->winright; (*RG[vp->RGdevice].drawline) (vp->RGnum, (short) ((long)(xa - l) * INXMAX / (long) vp->winwide), (short) ((long)(ya- b) * INYMAX / (long) vp->wintall), (short) ((long)(xb - l) * INXMAX / (long) vp->winwide), (short) ((long)(yb- b) * INYMAX / (long) vp->wintall) ); } /* end clipvec() */ /* * Draw a stroked character at the current cursor location. * Uses simple 8-directional moving, 8-directional drawing. * * Modified 17jul90dsw: TEK4105 character set added. */ short drawc(short vw, short c) /* character to draw */ { short x,y,savex,savey; short strokex,strokey; short n; /* number of times to perform command */ char *pstroke; /* pointer into stroke data */ short hmag,vmag; short xdir,ydir; short height; xdir = 1; ydir = 0; if (c == 10) { linefeed(vw); return(0); } if (c == 7) { (*RG[VGwin[vw]->RGdevice].bell) (VGwin[vw]->RGnum); TEKunstore(VGstore[vw]); return(0); } savey = y = VGwin[vw]->cury; savex = x = VGwin[vw]->curx; if (c == 8) { if (savex <= VGwin[vw]->textcol) return(0); savex -= VGwin[vw]->charx; if (savex < VGwin[vw]->textcol) savex = VGwin[vw]->textcol; VGwin[vw]->cury = savey; VGwin[vw]->curx = savex; return(0); } if (VGwin[vw]->TEKtype) { height = VGwin[vw]->TEKSize; if (c > 126) { height = 1; (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,VGwin[vw]->pencolor); } else (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,VGwin[vw]->TEKIndex); hmag = (height*8); vmag = (height*8); xdir = 0; switch(VGwin[vw]->TEKRot) { case 0: xdir = 1; break; case 90: ydir = 1; break; case 180: xdir = -1; break; case 270: ydir = -1; break; } } else { hmag = VGwin[vw]->charx / 10; vmag = VGwin[vw]->chary / 10; } if ((c < 32) || (c > 137)) return(0); // Is this return value correct? c -= 32; pstroke = (VGwin[vw]->TEKtype) ? VGTEKfont[c] : VGfont[c]; while (*pstroke) { strokex = x; strokey = y; n = (*(pstroke++) - 48); /* run length */ c = *(pstroke++); /* direction code */ switch(c) /* horizontal movement: positive = right */ { case 'e': case 'd': case 'c': case 'y': case 'h': case 'n': x += (n * hmag) * xdir; y += (n * hmag) * ydir; break; case 'q': case 'a': case 'z': case 'r': case 'f': case 'v': x -= (n * hmag) * xdir; y -= (n * hmag) * ydir; } switch(c) /* vertical movement: positive = up */ { case 'q': case 'w': case 'e': case 'r': case 't': case 'y': x -= (n * vmag) * ydir; y += (n * vmag) * xdir; break; case 'z': case 'x': case 'c': case 'v': case 'b': case 'n': x += (n * vmag) * ydir; y -= (n * vmag) * xdir; } switch(c) /* draw or move */ { case 'r': case 't': case 'y': case 'f': case 'h': case 'v': case 'b': case 'n': clipvec (vw,strokex,strokey,x,y); break; } } /* end while not at end of string */ /* Update cursor location to next char position */ savex += VGwin[vw]->charx * xdir; savey += VGwin[vw]->charx * ydir; if ((savex < 0) || (savex > 4095) || (savey < 0) || (savey > 3119)) { savex = savex < 0 ? 0 : savex > 4095 ? 4095 : savex; savey = savey < 0 ? 0 : savey > 3119 ? 3119 : savey; } if (VGwin[vw]->TEKtype) (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,VGwin[vw]->pencolor); VGwin[vw]->cury = savey; VGwin[vw]->curx = savex; } /*********************************************************** ************************************************************ *** *** ** All routines given below may be called by the user ** ** program. No routines given above may be called from ** ** the user program. ** *** *** ************************************************************ ***********************************************************/ /* Initialize the whole VG environment. Should be called ONCE * at program startup before using the VG routines. */ void VGinit(void) { short i; for (i = 0; i < MAXVG; i++) { VGwin[i] = nil; } for (i=0; i<TEK_DEVICE_MAX; i++) (*RG[i].init)(); /* BYU LSC */ } short VGgetVS(short theVGnum) /* NCSA 2.5: give us the VS */ { /* NCSA 2.5 */ if (VGcheck(theVGnum)) { return -1; } return VGwin[theVGnum]->theVS; /* NCSA 2.5 */ } /* NCSA 2.5 */ static short VGcheck(short dnum) { if ((dnum >= MAXVG) || (dnum < 0)) return -1; if (VGwin[dnum] == nil) return -1; return 0; } /* * create a new VG window and return its number. * New window will be attached to specified real device. * Returns -1 if unable to create a new VG window. * * Modified 16jul90dsw: Support selection of 4105 or 4014. */ short VGnewwin ( short device, /* number of RG device to use */ short theVS ) { short vw = 0; short theScrn; while ((vw < MAXVG) && (VGwin[vw] != nil)) vw++; if (vw == MAXVG) return(-1); VGwin[vw] = (struct VGWINTYPE *) myNewPtr(sizeof(struct VGWINTYPE)); if (VGwin[vw] == nil) { return -1; } VGstore[vw] = newTEKstore(); if (VGstore[vw] == nil) { DisposePtr((Ptr)VGwin[vw]); VGwin[vw] = nil; return -1; } VGwin[vw]->id = 'VGWN'; VGwin[vw]->RGdevice = device; VGwin[vw]->RGnum = (*RG[device].newwin)(); theScrn = findbyVS(theVS); VGwin[vw]->TEKtype = screens[theScrn].tektype; // 0 = 4014, 1 = 4105 if (VGwin[vw]->RGnum < 0) { /* no windows available on device */ DisposePtr((Ptr)VGwin[vw]); VGwin[vw] = nil; freeTEKstore(VGstore[vw]); return(-1); } VGwin[vw]->mode = ALPHA; VGwin[vw]->TEKPanel = (pointlist) NULL; VGwin[vw]->theVS = theVS; state[vw] = DONE; storing[vw] = TRUE; VGwin[vw]->textcol = 0; drawing[vw] = 1; fontnum(vw,0); (*RG[device].pencolor)(VGwin[vw]->RGnum,1); storexy(vw,0,3071); #if 1 /* BYU LSC */ VGzoom(vw,0,0,4095,3119); /* BYU LSC - important */ #else /* BYU LSC */ VGzoom(vw,0,0,INXMAX-1,INYMAX-1); #endif /* BYU LSC */ return(vw); } /* Release its real graphics device and its store. */ void VGclose(short vw) { if (VGcheck(vw)) { return; } (*RG[VGwin[vw]->RGdevice].close)(VGwin[vw]->RGnum); freeTEKstore(VGstore[vw]); DisposePtr((Ptr)VGwin[vw]); VGwin[vw] = nil; } /* Detach window from its current device and attach it to the * specified device. Returns negative number if unable to do so. * Sample application: switching an image from #9 to Hercules. * Must redraw after calling this. */ short VGdevice(short vw, short dev) { short newwin; if (VGcheck(vw)) { return -1; } newwin = (*RG[dev].newwin)(); if (newwin<0) return(newwin); /* unable to open new window */ (*RG[VGwin[vw]->RGdevice].close)(VGwin[vw]->RGnum); VGwin[vw]->RGdevice = dev; VGwin[vw]->RGnum = newwin; VGwin[vw]->pencolor = 1; VGwin[vw]->TEKBackground = 0; fontnum(vw,1); return(0); } /* Clear the store associated with window vw. * All contents are lost. * User program can call this whenever desired. * Automatically called after receipt of Tek page command. */ void VGclrstor(short vw) { if (VGcheck(vw)) { return; } freeTEKstore(VGstore[vw]); VGstore[vw] = newTEKstore(); /* Don't have to check for errors -- */ /* there was definitely enough memory. */ } /* Successively call the function pointed to by 'func' for each * character stored from window vw. Each character will * be passed in integer form as the only parameter. A value of -1 * will be passed on the last call to indicate the end of the data. */ void VGdumpstore(short vw, short (*func )(short)) { short data; TEKSTOREP st; if (VGcheck(vw)) { return; } st = VGstore[vw]; topTEKstore(st); while ((data = nextTEKitem(st)) != -1) (*func)(data); (*func)(-1); } /* This is the main Tek emulator process. Pass it the window and * the latest input character, and it will take care of the rest. * Calls RG functions as well as local zoom and character drawing * functions. * * Modified 16jul90dsw: * Added 4105 support. */ void VGdraw(short vw, char c) /* the latest input char */ { char cmd; char value; char goagain; /* true means go thru the function a second time */ char temp[80]; RgnHandle PanelRgn; struct VGWINTYPE *vp; pointlist temppoint; if (VGcheck(vw)) { return; } vp = VGwin[vw]; /* BYU */ temp[0] = c; temp[1] = (char) 0; /*** MAIN LOOP ***/ do { c &= 0x7f; /* BYU 2.4.15 */ cmd = (c >> 5) & 0x03; value = c & 0x1f; goagain = FALSE; switch(state[vw]) { case HIY: /* beginning of a vector */ vp->nhiy = vp->hiy; vp->nhix = vp->hix; vp->nloy = vp->loy; vp->nlox = vp->lox; vp->ney = vp->ey; vp->nex = vp->ex; switch(cmd) { case 0: if (value == 27) /* escape sequence */ { state[vw] = ESCOUT; savstate[vw] = HIY; } else if (value < 27) /* ignore */ { break; } else { state[vw] = CANCEL; goagain = TRUE; } break; case 1: /* hiy */ vp->nhiy = value; state[vw] = EXTRA; break; case 2: /* lox */ vp->nlox = value; state[vw] = DONE; break; case 3: /* extra or loy */ vp->nloy = value; state[vw] = LOY; break; } break; case ESCOUT: if ((value != 13) && (value != 10) && (value != 27) && (value != '~')) { state[vw] = savstate[vw]; /* skip all EOL-type characters */ goagain = TRUE; } break; case EXTRA: /* got hiy; expecting extra or loy */ switch(cmd) { case 0: if (value == 27) /* escape sequence */ { state[vw] = ESCOUT; savstate[vw] = EXTRA; } else if (value < 27) /* ignore */ { break; } else { state[vw] = DONE; goagain = TRUE; } break; case 1: /* hix */ vp->nhix = value; state[vw] = LOX; break; case 2: /* lox */ vp->nlox = value; state[vw] = DONE; break; case 3: /* extra or loy */ vp->nloy = value; state[vw] = LOY; break; } break; case LOY: /* got extra or loy; next may be loy or something else */ switch(cmd) { case 0: if (value == 27) /* escape sequence */ { state[vw] = ESCOUT; savstate[vw] = LOY; } else if (value < 27) /* ignore */ { break; } else { state[vw] = DONE; goagain = TRUE; } break; case 1: /* hix */ vp->nhix = value; state[vw] = LOX; break; case 2: /* lox */ vp->nlox = value; state[vw] = DONE; break; case 3: /* this is loy; previous loy was really extra */ vp->ney = (vp->nloy >> 2) & 3; vp->nex = vp->nloy & 3; vp->nloy = value; state[vw] = HIX; break; } break; case HIX: /* hix or lox */ switch(cmd) { case 0: if (value == 27) /* escape sequence */ { state[vw] = ESCOUT; savstate[vw] = HIX; } else if (value < 27) /* ignore */ { break; } else { state[vw] = DONE; goagain = TRUE; } break; case 1: /* hix */ vp->nhix = value; state[vw] = LOX; break; case 2: /* lox */ vp->nlox = value; state[vw] = DONE; break; } break; case LOX: /* must be lox */ switch(cmd) { case 0: if (value == 27) /* escape sequence */ { state[vw] = ESCOUT; savstate[vw] = LOX; } else if (value < 27) /* ignore */ { break; } else { state[vw] = DONE; goagain = TRUE; } break; case 2: vp->nlox = value; state[vw] = DONE; break; } break; case ENTERVEC: if (c == 7) vp->mode = DRAW; if (c < 32) { state[vw] = DONE; goagain = TRUE; vp->mode = DONE; break; } state[vw] = HIY; vp->mode = TEMPMOVE; vp->modesave = DRAW; goagain = TRUE; break; case RS: switch (c) { case ' ': /* pen up */ vp->modesave = vp->mode; vp->mode = TEMPMOVE; break; case 'P': /* pen down */ vp->mode = DRAW; break; case 'D': /* move up */ vp->cury++; break; case 'E': vp->cury++; vp->curx++; break; case 'A': vp->curx++; break; case 'I': vp->curx++; vp->cury--; break; case 'H': vp->cury--; break; case 'J': vp->curx--; vp->cury--; break; case 'B': vp->curx--; break; case 'F': vp->cury++; vp->curx--; break; case 27: savstate[vw] = RS; state[vw] = ESCOUT; break; default: /* storexy(vw,vp->curx,vp->cury);*/ state[vw] = CANCEL; goagain = TRUE; break; } if (vp->mode == DRAW) clipvec(vw,vp->curx,vp->cury,vp->curx,vp->cury); break; case CMD0: /* *->CMD0: get 1st letter of cmd */ switch(c) { case 29: /* GS, start draw */ state[vw] = DONE; goagain = TRUE; break; case '%': state[vw] = TERMSTAT; break; case '8': fontnum(vw,0); state[vw] = DONE; break; case '9': fontnum(vw,1); state[vw] = DONE; break; case ':': fontnum(vw,2); state[vw] = DONE; break; case ';': fontnum(vw,3); state[vw] = DONE; break; case 12: /* form feed = clrscr */ if (screens[findbyVS(vp->theVS)].tekclear) { VGpage(vw); VGclrstor(vw); } break; case 'L': state[vw] = SOMEL; break; case 'K': state[vw] = IGNORE; break; case 'M': state[vw] = SOMEM; break; case 'R': state[vw] = SOMER; break; case 'T': state[vw] = SOMET; break; case 26: (*RG[vp->RGdevice].gin)(vp->RGnum); TEKunstore(VGstore[vw]); TEKunstore(VGstore[vw]); break; case 10: case 13: case 27: case '~': savstate[vw] = DONE; state[vw] = ESCOUT; break; /* completely ignore these after ESC */ default: state[vw] = DONE; } break; case TERMSTAT: switch(c) { case '!': state[vw] = INTEGER; /* Drop the next integer */ savstate[vw] = DONE; break; } break; case SOMER: switch(c) { case 'A': state[vw] = INTEGER; savstate[vw] = VIEWAT; break; default: state[vw] = DONE; } break; case VIEWAT: state[vw] = INTEGER; savstate[vw] = VIEWAT2; goagain = TRUE; break; case VIEWAT2: vp->TEKBackground = vp->intin < 0 ? 0 : vp->intin > 7 ? 7 : vp->intin; state[vw] = INTEGER; savstate[vw] = DONE; goagain = TRUE; break; case SOMET: /* Got ESC T; now handle 3rd char. */ switch(c) { case 'C': /* GCURSOR */ vp->intin = 3; state[vw] = STARTDISC; break; case 'D': vp->intin = 2; state[vw] = STARTDISC; break; case 'F': /* set dialog area color map */ state[vw] = JUNKARRAY; break; case 'G': /* set surface color map */ state[vw] = INTEGER; savstate[vw] = JUNKARRAY; break; default: state[vw] = DONE; } break; case JUNKARRAY: /* This character is the beginning of an integer array to be discarded. Get array size. */ savstate[vw] = STARTDISC; state[vw] = INTEGER; break; case STARTDISC: /* Begin discarding integers. */ vp->count = vp->intin + 1; goagain = TRUE; state[vw] = DISCARDING; break; case DISCARDING: /* We are in the process of discarding an integer array. */ goagain = TRUE; if (!(--(vp->count))) state[vw] = DONE; else if (vp->count == 1) { state[vw] = INTEGER; savstate[vw] = DONE; } else { state[vw] = INTEGER; savstate[vw] = DISCARDING; } break; case INTEGER: if (c & 0x40) { vp->intin = c & 0x3f; state[vw] = INTEGER1; } else { vp->intin = c & 0x0f; if (!(c & 0x10)) vp->intin *= -1; state[vw] = savstate[vw]; } break; case INTEGER1: if (c & 0x40) { vp->intin = (vp->intin << 6) | (c & 0x3f); state[vw] = INTEGER2; } else { vp->intin = (vp->intin << 4) | (c & 0x0f); if (!(c & 0x10)) vp->intin *= -1; state[vw] = savstate[vw]; } break; case INTEGER2: vp->intin = (vp->intin << 4) | (c & 0x0f); if (!(c & 0x10)) vp->intin *= -1; state[vw] = savstate[vw]; break; case IGNORE: /* ignore next char; it's not supported */ state[vw] = DONE; break; case IGNORE2: /* ignore next 2 chars */ state[vw] = IGNORE; break; case SOMEL: /* now process 2nd letter */ switch(c) { case 'E': /* END PANEL 25jul90dsw */ if (vp->TEKtype) { if (vp->TEKPanel) { if ((vp->current->x != vp->savx) || (vp->current->y != vp->savy)) { temppoint = (pointlist) myNewPtr(sizeof(point)); temppoint->x = vp->savx; temppoint->y = vp->savy; temppoint->next = (pointlist) NULL; vp->current->next = temppoint; } temppoint = vp->current = vp->TEKPanel; vp->savx = vp->curx = vp->current->x; vp->savy = vp->cury = vp->current->y; vp->current = vp->current->next; DisposePtr((Ptr) temppoint); PanelRgn = NewRgn(); OpenRgn(); while (vp->current) { clipvec(vw,vp->curx,vp->cury, vp->current->x,vp->current->y); temppoint = vp->current; vp->curx = vp->current->x; vp->cury = vp->current->y; vp->current = vp->current->next; DisposePtr((Ptr) temppoint); } CloseRgn(PanelRgn); if (vp->TEKPattern <= 0) (*RG[vp->RGdevice].pencolor)(vp->RGnum,-vp->TEKPattern); PaintRgn(PanelRgn); /* if (vp->TEKOutline) FrameRgn(PanelRgn); */ DisposeRgn(PanelRgn); (*RG[vp->RGdevice].pencolor)(vp->RGnum,vp->pencolor); vp->TEKPanel = (pointlist) NULL; vp->curx = vp->savx; vp->cury = vp->savy; } } state[vw] = DONE; break; case 'F': /* MOVE */ vp->modesave = vp->mode; vp->mode = TEMPMOVE; state[vw] = HIY; break; case 'G': /* DRAW */ vp->modesave = vp->mode; vp->mode = TEMPDRAW; state[vw] = HIY; break; case 'H': /* MARKER */ vp->modesave = vp->mode; vp->mode = TEMPMARK; state[vw] = HIY; break; case 'I': /* DAINDEX 24jul90dsw*/ state[vw] = STARTDISC; vp->intin = 3; break; case 'L': state[vw] = INTEGER; savstate[vw] = DONE; break; case 'P': /* BEGIN PANEL 17jul90dsw */ if (vp->TEKtype) /* 4105 only */ { state[vw] = HIY; vp->mode = PANEL; } else state[vw] = DONE; break; case 'T': /* GTEXT 17jul90dsw */ if (vp->TEKtype) /* 4105 only */ { savstate[vw] = GTEXT; state[vw] = INTEGER; } else state[vw] = DONE; break; default: state[vw] = DONE; } break; case SOMEM: switch(c) { case 'C': /* set graphtext size */ savstate[vw] = GTSIZE0; state[vw] = INTEGER; break; case 'L': /* set line index */ savstate[vw] = COLORINT; state[vw] = INTEGER; break; case 'M': /* MARKERTYPE 17jul90dsw */ if (vp->TEKtype) { savstate[vw] = MARKER; state[vw] = INTEGER; } else state[vw] = DONE; break; case 'N': /* GTPATH 17jul90dsw */ if (vp->TEKtype) { savstate[vw] = GTPATH; state[vw] = INTEGER; } else state[vw] = DONE; break; case 'P': /* FillPattern 17jul90dsw */ if (vp->TEKtype) { savstate[vw] = FPATTERN; state[vw] = INTEGER; } else state[vw] = DONE; break; case 'R': /* GTROT 17jul90dsw */ if (vp->TEKtype) { savstate[vw] = GTROT; state[vw] = INTEGER; } else state[vw] = DONE; break; case 'T': /* GTINDEX 17jul90dsw */ if (vp->TEKtype) { savstate[vw] = GTINDEX; state[vw] = INTEGER; } else state[vw] = DONE; break; case 'V': if (vp->TEKtype) { state[vw] = INTEGER; savstate[vw] = DONE; } else state[vw] = DONE; break; default: state[vw] = DONE; } break; case COLORINT: /* set line index; have integer */ vp->pencolor = vp->intin; (*RG[vp->RGdevice].pencolor)(vp->RGnum,vp->intin); state[vw] = CANCEL; goagain = TRUE; /* we ignored current char; now process it */ break; case GTSIZE0: /* discard the first integer; get the 2nd */ state[vw] = INTEGER; /* get the important middle integer */ savstate[vw] = GTSIZE1; goagain = TRUE; break; case GTSIZE1: /* integer is the height */ if (vp->TEKtype) { if (vp->intin < 88) vp->TEKSize = 1; else if ((vp->intin > 87) && (vp->intin < 149)) vp->TEKSize = 2; else if ((vp->intin > 148) && (vp->intin < 209)) vp->TEKSize = 3; else if (vp->intin > 208) vp->TEKSize = vp->intin / 61; VGwin[vw]->charx = (vp->TEKSize * 52); VGwin[vw]->chary = (vp->TEKSize * 64); } else { if (vp->intin < 88) fontnum(vw,0); else if (vp->intin < 149) fontnum(vw,4); else fontnum(vw,5); } state[vw] = INTEGER; /* discard last integer */ savstate[vw] = DONE; goagain = TRUE; break; case GTEXT: /* TEK4105 GraphText output. 17jul90dsw */ if (vp->intin > 0) { drawc(vw,(short) c); /* Draw the character */ vp->intin--; /* One less character in the string... */ } else { goagain = TRUE; state[vw] = DONE; newcoord(vw); } break; case MARKER: /* TEK4105 Set marker type. 17jul90dsw */ vp->TEKMarker = vp->intin; if (vp->TEKMarker > 10) vp->TEKMarker = 10; if (vp->TEKMarker < 0) vp->TEKMarker = 0; state[vw] = DONE; goagain = TRUE; break; case GTPATH: vp->TEKPath = vp->intin; state[vw] = DONE; goagain = TRUE; break; case FPATTERN: vp->TEKPattern = (vp->intin < -7) ? -7 : (vp->intin > 149) ? 149 : vp->intin; state[vw] = DONE; goagain = TRUE; break; case GTROT: vp->TEKRot = vp->intin; state[vw] = INTEGER; savstate[vw] = GTROT1; goagain = TRUE; break; case GTROT1: vp->TEKRot = (vp->TEKRot) << (vp->intin); vp->TEKRot = ((vp->TEKRot + 45) / 90) * 90; state[vw] = DONE; goagain = TRUE; break; case GTINDEX: vp->TEKIndex = (vp->intin < 0) ? 0 : (vp->intin > 7) ? 7 : vp->intin; state[vw] = DONE; goagain = TRUE; break; case PANEL: vp->TEKOutline = (vp->intin == 0) ? 0 : 1; temppoint = (pointlist) myNewPtr(sizeof(point)); if (vp->TEKPanel) { if ((vp->current->x != vp->savx) && (vp->current->y != vp->savy)) { temppoint->x = vp->savx; temppoint->y = vp->savy; vp->current->next = temppoint; vp->current = temppoint; temppoint = (pointlist) myNewPtr(sizeof(point)); } vp->current->next = temppoint; } else vp->TEKPanel = temppoint; vp->current = temppoint; vp->current->x = vp->savx = joinup(vp->nhix,vp->nlox,vp->nex); vp->current->y = vp->savy = joinup(vp->nhiy,vp->nloy,vp->ney); vp->current->next = (pointlist) NULL; state[vw] = INTEGER; savstate[vw] = PANEL; vp->mode = DONE; newcoord(vw); state[vw] = DONE; goagain = TRUE; break; case DONE: /* ready for anything */ switch(c) { case 31: /* US - enter ALPHA mode */ vp->mode = ALPHA; state[vw] = CANCEL; break; case 30: state[vw] = RS; break; case 28: vp->mode = MARK; state[vw] = HIY; break; case 29: /* GS - enter VECTOR mode */ state[vw] = ENTERVEC; break; case 27: state[vw] = CMD0; break; default: if (vp->mode == ALPHA) { state[vw] = DONE; if (! vp->TEKtype) drawc(vw,(short) c); else { VSwrite(vp->theVS,&c,1); TEKunstore(VGstore[vw]); } return; } else if ((vp->mode == DRAW) && cmd) { state[vw] = HIY; goagain = TRUE; } else if ((vp->mode == MARK) && cmd) { state[vw] = HIY; goagain = TRUE; } else if ((vp->mode == DRAW) && ((c == 13) || (c == 10))) { /* break drawing mode on CRLF */ vp->mode = ALPHA; state[vw] = CANCEL; } else { state[vw] = DONE; /* do nothing */ return; } } } if (state[vw] == DONE) { if (vp->mode == PANEL) { vp->mode = DONE; state[vw] = INTEGER; savstate[vw] = PANEL; } else if ((vp->TEKPanel) && ((vp->mode == DRAW) || (vp->mode == TEMPDRAW) || (vp->mode == MARK) || (vp->mode == TEMPMARK) || (vp->mode == TEMPMOVE))) { temppoint = (pointlist) myNewPtr(sizeof(point)); vp->current->next = temppoint; vp->current = temppoint; vp->current->x = joinup(vp->nhix,vp->nlox,vp->nex); vp->current->y = joinup(vp->nhiy,vp->nloy,vp->ney); vp->current->next = (pointlist) NULL; if ((vp->mode == TEMPDRAW) || (vp->mode == TEMPMOVE) || (vp->mode == TEMPMARK)) vp->mode = vp->modesave; newcoord(vw); } else if (vp->mode == TEMPMOVE) { vp->mode = vp->modesave; newcoord(vw); } else if ((vp->mode == DRAW) || (vp->mode == TEMPDRAW)) { clipvec(vw,vp->curx,vp->cury, joinup(vp->nhix,vp->nlox,vp->nex), joinup(vp->nhiy,vp->nloy,vp->ney)); newcoord(vw); if (vp->mode == TEMPDRAW) vp->mode = vp->modesave; } else if ((vp->mode == MARK) || (vp->mode == TEMPMARK)) { newcoord(vw); if (vp->TEKtype) drawc(vw,127 + vp->TEKMarker); newcoord(vw); if (vp->mode == TEMPMARK) vp->mode = vp->modesave; } } if (state[vw] == CANCEL) state[vw] = DONE; } while (goagain); return; } /* Clear screen and have a few other effects: * - Return graphics to home position (0,3071) * - Switch to alpha mode * This is a standard Tek command; don't look at me. */ void VGpage(short vw) { if (VGcheck(vw)) { return; } if (VGwin[vw]->TEKtype) (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,VGwin[vw]->TEKBackground); else (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,0); (*RG[VGwin[vw]->RGdevice].clrscr)(VGwin[vw]->RGnum); (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,1); VGwin[vw]->mode = ALPHA; state[vw] = DONE; VGwin[vw]->textcol = 0; fontnum(vw,0); storexy(vw,0,3071); } /* Redraw window 'vw' in pieces to window 'dest'. * Must call this function repeatedly to draw whole image. * Only draws part of the image at a time, to yield CPU power. * Returns 0 if needs to be called more, or 1 if the image * is complete. Another call would result in the redraw beginning again. * User should clear screen before beginning redraw. */ short VGpred(short vw, short dest) { short data; TEKSTOREP st; short count = 0; if (VGcheck(vw)) { return -1; } st = VGstore[vw]; if (drawing[vw]) /* wasn't redrawing */ { topTEKstore(VGstore[vw]); drawing[vw] = 0; /* redraw incomplete */ } while (++count < PREDCOUNT && ((data = nextTEKitem(st)) != -1)) VGdraw(dest,data); if (data == -1) drawing[vw] = 1; /* redraw complete */ return(drawing[vw]); } /* Abort VGpred redrawing of specified window. Must call this routine if you decide not to complete the redraw. */ void VGstopred(short vw) { if (VGcheck(vw)) { return; } drawing[vw] = 1; } /* Redraw the contents of window 'vw' to window 'dest'. * Does not yield CPU until done. * User should clear the screen before calling this, to avoid * a messy display. */ void VGredraw(short vw, short dest) { short data; if (VGcheck(vw)) { return; } topTEKstore(VGstore[vw]); while ((data = nextTEKitem(VGstore[vw])) != -1) VGdraw(dest,data); } /* Send interesting information about the virtual window down to * its RG, so that the RG can make VG calls and display zoom values */ void VGgiveinfo(short vw) { if (VGcheck(vw)) { return; } (*RG[VGwin[vw]->RGdevice].info)(VGwin[vw]->RGnum, vw, VGwin[vw]->winbot, VGwin[vw]->winleft, VGwin[vw]->wintop, VGwin[vw]->winright); } /* Set new borders for zoom/pan region. * x0,y0 is lower left; x1,y1 is upper right. * User should redraw after calling this. */ void VGzoom(short vw, short x0, short y0, short x1, short y1) { if (VGcheck(vw)) { return; } VGwin[vw]->winbot = y0; VGwin[vw]->winleft = x0; VGwin[vw]->wintop = y1; VGwin[vw]->winright = x1; VGwin[vw]->wintall = y1 - y0 + 1; VGwin[vw]->winwide = x1 - x0 + 1; VGgiveinfo(vw); } void VGwhatzoom(short vw, short *px0, short *py0, short *px1, short *py1) { if (VGcheck(vw)) { return; } *py0 = VGwin[vw]->winbot; *px0 = VGwin[vw]->winleft; *py1 = VGwin[vw]->wintop; *px1 = VGwin[vw]->winright; } /* Set zoom/pan borders for window 'dest' equal to those for window 'src'. * User should redraw window 'dest' after calling this. */ void VGzcpy(short src, short dest) { VGzoom(dest,VGwin[src]->winleft, VGwin[src]->winbot, VGwin[src]->winright, VGwin[src]->wintop); } /* Close virtual window. /* Draw the data pointed to by 'data' of length 'count' * on window vw, and add it to the store for that window. * This is THE way for user program to pass Tektronix data. */ short VGwrite(short vw, char *data, short count) { char *c = data; char *end = &(data[count]); char storeit; if (VGcheck(vw)) { return -1; } storeit = storing[vw]; while (c != end) { if (*c == 24) /* ASC CAN character */ return(c-data+1); if (storeit) addTEKstore(VGstore[vw],*c); VGdraw(vw,*c++); } return(count); } /* Return a pointer to a human-readable string * which describes the specified real device */ char * VGrgname(short rgdev) { return(*RG[rgdev].devname)(); } /* Put the specified real device into text mode */ void VGtmode(short rgdev) { (*RG[rgdev].tmode)(); } /* Translate data for output as GIN report. * * User indicates VW number and x,y coordinates of the GIN cursor. * Coordinate space is 0-4095, 0-4095 with 0,0 at the bottom left of * the real window and 4095,4095 at the upper right of the real window. * 'c' is the character to be returned as the keypress. * 'a' is a pointer to an array of 5 characters. The 5 chars must * be transmitted by the user to the remote host as the GIN report. */ void VGgindata( short vw, unsigned short x, /* NCSA: SB - UNSIGNED data */ unsigned short y, /* NCSA: SB - " " */ char c, char *a) { long x2,y2; if (VGcheck(vw)) { return; } x2 = ((x * VGwin[vw]->winwide) / INXMAX + VGwin[vw]->winleft) >> 2; y2 = ((y * VGwin[vw]->wintall) / INYMAX + VGwin[vw]->winbot) >> 2; a[0] = c; a[1] = 0x20 | ((x2 & 0x03E0) >> 5); a[2] = 0x20 | (x2 & 0x001F); a[3] = 0x20 | ((y2 & 0x03E0) >> 5); a[4] = 0x20 | (y2 & 0x001F); } \ No newline at end of file diff --git a/source/telnet.68k.r b/source/telnet.68k.r index a93160d..b8259ea 100644 --- a/source/telnet.68k.r +++ b/source/telnet.68k.r @@ -1,11 +1,12 @@ data 'vers' (1) { - $"0122 8000 0000 0531 2E32 2E32 2131 2E32" /* ."....1.2.2!1.2 */ - $"2E32 2036 386B 2043 5731 3020 284F 6374" /* .2 68k CW10 (Oct */ - $"6F62 6572 2032 392C 2031 3939 3729" /* ober 29, 1997) */ + $"0200 8001 0000 0632 2E30 6663 3117 322E" /* ......2.0fc1.2. */ + $"3066 6331 2036 386B 2028 3120 4A61 6E20" /* 0fc1 68k (1 Jan */ + $"3139 3939 29" /* 1999) */ }; data 'vers' (2) { - $"0122 8000 0000 0531 2E32 2E32 1242 6574" /* ."....1.2.2.Bet */ - $"7465 7254 656C 6E65 7420 312E 322E 32" /* terTelnet 1.2.2 */ + $"0200 8001 0000 0632 2E30 6663 3113 4265" /* ......2.0fc1.Be */ + $"7474 6572 5465 6C6E 6574 2032 2E30 6663" /* tterTelnet 2.0fc */ + $"31" /* 1 */ }; diff --git a/source/telnet.ppc.r b/source/telnet.ppc.r index 17f57d2..cc0fd67 100644 --- a/source/telnet.ppc.r +++ b/source/telnet.ppc.r @@ -1,11 +1,12 @@ data 'vers' (1) { - $"0122 8000 0000 0531 2E32 2E32 2131 2E32" /* ."....1.2.2!1.2 */ - $"2E32 2050 5043 2043 5731 3020 284F 6374" /* .2 PPC CW10 (Oct */ - $"6F62 6572 2032 392C 2031 3939 3729" /* ober 29, 1997) */ + $"0200 8001 0000 0632 2E30 6663 3117 322E" /* ......2.0fc1.2. */ + $"3066 6331 2046 6174 2028 3320 4A61 6E20" /* 0fc1 Fat (3 Jan */ + $"3139 3939 29" /* 1999) */ }; data 'vers' (2) { - $"0122 8000 0000 0531 2E32 2E32 1242 6574" /* ."....1.2.2.Bet */ - $"7465 7254 656C 6E65 7420 312E 322E 32" /* terTelnet 1.2.2 */ + $"0200 8001 0000 0632 2E30 6663 3113 4265" /* ......2.0fc1.Be */ + $"7474 6572 5465 6C6E 6574 2032 2E30 6663" /* tterTelnet 2.0fc */ + $"31" /* 1 */ }; diff --git a/source/telnet.r b/source/telnet.r index 4ae5c24..c032be6 100644 --- a/source/telnet.r +++ b/source/telnet.r @@ -1,5 +1,5 @@ data 'aete' (0) { - $"0100 0000 0000 0002 0E52 6571 7569 7265" /* .........Require */ + $"0100 0000 0000 0003 0E52 6571 7569 7265" /* .........Require */ $"6420 5375 6974 652C 4576 656E 7473 2074" /* d Suite,Events t */ $"6861 7420 6576 6572 7920 6170 706C 6963" /* hat every applic */ $"6174 696F 6E20 7368 6F75 6C64 2073 7570" /* ation should sup */ @@ -7,14 +7,99 @@ data 'aete' (0) { $"0000 0000 0955 524C 2053 7569 7465 2C53" /* ....URL Suite,S */ $"7461 6E64 6172 6420 5375 6974 6520 666F" /* tandard Suite fo */ $"7220 556E 6966 6F72 6D20 5265 736F 7572" /* r Uniform Resour */ - $"6365 204C 6F63 6174 6F72 7300 4755 524C" /* ce Locators.GURL */ + $"6365 204C 6F63 6174 6F72 7361 4755 524C" /* ce LocatorsaGURL */ $"0001 0001 0001 0667 6574 7572 6C2B 4F70" /* .......geturl+Op */ $"656E 2061 2074 656C 6E65 7420 636F 6E6E" /* en a telnet conn */ $"6563 7469 6F6E 2073 7065 6369 6669 6564" /* ection specified */ - $"2062 7920 6120 5552 4C00 4755 524C 4755" /* by a URL.GURLGU */ + $"2062 7920 6120 5552 4C62 4755 524C 4755" /* by a URLbGURLGU */ $"524C 7368 6F72 0B72 6573 756C 7420 636F" /* RLshor.result co */ $"6465 0000 5445 5854 0C61 2074 656C 6E65" /* de..TEXT.a telne */ $"7420 5552 4C00 0000 0000 0000 0000 0000" /* t URL........... */ + $"1242 6574 7465 7254 656C 6E65 7420 5375" /* .BetterTelnet Su */ + $"6974 655B 436F 6E74 6169 6E73 2065 7665" /* ite[Contains eve */ + $"6E74 7320 7573 6566 756C 2066 6F72 2073" /* nts useful for s */ + $"6372 6970 7469 6E67 2042 6574 7465 7254" /* cripting BetterT */ + $"656C 6E65 742C 2069 6E63 6C75 6469 6E67" /* elnet, including */ + $"2061 2073 7562 7365 7420 6F66 2063 6F72" /* a subset of cor */ + $"6520 7375 6974 6520 6576 656E 7473 2E0E" /* e suite events.. */ + $"726C 6654 0001 0001 0006 0973 656E 6420" /* rlfT......send */ + $"7465 7874 2673 656E 6473 2061 2074 6578" /* text&sends a tex */ + $"7420 7374 7269 6E67 2074 6F20 7468 6520" /* t string to the */ + $"7265 6D6F 7465 2068 6F73 7474 726C 6654" /* remote hosttrlfT */ + $"7365 6E64 6E75 6C6C 0320 2020 0000 5445" /* sendnull. ..TE */ + $"5854 1074 6865 2074 6578 7420 746F 2073" /* XT.the text to s */ + $"656E 6468 0000 0000 0763 6F6E 6E65 6374" /* endh.....connect */ + $"996F 7065 6E73 2061 206E 6577 2063 6F6E" /* opens a new con */ + $"6E65 6374 696F 6E20 746F 2061 2072 656D" /* nection to a rem */ + $"6F74 6520 686F 7374 2028 6578 616D 706C" /* ote host (exampl */ + $"653A 2063 6F6E 6E65 6374 2022 3C44 6566" /* e: connect "<Def */ + $"6175 6C74 3E22 2068 6F73 7420 2268 6F73" /* ault>" host "hos */ + $"746E 616D 652E 646F 6D61 696E 2E63 6F6D" /* tname.domain.com */ + $"3A32 3332 3322 2074 6974 6C65 2022 5769" /* :2323" title "Wi */ + $"6E64 6F77 2054 6974 6C65 2220 7761 6974" /* ndow Title" wait */ + $"696E 6720 2279 6573 2220 7375 7370 656E" /* ing "yes" suspen */ + $"6465 6420 2279 6573 2229 726C 6654 6D6B" /* ded "yes")rlfTmk */ + $"4358 6E75 6C6C 0000 0000 5445 5854 5274" /* CXnull....TEXTRt */ + $"6865 206E 616D 6520 6F66 2074 6865 2042" /* he name of the B */ + $"6574 7465 7254 656C 6E65 7420 6661 766F" /* etterTelnet favo */ + $"7269 7465 7320 7365 7420 746F 2075 7365" /* rites set to use */ + $"2066 6F72 2073 6574 7469 6E67 7320 666F" /* for settings fo */ + $"7220 7468 6973 2063 6F6E 6E65 6374 696F" /* r this connectio */ + $"6E6F 0000 0004 0468 6F73 7490 686F 7374" /* no.....hosthost */ + $"5445 5854 7974 6865 206E 616D 6520 6F66" /* TEXTythe name of */ + $"2074 6865 2068 6F73 7420 746F 2077 6869" /* the host to whi */ + $"6368 2074 6F20 636F 6E6E 6563 742C 2069" /* ch to connect, i */ + $"6E63 6C75 6469 6E67 2074 6865 2070 6F72" /* ncluding the por */ + $"7420 6E75 6D62 6572 2C20 6966 2061 7070" /* t number, if app */ + $"6C69 6361 626C 6520 2D20 6966 206E 756C" /* licable - if nul */ + $"6C2C 2074 6865 2064 6566 6175 6C74 2077" /* l, the default w */ + $"696C 6C20 6265 2075 7365 6420 2020 8000" /* ill be used . */ + $"0574 6974 6C65 7469 746C 5445 5854 2774" /* .titletitlTEXT't */ + $"6865 2077 696E 646F 7720 7469 746C 6520" /* he window title */ + $"666F 7220 7468 6520 6E65 7720 636F 6E6E" /* for the new conn */ + $"6563 7469 6F6E 8000 0973 7573 7065 6E64" /* ection.suspend */ + $"6564 7375 7370 5445 5854 6573 6574 2074" /* edsuspTEXTeset t */ + $"6869 7320 746F 2022 7965 7322 2069 6620" /* his to "yes" if */ + $"796F 7520 7761 6E74 2074 6865 2063 6F6E" /* you want the con */ + $"6E65 6374 696F 6E20 746F 2062 6520 7375" /* nection to be su */ + $"7370 656E 6465 6420 7768 656E 2069 7420" /* spended when it */ + $"6F70 656E 7320 2D20 6F74 6865 7277 6973" /* opens - otherwis */ + $"652C 206C 6561 7665 2069 7420 6F75 7420" /* e, leave it out */ + $"8000 0777 6169 7469 6E67 7761 6974 5445" /* ..waitingwaitTE */ + $"5854 6573 6574 2074 6869 7320 746F 2022" /* XTeset this to " */ + $"7965 7322 2069 6620 796F 7520 7761 6E74" /* yes" if you want */ + $"2074 6865 2073 6372 6970 7420 746F 2077" /* the script to w */ + $"6169 7420 666F 7220 7468 6520 636F 6E6E" /* ait for the conn */ + $"6563 7469 6F6E 2074 6F20 6F70 656E 202D" /* ection to open - */ + $"206F 7468 6572 7769 7365 2C20 6C65 6176" /* otherwise, leav */ + $"6520 6974 206F 7574 8000 0773 656E 6420" /* e it out..send */ + $"6372 2C73 656E 6473 2061 2063 6172 7269" /* cr,sends a carri */ + $"6167 6520 7265 7475 726E 2074 6F20 7468" /* age return to th */ + $"6520 7265 6D6F 7465 2068 6F73 742E 0DFC" /* e remote host.. */ + $"726C 6654 7365 4352 6E75 6C6C 003C 0000" /* rlfTseCRnull.<.. */ + $"6E75 6C6C 0000 0000 0000 0D77 6169 7420" /* null.......wait */ + $"666F 7220 7465 7874 9077 6169 7473 2066" /* for textwaits f */ + $"6F72 2074 6865 2073 7065 6369 6669 6564" /* or the specified */ + $"2074 6578 7420 6F6E 2074 6865 2063 7572" /* text on the cur */ + $"7265 6E74 2063 6F6E 6E65 6374 696F 6E2C" /* rent connection, */ + $"2073 7573 7065 6E64 696E 6720 7468 6520" /* suspending the */ + $"4170 706C 6553 6372 6970 7420 616E 6420" /* AppleScript and */ + $"756E 2D73 7573 7065 6E64 696E 6720 7468" /* un-suspending th */ + $"6520 636F 6E6E 6563 7469 6F6E 2066 6F72" /* e connection for */ + $"2074 6865 2064 7572 6174 696F 6E20 6F66" /* the duration of */ + $"2074 6865 2077 6169 7432 726C 6654 5761" /* the wait2rlfTWa */ + $"6954 6E75 6C6C 0000 0000 5445 5854 1A74" /* iTnull....TEXT.t */ + $"6865 2074 6578 7420 666F 7220 7768 6963" /* he text for whic */ + $"6820 746F 2077 6169 7488 0000 0000 0773" /* h to wait.....s */ + $"7573 7065 6E64 1F73 7573 7065 6E64 7320" /* uspend.suspends */ + $"7468 6520 6375 7272 656E 7420 636F 6E6E" /* the current conn */ + $"6563 7469 6F6E 726C 6654 7375 7370 6E75" /* ectionrlfTsuspnu */ + $"6C6C 0032 0000 6E75 6C6C 0090 0000 0000" /* ll.2..null..... */ + $"0975 6E73 7573 7065 6E64 2175 6E73 7573" /* unsuspend!unsus */ + $"7065 6E64 7320 7468 6520 6375 7272 656E" /* pends the curren */ + $"7420 636F 6E6E 6563 7469 6F6E 726C 6654" /* t connectionrlfT */ + $"2173 7573 6E75 6C6C 0000 0000 6E75 6C6C" /* !susnull....null */ + $"00B9 0000 0000 0000 0000 0000" /* ........... */ }; data 'ALRT' (200, "Low Memory Alert", preload) { @@ -45,6 +130,14 @@ data 'CNTL' (133, "Large WFONT button") { $"000A 0000 07C7 00" /* ..... */ }; +data 'CNTL' (1001, "Tabs (Favorites)") { + $"0004 0004 0014 0140 0001 0100 0007 00D2" /* .......@....... */ + $"4550 0000 0007 3247 656E 6572 616C 0D4E" /* EP....2General.N */ + $"6574 776F 726B 0D54 6572 6D69 6E61 6C0D" /* etwork.Terminal. */ + $"5365 6375 7269 7479 0D4F 5450 0D53 5348" /* Security.OTP.SSH */ + $"0D46 6972 6577 616C 6C" /* .Firewall */ +}; + data 'CNTL' (1000, "Tabs (Terminals)") { $"0004 0004 0014 0140 0001 0100 0004 00D2" /* .......@....... */ $"4550 0000 0000 1C54 6572 6D69 6E61 6C0D" /* EP.....Terminal. */ @@ -52,35 +145,20 @@ data 'CNTL' (1000, "Tabs (Terminals)") { $"6C6F 72" /* lor */ }; -data 'CNTL' (128) { - $"0000 0000 0000 0000 0000 0100 0000 0000" /* ................ */ - $"0000 0000 0000 00" /* ....... */ +data 'CNTL' (2000, "Protocol Pop-up (Favorites)") { + $"0000 0000 0014 012C 0000 0100 0064 07D0" /* .......,.....d. */ + $"03F9 0000 0000 0950 726F 746F 636F 6C3A" /* .....Protocol: */ }; -data 'CNTL' (1001, "Tabs (Favorites)") { - $"0004 0004 0014 0140 0001 0100 0004 00D2" /* .......@....... */ - $"4550 0000 0000 2147 656E 6572 616C 0D4E" /* EP....!General.N */ - $"6574 776F 726B 0D54 6572 6D69 6E61 6C0D" /* etwork.Terminal. */ - $"5365 6375 7269 7479" /* Security */ +data 'CNTL' (2001, "SSH Pop-up (Favorites)") { + $"0000 0000 0014 012C 0000 0100 004B 07D1" /* .......,.....K. */ + $"03F9 0000 0000 0B45 6E63 7279 7074 696F" /* ......Encryptio */ + $"6E3A" /* n: */ }; -data 'crsr' (129) { - $"8001 0000 0060 0000 0092 0000 0000 0000" /* ....`......... */ - $"0000 0000 0000 0000 0000 FFFF FFEF FFE7" /* .......... */ - $"F803 FFE7 FFEF FFFF FFFF FFFF FFFF FFFF" /* . */ - $"0000 0000 0000 0000 0000 FFFF FFFF FFFF" /* .......... */ - $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ - $"0000 0000 0003 0001 0000 0000 0000 0000" /* ................ */ - $"0000 0000 8004 0000 0000 0010 0010 0000" /* ............... */ - $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ - $"0002 0001 0002 0000 0000 0000 00D2 0000" /* ............... */ - $"0000 0000 0000 0000 0000 0000 0000 FFFF" /* .............. */ - $"FFFF FFFF FDFF FFFF FD7F FFD5 555F FFFF" /* .U_ */ - $"FD7F FFFF FDFF FFFF FFFF FFFF FFFF FFFF" /* . */ - $"FFFF FFFF FFFF FFFF FFFF 0000 0000 0000" /* ...... */ - $"0000 0000 0000 0000 0002 0000 FFFF FFFF" /* ............ */ - $"FFFF 0001 FC00 F37D 052F 0003 0000 0000" /* ...}./...... */ - $"0000" /* .. */ +data 'CNTL' (2002, "Keymappings Pop-Up") { + $"0000 0000 0014 012C 0000 0100 004B 07D2" /* .......,.....K. */ + $"03F9 0000 0000 084B 6579 2053 6574 3A" /* ......Key Set: */ }; data 'crsr' (130) { @@ -121,12 +199,23 @@ data 'crsr' (131) { $"0000" /* .. */ }; -data 'CURS' (256, "CPos", purgeable, preload) { - $"0000 0000 0FE0 0FE0 0FE0 0FE0 0FE0 0FE0" /* .......... */ - $"0FE0 0FE0 0FE0 0FE0 0FE0 0FE0 0000 0000" /* .......... */ - $"0000 0000 0FE0 0820 0820 0820 0820 0820" /* ...... . . . . */ - $"0820 0820 0820 0820 0820 0FE0 0000 0000" /* . . . . . ..... */ - $"0007 000A" /* ... */ +data 'crsr' (129) { + $"8001 0000 0060 0000 0092 0000 0000 0000" /* ....`......... */ + $"0000 0000 0000 0000 0000 FFFF FFEF FFE7" /* .......... */ + $"F803 FFE7 FFEF FFFF FFFF FFFF FFFF FFFF" /* . */ + $"0000 0000 0000 0000 0000 FFFF FFFF FFFF" /* .......... */ + $"FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF" /* */ + $"0000 0000 0003 0001 0000 0000 0000 0000" /* ................ */ + $"0000 0000 8004 0000 0000 0010 0010 0000" /* ............... */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0002 0001 0002 0000 0000 0000 00D2 0000" /* ............... */ + $"0000 0000 0000 0000 0000 0000 0000 FFFF" /* .............. */ + $"FFFF FFFF FDFF FFFF FD7F FFD5 555F FFFF" /* .U_ */ + $"FD7F FFFF FDFF FFFF FFFF FFFF FFFF FFFF" /* . */ + $"FFFF FFFF FFFF FFFF FFFF 0000 0000 0000" /* ...... */ + $"0000 0000 0000 0000 0002 0000 FFFF FFFF" /* ............ */ + $"FFFF 0001 FC00 F37D 052F 0003 0000 0000" /* ...}./...... */ + $"0000" /* .. */ }; data 'CURS' (257, "Graphics", purgeable, preload) { @@ -153,6 +242,14 @@ data 'CURS' (290, "Xfer in progress", purgeable, preload) { $"0008 0006" /* .... */ }; +data 'CURS' (256, "CPos", purgeable, preload) { + $"0000 0000 0FE0 0FE0 0FE0 0FE0 0FE0 0FE0" /* .......... */ + $"0FE0 0FE0 0FE0 0FE0 0FE0 0FE0 0000 0000" /* .......... */ + $"0000 0000 0FE0 0820 0820 0820 0820 0820" /* ...... . . . . */ + $"0820 0820 0820 0820 0820 0FE0 0000 0000" /* . . . . . ..... */ + $"0007 000A" /* ... */ +}; + data 'dctb' (500) { $"0000 0000 0000 0004 0000 FFFF FFFF FFFF" /* .......... */ $"0001 0000 0000 0000 0002 0000 0000 0000" /* ................ */ @@ -324,8 +421,7 @@ data 'DITL' (200, "Low Memory Alert", preload) { }; data 'DITL' (259, "My IP Number", purgeable) { - $"0002 0000 0000 0050 00BE 0064 00FA 0402" /* .......P..d... */ - $"4F4B 0000 0000 000A 0048 003C 0104 880E" /* OK......H.<... */ + $"0001 0000 0000 000A 0048 003C 0104 880E" /* ........H.<... */ $"4950 2041 6464 7265 7373 3A0D 5E31 0000" /* IP Address:.^1.. */ $"0000 000A 0014 002A 0034 A002 0001" /* ......*.4... */ }; @@ -383,34 +479,33 @@ data 'DITL' (303, "Couldnt Connect", purgeable) { }; data 'DITL' (500, "Macros", purgeable) { - $"0019 0000 0000 00E0 01A4 00F4 01E8 0402" /* ............ */ - $"4F4B 0000 0000 00E0 00A4 00F4 00E4 0406" /* OK.......... */ - $"4361 6E63 656C 0000 0000 0008 0000 0020" /* Cancel......... */ - $"0018 0402 1130 0000 0000 0030 0000 0048" /* .....0.....0...H */ - $"0018 0402 1131 0000 0000 0058 0000 0070" /* .....1.....X...p */ - $"0018 0402 1132 0000 0000 0080 0000 0098" /* .....2........ */ - $"0018 0402 1133 0000 0000 00A8 0000 00C0" /* .....3........ */ - $"0018 0402 1134 0000 0000 0008 00F8 0020" /* .....4........ */ - $"0110 0402 1135 0000 0000 0030 00F8 0048" /* .....5.....0..H */ - $"0110 0402 1136 0000 0000 0058 00F8 0070" /* .....6.....X..p */ - $"0110 0402 1137 0000 0000 0080 00F8 0098" /* .....7....... */ - $"0110 0402 1138 0000 0000 00A8 00F8 00C0" /* .....8....... */ - $"0110 0402 1139 0000 0000 0008 0020 0028" /* .....9....... .( */ - $"00E8 1000 0000 0000 0030 0020 0050 00E8" /* ........0. .P. */ - $"1000 0000 0000 0058 0020 0078 00E8 1000" /* .......X. .x... */ - $"0000 0000 0080 0020 00A0 00E8 1000 0000" /* ...... ...... */ - $"0000 00A8 0020 00C8 00E8 1000 0000 0000" /* .... ........ */ - $"0008 0118 0028 01E0 1000 0000 0000 0030" /* .....(........0 */ - $"0118 0050 01E0 1000 0000 0000 0058 0118" /* ...P........X.. */ - $"0078 01E0 1000 0000 0000 0080 0118 00A0" /* .x........... */ - $"01E0 1000 0000 0000 00A8 0118 00C8 01E0" /* ............ */ - $"1000 0000 0000 00E0 0144 00F4 0194 0409" /* ........D... */ - $"496D 706F 7274 2E2E 2E02 0000 0000 00E0" /* Import......... */ - $"00EC 00F4 013C 0409 4578 706F 7274 2E2E" /* ...<.Export.. */ - $"2E02 0000 0000 00E0 0007 00F4 007F 040F" /* .............. */ - $"5361 7665 2061 7320 4465 6661 756C 7400" /* Save as Default. */ - $"0000 0000 0000 0000 0000 0000 0104 0001" /* ................ */ - $"01F4" /* . */ + $"001A 0000 0000 0104 01C8 0118 020C 0402" /* ............... */ + $"4F4B 0000 0000 0104 00C8 0118 0108 0406" /* OK............. */ + $"4361 6E63 656C 0000 0000 0036 0005 0048" /* Cancel.....6...H */ + $"0055 0800 0000 0000 005E 0005 0070 0055" /* .U.......^...p.U */ + $"0800 0000 0000 0086 0005 0098 0055 0800" /* ...........U.. */ + $"0000 0000 00AE 0005 00C0 0055 0800 0000" /* .........U.... */ + $"0000 00D6 0005 00E8 0055 0800 0000 0000" /* .......U...... */ + $"0036 0104 0048 0154 0800 0000 0000 005E" /* .6...H.T.......^ */ + $"0104 0070 0154 0800 0000 0000 0086 0104" /* ...p.T......... */ + $"0098 0154 0800 0000 0000 00AE 0104 00C0" /* ..T.......... */ + $"0154 0800 0000 0000 00D6 0104 00E8 0154" /* .T...........T */ + $"0800 0000 0000 002C 004D 004C 0101 1000" /* .......,.M.L.... */ + $"0000 0000 0054 004D 0074 0101 1000 0000" /* .....T.M.t...... */ + $"0000 007C 004D 009C 0101 1000 0000 0000" /* ...|.M......... */ + $"00A4 004D 00C4 0101 1000 0000 0000 00CC" /* ..M.......... */ + $"004D 00EC 0101 1000 0000 0000 002C 0154" /* .M..........,.T */ + $"004C 0208 1000 0000 0000 0054 0154 0074" /* .L.........T.T.t */ + $"0208 1000 0000 0000 007C 0154 009C 0208" /* .........|.T... */ + $"1000 0000 0000 00A4 0154 00C4 0208 1000" /* ........T..... */ + $"0000 0000 00CC 0154 00EC 0208 1000 0000" /* ......T....... */ + $"0000 0104 0168 0118 01B8 0409 496D 706F" /* .....h....Impo */ + $"7274 2E2E 2E00 0000 0000 0104 0110 0118" /* rt.............. */ + $"0160 0409 4578 706F 7274 2E2E 2E00 0000" /* .`.Export...... */ + $"0000 0104 000C 0118 0084 040F 5361 7665" /* ...........Save */ + $"2061 7320 4465 6661 756C 7401 0000 0000" /* as Default..... */ + $"0000 0000 0000 0000 0104 0001 01F4 0000" /* ............... */ + $"0000 000A 0005 001E 0131 0702 07D2" /* ........1... */ }; data 'DITL' (640, "Generic Errors", preload) { @@ -617,71 +712,6 @@ data 'DITL' (5500, "Screen Size", purgeable) { $"6E20 6469 6D65 6E73 696F 6E73" /* n dimensions */ }; -data 'DITL' (7004, "Session Config", purgeable) { - $"0034 0000 0000 00DC 0106 00F0 0140 0402" /* .4.........@.. */ - $"4F4B 0000 0000 00DC 00C0 00F0 00FA 0406" /* OK.......... */ - $"4361 6E63 656C 0000 0000 0049 0055 0059" /* Cancel.....I.U.Y */ - $"00A0 0702 0082 0000 0000 0049 009F 0059" /* .........I..Y */ - $"00EA 0702 0082 0000 0000 0049 00ED 0059" /* .........I..Y */ - $"0138 0702 0082 0000 0000 0033 0055 0043" /* .8........3.U.C */ - $"00A0 0702 0082 0000 0000 0033 009F 0043" /* .........3..C */ - $"00EA 0702 0082 0000 0000 0033 0055 0043" /* .........3.U.C */ - $"00A0 0702 0082 0000 0000 0033 009F 0043" /* .........3..C */ - $"00EA 0702 0082 0000 0000 005F 000A 006F" /* ........._..o */ - $"0084 0702 0084 0000 0000 006E 000A 007E" /* .........n..~ */ - $"0084 0702 0084 0000 0000 005F 000A 006F" /* ........._..o */ - $"0084 0702 0084 0000 0000 008C 000A 009C" /* ........... */ - $"0084 0702 0084 0000 0000 006E 000A 007E" /* .........n..~ */ - $"0084 0702 0084 0000 0000 0033 000A 0043" /* .........3..C */ - $"0123 0702 0083 0000 0000 0042 000A 0052" /* .#........B..R */ - $"0123 0702 0083 0000 0000 007D 000A 008D" /* .#........}.. */ - $"0084 0702 0084 0000 0000 001F 004A 002C" /* ...........J., */ - $"00F5 1000 0000 0000 0034 004A 0041 00F5" /* ........4.J.A. */ - $"1000 0000 0000 0049 004A 0056 0086 1005" /* .......I.J.V... */ - $"3530 3030 3000 0000 0000 0036 00F2 0044" /* 50000......6..D */ - $"0117 1003 3230 3000 0000 0000 0050 0100" /* ....200......P.. */ - $"0060 0117 1000 0000 0000 006B 0100 007B" /* .`.........k...{ */ - $"0117 1000 0000 0000 0086 0100 0096 0117" /* .............. */ - $"1000 0000 0000 005F 0063 006F 00C0 0000" /* ......._.c.o... */ - $"0000 0000 0074 0063 0084 00C0 0000 0000" /* .....t.c...... */ - $"0000 0033 000A 0043 0044 880A 486F 7374" /* ...3..C.DHost */ - $"204E 616D 653A 0000 0000 001E 000A 002E" /* Name:......... */ - $"0044 8806 416C 6961 733A 0000 0000 0049" /* .D.Alias:.....I */ - $"000A 0059 0044 8805 506F 7274 3A00 0000" /* ..Y.D.Port:... */ - $"0000 0049 000A 0059 0032 8804 5445 4B3A" /* ...I..Y.2.TEK: */ - $"0000 0000 0033 000A 0043 0053 880D 5061" /* .....3..C.S.Pa */ - $"7374 6520 4D65 7468 6F64 3A00 0000 0000" /* ste Method:..... */ - $"0033 000A 0043 0053 880D 4465 6C65 7465" /* .3..C.S.Delete */ - $"2053 656E 6473 3A00 0000 0000 0050 00C6" /* Sends:......P. */ - $"0060 00F8 880A 496E 7465 7272 7570 743A" /* .`.Interrupt: */ - $"0000 0000 006B 00C6 007B 00F8 8808 5375" /* .....k..{..Su */ - $"7370 656E 643A 0000 0000 0086 00C6 0096" /* spend:....... */ - $"00F8 8807 5265 7375 6D65 3A00 0000 0000" /* ..Resume:..... */ - $"005F 000A 006F 0046 8809 5465 726D 696E" /* ._..o.FTermin */ - $"616C 3A00 0000 0000 0074 000A 0082 0061" /* al:......t...a */ - $"8812 5472 616E 736C 6174 696F 6E20 5461" /* .Translation Ta */ - $"626C 653A 0000 0000 0049 000A 0059 006E" /* ble:.....I..Y.n */ - $"8813 4E65 7477 6F72 6B20 426C 6F63 6B20" /* .Network Block */ - $"5369 7A65 3A00 0000 0000 0048 0074 0058" /* Size:......H.t.X */ - $"009C 1000 0000 0000 0078 00C8 008C 0136" /* ........x...6 */ - $"040E 5361 7665 2061 7320 5365 742E 2E2E" /* ..Save as Set... */ - $"0000 0000 005F 00C8 0073 0136 040D 4164" /* ....._..s.6..Ad */ - $"6420 746F 2053 6574 2E2E 2E00 0000 0000" /* d to Set........ */ - $"007D 000A 008D 0084 0702 0084 0000 0000" /* .}.......... */ - $"005F 00A5 006F 011F 0702 0084 0000 0000" /* ._..o......... */ - $"006E 00A5 007E 011F 0702 0084 0000 0000" /* .n..~......... */ - $"0000 0000 0000 0000 0104 0001 1B5C 0000" /* .............\.. */ - $"0000 0004 0004 0014 0140 0702 03E9 0000" /* .........@..... */ - $"0000 0051 000A 0061 0123 0702 0083 0000" /* ...Q..a.#..... */ - $"0000 0060 000A 0070 0123 0702 0083 0000" /* ...`..p.#..... */ - $"0000 006F 000A 007F 0123 0702 0083 0000" /* ...o....#..... */ - $"0000 007E 000A 008E 0123 0702 0083 0000" /* ...~...#..... */ - $"0000 0091 000A 00A1 0055 880D 4F54 5020" /* ......U.OTP */ - $"5061 7373 776F 7264 3A00 0000 0000 0091" /* Password:...... */ - $"005D 00A1 00C8 1000 0000 0000 00A5 000A" /* .].......... */ - $"00B5 0123 0702 0083" /* ..#... */ -}; - data 'DITL' (2001, "Close Connection", purgeable, preload) { $"0003 0000 0000 0055 0140 0069 017C 0402" /* .......U.@.i.|.. */ $"4F4B 0000 0000 0055 00FA 0069 0136 0406" /* OK.....U..i.6.. */ @@ -705,12 +735,12 @@ data 'DITL' (132, purgeable) { data 'DITL' (501, "flash.about", purgeable) { $"0001 0000 0000 0000 0000 012C 0190 4002" /* ...........,.@. */ - $"0401 0000 0000 0000 00DB 0014 018C 0000" /* .............. */ + $"0401 0000 0000 FFFE 0009 0012 00BA 0000" /* ............ */ }; data 'DITL' (7001, "Main Prefs", purgeable) { - $"0024 0000 0000 00FA 0136 010E 0172 0402" /* .$......6...r.. */ - $"4F4B 0000 0000 00FA 00F0 010E 012C 0406" /* OK.........,.. */ + $"0025 0000 0000 0104 0136 0118 0172 0402" /* .%.......6...r.. */ + $"4F4B 0000 0000 0104 00F0 0118 012C 0406" /* OK..........,.. */ $"4361 6E63 656C 0000 0000 0084 000C 0094" /* Cancel........ */ $"0086 0702 0084 0000 0000 0094 000C 00A4" /* ............ */ $"0086 0702 0084 0000 0000 007A 00BC 008A" /* .........z.. */ @@ -724,9 +754,9 @@ data 'DITL' (7001, "Main Prefs", purgeable) { $"01D5 0702 0083 0000 0000 006A 00BC 007A" /* .........j..z */ $"01D5 0702 0083 0000 0000 0018 0079 0028" /* ...........y.( */ $"009A 1000 0000 0000 0030 0079 0040 009A" /* ........0.y.@. */ - $"1000 0000 0000 00DE 00BC 00F2 0145 0412" /* ..........E.. */ + $"1000 0000 0000 00E8 00BC 00FC 0145 0412" /* ..........E.. */ $"5365 6C65 6374 2041 7070 6C69 6361 7469" /* Select Applicati */ - $"6F6E 0000 0000 00DF 000C 00EF 0085 8815" /* on.......... */ + $"6F6E 0000 0000 00E9 000C 00F9 0085 8815" /* on.......... */ $"4361 7074 7572 6520 4669 6C65 2043 7265" /* Capture File Cre */ $"6174 6F72 3A00 0000 0000 0048 0079 0058" /* ator:......H.y.X */ $"009A 1000 0000 0000 0048 000C 0058 0071" /* ........H...X.q */ @@ -734,31 +764,31 @@ data 'DITL' (7001, "Main Prefs", purgeable) { $"0000 0000 0060 0079 006F 009A 1000 0000" /* .....`.y.o..... */ $"0000 0095 008D 00A5 00A5 1000 0000 0000" /* ............ */ $"0030 000C 0041 006F 880D 5365 6E64 2054" /* .0...A.o.Send T */ - $"696D 656F 7574 3A00 0000 0000 00FA 000C" /* imeout:........ */ - $"010E 006E 040B 414E 5349 2043 6F6C 6F72" /* ...n..ANSI Color */ - $"7302 0000 0000 00DF 008D 00EF 00AE 1000" /* s........... */ + $"696D 656F 7574 3A00 0000 0000 0104 000C" /* imeout:......... */ + $"0118 006E 040B 414E 5349 2043 6F6C 6F72" /* ...n..ANSI Color */ + $"7302 0000 0000 00E9 008D 00F9 00AE 1000" /* s........... */ $"0000 0000 0096 0078 00A5 0086 8802 6279" /* ......x...by */ $"0000 0000 0018 000C 0028 0075 0815 436F" /* .........(.u..Co */ $"7079 2054 6162 6C65 2074 6872 6573 686F" /* py Table thresho */ $"6C64 3A00 0000 0000 005F 000C 006F 006D" /* ld:......_...o.m */ $"880A 5469 6D65 736C 6963 653A 0000 0000" /* Timeslice:.... */ - $"0003 000A 000F 0057 C002 0100 0000 0000" /* ......W....... */ - $"0010 000A 0011 0168 C002 0800 0000 0000" /* ......h....... */ - $"00AA 00BC 00BA 01D5 0702 0083 0000 0000" /* ........... */ - $"0074 000C 0084 0086 0702 0084 0000 0000" /* .t........... */ - $"00A4 000C 00B4 0086 0702 0084 0000 0000" /* ............ */ - $"00B4 000C 00C4 0086 0702 0084 0000 0000" /* ............ */ - $"00C4 000C 00D4 0086 0702 0084 0000 0000" /* ............ */ - $"0000 0000 0000 0000 0104 0001 1B59 0000" /* .............Y.. */ - $"0000 00BA 00BC 00CA 01D5 0702 0083 0000" /* ........... */ - $"0000 00CA 00BC 00DA 01D5 0702 0083" /* ......... */ + $"0003 0176 000F 01C3 8800 0000 0000 0120" /* ...v...È...... */ + $"011E 012F 0158 8800 0000 0000 00AA 00BC" /* .../.X....... */ + $"00BA 01D5 0702 0083 0000 0000 0074 000C" /* ..........t.. */ + $"0084 0086 0702 0084 0000 0000 00A4 000C" /* ............ */ + $"00B4 0086 0702 0084 0000 0000 00B4 000C" /* ............ */ + $"00C4 0086 0702 0084 0000 0000 00C4 000C" /* ............ */ + $"00D4 0086 0702 0084 0000 0000 0000 0000" /* ............. */ + $"0000 0000 0104 0001 1B59 0000 0000 00BA" /* .........Y..... */ + $"00BC 00CA 01D5 0702 0083 0000 0000 00CA" /* ........... */ + $"00BC 00DA 01D5 0702 0083 0000 0000 00D4" /* ........... */ + $"000C 00E4 0086 0702 0084" /* ....... */ }; data 'DITL' (1023, "Opening Dialog", purgeable, preload) { $"0002 0000 0000 0000 0000 012C 0190 4002" /* ...........,.@. */ - $"0401 0000 0000 0000 00DB 0014 018C 0000" /* .............. */ - $"0000 0000 012D 0001 013B 00B6 880E 5374" /* .....-...;..St */ - $"6172 7469 6E67 2055 702E 2E2E" /* arting Up... */ + $"0401 0000 0000 FFFE 0008 0012 00B9 0000" /* ............. */ + $"0000 0000 012D 0001 013B 00B6 8800" /* .....-...;.. */ }; data 'DITL' (8000, "OTP Password Entry", purgeable) { @@ -781,7 +811,7 @@ data 'DITL' (8000, "OTP Password Entry", purgeable) { }; data 'DITL' (7003, "Terminal Configuration", purgeable) { - $"002F 0000 0000 00DC 0106 00F0 0140 0402" /* ./.........@.. */ + $"0031 0000 0000 00DC 0106 00F0 0140 0402" /* .1.........@.. */ $"4F4B 0000 0000 00DC 00C0 00F0 00FA 0406" /* OK.......... */ $"4361 6E63 656C 0000 0000 0035 00A1 0045" /* Cancel.....5..E */ $"00DC 0000 0000 0000 004A 00A1 005A 00DC" /* ........J..Z. */ @@ -815,14 +845,14 @@ data 'DITL' (7003, "Terminal Configuration", purgeable) { $"0082 000B 0092 0056 880B 5363 726F 6C6C" /* .....V.Scroll */ $"6261 636B 3A00 0000 0000 0081 0069 0091" /* back:.......i. */ $"0096 1003 3230 3000 0000 0000 009B 000B" /* ...200........ */ - $"00AB 0085 0702 0084 0000 0000 0050 00B2" /* ..........P. */ - $"0060 012C 0702 0084 0000 0000 005F 00B2" /* .`.,........_. */ - $"006F 012C 0702 0084 0000 0000 0037 000B" /* .o.,........7.. */ + $"00AB 0085 0702 0084 0000 0000 004B 00B2" /* ..........K. */ + $"005B 012C 0702 0084 0000 0000 005A 00B2" /* .[.,........Z. */ + $"006A 012C 0702 0084 0000 0000 0037 000B" /* .j.,........7.. */ $"0047 0063 880A 456D 756C 6174 696F 6E3A" /* .G.cEmulation: */ $"0000 0000 0037 00BE 0047 0138 0702 0084" /* .....7..G.8... */ $"0000 0000 0055 00BE 0065 0138 0702 0084" /* .....U..e.8... */ - $"0000 0000 006E 00B2 007E 012C 0702 0084" /* .....n..~.,... */ - $"0000 0000 007D 00B2 008D 012C 0702 0084" /* .....}...,... */ + $"0000 0000 0069 00B2 0079 012C 0702 0084" /* .....i..y.,... */ + $"0000 0000 0078 00B2 0088 012C 0702 0084" /* .....x...,... */ $"0000 0000 0046 00BE 0056 0138 0702 0084" /* .....F..V.8... */ $"0000 0000 0037 0067 0047 00B2 0702 0082" /* .....7.g.G.... */ $"0000 0000 0037 00B9 0047 0104 0702 0082" /* .....7..G..... */ @@ -841,7 +871,160 @@ data 'DITL' (7003, "Terminal Configuration", purgeable) { $"0104 0001 1B5B 0000 0000 0004 0004 0014" /* .....[.......... */ $"0140 0702 03E8 0000 0000 0052 00A6 0062" /* .@........R..b */ $"0120 0702 0084 0000 0000 00B0 000A 00C0" /* . .......... */ - $"0123 0702 0083" /* .#... */ + $"0123 0702 0083 0000 0000 0087 00B2 0097" /* .#.......... */ + $"012C 0702 0084 0000 0000 00AA 000B 00BA" /* .,........... */ + $"0085 0702 0084" /* .... */ +}; + +data 'DITL' (10000, "Randomization", purgeable) { + $"0001 0000 0000 0005 0005 0047 0143 088C" /* ...........G.C. */ + $"506C 6561 7365 2074 7970 6520 3531 3220" /* Please type 512 */ + $"7261 6E64 6F6D 2063 6861 7261 6374 6572" /* random character */ + $"7320 6E6F 772E 2054 6865 2063 6861 7261" /* s now. The chara */ + $"6374 6572 7320 616E 6420 7468 6520 696E" /* cters and the in */ + $"7465 7276 616C 7320 6265 7477 6565 6E20" /* tervals between */ + $"7468 656D 2077 696C 6C20 6265 2075 7365" /* them will be use */ + $"6420 746F 2069 6E69 7469 616C 697A 6520" /* d to initialize */ + $"7468 6520 7261 6E64 6F6D 206E 756D 6265" /* the random numbe */ + $"7220 6765 6E65 7261 746F 722E 0000 0000" /* r generator..... */ + $"005D 0005 006F 0053 8801 3000" /* .]...o.S.0. */ +}; + +data 'DITL' (10001, "Password Prompt", purgeable) { + $"0004 0000 0000 005D 0107 0071 0141 0402" /* .......]...q.A.. */ + $"4F4B 0000 0000 005D 00C0 0071 00FA 0406" /* OK.....]..q... */ + $"4361 6E63 656C 0000 0000 003C 0052 004C" /* Cancel.....<.R.L */ + $"013E 1000 0000 0000 000D 0017 002D 0037" /* .>...........-.7 */ + $"A002 0081 0000 0000 000D 004E 002D 0141" /* .........N.-.A */ + $"882B 506C 6561 7365 2065 6E74 6572 2074" /* +Please enter t */ + $"6865 2070 6173 7377 6F72 6420 666F 7220" /* he password for */ + $"7468 6973 2073 6572 7669 6365 3A6C" /* this service:l */ +}; + +data 'DITL' (10002, "Host Key Unknown", purgeable) { + $"0004 0000 0000 005D 00D3 0071 0141 040D" /* .......]..q.A.. */ + $"4163 6365 7074 2026 2053 6176 6500 0000" /* Accept & Save... */ + $"0000 005D 006E 0071 00C9 040B 4163 6365" /* ...].n.q...Acce */ + $"7074 204F 6E63 6500 0000 0000 005D 002A" /* pt Once......].* */ + $"0071 0064 0406 4361 6E63 656C 0000 0000" /* .q.d..Cancel.... */ + $"000D 0017 002D 0037 A002 0002 0000 0000" /* .....-.7....... */ + $"000D 004E 004F 0141 8854 5468 6520 6B65" /* ...N.O.ATThe ke */ + $"7920 666F 7220 7468 6973 2068 6F73 7420" /* y for this host */ + $"6861 7320 6E65 7665 7220 6265 656E 2073" /* has never been s */ + $"6565 6E20 6265 666F 7265 2E20 4172 6520" /* een before. Are */ + $"796F 7520 7375 7265 2079 6F75 2077 616E" /* you sure you wan */ + $"7420 746F 2074 7275 7374 2069 743F" /* t to trust it? */ +}; + +data 'DITL' (10003, "Host Key Changed", purgeable) { + $"0004 0000 0000 0076 00D3 008A 0141 040D" /* .......v...A.. */ + $"4163 6365 7074 2026 2053 6176 6500 0000" /* Accept & Save... */ + $"0000 0076 006E 008A 00C9 040B 4163 6365" /* ...v.n....Acce */ + $"7074 204F 6E63 6500 0000 0000 0076 002A" /* pt Once......v.* */ + $"008A 0064 0406 4361 6E63 656C 0000 0000" /* ..d..Cancel.... */ + $"000D 0017 002D 0037 A002 0002 0000 0000" /* .....-.7....... */ + $"000D 004E 006E 0141 88B5 5468 6520 6B65" /* ...N.n.AThe ke */ + $"7920 666F 7220 7468 6973 2068 6F73 7420" /* y for this host */ + $"646F 6573 206E 6F74 206D 6174 6368 2061" /* does not match a */ + $"6E79 206F 6620 7468 6520 6B65 7973 2073" /* ny of the keys s */ + $"6176 6564 2066 726F 6D20 7468 6973 2068" /* aved from this h */ + $"6F73 742E 2059 4F55 2043 4F55 4C44 2042" /* ost. YOU COULD B */ + $"4520 5448 4520 5355 424A 4543 5420 4F46" /* E THE SUBJECT OF */ + $"2041 204D 414E 2D49 4E2D 5448 452D 4D49" /* A MAN-IN-THE-MI */ + $"4444 4C45 2041 5454 4143 4B20 5249 4748" /* DDLE ATTACK RIGH */ + $"5420 4E4F 572E 2041 7265 2079 6F75 2073" /* T NOW. Are you s */ + $"7572 6520 796F 7520 7761 6E74 2074 6F20" /* ure you want to */ + $"7472 7573 7420 7468 6973 206B 6579 3F00" /* trust this key?. */ +}; + +data 'DITL' (7004, "Session Config", purgeable) { + $"0048 0000 0000 00DC 0106 00F0 0140 0402" /* .H.........@.. */ + $"4F4B 0000 0000 00DC 00C0 00F0 00FA 0406" /* OK.......... */ + $"4361 6E63 656C 0000 0000 004A 0055 005A" /* Cancel.....J.U.Z */ + $"00A0 0702 0082 0000 0000 004A 009F 005A" /* .........J..Z */ + $"00EA 0702 0082 0000 0000 004A 00ED 005A" /* .........J..Z */ + $"0138 0702 0082 0000 0000 0034 0055 0044" /* .8........4.U.D */ + $"00A0 0702 0082 0000 0000 0034 009F 0044" /* .........4..D */ + $"00EA 0702 0082 0000 0000 0034 0055 0044" /* .........4.U.D */ + $"00A0 0702 0082 0000 0000 0034 009F 0044" /* .........4..D */ + $"00EA 0702 0082 0000 0000 0060 000A 0070" /* .........`..p */ + $"0084 0702 0084 0000 0000 006F 000A 007F" /* .........o... */ + $"0084 0702 0084 0000 0000 0060 000A 0070" /* .........`..p */ + $"0084 0702 0084 0000 0000 008D 000A 009D" /* ........... */ + $"0084 0702 0084 0000 0000 006F 000A 007F" /* .........o... */ + $"0084 0702 0084 0000 0000 0043 000A 0053" /* .........C..S */ + $"0123 0702 0083 0000 0000 0034 000A 0044" /* .#........4..D */ + $"0123 0702 0083 0000 0000 007E 000A 008E" /* .#........~.. */ + $"0084 0702 0084 0000 0000 001F 004A 002C" /* ...........J., */ + $"00F5 1000 0000 0000 0035 004A 0042 00F5" /* ........5.J.B. */ + $"1000 0000 0000 004A 004A 0057 0086 1005" /* .......J.J.W... */ + $"3530 3030 3000 0000 0000 0037 00F2 0045" /* 50000......7..E */ + $"0117 1003 3230 3000 0000 0000 0051 0100" /* ....200......Q.. */ + $"0061 0117 1000 0000 0000 006C 0100 007C" /* .a.........l...| */ + $"0117 1000 0000 0000 0087 0100 0097 0117" /* .............. */ + $"1000 0000 0000 0060 0063 0070 00C0 0000" /* .......`.c.p... */ + $"0000 0000 0075 0063 0085 00C0 0000 0000" /* .....u.c...... */ + $"0000 0034 000A 0044 0044 880A 486F 7374" /* ...4..D.DHost */ + $"204E 616D 653A 0000 0000 001E 000A 002E" /* Name:......... */ + $"0044 8806 416C 6961 733A 0000 0000 004A" /* .D.Alias:.....J */ + $"000A 005A 0044 8805 506F 7274 3A00 0000" /* ..Z.D.Port:... */ + $"0000 004A 000A 005A 0032 8804 5445 4B3A" /* ...J..Z.2.TEK: */ + $"0000 0000 0034 000A 0044 0053 880D 5061" /* .....4..D.S.Pa */ + $"7374 6520 4D65 7468 6F64 3A00 0000 0000" /* ste Method:..... */ + $"0034 000A 0044 0053 880D 4465 6C65 7465" /* .4..D.S.Delete */ + $"2053 656E 6473 3A00 0000 0000 0051 00C6" /* Sends:......Q. */ + $"0061 00F8 880A 496E 7465 7272 7570 743A" /* .a.Interrupt: */ + $"0000 0000 006C 00C6 007C 00F8 8808 5375" /* .....l..|..Su */ + $"7370 656E 643A 0000 0000 0087 00C6 0097" /* spend:....... */ + $"00F8 8807 5265 7375 6D65 3A00 0000 0000" /* ..Resume:..... */ + $"0060 000A 0070 0046 8809 5465 726D 696E" /* .`..p.FTermin */ + $"616C 3A00 0000 0000 0075 000A 0083 0061" /* al:......u...a */ + $"8812 5472 616E 736C 6174 696F 6E20 5461" /* .Translation Ta */ + $"626C 653A 0000 0000 004A 000A 005A 006E" /* ble:.....J..Z.n */ + $"8813 4E65 7477 6F72 6B20 426C 6F63 6B20" /* .Network Block */ + $"5369 7A65 3A00 0000 0000 0049 0074 0059" /* Size:......I.t.Y */ + $"009C 1000 0000 0000 0079 00C8 008D 0136" /* ........y...6 */ + $"040E 5361 7665 2061 7320 5365 742E 2E2E" /* ..Save as Set... */ + $"0000 0000 0060 00C8 0074 0136 040D 4164" /* .....`..t.6..Ad */ + $"6420 746F 2053 6574 2E2E 2E00 0000 0000" /* d to Set........ */ + $"007E 000A 008E 0084 0702 0084 0000 0000" /* .~.......... */ + $"0060 00A5 0070 011F 0702 0084 0000 0000" /* .`..p......... */ + $"006F 00A5 007F 011F 0702 0084 0000 0000" /* .o............ */ + $"0000 0000 0000 0000 0104 0001 1B5C 0000" /* .............\.. */ + $"0000 0004 0004 0014 0140 0702 03E9 0000" /* .........@..... */ + $"0000 0052 000A 0062 0123 0702 0083 0000" /* ...R..b.#..... */ + $"0000 0061 000A 0071 0123 0702 0083 0000" /* ...a..q.#..... */ + $"0000 0070 000A 0080 0123 0702 0083 0000" /* ...p...#..... */ + $"0000 007F 000A 008F 0123 0702 0083 0000" /* .......#..... */ + $"0000 0092 000A 00A2 0055 880D 4F54 5020" /* ......U.OTP */ + $"5061 7373 776F 7264 3A00 0000 0000 0092" /* Password:...... */ + $"005D 00A2 00C8 1000 0000 0000 00A6 000A" /* .].......... */ + $"00B6 0123 0702 0083 0000 0000 0053 000A" /* ..#........S. */ + $"0067 0136 0702 07D0 0000 0000 006C 000A" /* .g.6........l. */ + $"007C 0055 8809 5573 6572 6E61 6D65 3A00" /* .|.UUsername:. */ + $"0000 0000 0080 000A 0090 0055 8809 5061" /* ........UPa */ + $"7373 776F 7264 3A00 0000 0000 0094 000A" /* ssword:....... */ + $"00A4 005C 8810 436C 6965 6E74 2075 7365" /* ..\.Client use */ + $"726E 616D 653A 0000 0000 00A8 000A 00B8" /* rname:....... */ + $"0055 8808 436F 6D6D 616E 643A 0000 0000" /* .U.Command:.... */ + $"006C 005F 0078 0137 1000 0000 0000 0080" /* .l._.x.7....... */ + $"005F 008C 0137 1000 0000 0000 0094 005F" /* ._..7........_ */ + $"00A0 0137 1000 0000 0000 00A8 005F 00B4" /* ..7........_. */ + $"0137 1000 0000 0000 0053 000A 0067 0136" /* .7.......S..g.6 */ + $"0702 07D1 0000 0000 0039 005A 004D 00F0" /* ........9.Z.M. */ + $"0411 496E 6974 6961 6C69 7A65 2053 5348" /* ..Initialize SSH */ + $"2E2E 2E00 0000 0000 0033 000A 0043 0084" /* .........3..C. */ + $"0702 0084 0000 0000 0043 0019 0053 0132" /* ........C...S.2 */ + $"0702 0083 0000 0000 005A 0050 0067 00E6" /* ........Z.P.g. */ + $"1000 0000 0000 005A 010E 0067 012E 1000" /* .......Z...g.... */ + $"0000 0000 0059 000A 0067 0048 880B 534F" /* .....Y..g.H.SO */ + $"434B 5320 486F 7374 3A00 0000 0000 0059" /* CKS Host:......Y */ + $"00EC 0069 0107 8805 506F 7274 3A00 0000" /* ..i...Port:... */ + $"0000 0072 000A 0080 0048 8809 5573 6572" /* ...r...HUser */ + $"6E61 6D65 3A00 0000 0000 0073 0050 0080" /* name:......s.P. */ + $"00E6 1000 0000 0000 0091 0046 00A5 0104" /* .........F... */ + $"0416 4564 6974 2053 6573 7369 6F6E 204D" /* ..Edit Session M */ + $"6163 726F 732E 2E2E" /* acros... */ }; data 'DLOG' (128, "Resolver Error", purgeable) { @@ -880,7 +1063,7 @@ data 'DLOG' (195, "DNR Error Alert", purgeable) { }; data 'DLOG' (259, "My IP Number", purgeable) { - $"0062 007F 00CC 0186 0000 0100 0100 0000" /* .b............ */ + $"0062 007F 009A 0188 0000 0100 0100 0000" /* .b............ */ $"0000 0103 0A49 5020 4164 6472 6573 7300" /* ....IP Address. */ $"300A" /* 0 */ }; @@ -907,7 +1090,7 @@ data 'DLOG' (303, "Couldn't Connect", purgeable) { }; data 'DLOG' (500, "Macros", purgeable) { - $"003C 000A 0136 01FE 0004 0100 0100 0000" /* .<..6......... */ + $"003C 000A 015E 0221 0004 0100 0100 0000" /* .<..^.!........ */ $"0000 01F4 0D53 6574 204D 6163 726F 732E" /* ....Set Macros. */ $"2E2E 4546" /* ..EF */ }; @@ -1018,11 +1201,41 @@ data 'DLOG' (8000, "OTP Password Entry") { }; data 'DLOG' (7001, "Main Prefs", purgeable) { - $"0088 00D0 01A0 0253 0005 0000 0000 0000" /* ....S........ */ + $"0044 004C 0166 01CF 0005 0000 0000 0000" /* .D.L.f......... */ $"0000 1B59 0E50 7265 6665 7265 6E63 6573" /* ...Y.Preferences */ $"2E2E 2E00 0000" /* ...... */ }; +data 'DLOG' (10000, "Randomization", purgeable) { + $"0030 0028 00A2 0174 0005 0100 0000 0000" /* .0.(..t........ */ + $"0000 2710 0D52 616E 646F 6D69 7A61 7469" /* ..'..Randomizati */ + $"6F6E 300A" /* on0 */ +}; + +data 'DLOG' (10001, "Password Prompt", purgeable) { + $"0082 0082 0100 01D0 0005 0100 0000 0000" /* ............. */ + $"0000 2711 0E45 6E74 6572 2050 6173 7377" /* ..'..Enter Passw */ + $"6F72 6474 300A" /* ordt0 */ +}; + +data 'DLOG' (10002, "Host Key Unknown", purgeable) { + $"0082 0082 0100 01D0 0005 0100 0000 0000" /* ............. */ + $"0000 2712 1048 6F73 7420 4B65 7920 556E" /* ..'..Host Key Un */ + $"6B6E 6F77 6E0A 300A" /* known0 */ +}; + +data 'DLOG' (10003, "Host Key Changed", purgeable) { + $"0082 0082 0119 01D0 0005 0100 0000 0000" /* ............. */ + $"0000 2713 1048 6F73 7420 4B65 7920 4368" /* ..'..Host Key Ch */ + $"616E 6765 640A 300A" /* anged0 */ +}; + +data 'DLOG' (502, "Macros Modal", purgeable) { + $"003C 000A 015E 0221 0005 0100 0100 0000" /* .<..^.!........ */ + $"0000 01F4 0D53 6574 204D 6163 726F 732E" /* ....Set Macros. */ + $"2E2E 4546" /* ..EF */ +}; + data 'FOND' (74, "%NCSA VT", purgeable) { $"0000 004A 0000 0000 0000 0000 0000 0000" /* ...J............ */ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ @@ -2026,7 +2239,7 @@ data 'MENU' (1005) { }; data 'MENU' (258, "Session", preload) { - $"0102 0000 0000 0000 0000 FFFE EFD7 0753" /* ...........S */ + $"0102 0000 0000 0000 0000 FFFB EFD7 0753" /* ...........S */ $"6573 7369 6F6E 0942 6163 6B73 7061 6365" /* essionBackspace */ $"0000 0000 0644 656C 6574 6500 0000 0001" /* .....Delete..... */ $"2D00 0000 0010 5365 7420 5363 7265 656E" /* -.....Set Screen */ @@ -2040,38 +2253,41 @@ data 'MENU' (258, "Session", preload) { $"696F 6E20 746F 2046 696C 6500 0000 0000" /* ion to File..... */ $"1051 7565 7565 2050 7269 6E74 204A 6F62" /* .Queue Print Job */ $"7300 0000 0011 4967 6E6F 7265 2046 6F72" /* s.....Ignore For */ - $"6D20 4665 6564 7300 0000 0001 2D00 0000" /* m Feeds.....-... */ - $"000A 4C6F 6361 6C20 4563 686F 0000 0000" /* .Local Echo.... */ - $"0957 7261 7020 4D6F 6465 0000 0000 1242" /* Wrap Mode.....B */ - $"5344 2034 2E33 2043 5220 6D61 7070 696E" /* SD 4.3 CR mappin */ - $"6700 0000 0014 414E 5349 2063 6F6C 6F72" /* g.....ANSI color */ - $"2073 6571 7565 6E63 6573 0000 0000 0F58" /* sequences.....X */ - $"7465 726D 2073 6571 7565 6E63 6573 0000" /* term sequences.. */ - $"0000 1138 2D62 6974 2063 6F6E 6E65 6374" /* ...8-bit connect */ - $"696F 6E73 0000 0000 0C52 656D 6170 204B" /* ions.....Remap K */ - $"6579 7061 6400 0000 0013 454D 4143 5320" /* eypad.....EMACS */ - $"6172 726F 7720 6D61 7070 696E 6700 0000" /* arrow mapping... */ - $"0018 4D61 7020 5067 5570 2F50 6744 6F77" /* ..Map PgUp/PgDow */ - $"6E2F 486F 6D65 2F45 6E64 0000 0000 0B54" /* n/Home/End.....T */ - $"7261 6E73 6C61 7469 6F6E 001B 8400 1843" /* ranslation....C */ - $"6C65 6172 2053 6372 6565 6E20 5361 7665" /* lear Screen Save */ - $"7320 4C69 6E65 7300 0000 000E 5265 7365" /* s Lines.....Rese */ - $"7420 5465 726D 696E 616C 0000 0000 0B4A" /* t Terminal.....J */ - $"756D 7020 5363 726F 6C6C 0000 0000 0B54" /* ump Scroll.....T */ - $"454B 2050 6167 652E 2E2E 0000 0000 1B54" /* EK Page........T */ - $"454B 2066 6F72 6D20 6665 6564 2063 6C65" /* EK form feed cle */ - $"6172 7320 7363 7265 656E 0000 0000 0F52" /* ars screen.....R */ - $"656D 6170 2044 656C 2074 6F20 5E44 0000" /* emap Del to ^D.. */ - $"0000 1041 6C6C 6F77 2062 6F6C 6466 6163" /* ...Allow boldfac */ - $"696E 6700 0000 0012 5573 6520 636F 6C6F" /* ing.....Use colo */ - $"7220 666F 7220 626F 6C64 0000 0000 1455" /* r for bold.....U */ - $"7365 2069 6E76 6572 7365 2066 6F72 2062" /* se inverse for b */ - $"6F6C 6400 0000 000C 4967 6E6F 7265 2062" /* old.....Ignore b */ - $"6565 7073 0000 0000 00" /* eeps..... */ + $"6D20 4665 6564 7300 0000 000F 5375 7370" /* m Feeds.....Susp */ + $"656E 6420 5365 7373 696F 6E00 0000 0011" /* end Session..... */ + $"436C 6561 7220 5361 7665 6420 4C69 6E65" /* Clear Saved Line */ + $"7300 0000 0001 2D00 0000 000A 4C6F 6361" /* s.....-....Loca */ + $"6C20 4563 686F 0000 0000 0957 7261 7020" /* l Echo....Wrap */ + $"4D6F 6465 0000 0000 1242 5344 2034 2E33" /* Mode.....BSD 4.3 */ + $"2043 5220 6D61 7070 696E 6700 0000 0014" /* CR mapping..... */ + $"414E 5349 2063 6F6C 6F72 2073 6571 7565" /* ANSI color seque */ + $"6E63 6573 0000 0000 0F58 7465 726D 2073" /* nces.....Xterm s */ + $"6571 7565 6E63 6573 0000 0000 1138 2D62" /* equences.....8-b */ + $"6974 2063 6F6E 6E65 6374 696F 6E73 0000" /* it connections.. */ + $"0000 0C52 656D 6170 204B 6579 7061 6400" /* ...Remap Keypad. */ + $"0000 0013 454D 4143 5320 6172 726F 7720" /* ....EMACS arrow */ + $"6D61 7070 696E 6700 0000 0018 4D61 7020" /* mapping.....Map */ + $"5067 5570 2F50 6744 6F77 6E2F 486F 6D65" /* PgUp/PgDown/Home */ + $"2F45 6E64 0000 0000 0B54 7261 6E73 6C61" /* /End.....Transla */ + $"7469 6F6E 001B 8400 1843 6C65 6172 2053" /* tion....Clear S */ + $"6372 6565 6E20 5361 7665 7320 4C69 6E65" /* creen Saves Line */ + $"7300 0000 000E 5265 7365 7420 5465 726D" /* s.....Reset Term */ + $"696E 616C 0000 0000 0B4A 756D 7020 5363" /* inal.....Jump Sc */ + $"726F 6C6C 0000 0000 0B54 454B 2050 6167" /* roll.....TEK Pag */ + $"652E 2E2E 0000 0000 1B54 454B 2066 6F72" /* e........TEK for */ + $"6D20 6665 6564 2063 6C65 6172 7320 7363" /* m feed clears sc */ + $"7265 656E 0000 0000 0F52 656D 6170 2044" /* reen.....Remap D */ + $"656C 2074 6F20 5E44 0000 0000 1041 6C6C" /* el to ^D.....All */ + $"6F77 2062 6F6C 6466 6163 696E 6700 0000" /* ow boldfacing... */ + $"0012 5573 6520 636F 6C6F 7220 666F 7220" /* ..Use color for */ + $"626F 6C64 0000 0000 1455 7365 2069 6E76" /* bold.....Use inv */ + $"6572 7365 2066 6F72 2062 6F6C 6400 0000" /* erse for bold... */ + $"000C 4967 6E6F 7265 2062 6565 7073 0000" /* ..Ignore beeps.. */ + $"0000 00" /* ... */ }; data 'MENU' (516, "nNetwork", preload) { - $"0204 0000 0000 0000 0000 FFFF AFF7 034E" /* ...........N */ + $"0204 0000 0000 0000 0000 FFFD 7FF7 034E" /* ............N */ $"6574 1053 656E 6420 4654 5020 436F 6D6D" /* et.Send FTP Comm */ $"616E 6400 4600 000F 5365 6E64 2049 5020" /* and.F...Send IP */ $"4164 6472 6573 7300 4900 0001 2D00 0000" /* Address.I...-... */ @@ -2086,11 +2302,14 @@ data 'MENU' (516, "nNetwork", preload) { $"000B 5365 6E64 2022 5359 4E43 2200 0000" /* ..Send "SYNC"... */ $"0012 5365 6E64 2022 4252 4B20 2842 7265" /* ..Send "BRK (Bre */ $"616B 2922 0000 0000 0E53 656E 6420 4950" /* ak)".....Send IP */ - $"202B 2053 594E 4300 5900 0001 2D00 0000" /* + SYNC.Y...-... */ - $"000F 5375 7370 656E 6420 4E65 7477 6F72" /* ..Suspend Networ */ - $"6B00 0000 0001 2D00 0000 0010 5368 6F77" /* k.....-.....Show */ - $"2049 5020 4164 6472 6573 73C9 0000 0000" /* IP Address.... */ - $"00" /* . */ + $"202B 2053 594E 4300 5900 0012 5365 6E64" /* + SYNC.Y...Send */ + $"2022 456E 6420 6F66 2046 696C 6522 0000" /* "End of File".. */ + $"0000 0E53 656E 6420 2253 5553 5065 6E64" /* ...Send "SUSPend */ + $"2200 0000 000C 5365 6E64 2022 4142 4F52" /* ".....Send "ABOR */ + $"5422 0000 0000 012D 0000 0000 0F53 7573" /* T".....-.....Sus */ + $"7065 6E64 204E 6574 776F 726B 0000 0000" /* pend Network.... */ + $"012D 0000 0000 1053 686F 7720 4950 2041" /* .-.....Show IP A */ + $"6464 7265 7373 C900 0000 0000" /* ddress..... */ }; data 'MENU' (132, "Translation SubMenu", preload) { @@ -2116,7 +2335,7 @@ data 'MENU' (513, "nEdit", preload) { }; data 'MENU' (514, "Session", preload) { - $"0202 0000 0000 0000 0000 FFFE EFD7 0753" /* ...........S */ + $"0202 0000 0000 0000 0000 FFFB EFD7 0753" /* ...........S */ $"6573 7369 6F6E 0942 6163 6B73 7061 6365" /* essionBackspace */ $"0000 0000 0644 656C 6574 6500 0000 0001" /* .....Delete..... */ $"2D00 0000 0010 5365 7420 5363 7265 656E" /* -.....Set Screen */ @@ -2130,34 +2349,37 @@ data 'MENU' (514, "Session", preload) { $"696F 6E20 746F 2046 696C 6500 004B 0000" /* ion to File..K.. */ $"1051 7565 7565 2050 7269 6E74 204A 6F62" /* .Queue Print Job */ $"7300 0000 0011 4967 6E6F 7265 2046 6F72" /* s.....Ignore For */ - $"6D20 4665 6564 7300 0000 0001 2D00 0000" /* m Feeds.....-... */ - $"000A 4C6F 6361 6C20 4563 686F 0000 0000" /* .Local Echo.... */ - $"0957 7261 7020 4D6F 6465 0000 0000 1242" /* Wrap Mode.....B */ - $"5344 2034 2E33 2043 5220 6D61 7070 696E" /* SD 4.3 CR mappin */ - $"6700 0000 0014 414E 5349 2063 6F6C 6F72" /* g.....ANSI color */ - $"2073 6571 7565 6E63 6573 0000 0000 0F58" /* sequences.....X */ - $"7465 726D 2073 6571 7565 6E63 6573 0000" /* term sequences.. */ - $"0000 1138 2D62 6974 2063 6F6E 6E65 6374" /* ...8-bit connect */ - $"696F 6E73 0000 0000 0C52 656D 6170 204B" /* ions.....Remap K */ - $"6579 7061 6400 0000 0013 454D 4143 5320" /* eypad.....EMACS */ - $"6172 726F 7720 6D61 7070 696E 6700 0000" /* arrow mapping... */ - $"0018 4D61 7020 5067 5570 2F50 6744 6F77" /* ..Map PgUp/PgDow */ - $"6E2F 486F 6D65 2F45 6E64 0000 0000 0B54" /* n/Home/End.....T */ - $"7261 6E73 6C61 7469 6F6E 001B 8400 1843" /* ranslation....C */ - $"6C65 6172 2053 6372 6565 6E20 5361 7665" /* lear Screen Save */ - $"7320 4C69 6E65 7300 0000 000E 5265 7365" /* s Lines.....Rese */ - $"7420 5465 726D 696E 616C 0052 0000 0B4A" /* t Terminal.R...J */ - $"756D 7020 5363 726F 6C6C 004A 0000 0B54" /* ump Scroll.J...T */ - $"454B 2050 6167 652E 2E2E 0000 0000 1B54" /* EK Page........T */ - $"454B 2066 6F72 6D20 6665 6564 2063 6C65" /* EK form feed cle */ - $"6172 7320 7363 7265 656E 0000 0000 0F52" /* ars screen.....R */ - $"656D 6170 2044 656C 2074 6F20 5E44 0000" /* emap Del to ^D.. */ - $"0000 1041 6C6C 6F77 2062 6F6C 6466 6163" /* ...Allow boldfac */ - $"696E 6700 0000 0012 5573 6520 636F 6C6F" /* ing.....Use colo */ - $"7220 666F 7220 626F 6C64 0000 0000 1455" /* r for bold.....U */ - $"7365 2069 6E76 6572 7365 2066 6F72 2062" /* se inverse for b */ - $"6F6C 6400 0000 000C 4967 6E6F 7265 2062" /* old.....Ignore b */ - $"6565 7073 0000 0000 00" /* eeps..... */ + $"6D20 4665 6564 7300 0000 000F 5375 7370" /* m Feeds.....Susp */ + $"656E 6420 5365 7373 696F 6E00 0000 0011" /* end Session..... */ + $"436C 6561 7220 5361 7665 6420 4C69 6E65" /* Clear Saved Line */ + $"7300 0000 0001 2D00 0000 000A 4C6F 6361" /* s.....-....Loca */ + $"6C20 4563 686F 0000 0000 0957 7261 7020" /* l Echo....Wrap */ + $"4D6F 6465 0000 0000 1242 5344 2034 2E33" /* Mode.....BSD 4.3 */ + $"2043 5220 6D61 7070 696E 6700 0000 0014" /* CR mapping..... */ + $"414E 5349 2063 6F6C 6F72 2073 6571 7565" /* ANSI color seque */ + $"6E63 6573 0000 0000 0F58 7465 726D 2073" /* nces.....Xterm s */ + $"6571 7565 6E63 6573 0000 0000 1138 2D62" /* equences.....8-b */ + $"6974 2063 6F6E 6E65 6374 696F 6E73 0000" /* it connections.. */ + $"0000 0C52 656D 6170 204B 6579 7061 6400" /* ...Remap Keypad. */ + $"0000 0013 454D 4143 5320 6172 726F 7720" /* ....EMACS arrow */ + $"6D61 7070 696E 6700 0000 0018 4D61 7020" /* mapping.....Map */ + $"5067 5570 2F50 6744 6F77 6E2F 486F 6D65" /* PgUp/PgDown/Home */ + $"2F45 6E64 0000 0000 0B54 7261 6E73 6C61" /* /End.....Transla */ + $"7469 6F6E 001B 8400 1843 6C65 6172 2053" /* tion....Clear S */ + $"6372 6565 6E20 5361 7665 7320 4C69 6E65" /* creen Saves Line */ + $"7300 0000 000E 5265 7365 7420 5465 726D" /* s.....Reset Term */ + $"696E 616C 0052 0000 0B4A 756D 7020 5363" /* inal.R...Jump Sc */ + $"726F 6C6C 004A 0000 0B54 454B 2050 6167" /* roll.J...TEK Pag */ + $"652E 2E2E 0000 0000 1B54 454B 2066 6F72" /* e........TEK for */ + $"6D20 6665 6564 2063 6C65 6172 7320 7363" /* m feed clears sc */ + $"7265 656E 0000 0000 0F52 656D 6170 2044" /* reen.....Remap D */ + $"656C 2074 6F20 5E44 0000 0000 1041 6C6C" /* el to ^D.....All */ + $"6F77 2062 6F6C 6466 6163 696E 6700 0000" /* ow boldfacing... */ + $"0012 5573 6520 636F 6C6F 7220 666F 7220" /* ..Use color for */ + $"626F 6C64 0000 0000 1455 7365 2069 6E76" /* bold.....Use inv */ + $"6572 7365 2066 6F72 2062 6F6C 6400 0000" /* erse for bold... */ + $"000C 4967 6E6F 7265 2062 6565 7073 0000" /* ..Ignore beeps.. */ + $"0000 00" /* ... */ }; data 'MENU' (133, "Font") { @@ -2166,7 +2388,7 @@ data 'MENU' (133, "Font") { }; data 'MENU' (260, "Network", preload) { - $"0104 0000 0000 0000 0000 FFFF AFF7 034E" /* ...........N */ + $"0104 0000 0000 0000 0000 FFFD 7FF7 034E" /* ............N */ $"6574 1053 656E 6420 4654 5020 436F 6D6D" /* et.Send FTP Comm */ $"616E 6400 0000 000F 5365 6E64 2049 5020" /* and.....Send IP */ $"4164 6472 6573 7300 0000 0001 2D00 0000" /* Address.....-... */ @@ -2181,11 +2403,48 @@ data 'MENU' (260, "Network", preload) { $"000B 5365 6E64 2022 5359 4E43 2200 0000" /* ..Send "SYNC"... */ $"0012 5365 6E64 2022 4252 4B20 2842 7265" /* ..Send "BRK (Bre */ $"616B 2922 0000 0000 0E53 656E 6420 4950" /* ak)".....Send IP */ - $"202B 2053 594E 4300 0000 0001 2D00 0000" /* + SYNC.....-... */ - $"000F 5375 7370 656E 6420 4E65 7477 6F72" /* ..Suspend Networ */ - $"6B00 0000 0001 2D00 0000 0012 5368 6F77" /* k.....-.....Show */ - $"2049 5020 4164 6472 6573 732E 2E2E 0000" /* IP Address..... */ - $"0000 00" /* ... */ + $"202B 2053 594E 4300 0000 0012 5365 6E64" /* + SYNC.....Send */ + $"2022 456E 6420 6F66 2046 696C 6522 0000" /* "End of File".. */ + $"0000 0E53 656E 6420 2253 5553 5065 6E64" /* ...Send "SUSPend */ + $"2200 0000 000C 5365 6E64 2022 4142 4F52" /* ".....Send "ABOR */ + $"5422 0000 0000 012D 0000 0000 0F53 7573" /* T".....-.....Sus */ + $"7065 6E64 204E 6574 776F 726B 0000 0000" /* pend Network.... */ + $"012D 0000 0000 1253 686F 7720 4950 2041" /* .-.....Show IP A */ + $"6464 7265 7373 2E2E 2E00 0000 0000" /* ddress........ */ +}; + +data 'MENU' (2000) { + $"07D0 0000 0000 0000 0000 FFFF FFFF 0950" /* .........P */ + $"726F 746F 636F 6C3A 0654 656C 6E65 7400" /* rotocol:.Telnet. */ + $"0000 0006 726C 6F67 696E 0000 0000 0372" /* ....rlogin.....r */ + $"7368 0000 0000 0572 6578 6563 0000 0000" /* sh.....rexec.... */ + $"1273 7368 2028 5365 6375 7265 2053 6865" /* .ssh (Secure She */ + $"6C6C 2900 0000 0007 7261 7720 5443 5000" /* ll).....raw TCP. */ + $"0000 0000" /* .... */ +}; + +data 'MENU' (2001) { + $"07D1 0000 0000 0000 0000 FFFF FFFF 0B45" /* ..........E */ + $"6E63 7279 7074 696F 6E3A 0433 4445 5300" /* ncryption:.3DES. */ + $"0000 0003 4445 5300 0000 0008 426C 6F77" /* ....DES.....Blow */ + $"6669 7368 0000 0000 0449 4445 4100 0000" /* fish.....IDEA... */ + $"0006 3C6E 6F6E 653E 0000 0000 00" /* ..<none>..... */ +}; + +data 'MENU' (2002) { + $"07D2 0000 0000 0000 0000 FFFF FFFF 084B" /* ..........K */ + $"6579 2053 6574 3A0D 436F 6D6D 616E 642B" /* ey Set:.Command+ */ + $"5B30 2D39 5D00 0000 0013 436F 6D6D 616E" /* [0-9].....Comman */ + $"642B 5368 6966 742B 5B30 2D39 5D00 0000" /* d+Shift+[0-9]... */ + $"0006 4631 2D46 3130 0000 0000 0C53 6869" /* ..F1-F10.....Shi */ + $"6674 2B46 312D 4631 3000 0000 000F 4631" /* ft+F1-F10.....F1 */ + $"312D 4631 3528 2B53 6869 6674 2900 0000" /* 1-F15(+Shift)... */ + $"0011 5046 312D 342C 2050 6755 702C 2065" /* ..PF1-4, PgUp, e */ + $"7463 2E00 0000 0015 4B65 7970 6164 2030" /* tc......Keypad 0 */ + $"2D39 2028 6170 7020 6D6F 6465 2900 0000" /* -9 (app mode)... */ + $"000E 4B65 7970 6164 2073 796D 626F 6C73" /* ..Keypad symbols */ + $"0000 0000 0A41 7272 6F77 204B 6579 7300" /* ....Arrow Keys. */ + $"0000 0000" /* .... */ }; data 'NFNT' (9484, "%NCSA VT 12") { @@ -3554,7 +3813,7 @@ data 'PICT' (1000, "Keypad", purgeable) { }; data 'PICT' (1025) { - $"838A 0000 0000 012C 0190 0011 02FF 0C00" /* .....,...... */ + $"86DE 0000 0000 012C 0190 0011 02FF 0C00" /* .....,...... */ $"FFFE 0000 0048 0000 0048 0000 0000 0000" /* ...H...H...... */ $"012C 0190 0000 0000 00A1 01F2 0016 3842" /* .,.........8B */ $"494D 0000 0000 0000 012C 0190 4772 8970" /* IM.......,.Grp */ @@ -3562,7 +3821,7 @@ data 'PICT' (1025) { $"0098 8190 0000 0000 012C 0190 0000 0000" /* ......,..... */ $"0000 0000 0048 0000 0048 0000 0000 0008" /* .....H...H...... */ $"0001 0008 0000 0000 0000 0000 0000 0000" /* ................ */ - $"004A 919A 0000 00FF 0000 FFFF FFFF FFFF" /* .J..... */ + $"0046 4412 0000 00FF 0000 FFFF FFFF FFFF" /* .FD...... */ $"0001 FFFF FFFF CCCC 0002 FFFF FFFF 9999" /* .... */ $"0003 FFFF FFFF 6666 0004 FFFF FFFF 3333" /* ..ff..33 */ $"0005 FFFF FFFF 0000 0006 FFFF CCCC FFFF" /* ...... */ @@ -3703,1545 +3962,1310 @@ data 'PICT' (1025) { $"0CFE F584 0081 0081 00F4 00FE FD00 0CFE" /* ....... */ $"F584 0081 0081 00F4 00FE FD00 0CFE F584" /* ...... */ $"0081 0081 00F4 00FE FD00 0CFE F584 0081" /* ....... */ - $"0081 00F4 00FE FD00 10FE F584 00D8 00FF" /* ....... */ - $"F6AC 0081 00F4 00FE FD00 12FE F584 00D9" /* ...... */ - $"0002 56FF 81AC 0081 00F4 00FE FD00 1DFE" /* ..V..... */ - $"F587 0002 F700 00EE 0001 F6F7 F000 04F5" /* ........ */ - $"FBFF FFFB AC00 8100 F400 FEFD 001F FEF5" /* ..... */ - $"8800 03F8 FD00 00EE 00FF 81F2 0002 F5FA" /* ....... */ - $"FEFE FF00 F9AC 0081 00F4 00FE FD00 1EFE" /* ...... */ - $"F588 0003 F9FF F500 EE00 01FF FCF3 0000" /* ....... */ - $"F7FB FF00 F9AC 0081 00F4 00FE FD00 2FFE" /* ...../ */ - $"F5F7 0003 F52B 2B56 FDF9 0256 2B2B 9D00" /* ..++V.V++. */ - $"03FB FFFD F8F2 2BFF 0003 F6FC FF81 F300" /* .+... */ - $"00FA FBFF 00F9 AC00 8100 F400 FEFD 0027" /* ......' */ - $"FEF5 FA00 01F8 FCF4 FF02 ACFA F5A1 0000" /* ..... */ - $"ACFE FFED FF00 F9F2 0000 F9FC FF00 F9AC" /* .... */ - $"0081 00F4 00FE FD00 23FE F5FB 0000 81EF" /* ....#.. */ - $"FF01 81F5 A300 FDFF EDFF 00F9 F100 00F9" /* ..... */ - $"FDFF 00F9 AC00 8100 F400 FEFD 0041 FEF5" /* .....A */ - $"FB00 03FC FFFC FEFB FF00 FAFE 2B01 FAFD" /* ...+. */ - $"FDFF 01FE F6A5 0000 F6FD FF01 FBF6 FE00" /* ..... */ - $"00FE FDFF 0056 FE00 01F6 F9FD FF00 F9F1" /* ..V... */ - $"0000 2BFD FF00 F9AC 0081 00F4 00FE FD00" /* ..+..... */ - $"3BFE F5F8 0000 F5FC FF00 FAFB 0000 81FD" /* ;..... */ - $"FF01 FEF6 A600 00F7 FEFF 0081 FC00 00FC" /* ...... */ - $"FDFF 002B FC00 002B FEFF 00F9 F100 002B" /* .+..+...+ */ - $"FDFF 00F9 AC00 8100 F400 FEFD 0039 FEF5" /* .....9 */ - $"F700 00AC FDFF 002B FA00 00FB FDFF 00FD" /* ...+... */ - $"A600 04F9 FFFF FC00 FC00 00FC FDFF 002B" /* ......+ */ - $"FB00 0381 FFFF F9F1 0000 2BFD FF00 F9AC" /* ....+. */ - $"0081 00F4 00FE FD00 39FE F5F7 0000 FCFD" /* ....9.. */ - $"FF00 2BFA 0000 F5FC FF00 F9A7 0004 FCFF" /* .+..... */ - $"FFF5 00FC 0000 FCFD FF00 2BFB 0003 F6FF" /* ....+.. */ - $"FFF9 F100 002B FDFF 00F9 AC00 8100 F400" /* ..+.... */ - $"FEFD 0038 FEF5 F700 00FC FDFF 002B F900" /* .8...+. */ - $"0081 FDFF 00FD A700 04FD FF81 0000 FC00" /* ....... */ - $"00FC FDFF 002B FA00 FFFF 00F9 F100 002B" /* ..+....+ */ - $"FDFF 00F9 AC00 8100 F400 FEFD 0048 FEF5" /* .....H */ - $"F700 00FC FDFF 002B F900 00F7 FCFF 00F6" /* ...+... */ - $"E100 01AC F5F5 0001 ACF5 D800 FFFF 022B" /* ......+ */ - $"0000 FC00 00FC FDFF 002B FB00 032B FCFF" /* .....+..+ */ - $"56F1 0000 2BFD FF00 F9C7 0001 F5AC E800" /* V..+.... */ - $"8100 F400 FEFD 0047 FEF5 F700 00FC FDFF" /* ...G.. */ - $"002B F800 FCFF 0056 E200 02F8 FF2B F600" /* .+..V..+. */ - $"02F8 FF2B D900 022B FFFD FE00 FC00 00FC" /* .+..+... */ - $"FDFF 002B FA00 0281 FF2B F100 002B FDFF" /* .+..+..+ */ - $"00F9 C700 0181 FFE8 0081 00F4 00FE FD00" /* ....... */ - $"4AFE F5F7 0000 FCFD FF00 2BF8 0000 FEFD" /* J...+.. */ - $"FF00 F9E2 0002 FDFF 2BF6 0002 FDFF 2BD9" /* ...+..+ */ - $"0002 F8FF F8FE 00FC 0000 FCFD FF00 2BFA" /* ......+ */ - $"0002 F9FF F6F1 0000 2BFD FF00 F9C8 0002" /* ....+... */ - $"F5FF FFE8 0081 00F4 00FE FD00 45FE F5F7" /* ....E */ - $"0000 FCFD FF00 2BF8 0000 FCFD FF00 FCE3" /* ...+... */ - $"0003 F8FF FF2B F700 03F8 FFFF 2BD9 0001" /* ..+..+.. */ - $"F8AC FD00 FC00 00FC FDFF 002B E700 002B" /* ....+..+ */ - $"FDFF 00F9 C800 0281 FFFF E800 8100 F400" /* ...... */ - $"FEFD 0044 FEF5 F700 00FC FDFF 002B F800" /* .D...+. */ - $"00FC FDFF 00FC E300 03FD FFFF 2BF7 0003" /* ....+.. */ - $"FDFF FF2B D300 FC00 00FC FDFF 002B F700" /* +....+. */ - $"00F6 F200 002B FDFF 00F9 C900 00F6 FEFF" /* ...+... */ - $"E800 8100 F400 FEFD 0042 FEF5 F700 00FC" /* ....B.. */ - $"FDFF 002B F800 00FC FDFF 00FC E400 00F9" /* .+..... */ - $"FEFF 002B F800 00F9 FEFF 002B D300 FC00" /* .+...+.. */ - $"00FC FDFF 002B E700 002B FDFF 00F9 C900" /* ..+..+.. */ - $"00FC FEFF E800 8100 F400 FEFD 007E FEF5" /* .....~ */ - $"F700 00FC FDFF 002B F800 00FC FDFF 00FB" /* ...+... */ - $"F500 052B F9FC FC81 F8F7 0000 F6FD FF00" /* ..+... */ - $"2BF9 0000 F6FD FF00 2BF3 0005 2BF9 FCFC" /* +...+..+ */ - $"81F8 F300 01F8 81FE 0003 F581 FCF9 FE00" /* ..... */ - $"FC00 00FC FDFF 002B F400 0556 81FC FCF9" /* ...+..V */ - $"F6FA 0000 2BFD FF00 F9F7 0000 FCFC 0004" /* ..+..... */ - $"F881 FC81 F8EF 0005 F8FA FCFC FAF7 F700" /* ... */ - $"0056 FDFF E800 8100 F400 FEFD 0095 FEF5" /* .V.... */ - $"F700 00FC FDFF 002B F800 00FD FDFF 00F9" /* ...+... */ - $"F700 01F6 FCFB FF01 FEF7 FA00 01F6 FEFD" /* ..... */ - $"FF00 F9FD 2B04 F600 00F6 FEFD FF00 F9FD" /* .+.... */ - $"2B00 F6FA 0001 F6FC FBFF 01FE F7F6 0006" /* +...... */ - $"F6FE FC00 00F6 FEFE FF02 FC00 00FC 0000" /* ....... */ - $"FCFD FF00 2BF6 0001 F9FE FBFF 00FB FB00" /* .+.... */ - $"002B FDFF 00F9 F800 06F9 FF2B 0000 F5AC" /* .+...+.. */ - $"FCFF 01AC F6F3 0001 F7FD FBFF 01AC F6FA" /* .... */ - $"0000 F8FC FF00 F7FD 2B00 F5EE 0081 00F4" /* ...+... */ - $"00FE FD00 98FE F5F7 0000 FCFD FF00 2BF8" /* .....+ */ - $"00FC FF00 F8F8 000B F8FE FFFF F900 00F8" /* ...... */ - $"FEFF FFFA FB00 00AC F7FF 03FC 0000 ACF7" /* ..... */ - $"FF00 FCFB 000B F8FE FFFF F900 00F8 FEFF" /* ..... */ - $"FFFA F700 05AC FFFC 0000 FDFC FF01 F800" /* ...... */ - $"FC00 00FC FDFF 002B F700 0BFC FFFF AC2B" /* ...+..+ */ - $"00F5 FBFF FFFD F6FD 0000 2BFD FF00 F9F9" /* ...+. */ - $"0006 F7FF FF2B 00F5 FEFA FF00 FEF4 000B" /* ..+.... */ - $"FAFF FFFE F800 00F9 FFFF FEF8 FC00 01F6" /* .... */ - $"FEF7 FF00 F9EE 0081 00F4 00FE FD00 99FE" /* ..... */ - $"F5F7 0000 FCFD FF00 2BF9 0000 F7FC FFF8" /* ...+.. */ - $"0000 2BFE FF00 F8FD 0004 F6FE FFFF F8FD" /* ..+... */ - $"0000 ACF6 FF02 FC00 ACF6 FF00 FCFC 0000" /* ....... */ - $"2BFE FF00 F8FD 0004 F6FE FFFF F8F9 0005" /* +..... */ - $"81FF FFFC 00FA FBFF 01FB 00FC 0000 FCFD" /* ..... */ - $"FF00 2BF8 0003 FCFF FFAC FC00 0381 FFFF" /* .+.... */ - $"ACFD 0000 2BFD FF00 F9FA 0006 2BFE FFFF" /* ..+...+ */ - $"2B00 ACF8 FF00 FBF6 0004 F9FF FFFE F6FD" /* +.... */ - $"0004 F8FF FFFE F6FE 0001 F5FE F6FF 00F9" /* ..... */ - $"EE00 8100 F400 FEFD 0097 FEF5 F700 00FC" /* ...... */ - $"FDFF 002B F900 00FB FDFF 00FB F800 03FE" /* .+..... */ - $"FFFF 81FB 0004 56FF FFFE F5FE 0000 FEF6" /* ..V.. */ - $"FF02 FC00 FEF6 FF00 FCFC 0003 FEFF FF81" /* ..... */ - $"FB00 0456 FFFF FEF5 FB00 0081 FEFF 01FC" /* ..V... */ - $"F6FA FF01 FE00 FC00 00FC FDFF 002B F900" /* .....+. */ - $"00F9 FEFF 00F5 FB00 03FD FFFF FAFE 0000" /* ...... */ - $"2BFD FF00 F9FB 0000 F8FD FF01 2BF9 F6FF" /* +....+ */ - $"00F6 F800 002B FEFF 00F8 FB00 03FB FFFF" /* ...+... */ - $"ACFE 0000 F6F5 FF00 F9EE 0081 00F4 00FE" /* ...... */ - $"FD00 A6FE F5F7 0000 FCFD FF00 2BFA 0000" /* ....+.. */ - $"F6FC FF00 2BF9 0000 81FE FFF9 00FE FF00" /* .+.... */ - $"81FE 0002 F52B 81FD FF00 F9FD 2B04 F500" /* ..+.+.. */ - $"F52B 81FD FF00 F9FD 2B00 F5FD 0000 81FE" /* +.+... */ - $"FFF9 00FE FF00 81FC 0000 FCFD FF01 FDAC" /* ..... */ - $"F9FF 0000 FC00 00FC FDFF 002B FA00 00F5" /* .....+.. */ - $"FEFF 00FA FA00 00FA FEFF 03F5 0000 2BFD" /* ......+ */ - $"FF00 F9FC 0000 FAFC FF07 F8FF FFF9 0000" /* ...... */ - $"F6AC FCFF 0081 F800 03FD FFFF ACFA 0000" /* ..... */ - $"F7FE FF00 F8FE 0002 F62B ACFD FF00 F7FD" /* ...+. */ - $"2BED 0081 00F4 00FE FD00 98FE F5F7 0000" /* +...... */ - $"FCFD FF00 2BFA 0000 ACFD FF00 FAF9 0000" /* .+..... */ - $"F5FE FF00 81F9 0000 ACFE FFFC 0000 2BFD" /* .....+ */ - $"FF00 2BF9 0000 2BFD FF00 2BF9 0000 F5FE" /* .+..+.+.. */ - $"FF00 81F9 0000 ACFE FFFD 0000 ACFB FF03" /* ...... */ - $"FEF6 F6FE FCFF 0000 FC00 00FC FDFF 002B" /* .....+ */ - $"FA00 0081 FEFF 00F5 FA00 00F7 FEFF 03FA" /* ...... */ - $"0000 2BFD FF00 F9FD 0000 F8F9 FF00 2BFC" /* ..+....+ */ - $"0000 ACFD FF00 FDF9 0000 F8FE FF00 F8F9" /* ...... */ - $"00FE FF00 ACFC 0000 F9FD FFE8 0081 00F4" /* ...... */ - $"00FE FD00 9CFE F5F7 0000 FCFD FF00 2BFC" /* .....+ */ - $"0001 F6AC FDFF 0081 F800 0081 FEFF 00F7" /* ...... */ - $"F900 00FC FEFF 00F8 FD00 002B FDFF 002B" /* .....+.+ */ - $"F900 002B FDFF 002B F900 0081 FEFF 00F7" /* ..+.+... */ - $"F900 00FC FEFF 00F8 FE00 00FE FBFF 0381" /* ...... */ - $"0000 F8FD FF01 AC00 FC00 00FC FDFF 002B" /* .......+ */ - $"FB00 00F5 FEFF 00AC F900 002B FEFF 03FD" /* .....+. */ - $"0000 2BFD FF00 F9FD 0000 56FA FF00 81FB" /* ..+...V. */ - $"0000 2BFC FF00 F5FA 0000 FDFE FFF8 00FD" /* ..+.... */ - $"FF00 F5FD 0000 F9FD FFE8 0081 00F4 00FE" /* ...... */ - $"FD00 ABFE F5F7 0000 FCFD FF00 81FE 2B01" /* ....+. */ - $"56FB FCFF 00F9 F700 00FE FEFF F800 00FC" /* V..... */ - $"FEFF 00FB FD00 002B FDFF 002B F900 002B" /* ...+.+..+ */ - $"FDFF 002B F900 00FE FEFF F800 00FC FEFF" /* .+.... */ - $"00FB FD00 00FA FCFF 00F7 FE00 0081 FEFF" /* ...... */ - $"01F8 00FC 0000 FCFD FF00 2BFB 0000 F9FE" /* .....+.. */ - $"FF00 FAF9 0000 2BFD FF02 F600 2BFD FF00" /* ...+..+. */ - $"F9FC 0001 2BFD FCFF 00F6 FA00 00AC FDFF" /* ..+... */ - $"00F7 FB00 002B FEFF 00AC F800 FDFF 0056" /* ...+...V */ - $"FD00 00F9 FDFF E800 EB00 00F9 FBFF 00F9" /* ...... */ - $"FA00 00F9 FBFF 00F9 AE00 F400 FEFD 00A3" /* ...... */ - $"FEF5 F700 00FC F3FF 01FC F6F8 0000 F8FE" /* ..... */ - $"FF00 FDF8 00FD FF00 FEFD 0000 2BFD FF00" /* .....+. */ - $"2BF9 0000 2BFD FF00 2BFA 0000 F8FE FF00" /* +..+.+... */ - $"FDF8 00FD FF00 FEFC 0000 FDFD FF00 2BFD" /* .....+ */ - $"0004 F9FC F900 00FC 0000 FCFD FF00 2BFB" /* .......+ */ - $"0000 FDFE FF00 F8F9 0000 F9FD FF02 5600" /* ......V. */ - $"2BFD FF00 F9FB 0000 F9FD FF00 FDF9 0000" /* +...... */ - $"F9FD FF00 F9FB 0000 81FE FF00 81F9 0000" /* ...... */ - $"2BFD FF00 FBFD 0000 F9FD FFE8 00EB 0000" /* +...... */ - $"FFFB 2B00 FFFA 0000 FFFB 2B00 FFAE 00F4" /* +...+.. */ - $"00FE FD00 9EFE F5F7 0000 FCF1 FF00 81F9" /* ..... */ - $"0000 81FE FF00 FCF9 0000 56FC FFFD 0000" /* .....V.. */ - $"2BFD FF00 2BF9 0000 2BFD FF00 2BFA 0000" /* +.+..+.+.. */ - $"81FE FF00 FCF9 0000 56FC FFFC 0000 FCFD" /* ...V.. */ - $"FFF7 00FC 0000 FCFD FF00 2BFC 0000 F5FD" /* ....+.. */ - $"FF00 2BF9 0000 FDFD FF02 F900 2BFD FF00" /* .+....+. */ - $"F9FB 0000 2BFD FF00 FCF9 0000 F7FD FF00" /* ..+.... */ - $"F9FB 0000 FDFE FF00 F9F9 0000 FBFD FF00" /* ...... */ - $"FCFD 0000 F9FD FFE8 00EB 0001 FF2B FDFC" /* .....+ */ - $"012B FFFA 0001 FF2B FDFC 012B FFAE 00F4" /* .+..+.+. */ - $"00FE FD00 B1FE F5F7 0000 FCFD FF00 F9FD" /* ..... */ - $"2B02 F7FA FEFC FF00 ACFA 0000 FDFE FF00" /* +..... */ - $"ACFB 0001 2B81 FBFF 002B FE00 002B FDFF" /* ..+.+..+ */ - $"002B F900 002B FDFF 002B FA00 00FD FEFF" /* .+..+.+.. */ - $"00AC FB00 012B 81FB FF00 2BFD 0000 FCFD" /* ...+.+.. */ - $"FFF7 00FC 0000 FCFD FF00 2BFC 0000 F8FD" /* ....+.. */ - $"FF00 F7FC 0002 F5F8 FDFC FF02 FC00 2BFD" /* .....+ */ - $"FF00 F9FB 0000 2BFD FF00 F9F9 0000 2BFD" /* ...+...+ */ - $"FF00 FCFC 0000 F5FD FF00 FAFB 0001 F7FC" /* ...... */ - $"FBFF FD00 00F9 FDFF E800 EB00 07FF 2BFC" /* .....+ */ - $"2A2A F52B FFFA 0007 FF2B FC2A 2AF5 2BFF" /* **+..+**+ */ - $"AE00 F400 FEFD 0084 FEF5 F700 00FC FDFF" /* ..... */ - $"002B FA00 0081 FCFF 00FC FB00 EEFF 002B" /* .+.....+ */ - $"FE00 002B FDFF 002B F900 002B FDFF 002B" /* ..+.+..+.+ */ - $"FA00 EEFF 002B FD00 00FC FDFF F700 FC00" /* ..+.... */ - $"00FC FDFF 002B FC00 00FA EFFF 02FC 002B" /* ..+....+ */ - $"FDFF 00F9 FB00 002B FDFF 00F9 F800 FDFF" /* ...+.. */ - $"00FC FC00 00F7 EEFF FD00 00F9 FDFF E800" /* ...... */ - $"EB00 02FF 2BFC FEF5 012B FFFA 0002 FF2B" /* ..+.+..+ */ - $"FCFE F501 2BFF AE00 F400 FEFD 0084 FEF5" /* .+... */ - $"F700 00FC FDFF 002B F900 0081 FCFF 0056" /* ...+...V */ - $"FD00 002B EEFF 00F5 FE00 002B FDFF 002B" /* ..+...+.+ */ - $"F900 002B FDFF 002B FB00 002B EEFF 00F5" /* ..+.+..+. */ - $"FD00 00FC FDFF F700 FC00 00FC FDFF 002B" /* ......+ */ - $"FC00 00FC EFFF 0281 002B FDFF 00F9 FB00" /* ....+.. */ - $"002B FDFF 00F9 F800 FDFF 00FC FC00 00F9" /* .+..... */ - $"EFFF 00FD FD00 00F9 FDFF E800 EB00 00FF" /* ...... */ + $"0081 00F4 00FE FD00 0CFE F584 0081 0081" /* ....... */ + $"00F4 00FE FD00 0CFE F584 0081 0081 00F4" /* ....... */ + $"00FE FD00 16FE F584 008B 0002 F6F7 32FD" /* ......2 */ + $"3902 F7F6 0081 00F4 00FE FD00 15FE F584" /* 9...... */ + $"008F 0002 F532 39F6 D901 390E 8300 F400" /* ...29.9... */ + $"FEFD 001A FEF5 8400 E800 00F6 AB00 01F6" /* ....... */ + $"39F3 D9FF D901 4032 8500 F400 FEFD 001C" /* 9.@2.... */ + $"FEF5 8400 E900 0281 FF56 AE00 01F5 39F1" /* ...V..9 */ + $"D9FD D901 4007 8700 F400 FEFD 0025 FEF5" /* .@....% */ + $"9300 00F8 F300 FC00 012B F7F2 0004 2BFD" /* .....+..+ */ + $"FFFF F9AF 0000 0EEF D9FB D900 3288 00F4" /* ....2. */ + $"00FE FD00 35FE F594 0002 F8FF F5F4 00FC" /* ..5... */ + $"0001 FD81 F400 012B FCFD FF00 F7B1 0001" /* ....+... */ + $"F539 FCD9 0840 32F7 F500 00F6 0E39 FCD9" /* 9.@2...9 */ + $"FAD9 0039 8900 F400 FEFD 0036 FEF5 F400" /* .9...6. */ + $"FDF5 A500 02F9 FF56 F400 FD00 02F7 FFFB" /* ..V... */ + $"F500 002B FBFF 00F7 B200 01F5 40FD D901" /* ..+...@. */ + $"39F6 F700 0039 FED9 F9D9 0039 8A00 F400" /* 9..9.9.. */ + $"FEFD 0047 FEF5 FA00 052B F9FA FBFB FDFE" /* .G..+ */ + $"FE05 FDFC FBFA F8F6 AA00 03FB FFFF ACF5" /* ... */ + $"FB06 FBFA F981 FFFF F9F5 0001 2BFD FCFF" /* ...+ */ + $"00F7 B300 0007 FDD9 0140 F6F4 0002 F640" /* .....@..@ */ + $"D9F8 D900 328B 00F4 00FE FD00 35FE F5FB" /* .2...5 */ + $"0000 81F2 FF01 81F6 AC00 00FD F2FF FBFF" /* ..... */ + $"0056 F400 01F5 ACFD FF00 F7B4 0000 07FD" /* .V...... */ + $"D900 32F1 0001 F540 F7D9 00F7 8C00 F400" /* .2..@... */ + $"FEFD 0048 FEF5 FC00 00F8 F8FF 03AC 8181" /* .H... */ + $"FDFC FF00 56AD 00FD FF03 FEF9 F956 FCFF" /* .V..V */ + $"02FB F9F9 01F9 FCFD FF00 56F3 0000 2BFD" /* ...V..+ */ + $"FF00 F7B5 0000 07FD D900 07EF 0000 F500" /* ......... */ + $"40F8 D901 40F5 8D00 F400 FEFD 0051 FEF5" /* @.@...Q */ + $"FC00 03F5 F82B F7FC FF00 FAFE 0002 F5F7" /* ..+... */ + $"FEFD FF00 56AF 0000 F5FE FF01 ACF5 FE00" /* .V.... */ + $"0081 FDFF 02F6 0000 FF00 0056 FEFF 0056" /* ......V.V */ + $"F300 00F6 FDFF 00F7 B600 01F5 40FE D900" /* .....@. */ + $"07ED 0000 07F7 D900 398D 00F4 00FE FD00" /* .....9... */ + $"4AFE F5F8 0000 ACFD FF00 F5FC 0000 F6FC" /* J..... */ + $"FF00 2BB0 0004 F7FF FFFE F5FD 0000 FAFD" /* .+.... */ + $"FF02 F500 00FE 0003 FBFF FF56 F300 00F6" /* .....V.. */ + $"FDFF 00F7 B600 0040 FED9 0007 EC00 0100" /* ...@..... */ + $"32F7 D900 F68E 00F4 00FE FD00 48FE F5F8" /* 2....H */ + $"0000 FBFD FFFA 0000 F7FD FF00 ACB0 0003" /* ....... */ + $"FAFF FF2B FC00 00FA FDFF 02F6 0000 FE00" /* +...... */ + $"03F6 FFFF F9F3 0000 F6FD FF00 F7B7 0000" /* ...... */ + $"39FE D900 0EEB 00FF 0000 40F8 D900 398E" /* 9.....@.9 */ + $"00F4 00FE FD00 4BFE F5F8 0000 FBFD FFFA" /* ...K.. */ + $"0001 F5FE FDFF 002B E400 00F5 CF00 02FB" /* ...+.... */ + $"FFAC FB00 00FA FDFF 02F6 0000 FD00 FFFF" /* ...... */ + $"00F9 F300 00F6 FDFF 00F7 B800 0032 FED9" /* ......2 */ + $"0039 EA00 FF00 0032 F7D9 00F5 8F00 F400" /* .9...2... */ + $"FEFD 0055 FEF5 F800 00FB FDFF F900 00F9" /* .U.... */ + $"FDFF 00F9 E500 02F5 FEF5 F700 01FA FBDC" /* ..... */ + $"0002 ACFF F8FB 0000 FAFD FF02 F600 00FE" /* ....... */ + $"0003 F6FD FFF8 F300 00F6 FDFF 00F7 CD00" /* ...... */ + $"012B FAEF 0000 F6FE D900 40E9 00FE 00F7" /* .+...@.. */ + $"D900 328F 00F4 00FE FD00 58FE F5F8 0000" /* .2...X.. */ + $"FBFD FFF9 0000 F8FD FF00 FBE5 0002 81FF" /* ..... */ + $"F6F8 0002 F5FF FDDD 0003 F5FF FFF5 FB00" /* ..... */ + $"00FA FDFF 02F6 0000 FD00 02FC FFF6 F300" /* ....... */ + $"00F6 FDFF 00F7 CD00 01FF FCEF 0000 40FE" /* ......@ */ + $"D900 07E9 00FE 0000 39F8 D900 408F 00F4" /* .....9.@. */ + $"00FE FD00 58FE F5F8 0000 FBFD FFF9 0000" /* ..X.... */ + $"F7FD FF00 FDE6 0003 F5FF FFF6 F800 0256" /* .....V */ + $"FFAC DD00 02F6 FFF9 FA00 00FA FDFF 02F6" /* ..... */ + $"0000 FD00 01F8 81F2 0000 F6FD FF00 F7CE" /* ....... */ + $"0002 2BFF FCF0 0000 32FE D900 32E8 00FE" /* ..+..2.2. */ + $"0000 0EF7 D900 F590 00F4 00FE FD00 51FE" /* .......Q */ + $"F5F8 0000 FBFD FFF9 0000 2BFC FF00 F5E7" /* ....+. */ + $"0003 FBFF FFF6 F900 03F5 FFFF ACDC 0001" /* ...... */ + $"56F5 FA00 00FA FDFF 02F6 0000 EC00 00F6" /* V....... */ + $"FDFF 00F7 CE00 FFFF 00FC F100 00F5 FED9" /* ..... */ + $"0040 E700 FD00 F7D9 00F7 9000 F400 FEFD" /* .@..... */ + $"0050 FEF5 F800 00FB FDFF F900 002B FCFF" /* .P....+ */ + $"00F5 E800 00F6 FEFF 00F6 F900 03F9 FFFF" /* ...... */ + $"ACD3 0000 FAFD FF02 F600 00EC 0000 F6FD" /* ....... */ + $"FF00 F7CF 0003 F8FF FFFC F100 0039 FED9" /* .....9 */ + $"0007 E700 FD00 0040 F8D9 0039 9000 F400" /* .....@.9.. */ + $"FEFD 008A FEF5 F800 00FB FDFF F900 002B" /* .....+ */ + $"FCFF 00F5 F700 04F6 F9FB 8156 F700 00FD" /* ...V.. */ + $"FEFF 00F6 FA00 00F6 FEFF 00FC F400 04F6" /* ...... */ + $"F9FB 8156 F400 01F7 F9FE 0002 F7FB F9FA" /* V.... */ + $"0000 FAFD FF02 F600 00F8 0004 F6F9 81FB" /* ....... */ + $"56FA 0000 F6FD FF00 F7F9 0001 F756 FD00" /* V.....V. */ + $"04F7 FA81 F9F5 F100 04F8 FAFB FA2B F800" /* ...+. */ + $"00F5 FEFF 00FC F200 00F6 FED9 0039 E600" /* .....9. */ + $"FD00 0040 F8D9 0039 9000 F400 FEFD 009C" /* ..@.9... */ + $"FEF5 F800 00FB FDFF F900 00F7 FDFF 00AC" /* ..... */ + $"F800 01F5 FCFB FF00 56FA 0000 FBFD FF07" /* ...V... */ + $"F9F6 2B2B F600 00F6 FDFF 05FE F7F6 2B2B" /* ++...++ */ + $"F5FB 0001 F5FB FBFF 00F9 F700 05F6 FFAC" /* ..... */ + $"0000 F9FE FF00 ACFB 0000 FAFD FF02 F600" /* ....... */ + $"00FA 0001 F5FB FBFF 00FA FC00 00F6 FDFF" /* ...... */ + $"00F7 F900 01FE FDFE 0000 FCFC FF00 56F4" /* ......V */ + $"0000 F8FB FF01 FDF6 FB00 00F5 FDFF 00FE" /* ...... */ + $"FE00 00F5 F600 0439 D9D9 40F5 E600 FD00" /* ....9@.. */ + $"0039 F8D9 0040 9000 F400 FEFD 00A1 FEF5" /* .9.@... */ + $"F800 00FB FDFF F900 00F8 FDFF 0081 F900" /* ...... */ + $"00F7 FEFF 06F9 002B FEFF FFFB FC00 00F9" /* ...+.. */ + $"F7FF 02F6 00FD F8FF 00FC FC00 00F7 FEFF" /* ..... */ + $"06FA F52B FDFF FFFC F800 04AC FFAC 00F8" /* .+... */ + $"FCFF 0056 FC00 00FA FDFF 02F6 0000 FB00" /* .V...... */ + $"00F6 FEFF 06FA F5F6 ACFF FFFC FD00 00F6" /* .... */ + $"FDFF 00F7 FA00 05FA FFAC 0000 FDFA FF00" /* ...... */ + $"F8F6 0000 81FE FF02 F700 56FE FF00 F8FC" /* ....V. */ + $"0000 ACF8 FF00 56F8 0000 F5FE D900 0EE5" /* ...V.... */ + $"00FD 0000 39F8 D900 4090 00F4 00FE FD00" /* ...9.@... */ + $"A1FE F5F8 0000 FBFD FFF9 0000 81FD FF00" /* ..... */ + $"F7FA 0000 F6FE FF00 F8FD 0003 ACFF FFF9" /* ..... */ + $"FE00 0056 F6FF 01F6 ACF7 FF00 FDFD 0000" /* ..V.... */ + $"F6FE FF00 56FD 0003 FCFF FF81 FA00 0481" /* .V.... */ + $"FFFF FBF5 FBFF 00FD FC00 00FA FDFF 02F6" /* .... */ + $"0000 FC00 00F6 FEFF 0056 FD00 03FB FFFF" /* .....V.. */ + $"81FE 0000 F6FD FF00 F7FB 0005 F9FF FFAC" /* ..... */ + $"00FB F8FF 00F6 F800 03FA FFFF FDFD 0000" /* ...... */ + $"F7FE FF00 F6FE 0000 FBF7 FF00 FAF8 0003" /* ...... */ + $"32D9 D939 E400 FD00 0039 F7D9 9000 F400" /* 29...9ِ.. */ + $"FEFD 00A1 FEF5 F800 00FB FDFF FA00 00F5" /* ..... */ + $"FDFF 01FE F5FA 0003 FDFF FFFA FC00 00F6" /* ..... */ + $"FEFF 03F6 0000 56F7 FF02 FEF5 FCF7 FF00" /* ...V.. */ + $"FBFD 0003 FCFF FF81 FC00 00F6 FEFF 002B" /* .....+ */ + $"FC00 0081 FEFF 01AC FAFA FFFC 0000 FAFD" /* ..... */ + $"FF02 F600 00FC 0003 ACFF FFFB FC00 00F5" /* ....... */ + $"FEFF 03F8 0000 F6FD FF00 F7FD 0001 F581" /* ...... */ + $"FEFF 01FC 56F7 FF00 F9F9 0000 F7FE FF00" /* .V.... */ + $"2BFC 0003 81FF FFAC FE00 00FA F7FF 00F8" /* +..... */ + $"F800 0339 D9D9 F5E4 00FD 0000 39F7 D990" /* ..9...9ِ */ + $"00F4 00FE FD00 ABFE F5F8 0000 FBFD FFFA" /* ..... */ + $"0000 FAFD FF00 F9FA 0000 F9FE FFFA 0003" /* ....... */ + $"FDFF FFAC FD00 00F8 FDFF 00F8 FEF5 FE00" /* .... */ + $"01F5 81FE FF04 FDF6 00F5 F5FD 0000 56FE" /* .....V */ + $"FF00 F5FB 0003 ACFF FFFD FD00 00FC FBFF" /* ..... */ + $"00FD FBFF FC00 00FA FDFF 02F6 0000 FD00" /* ....... */ + $"00F7 FEFF 00F6 FB00 06FB FFFF FC00 00F6" /* ...... */ + $"FDFF 00F7 FD00 00AC FDFF 07FE FFFF F900" /* ..... */ + $"00F5 FDFC FF00 F5FA 0003 FEFF FFFB FB00" /* ..... */ + $"00F6 FEFF 00F8 FD00 00FA FEFF 00AC F300" /* ...... */ + $"02F6 4007 E300 FD00 0039 F7D9 9000 F400" /* .@....9ِ.. */ + $"FEFD 00A9 FEF5 F800 00FB FDFF FB00 0056" /* .....V */ + $"FDFF 00FB F900 03FD FFFF FBFA 0000 FBFE" /* ..... */ + $"FFFC 00FD FF00 F6FA 0000 F8FE FF00 FCF9" /* ..... */ + $"0003 ACFF FFFC FA00 0081 FEFF 03F5 0000" /* ....... */ + $"FAFB FF02 AC00 F8FC FFFC 0000 FAFD FF02" /* ..... */ + $"F600 00FD 0003 FEFF FFAC FA00 00F9 FEFF" /* ...... */ + $"02F7 00F6 FDFF 00F7 FE00 0056 FAFF 0056" /* .....V.V */ + $"FD00 01F5 FEFD FF00 F6FB 0000 56FE FF00" /* .....V. */ + $"F6FA 00FE FF00 FCFD 0000 2BFE FF00 FCD2" /* ....+. */ + $"00FD 0000 40F7 D9FA 0000 F9FB FF00 F9FA" /* ...@... */ + $"0000 F9FB FF00 F9AE 00F4 00FE FD00 B3FE" /* ...... */ + $"F5F8 0000 FBFD FF05 2B00 00F5 F8FC FDFF" /* ...+.. */ + $"0081 F900 0056 FEFF 00F7 FA00 00FB FEFF" /* ...V... */ + $"00F9 FE00 00F5 FDFF 00F6 FA00 00F8 FEFF" /* ...... */ + $"00AC FA00 00F8 FEFF 00F8 FA00 00FA FEFF" /* ...... */ + $"04FA 0000 2BFD FCFF 03F8 0000 81FE FF00" /* ...+.... */ + $"FBFC 0000 FAFD FF02 F600 00FE 0000 F7FE" /* ....... */ + $"FF00 F9FA 0000 56FE FF02 F900 F6FD FF00" /* ...V... */ + $"F7FE 0001 F6FB FCFF 00AC FB00 0056 FDFF" /* .....V */ + $"00F8 FB00 00FD FEFF F900 FDFF FD00 002B" /* ......+ */ + $"FEFF 00FC D200 FD00 0040 F7D9 FA00 00FF" /* ....@.. */ $"FB2B 00FF FA00 00FF FB2B 00FF AE00 F400" /* +...+... */ - $"FEFD 008F FEF5 F700 00FC FDFF 002B F800" /* ....+. */ - $"00AC FDFF 00FD FD00 0056 FDFF 00FB F4F9" /* ....V. */ - $"002B FD00 002B FDFF 002B F900 002B FDFF" /* .+..+.+..+ */ - $"002B FB00 0056 FDFF 00FB F4F9 002B FC00" /* .+..V..+. */ - $"00FC FDFF F700 FC00 00FC FDFF 002B FC00" /* .....+. */ - $"00FE FEFF 00FE F4F9 0356 0000 2BFD FF00" /* ...V..+. */ - $"F9FB 0000 2BFD FF00 F9F8 00FD FF00 FCFC" /* ..+... */ - $"0000 FBFD FF00 FAF4 F900 F5FD 0000 F9FD" /* ...... */ - $"FFE8 00ED 00F5 FFFE 00F5 FFFD FAB4 00F4" /* .... */ - $"00FE FD00 8AFE F5F7 0000 FCFD FF00 2BF8" /* .....+ */ - $"0000 2BFC FF00 F8FE 0000 F9FD FF00 2BEF" /* ..+....+ */ - $"0000 2BFD FF00 2BF9 0000 2BFD FF00 2BFB" /* ..+.+..+.+ */ - $"0000 F9FD FF00 2BEE 0000 FCFD FFF7 00FC" /* ...+... */ - $"0000 FCFD FF00 2BFC 00FD FF00 FCF1 0000" /* ...+.... */ - $"2BFD FF00 F9FB 0000 2BFD FF00 F9F8 00FD" /* +...+.. */ - $"FF00 FCFC 0000 FCFD FFEE 0000 F9FD FFE8" /* ..... */ - $"00ED 0000 FFF9 2B02 D82B FFFE FA00 FFF9" /* ...+.+. */ - $"2B02 D82B FFFE 0000 FAB4 00F4 00FE FD00" /* +.+..... */ - $"86FE F5F7 0000 FCFD FF00 2BF7 0000 FDFD" /* ...+.. */ - $"FF00 FBFE 0000 F9FD FF00 2BEF 0000 2BFD" /* ....+..+ */ - $"FF00 2BF9 0000 2BFD FF00 2BFB 0000 F9FD" /* .+..+.+.. */ - $"FF00 2BEE 0000 FCFD FFF7 00FC 0000 FCFD" /* .+..... */ - $"FF00 2BFC 00FD FF00 FCF1 0000 2BFD FF00" /* .+....+. */ - $"F9FB 0000 2BFD FF00 F9F8 00FD FF00 FCFC" /* ..+... */ - $"0000 FCFD FFEE 0000 F9FD FFE8 00ED 0000" /* ....... */ - $"FFF7 2B00 FFFE 0000 FFF7 2B00 FFFE 0000" /* +...+... */ - $"FAB4 00F4 00FE FD00 8CFE F5F7 0000 FCFD" /* ..... */ - $"FF00 2BF7 0000 81FD FF00 FEFE 0000 FCFD" /* .+..... */ - $"FF00 2BEF 0000 2BFD FF00 2BF9 0000 2BFD" /* .+..+.+..+ */ - $"FF00 2BFB 0000 FCFD FF00 2BEE 0000 FCFD" /* .+...+.. */ - $"FFF7 00FC 0000 FCFD FF00 2BFD 0000 2BFD" /* ....+..+ */ - $"FF00 FCF1 0000 2BFD FF00 F9FB 0000 2BFD" /* ...+...+ */ - $"FF00 F9F8 00FD FF00 FCFC 00FC FFEE 0000" /* ...... */ - $"F9FD FFE8 00ED 00F5 FFFE 00F5 FFFE 0000" /* ..... */ - $"FACB 0000 F9FB FF00 F9FA 0000 F9FB FF00" /* ...... */ - $"F9F4 00FE FD00 83FE F5F7 0000 FCFD FF00" /* ..... */ - $"2BF7 0000 F8FC FF03 F500 00FC FDFF 002B" /* +......+ */ - $"EF00 0056 FDFF 002B F900 0056 FDFF 002B" /* ..V.+..V.+ */ - $"FB00 00FC FDFF 002B EE00 00FC FDFF F700" /* ...+... */ - $"FC00 00FC FDFF 002B FD00 002B FDFF 00FC" /* ...+..+. */ - $"F100 002B FDFF 00F9 FB00 002B FDFF 00F9" /* ..+...+. */ - $"F800 FDFF 00FC FC00 FCFF EE00 00FB FDFF" /* ..... */ - $"E800 CF00 00FA CB00 00FF FB2B 00FF FA00" /* .....+.. */ - $"00FF FB2B 00FF F400 FEFD 008B FEF5 F700" /* .+.... */ - $"00FC FDFF 002B F700 002B FCFF 032B 0000" /* ..+..+.+.. */ - $"FCFD FF00 2BEF 0000 F9FD FF00 2BF9 0000" /* .+...+.. */ - $"F9FD FF00 2BFB 0000 FCFD FF00 2BEE 0000" /* .+...+.. */ - $"FCFD FFF7 00FC 0000 FCFD FF00 2BFD 0000" /* ....+.. */ - $"2BFD FF00 FCF1 0000 2BFD FF00 F9FB 0000" /* +...+... */ - $"2BFD FF00 F9F8 00FD FF00 FCFC 00FC FFEE" /* +.... */ - $"0000 FCFD FFE8 00E4 00F6 FFF7 0000 FACB" /* ...... */ - $"0001 FF2B FDFC 012B FFFA 0001 FF2B FDFC" /* ..+.+..+ */ - $"012B FFF4 00FE FD00 95FE F5F7 0000 FCFD" /* .+.... */ - $"FF00 2BF6 00FC FF03 5600 00FC FDFF 002B" /* .+..V...+ */ - $"EF00 00F9 FDFF 002B F900 00F9 FDFF 002B" /* ...+...+ */ - $"FB00 00FC FDFF 002B EE00 00FC FDFF F700" /* ...+... */ - $"FC00 00FC FDFF 002B FD00 002B FDFF 00FC" /* ...+..+. */ - $"F100 002B FDFF 00F9 FB00 002B FDFF 00F9" /* ..+...+. */ - $"F800 FDFF 00FC FC00 FCFF EE00 00FC FDFF" /* ..... */ - $"E800 E400 0AFF F9FC F9FC F9FC F9FC F9FF" /* .. */ - $"F700 00FA CB00 07FF 2BFC 2A2A F52B FFFA" /* ....+**+ */ - $"0007 FF2B FC2A 2AF5 2BFF F400 FEFD 0097" /* ..+**+.. */ - $"FEF5 F700 00FC FDFF 002B F600 FCFF 03F9" /* ...+.. */ - $"0000 FCFD FF00 56EF 0000 F9FD FF00 2BF9" /* ...V...+ */ - $"0000 F9FD FF00 2BFB 0000 FCFD FF00 56EE" /* ...+...V */ - $"0000 FCFD FFF7 00FC 0000 FCFD FF00 2BFD" /* ......+ */ - $"0000 2BFD FF00 FEF1 0000 2BFD FF00 F9FB" /* ..+...+. */ - $"0000 2BFD FF00 F9F8 00FD FF00 FCFC 00FC" /* ..+.... */ - $"FF00 F6EF 0000 FCFD FFE8 00E4 000A FFF9" /* ..... */ - $"FCF9 FCF9 FCF9 FCF9 FFF7 0000 FACB 0002" /* .... */ - $"FF2B FCFE F501 2BFF FA00 02FF 2BFC FEF5" /* +.+..+ */ - $"012B FFF4 00FE FD00 8FFE F5F7 0000 FCFD" /* .+.... */ - $"FF00 2BF6 00FC FF03 F900 00FA FDFF 00F9" /* .+..... */ - $"EF00 00F9 FDFF 002B F900 00F9 FDFF 002B" /* ...+...+ */ - $"FB00 00FA FDFF 00F9 EE00 00FC FDFF F700" /* ...... */ - $"FC00 00FC FDFF 002B FC00 FCFF F100 002B" /* ...+...+ */ - $"FDFF 00F9 FB00 002B FDFF 00F9 F800 FDFF" /* ...+.. */ - $"00FC FC00 00AC FDFF 002B EF00 00FC FDFF" /* ....+.. */ - $"E800 E400 0AFF F9FC F9FC F9FC F9FC F9FF" /* .. */ - $"F700 00FA CB00 00FF FB2B 00FF FA00 00FF" /* ....+... */ - $"FB2B 00FF F400 FEFD 008D FEF5 F700 00FC" /* +..... */ - $"FDFF 002B F600 FCFF 03F9 0000 F9FD FF00" /* .+..... */ - $"FBEF 0000 F9FD FF00 2BF9 0000 F9FD FF00" /* ...+... */ - $"2BFB 0000 F9FD FF00 FBEE 0000 FCFD FFF7" /* +..... */ - $"00FC 0000 FCFD FF00 2BFC 00FC FF00 F6F2" /* ....+.. */ - $"0000 2BFD FF00 F9FB 0000 2BFD FF00 F9F8" /* ..+...+. */ - $"00FD FF00 FCFC 0000 FCFD FF00 56EF 0000" /* .....V.. */ - $"FCFD FFE8 00E4 000A FFF9 FCF9 FCF9 FCF9" /* .. */ - $"FCF9 FFF7 0000 FACD 00F5 FFFE 00F7 FFFF" /* .... */ - $"FFFD FAFA 00FE FD00 9AFE F5F7 0000 FCFD" /* .... */ - $"FF00 2BF6 00FC FF03 F900 00F9 FDFF 00FD" /* .+..... */ - $"EF00 00F9 FDFF 002B F900 00F9 FDFF 002B" /* ...+...+ */ - $"FB00 00F9 FDFF 00FD EE00 00FC FDFF F700" /* ...... */ - $"FC00 00FC FDFF 002B FC00 FCFF 00F8 F200" /* ...+... */ - $"002B FDFF 00F9 FB00 002B FDFF 00F9 F800" /* .+...+.. */ - $"FDFF 00FC FC00 00FC FDFF 0081 EF00 00FC" /* ...... */ - $"FDFF E800 E400 0AFF F9FC F9FC F9FC F9FC" /* .. */ - $"F9FF F700 EBFA E200 00FF F92B 02D8 2BFF" /* ...+.+ */ - $"FEFA 00FF F92B 00D8 012B FFFE 0000 FAFA" /* .+..+.. */ - $"00FE FD00 9AFE F5F7 0000 FCFD FF00 2BF7" /* .....+ */ - $"0000 F5FC FF03 F700 002B FCFF EF00 00F9" /* .....+.. */ - $"FDFF 002B F900 00F9 FDFF 002B FB00 002B" /* .+...+..+ */ - $"FCFF EE00 00FC FDFF F700 FC00 00FC FDFF" /* ..... */ - $"002B FC00 00FC FDFF 00FA F200 002B FDFF" /* .+.....+ */ - $"00F9 FB00 002B FDFF 00F9 F800 FDFF 00FC" /* ...+... */ - $"FC00 00F9 FDFF 00AC EF00 00FC FDFF E800" /* ...... */ - $"E400 0AFF F9FC F9FC F9FC F9FC F9FF F700" /* .. */ - $"00FA ED00 00FA E200 00FF F72B 00FF FE00" /* .....+.. */ - $"00FF F82B 012B FFFE 0000 FAFA 00FE FD00" /* .+.+.... */ - $"8BFE F5F7 0000 FCFD FF00 2BF7 0000 2BFC" /* ...+..+ */ - $"FF03 2B00 00F5 FCFF 00F8 F000 00F9 FDFF" /* .+..... */ - $"002B F900 00F9 FDFF 002B FB00 00F5 FCFF" /* .+...+.. */ - $"00F8 EF00 00FC FDFF F700 FC00 00FC FDFF" /* ...... */ - $"002B FC00 0081 FDFF 00FD F200 002B FDFF" /* .+.....+ */ - $"00F9 FB00 002B FDFF 00F9 F800 FDFF 00FC" /* ...+... */ - $"FC00 00F8 FCFF 00F5 F000 00FC FDFF E800" /* ...... */ - $"E700 F0FF FAFA EC00 00FA E200 F5FF FE00" /* ..... */ - $"F7FF FFFF FE00 00FA FA00 FEFD 0088 FEF5" /* .... */ - $"F700 00FC FDFF 002B F700 0056 FCFF FD00" /* ...+..V. */ - $"00FE FDFF 00FB F000 00F9 FDFF 002B F900" /* .....+. */ - $"00F9 FDFF 002B FA00 00FE FDFF 00FB EF00" /* ..+.... */ - $"00FC FDFF F700 FC00 00FC FDFF 002B FC00" /* .....+. */ - $"0056 FCFF 00F6 F300 002B FDFF 00F9 FB00" /* .V...+.. */ - $"002B FDFF 00F9 F800 FDFF 00FC FC00 00F6" /* .+..... */ - $"FCFF 0056 F000 00FC FDFF E800 E700 00FF" /* .V..... */ - $"F2F9 00FF FA00 00FA ED00 00FA C900 FC00" /* ....... */ - $"00FA FA00 FEFD 008E FEF5 F700 00FC FDFF" /* ..... */ - $"002B F700 00FB FDFF 00AC FD00 00FB FCFF" /* .+..... */ - $"00F5 F100 00F9 FDFF 002B F900 00F9 FDFF" /* ....+.. */ - $"002B FA00 00FB FCFF 00F5 F000 00FC FDFF" /* .+..... */ - $"F700 FC00 00FC FDFF 002B FC00 00F6 FCFF" /* ....+.. */ - $"0081 F300 002B FDFF 00F9 FB00 002B FDFF" /* ...+...+ */ - $"00F9 F800 FDFF 00FC FB00 00FE FDFF 00FD" /* ...... */ - $"F000 00FC FDFF E800 E700 00FF F2F9 00FF" /* ...... */ - $"FA00 00FA ED00 00FA D900 F6FF FC00 FC00" /* ....... */ - $"00FA FA00 FEFD 00A4 FEF5 F700 00FC FDFF" /* ..... */ - $"002B F700 00FE FDFF 00FA FD00 0056 FCFF" /* .+.....V */ - $"0081 F600 00AC FD00 00F9 FDFF 002B F900" /* ......+. */ - $"00F9 FDFF 002B FA00 0056 FCFF 0081 F600" /* ..+..V.. */ - $"00AC FC00 00FC FDFF F700 FC00 00FC FDFF" /* ...... */ - $"002B FB00 00FE FCFF 00F5 F700 03F7 F900" /* .+...... */ - $"2BFD FF00 F9FB 0000 2BFD FF00 F9F8 00FD" /* +...+.. */ - $"FF00 FCFB 0000 FBFC FF00 F8F7 0001 F5FB" /* ...... */ - $"FD00 00FC FDFF E800 E700 F0FF FA00 00FA" /* ...... */ - $"ED00 00FA D900 0AFF F9FC F9FC F9FC F9FC" /* ... */ - $"F9FF FC00 FC00 00FA FA00 FEFD 00A5 FEF5" /* ..... */ - $"F700 00FC FDFF 002B F800 00F8 FCFF 00F6" /* ...+... */ - $"FD00 00F5 FBFF 00F6 F800 01FA FEFD 0000" /* ....... */ - $"F9FD FF00 56F9 0000 F9FD FF00 56FA 0000" /* .V...V.. */ - $"F5FB FF00 F6F8 0001 FAFE FC00 00FC FDFF" /* ..... */ - $"F700 FC00 00FC FDFF 002B FB00 0081 FCFF" /* ....+.. */ - $"00FB F800 04F5 FE56 002B FDFF 00F9 FB00" /* ...V.+.. */ - $"002B FDFF 00F9 F800 FDFF 00FC FB00 00F8" /* .+..... */ - $"FCFF 00FD F700 01AC FBFD 0000 FCFD FF00" /* ...... */ - $"F6E9 00CF 0000 FAED 0000 FAD9 000A FFF9" /* ...... */ - $"FCF9 FCF9 FCF9 FCF9 FFFC 00FC 0000 FAFA" /* ... */ - $"00FE FD00 CAFE F5F7 0000 FCFD FF00 F9F8" /* ..... */ - $"0000 FDFD FF00 FDFB 0000 FCFC FF00 FEF9" /* ...... */ - $"0002 F8FF 81FD 0000 2BFD FF00 FAFD 0000" /* ....+... */ - $"2BFE 0000 2BFD FF00 FAFD 0000 2BFE 0000" /* +..+...+.. */ - $"FCFC FF00 FEF9 0002 F8FF 81FC 0000 FCFD" /* ..... */ - $"FFF7 00FC 0000 FCFD FF00 2BFB 0000 2BFB" /* ....+..+ */ - $"FF00 F9F9 0004 ACFF F500 2BFD FF00 F9FB" /* ....+. */ - $"0000 2BFD FF00 F9F8 00FD FF00 FCFA 0000" /* ..+..... */ - $"FEFC FF00 FCF9 0002 81FF F8FD 0000 F9FD" /* ..... */ - $"FF00 F7FD 0000 2BEE 00ED 0000 F9FC FF00" /* ...+.... */ - $"F9FD 0000 F9FC FF00 F9FD 0000 F9FC FF02" /* ...... */ - $"F900 FAED 0000 FAD9 000A FFF9 FCF9 FCF9" /* .... */ - $"FCF9 FCF9 FFFC 00FC 0000 FAFA 00FE FD00" /* ..... */ - $"D7FE F5F7 0000 FDFD FF00 ACF9 0000 81FC" /* ..... */ - $"FF00 F7FB 0000 F7FB FF01 FE2B FC00 03FA" /* ....+.. */ - $"FFFF F6FD 0000 2BFD FF00 FDFE 0005 F8FF" /* ..+... */ - $"2B00 002B FDFF 00FD FE00 05F8 FF2B 0000" /* +..+...+.. */ - $"F7FB FF01 FE2B FC00 03FA FFFF F6FC 0000" /* .+.... */ - $"FCFD FF00 F5F8 00FC 0000 FDFD FF00 F8FA" /* ..... */ - $"0000 ACFB FF00 81FC 0006 2BFD FFFB 0000" /* .....+.. */ - $"2BFD FF00 81FB 0000 2BFD FF00 F9F8 00FD" /* +...+.. */ - $"FF00 ACFA 0000 FAFB FF01 ACF5 FD00 03F5" /* ...... */ - $"FCFF FDFC 0000 F9FD FF00 81FE 0001 81FF" /* ..... */ - $"EE00 ED00 00FF FC2B 00FF FD00 00FF FC2B" /* ...+...+ */ - $"00FF FD00 00FF FC2B 02FF 00FA ED00 00FA" /* ...+.... */ - $"D900 0AFF F9FC F9FC F9FC F9FC F9FF FC00" /* .. */ - $"FC00 00FA FA00 FEFD 00D9 FEF5 F800 002B" /* ......+ */ - $"FBFF 0056 FB00 00FA FCFF 00FB F900 00AC" /* .V..... */ - $"FAFF 07AC F9F9 81FE FFFF FAFB 00FC FF05" /* ... */ - $"812B FAFF FFF5 FE00 FCFF 0581 2BFA FFFF" /* +..+ */ - $"F5FE 0000 ACFA FF07 ACF9 F981 FEFF FFFA" /* ... */ - $"FC00 00F5 FCFF 0081 F800 FD00 002B FCFF" /* ......+ */ - $"00FC FA00 00F7 FAFF 0BFE 81F9 F9AC FFFF" /* .... */ - $"FEF5 0000 F9FD FF00 FDFB 0000 FAFD FF00" /* ...... */ - $"ACF9 0000 2BFC FF00 F5FB 0001 F5FE FAFF" /* ..+... */ - $"03FB F9F9 FBFE FF00 F7FC 0000 2BFC FF04" /* ....+. */ - $"562B FCFF FDEE 00ED 0006 FF2B FCFC F52B" /* V+...++ */ - $"FFFD 0006 FF2B FCFC F52B FFFD 0008 FF2B" /* ..++..+ */ - $"FCFC F52B FF00 FAED 0000 FAD9 000A FFF9" /* +.... */ + $"FEFD 00B7 FEF5 F800 00FB FCFF FFFE FBFF" /* ... */ + $"00FC F800 00FB FEFF 00F6 FA00 00FD FEFF" /* ...... */ + $"00AC FE00 00F5 FDFF 00F6 FA00 00F8 FEFF" /* ...... */ + $"00AC FA00 0081 FEFF 002B FA00 00FC FEFF" /* ....+.. */ + $"00FE FD00 00FD FDFF 00F6 FE00 0381 FFFE" /* ...... */ + $"F5FC 0000 FAFD FF02 F600 00FE 0000 ACFE" /* ....... */ + $"FF00 F7FA 0000 81FE FF02 FC00 F6FD FF00" /* ...... */ + $"F7FC 0000 FCFD FF00 F9FB 0000 F6FD FF00" /* ...... */ + $"81FC 0000 F7FE FF00 ACFA 0000 F5FD FF00" /* ...... */ + $"F8FE 0000 2BFE FF00 FCD2 00FD 00F7 D900" /* ..+.... */ + $"40FA 0001 FF2B FDFC 012B FFFA 0001 FF2B" /* @..+.+..+ */ + $"FDFC 012B FFAE 00F4 00FE FD00 B1FE F5F8" /* .+... */ + $"0000 FBF3 FF01 FCF6 FB00 00F6 FDFF 00F5" /* ...... */ + $"FB00 00F6 FDFF 00FE FE00 00F5 FDFF 00F6" /* ...... */ + $"FA00 00F8 FEFF 00AC FB00 01F6 FEFE FF00" /* ...... */ + $"F6FB 0000 F5FC FFFD 0000 81FD FFFC 0001" /* ...... */ + $"F6F5 FB00 00FA FDFF 02F6 0000 FE00 FDFF" /* ...... */ + $"00F5 FB00 00F5 FDFF 02FD F5F6 FDFF 00F7" /* ..... */ + $"FC00 00F8 FDFF 00F8 FA00 00AC FEFF 00FB" /* ...... */ + $"FC00 00FA FEFF 0081 FA00 00FA FDFF 00F9" /* ...... */ + $"FE00 002B FEFF 00FC D200 FE00 00F7 F7D9" /* ..+.... */ + $"0040 FA00 07FF 2BFC 2A2A F52B FFFA 0007" /* .@..+**+.. */ + $"FF2B FC2A 2AF5 2BFF AE00 F400 FEFD 00B6" /* +**+... */ + $"FEF5 F800 00FB FDFF 00FA FE56 01F9 FCFB" /* ...V. */ + $"FF00 2BFC 0000 F8FD FF00 F6FC 0000 56FB" /* .+.....V */ + $"FFFE 0000 F5FD FF00 F6FA 0000 F8FE FF00" /* ...... */ + $"ACFB 0000 F7FD FF00 2BFC 0000 F8FB FF00" /* ...+... */ + $"F5FE 0000 FAFD FFF4 0000 FAFD FF02 F600" /* ...... */ + $"00FF 0000 2BFD FF00 F6FC 0001 F8FE FCFF" /* ...+... */ + $"01F6 F5FD FF00 F7FC 0000 F7FD FF00 F6FA" /* ..... */ + $"0000 FCFE FF00 FEFC 0000 FCFE FF00 81FC" /* ...... */ + $"0001 F6FB FCFF 00FB FE00 002B FEFF 00FC" /* .....+. */ + $"D200 FE00 0039 F7D9 0039 FA00 02FF 2BFC" /* ...9.9..+ */ + $"FEF5 012B FFFA 0002 FF2B FCFE F501 2BFF" /* .+..+.+ */ + $"AE00 F400 FEFD 008B FEF5 F800 00FB FDFF" /* ..... */ + $"FB00 01F6 ACFC FF00 F6FD 0000 56F0 FF03" /* .....V. */ + $"F500 00F5 FDFF 00F6 FA00 00F8 FEFF 00AC" /* ...... */ + $"FB00 00F8 F0FF 00F6 FE00 0081 FDFF F400" /* ...... */ + $"00FA FDFF 02F6 0000 FF00 00F9 F0FF 012B" /* .......+ */ + $"F5FD FF00 F7FC 0000 F8FD FF00 F6FA 0000" /* ...... */ + $"81FD FFFC 0000 FDF1 FF00 FBFE 0000 2BFE" /* .....+ */ + $"FF00 FCD2 00FE 0000 40F7 D900 32FA 0000" /* ....@.2.. */ + $"FFFB 2B00 FFFA 0000 FFFB 2B00 FFAE 00F4" /* +...+.. */ + $"00FE FD00 88FE F5F8 0000 FBFD FFF9 0000" /* ...... */ + $"FDFD FF00 FCFD 0000 81F1 FF00 FDFE 0000" /* ...... */ + $"F5FD FF00 F6FA 0000 F8FE FF00 ACFB 0000" /* ...... */ + $"FAF1 FF00 FEFD 0000 81FD FFF4 0000 FAFD" /* ..... */ + $"FF02 F600 00FF 0000 FBF1 FF02 FEF5 F6FD" /* ...... */ + $"FF00 F7FC 0000 F8FD FF00 F6FA 0000 FAFE" /* ...... */ + $"FF00 FEFD 0000 2BF0 FF00 F9FE 0000 2BFE" /* ...+...+ */ + $"FF00 FCD2 00FF 0000 F6F6 D900 F7FC 00F5" /* ...... */ + $"FFFE 00F5 FFFD FAB4 00F4 00FE FD00 A3FE" /* .... */ + $"F5F8 0000 FBFD FFF9 0000 F6FC FF00 2BFE" /* .....+ */ + $"0000 ACFE FF00 ACF5 5600 F5FE 0000 F5FD" /* ...V... */ + $"FF00 F6FA 0000 F8FE FF00 ACFB 0000 FCFE" /* ...... */ + $"FF00 FDF5 5600 F5FD 0000 81FD FFF4 0000" /* .V..... */ + $"FAFD FF02 F600 00FF 0000 FDFD FFF5 5602" /* .....V. */ + $"F500 F6FD FF00 F7FC 0000 F8FD FF00 F6FA" /* ..... */ + $"0000 FAFE FF00 FEFD 0000 F8FD FF00 FAF7" /* ...... */ + $"5601 F9F7 FD00 002B FEFF 00FC D200 FF00" /* V...+... */ + $"0039 F6D9 FB00 00FF F92B 02D8 2BFF FEFA" /* .9..+.+ */ + $"00FF F92B 02D8 2BFF FE00 00FA B400 F400" /* .+.+.... */ + $"FEFD 0094 FEF5 F800 00FB FDFF F800 00F9" /* ..... */ + $"FDFF 0081 FE00 00FD FEFF 00F9 F100 00F5" /* ...... */ + $"FDFF 00F6 FA00 00F8 FEFF 00AC FB00 00AC" /* ...... */ + $"FEFF 00F9 F000 0081 FDFF F400 00FA FDFF" /* ..... */ + $"02F6 0000 FF00 00FE FEFF 00FB F300 00F6" /* ........ */ + $"FDFF 00F7 FC00 00F8 FDFF 00F6 FA00 00FA" /* ...... */ + $"FEFF 00FE FD00 00F8 FDFF 00F5 F100 002B" /* ......+ */ + $"FEFF 00FC D200 FF00 0040 F7D9 0039 FB00" /* ....@.9. */ + $"00FF F72B 00FF FE00 00FF F72B 00FF FE00" /* .+...+.. */ + $"00FA B400 F400 FEFD 0094 FEF5 F800 00FB" /* ...... */ + $"FDFF F800 00F7 FCFF FF00 00F5 FDFF 00F9" /* ..... */ + $"F000 FDFF 00F6 FA00 00F8 FEFF 00AC FC00" /* ...... */ + $"01F5 FEFE FF00 FAF0 0000 81FD FFF4 0000" /* ...... */ + $"FAFD FF02 F600 00FF 00FD FF00 FBF3 0000" /* ....... */ + $"F6FD FF00 F7FC 0000 F8FD FF00 F6FA 0000" /* ...... */ + $"FAFE FF00 FEFD 0000 F9FD FF00 F5F1 0000" /* ...... */ + $"2BFE FF00 FCD2 0001 000E F6D9 0032 FB00" /* +......2. */ + $"F5FF FE00 F5FF FE00 00FA CB00 00F9 FBFF" /* ..... */ + $"00F9 FA00 00F9 FBFF 00F9 F400 FEFD 008F" /* ...... */ + $"FEF5 F800 00FB FDFF F800 01F5 FEFD FF02" /* ..... */ + $"F500 F6FD FF00 F9F1 0000 F6FD FF00 F6FA" /* ..... */ + $"0000 F9FE FF00 ACFC 0000 F6FD FF00 FAF0" /* ...... */ + $"0000 81FD FFF4 0000 FAFD FF02 F600 0001" /* ........ */ + $"00F5 FDFF 00FB F300 00F6 FDFF 00F7 FC00" /* ...... */ + $"00F8 FDFF 00F6 FA00 00FA FEFF 00FE FD00" /* ...... */ + $"00FA FDFF 00F5 F100 00F8 FEFF 00FC D200" /* ...... */ + $"0100 40F6 D900 F5DD 0000 FACB 0000 FFFB" /* ..@..... */ + $"2B00 FFFA 0000 FFFB 2B00 FFF4 00FE FD00" /* +...+... */ + $"95FE F5F8 0000 FBFD FFF7 0000 FCFD FF02" /* ..... */ + $"2B00 F6FD FF00 F9F1 0000 F8FD FF00 F6FA" /* +..... */ + $"0000 81FE FF00 ACFC 0000 F6FD FF00 FAF0" /* ...... */ + $"0000 81FD FFF4 0000 FAFD FF02 F600 0001" /* ........ */ + $"00F5 FDFF 00FB F300 00F6 FDFF 00F7 FC00" /* ...... */ + $"00F8 FDFF 00F6 FA00 00FA FEFF 00FE FD00" /* ...... */ + $"00FA FDFF 00F5 F100 00FA FEFF 00FC D200" /* ...... */ + $"00F7 F6D9 0039 F100 F6FF F700 00FA CB00" /* ..9.... */ + $"01FF 2BFD FC01 2BFF FA00 01FF 2BFD FC01" /* .+.+..+. */ + $"2BFF F400 FEFD 00A1 FEF5 F800 00FB FDFF" /* +.... */ + $"F700 0081 FDFF 02F9 00F6 FDFF 00F9 F100" /* ...... */ + $"00F8 FDFF 00F6 FA00 0081 FEFF 00AC FC00" /* ...... */ + $"00F6 FDFF 00FA F000 0081 FDFF F400 00FA" /* ...... */ + $"FDFF 02F6 0000 0100 F5FD FF00 FBF3 0000" /* ........ */ + $"F6FD FF00 F7FC 0000 F8FD FF00 F6FA 0000" /* ...... */ + $"FAFE FF00 FEFD 0000 FAFD FF00 F5F1 0000" /* ...... */ + $"FAFE FF00 FCD2 0000 40F6 D900 F6F1 000A" /* ...@.. */ + $"FFF9 FCF9 FCF9 FCF9 FCF9 FFF7 0000 FACB" /* .. */ + $"0007 FF2B FC2A 2AF5 2BFF FA00 07FF 2BFC" /* ..+**+..+ */ + $"2A2A F52B FFF4 00FE FD00 A1FE F5F8 0000" /* **+.... */ + $"FBFD FFF7 0000 FAFD FF02 FA00 F6FD FF00" /* ..... */ + $"FBF1 0000 F8FD FF00 F6FA 0000 81FE FF00" /* ...... */ + $"ACFC 0000 F6FD FF00 FBF0 0000 81FD FFF4" /* ..... */ + $"0000 FAFD FF02 F600 0001 00F5 FDFF 00FD" /* ........ */ + $"F300 00F6 FDFF 00F7 FC00 00F8 FDFF 00F6" /* ...... */ + $"FA00 00FA FEFF 00FE FD00 00FA FDFF 002B" /* ......+ */ + $"F100 00FA FEFF 00FC D300 00F7 F6D9 0040" /* ......@ */ + $"F000 0AFF F9FC F9FC F9FC F9FC F9FF F700" /* .. */ + $"00FA CB00 02FF 2BFC FEF5 012B FFFA 0002" /* ...+.+.. */ + $"FF2B FCFE F501 2BFF F400 FEFD 009C FEF5" /* +.+.. */ + $"F800 00FB FDFF F700 00FA FDFF 03FA 00F5" /* ...... */ + $"FEFE FF00 FCF1 0000 F8FD FF00 F6FA 0000" /* ...... */ + $"81FE FF00 ACFC 0001 F5FD FEFF 00AC F000" /* ..... */ + $"0081 FDFF F400 00FA FDFF 02F6 0000 FF00" /* ....... */ + $"00FE FDFF F300 00F6 FDFF 00F7 FC00 00F8" /* ...... */ + $"FDFF 00F6 FA00 00FA FEFF 00FE FD00 0056" /* ......V */ + $"FDFF 00F7 F100 00FA FEFF 00FC D300 0040" /* ......@ */ + $"F6D9 0007 F000 0AFF F9FC F9FC F9FC F9FC" /* ... */ + $"F9FF F700 00FA CB00 00FF FB2B 00FF FA00" /* ....+.. */ + $"00FF FB2B 00FF F400 FEFD 0098 FEF5 F800" /* .+.... */ + $"00FB FDFF F700 00FA FDFF 0381 0000 FDFD" /* ...... */ + $"FF00 F5F2 0000 F8FD FF00 F6FA 0000 81FE" /* ...... */ + $"FF00 ACFB 0000 ACFD FF00 F6F1 0000 81FD" /* ...... */ + $"FFF4 0000 FAFD FF02 F600 00FF 0000 FEFD" /* ....... */ + $"FFF3 0000 F6FD FF00 F7FC 0000 F8FD FF00" /* ...... */ + $"F6FA 0000 FAFE FF00 FEFD 0000 F8FD FF00" /* ...... */ + $"F9F1 0000 FAFE FF00 FCD4 0001 32D9 F7D9" /* .....2 */ + $"0039 EF00 0AFF F9FC F9FC F9FC F9FC F9FF" /* .9. */ + $"F700 00FA CD00 F5FF FE00 F7FF FFFF FDFA" /* .... */ + $"FA00 FEFD 00A8 FEF5 F800 00FB FDFF F700" /* ..... */ + $"00FA FDFF 03FA 0000 ACFD FF00 F6F2 0000" /* ....... */ + $"F8FD FF00 F6FA 0000 81FE FF00 ACFB 0000" /* ...... */ + $"FCFD FF00 2BF1 0000 81FD FFF4 0000 FAFD" /* .+.... */ + $"FF02 F600 00FF 0000 FDFD FF00 2BF4 0000" /* ......+.. */ + $"F6FD FF00 F7FC 0000 F8FD FF00 F6FA 0000" /* ...... */ + $"FAFE FF00 FEFD 0000 F8FD FF00 FCF1 0000" /* ...... */ + $"FAFE FF00 FCD5 0002 F5D9 D9F7 D900 F5EF" /* .... */ + $"000A FFF9 FCF9 FCF9 FCF9 FCF9 FFF7 00EB" /* .. */ + $"FAE2 0000 FFF9 2B02 D82B FFFE FA00 FFF9" /* ..+.+. */ + $"2B00 D801 2BFF FE00 00FA FA00 FEFD 00A6" /* +..+.... */ + $"FEF5 F800 00FB FDFF F700 00FB FDFF 03F8" /* ..... */ + $"0000 FAFD FF00 F7F2 0000 F8FD FF00 F6FA" /* ...... */ + $"0000 81FE FF00 ACFB 0000 F9FD FF00 F8F1" /* ...... */ + $"0000 81FD FFF4 0000 FAFD FF02 F600 00FF" /* ....... */ + $"0000 81FD FF00 F9F4 0000 F6FD FF00 F7FC" /* ...... */ + $"0000 F8FD FF00 F6FA 0000 FAFE FF00 FEFD" /* ...... */ + $"0000 F6FC FFF1 0000 FAFE FF00 FCD5 0002" /* ....... */ + $"39D9 D9F8 D900 0EEE 000A FFF9 FCF9 FCF9" /* 9... */ + $"FCF9 FCF9 FFF7 0000 FAED 0000 FAE2 0000" /* ...... */ + $"FFF7 2B00 FFFE 0000 FFF8 2B01 2BFF FE00" /* +...+.+. */ + $"00FA FA00 FEFD 0095 FEF5 F800 00FB FDFF" /* ..... */ + $"F700 00AC FDFF 032B 0000 F9FD FF00 FBF2" /* ...+... */ + $"0000 F8FD FF00 F6FA 0000 81FE FF00 ACFB" /* ...... */ + $"0000 56FD FF00 FCF1 0000 81FD FFF4 0000" /* ..V..... */ + $"FAFD FF02 F600 00FF 0000 F9FD FF00 ACF4" /* ...... */ + $"0000 F6FD FF00 F7FC 0000 F8FD FF00 F6FA" /* ...... */ + $"0000 FAFE FF00 FEFC 0000 FDFD FF00 F6F2" /* ...... */ + $"0000 FAFE FF00 FCD6 0000 F7FE D9F9 D900" /* ...... */ + $"39F0 00F0 FFFA FAEC 0000 FAE2 00F5 FFFE" /* 9.... */ + $"00F7 FFFF FFFE 0000 FAFA 00FE FD00 91FE" /* ..... */ + $"F5F8 0000 FBFD FFF8 0000 F6FC FFFE 0000" /* ...... */ + $"F8FC FFF2 0000 F8FD FF00 F6FA 0000 81FE" /* ..... */ + $"FF00 ACFB 0000 F7FC FF00 F5F2 0000 81FD" /* ...... */ + $"FFF4 0000 FAFD FF02 F600 00FF 0000 F6FC" /* ....... */ + $"FF00 2BF5 0000 F6FD FF00 F7FC 0000 F8FD" /* .+..... */ + $"FF00 F6FA 0000 FAFE FF00 FEFC 0000 FCFD" /* ...... */ + $"FF00 FCF2 0000 FAFE FF00 FCD7 0000 F5FD" /* ...... */ + $"D9FA D901 40F5 F000 00FF F2F9 00FF FA00" /* .@.... */ + $"00FA ED00 00FA C900 FC00 00FA FA00 FEFD" /* ....... */ + $"00A9 FEF5 F800 00FB FDFF F800 00F8 FDFF" /* ..... */ + $"00FD FE00 01F6 FEFD FF00 F9F8 0001 F5F9" /* ...... */ + $"FE00 00F8 FDFF 00F6 FA00 0081 FEFF 00FC" /* ...... */ + $"FB00 01F5 FEFD FF00 FAF8 0001 F5F9 FD00" /* ...... */ + $"0081 FDFF F400 00FA FDFF 02F6 0000 FE00" /* ....... */ + $"FCFF 00FB F700 02F8 F5F6 FDFF 00F7 FC00" /* ..... */ + $"00F8 FDFF 00F6 FA00 00FA FEFF 00FE FC00" /* ...... */ + $"00F9 FCFF 00F5 F800 012B F8FE 0000 FAFE" /* ....+.. */ + $"FF00 FCD7 0000 39FD D9FA D900 F6EF 0000" /* ...9... */ + $"FFF2 F900 FFFA 0000 FAED 0000 FAD9 00F6" /* ...... */ + $"FFFC 00FC 0000 FAFA 00FE FD00 B1FE F5F8" /* ..... */ + $"0000 FBFD FFF8 0000 81FD FF00 56FD 0000" /* .....V.. */ + $"81FC FF00 F5F9 0001 FBFE FE00 00F8 FDFF" /* ..... */ + $"00F8 FA00 0081 FEFF 00FD FA00 00FA FCFF" /* ...... */ + $"00F6 F900 01FA FFFD 0000 81FD FFF4 0000" /* ....... */ + $"FAFD FF02 F600 00FE 0000 FCFC FF00 2BF9" /* ......+ */ + $"0003 FAFD F5F6 FDFF 00F7 FC00 00F8 FDFF" /* ..... */ + $"00F6 FA00 00FA FEFF 00FE FC00 002B FCFF" /* ......+ */ + $"00FB F900 02F6 FEF9 FE00 0081 FEFF 00AC" /* ...... */ + $"D800 0032 FCD9 FBD9 0007 EE00 F0FF FA00" /* ..2.... */ + $"00FA ED00 00FA D900 0AFF F9FC F9FC F9FC" /* .... */ + $"F9FC F9FF FC00 FC00 00FA FA00 FEFD 00BA" /* ..... */ + $"FEF5 F800 00FB FDFF 00F7 FA00 002B FCFF" /* .....+ */ + $"00F6 FD00 0056 FCFF 00FD FA00 0256 FF81" /* ...V...V */ + $"FE00 00F5 FDFF 00F9 FE00 00F6 FE00 0056" /* .......V */ + $"FDFF 00F6 FE00 03F6 0000 F8FC FF00 FEFA" /* ...... */ + $"0002 F8FF FBFD 0000 FAFD FFF4 0000 FAFD" /* ...... */ + $"FF02 F600 00FE 0000 2BFC FF01 FDF5 FB00" /* .....+.. */ + $"04F7 FF81 00F6 FDFF 00F7 FC00 00F8 FDFF" /* ..... */ + $"00F6 FA00 00FA FEFF 00FE FB00 00AC FCFF" /* ...... */ + $"00F9 FA00 02FD FFF6 FE00 00F7 FEFF 00FE" /* ...... */ + $"D900 00F6 FBD9 FCD9 0007 D500 00FA ED00" /* ....... */ + $"00FA D900 0AFF F9FC F9FC F9FC F9FC F9FF" /* .. */ + $"FC00 FC00 00FA FA00 FEFD 00D7 FEF5 F800" /* ...... */ + $"00FD FDFF 0081 FB00 01F5 FEFD FF00 FAFB" /* ..... */ + $"0000 FDFC FF01 FEF6 FD00 03FA FFFF F5FD" /* ..... */ + $"00FD FF08 FD00 00F6 FFFA 0000 F8FD FF08" /* ....... */ + $"5600 00F9 FFF6 0000 ACFC FF01 FE2B FD00" /* V.....+. */ + $"03F9 FFFF F6FD 0000 81FD FFF4 0000 FBFD" /* ..... */ + $"FF02 F700 00FD 0000 FEFB FF00 2BFD 0005" /* ......+.. */ + $"F9FF FFF7 00F6 FDFF 0056 FC00 00F8 FDFF" /* ..V.. */ + $"00F6 FA00 00FA FDFF FB00 0056 FBFF 00FA" /* .....V. */ + $"FD00 03F6 FEFF FBFD 0000 2BFD FF04 F600" /* ....+.. */ + $"00F7 FFDE 0000 40FB D9FD D900 07F2 0000" /* ...@.... */ + $"F9FC FF00 F9FD 0000 F9FC FF00 F9FD 0000" /* ...... */ + $"F9FC FF02 F900 FAED 0000 FAD9 000A FFF9" /* ..... */ $"FCF9 FCF9 FCF9 FCF9 FFFC 00FC 0000 FAFA" /* ... */ - $"00FE FD00 BCFE F5FA 0002 56FA FEFA FF05" /* ....V. */ - $"FBF7 2B2B 56FD FCFF 00AC F800 00F6 F4FF" /* ++V... */ - $"00AC FA00 00AC F9FF 0081 FD00 00AC F9FF" /* ...... */ - $"0081 FD00 00F6 F4FF 00AC FC00 01F8 FDFB" /* ...... */ - $"FF01 FCF8 FA00 0300 F5F9 81FA FF02 FDF9" /* ..... */ - $"F7FC 0000 FBF4 FF03 F700 2B81 FBFF 05AC" /* ....+. */ - $"F7F5 00F5 FAFB FF01 FCF8 FC00 0156 FEFC" /* ....V */ - $"FF02 FD56 F5FC 0000 56F4 FF00 FAFA 00F8" /* .V..V.. */ - $"FF00 F8EE 00ED 0006 FF2B FC2A F52B FFFD" /* ....+*+ */ - $"0006 FF2B FC2A F52B FFFD 0008 FF2B FC2A" /* ..+*+..+* */ - $"F52B FFFA FAED 0000 FAD9 000A FFF9 FCF9" /* +... */ - $"FCF9 FCF9 FCF9 FFFC 00FC 0000 FAFA 00FE" /* .... */ - $"FD00 95FE F5FB 0000 2BED FF00 ACF6 0000" /* ...+... */ - $"F8F6 FF00 ACF9 0000 FAFA FF00 FDFC 0000" /* ...... */ - $"FAFA FF00 FDFB 0000 F8F6 FF00 ACFC 0000" /* ...... */ - $"FDF7 FF00 FEFB 0001 00FB F5FF 00F6 FC00" /* ...... */ - $"00AC F6FF 02F8 00F8 F7FF 02FE 00FC F8FF" /* ..... */ - $"00F9 FE00 00F9 F8FF 00FC FB00 0081 F6FF" /* ...... */ - $"0081 F900 00AC FAFF 00FB ED00 ED00 06FF" /* ....... */ + $"00FE FD00 D4FE F5F9 0000 2BFB FF00 F8FD" /* ....+. */ + $"0001 F6FD FDFF 01FE F5FB 0000 F9FA FF02" /* ...... */ + $"FD81 FCFE FF00 F9FC 0000 FEFD FF07 81F9" /* .... */ + $"FFFF 5600 00F6 FCFF 03F9 FBFF FFFE 0000" /* V..... */ + $"56FA FF02 FD81 FCFE FF00 FAFC 0000 FEFD" /* V.... */ + $"FF00 FBF6 0000 2BFC FF02 ACF5 00FD 0000" /* ...+.... */ + $"F7FA FF02 FDFB FBFE FF03 F900 00FA FDFF" /* .... */ + $"00FC FC00 00FC FDFF 00F9 FA00 00AC FDFF" /* ...... */ + $"00F7 FB00 00FD FAFF 02FC FBFD FEFF 00F5" /* ..... */ + $"FC00 FCFF 03F6 F9FF FFDF 0000 39FA D9FE" /* ....9 */ + $"D900 07F1 0000 FFFC 2B00 FFFD 0000 FFFC" /* ....+... */ + $"2B00 FFFD 0000 FFFC 2B02 FF00 FAED 0000" /* +...+.... */ + $"FAD9 000A FFF9 FCF9 FCF9 FCF9 FCF9 FFFC" /* . */ + $"00FC 0000 FAFA 00FE FD00 BEFE F5FB 0001" /* ....... */ + $"F8AC F9FF 03FB F9F9 FBFB FF00 F6F9 0000" /* .... */ + $"FCF6 FF00 FCFB 0000 FBFA FF04 FDF5 0000" /* ...... */ + $"F5F9 FF00 F9FD 0000 FBF6 FF00 ACFD 0001" /* ...... */ + $"56FE FBFF 02FE F9F5 FB00 01F9 ACF9 FF00" /* V.... */ + $"FB00 F7FD 0000 FBF6 FF03 FC00 F7AC FBFF" /* ..... */ + $"04AC 5600 F6AC FBFF 01FC 2BFE 0001 2BFE" /* .V..+..+ */ + $"FBFF 0181 F6FD 0000 2BF5 FF00 F8FB 00F9" /* ...+.. */ + $"FF00 2BE0 0000 32F9 D902 D940 07F0 0006" /* .+..2.@... */ + $"FF2B FCFC F52B FFFD 0006 FF2B FCFC F52B" /* ++..++ */ + $"FFFD 0008 FF2B FCFC F52B FF00 FAED 0000" /* ..++... */ + $"FAD9 000A FFF9 FCF9 FCF9 FCF9 FCF9 FFFC" /* . */ + $"00FC 0000 FAFA 00FE FD00 ACFE F5FB 0000" /* ....... */ + $"FCF0 FF01 FE2B F800 01F5 ACF8 FF00 FCFA" /* .+... */ + $"0000 F7FA FF00 2BFD 0000 81FB FF00 ACFB" /* ...+... */ + $"0000 FCF8 FF00 FCFD 0000 56F7 FF00 FAFC" /* .....V. */ + $"0000 F6F6 FF00 FBFC 0000 ACF8 FF02 FC00" /* ....... */ + $"F6F7 FF01 F7FC F9FF 00AC FE00 00FD F9FF" /* .... */ + $"00AC FC00 0056 F7FF 0056 FA00 00FA FBFF" /* ...V.V.. */ + $"00FA E000 0007 F8D9 0140 F5EF 0006 FF2B" /* .....@..+ */ + $"FC2A F52B FFFD 0006 FF2B FC2A F52B FFFD" /* *+..+*+ */ + $"0008 FF2B FC2A F52B FFFA FAED 0000 FAD9" /* ..+*+.. */ + $"000A FFF9 FCF9 FCF9 FCF9 FCF9 FFFC 00FC" /* .. */ + $"0000 FAFA 00FE FD00 C5FE F5FB 000A F8FB" /* ..... */ + $"F9F8 2B2B F8F9 FBFC FEFC FF02 FDF9 F5F6" /* ++. */ + $"0001 F5FC FAFF 00FA F800 00FC FCFF 002B" /* ......+ */ + $"FC00 00F6 FCFF 00FC F900 00FB FAFF 0081" /* ...... */ + $"FC00 03F6 FBFC 81FE F904 FAFB ACFD F7FB" /* ... */ + $"000A 56FB F9F8 F72B 2BF7 56FA FC00 F7FB" /* .V++V. */ + $"0000 FBFA FF00 FAFE 000D 81FD FC81 F9F9" /* ..... */ + $"FAFB ACAC F6F8 ACFB FEF9 03FA FBAC 56FE" /* .V */ + $"0002 F9FD 81FD F902 FCAC F8FB 0000 F8FA" /* ..... */ + $"FF01 FDF7 F800 FCFF 00FA E000 00F5 F8D9" /* ..... */ + $"0039 ED00 06FF 2BFC 2AF5 2BFF FDFA 06FF" /* .9..+*+. */ $"2BFC 2AF5 2BFF FDFA 06FF 2BFC 2AF5 2BFF" /* +*+.+*+ */ - $"FDFA 06FF 2BFC 2AF5 2BFF EB00 DBFA F0FF" /* .+*+. */ - $"FFFA FCFA F900 FEFD 00CD FEF5 FB00 09F5" /* ... */ - $"FEFD FCFA F9F9 FAFC FEF8 FF01 FEF9 F400" /* .. */ - $"00F8 F8FF 00FC F800 01F5 FEFC FF01 FEF6" /* ..... */ - $"FC00 01F5 FEFC FF01 FEF6 FA00 00F8 F8FF" /* ..... */ - $"00FC FB00 03AC FFFF FDFE FC00 ACFE FF00" /* ..... */ - $"FEFB 0005 0056 FFFD FCFA FDF9 03FB FCFF" /* ...V. */ - $"FDFA 0000 ACF9 FF04 FEF8 0000 F8FE FF03" /* ...... */ - $"FDFC FCAC FEFF 04FE 00FC FFFF FDFC 03FE" /* ... */ - $"FFFF 56FE 0003 F9FF FFAC FEFC 03AC FFFF" /* V... */ - $"FCFA 0000 81F8 FF00 FAF8 0000 F7FB FF00" /* ...... */ - $"ACEC 00ED 0001 FF2B FEF5 012B FFFD 0001" /* ...+.+.. */ - $"FF2B FEF5 012B FFFD 0001 FF2B FEF5 012B" /* +.+..+.+ */ - $"FFEB 0000 FADC 0000 FFF2 F902 FF00 00FC" /* ....... */ - $"0000 FAFA 00FE FD00 A8FE F5F0 0007 2B56" /* ......+V */ - $"F9FB FCFC FAF8 F100 012B FCFC FF01 FDF8" /* ..+. */ - $"F600 00F8 FDFF 00FC F900 00F8 FDFF 00FC" /* ...... */ - $"F700 012B FCFC FF01 FDF8 F900 00F5 FA00" /* ..+.... */ - $"02F5 2BF5 FB00 EB00 01F9 FEFC FF01 81F5" /* .+.... */ - $"FD00 012B F6FA 0004 2BF5 00F5 F6FA 0000" /* ..+..+... */ - $"2BFC 0000 2BFA 0000 2BF8 0001 F8FD FCFF" /* +..+..+.. */ - $"01FC 2BF6 0000 81FD FF00 FAEB 00ED 0006" /* .+...... */ - $"FFE3 2BFC FC2B FFFD 0006 FFE3 2BFC FC2B" /* ++..++ */ - $"FFFD 0006 FFE3 2BFC FC2B FFEB 0000 FADC" /* ..++.. */ - $"0000 FFF2 F902 FF00 00FC 0000 FAFA 00FE" /* ........ */ - $"FD00 63FE F5D6 0004 F656 F956 F6F3 0003" /* .c..VV.. */ - $"F5F9 56F5 F700 03F5 F956 F5F4 0004 F656" /* V..V..V */ - $"F956 F6E6 00E9 0003 F7F9 F9F7 CB00 042B" /* V.....+ */ - $"F9F9 F8F5 F300 022B F9F8 E900 ED00 00FF" /* ..+... */ - $"FC2B 00FF FD00 00FF FC2B 00FF FD00 00FF" /* +...+... */ - $"FC2B 00FF EB00 00FA DC00 F0FF FF00 FC00" /* +...... */ - $"00FA FA00 FEFD 0020 FEF5 8400 8100 EC00" /* ... ... */ - $"FCFF FB00 FCFF FB00 FCFF EA00 00FA C900" /* ..... */ - $"FC00 00FA FA00 FEFD 002A FEF5 8400 8100" /* ....*.. */ - $"BA00 00FA E200 00F9 FCFF 00F9 FD00 00F9" /* ....... */ - $"FCFF 00F9 FD00 02F9 FFFF FEFF 02F9 00FA" /* ..... */ - $"FA00 FEFD 0033 FEF5 A700 00F5 DF00 D600" /* ..3.... */ - $"01F6 2BAE 00BA 0000 FAE2 0000 FFFC 2B00" /* .+.....+. */ - $"FFFD 0000 FFFC 2B00 FFFD 0002 FF2B 2BFE" /* ..+...++ */ - $"2B02 FF00 FAFA 00FE FD00 6EFE F5FB 0001" /* +....n.. */ - $"F62B FC00 05F7 2BF5 56FD F9ED 0002 F781" /* +..+V.. */ - $"FFE3 0001 F62B FC00 01F7 2BFA 0002 F8FC" /* ..+..+.. */ - $"FCDF 00FF 0007 F6FA FE2B 0000 2BF7 E100" /* ...+..+. */ - $"03FC FBFF FBCE 0001 2AF5 F800 002A EE00" /* ...*..*. */ - $"C200 F1FF E900 06FF 2BFC FCF5 2BFF FD00" /* ...++. */ - $"06FF 2BFC FCF5 2BFF FD00 02FF 2BFC 05FC" /* .++..+. */ - $"F52B FF00 FAFA 00FE FD00 8CFE F5FB 000C" /* +..... */ - $"F9FF FCFF FFAC FDFF 2B56 FFFF F9EE 0003" /* +V.. */ - $"F5AC FFFF E300 08F9 FFFC FFFF ACFD FF2B" /* ..+ */ - $"FB00 032B FEFF FCDF 00FF 0008 FBFF FF2B" /* ..+...+ */ - $"00F5 FFFF F5E3 0004 81FF 00FB 81ED 0003" /* ...... */ - $"F9AC FCAC FD00 03FC FFFF 56F0 0005 547E" /* ..V..T~ */ - $"547E 7E2A FC00 0454 7E54 A854 F000 C200" /* T~~*..T~TT.. */ - $"F1FF E900 06FF 2BFC 2AF5 2BFF FD00 06FF" /* ..+*+.. */ - $"2BFC 2AF5 2BFF FD00 02FF 2BFC 052A F52B" /* +*+..+.*+ */ - $"FFFA FAFA 00FE FD00 9CFE F5FB 000C FB56" /* ....V */ - $"00FF FF2B 00FF 2B00 FCFF F9ED 0002 2BFF" /* .+.+...+ */ - $"FFEB 0000 FAFA 0008 FB56 00FF FF2B 00FF" /* ....V.+. */ - $"2BFA 0002 F9FF FCEC 0000 FAF5 00FE 00FF" /* +...... */ - $"FF05 2B00 F5FF FFF5 EC00 00F9 F900 FFFF" /* .+.... */ - $"0100 F6EB 0009 FAFF FFF5 0000 F5FF FFF9" /* ..... */ - $"F000 0754 A8F5 0000 7EA8 2AFE 0005 547E" /* ..T..~*..T~ */ - $"0000 2A54 F000 C600 FDFF FD48 F900 FD48" /* ..*T..H.H */ - $"FDFF ED00 06FF 2BFC 2AF5 2BFF FDFA 06FF" /* ..+*+. */ - $"2BFC 2AF5 2BFF FDFA 02FF 2BFC 032A F52B" /* +*+.+.*+ */ - $"FFF8 00FE FD00 9BFE F5FB 000C FC00 00FF" /* ...... */ - $"FF2B 0081 F500 FCFF F9ED 0002 2BFF FFEC" /* +....+ */ - $"0001 F8FF FA00 08FC 0000 FFFF 2B00 81F5" /* ......+. */ - $"FA00 02F9 FFFC ED00 01F8 FFF5 00FE 00FF" /* ...... */ - $"FF04 2B00 002B F7EC 0001 81FC FA00 02F5" /* .+..+.... */ - $"FFFF E900 09F9 FFFF 5600 0056 FFFF F9F1" /* .V..V */ - $"0002 2AA8 54FD 00FF A8FE 00FF 7EFE 0000" /* ..*T..~.. */ - $"54F0 00C6 00FD FFFD 48F9 00FD 48FD FFED" /* T..H.H */ - $"0001 FF2B FEF5 012B FFFD 0001 FF2B FEF5" /* ..+.+..+ */ - $"012B FFFD 0002 FF2B F5FF F501 2BFF F800" /* .+..+.+. */ - $"FEFD 0105 FEF5 F800 FFFF 002B FD00 05FC" /* ....+.. */ - $"FFF9 56FC 56FC 0003 2B81 FC56 F900 062B" /* VV..+V..+ */ - $"FFFF F8FB FBF6 FD00 10F8 FBFB F700 002B" /* ....+ */ - $"FBFC 5600 00FA FFFF F92B F900 FFFF 002B" /* V..+..+ */ - $"FD00 08F8 FBFB F700 00F9 FFFC FE00 0456" /* ......V */ - $"F9F8 FCFA FC00 0AF5 FAFC FA00 00FA FFFF" /* ... */ - $"F92B FA00 0256 FCFB 05F8 0000 FFFF 2BFE" /* +..V...+ */ - $"0001 F7F6 FE00 032B 81FC 56FE 0005 2BFB" /* ....+V..+ */ - $"2BFB 81F6 FE00 04FC FFFD F9F5 FC00 0BFB" /* +.... */ - $"FFFF F92B 0000 2B81 FCFA F5FE 0004 F5AC" /* +..+.. */ - $"F7FB F8FA 000F F9FB FFFB 0000 FCFF FFF9" /* .... */ - $"0000 56FC 81F5 FE00 09F6 81FC FAF5 0000" /* ..V... */ - $"7EA8 54FD 0007 7EA8 5400 00A8 A854 ED00" /* ~T..~T..T. */ + $"EB00 DBFA F0FF FFFA FCFA F900 FEFD 008B" /* ... */ + $"FEF5 F000 04F6 F7F8 F82B F100 06F8 FBFE" /* ..+.. */ + $"FEAC FA2B F700 05F5 FAFE FDFA F6FA 0004" /* +.... */ + $"2BAC FFFC 56F7 0006 F8FB FEFE ACFA 2BDE" /* +V..+ */ + $"00F9 0006 F7FB FDFE ACFA 2BD4 0006 F5F9" /* ...+.. */ + $"ACFF FDFB 56F6 0004 F581 FDFA F6E0 0001" /* V.... */ + $"F540 F9D9 0132 00ED 0001 FF2B FEF5 012B" /* @.2...+.+ */ + $"FFFD 0001 FF2B FEF5 012B FFFD 0001 FF2B" /* ..+.+..+ */ + $"FEF5 012B FFEB 0000 FADC 0000 FFF2 F902" /* .+..... */ + $"FF00 00FC 0000 FAFA 00FE FD00 5BFE F5D9" /* ......[ */ + $"00FF F5F2 0000 F5F5 0000 F5F3 00FF F5DB" /* ...... */ + $"00F6 0000 F5CE 00FF F5CE 0000 39FA D903" /* ......9. */ + $"4007 0000 ED00 06FF E32B FCFC 2BFF FD00" /* @.....++. */ + $"06FF E32B FCFC 2BFF FD00 06FF E32B FCFC" /* .++..+ */ + $"2BFF EB00 00FA DC00 00FF F2F9 02FF 0000" /* +....... */ + $"FC00 00FA FA00 FEFD 0039 FEF5 8400 8E00" /* ....9.. */ + $"0039 FAD9 0140 F5FE 00ED 0000 FFFC 2B00" /* .9.@...+. */ + $"FFFD 0000 FFFC 2B00 FFFD 0000 FFFC 2B00" /* ..+...+. */ + $"FFEB 0000 FADC 00F0 FFFF 00FC 0000 FAFA" /* ...... */ + $"00FE FD00 2DFE F584 00E6 0001 2BF5 AC00" /* ..-...+. */ + $"0032 FAD9 0039 FC00 EC00 FCFF FB00 FCFF" /* .2.9... */ + $"FB00 FCFF EA00 00FA C900 FC00 00FA FA00" /* ....... */ + $"FEFD 007B FEF5 FB00 0BF7 2B00 F5F5 F6F8" /* .{..+. */ + $"F62B FDAC F5F0 0003 2BFB FFF5 E700 01F6" /* +..+.. */ + $"F7FD F5FF F7FB 0003 2BFC FEF6 E100 0656" /* ..+..V */ + $"FFFA 0000 F7F8 FE00 E800 04F7 ACFF FFF6" /* ..... */ + $"EF00 00F5 FA00 00F5 EF00 FF2A F900 012A" /* .....*..* */ + $"F5E7 0000 32FA D900 32FB 00BA 0000 FAE2" /* ..2.2... */ + $"0000 F9FC FF00 F9FD 0000 F9FC FF00 F9FD" /* ...... */ + $"0002 F9FF FFFE FF02 F900 FAFA 00FE FD00" /* ...... */ + $"8FFE F5FC 000C F6FF FEFF FFFE FFFF F6FC" /* .. */ + $"FFFE F5F0 0003 FAFF FFF5 E700 0781 FFFD" /* .... */ + $"FFFF ACFF 81FB 0003 81FF FFF6 E200 07F6" /* .... */ + $"FFFF 8100 00FF FFFE 00E9 0005 F5FF FCF7" /* ..... */ + $"ACF6 F000 03F7 FDFF FEFE 0003 56FF FFFA" /* ....V */ + $"F200 0554 7E54 7EA8 54FD 0004 547E 54A8" /* ..T~T~T..T~T */ + $"54E9 0000 07FB D901 4007 FA00 BA00 00FA" /* T....@.... */ + $"E200 00FF FC2B 00FF FD00 00FF FC2B 00FF" /* ..+...+. */ + $"FD00 02FF 2B2B FE2B 02FF 00FA FA00 FEFD" /* ..+++... */ + $"009F FEF5 FC00 0C56 FC00 FDFF F7F5 FF00" /* ...V.. */ + $"F7FF FEF5 F000 03F5 FFFF F5EF 0001 F6FB" /* .... */ + $"FB00 07AC F72B FFFD 00AC 81FB 0003 2BFF" /* ..+...+ */ + $"FFF6 EF00 01FB F5F5 0006 FAFF 8100 00FF" /* ...... */ + $"FEFE 00F1 0001 F856 FB00 022B FFFC EC00" /* ...V..+. */ + $"08F9 FFFF F600 0081 FFFD F200 0F2A D254" /* .....*T */ + $"0000 7ED2 5400 002A A82A 002A 54EA 0000" /* ..~T..**.*T.. */ + $"07FB D901 40F5 F900 C200 F1FF E900 06FF" /* ..@.... */ + $"2BFC FCF5 2BFF FD00 06FF 2BFC FCF5 2BFF" /* ++..++ */ + $"FD00 02FF 2BFC 05FC F52B FF00 FAFA 00FE" /* ..+.+.. */ + $"FD00 EBFE F5FC 000E F7F8 00FD FFF8 00F8" /* ..... */ + $"00F7 FFFE 2B2B F5FC 0002 F656 F6FA 0005" /* .++..V.. */ + $"F5FF FF2B F7F6 FC00 FFF8 FE00 08F6 562B" /* +...V+ */ + $"0000 2BFD FFF5 FC00 17F9 002B FFFD 00F7" /* ..+...+. */ + $"F600 00F8 F700 002B FFFF F600 00F5 F5F6" /* ....+.. */ + $"F7FB 0007 F7F8 F500 F581 FFF7 FA00 07F5" /* ..... */ + $"F8F7 0000 FAFF 81FE 0000 F6FE 0003 00F6" /* ....... */ + $"56F6 FE00 03F5 F6F6 F7FD 0002 F9FF FBFB" /* V.... */ + $"0002 F9FF FDFD 0002 2B56 F6FD 0002 2BF5" /* ....+V..+ */ + $"F6FA 000D 56FF FFF9 00F6 FFFF FD00 00F5" /* ..V... */ + $"F8F6 FD00 02F6 56F6 FE00 FFA8 00F5 FE00" /* ..V... */ + $"09D2 A800 0054 D22A 0000 2AEB 0000 07FB" /* Ҩ..T*..*... */ + $"D900 39F7 00C2 00F1 FFE9 0006 FF2B FC2A" /* .9....+* */ + $"F52B FFFD 0006 FF2B FC2A F52B FFFD 0002" /* +..+*+.. */ + $"FF2B FC05 2AF5 2BFF FAFA FA00 FEFD 00FC" /* +.*+.. */ + $"FEF5 F900 02FD FFF8 FE00 06F7 FFFF 81FF" /* .... */ + $"FF2B FE00 0456 FCFA FC56 FB00 19F5 FFFF" /* +..VV.. */ + $"81FD FF56 0000 F6FC 8181 FB00 F7FC FAFD" /* V... */ + $"F800 FCFF FFFA F5FB 0002 F7FF FDFE 0010" /* ..... */ + $"2BAC FAFB 8100 2BFF FFF6 00F9 FEFC ACFF" /* +.+. */ + $"81FD 0000 81FE FB05 F5F9 FFFF FC2B FC00" /* ...+. */ + $"0FF8 FDFC FDFB 00FA FF81 0000 F7FB F600" /* ..... */ + $"000E F9FC FAAC F800 F9FD ACAC FFAC F500" /* .... */ + $"F6FE FF00 F8FD 0000 F5FE FF0E F900 0081" /* ...... */ + $"FC81 FE56 00F6 FAFF FDFF FCFB 0019 56FB" /* V...V */ + $"FFFE 00F7 FFFF FD00 56FD FCFF F800 00F9" /* ..V.. */ + $"FD81 FE56 002A D2A8 FD00 077E D254 0054" /* V.*Ҩ..~T.T */ + $"D2A8 54EA 0000 07FB D900 32F6 00C6 00FD" /* ҨT....2.. */ + $"FFFD 48F9 00FD 48FD FFED 0006 FF2B FC2A" /* H.H..+* */ + $"F52B FFFD FA06 FF2B FC2A F52B FFFD FA02" /* +.+*+. */ + $"FF2B FC03 2AF5 2BFF F800 FEFD 00FD FEF5" /* +.*+.. */ + $"F900 02FD FFF8 FE00 0FF7 FFFF 56FC FFFB" /* ....V */ + $"0000 F7FF 8100 FDFF F5FC 0018 F5FF FFF7" /* ..... */ + $"F7FF FFF6 00FC FFF5 00FF FCFE AC00 F956" /* ...V */ + $"00F9 FFFF F6FA 0002 F7FF FDFE 001D FEFF" /* ..... */ + $"002B FF56 F6FF FFF6 F5FF FFAC F8FF FFF8" /* .+V */ + $"0000 81FF F52B FFFB 2BFF FFF8 FC00 10F5" /* ..++.. */ + $"FFFF 0056 FF00 F9FF 8100 56FF FFF6 00F8" /* .V..V. */ + $"11FF F900 FEFF F6FD FFFD 2BFE FFF8 00F5" /* ..+. */ + $"FDFF FBFB 0011 81FF FDF5 00FA FFF7 00FD" /* .... */ + $"FF2B 00FF FFFE FFFF FB00 19F9 F7FF FFF5" /* +... */ + $"F8FE FFFD 56FF FB2B FFFD 0056 FFFA 00FE" /* V+.V. */ + $"FE00 54D2 7EFD 0008 7ED2 7E00 2AA8 D2D2" /* .T~..~~.* */ + $"7EEC 0000 07FC D901 4007 F500 C600 FDFF" /* ~....@... */ + $"FD48 F900 FD48 FDFF ED00 01FF 2BFE F501" /* H.H..+. */ + $"2BFF FD00 01FF 2BFE F501 2BFF FD00 02FF" /* +..+.+.. */ + $"2BF5 FFF5 012B FFF8 00FE FD01 07FE F5F9" /* +.+... */ + $"0002 FDFF F8FE 000F F7FF FEF5 56FF FD00" /* ....V. */ + $"0081 FFFD 81FE FFF6 FC00 0CF5 FFFF 0000" /* ..... */ + $"81FF FAF5 FFFF FBFB FDFF 06AC 2B00 002B" /* .+..+ */ + $"FFFF F900 23F7 FFFD 0000 F8FF FF81 FCFF" /* .#.. */ + $"FAF5 FFFF F600 FBFF 8100 FCFF 5600 00FF" /* ..V.. */ + $"FF81 FCFF FCF6 FFFF F5FC 0010 FAFF F900" /* ... */ + $"F556 00FA FF81 002B FFFF F500 FB11 FFAC" /* V..+.. */ + $"81FF FFF5 F9FF FC00 ACFF F900 00FC FFF9" /* ... */ + $"FB00 1156 FFAC 0000 FFFF F500 F7FF FC00" /* ..V.... */ + $"FCFF F9F8 F7FB 0019 FBF6 FFFF 8156 56FF" /* ..VV */ + $"FD56 FA00 F6FF FE00 ACFF 2B00 F6F7 0054" /* V..+..T */ + $"D27E FD00 057E D27E 0000 2AFE D200 7EEE" /* ~..~~..*.~ */ + $"0001 F540 FDD9 0140 F5F4 00CA 00FD FFFF" /* ..@.@.. */ + $"E4FD 48FF 49FF A6FF 48FB 00FD 48FF E4FD" /* HIH.H */ + $"FFF1 0006 FFE3 2BFC FC2B FFFD 0006 FFE3" /* ..++.. */ + $"2BFC FC2B FFFD 0002 FFE3 2BFF FC01 2BFF" /* ++..+.+ */ + $"F800 FEFD 00FE FEF5 F900 02FD FFF8 FE00" /* ..... */ + $"0EF7 FFFE F556 FFFD 0000 FDFF FA2B 2BF6" /* .V..++ */ + $"FB00 0FF5 FFFF F500 F9FF 81F8 FFFE F82B" /* ...+ */ + $"F6F6 FCFE FF04 F800 F7FF FFF9 0023 F7FF" /* ...# */ + $"FD00 0081 FFAC F72B F600 2BFF FFF6 0081" /* ..+.+. */ + $"FF81 00FC FF56 00F6 FFFF 2BF7 2BF5 F5FF" /* .V.++ */ + $"FFF5 FC00 02AC FF56 FD00 09FA FF81 0000" /* ..V... */ + $"FFFF F5F5 FE11 FFF9 2B2B F600 F9FF FC00" /* .++.. */ + $"ACFF 5600 00FC FFF9 FB00 0F56 FFAC 00F7" /* V....V. */ + $"FFFF F500 2BFF FD00 FCFF F9F9 0012 FCF6" /* .+... */ + $"FAFF FFF9 F7FF FD00 00F7 FCFF FD2B FFFF" /* ..+ */ + $"F6FD 0002 54D2 7EFD 0002 7ED2 7EFE 0004" /* ..T~..~~.. */ + $"F5A8 D2D2 F5F0 0001 F540 FDD9 0039 F200" /* ..@.9. */ $"CA00 FDFF FFE4 FD48 FF49 FFA6 FF48 FB00" /* .HIH. */ - $"FD48 FFE4 FDFF F100 06FF E32B FCFC 2BFF" /* H..++ */ - $"FD00 06FF E32B FCFC 2BFF FD00 02FF E32B" /* ..++..+ */ - $"FFFC 012B FFF8 00FE FD01 0AFE F5F8 00FF" /* .+... */ - $"FF00 2BFD 0006 FCFF FDF9 FEFF 56FE 0005" /* .+..V.. */ - $"F8FF F700 FD81 FA00 1B2B FFFF 5656 FFFE" /* ...+VV */ - $"F600 0081 FEF5 F6FF F82B FFF6 F5FE 2B00" /* ..++. */ - $"81FF FFF9 2BF9 00FF FF00 2BFE 0012 81FE" /* +..+.. */ - $"F5F6 FFF8 00F9 FFFC 002B ACFF ACFA ACFF" /* ..+ */ - $"FBFE 000B F6FE FA00 FBAC 0081 FFFF F92B" /* ....+ */ - $"FB00 03AC FEF6 F922 FF2B 00FF FF2B 00F5" /* .."+.+. */ - $"81FF 2B00 00F8 FFF7 00FD 81F5 FBFF ACFB" /* +... */ - $"FBFF FE00 00F5 FCFF FDF9 F5FC 0013 81FF" /* .... */ - $"FFF9 2B00 F8FF 5600 ACFE F600 81FF FFAC" /* +.V.. */ - $"FFFE FA00 1CF9 F8FF FF00 F5FB FFFF F900" /* .... */ - $"FDFD F5FF FE00 00F8 FF81 00FE FC00 00A8" /* ..... */ - $"A82A FD00 0954 A87E 0000 7EA8 A87E 2AEF" /* *.T~..~~* */ - $"00CA 00FD FFFF E4FD 48FF 49FF A6FF 48FB" /* ..HIH */ - $"00FD 48FF E4FD FFF1 0000 FFFC 2B00 FFFD" /* .H..+. */ - $"0000 FFFC 2B00 FFFD 0002 FF2B 2BFE 2B00" /* ..+...+++. */ - $"FFF8 00FE FD00 FCFE F5F8 00FF FF00 2BFD" /* ....+ */ - $"0006 FCFF FA00 FAFF FBFE 0006 FEFD 0000" /* ....... */ - $"ACFF F5FB 0019 2BFF FF00 0081 FF81 002B" /* ..+...+ */ - $"FF81 00F5 FFFD FBFF F700 2BF5 002B FFFF" /* ..+.+ */ - $"F700 FFFF 162B 0000 2BFF 8100 F5FF FD00" /* ..+..+.. */ - $"F9FF FC00 0081 FFFC 00F7 FFFF FE00 09FC" /* .... */ - $"FFF5 0081 FFF8 2BFF FFFA 0004 F9FF FA00" /* .+... */ - $"0020 FE2B 00FF FF2B 0081 FFFF 2B00 00FE" /* . +.+.+.. */ - $"FD00 00AC FFF5 56FF FF00 00FF FF2B 0000" /* ..V..+.. */ - $"F9FF FCFA 0002 2BFF FFFE 00FF FEFF 0009" /* ..+.. */ - $"F8FF FC00 F5FF FF56 FEAC FA00 1C81 00FF" /* .V... */ - $"FFF7 F8F8 FDFF F9FA FFF7 00FF FF2B 00FE" /* .+. */ - $"FF00 00F9 FC00 2AA8 A82A FD00 0554 A8A8" /* ...**..T */ - $"0000 2AFD A800 2AF0 00CC 00FF FFF9 E4FB" /* ..*.*.. */ - $"71FF 48FF 6CFF 48FB 00FF A2FF E4FF 71FF" /* qHlH.q */ - $"FFF2 00FC FFFB 00FC FFFB 00FF FFFE FFF7" /* ... */ - $"00FE FD00 EAFE F5F8 00FF FF00 2BFD 000B" /* ....+.. */ - $"FCFF F900 F9FF FC00 00F7 FFFE FDFC 00F5" /* .... */ - $"FB00 0B2B FFFF 0000 F7FF FE00 FAFF FDFE" /* ..+... */ - $"FCFF FBFF FF06 FC2B 0000 2BFF FFF7 00FF" /* .+..+. */ - $"FF05 2B00 00FA FFFD FEFC 0DFB 00F9 FFFC" /* .+.... */ - $"0000 F9FF FC00 2BFF FFFE 00FF FFFD FC03" /* ...+.. */ - $"F72B FFFF FA00 04AC FF2B 0000 0EF6 0000" /* +..+..... */ - $"FFFF 2B00 00FF FF2B 00F7 FFFE FDFC 0DF5" /* +..+.. */ - $"2BFF FF00 00FF FF2B 0000 F9FF FCFA 0007" /* +..+.... */ - $"2BFF FF00 00F7 FFFC FE00 FFFF FF00 FFFF" /* +.... */ - $"012B F5F9 0013 FC00 FCFF FAFB 00FC FFF9" /* .+.... */ - $"F62B 0000 FFFF 2BF7 FFFC FE00 05F5 002A" /* +..+...* */ - $"A8A8 2AFD 0002 54A8 A8FE 0000 2AFD A8F0" /* *..T..* */ - $"00CC 00FF FFF9 E4FB 71FF 48FF 6CFF 48FB" /* ..qHlH */ - $"00FF A2FF E4FF 71FF FFDA 00F4 00FE FD00" /* .q... */ - $"E3FE F5F8 00FF FF00 2BFD 000B FCFF F900" /* ..+... */ - $"F9FF FC00 00F9 FFFC F600 0B2B FFFF 0000" /* ....+.. */ - $"2BFF FF00 FCFF F9FD 0000 F7FD FF04 2B00" /* +....+. */ - $"2BFF FFF7 00FF FF05 2B00 00FC FFF9 FC00" /* +..+... */ - $"10F9 FFFC 0000 F9FF FC00 2BFF FF00 002B" /* ....+..+ */ - $"FFFF FC00 022B FFFF FA00 FFFF 022B 0000" /* ..+..+.. */ - $"FE00 FFFF 092B 0000 FFFF 2B00 F9FF FCFC" /* .+..+. */ - $"000C 2BFF FF00 00FF FF2B 0000 F9FF FCFA" /* ..+..+.. */ - $"0007 2BFF FF00 00F9 FFFC FE00 FFFF 042B" /* ..+....+ */ - $"00FF FF2B F800 13FC 0056 FFFD FC00 FCFF" /* .+...V. */ - $"F900 0056 FBFF FF2B F9FF FCFB 00FF A800" /* ..V+.. */ - $"2AFD 0002 54A8 7EFC 0003 7EA8 A82A F100" /* *..T~..~*. */ - $"CE00 FFFF FF9B FF7D FFE4 F74C FD71 FF6C" /* .}Lql */ - $"FF00 FF48 FF00 FDA2 FFCC FFE4 FFFF DC00" /* .H.. */ - $"F400 FEFD 00E5 FEF5 F800 FFFF 002B FD00" /* ....+. */ - $"0BFC FFF9 00F9 FFFC 0000 56FF FCF6 000B" /* ....V.. */ - $"2BFF FF00 002B FFFD 00FB FFF9 FC00 08F6" /* +..+... */ - $"FCFF FF81 002B FFFF F700 FFFF 052B 0000" /* .+..+.. */ - $"FBFF F9FC 0010 F9FF FC00 00F9 FFFC 002B" /* .....+ */ - $"FFFF 0000 F6FF FFFC 0002 2BFF FFFA 0004" /* ....+.. */ - $"FEFF F700 00FE 00FF FF09 2B00 00FF FF2B" /* ...+..+ */ - $"0056 FFFC FC00 0C2B FFFF 0000 FFFF 2B00" /* .V..+..+. */ - $"00F9 FFFC FA00 072B FFFF 0000 56FF FCFE" /* ...+..V */ - $"00FF FF04 F600 FFFF 2BF8 0013 FC00 F6FF" /* ...+... */ - $"FF56 00FC FFF9 00AC FB00 FFFF 2B56 FFAC" /* V...+V */ - $"FB00 027E A854 FD00 057E A854 0000 2AFE" /* ..~T..~T..* */ - $"0002 7EA8 2AF1 00CE 00FF FFFF 9BFF 7DFF" /* ..~*..} */ - $"E4F7 4CFD 71FF 6CFF 00FF 48FF 00FD A2FF" /* Lql.H. */ - $"CCFF E4FF FFDC 00F4 00FE FD00 E5FE F5F8" /* ... */ - $"00FF FF00 2BFD 000C FCFF F900 F9FF FC00" /* ..+.... */ - $"00F6 FFFF F5F7 000B 2BFF FF00 0056 FF81" /* ...+..V */ - $"0056 FFFD FD00 09F9 0000 F8FF FB00 2BFF" /* .V....+ */ - $"FFF7 00FF FF05 2B00 0056 FFFD FC00 0BF9" /* ..+..V.. */ - $"FFFC 0000 F9FF FC00 2BFF FFFE 0002 FEFF" /* ...+.. */ - $"F8FD 0002 2BFF FFFA 0004 FBFF FB00 00FE" /* ..+.... */ - $"00FF FF0A 2B00 00FF FF2B 00F6 FFFF F5FD" /* .+..+. */ - $"000C 2BFF FF00 00FF FF2B 0000 F9FF FCFA" /* ..+..+.. */ - $"0007 2BFF FF00 00F6 FFFE FE00 06FF FE00" /* ..+..... */ - $"00FF FF2B F800 14FC 0000 FDFF F500 FCFF" /* .+..... */ - $"F9F9 FF2B 00FF FF2B F6FF FFF6 FC00 022A" /* +.+..* */ - $"A87E FD00 017E A8FE 0000 54FE 0001 54A8" /* ~..~..T..T */ - $"F000 D000 FFFF FFA7 FF7D F14C FD71 FD9C" /* ..}Lq */ + $"FD48 FFE4 FDFF F100 00FF FC2B 00FF FD00" /* H..+.. */ + $"00FF FC2B 00FF FD00 02FF 2B2B FE2B 00FF" /* .+...+++. */ + $"F800 FEFD 00EC FEF5 F900 02FD FFF8 FE00" /* ..... */ + $"0BF7 FFFE F556 FFFD 0000 FDFF F8F8 000A" /* .V... */ + $"F5FF FFF5 00F9 FFFA F8FF ACFC 0007 FAFF" /* ... */ + $"FFFD 002B FFFF F900 07F7 FFFD 0000 FAFF" /* .+.... */ + $"81FD 000F 2BFF FFF6 0081 FF81 00FC FF56" /* ..+..V */ + $"00F6 FFFF FD00 03F5 FFFF F5FC 0002 ACFF" /* ..... */ + $"F9FD 0009 FAFF 8100 00FF FFF5 00FE 01FF" /* ..... */ + $"F7FD 000B F9FF FC00 ACFF 5600 00FC FFF9" /* ...V.. */ + $"FB00 0F56 FFAC 002B FFFF F500 2BFF FD00" /* ..V.+.+. */ + $"FCFF F9F9 0012 FBF6 2BFF FF2B F7FF FD00" /* ..++. */ + $"FBFC F8FF FD2B FFFF 2BFD 0002 2AD2 A8FD" /* ++..*Ҩ */ + $"0004 A8D2 2A00 F5FE 0002 A8D2 2AF1 0001" /* ..*...*.. */ + $"F540 FDD9 0032 F100 CC00 FFFF F9E4 FB71" /* @.2..q */ + $"FF48 FF6C FF48 FB00 FFA2 FFE4 FF71 FFFF" /* HlH.q */ + $"F200 FCFF FB00 FCFF FB00 FFFF FEFF F700" /* .... */ + $"FEFD 00E2 FEF5 F900 02FD FFF8 FE00 0BF7" /* ..... */ + $"FFFE 0056 FFFD 0000 FAFF 81F8 0017 F5FF" /* .V.... */ + $"FF00 00FC FFF7 F5FF FF2B 0000 F756 00F5" /* ..+..V. */ + $"FFFF F52B FFFF F900 07F7 FFFD 0000 F7FF" /* +.... */ + $"FFFD 0010 2BFF FFF6 0081 FF81 00FC FF56" /* ..+..V */ + $"0000 FFFF F7FE 0003 F5FF FFF5 FC00 02F9" /* ...... */ + $"FFFE FD00 09FA FFFA 0000 FFFF F500 FB01" /* ..... */ + $"FFFA FD00 0B56 FFFC 00AC FF56 0000 FCFF" /* ..V.V.. */ + $"F9FB 000F 56FF AC00 00FF FFF5 002B FFFB" /* ..V...+ */ + $"00FC FF56 F900 12FC F600 FFFF 00F8 FFFD" /* .V.... */ + $"F9FF F82B FFFE 00AC FFF9 FC00 027E D22A" /* +...~* */ + $"FE00 FFA8 FF00 0554 2A00 007E A8F1 0001" /* ...T*..~.. */ + $"F540 FDD9 00F7 F000 CC00 FFFF F9E4 FB71" /* @...q */ + $"FF48 FF6C FF48 FB00 FFA2 FFE4 FF71 FFFF" /* HlH.q */ + $"DA00 F400 FEFD 00F6 FEF5 F900 FFFF 00F9" /* ..... */ + $"FE00 0FF9 FFFF 2BFA FFFF F500 2BFF FFFA" /* ..+.+ */ + $"2B81 F5FC 0019 F5FF FF2B F7FF FC00 00FB" /* +..+.. */ + $"FFFF F7F8 ACAC 2B00 FEFB 00F6 FFFF F9F6" /* +.. */ + $"FB00 24F9 FFFF F600 00FD FFFD 2BF9 F9F7" /* .$..+ */ + $"FFFF F800 FCFF FCF5 FDFF FA00 00FA FFFF" /* ... */ + $"F856 F9F5 FFFF 81F7 FC00 0FFE FFFB F7F8" /* V.. */ + $"F6FB FFFC 00F6 FFFF F800 F7FF FF10 F92B" /* ...+ */ + $"FAF5 81FF AC00 FDFF 8100 0081 FFFF F8FC" /* ... */ + $"000F 81FF FE00 00F9 FF81 F5FC FF2B 00FD" /* ....+. */ + $"FF81 FA00 28F5 FE56 00FB FB00 81FF FFFE" /* .(V.. */ + $"FFAC FBFF FFF7 F8FF FFF9 F7F9 0000 F5A8" /* .. */ + $"A82A 007E A8F5 0000 7E7E 00F5 7E54 F200" /* *.~..~~.~T. */ + $"01F5 40FE D901 4007 EF00 CE00 FFFF FF9B" /* .@.@... */ + $"FF7D FFE4 F74C FD71 FF6C FF00 FF48 FF00" /* }Lql.H. */ + $"FDA2 FFCC FFE4 FFFF DC00 F400 FEFD 00F7" /* ... */ + $"FEF5 FA00 15F9 FCFB FCF6 00F5 81FB FCF9" /* ... */ + $"81FB FC56 0000 F7FE FFFF F7FB 0006 F5F9" /* V.... */ + $"FBFB ACFC F5FE 000E FBFF FF81 F5FB FC81" /* .. */ + $"FAF5 0000 ACFF FAFB 0004 F5FC 81FC F9FE" /* .... */ + $"001D FCFF FFFA F5FA FCFB 81F8 FBFB 81FA" /* .. */ + $"FC81 FCF6 0000 FAFF FFFC F500 FAFF ACF5" /* ... */ + $"FC00 0FF6 ACFF FFF8 2BAC 81AC F781 FBFB" /* ..+ */ + $"8100 0012 F8FF FFFE 2B2B FCFB 8181 FB81" /* ...++ */ + $"FCF6 002B FFFE F7FD 0011 F6FC 81AC F900" /* .+... */ + $"00F9 FE81 ACF8 00F8 AC81 FC2B FB00 02F9" /* ..+.. */ + $"FCFC FEF5 102B FC81 FBFC FEFD F781 FF56" /* .+V */ + $"0056 FFFF AC2B FE00 05F5 7E7E 5454 F5FE" /* .V+..~~TT */ + $"0004 2A7E 547E 54F2 0001 F540 FED9 0140" /* ..*~T~T..@.@ */ + $"F5EE 00CE 00FF FFFF 9BFF 7DFF E4F7 4CFD" /* ..}L */ + $"71FF 6CFF 00FF 48FF 00FD A2FF CCFF E4FF" /* ql.H. */ + $"FFDC 00F4 00FE FD00 38FE F5DA 0000 F5AC" /* ...8.. */ + $"00E1 0000 F5BD 0001 F540 FED9 0139 F5ED" /* .....@.9 */ + $"00D0 00FF FFFF A7FF 7DF1 4CFD 71FD 9CFF" /* ..}Lq */ + $"78FD 9CFF A2FF C6FF A7FF FFDE 00F4 00FE" /* x.. */ + $"FD00 2FFE F584 009D 0001 F540 FED9 0039" /* ./...@.9 */ + $"EB00 D000 FFFF FFA7 FF7D F14C FD71 FD9C" /* ..}Lq */ $"FF78 FD9C FFA2 FFC6 FFA7 FFFF DE00 F400" /* x.. */ - $"FEFD 00F8 FEF5 F800 FFFF 002B FD00 06FC" /* ...+.. */ - $"FFF9 00F9 FFFC FE00 06AC FFAC F500 81F5" /* .... */ - $"FB00 1B2B FFFF 0000 FCFF F500 F5FE FF81" /* ..+... */ - $"00F5 FBFC 2B00 00FF F800 F6FF FFF8 F8F9" /* .+... */ - $"00FF FF16 2B00 00F5 FEFF 8100 F5FB 00F9" /* ..+.... */ - $"FFFC 0000 F9FF FC00 2BFF FFFE 000B FAFF" /* ...+.. */ - $"FE2B 0056 F8F6 FFFF F8F8 FC00 042B FFFF" /* +.V..+ */ - $"5600 222B F700 FFFF 2B00 00FF FF2B 0000" /* V."+.+..+.. */ - $"ACFF ACF5 0081 F52B FFFF 0000 FFFF 2B00" /* .+..+. */ - $"0056 FFFD F82B FC00 022B FFFF FE00 0BFC" /* .V+..+.. */ - $"FFF7 00F8 FFF9 0000 FFFF 2BF8 0017 FD00" /* ...+... */ - $"00FA AC00 00FD FF81 FCFF FAF9 FFFF F9F5" /* ... */ - $"FCFF ACF5 00F9 FE00 0754 A854 0000 54A8" /* ...TT..T */ - $"2AFE 0000 A8FE 0001 7E54 F000 D000 FFFF" /* *....~T.. */ - $"FFA7 FF7D F14C FD71 FD9C FF78 FD9C FFA2" /* }Lqx */ - $"FFC6 FFA7 FFFF DE00 F400 FEFD 0100 FEF5" /* .... */ - $"F900 0FAC FCFC ACF6 0000 FAAC FCAC 56AC" /* ....V */ - $"FCAC FAFE 0004 ACFF FFFE F7FA 0006 2BFB" /* ....+ */ - $"FCFB FBFE F7FE 000A F6FE FFFF ACF6 FAFE" /* . */ - $"F9FC FAFE 0003 FDFF FDF6 FA00 1AAC FCFC" /* .... */ - $"ACF6 0000 F6FE FFFF ACF6 F8AC FCAC 81F8" /* .. */ - $"ACFC ACF9 ACFC FCAC FE00 0081 FEFF 06F9" /* ... */ - $"0000 FDFF FDF6 FB00 03F8 FEFF FF17 8100" /* ...... */ - $"ACFC FCFD F6AC FCFC ACF6 0000 ACFF FFFE" /* .. */ - $"F7F6 ACFC FC81 FEFC 06AC F600 F5FF FFFC" /* .. */ - $"FC00 13F6 ACFC FCFD F600 00FC FEF9 FEFA" /* .... */ - $"0000 ACFC FCAC F6FA 0006 ACFC ACF5 F6F7" /* .... */ - $"00FE FCFF AC0C FFFE F8FA FFAC 0000 FCFF" /* .... */ - $"FFFD F7FD 0005 54A8 5454 7E2A FD00 FF7E" /* ..TTT~*.~ */ - $"0254 7E54 EF00 D200 FFFF FFA7 FF7D FF4B" /* .T~T..}K */ - $"F34C FFAC FD71 FFE4 FF9C FD6C FF78 FF9C" /* Lqlx */ - $"FFA2 FFA4 FFA7 FFFF E000 F400 FEFD 007F" /* .... */ - $"FEF5 E500 01F6 2BF8 0004 F600 00F5 2BFA" /* ..+....+ */ - $"0001 2BF6 FE00 01F5 2BFB 0000 2BEF 0001" /* ..+..+..+.. */ - $"2BF6 ED00 01F5 2BFC 0000 2BF7 0001 2BF5" /* +..+..+..+ */ - $"F200 01F6 2BF3 0001 F5F6 F200 01F6 2BE5" /* ..+....+ */ - $"0000 F6FE 0000 2BFD 0001 F62B F900 012A" /* ....+..+..* */ - $"F5F9 0000 2AED 00D2 00FF FFFF A7FF 7DFF" /* ..*..} */ - $"4BF3 4CFF ACFD 71FF E4FF 9CFD 6CFF 78FF" /* KLqlx */ - $"9CFF A2FF A4FF A7FF FFE0 00F4 00FE FD00" /* ... */ - $"30FE F584 0081 00D2 00FF FFFF A7FF 77FB" /* 0...w */ + $"FEFD 0037 FEF5 8400 9E00 0107 40FE D900" /* .7....@. */ + $"32EA 00D2 00FF FFFF A7FF 7DFF 4BF3 4CFF" /* 2..}KL */ + $"ACFD 71FF E4FF 9CFD 6CFF 78FF 9CFF A2FF" /* qlx */ + $"A4FF A7FF FFE0 00F4 00FE FD00 4DFE F5D1" /* ...M */ + $"0001 F681 E400 FF56 FF00 03F8 FCFB F6DB" /* ...V.. */ + $"00CD 0003 F581 FCF9 D700 0007 FDD9 0032" /* .......2 */ + $"E900 D200 FFFF FFA7 FF7D FF4B F34C FFAC" /* ..}KL */ + $"FD71 FFE4 FF9C FD6C FF78 FF9C FFA2 FFA4" /* qlx */ + $"FFA7 FFFF E000 F400 FEFD 0085 FEF5 FD00" /* .... */ + $"0BF6 FBFC FAFA FCFB FBFA F9FC F8FD 0002" /* ... */ + $"F6FE FAE9 0002 F7FE FFF4 0001 F681 FDFC" /* .... */ + $"0056 F900 10FB FFFA 00F7 FF56 FEF6 00F5" /* .V...V. */ + $"FAFC FBFA FBF8 E300 FA00 0356 FAFA FCE5" /* ...V */ + $"00FF FA01 FBFA F800 03FC 81FC FAD8 0000" /* ...... */ + $"07FD D900 07E8 00D2 00FF FFFF A7FF 77FB" /* .....w */ $"4CFD 04FD 4CFF ACFF 9CFF 4CFF E4FF 9CF9" /* L.LL */ $"6CFF 9CFF A2FF E4FF A7FF FFE0 00F4 00FE" /* l.. */ - $"FD00 30FE F584 0081 00D2 00FF FFFF A7FF" /* .0... */ + $"FD00 90FE F5FC 0009 56FF FAF5 FF81 FAF6" /* ..V */ + $"F781 FC00 05F6 FEFA 0000 FCFE 0000 FCEF" /* ...... */ + $"0001 FCFF F300 06F7 FFFA F5FB FF56 FA00" /* ....V. */ + $"11F7 FFFA 00FA FF00 2B00 00F5 F9FF FA00" /* ...+... */ + $"FAFF F7E4 00FB 0004 F7FF F500 FCE6 0004" /* ...... */ + $"FAAC 00F5 FBF9 0006 F5FF FAF6 F5F7 FADB" /* ... */ + $"0000 07FD D900 07E7 00D2 00FF FFFF A7FF" /* ....... */ $"77FB 4CFD 04FD 4CFF ACFF 9CFF 4CFF E4FF" /* wL.LL */ $"9CF9 6CFF 9CFF A2FF E4FF A7FF FFE0 00F4" /* l. */ - $"00FE FD00 34FE F584 0081 00D4 00FF FFFF" /* ..4... */ - $"7DFF A7FD 7DFB 4CFD 04FF 9CFD 4CFF E4FF" /* }}L.L */ - $"9CFF 00FD 48FD 6CFF 78FF A2FF CCFF C8FF" /* .Hlx */ - $"7DFF FFE2 00F4 00FE FD00 34FE F584 0081" /* }...4. */ - $"00D4 00FF FFFF 7DFF A7FD 7DFB 4CFD 04FF" /* ..}}L. */ - $"9CFD 4CFF E4FF 9CFF 00FD 48FD 6CFF 78FF" /* L.Hlx */ - $"A2FF CCFF C8FF 7DFF FFE2 00F4 00FE FD00" /* }... */ - $"4FFE F5EA 0000 F5E6 0002 F5F8 F9E1 0001" /* O...... */ - $"F781 FE00 03F8 81FC 2BE3 00BC 0003 F881" /* ..+... */ - $"FC2B CA00 D400 FFFF FF4D FFA7 FFF6 FF7D" /* +..M} */ - $"FB4C FB04 FF4C FFE4 FF9C FB00 FF48 FB6C" /* L.L.Hl */ - $"FF96 FFA2 FFE4 FF4D FFFF E200 F400 FEFD" /* M.. */ - $"0082 FEF5 FA00 0BFB FCFB F7FC FCF9 FCF8" /* ... */ - $"81FC F7FE 0002 FDFF F5E7 0002 FBFF FCF2" /* .... */ - $"0006 F7FC FC81 81FC 56F8 0011 56FF FF00" /* ..V..V. */ - $"00F8 FF00 FD2B 00F7 81FC FAFA 812B EB00" /* ..+.+. */ - $"EF00 0381 FAFC F9E0 0003 81FA FCF9 F800" /* ..... */ - $"04F8 FF00 FD2B CA00 D400 FFFF FF4D FFA7" /* ..+..M */ - $"FFF6 FF7D FB4C FB04 FF4C FFE4 FF9C FB00" /* }L.L. */ - $"FF48 FB6C FF96 FFA2 FFE4 FF4D FFFF E200" /* HlM. */ - $"F400 FEFD 008F FEF5 FA00 0A2B FFFD 0081" /* ...+. */ - $"FFF5 FD00 F881 FD00 01FB FDFE 0000 ACFE" /* ..... */ - $"0000 ACEE 0002 2BFF FCF1 0006 FCFF 2B00" /* ....+..+. */ - $"FCFF F9F8 00FF FFFF 0001 FCFF FC00 06AC" /* ..... */ - $"FF2B 00FB FF2B EC00 F000 04FB FA00 00FC" /* +.+..... */ - $"E100 04FB FA00 00FC F800 01FC FFFE 0000" /* ........ */ - $"ACCB 00D6 00FF FFFF CEFF CDFF C6FD A7FF" /* .. */ - $"7DFD 4CFF 70FD E4FF 4DFF 9CFD 48FF 00FD" /* }LpMH. */ - $"48FB 6CFF 96FF A2FF C6FF 4DFF A7FF FFE4" /* HlM */ - $"00F4 00FE FD01 04FE F5F9 001D ACFF F6F6" /* ...... */ - $"FFFD F800 FAF5 00FA F556 00F7 00F5 ACFF" /* ..V.. */ - $"2BF6 ACFF 2B00 00F7 F9F8 FD00 03F9 F6F9" /* ++.... */ - $"F8FC 0007 2BFF FCF7 F92B 0000 FE2B 03F5" /* ..++..+. */ - $"F62B 2BFD 0006 FCFF 2B00 F9FF FBFE 0002" /* ++..+... */ - $"F7F9 F8FE 00FF FF05 002B FFFF 2BF5 FE00" /* ...++. */ - $"06FC FF2B 00F9 FFF9 FE00 11FA F556 F5F8" /* .+...V */ - $"F92B 0000 F62B 2B00 2B2B F600 0004 00F9" /* +..++.++.... */ - $"F6F9 F8F5 0004 FFAC 0000 2BFE 0002 F8F9" /* ....+.. */ - $"2BFE 000B F556 F9F6 0000 F556 F9F6 0000" /* +..V..V.. */ - $"FE2B 03F5 F62B 2BFD 0009 FFAC 0000 2B00" /* +.++...+. */ - $"00F7 F9F8 FE00 082B FFFF 2B2B ACFF 2BF5" /* ...++++ */ - $"FB2B 08F6 F52B 2B00 00F8 F92B FE00 07FA" /* +.++..+.. */ - $"F556 0000 F7F9 F8E7 00D6 00FF FFFF CEFF" /* V.... */ - $"CDFF C6FD A7FF 7DFD 4CFF 70FD E4FF 4DFF" /* }LpM */ - $"9CFD 48FF 00FD 48FB 6CFF 96FF A2FF C6FF" /* H.Hl */ - $"4DFF A7FF FFE4 00F4 00FE FD01 05FE F5F9" /* M.... */ - $"0026 56FF FA00 FDFF 0000 FCF9 FEFF FEFF" /* .&V... */ - $"FDFF 00F8 FFFF F9F9 FFFF F9F6 ACFB 00FB" /* .. */ - $"FC00 F9FE FEF8 81FF F9FD 000E 2BFF FD2B" /* ...++ */ - $"81FF FA00 F9FF ACF5 F5FD F8FD 0017 FCFF" /* ... */ - $"2B00 ACFE 2B00 00AC FB00 FBFE F600 FFFF" /* +.+.... */ - $"00F6 FFFF 2BF5 FE00 1BFC FF2B F5AC FDF5" /* .+..+ */ - $"00F9 FEFF FEFF FFF9 F9FF F700 2BFF FF00" /* ..+. */ - $"F9FF FC00 F9FF FE03 F881 FFF9 F600 20FD" /* ... */ - $"FFFE F900 00F6 FEF9 F9FF F700 F5FE F5F6" /* ... */ - $"FB00 F5FE F5F6 FB00 00F9 FFAC F5F5 FDF8" /* ... */ - $"FD00 30FD FFFE F900 00AC FB00 FBFE F600" /* .0.... */ - $"F6FF FF2B 56FF FFF9 2BFA FFFB F7FF FFF7" /* +V+ */ - $"F5FD 56F6 FEF9 F9FF F7F9 FEFF FEFF 56AC" /* VV */ - $"FB00 FBFC E800 D600 FFFF FFCE FDCD FDCC" /* ... */ - $"FFA7 FF71 FF4D FDC6 FF78 FFE4 FF6C F748" /* qMxlH */ - $"FD6C FB96 FFC6 FF7D FFA7 FFFF E400 F400" /* l}.. */ - $"FEFD 0101 FEF5 F800 25FF FD00 FAFF F7F7" /* ...%. */ - $"5600 FFFF F681 FFFF 0000 FFFF 0000 FFFF" /* V..... */ - $"0056 FFF9 2BFB FFF6 00FF FF00 2BFF FCFD" /* .V+..+ */ - $"000D 2BFF FC00 00FE FF00 00FE FFF5 00FA" /* ..+..... */ - $"FC00 15FC FF81 FDFE F600 0056 FFF7 00F6" /* ....V. */ - $"FFFB 00FF FF00 00FF FFFC 0005 FCFF FB81" /* ..... */ - $"FFF9 FE00 FFFF 10F6 FB81 00F9 FFF9 0000" /* ..... */ - $"FFFF 002B FFFC 0000 FFFF 0300 2BFF FCF6" /* .+....+ */ - $"0017 F6FE FFFF 8100 5681 00F9 FFF9 00F9" /* ...V.. */ - $"FFFB F6F5 00F9 FFFB F6F5 FE00 04FE FFF5" /* ... */ - $"00FA FC00 13F6 FEFF FF81 56FF F700 F6FF" /* ...V. */ - $"FB00 00FF FF00 00FF FFFE 001A FEFD 0081" /* ....... */ - $"FFF8 00FB 0056 8100 F9FF F900 FFFF F681" /* ..V.. */ - $"FAFF F92B FBFF F6E9 00D6 00FF FFFF CEFD" /* +.. */ - $"CDFD CCFF A7FF 71FF 4DFD C6FF 78FF E4FF" /* qMx */ - $"6CF7 48FD 6CFB 96FF C6FF 7DFF A7FF FFE4" /* lHl} */ - $"00F4 00FE FD01 02FE F5F8 001A FBFF F7FB" /* ...... */ - $"FF81 8100 00FF FF00 00FF FF00 00FF FF00" /* ....... */ - $"00FF FF00 FCFF 56FE 2BFF 00FF FF03 002B" /* ..V+...+ */ - $"FFFC FD00 0D2B FFFC 0000 FCFF 2B00 F9FF" /* ..+..+. */ - $"F9F8 2BFC 0015 FCFF 2B81 FFFB 0000 FCFF" /* +..+.. */ - $"2B00 00FF FF00 FFFF 0000 FFFF FC00 0AFC" /* +...... */ - $"FF2B 00F9 FFF9 0000 FFFF FE00 0DF9 ACFF" /* +..... */ - $"F900 00FF FF00 2BFF FC00 00FF FF03 002B" /* ...+....+ */ - $"FFFC FD00 03F8 FFFF 81FD 000C F581 FFFF" /* .... */ - $"F500 00F9 ACFF F900 F6FE FF02 8100 F6FE" /* ..... */ - $"FF00 81FE 0004 F9FF F9F8 2BFB 0012 F581" /* ...+.. */ - $"FFFF FDFF 2B00 00FF FF00 00FF FF00 00FF" /* +...... */ - $"FFFE 0007 81FF F681 FFFB F7F8 FE00 0BF9" /* .... */ - $"ACFF F900 FFFF 0000 FCFF 56FE 2BE8 00D6" /* ...V+. */ - $"00FF FFFD CEFD CDFD CCFF E4FF 71FF C6FB" /* .q */ - $"78FD 6CFB 48FB 6CFD 96FF A2FF C6FF E4FF" /* xlHl */ - $"4DFF FFE4 00F4 00FE FD00 FEFE F5F8 001A" /* M..... */ - $"F7FF ACFA ACFE FB00 00FF FF00 00FF FF00" /* ..... */ - $"00FF FF00 00FF FF00 FBFF F7FC 00FF FF03" /* ...... */ - $"002B FFFC FD00 0C2B FFFC 0000 FCFF F500" /* .+..+... */ - $"F5FF FDFA FB00 15FC FF2B F5FF FFF5 00FB" /* ..+. */ - $"FF2B 0000 FFFE 00FF FF00 00FF FFFC 001B" /* +....... */ - $"FCFF 2B00 2BFF FC00 00FF FF00 F6FE 2BF9" /* +.+...+ */ - $"FFF9 0000 FFFF 002B FFFC 0000 FFFF 0300" /* ...+.... */ - $"2BFF FCFD 0003 F9FC FCF7 FE00 1EF7 0000" /* +...... */ - $"F9FF 2BF6 FE2B F9FF F900 00F5 81FF FFF6" /* ++.. */ - $"00F5 81FF FFF6 0000 F5FF FDFA FB00 13F7" /* ..... */ - $"0000 F9FF FEFF 2B00 00FF FE00 00FF FF00" /* ..+..... */ - $"00FF FFFE 0016 F6FF FB56 FCFF 8100 00F6" /* ...V.. */ - $"FE2B F9FF F900 FFFF 0000 FBFF F7E5 00D6" /* +.... */ - $"00FF FFFD CEFD CDFD CCFF E4FF 71FF C6FB" /* .q */ - $"78FD 6CFB 48FB 6CFD 96FF A2FF C6FF E4FF" /* xlHl */ - $"4DFF FFE4 00F4 00FE FD00 F8FE F5F7 0024" /* M....$ */ - $"FEFF F556 FFF8 0000 FFFF 0000 FFFF 0000" /* V...... */ - $"FFFF 0000 FFFF 00F8 FFFC 0000 F600 00FF" /* ....... */ - $"FF00 2BFF FCFD 0006 2BFF FC00 00FE FCFE" /* .+..+.. */ - $"0002 81FF F8FB 0015 FCFF 2B00 81FF 8100" /* ....+.. */ - $"F8FF FA00 F5FF 8100 FFFF 0000 FFFF FC00" /* ..... */ - $"1BFC FF2B 00F7 FF81 0000 FFFF 00FB FF00" /* .+..... */ - $"81FF F900 00FE FF00 2BFF FC00 00FF FF03" /* ...+... */ - $"002B FFFC F600 1881 0000 2BFE 00FB FF00" /* .+....+.. */ - $"81FF F900 F9F5 00F7 FFF5 F9F5 00F7 FFF5" /* ... */ - $"FE00 0281 FFF8 FB00 1381 0000 2BFE F8FF" /* ......+ */ - $"FA00 F5FF 8100 00FF FF00 00FF FFFD 0018" /* ....... */ - $"ACFF 00F8 FF81 0000 FBFF 0081 FFF9 00FF" /* ..... */ - $"FF00 00F8 FFFC 0000 F6E8 00D6 00FF FFFD" /* ...... */ - $"CEFD CDFD CCFF A7FF E4FF 71FF 4DFD 78FD" /* qMx */ - $"71F7 6CFB 96FD A2FF C6FF 71FF FFE4 00F4" /* qlq. */ - $"00FE FD00 FCFE F5F7 0025 FA81 00F5 FE00" /* ...%.. */ - $"00F9 FFFF F9F9 FFFF FA00 FCFF ACF6 FCFF" /* .. */ - $"ACF6 FAFF FDFC FA00 F9FF FFF8 FBFF FEF7" /* . */ - $"FE00 052B FDFD 2B81 FCFD 0001 2BFE FB00" /* ..++..+. */ - $"17F7 FEFF FBF5 F6FF FF56 00FA FEF7 81FC" /* .V. */ - $"00F9 FFFF FAF9 FFFF FAFE 001C 2BFD FFF9" /* ...+ */ - $"F7AC FDF6 00F9 FFFF F9F9 FFFD 56FF FEF6" /* .V */ - $"00FA FFFB FAFD FD2B F9FF FF04 F8FB FFFE" /* .+. */ - $"F7F7 0017 FEF8 F7FC F600 F9FF FD56 FFFE" /* ...V */ - $"F656 AC2B 81F8 0056 AC2B 81F8 FD00 012B" /* V+.V+..+ */ - $"FEFA 0030 FEF8 F7FC F600 FAFE F781 FC00" /* .0.. */ - $"00F9 FFFF FA00 FCFF ACF6 0000 56FB 0000" /* ....V.. */ - $"FEF6 0000 F9FF FD56 FFFE FBFF FFF9 0000" /* ..V.. */ - $"FAFF FDFC FAE8 00D6 00FF FFFD CEFD CDFD" /* .. */ - $"CCFF A7FF E4FF 71FF 4DFD 78FD 71F7 6CFB" /* qMxql */ - $"96FD A2FF C6FF 71FF FFFD FAE8 00F4 00FE" /* q.. */ - $"FD00 A1FE F5F3 0000 F5F5 0000 2BFE 0000" /* .....+.. */ - $"2BFE 0001 F52B F000 012B F6FB 0000 81EF" /* +..+..+.. */ - $"0001 2BF5 F400 05F5 0000 2B2B F6F9 0003" /* ..+....++.. */ - $"2B00 00F6 FD00 FFF6 0100 F5FE 00EF 00FF" /* +....... */ - $"2BFD 0003 2B00 00F6 FE00 01F5 2BFD 0001" /* +..+....+.. */ - $"F52B FA00 0081 F900 FF2B FC00 012B F5F8" /* +...+..+ */ - $"0000 2BFC 0003 F500 00F6 FD00 032B 0000" /* ..+......+.. */ - $"F6F9 0001 F52B E600 D600 FFFF FDCE FDCD" /* ..+.. */ - $"FDCC FFC6 FFA6 FFE4 FF71 FFC6 F978 FD6C" /* qxl */ - $"F996 FBA2 FFCC FFE4 FFFF FE00 00FA E800" /* ... */ - $"F400 FEFD 003E FEF5 C500 0281 FDF6 C300" /* ..>... */ - $"D500 0281 FDF6 B000 D600 FFFF FDCE FDCD" /* .... */ - $"FDCC FFC6 FFA6 FFE4 FF71 FFC6 F978 FD6C" /* qxl */ - $"F996 FBA2 FFCC FFE4 FFFF FE00 00FA E800" /* ... */ - $"F400 FEFD 0038 FEF5 C500 FFAC C200 D500" /* ..8... */ - $"FFAC AF00 D600 FFFF FDCE FDCD FBCC FDC6" /* .. */ - $"FFA6 FF71 FFC6 FB9C FDA2 FB96 FBA2 FFC6" /* q */ - $"FDCC FFFF FE00 00FA E800 F400 FEFD 0030" /* .....0 */ - $"FEF5 8400 8100 D600 FFFF FDCE FDCD FBCC" /* ... */ - $"FDC6 FFA6 FF71 FFC6 FB9C FDA2 FB96 FBA2" /* q */ - $"FFC6 FDCC FFFF FE00 00FA E800 F400 FEFD" /* .... */ - $"0034 FEF5 8400 8100 D600 FFFF FDCE FBCD" /* .4... */ - $"FBCC FDC6 FFA6 FF71 FF4C FD04 FF71 FF7D" /* qL.q} */ - $"FFA2 FFC6 FBA2 FFC6 FBCC FFFF FE00 00FA" /* .. */ - $"E800 F400 FEFD 0047 FEF5 D600 00F5 F900" /* ...G... */ - $"01F7 81C1 0006 F781 0000 F881 FC00 2B82" /* ......+ */ - $"00D6 00FF FFFD CEFB CDFB CCFD C6FF A6FF" /* .. */ - $"71FF 4CFD 04FF 71FF 7DFF A2FF C6FB A2FF" /* qL.q} */ - $"C6FB CCFF FFFE 0000 FAE8 00F4 00FE FD00" /* ..... */ - $"85FE F5F8 0005 F7FC 81FA FCF7 E600 02FD" /* .... */ - $"FFF5 FB00 0256 FFFF F300 02F5 F9FD FD00" /* ..V... */ - $"04F7 FAFB FCF6 FE00 08F7 FAFB FCF6 0000" /* ..... */ - $"2BFF FDFC 00FB FD00 06F7 FCFC 8181 FC56" /* +...V */ - $"F800 0756 FFFF 00F8 FF00 FD09 2B00 00F7" /* ..V..+.. */ - $"81FC FAFA 812B 8B00 D600 FFFF FBCE FDCD" /* +.. */ - $"F9CC FDC6 FFA6 FF71 FF04 FD4C FF04 FF71" /* q.L.q */ - $"FF7D FFCC FDC6 FBCC FFEE FFFF FE00 00FA" /* }.. */ - $"E800 F400 FEFD 0086 FEF5 F900 06FA FFF8" /* ..... */ - $"0000 2BF9 E600 01FB FDF9 00FF FFFA 0000" /* ..+..... */ - $"ACFC 0003 FAF9 FFFF FE00 10F5 FE00 00FC" /* ...... */ - $"FEF5 00F5 FE00 00FC FEF5 002B FCFF 00FA" /* ....+. */ - $"FC00 06FC FF2B 00FC FFF9 F800 FFFF 0400" /* ..+.... */ - $"FCFF 0000 FD00 06AC FF2B 00FB FF2B 8C00" /* ....+.+. */ - $"D600 FFFF FBCE FDCD F9CC FDC6 FFA6 FF71" /* .q */ - $"FF04 FD4C FF04 FF71 FF7D FFCC FDC6 FBCC" /* .L.q} */ - $"FFEE FFFF FE00 00FA E800 F400 FEFD 00BB" /* ..... */ - $"FEF5 FA00 022B FFAC FD00 05F5 0000 F7F9" /* ..+.... */ - $"F8FD 0005 FA00 56F8 0000 FE2B 0FF5 F62B" /* ...V..+.+ */ - $"2B00 00FA F556 00F7 0000 F8F9 F7FE 00FF" /* +..V.... */ - $"FF08 F5F9 F800 00F5 ACFF 2BFB 00FF FFFE" /* ...+. */ - $"0010 56FF 0000 F8FF F900 56FF 0000 F8FF" /* ..V...V.. */ - $"F900 00FD 2B01 ACF5 FC00 0BFC FF2B 00F9" /* ..+...+. */ - $"FFFB 0000 F7F9 F8FD 00FF FF04 2BFF FF2B" /* ....++ */ - $"F5FD 0006 FCFF 2B00 F9FF F9FE 000F FAF5" /* ..+... */ - $"56F5 F8F9 2B00 00F6 2B2B 002B 2BF6 FE00" /* V+..++.++. */ - $"03F9 F6F9 F8A6 00D4 00FF FFFD CEFB CDF7" /* ... */ - $"CCFF E4FF 71F7 4CFF 71FF 7DFF A6F9 CCFF" /* qLq} */ - $"FFFC 0000 FAE8 00F4 00FE FD00 BBFE F5FA" /* ..... */ - $"0002 FAFF FAFB 002F ACFB 00FB FEF6 F9FD" /* .../. */ - $"FFF9 FCFF FA00 F9FF ACF5 F5FD F8F9 FEFF" /* . */ - $"FEFF FDFF 00FD FB00 ACFF 8100 FFFF 5681" /* ...V */ - $"FFF9 00F8 FFFF F9F6 FC00 FFFF FE00 0E56" /* ....V */ - $"FFF6 002B FFFC 0056 FFF6 002B FFFC FC00" /* .+.V.+. */ - $"01F5 81FB 0016 FCFF 2B00 ACFE 2B00 ACFB" /* ...+.+. */ - $"00FB FEF6 0000 FFFF F6FF FF2B F5FD 0021" /* ...+.! */ - $"FCFF 2BF5 ACFD F500 F9FE FFFE FFFF F9F9" /* +. */ - $"FFF7 002B FFFF 00F9 FFFC 00F9 FEFE F881" /* .+.. */ - $"FFF9 A700 D400 FFFF FDCE FBCD F7CC FFE4" /* .. */ - $"FF71 F74C FF71 FF7D FFA6 F9CC FFFF FC00" /* qLq}. */ - $"00FA E800 F400 FEFD 00BA FEF5 FA00 02FC" /* ...... */ - $"FFF9 FC00 2E56 FFF7 00F6 FFFB 00FF FF00" /* ..V... */ - $"00FE FF00 00FE FFF5 00FA 0000 FFFF F681" /* ...... */ - $"FFFF 56FF 2B00 F9FF F600 FFFF 002B FFFC" /* V+...+ */ - $"0000 FFFF FA00 FFFF FE00 0EF5 FEFB 002B" /* ......+ */ - $"FFFB 00F5 FEFB 002B FFFB FC00 0156 2BFB" /* ..+..V+ */ - $"0016 FCFF 81FD FEF6 0056 FFF7 00F6 FFFB" /* ...V. */ - $"0000 FFFF 00FF FF00 00FD 0005 FCFF FB81" /* ....... */ - $"FFF9 FE00 FFFF 16F6 FB81 00F9 FFF9 0000" /* ..... */ - $"FFFF 002B FFFC 0000 FFFF 002B FFFC A700" /* .+...+. */ - $"D400 FFFF FBCE FBCD F9CC FF7D FD71 FD4C" /* .}qL */ - $"F771 FFA6 FDCC FFEE FFFF FC00 00FA E800" /* q... */ - $"F400 FEFD 00B8 FEF5 FA00 02FB FFF9 FC00" /* ..... */ - $"2EFC FF2B 0000 FFFF 00FF FF00 00FC FF2B" /* .+.....+ */ - $"00F9 FFF9 F82B 0000 FFFF 0000 FFFF F8FF" /* .+.... */ - $"F800 81FF F500 FFFF 002B FFFC 0000 FFFF" /* ...+.. */ - $"FA00 FFFF FD00 0D2B FB81 F9FF F800 002B" /* ...+..+ */ - $"FB81 F9FF F8FC 0000 FBFA 0016 FCFF 2B81" /* ....+ */ - $"FFFB 00FC FF2B 0000 FFFF 0000 FFFF 00FF" /* .+..... */ - $"FF00 00FD 000A FCFF 2B00 F9FF F900 00FF" /* ...+... */ - $"FFFE 0013 F9AC FFF9 0000 FFFF 002B FFFC" /* .....+ */ - $"0000 FFFF 002B FFFC A700 D400 FFFF FBCE" /* ...+.. */ - $"FBCD F9CC FF7D FD71 FD4C F771 FFA6 FDCC" /* }qLq */ - $"FFEE FFFF FC00 00FA E800 F400 FEFD 00B3" /* ..... */ - $"FEF5 FA00 02F8 FFFC FD00 142B FBFF 2B00" /* ....++. */ - $"00FF FE00 FFFF 0000 FCFF F600 F5FF FDFA" /* ..... */ - $"FE00 FFFF FF00 FFFF 1100 FAFE FAAC F700" /* ..... */ - $"00FF FF00 2BFF FC00 00FF FFFA 00FF FFFA" /* ..+... */ - $"0001 FCFE FB00 01FC FEFC 0001 2B56 FA00" /* ......+V. */ - $"16FC FF2B F5FF FFF5 FBFF 2B00 00FF FE00" /* .++... */ - $"00FF FF00 FFFF 0000 FD00 21FC FF2B 002B" /* .....!+.+ */ - $"FFFC 0000 FFFF 00F6 FE2B F9FF F900 00FF" /* ...+.. */ - $"FF00 2BFF FC00 00FF FF00 2BFF FCA7 00D2" /* .+...+. */ + $"00FE FD00 FFFE F5FB 00FF FD22 00FB FEFA" /* ...". */ + $"00F9 2B00 F6FA 56F8 00F5 2BF5 81FF F7F6" /* .+.V.+ */ + $"81FF F7F5 00F8 FA56 0000 F556 F6FA 56FC" /* .V..VV */ + $"0005 FCFF F7FA F700 FEF7 03F6 2BF7 2BFE" /* ....++ */ + $"0015 F7FF FA00 F7FF FA00 F556 FAF8 0000" /* ....V.. */ + $"F7FF FAF5 FDFF F7F5 FE00 1EF7 FFFA 00F7" /* ... */ + $"FFFA 00F6 FA56 F800 F7FA 5600 00F7 F7F6" /* .V.V.. */ + $"F6F7 F700 00F7 2B56 FAF6 FC00 FB00 15FA" /* ..+V... */ + $"FF56 002B 0000 F5F9 FAF6 0000 F6FA F9F6" /* V.+.... */ + $"00F6 FAF9 F6FE F703 F62B F72B FE00 13FC" /* ..++.. */ + $"FE2B 002B 0000 F556 FAF8 0000 F9FF 812B" /* +.+..V..+ */ + $"F7FE 81FA F706 F6F7 F700 56FA F7FE 0007" /* ..V.. */ + $"F9F8 FAF5 00F8 FA56 F500 0007 FDD9 0007" /* .V..... */ + $"E600 FE00 0007 D800 FFFF FF7D FFA7 FD7D" /* .....}} */ + $"FB4C FD04 FF9C FD4C FFE4 FF9C FF00 FD48" /* L.L.H */ + $"FD6C FF78 FFA2 FFCC FFC8 FF7D FFFF E200" /* lx}. */ + $"F400 FEFD 0108 FEF5 FB00 25FA FF2B 56FF" /* ....%+V */ + $"5600 FB00 F9FF FEFF FFFA FDFA F7FD FFFA" /* V.. */ + $"56FD FFFA F681 FB00 FBFA F7FE FEF9 81FF" /* V. */ + $"56FD 000C FCFF F881 FF56 F9FF ACF6 2BFE" /* V..V+ */ + $"F7FE 0015 F7FF FAF5 FBAC F5F5 ACF9 F5FD" /* .. */ + $"FB00 F7FF FAF7 FDFF FAF6 FE00 1EF7 FFFA" /* ... */ + $"F581 FEF6 F9FF FEFF FFFA FFF7 FF81 00FA" /* . */ + $"FFFA F6FD FF00 FBFF FCF8 FEFD FC00 FB00" /* ... */ + $"1C56 FFFF FCF6 00F6 FEFB FAFF F6F7 FFF5" /* .V. */ + $"56FA F7FF F556 FAF9 FFAC F62B FEF7 FE00" /* VV+. */ + $"2D81 FFFF FAF5 00F5 ACF9 F5FD FB00 81FF" /* -.. */ + $"FC56 81FF FCF9 ACFF F981 FFFA F5AC F9AC" /* V */ + $"FD56 FF56 F6AC FFFE FFFA 81FB 00FB FAF7" /* VV. */ + $"0000 07FE D901 40F6 E500 FF00 0239 D932" /* ....@...92 */ + $"D900 FFFF FF7D FFA7 FD7D FB4C FD04 FF9C" /* .}}L. */ + $"FD4C FFE4 FF9C FF00 FD48 FD6C FF78 FFA2" /* L.Hlx */ + $"FFCC FFC8 FF7D FFFF E200 F400 FEFD 0107" /* }.... */ + $"FEF5 FB00 252B FFFA F5FF 81F6 FA00 00FF" /* .%+.. */ + $"FC56 FAF8 FFFA 00FC FF00 00FC FF00 F8FF" /* V.... */ + $"FAF7 FCFF 00FC FF00 F7FF FAFD 000B FCFF" /* .... */ + $"0000 FEFD 00AC FFF6 F5FA FD00 13F7 FFFD" /* ..... */ + $"FFFE F500 FAFF F500 F9FF F8F7 FFFA 00FC" /* ... */ + $"FFFC 001E F7FF ACFA FE81 F500 FFFC 56FA" /* ...V */ + $"FC56 00FF FC00 F7FF FA00 FCFF 00F7 FFFA" /* V.... */ + $"00FC FFFD 0000 F6FF F700 F5FD 001A 81FF" /* ...... */ + $"FFFE F556 FBF5 FAFF F7FA FF81 F5F6 FAFF" /* V */ + $"81F5 F600 ACFF F6F5 FAFD 002D F5AC FFFF" /* ..- */ + $"FC00 FAFF F500 F9FF F8F7 FFFA 00F7 FFFA" /* ... */ + $"00F8 FFF9 F6FF 8100 FB2B FC2B F7FF FA00" /* ..++. */ + $"FAFF F8FB FAFF FAF7 FCFF F800 0007 FED9" /* ... */ + $"0140 F5E4 0004 00F7 D9D9 39D9 00FF FFFF" /* .@...9. */ + $"4DFF A7FF F6FF 7DFB 4CFB 04FF 4CFF E4FF" /* M}L.L */ + $"9CFB 00FF 48FB 6CFF 96FF A2FF E4FF 4DFF" /* .HlM */ + $"FFE2 00F4 00FE FD01 02FE F5FA 00FF FD18" /* ...... */ + $"56FE FEF9 2B00 00FF FC00 00F7 FFFA 00FC" /* V+..... */ + $"FF00 00FC FF00 FAFF F9FE F706 00FC FF00" /* ...... */ + $"F7FF FAFD 000B FCFF 0000 FCFF 0056 FFF9" /* .....V */ + $"F9F6 FD00 13F7 FFFA FAFF FA00 FCFF 0000" /* ..... */ + $"F7FF FAF7 FFFA 00FC FFFC 0009 F7FF FA00" /* ... */ + $"F7FF FA00 FFFC FE00 11F7 FAFF FC00 F7FF" /* .... */ + $"FA00 FCFF 00F7 FFFA 00FC FFFD 0000 FAFF" /* ..... */ + $"FF00 F6FC 0019 F7FD FFF9 00F5 FAFC FFF7" /* .... */ + $"F7FF FFFE F7F7 FFFF FEF7 0056 FFF9 F9F6" /* .V */ + $"FB00 28F9 FEFF 2BFC FF00 00F7 FFFA F7FF" /* .(+.. */ + $"FA00 F7FF FA00 00FE ACF8 FDFE F6F9 0000" /* ..... */ + $"56FB FFFA 00FA FFF7 00FA FFF9 FEF7 F900" /* V... */ + $"0007 FED9 0140 F5E3 0004 0040 D9D9 0ED9" /* ...@...@. */ + $"00FF FFFF 4DFF A7FF F6FF 7DFB 4CFB 04FF" /* .M}L. */ + $"4CFF E4FF 9CFB 00FF 48FB 6CFF 96FF A2FF" /* L.Hl */ + $"E4FF 4DFF FFE2 00F4 00FE FD01 05FE F5FA" /* M.... */ + $"0005 FAFF AC56 FFFD FE00 11FF FC00 00F7" /* ..V.... */ + $"FFFA 00FC FF00 00FC FF00 F9FF F8FD 0005" /* ...... */ + $"FCFF 00F7 FFFA FD00 0AFC FF00 00FC FD00" /* ..... */ + $"F5FE ACFA FC00 13F7 FFFA F6FF FEF5 FBFF" /* .. */ + $"F500 F7FF F9F7 FFFA 00FC FFFC 001E F7FF" /* .... */ + $"FA00 00FF FC00 FFFC 0000 FAFE F5FF FC00" /* ...... */ + $"F7FF FA00 FCFF 00F7 FFFA 00FC FFFD 0000" /* ..... */ + $"56FF FAFD 001A 5600 00F6 FFFA F6FD FAFA" /* V..V.. */ + $"FFF7 00F7 ACFF FC00 F7AC FFFC 00F5 FEAC" /* ... */ + $"FAFC 002A 5600 0056 FFF7 FBFF F500 F7FF" /* .*V..V. */ + $"F9F7 FFFA 00F7 FFFA 0000 FAFF FA56 FFFC" /* ...V */ + $"F600 FCFC F7FF FA00 FAFF F700 F9FF F8F7" /* ... */ + $"0000 07FE D901 40F5 E200 00F7 FED9 00F5" /* ....@... */ + $"DB00 FFFF FFCE FFCD FFC6 FDA7 FF7D FD4C" /* .}L */ + $"FF70 FDE4 FF4D FF9C FD48 FF00 FD48 FB6C" /* pMH.Hl */ + $"FF96 FFA2 FFC6 FF4D FFA7 FFFF E400 F400" /* M.. */ + $"FEFD 0104 FEF5 FA00 052B FFFA F5FF FAFE" /* ....+ */ + $"001B FFFC 0000 F7FF FA00 FCFF 0000 FCFF" /* ....... */ + $"00F6 FEFC F500 FA00 FCFF 00F7 FFFA FD00" /* ..... */ + $"0AFC FF00 F5FF FA00 0081 FFF8 FC00 13F7" /* ..... */ + $"FFFA 0081 FFF9 F8FF 5600 F9FE F6F7 FFFA" /* .V. */ + $"00FC FFFC 001E F7FF FA00 F6FF 8100 FFFC" /* ..... */ + $"0000 FFFC F5FF FCF5 2BFF FA00 ACFF F5F7" /* ..+. */ + $"FFFA 00FC FFFC 00FB 001A FAF7 00F5 FFF6" /* ..... */ + $"FAFF F7FA FFF8 FA2B 00AC 81FA 2B00 AC81" /* +.+. */ + $"0000 81FF F8FC 002D FBF5 00F8 FD00 F8FF" /* ...-.. */ + $"5600 F9FE F6F7 FFFA 00F7 FFFA 0000 2BFF" /* V....+ */ + $"F900 FEFB 00F7 FFFA F8FF FAF5 FAFF F700" /* ... */ + $"F6FE FCF5 00FA FB00 0007 FED9 0140 F5E1" /* .....@ */ + $"0003 40D9 D940 DA00 FFFF FFCE FFCD FFC6" /* ..@@. */ + $"FDA7 FF7D FD4C FF70 FDE4 FF4D FF9C FD48" /* }LpMH */ + $"FF00 FD48 FB6C FF96 FFA2 FFC6 FF4D FFA7" /* .HlM */ + $"FFFF E400 F400 FEFD 0101 FEF5 F900 24AC" /* .....$ */ + $"F500 812B 0000 F9FF FEF7 00FB FFAC F6F9" /* .+... */ + $"FF81 F5F9 FF81 F5F7 FDFD 812B F7FE FFF9" /* + */ + $"FBFF ACF6 FE00 04FC 8181 FCFA FE00 012B" /* ....+ */ + $"FDFC 0015 F6FB FFAC F7F7 FFFE 2BF9 FDFA" /* ..+ */ + $"FCF7 00FB FFAC 56FE FFF9 FE00 20F6 FBFF" /* .V. */ + $"ACFA FDFB F5F9 FFFE F700 FBFE 56FC ACF6" /* .V */ + $"00FC FFFA FBFB 56FB FFAC 56FE FFF9 FD00" /* .VV. */ + $"FB00 19F7 FBFA FBF8 00F7 FEFB 56FF F9F8" /* ...V */ + $"ACFA FBF5 F8AC FAFB F500 002B FDFB 002D" /* ..+.- */ + $"F981 FAFB 2B00 00F9 FDFA FCF7 00FB FFAC" /* +... */ + $"F6F5 FDFD F800 00AC F500 FAF8 00F5 FDAC" /* .... */ + $"F8FE 812B ACFF FB00 00F7 FDFD 812B FC00" /* +..+. */ + $"0007 FED9 0140 F5E1 0000 0EFE D900 32DA" /* ...@....2 */ + $"00FF FFFF CEFD CDFD CCFF A7FF 71FF 4DFD" /* .qM */ + $"C6FF 78FF E4FF 6CF7 48FD 6CFB 96FF C6FF" /* xlHl */ + $"7DFF A7FF FFE4 00F4 00FE FD00 4CFE F5C9" /* }...L */ + $"0001 F5FA BE00 E300 01F5 FAC9 0000 07FE" /* ........ */ + $"D901 40F5 E100 01F5 D9FE D900 F6DA 00FF" /* .@.... */ + $"FFFF CEFD CDFD CCFF A7FF 71FF 4DFD C6FF" /* qM */ + $"78FF E4FF 6CF7 48FD 6CFB 96FF C6FF 7DFF" /* xlHl} */ + $"A7FF FFE4 00F4 00FE FD00 4CFE F5CA 0002" /* ...L.. */ + $"FAFD 2BBE 00E4 0002 FAFD 2BCA 0000 07FD" /* +...+... */ + $"D900 07E1 0002 F540 D9FF D900 40D9 00FF" /* ....@.@. */ + $"FFFD CEFD CDFD CCFF E4FF 71FF C6FB 78FD" /* qx */ + $"6CFB 48FB 6CFD 96FF A2FF C6FF E4FF 4DFF" /* lHlM */ + $"FFE4 00F4 00FE FD00 5AFE F5D1 00FF 56FC" /* ...Z.V */ + $"0001 FBAC BD00 F400 07F7 FA00 002B FBFC" /* .......+ */ + $"F7F9 0001 FBAC CA00 0007 FDD9 0007 E100" /* ........ */ + $"03F5 40D9 D9FF D900 32D9 00FF FFFD CEFD" /* .@.2. */ + $"CDFD CCFF E4FF 71FF C6FB 78FD 6CFB 48FB" /* qxlH */ + $"6CFD 96FF A2FF C6FF E4FF 4DFF FFE4 00F4" /* lM. */ + $"00FE FD00 A1FE F5FA 0004 FAFC FAFB FAE7" /* .... */ + $"00FF ACFA 0002 FBFF FAF4 0012 F881 FA00" /* ...... */ + $"002B FBFA ACF8 0000 FA81 FC81 F500 FEFD" /* .+... */ + $"FC00 FAF9 0002 F6F9 FDFE 0011 FA81 FC81" /* ..... */ + $"F500 2BFB FAAC F800 0056 81FB FCF5 FD00" /* .+..V. */ + $"01FA FCFE FC01 FAF5 FA00 10F9 FFFC 00F5" /* ..... */ + $"FEF9 FEF8 0000 F9FB FCFA FBF9 C900 00F7" /* .... */ + $"FDD9 00F7 E100 0032 FDD9 FFD9 00F6 D900" /* ...2.. */ + $"FFFF FDCE FDCD FDCC FFA7 FFE4 FF71 FF4D" /* qM */ + $"FD78 FD71 F76C FB96 FDA2 FFC6 FF71 FFFF" /* xqlq */ + $"E400 F400 FEFD 00AB FEF5 FB00 0581 ACF5" /* ..... */ + $"0000 ACE7 00FF ACFA 0002 F7FF FAFC 0001" /* ....... */ + $"F7FA FC00 FF81 10FF FA00 00AC FA00 FAFF" /* ..... */ + $"F6F8 FFF5 F5FE 8100 FCFF 0056 FA00 18F8" /* ..V.. */ + $"FAFD FF00 00F8 FFF5 F5FE 8100 ACFA 00FA" /* .... */ + $"FFF6 F7FF 0000 ACFB FC00 00FF 04AC 00FA" /* ...... */ + $"FF81 F900 06FF FC00 F8FF F72B FE00 06F7" /* ...+.. */ + $"FFFC 00F7 FFFA CB00 0032 FDD9 0032 E300" /* ...2.2. */ + $"02F7 3940 FCD9 01D9 40D8 00FF FFFD CEFD" /* .9@.@. */ + $"CDFD CCFF A7FF E4FF 71FF 4DFD 78FD 71F7" /* qMxq */ + $"6CFB 96FD A2FF C6FF 71FF FFFD FAE8 00F4" /* lq. */ + $"00FE FD00 E0FE F5FC 0002 56FF F8FE 0006" /* ....V.. */ + $"F600 002B FAF9 F6FE 0004 FAF6 FAF8 00FE" /* ..+... */ + $"F71C F62B F72B F5FA F7F9 0000 F700 F556" /* .++...V */ + $"FAF8 0000 F7FF FA56 FAF6 00F7 FE81 2BFC" /* ..V.+ */ + $"0011 F7FF FA00 2BFF FA00 F6FF FAFB FF00" /* ...+.. */ + $"0081 FFF5 FDF7 00AC F700 16FC FF00 00FB" /* ...... */ + $"FF00 0081 FFF7 FFFA 00F6 FFFA FAFF F700" /* .... */ + $"ACFB FC00 00FF 13FC 0000 FFFC 0000 F8FA" /* ....... */ + $"56F5 0000 FFFC 00FB FFF9 F6FD 001D FFFC" /* V..... */ + $"0000 FFFC 00F5 FAF7 F900 F6FA F9F5 002B" /* .....+ */ + $"F72B F5F7 F7F5 00F6 F8F7 FAF7 E400 0032" /* +...2 */ + $"FCD9 E440 F7D9 01D9 39D8 00FF FFFD CEFD" /* @.9. */ + $"CDFD CCFF C6FF A6FF E4FF 71FF C6F9 78FD" /* qx */ + $"6CF9 96FB A2FF CCFF E4FF FFFE 0000 FAE8" /* l.. */ + $"00F4 00FE FD00 DCFE F5FC 0002 FBFF F5FC" /* ..... */ + $"002C 56FD F5F9 FEF7 F7FD FFF8 81FF F9F9" /* .,V */ + $"FFAC F62B FEFA FEFF FEFF 81AC FC00 ACFB" /* +. */ + $"F5FD FE56 F7FF ACF8 FEFD 0081 FFFC 56FC" /* V.V */ + $"0011 F7FF FA00 F7FF 8100 00FF FCFC FFF6" /* ..... */ + $"00FA FFF7 FE00 01F6 FAF7 0016 FCFF 0000" /* ....... */ + $"FCFF F600 FAFF FAFF 8100 00FF FCF7 FFFF" /* ... */ + $"FBAC F5FC 0000 FF13 FC00 FAFE 2B00 81FB" /* ....+. */ + $"00FB FDF5 00FF FCF6 FCFF 81F7 FD00 1EFF" /* .... */ + $"FC00 F9FF F8F7 FEFF FEFF FAFF F9AC FD00" /* .. */ + $"F7FF FCF5 FBFF F7F9 FFFD F8AC FFF6 E600" /* . */ + $"0032 D4D9 01D9 F7D8 00FF FFFD CEFD CDFD" /* .2.. */ + $"CCFF C6FF A6FF E4FF 71FF C6F9 78FD 6CF9" /* qxl */ + $"96FB A2FF CCFF E4FF FFFE 0000 FAE8 00F4" /* ... */ + $"00FE FD00 D7FE F5FC 0001 FCFF FC00 2CF5" /* ....., */ + $"FFFA 0000 FEAC 00FC FF00 00FE FD00 ACFF" /* ...... */ + $"F6F5 FA00 FCFF 2BFB F6FF FCF7 FFF7 00FA" /* .+. */ + $"FF00 F7FF FA00 FCFF 00F7 FFFA FB00 11F7" /* ..... */ + $"FFFA 0000 FEFE F500 FFFC F9FF FA00 FAFF" /* .... */ + $"F7FE 0001 FAF6 F700 12FC FF00 00F9 FFFA" /* ...... */ + $"00FA FFF7 FEFE F500 FFFC 00FA FEFF 0056" /* ....V */ + $"FC00 00FF FFFE 10FF F700 F8FF F800 2BFF" /* .....+ */ + $"FA00 FFFC 00FA FFF7 FC00 1EFF FEFA FDAC" /* .... */ + $"F600 FCFF 2BFB 81FA 00FC FF00 00FF FC00" /* .+.... */ + $"FAFF F700 FFFC 00FA FFF7 E700 0032 D3D9" /* ....2 */ + $"00D9 D700 FFFF FDCE FDCD FBCC FDC6 FFA6" /* .. */ + $"FF71 FFC6 FB9C FDA2 FB96 FBA2 FFC6 FDCC" /* q */ + $"FFFF FE00 00FA E800 F400 FEFD 00D6 FEF5" /* ..... */ + $"FC00 02FB FFF5 FD00 16F7 FFFA 0000 FCFF" /* ...... */ + $"00FC FF00 00FC FF00 56FF F9F9 F600 FCFF" /* ....V. */ + $"FE00 12FF FCF6 FF56 0081 FD00 F7FF FA00" /* ..V... */ + $"FCFF 00F7 FFFA FB00 10F7 FFFA 0000 2BFD" /* .....+ */ + $"FBF7 FFFA 00FA FE56 81FF FD00 0081 F600" /* .V... */ + $"01FC FFFE 0011 FAFE 5681 FF00 2BFD FBF7" /* ...V.+ */ + $"FFFA F8FE F5FA FFFE FC00 00FF 12FC F7FF" /* ... */ + $"AC00 FAFF F700 00FF FC00 FFFC 00FA FFF7" /* ..... */ + $"FC00 08FF FC00 F5FE FC00 FCFF FE00 12F6" /* ...... */ + $"FAFD FF00 00FF FC00 FAFF F700 FFFC 00FA" /* ..... */ + $"FFF7 E800 0032 D2D9 0039 D700 FFFF FDCE" /* ..2.9. */ + $"FDCD FBCC FDC6 FFA6 FF71 FFC6 FB9C FDA2" /* q */ + $"FB96 FBA2 FFC6 FDCC FFFF FE00 00FA E800" /* ... */ + $"F400 FEFD 00D5 FEF5 FC00 0256 FFF8 FE00" /* ....V. */ + $"17F8 2BFF FA00 00FC FE00 FCFF 0000 FCFE" /* .+..... */ + $"00F5 FEAC FA00 00FC FFFE 0012 FFFC 0056" /* ......V */ + $"FEFA FD2B 00F7 FFFA 00FC FF00 F7FF FAFB" /* +... */ + $"0002 F7FF FAFC 0002 56FF F6FD 0001 FD81" /* ....V.. */ + $"FE00 012B 56F6 0001 FCFF FB00 01FD 81FD" /* ..+V.... */ + $"0008 56FF F6FC FC00 0081 FFFC 0000 FF12" /* ..V..... */ + $"FC00 FDFF F7F9 FFF8 0000 FFFB 00FF FC00" /* ..... */ + $"FAFF F7FC 001E FFFC 0000 FCFF 00FC FF00" /* ...... */ + $"00F8 FEF7 FCFF 0000 FFFC 00FA FFF7 00FF" /* ..... */ + $"FC00 FAFF F7E9 0000 32D1 D900 32D7 00FF" /* ...2.2. */ + $"FFFD CEFB CDFB CCFD C6FF A6FF 71FF 4CFD" /* qL */ + $"04FF 71FF 7DFF A2FF C6FB A2FF C6FB CCFF" /* .q} */ + $"FFFE 0000 FAE8 00F4 00FE FD00 DAFE F5FB" /* ..... */ + $"00FF AC1A F500 00AC 00AC FD00 00FE FA00" /* ........ */ + $"FCFF 00F5 FF81 0000 81FF F800 00FC FFFE" /* ..... */ + $"0012 FFFC 00AC FDF7 F700 00F7 FFFA 00FC" /* ...... */ + $"FF00 F7FF FAFB 0002 F7FF FAFC 0001 FDFA" /* ..... */ + $"FD00 0256 FEF5 FE00 0681 F500 00F5 FBF8" /* ..V.... */ + $"FB00 01FC FFFC 0002 56FE F5FD 0008 FDFA" /* ....V.. */ + $"0081 FD00 00FA 81FC 0000 FF12 FC00 56FF" /* .......V */ + $"FBF6 FE81 002B FFF8 00FF FC00 FAFF F7FC" /* .+.. */ + $"001E FFFC 0000 FDFD 00FC FF00 00FC FF00" /* ........ */ + $"ACFF F500 FEAC 00FA FFF8 00FF FC00 FAFF" /* .... */ + $"F7EA 0000 32D0 D900 F7D7 00FF FFFD CEFB" /* ..2.. */ + $"CDFB CCFD C6FF A6FF 71FF 4CFD 04FF 71FF" /* qL.q */ + $"7DFF A2FF C6FB A2FF C6FB CCFF FFFE 0000" /* }.. */ + $"FAE8 00F4 00FE FD00 E0FE F5FB 0023 F5FA" /* ....# */ + $"FCFA 81FA 00F6 FCFB 81FA F500 FCFF FAAC" /* .. */ + $"FCF5 0000 2BFD 0000 F7FE FFF9 00F9 FFFE" /* ..+... */ + $"F7FA FEFF 0CFE 2BFB FFAC 56FE FFF9 F5FD" /* .+V */ + $"FDF8 FD00 04FA FDFF FEFA FE00 FF81 FD00" /* .... */ + $"022B FD2B FD00 0081 FE00 022B FFFC FD00" /* .++....+. */ + $"0A2B FCFF FFAC 2B00 002B FD2B FD00 FF81" /* ++..++. */ + $"FF00 05F5 81FB FA81 F5FD 0001 FAFF 12FE" /* ..... */ + $"56F5 FEFF 56F7 FDFA FBF9 00F9 FFFE 56AC" /* VV.V */ + $"FFFB FD00 1FFA FFFE FAFC AC2B F7FE FFF9" /* ..+ */ + $"00F9 FFFA FAFE F700 FAFF FBFA ACFA F9FF" /* .. */ + $"FE56 ACFF FBEB 0000 F6CF D9D6 00FF FFFB" /* V... */ + $"CEFD CDF9 CCFD C6FF A6FF 71FF 04FD 4CFF" /* q.L */ + $"04FF 71FF 7DFF CCFD C6FB CCFF EEFF FFFE" /* .q} */ + $"0000 FAE8 00F4 00FE FD00 70FE F5ED 0001" /* .....p.. */ + $"FCFF FB00 01F5 FAF7 0006 F5FB F8FA 81FF" /* .... */ + $"FAEC 0002 F681 FAFD 0002 56FB 2BFD 0001" /* ....V+.. */ + $"F6F7 FD00 01F5 81F6 0002 56FB 2BFE 0002" /* ....V+.. */ + $"F681 FAF2 00B4 0000 39D0 D900 39D6 00FF" /* ...9.9. */ + $"FFFB CEFD CDF9 CCFD C6FF A6FF 71FF 04FD" /* q. */ + $"4CFF 04FF 71FF 7DFF CCFD C6FB CCFF EEFF" /* L.q} */ + $"FFFE 0000 FAE8 00F4 00FE FD00 5CFE F5ED" /* .....\ */ + $"0001 FCFF FC00 02FA FD2B F700 01F9 ACFE" /* ....+.. */ + $"0001 ACF7 EC00 01F9 F6FD 0001 F7F8 F500" /* ....... */ + $"0156 2BF7 0001 F7F8 FC00 01F9 F6F1 00B4" /* .V+..... */ + $"00CF D900 F7D4 00FF FFFD CEFB CDF7 CCFF" /* ... */ + $"E4FF 71F7 4CFF 71FF 7DFF A6F9 CCFF FFFC" /* qLq} */ + $"0000 FAE8 00F4 00FE FD00 4AFE F5EE 0003" /* .....J.. */ + $"F7FE FFF9 FD00 01FB ACF6 0005 F581 FCFA" /* .... */ + $"FAF7 D700 00F8 DD00 B400 0040 D1D9 0140" /* .....@.@ */ + $"00D4 00FF FFFD CEFB CDF7 CCFF E4FF 71F7" /* ..q */ + $"4CFF 71FF 7DFF A6F9 CCFF FFFC 0000 FAE8" /* Lq}.. */ + $"00F4 00FE FD00 34FE F584 00B4 0002 F639" /* ...4...9 */ + $"40D4 D902 40F5 00D4 00FF FFFB CEFB CDF9" /* @.@.. */ + $"CCFF 7DFD 71FD 4CF7 71FF A6FD CCFF EEFF" /* }qLq */ + $"FFFC 0000 FAE8 00F4 00FE FD00 2AFE F584" /* .....* */ + $"0081 00D4 00FF FFFB CEFB CDF9 CCFF 7DFD" /* ...} */ + $"71FD 4CF7 71FF A6FD CCFF EEFF FFFC 0000" /* qLq.. */ + $"FAE8 00F4 00FE FD00 2AFE F584 0081 00D2" /* ...*.. */ $"00FF FFFB CEFB CDFB CCFF A6FF 7DF7 71FB" /* .}q */ $"7DFF A6FF CCFF CDFF FFFA 0000 FAE8 00F4" /* }... */ - $"00FE FD00 B4FE F5F9 0014 ACFF F600 00F5" /* ...... */ - $"FCF8 FFFA 00F5 FF81 00FF FF00 00FD FDFE" /* .... */ - $"0002 81FF F8FE 00FF FFFF 00FF FF04 2BFE" /* .....+ */ - $"FC2B 2BFE 00FF FF07 002B FFFC 0000 FFFF" /* ++...+.. */ - $"FA00 FFFF FB00 022B FFF7 FC00 022B FFF7" /* ...+..+ */ - $"FC00 0081 F900 16FC FF2B 0081 FF81 F8FF" /* ....+. */ - $"FA00 F5FF 8100 00FF FF00 FFFF 0000 FD00" /* ....... */ - $"21FC FF2B 00F7 FF81 0000 FFFF 00FB FF00" /* !+..... */ - $"81FF F900 00FE FF00 2BFF FC00 00FF FF00" /* ...+... */ - $"2BFF FCA7 00D2 00FF FFFB CEFB CDFB CCFF" /* +.. */ - $"A6FF 7DF7 71FB 7DFF A6FF CCFF CDFF FFFA" /* }q} */ - $"0000 FAE8 00F4 00FE FD00 B6FE F5F8 0013" /* ....... */ - $"81FE F8F7 AC56 00FA FEF7 81FC 0000 FFFF" /* V... */ - $"F7FA FEF6 FE00 012B FEFE 0008 F9FF FFF9" /* ..+.. */ - $"F9FF FFFA FBFD FF0D F7F9 FFFF F7FB FFFE" /* . */ - $"F700 FCFF ACF6 FE00 052B FCFF FFFB F6FD" /* ...+ */ - $"0001 FDF8 FB00 01FD F8FB 0000 81FA 0017" /* ........ */ - $"F7FE FFFB F5F6 FFFF 56FA FEF7 81FC 0000" /* V.. */ - $"F9FF FF81 FFFF FA00 FE00 232B FDFF F9F7" /* ..#+ */ - $"ACFD F600 F9FF FFF9 F9FF FD56 FFFE F600" /* .V. */ - $"FAFF FBFA FDFD 2BF9 FFFF F8FB FFFE F7A8" /* + */ - $"00D2 00FF FFF9 CEFB CDFD CCFF CDFF A6F3" /* .. */ - $"7DFF A7FB CDFF FFFA 0000 FAE8 00F4 00FE" /* }.... */ - $"FD00 75FE F5F6 00FF 2BFC 0001 2BF5 FE00" /* .u.+..+. */ - $"FFFF 01F5 2BFB 0000 81F7 0006 F681 F8F9" /* .+.... */ - $"FAFE FCF7 0000 2BF4 0002 F8AC F7FC 0002" /* ..+.... */ - $"F8AC F7FB 0001 F5F6 EF00 012B F5F6 00FE" /* ....+. */ - $"0005 F500 002B 2BF6 F900 032B 0000 F6FD" /* ....++..+.. */ - $"00FF F601 00F5 9E00 D200 FFFF F9CE FBCD" /* ..... */ - $"FDCC FFCD FFA6 F37D FFA7 FBCD FFFF FA00" /* }. */ - $"00FA E800 F400 FEFD 0046 FEF5 EA00 FFFF" /* ....F. */ - $"FB00 0281 FDF6 F700 01FB FAFE 0001 ACF8" /* ...... */ - $"EA00 01F5 F8FB 0001 F5F8 D800 8100 D000" /* ....... */ - $"FFFF F9CE F7CD FFCF FFA6 FD7D FBE4 FFA7" /* } */ - $"FFF3 FDCD FFFF F800 00FA E800 F400 FEFD" /* .... */ - $"003C FEF5 EB00 03FA FFFF FAFC 00FF ACF6" /* .<... */ - $"0005 F6FB 81F9 F9F7 B600 8100 D000 FFFF" /* ..... */ - $"F9CE F7CD FFCF FFA6 FD7D FBE4 FFA7 FFF3" /* } */ - $"FDCD FFFF F800 00FA E800 F400 FEFD 0026" /* .....& */ - $"FEF5 8400 8100 CE00 FFFF F7CE F9CD FFA6" /* ... */ - $"FF7D FDE4 FFA7 FFF3 FBCE FFFF F600 00FA" /* }.. */ - $"E800 F400 FEFD 0026 FEF5 8400 8100 CE00" /* ...&... */ - $"FFFF F7CE F9CD FFA6 FF7D FDE4 FFA7 FFF3" /* } */ - $"FBCE FFFF F600 00FA E800 F400 FEFD 0024" /* .....$ */ - $"FEF5 8400 8100 CC00 FFFF F5CE FDCD FFA6" /* ... */ - $"FFE4 FDA7 FFF3 FBCE FFFF F400 00FA E800" /* ... */ - $"F400 FEFD 0024 FEF5 8400 8100 CC00 FFFF" /* ..$... */ - $"F5CE FDCD FFA6 FFE4 FDA7 FFF3 FBCE FFFF" /* */ - $"F400 00FA E800 F400 FEFD 001C FEF5 8400" /* ....... */ - $"8100 CA00 FDFF F5CE FBA7 FBCE FDFF F200" /* ... */ - $"00FA E800 F400 FEFD 001C FEF5 8400 8100" /* ....... */ - $"CA00 FDFF F5CE FBA7 FBCE FDFF F200 00FA" /* ... */ - $"E800 F400 FEFD 0020 FEF5 8400 8100 C600" /* ... ... */ - $"FDFF F9CE FFF3 FFA7 FFF3 FFCE FDFF EE00" /* . */ - $"00FA E800 F400 FEFD 0020 FEF5 8400 8100" /* .... .. */ - $"C600 FDFF F9CE FFF3 FFA7 FFF3 FFCE FDFF" /* . */ - $"EE00 00FA E800 F400 FEFD 0014 FEF5 8400" /* ....... */ - $"8100 C100 F2FF EA00 00FA E800 F400 FEFD" /* ...... */ - $"0030 FEF5 F700 FDFF EC00 FFFF FA00 FEFF" /* .0... */ - $"FB00 FFFF FF00 FFFF F100 FFFF F200 FFFF" /* .... */ - $"E200 8100 C100 F2FF EA00 00FA E800 F400" /* ....... */ - $"FEFD 0030 FEF5 F800 FFFF FF00 FFFF E300" /* .0... */ - $"FFFF FB00 FFFF FF00 FFFF F100 FFFF F200" /* .... */ - $"FFFF E200 8100 B900 00FA E400 00FA E800" /* ....... */ - $"F400 FEFD 0064 FEF5 F800 FFFF FC00 FDFF" /* ..d.. */ - $"FE00 FEFF FE00 FEFF FF00 FEFF FF00 FEFF" /* .... */ - $"FE00 FFFF FC00 FDFF 0000 FDFF FE00 FEFF" /* ..... */ - $"FF00 FDFF FF00 FFFF 0400 FFFF 0000 FDFF" /* ...... */ - $"FC00 FDFF FF00 FEFF FD00 FFFF EE00 8100" /* ..... */ - $"B900 00FA E700 00F9 FBFF 00F9 FA00 00F9" /* ....... */ - $"FBFF 00F9 FB00 F400 FEFD 007E FEF5 F700" /* ....~. */ - $"FDFF FF00 FFFF 1200 FFFF 00FF FF00 FFFF" /* ..... */ - $"00FF FF00 FFFF 0000 FFFF FD00 FFFF FF00" /* ...... */ - $"FFFF FB00 FFFF FF00 FFFF 0200 FFFF FD00" /* ..... */ - $"FFFF 0600 FFFF 00FF FF00 FDFF FF00 FFFF" /* ..... */ - $"F800 FFFF FF00 FFFF 0200 FFFF E900 8100" /* ...... */ - $"EE00 00F9 FBFF 00F9 FA00 00F9 FBFF 00F9" /* ...... */ - $"E300 00FA E700 00FF FB2B 00FF FA00 00FF" /* ....+... */ - $"FB2B 00FF FB00 F400 FEFD 007C FEF5 F400" /* +....|. */ - $"FFFF 0600 FFFF 00FF FF00 FCFF 0200 FFFF" /* ...... */ - $"FC00 FFFF FF00 FDFF FF00 FFFF FB00 FFFF" /* .... */ - $"FF00 FFFF 0400 FFFF 0000 FDFF 0600 FFFF" /* ....... */ - $"00FF FF00 FEFF FD00 FEFF FA00 FFFF FF00" /* ..... */ - $"FFFF 0200 FFFF E900 8100 EE00 00FF FB2B" /* ......+ */ - $"00FF FA00 00FF FB2B 00FF E300 00FA E700" /* ...+.... */ - $"01FF 2BFD FC01 2BFF FA00 01FF 2BFD FC01" /* .+.+..+. */ - $"2BFF FB00 F400 FEFD 008D FEF5 F800 FFFF" /* +.... */ - $"FF00 FFFF 0800 FFFF 00FF FF00 FFFF FD00" /* ...... */ - $"FFFF 1000 FFFF 0000 FFFF 00FF FF00 FFFF" /* ...... */ - $"0000 FFFF FB00 FFFF FF00 FFFF 0F00 FFFF" /* ...... */ - $"00FF FF00 FFFF 00FF FF00 FFFF 00FD FFFC" /* ..... */ - $"00FF FFFB 00FF FFFF 00FF FF02 00FF FFE9" /* ..... */ - $"0081 00EE 0001 FF2B FDFC 012B FFFA 0001" /* ....+.+.. */ - $"FF2B FDFC 012B FFE3 0000 FAE7 0007 FF2B" /* +.+....+ */ - $"FC2A 2AF5 2BFF FA00 07FF 2BFC 2A2A F52B" /* **+..+**+ */ - $"FFFB 00F4 00FE FD00 83FE F5F7 00FD FFFF" /* .... */ - $"00FD FFFE 00FE FFFE 00FE FFFE 00FF FFFF" /* .... */ - $"00FD FFFF 00FF FFFA 00FF FF07 00FF FF00" /* ...... */ - $"FFFF 0000 FDFF 0C00 FFFF 00FF FF00 FFFF" /* ...... */ - $"00FF FF00 FDFF F900 FFFF FF00 FEFF FD00" /* ..... */ - $"FFFF EE00 8100 EE00 07FF 2BFC 2A2A F52B" /* ....+**+ */ - $"FFFA 0007 FF2B FC2A 2AF5 2BFF E300 00FA" /* ..+**+.. */ - $"E700 02FF 2BFC FEF5 012B FFFA 0002 FF2B" /* ..+.+..+ */ - $"FCFE F501 2BFF FB00 F400 FEFD 003A FEF5" /* .+...: */ - $"F100 FFFF 9600 8100 EE00 02FF 2BFC FEF5" /* .....+ */ - $"012B FFFA 0002 FF2B FCFE F501 2BFF E300" /* .+..+.+. */ - $"00FA E700 00FF FB2B 00FF FA00 00FF FB2B" /* ...+...+ */ - $"00FF FB00 F400 FEFD 002C FEF5 F100 FFFF" /* ....,. */ - $"9600 8100 EE00 00FF FB2B 00FF FA00 00FF" /* ....+... */ - $"FB2B 00FF E300 00FA E900 F5FF FE00 F5FF" /* +..... */ - $"FDFA F400 FEFD 0030 FEF5 8400 8100 F000" /* ..0... */ - $"F5FF FE00 F5FF FDFA E900 00FA E900 00FF" /* ..... */ + $"00FE FD00 2AFE F584 0081 00D2 00FF FFFB" /* ..*... */ + $"CEFB CDFB CCFF A6FF 7DF7 71FB 7DFF A6FF" /* }q} */ + $"CCFF CDFF FFFA 0000 FAE8 00F4 00FE FD00" /* ..... */ + $"26FE F584 0081 00D2 00FF FFF9 CEFB CDFD" /* &... */ + $"CCFF CDFF A6F3 7DFF A7FB CDFF FFFA 0000" /* }.. */ + $"FAE8 00F4 00FE FD00 26FE F584 0081 00D2" /* ...&.. */ + $"00FF FFF9 CEFB CDFD CCFF CDFF A6F3 7DFF" /* .} */ + $"A7FB CDFF FFFA 0000 FAE8 00F4 00FE FD00" /* ..... */ + $"28FE F584 0081 00D0 00FF FFF9 CEF7 CDFF" /* (... */ + $"CFFF A6FD 7DFB E4FF A7FF F3FD CDFF FFF8" /* } */ + $"0000 FAE8 00F4 00FE FD00 28FE F584 0081" /* .....(. */ + $"00D0 00FF FFF9 CEF7 CDFF CFFF A6FD 7DFB" /* ..} */ + $"E4FF A7FF F3FD CDFF FFF8 0000 FAE8 00F4" /* ... */ + $"00FE FD00 26FE F584 0081 00CE 00FF FFF7" /* ..&... */ + $"CEF9 CDFF A6FF 7DFD E4FF A7FF F3FB CEFF" /* } */ + $"FFF6 0000 FAE8 00F4 00FE FD00 42FE F5F7" /* .....B */ + $"00FD FFEC 00FF FFFA 00FE FFFB 00FF FFFF" /* .... */ + $"00FF FFF1 00FF FFF2 00FF FFE2 0081 00CE" /* ..... */ + $"00FF FFF7 CEF9 CDFF A6FF 7DFD E4FF A7FF" /* .} */ + $"F3FB CEFF FFF6 0000 FAE8 00F4 00FE FD00" /* ..... */ + $"40FE F5F8 00FF FFFF 00FF FFE3 00FF FFFB" /* @... */ + $"00FF FFFF 00FF FFF1 00FF FFF2 00FF FFE2" /* .... */ + $"0081 00CC 00FF FFF5 CEFD CDFF A6FF E4FD" /* ... */ + $"A7FF F3FB CEFF FFF4 0000 FAE8 00F4 00FE" /* .... */ + $"FD00 68FE F5F8 00FF FFFC 00FD FFFE 00FE" /* .h... */ + $"FFFE 00FE FFFF 00FE FFFF 00FE FFFE 00FF" /* .... */ + $"FFFC 00FD FF00 00FD FFFE 00FE FFFF 00FD" /* ..... */ + $"FFFF 00FF FF04 00FF FF00 00FD FFFC 00FD" /* ...... */ + $"FFFF 00FE FFFD 00FF FFEE 0081 00CC 00FF" /* ..... */ + $"FFF5 CEFD CDFF A6FF E4FD A7FF F3FB CEFF" /* */ + $"FFF4 0000 FAE8 00F4 00FE FD00 6AFE F5F7" /* .....j */ + $"00FD FFFF 00FF FF12 00FF FF00 FFFF 00FF" /* ...... */ + $"FF00 FFFF 00FF FF00 00FF FFFD 00FF FFFF" /* ..... */ + $"00FF FFFB 00FF FFFF 00FF FF02 00FF FFFD" /* ..... */ + $"00FF FF06 00FF FF00 FFFF 00FD FFFF 00FF" /* ...... */ + $"FFF8 00FF FFFF 00FF FF02 00FF FFE9 0081" /* ..... */ + $"00CA 00FD FFF5 CEFB A7FB CEFD FFF2 0000" /* .... */ + $"FAE8 00F4 00FE FD00 64FE F5F4 00FF FF06" /* ...d.. */ + $"00FF FF00 FFFF 00FC FF02 00FF FFFC 00FF" /* ...... */ + $"FFFF 00FD FFFF 00FF FFFB 00FF FFFF 00FF" /* .... */ + $"FF04 00FF FF00 00FD FF06 00FF FF00 FFFF" /* ....... */ + $"00FE FFFD 00FE FFFA 00FF FFFF 00FF FF02" /* ..... */ + $"00FF FFE9 0081 00CA 00FD FFF5 CEFB A7FB" /* .... */ + $"CEFD FFF2 0000 FAE8 00F4 00FE FD00 73FE" /* .....s */ + $"F5F8 00FF FFFF 00FF FF08 00FF FF00 FFFF" /* ..... */ + $"00FF FFFD 00FF FF10 00FF FF00 00FF FF00" /* ....... */ + $"FFFF 00FF FF00 00FF FFFB 00FF FFFF 00FF" /* ..... */ + $"FF0F 00FF FF00 FFFF 00FF FF00 FFFF 00FF" /* ...... */ + $"FF00 FDFF FC00 FFFF FB00 FFFF FF00 FFFF" /* .... */ + $"0200 FFFF E900 8100 C600 FDFF F9CE FFF3" /* ..... */ + $"FFA7 FFF3 FFCE FDFF EE00 00FA E800 F400" /* .... */ + $"FEFD 0067 FEF5 F700 FDFF FF00 FDFF FE00" /* .g... */ + $"FEFF FE00 FEFF FE00 FFFF FF00 FDFF FF00" /* .... */ + $"FFFF FA00 FFFF 0700 FFFF 00FF FF00 00FD" /* ...... */ + $"FF0C 00FF FF00 FFFF 00FF FF00 FFFF 00FD" /* ...... */ + $"FFF9 00FF FFFF 00FE FFFD 00FF FFEE 0081" /* .... */ + $"00C6 00FD FFF9 CEFF F3FF A7FF F3FF CEFD" /* .. */ + $"FFEE 0000 FAE8 00F4 00FE FD00 18FE F5F1" /* ...... */ + $"00FF FF96 0081 00C1 00F2 FFEA 0000 FAE8" /* ...... */ + $"00F4 00FE FD00 18FE F5F1 00FF FF96 0081" /* ...... */ + $"00C1 00F2 FFEA 0000 FAE8 00F4 00FE FD00" /* ....... */ + $"14FE F584 0081 00B9 0000 FAE4 0000 FAE8" /* ....... */ + $"00F4 00FE FD00 20FE F584 0081 00B9 0000" /* ... .... */ + $"FAE7 0000 F9FB FF00 F9FA 0000 F9FB FF00" /* ...... */ + $"F9FB 00F4 00FE FD00 30FE F584 0081 00EE" /* ...0.. */ + $"0000 F9FB FF00 F9FA 0000 F9FB FF00 F9E3" /* ...... */ + $"0000 FAE7 0000 FFFB 2B00 FFFA 0000 FFFB" /* ....+... */ + $"2B00 FFFB 00F4 00FE FD00 6CFE F5F7 00FE" /* +....l. */ + $"FFFF 00FF FFF2 00FD FFF9 0000 FFFB 0000" /* ...... */ + $"FFDB 0000 FFEC 00FD FFFE 0000 FFFC 00EE" /* ...... */ + $"0000 FFFE 0000 FFDA 00FE FFF1 0000 FFFE" /* ....... */ + $"0000 FFF7 0000 FFE3 00EE 0000 FFFB 2B00" /* .......+. */ + $"FFFA 0000 FFFB 2B00 FFE3 0000 FAE7 0001" /* ..+..... */ + $"FF2B FDFC 012B FFFA 0001 FF2B FDFC 012B" /* +.+..+.+ */ + $"FFFB 00F4 00FE FD00 77FE F5F8 0000 FFFE" /* ...w.. */ + $"0003 FF00 00FF F200 00FF FE00 00FF F300" /* ......... */ + $"00FF DB00 00FF EC00 00FF FE00 00FF F900" /* ........ */ + $"EE00 03FF 0000 FFD9 0003 FF00 00FF F200" /* ......... */ + $"00FF FE00 00FF F700 00FF E300 EE00 01FF" /* ........ */ + $"2BFD FC01 2BFF FA00 01FF 2BFD FC01 2BFF" /* +.+..+.+ */ + $"E300 00FA E700 07FF 2BFC 2A2A F52B FFFA" /* ....+**+ */ + $"0007 FF2B FC2A 2AF5 2BFF FB00 F400 FEFD" /* ..+**+.. */ + $"00F6 FEF5 F800 00FF FE00 0AFF 0000 FF00" /* ....... */ + $"00FF FF00 00FF FE00 00FF FD00 00FF FE00" /* ........ */ + $"09FF 00FF 00FF FF00 FFFF 00FE FFFF 0004" /* ...... */ + $"FF00 00FF 00FE FF02 00FF FFFE 00FF FFFF" /* ...... */ + $"00FE FFFF 00FE FFF4 0004 FF00 00FF FFFE" /* ...... */ + $"00FF FFFF 00FE FFFA 0000 FFFE 0008 FF00" /* ....... */ + $"FFFF 0000 FFFF 000D 00FF 00FF FF00 FF00" /* ........ */ + $"FFFF 0000 FFFF FC00 02FF 00FF FE00 0AFF" /* ...... */ + $"0000 FF00 FF00 00FF 0000 FEFF FE00 FFFF" /* ........ */ + $"FF00 05FF 00FF FF00 00FE FFF9 0000 FFFE" /* ....... */ + $"0006 FF00 00FF FF00 00FE FFFC 0000 FFFE" /* ........ */ + $"0005 FF00 FF00 00FF FE00 FEFF FF00 FFFF" /* ....... */ + $"E700 EE00 07FF 2BFC 2A2A F52B FFFA 0007" /* ...+**+.. */ + $"FF2B FC2A 2AF5 2BFF E300 00FA E700 02FF" /* +**+.... */ + $"2BFC FEF5 012B FFFA 0002 FF2B FCFE F501" /* +.+..+. */ + $"2BFF FB00 F400 FEFD 00ED FEF5 F800 00FF" /* +..... */ + $"FE00 03FF 0000 FFFD 0005 FF00 00FF 00FF" /* ......... */ + $"FC00 FDFF FF00 FFFF FD00 12FF 00FF 0000" /* ....... */ + $"FF00 FF00 FF00 00FF 0000 FF00 00FF FD00" /* ......... */ + $"0AFF 00FF 0000 FF00 FF00 00FF F500 05FF" /* ........ */ + $"00FF 0000 FFFD 0006 FF00 FF00 00FF 00FD" /* ......... */ + $"FF00 00FD FFFE 0005 FF00 FF00 00FF 0200" /* ......... */ + $"FFFF FE00 FFFF FE00 03FF 0000 FFFD 00FF" /* ...... */ + $"FFFD 0016 FF00 00FF 00FF 0000 FF00 00FF" /* ......... */ + $"0000 FF00 FF00 00FF 00FF FFFE 0000 FFF6" /* ........ */ + $"0000 FFFE 0000 FFFD 0005 FF00 FF00 00FF" /* ......... */ + $"FD00 FCFF 0F00 FF00 00FF 0000 FF00 00FF" /* ......... */ + $"00FF 0000 FFE8 00EE 0002 FF2B FCFE F501" /* ......+. */ + $"2BFF FA00 02FF 2BFC FEF5 012B FFE3 0000" /* +..+.+.. */ + $"FAE7 0000 FFFB 2B00 FFFA 0000 FFFB 2B00" /* ..+...+. */ + $"FFFB 00F4 00FE FD00 DFFE F5F8 0000 FFFE" /* ..... */ + $"0005 FF00 00FF 0000 FEFF FF00 02FF 00FF" /* ......... */ + $"FC00 00FF FE00 02FF 00FF FC00 08FF 00FF" /* ........ */ + $"0000 FF00 FFFF FE00 08FF 0000 FF00 00FF" /* ......... */ + $"0000 FEFF 0900 FF00 00FF 00FF 0000 FFF9" /* ........ */ + $"0000 FFFE 0001 FF00 FDFF FF00 FEFF 0400" /* ........ */ + $"FF00 00FF FB00 00FF FB00 01FF 00FD FF01" /* ........ */ + $"00FF FD00 00FF FD00 FDFF FD00 02FF 00FF" /* ....... */ + $"FE00 0FFF 0000 FF00 FF00 00FF 0000 FF00" /* .......... */ + $"00FF 00FD FF01 00FF FC00 FFFF F800 00FF" /* ....... */ + $"FE00 02FF 0000 FEFF 0400 FF00 00FF FD00" /* ......... */ + $"00FF FE00 0CFF 00FF 0000 FF00 00FF 0000" /* .......... */ + $"FF00 FDFF E800 EE00 00FF FB2B 00FF FA00" /* ....+.. */ + $"00FF FB2B 00FF E300 00FA E900 F5FF FE00" /* .+..... */ + $"F5FF FDFA F400 FEFD 00E7 FEF5 F800 00FF" /* .... */ + $"FE00 08FF 0000 FF00 FF00 00FF FE00 00FF" /* ......... */ + $"FB00 00FF FE00 02FF 00FF FC00 21FF 00FF" /* ......!. */ + $"0000 FF00 FF00 FF00 00FF 0000 FF00 00FF" /* .......... */ + $"00FF 0000 FF00 FF00 00FF 00FF 0000 FFF9" /* ......... */ + $"0000 FFFE 0002 FF00 FFFD 0008 FF00 00FF" /* ......... */ + $"00FF 0000 FFFB 0000 FFFB 0002 FF00 FFFE" /* ........ */ + $"0001 00FF FD00 00FF FD00 00FF FA00 16FF" /* ......... */ + $"0000 FF00 00FF 0000 FF00 FF00 00FF 0000" /* ........... */ + $"FF00 00FF 00FF FD00 00FF FA00 00FF F900" /* ........ */ + $"0EFF 0000 FF00 00FF 0000 FF00 FF00 00FF" /* .......... */ + $"FD00 00FF FE00 0DFF 00FF 0000 FF00 00FF" /* ......... */ + $"0000 FF00 FFE5 00F0 00F5 FFFE 00F5 FFFD" /* ...... */ + $"FAE9 0000 FAE9 0000 FFF9 2B02 D82B FFFE" /* ....+.+ */ + $"FA00 FFF9 2B02 D82B FFFE 0000 FAF4 00FE" /* .+.+... */ + $"FD00 EDFE F5F7 00FE FFFE 0002 FF00 00FE" /* ...... */ + $"FFFE 0000 FFFB 00FD FFFF 0000 FFFC 0014" /* ....... */ + $"FF00 FF00 00FF 00FF 0000 FF00 FF00 00FF" /* ......... */ + $"0000 FF00 00FE FF09 00FF 0000 FF00 FF00" /* ......... */ + $"00FF FE00 00FF FC00 FEFF FE00 FFFF FE00" /* ...... */ + $"FEFF 0400 FF00 00FF FB00 00FF FB00 05FF" /* ........ */ + $"0000 FFFF 0001 00FF FD00 00FF FC00 FFFF" /* ........ */ + $"FC00 00FF FE00 02FF 0000 FEFF FF00 FEFF" /* ....... */ + $"FF00 FEFF FE00 FFFF FF00 00FF FD00 FEFF" /* ..... */ + $"FD00 00FF FD00 FEFF FD00 FEFF 0400 FF00" /* ....... */ + $"00FF FD00 00FF FE00 02FF 0000 FEFF FE00" /* ........ */ + $"FEFF FF00 FFFF FD00 00FF EC00 F000 00FF" /* ...... */ $"F92B 02D8 2BFF FEFA 00FF F92B 02D8 2BFF" /* +.+.+.+ */ - $"FE00 00FA F400 FEFD 003A FEF5 8400 8100" /* ....:.. */ - $"F000 00FF F92B 02D8 2BFF FEFA 00FF F92B" /* ..+.+.+ */ - $"02D8 2BFF FE00 00FA E900 00FA E900 00FF" /* .+...... */ - $"F72B 00FF FE00 00FF F72B 00FF FE00 00FA" /* +...+... */ - $"F400 FEFD 002E FEF5 8400 8100 F000 00FF" /* ....... */ - $"F72B 00FF FE00 00FF F72B 00FF FE00 00FA" /* +...+... */ - $"E900 00FA E900 F5FF FE00 F5FF FE00 00FA" /* ...... */ - $"F400 FEFD 004A FEF5 F700 FEFF FF00 FFFF" /* ..J.. */ - $"F200 FDFF F900 00FF FB00 00FF DB00 00FF" /* ....... */ - $"EC00 FDFF FE00 00FF FC00 EE00 00FF FE00" /* ....... */ - $"00FF DA00 FEFF C300 F000 F5FF FE00 F5FF" /* ..... */ - $"FE00 00FA E900 00FA CB00 00FA F400 FEFD" /* ....... */ - $"004B FEF5 F800 00FF FE00 03FF 0000 FFF2" /* .K...... */ - $"0000 FFFE 0000 FFF3 0000 FFDB 0000 FFEC" /* ........ */ - $"0000 FFFE 0000 FFF9 00EE 0003 FF00 00FF" /* ......... */ - $"D900 03FF 0000 FFC4 00D2 0000 FAE9 0000" /* ......... */ - $"FAE0 00F6 FFF7 0000 FAF4 00FE FD00 CDFE" /* ..... */ - $"F5F8 0000 FFFE 000A FF00 00FF 0000 FFFF" /* ....... */ - $"0000 FFFE 0000 FFFD 0000 FFFE 0009 FF00" /* ........ */ - $"FF00 FFFF 00FF FF00 FEFF FF00 04FF 0000" /* ....... */ - $"FF00 FEFF 0200 FFFF FE00 FFFF FF00 FEFF" /* ..... */ - $"FF00 FEFF F400 04FF 0000 FFFF FE00 FFFF" /* ...... */ - $"FF00 FEFF FA00 00FF FE00 08FF 00FF FF00" /* ....... */ - $"00FF FF00 0D00 FF00 FFFF 00FF 00FF FF00" /* ........ */ - $"00FF FFFC 0002 FF00 FFFE 000A FF00 00FF" /* ....... */ - $"00FF 0000 FF00 00FE FFFE 00FF FFFF 0005" /* ........ */ - $"FF00 FFFF 0000 FEFF F900 00FF FE00 06FF" /* ....... */ - $"0000 FFFF 0000 FEFF CE00 E700 F6FF F700" /* ....... */ - $"00FA E900 00FA E000 0AFF F9FC F9FC F9FC" /* .... */ - $"F9FC F9FF F700 00FA F400 FEFD 00D4 FEF5" /* .... */ - $"F800 00FF FE00 03FF 0000 FFFD 0005 FF00" /* ......... */ - $"00FF 00FF FC00 FDFF FF00 FFFF FD00 12FF" /* ...... */ - $"00FF 0000 FF00 FF00 FF00 00FF 0000 FF00" /* .......... */ - $"00FF FD00 0AFF 00FF 0000 FF00 FF00 00FF" /* ........ */ - $"F500 05FF 00FF 0000 FFFD 0006 FF00 FF00" /* ......... */ - $"00FF 00FD FF00 00FD FFFE 0005 FF00 FF00" /* ........ */ - $"00FF 0200 FFFF FE00 FFFF FE00 03FF 0000" /* ........ */ - $"FFFD 00FF FFFD 0016 FF00 00FF 00FF 0000" /* ........ */ - $"FF00 00FF 0000 FF00 FF00 00FF 00FF FFFE" /* ........ */ - $"0000 FFF6 0000 FFFE 0000 FFFD 0005 FF00" /* ......... */ - $"FF00 00FF CF00 E700 0AFF F9FC F9FC F9FC" /* .... */ - $"F9FC F9FF F700 00FA E900 00FA E000 0AFF" /* ..... */ - $"F9FC F9FC F9FC F9FC F9FF F700 00FA F400" /* ... */ - $"FEFD 00D3 FEF5 F800 00FF FE00 05FF 0000" /* ....... */ - $"FF00 00FE FFFF 0002 FF00 FFFC 0000 FFFE" /* ....... */ - $"0002 FF00 FFFC 0008 FF00 FF00 00FF 00FF" /* ......... */ - $"FFFE 0008 FF00 00FF 0000 FF00 00FE FF09" /* ........ */ - $"00FF 0000 FF00 FF00 00FF F900 00FF FE00" /* ......... */ - $"01FF 00FD FFFF 00FE FF04 00FF 0000 FFFB" /* ....... */ - $"0000 FFFB 0001 FF00 FDFF 0100 FFFD 0000" /* ......... */ - $"FFFD 00FD FFFD 0002 FF00 FFFE 000F FF00" /* ....... */ - $"00FF 00FF 0000 FF00 00FF 0000 FF00 FDFF" /* ......... */ - $"0100 FFFC 00FF FFF8 0000 FFFE 0002 FF00" /* ........ */ - $"00FE FF04 00FF 0000 FFCF 00E7 000A FFF9" /* ....... */ - $"FCF9 FCF9 FCF9 FCF9 FFF7 0000 FAE9 0000" /* .... */ - $"FAE0 000A FFF9 FCF9 FCF9 FCF9 FCF9 FFF7" /* . */ - $"0000 FAF4 00FE FD00 D4FE F5F8 0000 FFFE" /* ...... */ - $"0008 FF00 00FF 00FF 0000 FFFE 0000 FFFB" /* ......... */ - $"0000 FFFE 0002 FF00 FFFC 0021 FF00 FF00" /* ......!.. */ - $"00FF 00FF 00FF 0000 FF00 00FF 0000 FF00" /* .......... */ - $"FF00 00FF 00FF 0000 FF00 FF00 00FF F900" /* ......... */ - $"00FF FE00 02FF 00FF FD00 08FF 0000 FF00" /* ......... */ - $"FF00 00FF FB00 00FF FB00 02FF 00FF FE00" /* ........ */ - $"0100 FFFD 0000 FFFD 0000 FFFA 0016 FF00" /* ......... */ - $"00FF 0000 FF00 00FF 00FF 0000 FF00 00FF" /* .......... */ - $"0000 FF00 FFFD 0000 FFFA 0000 FFF9 000E" /* ......... */ - $"FF00 00FF 0000 FF00 00FF 00FF 0000 FFCF" /* ......... */ + $"FE00 00FA E900 00FA E900 00FF F72B 00FF" /* ......+. */ + $"FE00 00FF F72B 00FF FE00 00FA F400 FEFD" /* ..+.... */ + $"0045 FEF5 B000 00FF D600 E000 03FF 0000" /* .E....... */ + $"FFEC 0000 FFE1 0000 FFF3 0000 FFEC 00F0" /* ....... */ + $"0000 FFF7 2B00 FFFE 0000 FFF7 2B00 FFFE" /* ..+...+. */ + $"0000 FAE9 0000 FAE9 00F5 FFFE 00F5 FFFE" /* ...... */ + $"0000 FAF4 00FE FD00 36FE F5B1 0000 FFD5" /* ....6.. */ + $"00E2 00FF FFFE 0000 FFED 0000 FFE2 00FF" /* ....... */ + $"FFF3 0000 FFEB 00F0 00F5 FFFE 00F5 FFFE" /* ..... */ + $"0000 FAE9 0000 FACB 0000 FAF4 00FE FD00" /* ........ */ + $"1AFE F584 0081 00D2 0000 FAE9 0000 FAE0" /* ....... */ + $"00F6 FFF7 0000 FAF4 00FE FD00 28FE F584" /* .....( */ + $"0081 00E7 00F6 FFF7 0000 FAE9 0000 FAE0" /* ....... */ + $"000A FFF9 FCF9 FCF9 FCF9 FCF9 FFF7 0000" /* ... */ + $"FAF4 00FE FD00 32FE F584 0081 00E7 000A" /* ..2... */ + $"FFF9 FCF9 FCF9 FCF9 FCF9 FFF7 0000 FAE9" /* .. */ + $"0000 FAE0 000A FFF9 FCF9 FCF9 FCF9 FCF9" /* ... */ + $"FFF7 0000 FAF4 00FE FD00 75FE F5F8 00FD" /* ....u. */ + $"FFEF 0000 FFFB 00FE FFFA 0000 FFE3 00FE" /* ...... */ + $"FFF5 00FF FFFD 00FD FFFA 00FF FF02 00FF" /* ..... */ + $"FFF9 0000 FFFE FFFA 0000 FFF8 00FD FFF8" /* ..... */ + $"00FE FFF4 0000 FFFE 0000 FFF4 0003 FF00" /* ........ */ + $"00FF C800 E700 0AFF F9FC F9FC F9FC F9FC" /* ... */ + $"F9FF F700 00FA E900 00FA E000 0AFF F9FC" /* ..... */ + $"F9FC F9FC F9FC F9FF F700 00FA F400 FEFD" /* ... */ + $"0083 FEF5 F800 00FF FE00 00FF F000 00FF" /* ....... */ + $"FC00 00FF FE00 00FF FB00 00FF E400 00FF" /* ........ */ + $"FE00 00FF F500 00FF FD00 00FF FE00 00FF" /* ........ */ + $"FA00 03FF 0000 FFF9 0000 FFED 0000 FFFE" /* ........ */ + $"0000 FFFA 0000 FFFE 0000 FFF5 0000 FFFE" /* ........ */ + $"0000 FFF4 0000 FFC5 00E7 000A FFF9 FCF9" /* ...... */ + $"FCF9 FCF9 FCF9 FFF7 0000 FAE9 0000 FAE0" /* .... */ + $"000A FFF9 FCF9 FCF9 FCF9 FCF9 FFF7 0000" /* ... */ + $"FAF4 00FE FD00 C6FE F5F8 0000 FFFE 000B" /* ...... */ + $"FF00 FF00 FFFF 0000 FFFF 0000 FEFF FF00" /* ....... */ + $"FEFF FD00 00FF FB00 FFFF FF00 FEFF FF00" /* ..... */ + $"00FF FC00 06FF 0000 FFFF 0000 FEFF F800" /* ........ */ + $"00FF FB00 FFFF FF00 06FF 00FF FF00 00FF" /* ....... */ + $"FD00 00FF FE00 04FF 0000 FFFF FE00 03FF" /* ........ */ + $"0000 FFF9 0000 FFFD 000A FF00 FFFF 00FF" /* ....... */ + $"FF00 00FF FFFC 0000 FFFE 0000 FFFA 0000" /* ........ */ + $"FFFB 00FF FFFE 00FF FFFF 00FE FF00 00FE" /* ..... */ + $"FFF5 0004 FF00 FFFF 00FE FF02 00FF FFCF" /* ...... */ $"00E7 000A FFF9 FCF9 FCF9 FCF9 FCF9 FFF7" /* .. */ $"0000 FAE9 0000 FAE0 000A FFF9 FCF9 FCF9" /* ..... */ - $"FCF9 FCF9 FFF7 0000 FAF4 00FE FD00 CDFE" /* .... */ - $"F5F7 00FE FFFE 0002 FF00 00FE FFFE 0000" /* ....... */ - $"FFFB 00FD FFFF 0000 FFFC 0014 FF00 FF00" /* ....... */ - $"00FF 00FF 0000 FF00 FF00 00FF 0000 FF00" /* .......... */ - $"00FE FF09 00FF 0000 FF00 FF00 00FF FE00" /* ........ */ - $"00FF FC00 FEFF FE00 FFFF FE00 FEFF 0400" /* ...... */ - $"FF00 00FF FB00 00FF FB00 05FF 0000 FFFF" /* ........ */ - $"0001 00FF FD00 00FF FC00 FFFF FC00 00FF" /* ........ */ - $"FE00 02FF 0000 FEFF FF00 FEFF FF00 FEFF" /* ...... */ - $"FE00 FFFF FF00 00FF FD00 FEFF FD00 00FF" /* ...... */ - $"FD00 FEFF FD00 FEFF 0400 FF00 00FF CF00" /* ....... */ - $"E700 0AFF F9FC F9FC F9FC F9FC F9FF F700" /* .. */ - $"00FA E900 00FA E000 0AFF F9FC F9FC F9FC" /* .... */ - $"F9FC F9FF F700 00FA F400 FEFD 003D FEF5" /* ....= */ - $"B000 00FF D600 E000 03FF 0000 FFEC 0000" /* ......... */ - $"FFBC 00E7 000A FFF9 FCF9 FCF9 FCF9 FCF9" /* .. */ - $"FFF7 00E7 FAE0 000A FFF9 FCF9 FCF9 FCF9" /* .. */ - $"FCF9 FFF7 0000 FAF4 00FE FD00 34FE F5B1" /* ....4 */ - $"0000 FFD5 00E2 00FF FFFE 0000 FFED 0000" /* ........ */ - $"FFBB 00E7 000A FFF9 FCF9 FCF9 FCF9 FCF9" /* .. */ - $"FFF7 0000 FACA 00F0 FFFA FA00 00F4 00FE" /* ...... */ - $"FD00 1CFE F584 0081 00EA 00F0 FFFA FAC9" /* ..... */ + $"FCF9 FCF9 FFF7 0000 FAF4 00FE FD00 C0FE" /* .... */ + $"F5F8 00FD FFFF 00FF FFFE 000B FF00 00FF" /* ...... */ + $"00FF 0000 FF00 00FF FB00 FEFF FF00 0FFF" /* ........ */ + $"0000 FF00 FF00 00FF 0000 FF00 FF00 FFFC" /* ......... */ + $"0005 FF00 FF00 00FF F900 00FF F900 03FF" /* ......... */ + $"00FF FFFD 0000 FFFD 00FD FFFF 0009 FF00" /* ...... */ + $"00FF 0000 FF00 00FF F900 00FF FFFF FF00" /* ........ */ + $"FFFF FD00 05FF 00FF 0000 FFFD 00FD FFF8" /* ...... */ + $"00FE FFFF 000B FF00 00FF 00FF 0000 FF00" /* ......... */ + $"00FF FE00 00FF F400 0BFF 0000 FF00 FF00" /* ......... */ + $"00FF 0000 FFD0 00E7 000A FFF9 FCF9 FCF9" /* ..... */ + $"FCF9 FCF9 FFF7 00E7 FAE0 000A FFF9 FCF9" /* .. */ + $"FCF9 FCF9 FCF9 FFF7 0000 FAF4 00FE FD00" /* .... */ + $"B1FE F5F8 0000 FFFE 0002 FF00 FFFD 00FD" /* ...... */ + $"FF07 00FF 0000 FF00 00FF F800 02FF 00FF" /* ......... */ + $"FD00 0AFF 0000 FF00 00FF 00FF 00FF FE00" /* ........ */ + $"FEFF 0400 FF00 00FF F900 00FF FB00 FEFF" /* ....... */ + $"0100 FFFC 0000 FFFD 0000 FFFE 0001 FF00" /* ......... */ + $"FDFF FF00 03FF 0000 FFF9 0000 FFFD 0000" /* ........ */ + $"FFFC 0002 FF00 FFFA 0000 FFF2 0002 FF00" /* ........ */ + $"FFFD 0006 FF00 00FF 0000 FFFE 0000 FFF8" /* ........ */ + $"0000 FFFE 000B FF00 00FF 00FF 0000 FF00" /* .......... */ + $"00FF D000 E700 0AFF F9FC F9FC F9FC F9FC" /* ... */ + $"F9FF F700 00FA CA00 F0FF FAFA 0000 F400" /* ...... */ + $"FEFD 00BB FEF5 F800 00FF FE00 02FF 00FF" /* ...... */ + $"FD00 00FF FD00 06FF 0000 FF00 00FF FC00" /* ......... */ + $"00FF FE00 0AFF 00FF 0000 FF00 FF00 00FF" /* ........ */ + $"FE00 02FF 00FF FE00 08FF 0000 FF00 FF00" /* ......... */ + $"00FF F900 00FF FE00 07FF 00FF 0000 FF00" /* ......... */ + $"FFFC 0000 FFFD 0000 FFFE 0002 FF00 FFFC" /* ....... */ + $"0003 FF00 00FF F900 00FF FD00 00FF FC00" /* ......... */ + $"05FF 00FF 0000 FFFD 0000 FFF6 0000 FFFE" /* ........ */ + $"000D FF00 FF00 00FF 00FF 0000 FF00 00FF" /* .......... */ + $"FE00 00FF F800 00FF FE00 0BFF 0000 FF00" /* ......... */ + $"FF00 00FF 0000 FFD0 00EA 00F0 FFFA FAC9" /* ...... */ $"0000 FFF2 F900 FFFA 0000 FAF4 00FE FD00" /* ....... */ - $"22FE F584 0081 00EA 0000 FFF2 F900 FFFA" /* "..... */ - $"0000 FACA 0000 FFF2 F900 FFFA 0000 FAF4" /* ....... */ - $"00FE FD00 1EFE F584 0081 00EA 0000 FFF2" /* ....... */ - $"F900 FFFA 0000 FACA 00F0 FFFA 0000 FAF4" /* ...... */ - $"00FE FD00 5CFE F5F8 0000 FFFE 0000 FFF7" /* ..\.... */ - $"0000 FFF4 00FD FFEF 0000 FFFB 00FE FFFA" /* ...... */ - $"0000 FFE3 00FE FFF5 00FF FFFD 00FD FFFA" /* ..... */ - $"00FF FF02 00FF FFF9 00FD FFFA 0000 FFF8" /* ...... */ - $"00FD FFF8 00FE FFF4 0000 FFFE 0000 FFD4" /* ...... */ - $"00EA 00F0 FFFA 0000 FAB2 0000 FAF4 00FE" /* ....... */ - $"FD00 81FE F5F8 0000 FFFE 0000 FFF7 0000" /* ....... */ - $"FFF4 0000 FFFE 0000 FFF0 0000 FFFC 0000" /* ........ */ - $"FFFE 0000 FFFB 0000 FFE4 0000 FFFE 0000" /* ........ */ - $"FFF5 0000 FFFD 0000 FFFE 0000 FFFA 0003" /* ........ */ - $"FF00 00FF F900 00FF ED00 00FF FE00 00FF" /* ........ */ - $"FA00 00FF FE00 00FF F500 00FF FE00 00FF" /* ........ */ - $"D400 D200 00FA D000 00F9 FCFF 00F9 FD00" /* ....... */ - $"00F9 FCFF 00F9 FD00 00F9 FCFF 02F9 00FA" /* ...... */ - $"F400 FEFD 00D9 FEF5 F800 00FF FE00 05FF" /* ...... */ - $"00FF 0000 FFFE 00FE FFFF 00FF FFF8 0000" /* ....... */ - $"FFFE 000B FF00 FF00 FFFF 0000 FFFF 0000" /* ........ */ - $"FEFF FF00 FEFF FD00 00FF FB00 FFFF FF00" /* ..... */ - $"FEFF FF00 00FF FC00 06FF 0000 FFFF 0000" /* ........ */ - $"FEFF F800 00FF FB00 FFFF FF00 06FF 00FF" /* ...... */ - $"FF00 00FF FD00 00FF FE00 04FF 0000 FFFF" /* ........ */ - $"FE00 03FF 0000 FFF9 0000 FFFD 000A FF00" /* ........ */ - $"FFFF 00FF FF00 00FF FFFC 0000 FFFE 0000" /* ....... */ - $"FFFA 0000 FFFB 00FF FFFE 00FF FFFF 00FE" /* ..... */ - $"FF00 00FE FFD5 00F0 0000 F9FC FF00 F9FD" /* ...... */ - $"0000 F9FC FF00 F9FD 0000 F9FC FF02 F900" /* ....... */ - $"FAD0 0000 FFFC 2B00 FFFD 0000 FFFC 2B00" /* ..+...+. */ - $"FFFD 0000 FFFC 2B02 FF00 FAF4 00FE FD00" /* ..+.... */ - $"DAFE F5F8 00FC FF0F 00FF 0000 FF00 00FF" /* ....... */ - $"0000 FF00 FF00 00FF F900 FDFF FF00 FFFF" /* ....... */ - $"FE00 0BFF 0000 FF00 FF00 00FF 0000 FFFB" /* ......... */ - $"00FE FFFF 000F FF00 00FF 00FF 0000 FF00" /* ......... */ - $"00FF 00FF 00FF FC00 05FF 00FF 0000 FFF9" /* ........ */ - $"0000 FFF9 0003 FF00 FFFF FD00 00FF FD00" /* ........ */ - $"FDFF FF00 09FF 0000 FF00 00FF 0000 FFF9" /* ....... */ - $"00FE FFFF 00FF FFFD 0005 FF00 FF00 00FF" /* ....... */ - $"FD00 FDFF F800 FEFF FF00 0BFF 0000 FF00" /* ....... */ - $"FF00 00FF 0000 FFFE 0000 FFD4 00F0 0000" /* ......... */ - $"FFFC 2B00 FFFD 0000 FFFC 2B00 FFFD 0000" /* +...+... */ - $"FFFC 2B02 FF00 FAD0 0006 FF2B FCFC F52B" /* +....++ */ - $"FFFD 0006 FF2B FCFC F52B FFFD 0008 FF2B" /* ..++..+ */ - $"FCFC F52B FF00 FAF4 00FE FD00 DAFE F5F8" /* +... */ - $"0000 FFFE 000C FF00 FF00 00FF 0000 FF00" /* .......... */ - $"00FF 00FD FFF9 0000 FFFE 0002 FF00 FFFD" /* ....... */ - $"00FD FF07 00FF 0000 FF00 00FF F800 02FF" /* ......... */ - $"00FF FD00 0AFF 0000 FF00 00FF 00FF 00FF" /* ........ */ - $"FE00 FEFF 0400 FF00 00FF F900 00FF FB00" /* ........ */ - $"FEFF 0100 FFFC 0000 FFFD 0000 FFFE 0001" /* ........ */ - $"FF00 FDFF FF00 03FF 0000 FFF9 0000 FFFD" /* ....... */ - $"0000 FFFC 0002 FF00 FFFA 0000 FFF2 0002" /* ......... */ - $"FF00 FFFD 0006 FF00 00FF 0000 FFFE 0000" /* ......... */ - $"FFD4 00F0 0006 FF2B FCFC F52B FFFD 0006" /* ...++.. */ - $"FF2B FCFC F52B FFFD 0008 FF2B FCFC F52B" /* ++..++ */ - $"FF00 FAD0 0006 FF2B FC2A F52B FFFD 0006" /* ...+*+.. */ - $"FF2B FC2A F52B FFFD 0008 FF2B FC2A F52B" /* +*+..+*+ */ - $"FFFA FAF4 00FE FD00 EBFE F5F8 0000 FFFE" /* .... */ - $"000D FF00 FF00 00FF 0000 FF00 00FF 00FF" /* .......... */ - $"F600 00FF FE00 02FF 00FF FD00 00FF FD00" /* ........ */ - $"06FF 0000 FF00 00FF FC00 00FF FE00 0AFF" /* ........ */ - $"00FF 0000 FF00 FF00 00FF FE00 02FF 00FF" /* ......... */ - $"FE00 08FF 0000 FF00 FF00 00FF F900 00FF" /* ......... */ - $"FE00 07FF 00FF 0000 FF00 FFFC 0000 FFFD" /* ........ */ - $"0000 FFFE 0002 FF00 FFFC 0003 FF00 00FF" /* ......... */ - $"F900 00FF FD00 00FF FC00 05FF 00FF 0000" /* ......... */ - $"FFFD 0000 FFF6 0000 FFFE 000D FF00 FF00" /* ........ */ - $"00FF 00FF 0000 FF00 00FF FE00 00FF D400" /* ......... */ - $"F000 06FF 2BFC 2AF5 2BFF FD00 06FF 2BFC" /* ..+*+..+ */ - $"2AF5 2BFF FD00 08FF 2BFC 2AF5 2BFF FAFA" /* *+..+*+ */ - $"D000 06FF 2BFC 2AF5 2BFF FDFA 06FF 2BFC" /* ..+*+.+ */ - $"2AF5 2BFF FDFA 08FF 2BFC 2AF5 2BFF 0000" /* *+.+*+.. */ - $"F400 FEFD 00E9 FEF5 F800 00FF FE00 02FF" /* ...... */ - $"0000 FEFF FE00 FEFF FF00 FFFF FD00 00FF" /* ...... */ - $"FD00 FDFF FF00 00FF FC00 FFFF FF00 03FF" /* ...... */ - $"0000 FFFE 0000 FFFC 00FE FFFE 00FF FFFF" /* ...... */ - $"0003 FF00 00FF FE00 02FF 00FF FD00 FEFF" /* ........ */ - $"0400 FF00 00FF FE00 00FF FC00 FEFF FE00" /* ........ */ - $"FEFF 0100 FFFC 0000 FFFD 00FD FFFE 00FF" /* ...... */ - $"FFFE 0003 FF00 00FF FE00 00FF FD00 FDFF" /* ....... */ - $"0100 FFFC 0004 FF00 00FF FFFC 0000 FFFB" /* ........ */ - $"0000 FFFC 00FE FFFE 00FF FFFE 00FF FFFD" /* ..... */ - $"0000 FFFE 0000 FFFE 0000 FFD9 00F0 0006" /* ......... */ - $"FF2B FC2A F52B FFFD FA06 FF2B FC2A F52B" /* +*+.+*+ */ - $"FFFD FA06 FF2B FC2A F52B FFCE 0001 FF2B" /* .+*+..+ */ - $"FEF5 012B FFFD 0001 FF2B FEF5 012B FFFD" /* .+..+.+ */ - $"0001 FF2B FEF5 032B FF00 00F4 00FE FD00" /* ..+.+.... */ - $"5CFE F5EF 0000 FFF3 0000 FFBD 0000 FFEB" /* \...... */ - $"00EA 0000 FFC2 0000 FFD9 00F0 0001 FF2B" /* ........+ */ - $"FEF5 012B FFFD 0001 FF2B FEF5 012B FFFD" /* .+..+.+ */ - $"0001 FF2B FEF5 012B FFCE 0006 FFE3 2BFC" /* ..+.+..+ */ - $"FC2B FFFD 0006 FFE3 2BFC FC2B FFFD 0008" /* +..++.. */ - $"FFE3 2BFC FC2B FF00 00F4 00FE FD00 56FE" /* ++....V */ - $"F5F1 00FF FFF3 0000 FFBD 0000 FFEA 00EB" /* ...... */ - $"0000 FFC2 0000 FFD8 00F0 0006 FFE3 2BFC" /* .......+ */ - $"FC2B FFFD 0006 FFE3 2BFC FC2B FFFD 0006" /* +..++.. */ - $"FFE3 2BFC FC2B FFCE 0000 FFFC 2B00 FFFD" /* ++..+. */ - $"0000 FFFC 2B00 FFFD 0000 FFFC 2B02 FF00" /* ..+...+.. */ - $"00F4 00FE FD00 30FE F584 0081 00F0 0000" /* ...0.... */ - $"FFFC 2B00 FFFD 0000 FFFC 2B00 FFFD 0000" /* +...+... */ - $"FFFC 2B00 FFCD 00FC FFFB 00FC FFFB 00FC" /* +.... */ - $"FFFE 00F4 00FE FD00 18FE F584 0081 00EF" /* ...... */ - $"00FC FFFB 00FC FFFB 00FC FFAE 00F4 00FE" /* ..... */ - $"FD00 0CFE F584 0081 0081 00F4 00FE FD00" /* ....... */ - $"39FE F5F4 0003 FF00 00FF F500 00FF FC00" /* 9....... */ - $"00FF FA00 00FF FE00 03FF 0000 FFE1 0000" /* ......... */ - $"FFF6 0000 FFE9 00FD FF00 00FA 0003 FF00" /* ........ */ - $"FFFF 8C00 8100 F400 FEFD 0035 FEF5 F400" /* ....5. */ - $"00FF F200 FFFF FE00 FFFF FA00 00FF FE00" /* ...... */ - $"03FF 0000 FFE1 0000 FFF6 0000 FFE9 0000" /* ......... */ - $"FFFE 0000 FFF7 0000 FF8C 0081 00F4 00FE" /* ....... */ - $"FD00 7EFE F5F4 0004 FF00 FFFF 00FE FF02" /* .~..... */ - $"00FF FFFC 000C FF00 FF00 FF00 FF00 00FF" /* ........ */ - $"FF00 00FE FF00 00FE FF00 00FE FFFE 00FF" /* ....... */ - $"FFFF 0000 FFFC 0002 FF00 00FE FFF7 0004" /* ........ */ - $"FF00 FF00 00FE FFFE 00FE FF08 00FF 00FF" /* ....... */ - $"FF00 00FF FFFE 00FF FFFE 00FE FFFD 0000" /* ...... */ - $"FFFE 0000 FF10 00FF 00FF FF00 FFFF 0000" /* ........ */ - $"FF00 00FF FF00 00FE FF95 0081 00F4 00FE" /* ....... */ - $"FD00 7FFE F5F4 000B FF00 00FF 00FF 0000" /* ......... */ - $"FF00 00FF FD00 06FF 0000 FF00 00FF FD00" /* ......... */ - $"03FF 0000 FFFE 0015 FF00 00FF 0000 FF00" /* .......... */ - $"FF00 00FF 0000 FF00 FF00 FF00 00FF F400" /* ......... */ - $"10FF 00FF 0000 FF00 00FF 00FF 0000 FF00" /* .......... */ - $"FFFF FE00 03FF 0000 FFFD 0002 FF00 FFFA" /* ....... */ - $"00FD FF00 0002 00FF FFFD 000D FF00 00FF" /* ......... */ - $"00FF 0000 FF00 FF00 00FF 9600 8100 F400" /* ......... */ - $"FEFD 007D FEF5 F800 00FF FE00 0BFF 0000" /* .}...... */ - $"FF00 FF00 00FF 0000 FFFD 0000 FFFC 0002" /* ......... */ - $"FF00 00FE FFFF 0000 FFFE 0007 FF00 00FF" /* ........ */ - $"0000 FF00 FDFF FF00 04FF 00FF 00FF FE00" /* ........ */ - $"FFFF F700 FCFF 0B00 FF00 00FF 00FF 0000" /* ........ */ - $"FF00 FFFD 00FD FFFF 00FE FFFF 00FF FFFC" /* .... */ - $"0000 FFFD 0001 00FF FC00 0DFF 0000 FF00" /* .......... */ - $"FF00 00FF 00FF 0000 FF96 0081 00F4 00FE" /* ........ */ - $"FD00 80FE F5F8 0000 FFFE 000B FF00 00FF" /* ....... */ - $"00FF 0000 FF00 00FF FD00 00FF FC00 08FF" /* ......... */ - $"00FF 0000 FF00 00FF FE00 08FF 0000 FF00" /* .......... */ - $"00FF 00FF FB00 02FF 00FF FB00 00FF F800" /* ........ */ - $"00FF FE00 0CFF 00FF 0000 FF00 FF00 00FF" /* ......... */ - $"00FF FD00 00FF FD00 03FF 0000 FFFD 0000" /* ......... */ - $"FFFD 0000 FFFD 0001 00FF FC00 0DFF 0000" /* ......... */ - $"FF00 FF00 00FF 00FF 0000 FF96 0081 00F4" /* ........ */ - $"00FE FD00 7DFE F5F7 00FE FFFE 0008 FF00" /* ..}.... */ - $"FF00 00FF 0000 FFFD 0000 FFFC 0002 FF00" /* ......... */ - $"00FE FFFE 0000 FFFE 0009 FF00 FF00 00FF" /* ....... */ - $"0000 FFFF FD00 02FF 00FF FE00 FEFF FD00" /* ....... */ - $"00FF FC00 00FF FE00 07FF 00FF 0000 FF00" /* ......... */ - $"00FE FF01 00FF FC00 FFFF FE00 FEFF 0000" /* ....... */ - $"FEFF FC00 00FF FD00 0100 FFFC 0009 FF00" /* ....... */ - $"00FF 0000 FFFF 0000 FEFF 9500 8100 F400" /* ........ */ - $"FEFD 0014 FEF5 B600 00FF D000 F000 00FF" /* ....... */ - $"9300 8100 F400 FEFD 0014 FEF5 B700 00FF" /* ....... */ - $"CF00 F000 00FF 9300 8100 F400 FEFD 000C" /* ........ */ - $"FEF5 8400 8100 8100 F400 FEFD 000C FEF5" /* ...... */ - $"8400 8100 8100 F400 FEFD 000C FEF5 8400" /* ....... */ - $"8100 8100 F400 FEFD 000C FEF5 8400 8100" /* ....... */ - $"8100 F400 FEFD 000C FEF5 8400 8100 8100" /* ....... */ - $"F400 FEFD 000C FEF5 8400 8100 8100 F400" /* ....... */ - $"FEFD 000C FEF5 8400 8100 8100 F400 FEFD" /* ...... */ - $"000C FEF5 8400 8100 8100 F400 FEFD 000C" /* ........ */ + $"BDFE F5F8 00FD FFFF 0000 FFFC 00FF FFFF" /* .... */ + $"0003 FF00 00FF FE00 00FF FC00 FEFF FE00" /* ........ */ + $"FFFF FF00 03FF 0000 FFFE 0002 FF00 FFFD" /* ....... */ + $"00FE FF04 00FF 0000 FFFE 0000 FFFC 00FE" /* ........ */ + $"FFFE 00FE FF01 00FF FC00 00FF FD00 FDFF" /* ...... */ + $"FE00 FFFF FE00 03FF 0000 FFFE 0000 FFFD" /* ....... */ + $"0000 FFFE FF01 00FF FC00 04FF 0000 FFFF" /* ........ */ + $"FC00 00FF FB00 00FF FC00 FEFF FE00 FFFF" /* ...... */ + $"FE00 FFFF FD00 00FF FE00 00FF FE00 00FF" /* ....... */ + $"FC00 FEFF FE00 08FF 00FF 0000 FF00 00FF" /* ........ */ + $"D000 EA00 00FF F2F9 00FF FA00 00FA CA00" /* ....... */ + $"00FF F2F9 00FF FA00 00FA F400 FEFD 002A" /* ......* */ + $"FEF5 B800 00FF D400 00FF FC00 C700 00FF" /* ....... */ + $"BC00 EA00 00FF F2F9 00FF FA00 00FA CA00" /* ....... */ + $"F0FF FA00 00FA F400 FEFD 0022 FEF5 B900" /* ....". */ + $"00FF D400 00FF FB00 C800 00FF BB00 EA00" /* ........ */ + $"F0FF FA00 00FA B200 00FA F400 FEFD 0028" /* ......( */ + $"FEF5 8400 8100 D200 00FA D000 00F9 FCFF" /* ...... */ + $"00F9 FD00 00F9 FCFF 00F9 FD00 00F9 FCFF" /* ...... */ + $"02F9 00FA F400 FEFD 003E FEF5 8400 8100" /* ....>.. */ + $"F000 00F9 FCFF 00F9 FD00 00F9 FCFF 00F9" /* ...... */ + $"FD00 00F9 FCFF 02F9 00FA D000 00FF FC2B" /* ......+ */ + $"00FF FD00 00FF FC2B 00FF FD00 00FF FC2B" /* ...+...+ */ + $"02FF 00FA F400 FEFD 0044 FEF5 8400 8100" /* ....D.. */ + $"F000 00FF FC2B 00FF FD00 00FF FC2B 00FF" /* ..+...+. */ + $"FD00 00FF FC2B 02FF 00FA D000 06FF 2BFC" /* ..+....+ */ + $"FCF5 2BFF FD00 06FF 2BFC FCF5 2BFF FD00" /* +..++. */ + $"08FF 2BFC FCF5 2BFF 00FA F400 FEFD 009C" /* .++... */ + $"FEF5 F800 00FF FC00 00FF FA00 00FF FE00" /* ....... */ + $"03FF 0000 FFE1 0000 FFF6 0000 FFE9 00FD" /* ........ */ + $"FFF9 0003 FF00 FFFF F800 F500 00FF FE00" /* ....... */ + $"00FF FC00 00FF F800 00FF FE00 00FF F600" /* ........ */ + $"00FF FC00 00FF FD00 00FF F400 FDFF FE00" /* ....... */ + $"00FF FB00 00FF D900 F000 06FF 2BFC FCF5" /* ......+ */ + $"2BFF FD00 06FF 2BFC FCF5 2BFF FD00 08FF" /* +..++.. */ + $"2BFC FCF5 2BFF 00FA D000 06FF 2BFC 2AF5" /* ++...+* */ + $"2BFF FD00 06FF 2BFC 2AF5 2BFF FD00 08FF" /* +..+*+.. */ + $"2BFC 2AF5 2BFF FAFA F400 FEFD 0095 FEF5" /* +*+.. */ + $"F800 FFFF FE00 FFFF FA00 00FF FE00 03FF" /* ...... */ + $"0000 FFE1 0000 FFF6 0000 FFE9 0000 FFFE" /* ........ */ + $"0000 FFF7 0000 FFF8 00F5 0000 FFFE 0000" /* ......... */ + $"FFF2 0000 FFFE 0000 FFF6 0000 FFF7 0000" /* ........ */ + $"FFF4 0000 FFFE 0000 FFF8 0000 FFD9 00F0" /* ....... */ + $"0006 FF2B FC2A F52B FFFD 0006 FF2B FC2A" /* ..+*+..+* */ + $"F52B FFFD 0008 FF2B FC2A F52B FFFA FAD0" /* +..+*+ */ + $"0006 FF2B FC2A F52B FFFD FA06 FF2B FC2A" /* ..+*+.+* */ + $"F52B FFFD FA08 FF2B FC2A F52B FF00 00F4" /* +.+*+.. */ + $"00FE FD00 F1FE F5F8 000C FF00 FF00 FF00" /* ....... */ + $"FF00 00FF FF00 00FE FF00 00FE FF00 00FE" /* ........ */ + $"FFFE 00FF FFFF 0000 FFFC 0002 FF00 00FE" /* ....... */ + $"FFF7 0004 FF00 FF00 00FE FFFE 00FE FF08" /* ....... */ + $"00FF 00FF FF00 00FF FFFE 00FF FFFE 00FE" /* ...... */ + $"FFFD 0000 FFFE 0011 FF00 FF00 FFFF 00FF" /* ....... */ + $"FF00 00FF 0000 FFFF 0000 FEFF F600 0FFF" /* ........ */ + $"00FF 0000 FF00 00FF 00FF FF00 00FF FFFB" /* ........ */ + $"0002 FF00 FFFE 00FF FFFE 00FE FF00 00FE" /* ....... */ + $"FFFF 00FF FFFF 00FE FFFF 00FF FFF8 0000" /* ..... */ + $"FFFE 000D FF00 FFFF 0000 FFFF 0000 FF00" /* ........ */ + $"00FF DC00 F000 06FF 2BFC 2AF5 2BFF FDFA" /* ....+*+ */ + $"06FF 2BFC 2AF5 2BFF FDFA 06FF 2BFC 2AF5" /* .+*+.+* */ + $"2BFF CE00 01FF 2BFE F501 2BFF FD00 01FF" /* +..+.+.. */ + $"2BFE F501 2BFF FD00 01FF 2BFE F503 2BFF" /* +.+..+.+ */ + $"0000 F400 FEFD 00F0 FEF5 F800 06FF 0000" /* ........ */ + $"FF00 00FF FD00 03FF 0000 FFFE 0015 FF00" /* ......... */ + $"00FF 0000 FF00 FF00 00FF 0000 FF00 FF00" /* .......... */ + $"FF00 00FF F400 10FF 00FF 0000 FF00 00FF" /* ......... */ + $"00FF 0000 FF00 FFFF FE00 03FF 0000 FFFD" /* ........ */ + $"0002 FF00 FFFA 00FD FFFF 00FF FFFD 000C" /* ....... */ + $"FF00 00FF 00FF 0000 FF00 FF00 0000 FFF7" /* ......... */ + $"0007 FF00 FF00 00FF 00FF FE00 05FF 00FF" /* ......... */ + $"0000 FFFB 0000 FFFE 0005 FF00 00FF 00FF" /* ......... */ + $"FD00 0BFF 0000 FF00 00FF 00FF 0000 FFFD" /* ......... */ + $"0000 FFF9 00FD FFFE 0009 FF00 FF00 00FF" /* ....... */ + $"00FF 00FF DB00 F000 01FF 2BFE F501 2BFF" /* .....+.+ */ + $"FD00 01FF 2BFE F501 2BFF FD00 01FF 2BFE" /* ..+.+..+ */ + $"F501 2BFF CE00 06FF E32B FCFC 2BFF FD00" /* .+..++. */ + $"06FF E32B FCFC 2BFF FD00 08FF E32B FCFC" /* .++..+ */ + $"2BFF 0000 F400 FEFD 00E2 FEF5 F800 00FF" /* +...... */ + $"FC00 02FF 0000 FEFF FF00 00FF FE00 07FF" /* ........ */ + $"0000 FF00 00FF 00FD FFFF 0004 FF00 FF00" /* ......... */ + $"FFFE 00FF FFF7 00FC FF0B 00FF 0000 FF00" /* ....... */ + $"FF00 00FF 00FF FD00 FDFF FF00 FEFF FF00" /* ...... */ + $"FFFF FC00 00FF FC00 00FF FC00 0CFF 0000" /* ........ */ + $"FF00 FF00 00FF 00FF 0000 00FF F800 FCFF" /* ........ */ + $"0200 FFFF FD00 05FF 00FF 0000 FFFB 0000" /* ......... */ + $"FFFE 0017 FF00 00FF 0000 FFFF 0000 FF00" /* ......... */ + $"00FF 0000 FF00 FF00 00FF 0000 FEFF F900" /* ......... */ + $"02FF 00FF FD00 02FF 00FF FD00 FFFF DA00" /* ....... */ + $"F000 06FF E32B FCFC 2BFF FD00 06FF E32B" /* ..++..+ */ + $"FCFC 2BFF FD00 06FF E32B FCFC 2BFF CE00" /* +..++. */ + $"00FF FC2B 00FF FD00 00FF FC2B 00FF FD00" /* .+...+.. */ + $"00FF FC2B 02FF 0000 F400 FEFD 00DB FEF5" /* .+..... */ + $"F800 00FF FC00 08FF 00FF 0000 FF00 00FF" /* ......... */ + $"FE00 08FF 0000 FF00 00FF 00FF FB00 02FF" /* ......... */ + $"00FF FB00 00FF F800 00FF FE00 0CFF 00FF" /* ........ */ + $"0000 FF00 FF00 00FF 00FF FD00 00FF FD00" /* ......... */ + $"03FF 0000 FFFD 0000 FFFD 0000 FFFC 0000" /* ......... */ + $"FFFC 000C FF00 00FF 00FF 0000 FF00 FF00" /* ......... */ + $"0000 FFF8 0000 FFFE 0004 FF00 FF00 FFFE" /* ........ */ + $"0005 FF00 FF00 00FF FB00 00FF FE00 03FF" /* ......... */ + $"0000 FFFD 0012 FF00 FF00 00FF 0000 FF00" /* .......... */ + $"FF00 00FF 00FF 0000 FFF9 0003 FF00 00FF" /* ......... */ + $"FE00 09FF 00FF 0000 FF00 FF00 FFDB 00F0" /* ....... */ + $"0000 FFFC 2B00 FFFD 0000 FFFC 2B00 FFFD" /* ..+...+. */ + $"0000 FFFC 2B00 FFCD 00FC FFFB 00FC FFFB" /* ..+... */ + $"00FC FFFE 00F4 00FE FD00 C7FE F5F8 0000" /* ...... */ + $"FFFC 0002 FF00 00FE FFFE 0000 FFFE 0009" /* ....... */ + $"FF00 FF00 00FF 0000 FFFF FD00 02FF 00FF" /* ........ */ + $"FE00 FEFF FD00 00FF FC00 00FF FE00 07FF" /* ....... */ + $"00FF 0000 FF00 00FE FF01 00FF FC00 FFFF" /* ........ */ + $"FE00 FEFF 0000 FEFF FC00 00FF FC00 00FF" /* ....... */ + $"FC00 09FF 0000 FF00 00FF FF00 00FE FFFD" /* ....... */ + $"0000 FFFC 0000 FFFE 000C FF00 FF00 00FF" /* ......... */ + $"0000 FF00 00FF FFFA 0000 FFFD 00FF FFFF" /* ....... */ + $"00FE FFFF 0008 FF00 00FF 0000 FF00 00FE" /* ......... */ + $"FFFF 00FE FFFE 0000 FFFD 0000 FFFE 000D" /* ....... */ + $"FF00 00FF 0000 FFFF 0000 FF00 00FF DC00" /* ......... */ + $"EF00 FCFF FB00 FCFF FB00 FCFF AE00 F400" /* ..... */ + $"FEFD 001C FEF5 CA00 00FF BF00 02FF 0000" /* ........ */ + $"FD00 00FF C200 00FF C600 8100 F400 FEFD" /* ....... */ + $"001C FEF5 CB00 00FF BE00 02FF 0000 FE00" /* ......... */ + $"00FF C200 00FF C500 8100 F400 FEFD 000C" /* ........ */ $"FEF5 8400 8100 8100 F400 FEFD 000C FEF5" /* ...... */ $"8400 8100 8100 F400 FEFD 000C FEF5 8400" /* ....... */ - $"8100 8100 F400 FEFD 0088 FEF5 F800 FDFF" /* ..... */ - $"F900 00FF FE00 00FF F500 FCFF FB00 FFFF" /* ...... */ - $"F500 00FF FB00 00FF F800 00FF EB00 00FF" /* ........ */ - $"F000 FFFF FF00 02FF 0000 FEFF FE00 FEFF" /* ...... */ - $"FC00 00FF FB00 FCFF FB00 FFFF F500 00FF" /* ...... */ - $"FB00 FEFF FC00 FCFF 0100 FFFD 00FC FFF6" /* ..... */ - $"0000 FFF0 00FF FFF0 00FF 0000 FFF7 0000" /* ........ */ - $"FFFB 0003 FF00 00FF F500 FFFF FF00 00FF" /* ....... */ - $"FA00 00FF FE00 00FF F100 FFFF C800 F400" /* ....... */ - $"FEFD 008B FEF5 F800 00FF FE00 00FF FA00" /* ...... */ - $"00FF FE00 00FF F300 00FF F800 00FF F500" /* ........ */ - $"00FF F100 00FF EB00 00FF F000 FFFF FF00" /* ....... */ - $"02FF 00FF FE00 02FF 00FF FE00 00FF FD00" /* ........ */ - $"00FF F900 00FF F800 00FF F500 00FF FC00" /* ........ */ - $"00FF FE00 00FF F900 02FF 00FF FD00 00FF" /* ........ */ - $"F200 00FF EF00 00FF F000 FF00 00FF F700" /* ........ */ - $"00FF FB00 03FF 0000 FFF5 00FF FFFF 0000" /* ........ */ - $"FFFA 0000 FFEC 0000 FFC8 00F4 00FE FD00" /* ....... */ - $"FEFE F5F8 0000 FFFE 0006 FF00 00FF FF00" /* ....... */ - $"00FE FF00 00FE FFFF 00FF FFFF 0003 FF00" /* ....... */ - $"FFFF FE00 00FF FD00 FFFF FE00 01FF 00FE" /* ...... */ - $"FFFE 00FF FFFF 00FE FFFD 00FF FFFF 00FE" /* .... */ - $"FFFD 00FE FFFE 00FF FFFE 00FE FFFF 00FF" /* .... */ - $"FFFE 00FE FFFC 00FF FFFF 00FE FFFC 0003" /* ..... */ - $"FF00 FF00 02FF 00FF FC00 00FF FA00 02FF" /* ........ */ - $"00FF FA00 00FF FD00 FFFF FE00 01FF 00FE" /* ....... */ - $"FFFE 00FF FFFF 00FE FFF9 0000 FFFA 0002" /* ...... */ - $"FF00 00FE FFFF 00FD FFF7 00FE FFFF 00FF" /* ..... */ - $"FFFF 0000 FFFE 0004 FF00 00FF FFFE 0006" /* ........ */ - $"FF00 00FF FF00 00FE FFFE 00FF FFFE 00FE" /* ...... */ - $"FFFC 00FF FFFF 00FE FFFD 00FE FF00 00FE" /* ..... */ - $"FFFE 00FF FFFC 000A FF00 FF00 FF00 00FF" /* ...... */ - $"FF00 00FE FF08 00FF FF00 00FF FF00 00FE" /* ........ */ - $"FFFE 00FF FFFE 0000 FFC8 00F4 00FE FD01" /* ...... */ - $"14FE F5F8 00FD FFFF 0006 FF00 00FF 0000" /* ........ */ - $"FFFE 0009 FF00 00FF 0000 FF00 FFFF FC00" /* ....... */ - $"00FF FE00 13FF 0000 FF00 00FF 00FF 0000" /* .......... */ - $"FF00 FF00 00FF 0000 FFFB 0002 FF00 FFFA" /* ........ */ - $"0003 FF00 00FF FD00 02FF 00FF FD00 08FF" /* ......... */ - $"0000 FF00 FF00 00FF FD00 08FF 0000 FF00" /* .......... */ - $"FF00 00FF FD00 03FF 00FF 0002 FF00 FFFB" /* ........ */ - $"00FE FFFD 0002 FF00 FFFA 0000 FFFE 0013" /* ........ */ - $"FF00 00FF 0000 FF00 FF00 00FF 00FF 0000" /* .......... */ - $"FF00 00FF F900 00FF F900 06FF 0000 FF00" /* ......... */ - $"00FF FC00 00FF F900 27FF 0000 FF00 FF00" /* ....'.... */ - $"00FF 0000 FF00 FF00 00FF 0000 FF00 00FF" /* .......... */ + $"8100 8100 F400 FEFD 0010 FEF5 F800 FDFF" /* ...... */ + $"9100 8100 8100 F400 FEFD 0010 FEF5 F500" /* ....... */ + $"00FF 9100 8100 8100 F400 FEFD 0028 FEF5" /* ......( */ + $"F600 00FF FE00 FFFF FE00 FFFF FE00 FFFF" /* ..... */ + $"FE00 FFFF FF00 FEFF FE00 FFFF AE00 8100" /* ..... */ + $"8100 F400 FEFD 002D FEF5 F700 00FF FB00" /* ...-... */ + $"19FF 00FF 0000 FF00 FF00 00FF 00FF 0000" /* .......... */ + $"FF00 FF00 00FF 00FF 0000 FFAF 0081 0081" /* ........ */ + $"00F4 00FE FD00 2AFE F5F8 0000 FFFC 00FE" /* ...*... */ + $"FF01 00FF FD00 00FF FD00 09FF 0000 FF00" /* ........ */ + $"FF00 00FF 00FD FFAF 0081 0081 00F4 00FE" /* ....... */ + $"FD00 2DFE F5F8 0000 FFFD 0019 FF00 00FF" /* .-...... */ $"00FF 0000 FF00 FF00 00FF 00FF 0000 FF00" /* .......... */ - $"FFFF 0000 FFFA 0003 FF00 00FF FB00 0BFF" /* ........ */ - $"0000 FF00 00FF 00FF 0000 FFFD 0004 FF00" /* .......... */ - $"FF00 FFFD 0003 FF00 00FF FE00 0AFF 00FF" /* ....... */ - $"0000 FF00 FF00 00FF FD00 03FF 0000 FFC8" /* ......... */ - $"00F4 00FE FD01 0CFE F5F8 0000 FFFE 0001" /* ........ */ - $"FF00 FDFF FF00 00FF FE00 02FF 0000 FDFF" /* ....... */ - $"0100 FFFB 0000 FFFE 00FD FFFF 0006 FF00" /* ........ */ - $"FF00 00FF 00FD FFFF 0000 FFFB 0004 FF00" /* ........ */ - $"00FF FFFC 0005 FF00 00FF 0000 FEFF FF00" /* ........ */ - $"FFFF FF00 FDFF 0400 FF00 00FF FD00 08FF" /* ....... */ - $"0000 FF00 FF00 00FF FD00 03FF 0000 FF02" /* .......... */ - $"FF00 FFF8 0002 FF00 00FC FFFB 0000 FFFE" /* ....... */ - $"00FD FFFF 0006 FF00 FF00 00FF 00FD FFFF" /* ....... */ - $"0000 FFFA 0000 FFF9 0000 FFFE 0003 FF00" /* ......... */ - $"00FF FC00 00FF F900 04FF 0000 FF00 FDFF" /* ........ */ - $"FF00 04FF 00FF 0000 FDFF FF00 0BFF 00FF" /* ........ */ - $"0000 FF00 FF00 00FF 00FD FF01 00FF FF00" /* ......... */ - $"00FF FC00 FEFF FF00 00FF FB00 07FF 0000" /* ........ */ - $"FF00 00FF 00FD FFFD 0006 FF00 00FF FF00" /* ........ */ - $"00FE FFFF 0000 FFFE 000C FF00 FF00 00FF" /* ........ */ - $"00FF 0000 FF00 00FE FFFF 0000 FFC8 00F4" /* ........ */ - $"00FE FD01 12FE F5F8 0000 FFFE 0002 FF00" /* ........ */ - $"FFFC 0000 FFFE 0003 FF00 00FF FD00 00FF" /* ........ */ - $"FB00 00FF FE00 00FF FC00 07FF 00FF 0000" /* ......... */ - $"FF00 FFFC 0000 FFFB 0000 FFFD 0000 FFFD" /* ....... */ - $"0008 FF00 00FF 00FF 0000 FFFD 0002 FF00" /* .......... */ - $"FFFD 0003 FF00 00FF FD00 08FF 0000 FF00" /* ......... */ - $"FF00 00FF FD00 03FF 0000 FF02 FF00 FFFE" /* ........ */ - $"0002 FF00 FFFE 0003 FF00 00FF FE00 00FF" /* ......... */ - $"FB00 00FF FE00 00FF FC00 07FF 00FF 0000" /* ......... */ - $"FF00 FFFC 0000 FFFB 0000 FFF8 0000 FFFE" /* ....... */ - $"0005 FF00 00FF 00FF FE00 00FF F900 05FF" /* ......... */ - $"0000 FF00 FFFB 0000 FFFE 0000 FFFC 000C" /* ......... */ - $"FF00 FF00 00FF 00FF 0000 FF00 FFFD 0000" /* ......... */ - $"FFFF 0000 FFFD 0006 FF00 00FF 0000 FFFB" /* ........ */ - $"0008 FF00 00FF 0000 FF00 FFFA 000C FF00" /* .......... */ - $"00FF FF00 FF00 00FF 0000 FFFE 0012 FF00" /* ......... */ - $"FF00 00FF 00FF 0000 FF00 FF00 00FF 0000" /* .......... */ - $"FFC8 00F4 00FE FD01 05FE F5F8 00FD FFFE" /* ..... */ - $"00FF FFFD 0000 FFFE 0007 FF00 00FF FF00" /* ........ */ - $"00FF FB00 00FF FD00 FFFF FE00 09FF 00FF" /* ...... */ - $"0000 FF00 00FF FFFD 0000 FFFC 0001 FF00" /* ......... */ - $"FEFF FC00 FEFF FE00 FEFF 0000 FEFF FE00" /* ..... */ - $"FFFF FE00 FEFF FC00 FFFF FF00 03FF 0000" /* ...... */ - $"FFFD 0000 FFFE 0002 FF00 00FE FFFE 00FE" /* ....... */ - $"FFFE 0000 FFFE 0000 FFFB 0000 FFFD 00FF" /* ....... */ - $"FFFE 0009 FF00 FF00 00FF 0000 FFFF FD00" /* ....... */ - $"00FF FD00 FCFF FF00 00FF FE00 00FF FE00" /* ....... */ - $"FEFF FE00 FEFF FD00 00FF FC00 FEFF FF00" /* ..... */ - $"FFFF FD00 00FF FD00 FFFF FE00 06FF 0000" /* ....... */ - $"FFFF 0000 FEFF FE00 FFFF FE00 FEFF FC00" /* ..... */ - $"FEFF FE00 00FF FB00 09FF 00FF 0000 FF00" /* ....... */ - $"00FF FFFC 0000 FFFE 0002 FF00 00FE FFFE" /* ....... */ - $"000F FF00 00FF 0000 FFFF 0000 FF00 00FF" /* .......... */ - $"0000 FEFF FF00 00FF C800 F400 FEFD 0014" /* ........ */ - $"FEF5 8400 AE00 00FF E000 00FF F700 8100" /* ....... */ - $"F400 FEFD 0014 FEF5 8400 AF00 00FF DF00" /* ....... */ - $"00FF F700 8100 F400 FEFD 000C FEF5 8400" /* ....... */ - $"8100 8100 F400 FEFD 000C FEF5 8400 8100" /* ....... */ - $"8100 F400 FEFD 0014 FEF5 8400 BD00 00FF" /* ....... */ - $"E700 00FF E100 8100 F400 FEFD 0086 FEF5" /* ...... */ - $"F700 FEFF F400 00FF F000 FFFF F300 FEFF" /* ..... */ - $"CE00 00FF FE00 00FF FB00 F600 00FF F400" /* ........ */ - $"FFFF FF00 00FF F500 00FF FE00 00FF ED00" /* ....... */ - $"09FF 0000 FFFF 0000 FF00 00FE FFFE 00FE" /* ....... */ - $"FFFC 0000 FFFD 0000 FFF6 0000 FFFB 0003" /* ........ */ - $"FF00 00FF F800 FE00 00FF FE00 00FF FA00" /* ........ */ - $"00FF EA00 03FF 0000 FFEF 00FF FFFD 0009" /* ....... */ - $"FF00 FFFF 00FF FF00 00FF F500 00FF DB00" /* ....... */ - $"F400 FEFD 0079 FEF5 F800 00FF FE00 00FF" /* ..y.... */ - $"F500 00FF F100 00FF F200 00FF FE00 00FF" /* ........ */ - $"CF00 00FF F700 F600 00FF F300 00FF F200" /* ........ */ - $"00FF EA00 00FF FE00 FFFF FF00 02FF 00FF" /* ....... */ - $"FE00 02FF 00FF FE00 00FF FD00 00FF FC00" /* ........ */ - $"00FF F700 00FF FB00 03FF 0000 FFF8 00FE" /* ........ */ - $"0000 FFFE 0000 FFDF 0000 FFF0 0000 FFFB" /* ........ */ - $"0006 FF00 00FF 0000 FFCB 00F4 00FE FD01" /* ......... */ - $"2EFE F5F8 0000 FFFB 00FF FFFF 00FE FFFF" /* ..... */ - $"00FE FFFF 00FF FFFF 0003 FF00 FFFF FD00" /* ...... */ - $"FEFF FF00 FFFF FF00 03FF 00FF FFFD 0000" /* ...... */ - $"FFFC 0004 FF00 00FF 00FE FFFE 00FF FFFF" /* ...... */ - $"0007 FF00 FFFF 0000 FFFF FE00 FFFF FF00" /* ....... */ - $"FEFF 0400 FFFF 0000 FEFF FF00 04FF 0000" /* ........ */ - $"FF00 FEFF 0300 FFFF 00FE FFFF 0000 00FE" /* ....... */ - $"FFFB 0004 FF00 FF00 00FE FFFF 00FE FFFE" /* ...... */ - $"0007 FF00 FFFF 0000 FFFF FE00 FFFF FF00" /* ....... */ - $"FEFF 0800 FFFF 0000 FFFF 0000 FEFF FE00" /* ....... */ - $"FEFF FD00 00FF FE00 06FF 00FF 00FF 00FF" /* ....... */ - $"FC00 00FF FA00 02FF 00FF FD00 00FF FC00" /* ........ */ - $"FFFF FF00 FEFF FD00 FEFF 0000 FEFF FE00" /* ..... */ - $"FFFF FF00 FE00 00FF FE00 01FF 00FE FFFF" /* ...... */ - $"00FF FF01 00FF FE00 0CFF 0000 FFFF 0000" /* ......... */ - $"FF00 FFFF 0000 FEFF 0300 FFFF 00FE FF04" /* ....... */ - $"00FF 0000 FFFB 00FF FFFF 00FE FFFC 000A" /* ...... */ - $"FF00 00FF 0000 FF00 FFFF 00FE FFFE 00FF" /* ....... */ - $"FFFF 00FF FFFF 00FE FFE0 00F4 00FE FD01" /* ..... */ - $"34FE F5F8 0000 FFFC 0014 FF00 00FF 00FF" /* 4....... */ - $"0000 FF00 00FF 0000 FF00 00FF 00FF FFFA" /* ......... */ - $"0009 FF00 00FF 0000 FF00 FFFF FA00 FEFF" /* ....... */ - $"FF00 10FF 0000 FF00 FF00 00FF 00FF 0000" /* .......... */ - $"FF00 FFFF FE00 1DFF 0000 FF00 FF00 00FF" /* ........ */ - $"00FF 0000 FF00 00FF 00FF 0000 FF00 FF00" /* .......... */ - $"00FF 0000 FFFE 0006 FF00 FF00 00FF 0003" /* .......... */ - $"FF00 00FF FB00 18FF 00FF 0000 FF00 00FF" /* ......... */ - $"00FF 0000 FF00 00FF 0000 FF00 FF00 00FF" /* .......... */ - $"FD00 03FF 0000 FFFE 000C FF00 FF00 00FF" /* ......... */ - $"00FF 0000 FF00 FFFA 0000 FFFE 0006 FF00" /* ......... */ - $"FF00 FF00 FFFB 00FE FFFD 0002 FF00 FFFD" /* ...... */ - $"0000 FFFA 0003 FF00 00FF FB00 0CFF 0000" /* .......... */ - $"FF00 00FF 00FF 0000 FF00 FE00 00FF FE00" /* ......... */ - $"16FF 00FF 0000 FF00 00FF 0000 FF00 FF00" /* .......... */ - $"00FF 0000 FF00 FFFF FE00 00FF FC00 09FF" /* ....... */ - $"0000 FF00 00FF 0000 FFFC 0006 FF00 00FF" /* .......... */ - $"0000 FFFB 0018 FF00 00FF 0000 FF00 00FF" /* .......... */ - $"00FF 0000 FF00 FF00 00FF 0000 FF00 FFDD" /* ......... */ - $"00F4 00FE FD01 26FE F5F8 0000 FFFC 00FD" /* ...&... */ - $"FF09 00FF 0000 FF00 00FF 0000 FDFF 0100" /* ......... */ - $"FFF9 0008 FF00 00FF 0000 FF00 FFF6 000B" /* ......... */ - $"FF00 FF00 00FF 00FF 0000 FF00 FDFF 0100" /* ......... */ - $"FFFD 0000 FFFD 0018 FF00 00FF 00FF 0000" /* ......... */ - $"FF00 00FF 00FF 0000 FF00 FF00 00FF 0000" /* .......... */ - $"FFFE 0006 FF00 FF00 00FF 0003 FF00 00FF" /* ......... */ - $"FC00 FCFF 1100 FF00 00FF 00FF 0000 FF00" /* ......... */ - $"00FF 0000 FF00 FFFC 00FE FFFF 0000 FFFE" /* ....... */ - $"000E FF00 FF00 00FF 00FF 0000 FF00 00FF" /* .......... */ - $"FFFC 0000 FFFE 0006 FF00 00FF FF00 FFF8" /* ....... */ - $"0002 FF00 00FC FFFE 0000 FFFC 00FE FFFF" /* ....... */ - $"0000 FFFB 0007 FF00 00FF 0000 FF00 FDFF" /* ......... */ - $"0000 FE00 00FF FE00 0FFF 00FF 0000 FF00" /* .......... */ - $"00FF 0000 FF00 FF00 00FD FF01 00FF FC00" /* ......... */ - $"FFFF FE00 09FF 0000 FF00 00FF 0000 FFFC" /* ....... */ - $"0006 FF00 00FF 0000 FFFB 001A FF00 00FF" /* .......... */ - $"0000 FF00 00FF 00FF 0000 FF00 FF00 00FF" /* .......... */ - $"0000 FF00 00FF FFDF 00F4 00FE FD01 3DFE" /* .......= */ - $"F5F8 0000 FFFE 0002 FF00 FFFD 0009 FF00" /* ....... */ - $"00FF 0000 FF00 00FF FD00 00FF F900 08FF" /* ......... */ - $"0000 FF00 00FF 00FF FA00 00FF FE00 0CFF" /* ......... */ - $"00FF 0000 FF00 FF00 00FF 00FF FD00 00FF" /* ......... */ - $"FD00 1DFF 0000 FF00 FF00 00FF 00FF 0000" /* .......... */ - $"FF00 00FF 00FF 0000 FF00 FF00 00FF 0000" /* .......... */ - $"FFFE 0006 FF00 FF00 00FF 0003 FF00 00FF" /* ......... */ - $"FC00 00FF FE00 1DFF 00FF 0000 FF00 FF00" /* ......... */ - $"00FF 0000 FF00 00FF 00FF 0000 FF00 FF00" /* .......... */ - $"00FF 0000 FFFE 000A FF00 FF00 00FF 00FF" /* ........ */ - $"0000 FFFD 0000 FFFD 0000 FFFE 0006 FF00" /* ......... */ - $"00FF FF00 FFFE 0002 FF00 FFFE 0003 FF00" /* ........ */ - $"00FF FE00 00FF FE00 00FF FD00 06FF 0000" /* ......... */ - $"FF00 00FF FB00 08FF 0000 FF00 00FF 00FF" /* ......... */ - $"FD00 FE00 00FF FE00 08FF 00FF 0000 FF00" /* ......... */ - $"00FF FE00 00FF FE00 00FF FD00 00FF FA00" /* ........ */ - $"0CFF 0000 FF00 00FF 0000 FF00 00FF FC00" /* .......... */ - $"06FF 0000 FF00 00FF FB00 16FF 0000 FF00" /* .......... */ - $"00FF 0000 FF00 FF00 00FF 00FF 0000 FF00" /* .......... */ - $"00FF FD00 00FF E000 F400 FEFD 0122 FEF5" /* ......" */ - $"F700 FEFF FE00 FFFF FF00 03FF 0000 FFFE" /* ...... */ - $"0007 FF00 00FF FF00 00FF F900 00FF FE00" /* ......... */ - $"FFFF FF00 00FF F900 FEFF FE00 FEFF 0000" /* ...... */ - $"FEFF FE00 FFFF FF00 00FF FC00 FFFF FE00" /* ..... */ - $"FFFF FF00 07FF 0000 FF00 00FF 00FE FFFE" /* ....... */ - $"00FE FFFE 0009 FF00 00FF 00FF 0000 FF00" /* ........ */ - $"0000 FEFF FC00 00FF FE00 01FF 00FE FFFF" /* ....... */ - $"00FE FFFE 0007 FF00 00FF 0000 FFFF FE00" /* ........ */ - $"FEFF FE00 0EFF 0000 FF00 00FF FF00 00FF" /* ........ */ - $"0000 FF00 FEFF FB00 03FF 0000 FFFE 0002" /* ......... */ - $"FF00 00FE FFFE 00FE FFFE 0000 FFFE 0003" /* ....... */ - $"FF00 00FF FB00 FEFF FE00 00FF FB00 0BFF" /* ....... */ - $"00FF 0000 FF00 00FF FF00 00FD 00FE FFFF" /* ........ */ - $"0006 FF00 00FF 0000 FFFE 0000 FFFD 00FF" /* ......... */ - $"FFFF 0000 FFFD 00FE FFFE 0000 FFFE 0002" /* ....... */ - $"FF00 00FE FFFB 00FF FFFE 0000 FFFB 0012" /* ....... */ - $"FF00 00FF 0000 FF00 00FF 00FF 0000 FF00" /* .......... */ - $"00FF FFFE 0001 FF00 FEFF DF00 F400 FEFD" /* ...... */ - $"002C FEF5 BB00 00FF E100 00FF EC00 FE00" /* .,...... */ - $"00FF F600 00FF FD00 00FF D200 00FF E700" /* ........ */ - $"00FF E100 D100 00FF B200 F400 FEFD 0024" /* .......$ */ - $"FEF5 BB00 00FF E100 00FF EC00 0200 FFFF" /* ....... */ - $"F500 00FF FD00 00FF 9600 D300 FFFF B100" /* ....... */ - $"F400 FEFD 000C FEF5 8400 8100 8100 F400" /* ....... */ - $"FEFD 000C FEF5 8400 8100 8100 F400 FEFD" /* ...... */ - $"0014 FEF5 9400 00FF F200 FA00 00FF 8900" /* ........ */ - $"8100 F400 FEFD 0042 FEF5 F200 00FF FC00" /* ...B... */ - $"00FF FE00 00FF FB00 00FF E800 FEFF FF00" /* ....... */ - $"00FF E500 00FF F200 03FF 0000 FFFE 0005" /* ......... */ - $"FF00 00FF 00FF FE00 00FF FF00 FEFF FE00" /* ....... */ - $"00FF 8A00 8100 F400 FEFD 0044 FEF5 F200" /* .....D. */ - $"00FF FC00 00FF FE00 00FF FB00 00FF E900" /* ........ */ - $"00FF FE00 02FF 00FF D600 00FF FE00 00FF" /* ........ */ - $"FE00 05FF 0000 FF00 FFFE 0000 FF01 00FF" /* ......... */ - $"FE00 00FF FE00 00FF 8B00 8100 F400 FEFD" /* ....... */ - $"0072 FEF5 F700 FFFF FF00 FEFF FD00 00FF" /* .r.... */ - $"FE00 06FF 00FF 00FF FF00 FEFF FE00 FFFF" /* ...... */ - $"FF00 FEFF FE00 FFFF FA00 00FF FC00 FEFF" /* ..... */ - $"FE00 FFFF FF00 FEFF 0400 FFFF 0000 FEFF" /* ...... */ - $"FE00 FFFF FF00 FFFF FF00 FEFF 0000 FEFF" /* ..... */ - $"FC00 00FF FE00 00FF FE00 05FF 0000 FF00" /* ......... */ - $"FFFE 0000 FF01 00FF FA00 00FF 8B00 8100" /* ........ */ - $"F400 FEFD 007B FEF5 F500 03FF 0000 FFFC" /* ..{.... */ - $"0000 FFFE 0003 FF00 FFFF FE00 03FF 0000" /* ......... */ - $"FFFD 0005 FF00 FF00 00FF FD00 01FF 00FD" /* ........ */ - $"FF01 00FF FC00 03FF 0000 FFFD 000D FF00" /* ......... */ - $"FF00 00FF 0000 FF00 FF00 00FF FD00 0DFF" /* ......... */ - $"0000 FF00 FF00 00FF 00FF 0000 FFFD 0000" /* .......... */ - $"FFFE 0000 FFFE 0005 FF00 00FF 00FF FE00" /* ........ */ - $"00FF 0100 FFFA 0000 FF8B 0081 00F4 00FE" /* ........ */ - $"FD00 7CFE F5F7 00FE FFFF 0000 FFFC 0000" /* .|..... */ - $"FFFE 0002 FF00 FFFD 0005 FF00 00FF 0000" /* ......... */ - $"FEFF 0600 FF00 00FF 0000 FEFF FB00 00FF" /* ........ */ - $"FC00 05FF 0000 FF00 00FE FF0E 00FF 0000" /* .......... */ - $"FF00 00FF 00FF 0000 FF00 00FE FFFF 000A" /* ........ */ - $"FF00 FF00 00FF 00FF 0000 FFFD 0000 FFFE" /* ........ */ - $"0000 FFFE 0005 FF00 00FF 00FF FE00 00FF" /* ......... */ - $"0100 FFFA 0000 FF8B 0081 00F4 00FE FD00" /* ........ */ - $"85FE F5F8 0006 FF00 00FF 0000 FFFC 0000" /* ........ */ - $"FFFE 0002 FF00 FFFD 0012 FF00 00FF 00FF" /* ........ */ - $"0000 FF00 FF00 00FF 00FF 0000 FFFB 0000" /* .......... */ - $"FFFE 0029 FF00 FF00 00FF 00FF 0000 FF00" /* .)....... */ - $"FF00 00FF 0000 FF00 FF00 00FF 00FF 0000" /* .......... */ - $"FF00 00FF 00FF 0000 FF00 FF00 00FF FD00" /* ......... */ - $"00FF FE00 00FF FE00 05FF 0000 FF00 FFFE" /* ........ */ - $"0000 FF01 00FF FE00 00FF FE00 00FF 8B00" /* ......... */ - $"8100 F400 FEFD 0077 FEF5 F700 FEFF FE00" /* ...w.. */ - $"00FF FC00 FEFF FF00 00FF FD00 FEFF FE00" /* ...... */ - $"FEFF 0600 FF00 00FF 0000 FEFF FA00 FEFF" /* ....... */ - $"FF00 05FF 0000 FF00 00FE FF08 00FF 0000" /* .......... */ - $"FF00 00FF 00FE FFFE 00FE FFFF 0002 FF00" /* ....... */ - $"00FE FF04 00FF 0000 FFFC 0000 FFFE 00FE" /* ........ */ - $"FFFE 0002 FF00 00FE FF00 00FF 00FE FFFE" /* ....... */ - $"0000 FFFE 0000 FF8E 0081 00F4 00FE FD00" /* ........ */ - $"1CFE F5B0 0000 FFF2 0000 FFF6 0000 FFF2" /* ....... */ - $"00FA 0000 FF89 0081 00F4 00FE FD00 14FE" /* ........ */ - $"F5B0 0000 FFF4 00FF FFE5 0081 0081 00F4" /* ...... */ - $"00FE FD00 0CFE F584 0081 0081 00F4 00FE" /* ....... */ - $"FD00 0CFE F584 0081 0081 00F4 00FE FD00" /* ....... */ - $"0CFE F584 0081 0081 00F4 00FE FD00 0CFE" /* ....... */ + $"FF00 00FF 00FF AC00 8100 8100 F400 FEFD" /* ....... */ + $"002B FEF5 F800 FDFF FF00 FEFF FF00 FFFF" /* .+... */ + $"FE00 FFFF FE00 FFFF FF00 07FF 0000 FF00" /* ....... */ + $"00FF FFAE 0081 0081 00F4 00FE FD00 0CFE" /* ....... */ $"F584 0081 0081 00F4 00FE FD00 0CFE F584" /* ...... */ $"0081 0081 00F4 00FE FD00 0CFE F584 0081" /* ....... */ $"0081 00F4 00FE FD00 0CFE F584 0081 0081" /* ....... */ @@ -5251,414 +5275,702 @@ data 'PICT' (1025) { $"0CFE F584 0081 0081 00F4 00FE FD00 0CFE" /* ....... */ $"F584 0081 0081 00F4 00FE FD00 0CFE F584" /* ...... */ $"0081 0081 00F4 00FE FD00 0CFE F584 0081" /* ....... */ - $"0081 00F4 00FE FD00 24FE F5A7 0000 FFFC" /* ....$.. */ - $"0000 FFE5 00CF 0000 FFD8 0000 FFEA 0000" /* ......... */ - $"FFF6 00ED 0000 FF96 00F4 00FE FD00 65FE" /* ......e */ - $"F5F8 00FF FFFD 00FF FFFA 00FF FFF8 00FD" /* .... */ - $"FFFE 00FF FFFF 00FF FFF1 0000 FFFC 0000" /* ...... */ - $"FFFE 0000 FFF2 0000 FFFC 0000 FFE5 00F6" /* ....... */ - $"0000 FFE2 0000 FFFB 0006 FF00 00FF FF00" /* ......... */ - $"FFFB 0000 FFE5 0000 FFEA 0003 FF00 00FF" /* ........ */ - $"FA00 00FF 00FF F500 00FF FB00 00FF 9600" /* ........ */ - $"F400 FEFD 0064 FEF5 F800 FFFF FD00 FFFF" /* ..d.. */ - $"FA00 FFFF F900 FFFF FF00 FFFF FB00 FFFF" /* .... */ - $"F100 00FF FC00 00FF FE00 00FF F300 00FF" /* ........ */ - $"FC00 00FF E400 F600 00FF E200 00FF FC00" /* ........ */ - $"06FF 0000 FF00 FFFF FA00 00FF E600 00FF" /* ........ */ - $"EA00 00FF FE00 00FF F900 00FF F500 00FF" /* ........ */ - $"FC00 00FF 9500 F400 FEFD 00D2 FEF5 F700" /* ...... */ - $"FBFF FE00 FEFF FF00 FDFF FB00 FFFF FC00" /* .... */ - $"FEFF 0000 FDFF FF00 FEFF FD00 FFFF FD00" /* ..... */ - $"FEFF FF00 FEFF 0000 FEFF 0000 FEFF FD00" /* ...... */ - $"00FF FD00 00FF FC00 03FF 0000 FFFC 0002" /* ......... */ - $"FF00 FFFC 0002 FF00 FFFC 0000 FFFD 0002" /* ........ */ - $"00FF FFFE 00FE FF00 00FE FFFF 00FF FFFF" /* ..... */ - $"00FE FFFE 00FF FFFC 00FE FFFE 00FF FFFF" /* .... */ - $"00FE FFFD 0000 FFF9 0004 FF00 FFFF 00FE" /* ....... */ - $"FFFF 000E FF00 FFFF 0000 FFFF 0000 FF00" /* ........ */ - $"00FF 00FE FFFC 0002 FF00 00FE FF02 00FF" /* ........ */ - $"FFFE 00FF FFFE 00FF FFFC 0002 FF00 00FE" /* ...... */ - $"FFFF 00FF FFFE 0001 FF00 FEFF FE00 FFFF" /* ..... */ - $"FF00 FEFF FD00 00FF 9500 F400 FEFD 00E8" /* ...... */ - $"FEF5 F700 FBFF FF00 FFFF 0800 FFFF 00FF" /* ..... */ - $"FF00 FFFF FB00 FDFF FE00 FFFF FF00 FFFF" /* .... */ - $"FF00 FFFF 0200 FFFF F800 06FF 0000 FF00" /* ........ */ - $"00FF FE00 06FF 0000 FF00 00FF FA00 00FF" /* ......... */ - $"FC00 00FF FD00 04FF 00FF 00FF FE00 04FF" /* ........ */ - $"00FF 00FF FE00 04FF 00FF 00FF FC00 05FF" /* ........ */ - $"0000 FF00 FFFC 0010 FF00 00FF 0000 FF00" /* .......... */ - $"FF00 00FF 00FF 0000 FFFD 000B FF00 00FF" /* ......... */ - $"00FF 0000 FF00 00FF FD00 00FF F800 FFFF" /* ........ */ - $"FE00 06FF 0000 FF00 FFFF FB00 0AFF 00FF" /* ....... */ - $"0000 FF00 FF00 00FF FE00 00FF FE00 06FF" /* ......... */ - $"0000 FF00 00FF FD00 05FF 00FF 0000 FFFE" /* ......... */ - $"0000 FFFD 0008 FF00 00FF 0000 FF00 000D" /* ........... */ - $"FF00 FF00 00FF 00FF 0000 FF00 00FF FD00" /* ......... */ - $"00FF 9400 F400 FEFD 00D8 FEF5 F600 FDFF" /* ..... */ - $"FE00 FCFF 0500 FFFF 00FF FFF8 00FF FFFF" /* ..... */ - $"00FF FFFF 00FF FFFF 00FC FFF8 0006 FF00" /* ...... */ - $"00FF 0000 FFFE 0006 FF00 00FF 0000 FFFA" /* ......... */ - $"0000 FFFC 0000 FFFD 0004 FF00 FF00 FFFE" /* ........ */ - $"0004 FF00 FF00 FFFE 0004 FF00 FF00 FFFC" /* ........ */ - $"0000 FFFC 00FF FFFE 000C FF00 00FF 0000" /* ......... */ - $"FF00 FF00 00FF 00FD FFFD 0004 FF00 00FF" /* ........ */ - $"00FD FFFF 0000 FFFD 0000 FFF8 0000 FFFD" /* ....... */ - $"0005 FF00 00FF 00FF FC00 FEFF 0900 FF00" /* ........ */ - $"00FF 00FF 0000 FFFE 0000 FFFE 0008 FF00" /* ......... */ - $"00FF 0000 FF00 00FE FF01 00FF FB00 00FF" /* ......... */ - $"FD00 02FF 0000 FDFF FF00 06FF 00FF 0000" /* ......... */ - $"FF00 FDFF FF00 00FF FD00 00FF 9400 F400" /* ....... */ - $"FEFD 00D8 FEF5 F600 FDFF FE00 FFFF FD00" /* .... */ - $"FFFF 0200 FFFF FC00 FFFF FF00 FFFF FF00" /* ..... */ - $"FFFF FF00 FFFF FF00 FFFF F500 06FF 0000" /* ...... */ - $"FF00 00FF FE00 06FF 0000 FF00 00FF FB00" /* ......... */ - $"00FF FC00 00FF FB00 02FF 00FF FC00 02FF" /* ........ */ - $"00FF FC00 02FF 00FF FB00 03FF 0000 FFFD" /* ........ */ - $"0010 FF00 00FF 0000 FF00 00FF 00FF 0000" /* ........... */ - $"FF00 FFFA 0005 FF00 00FF 00FF FC00 00FF" /* ........ */ - $"FE00 00FF F700 00FF FD00 05FF 0000 FF00" /* ......... */ - $"FFFD 0010 FF00 00FF 00FF 0000 FF00 FF00" /* ......... */ - $"00FF 0000 FFFD 0013 FF00 00FF 0000 FF00" /* .......... */ - $"FF00 00FF 00FF 0000 FF00 00FF FC00 03FF" /* ......... */ - $"0000 FFFC 0007 FF00 FF00 00FF 00FF FC00" /* ......... */ - $"00FF FE00 00FF 9300 F400 FEFD 00D9 FEF5" /* ...... */ - $"F600 FDFF FD00 FEFF FF00 FDFF FA00 FDFF" /* .... */ - $"FE00 FFFF FE00 FFFF FF00 FEFF FD00 FFFF" /* .... */ - $"FD00 03FF 0000 FFFE 0000 FFFE 0001 FF00" /* ......... */ - $"FEFF FD00 03FF 0000 FFFC 0000 FFFB 0002" /* ........ */ - $"FF00 FFFC 0002 FF00 FFFC 0002 FF00 FFFD" /* ....... */ - $"0001 FF00 0400 FFFF 0000 FEFF FD00 0EFF" /* ......... */ - $"0000 FFFF 0000 FF00 00FF 0000 FFFF FE00" /* ......... */ - $"09FF 00FF 0000 FF00 00FF FFFD 0003 FF00" /* ........ */ - $"00FF F700 00FF FD00 FEFF FF00 00FF FC00" /* ....... */ - $"FEFF FF00 FEFF 0700 FF00 00FF 0000 FFFD" /* ....... */ - $"0008 FF00 00FF 0000 FF00 00FE FFFF 00FF" /* ......... */ - $"FFFE 0000 FFFB 0004 FF00 00FF FFFE 0009" /* ....... */ - $"FF00 FF00 00FF 0000 FFFF FD00 03FF 0000" /* ......... */ - $"FF93 00F4 00FE FD00 10FE F5B4 0000 FFD2" /* ...... */ - $"0081 0081 00F4 00FE FD00 10FE F5B4 0000" /* ........ */ - $"FFD2 0081 0081 00F4 00FE FD00 0CFE F584" /* ...... */ - $"0081 0081 00F4 00FE FD00 0CFE F584 0081" /* ....... */ $"0081 00F4 00FE FD00 0CFE F584 0081 0081" /* ....... */ - $"00F4 00FE FD00 0CFE F584 0081 0081 00F4" /* ....... */ - $"00FE FD00 0CFE F584 0081 0081 00F4 00FE" /* ....... */ - $"FD00 0CFE F584 0081 0081 00F4 00FE FD00" /* ....... */ - $"0CFE F584 0081 0081 00F4 00FE FD00 0CFE" /* ....... */ - $"F584 0081 0081 00F4 00FE FD00 0CFE F584" /* ...... */ - $"0081 0081 00F4 00FE FD00 0CFE F584 0081" /* ....... */ + $"00F4 00FE FD00 88FE F5F8 00FD FFF9 0000" /* ...... */ + $"FFFE 0000 FFF5 00FC FFFB 00FF FFF5 0000" /* ...... */ + $"FFFB 0000 FFF8 0000 FFEB 0000 FFF0 00FF" /* ....... */ + $"FFFF 0002 FF00 00FE FFFE 00FE FFFC 0000" /* ....... */ + $"FFFB 00FC FFFB 00FF FFF5 0000 FFFB 00FE" /* ..... */ + $"FFFC 00FC FF01 00FF FD00 FCFF F600 00FF" /* ...... */ + $"F000 FFFF F000 FF00 00FF F700 00FF FB00" /* ....... */ + $"03FF 0000 FFF5 00FF FFFF 0000 FFFA 0000" /* ........ */ + $"FFFE 0000 FFF1 00FF FFC8 00F4 00FE FD00" /* ...... */ + $"8BFE F5F8 0000 FFFE 0000 FFFA 0000 FFFE" /* ...... */ + $"0000 FFF3 0000 FFF8 0000 FFF5 0000 FFF1" /* ........ */ + $"0000 FFEB 0000 FFF0 00FF FFFF 0002 FF00" /* ........ */ + $"FFFE 0002 FF00 FFFE 0000 FFFD 0000 FFF9" /* ....... */ + $"0000 FFF8 0000 FFF5 0000 FFFC 0000 FFFE" /* ........ */ + $"0000 FFF9 0002 FF00 FFFD 0000 FFF2 0000" /* ......... */ + $"FFEF 0000 FFF0 00FF 0000 FFF7 0000 FFFB" /* ....... */ + $"0003 FF00 00FF F500 FFFF FF00 00FF FA00" /* ........ */ + $"00FF EC00 00FF C800 F400 FEFD 00FE FEF5" /* ...... */ + $"F800 00FF FE00 06FF 0000 FFFF 0000 FEFF" /* ........ */ + $"0000 FEFF FF00 FFFF FF00 03FF 00FF FFFE" /* ...... */ + $"0000 FFFD 00FF FFFE 0001 FF00 FEFF FE00" /* ....... */ + $"FFFF FF00 FEFF FD00 FFFF FF00 FEFF FD00" /* .... */ + $"FEFF FE00 FFFF FE00 FEFF FF00 FFFF FE00" /* .... */ + $"FEFF FC00 FFFF FF00 FEFF FC00 03FF 00FF" /* ..... */ + $"0002 FF00 FFFC 0000 FFFA 0002 FF00 FFFA" /* ........ */ + $"0000 FFFD 00FF FFFE 0001 FF00 FEFF FE00" /* ....... */ + $"FFFF FF00 FEFF F900 00FF FA00 02FF 0000" /* ....... */ + $"FEFF FF00 FDFF F700 FEFF FF00 FFFF FF00" /* .... */ + $"00FF FE00 04FF 0000 FFFF FE00 06FF 0000" /* ......... */ + $"FFFF 0000 FEFF FE00 FFFF FE00 FEFF FC00" /* ..... */ + $"FFFF FF00 FEFF FD00 FEFF 0000 FEFF FE00" /* ..... */ + $"FFFF FC00 0AFF 00FF 00FF 0000 FFFF 0000" /* ....... */ + $"FEFF 0800 FFFF 0000 FFFF 0000 FEFF FE00" /* ....... */ + $"FFFF FE00 00FF C800 F400 FEFD 0114 FEF5" /* ...... */ + $"F800 FDFF FF00 06FF 0000 FF00 00FF FE00" /* ........ */ + $"09FF 0000 FF00 00FF 00FF FFFC 0000 FFFE" /* ....... */ + $"0013 FF00 00FF 0000 FF00 FF00 00FF 00FF" /* .......... */ + $"0000 FF00 00FF FB00 02FF 00FF FA00 03FF" /* ......... */ + $"0000 FFFD 0002 FF00 FFFD 0008 FF00 00FF" /* ......... */ + $"00FF 0000 FFFD 0008 FF00 00FF 00FF 0000" /* .......... */ + $"FFFD 0003 FF00 FF00 02FF 00FF FB00 FEFF" /* ....... */ + $"FD00 02FF 00FF FA00 00FF FE00 13FF 0000" /* ......... */ + $"FF00 00FF 00FF 0000 FF00 FF00 00FF 0000" /* .......... */ + $"FFF9 0000 FFF9 0006 FF00 00FF 0000 FFFC" /* ........ */ + $"0000 FFF9 0027 FF00 00FF 00FF 0000 FF00" /* ...'...... */ + $"00FF 00FF 0000 FF00 00FF 0000 FF00 FF00" /* .......... */ + $"00FF 00FF 0000 FF00 FF00 00FF 00FF FF00" /* ......... */ + $"00FF FA00 03FF 0000 FFFB 000B FF00 00FF" /* ......... */ + $"0000 FF00 FF00 00FF FD00 04FF 00FF 00FF" /* ......... */ + $"FD00 03FF 0000 FFFE 000A FF00 FF00 00FF" /* ........ */ + $"00FF 0000 FFFD 0003 FF00 00FF C800 F400" /* ......... */ + $"FEFD 010C FEF5 F800 00FF FE00 01FF 00FD" /* ....... */ + $"FFFF 0000 FFFE 0002 FF00 00FD FF01 00FF" /* ........ */ + $"FB00 00FF FE00 FDFF FF00 06FF 00FF 0000" /* ........ */ + $"FF00 FDFF FF00 00FF FB00 04FF 0000 FFFF" /* ....... */ + $"FC00 05FF 0000 FF00 00FE FFFF 00FF FFFF" /* ....... */ + $"00FD FF04 00FF 0000 FFFD 0008 FF00 00FF" /* ......... */ + $"00FF 0000 FFFD 0003 FF00 00FF 02FF 00FF" /* ......... */ + $"F800 02FF 0000 FCFF FB00 00FF FE00 FDFF" /* ....... */ + $"FF00 06FF 00FF 0000 FF00 FDFF FF00 00FF" /* ........ */ + $"FA00 00FF F900 00FF FE00 03FF 0000 FFFC" /* ........ */ + $"0000 FFF9 0004 FF00 00FF 00FD FFFF 0004" /* ......... */ + $"FF00 FF00 00FD FFFF 000B FF00 FF00 00FF" /* ........ */ + $"00FF 0000 FF00 FDFF 0100 FFFF 0000 FFFC" /* ........ */ + $"00FE FFFF 0000 FFFB 0007 FF00 00FF 0000" /* ......... */ + $"FF00 FDFF FD00 06FF 0000 FFFF 0000 FEFF" /* ....... */ + $"FF00 00FF FE00 0CFF 00FF 0000 FF00 FF00" /* ......... */ + $"00FF 0000 FEFF FF00 00FF C800 F400 FEFD" /* ....... */ + $"0112 FEF5 F800 00FF FE00 02FF 00FF FC00" /* ........ */ + $"00FF FE00 03FF 0000 FFFD 0000 FFFB 0000" /* ......... */ + $"FFFE 0000 FFFC 0007 FF00 FF00 00FF 00FF" /* ........ */ + $"FC00 00FF FB00 00FF FD00 00FF FD00 08FF" /* ........ */ + $"0000 FF00 FF00 00FF FD00 02FF 00FF FD00" /* ......... */ + $"03FF 0000 FFFD 0008 FF00 00FF 00FF 0000" /* .......... */ + $"FFFD 0003 FF00 00FF 02FF 00FF FE00 02FF" /* ........ */ + $"00FF FE00 03FF 0000 FFFE 0000 FFFB 0000" /* ......... */ + $"FFFE 0000 FFFC 0007 FF00 FF00 00FF 00FF" /* ........ */ + $"FC00 00FF FB00 00FF F800 00FF FE00 05FF" /* ........ */ + $"0000 FF00 FFFE 0000 FFF9 0005 FF00 00FF" /* ......... */ + $"00FF FB00 00FF FE00 00FF FC00 0CFF 00FF" /* ........ */ + $"0000 FF00 FF00 00FF 00FF FD00 00FF FF00" /* ......... */ + $"00FF FD00 06FF 0000 FF00 00FF FB00 08FF" /* ......... */ + $"0000 FF00 00FF 00FF FA00 0CFF 0000 FFFF" /* ......... */ + $"00FF 0000 FF00 00FF FE00 12FF 00FF 0000" /* .......... */ + $"FF00 FF00 00FF 00FF 0000 FF00 00FF C800" /* ......... */ + $"F400 FEFD 0105 FEF5 F800 FDFF FE00 FFFF" /* ..... */ + $"FD00 00FF FE00 07FF 0000 FFFF 0000 FFFB" /* ........ */ + $"0000 FFFD 00FF FFFE 0009 FF00 FF00 00FF" /* ....... */ + $"0000 FFFF FD00 00FF FC00 01FF 00FE FFFC" /* ....... */ + $"00FE FFFE 00FE FF00 00FE FFFE 00FF FFFE" /* ..... */ + $"00FE FFFC 00FF FFFF 0003 FF00 00FF FD00" /* ....... */ + $"00FF FE00 02FF 0000 FEFF FE00 FEFF FE00" /* ....... */ + $"00FF FE00 00FF FB00 00FF FD00 FFFF FE00" /* ....... */ + $"09FF 00FF 0000 FF00 00FF FFFD 0000 FFFD" /* ....... */ + $"00FC FFFF 0000 FFFE 0000 FFFE 00FE FFFE" /* ...... */ + $"00FE FFFD 0000 FFFC 00FE FFFF 00FF FFFD" /* ..... */ + $"0000 FFFD 00FF FFFE 0006 FF00 00FF FF00" /* ........ */ + $"00FE FFFE 00FF FFFE 00FE FFFC 00FE FFFE" /* .... */ + $"0000 FFFB 0009 FF00 FF00 00FF 0000 FFFF" /* ........ */ + $"FC00 00FF FE00 02FF 0000 FEFF FE00 0FFF" /* ........ */ + $"0000 FF00 00FF FF00 00FF 0000 FF00 00FE" /* .......... */ + $"FFFF 0000 FFC8 00F4 00FE FD00 14FE F584" /* ...... */ + $"00AE 0000 FFE0 0000 FFF7 0081 00F4 00FE" /* ........ */ + $"FD00 14FE F584 00AF 0000 FFDF 0000 FFF7" /* ....... */ $"0081 00F4 00FE FD00 0CFE F584 0081 0081" /* ....... */ $"00F4 00FE FD00 0CFE F584 0081 0081 00F4" /* ....... */ - $"00FE FD00 0CFE F584 0081 0081 00F4 00FE" /* ....... */ + $"00FE FD00 14FE F584 00BD 0000 FFE7 0000" /* ........ */ + $"FFE1 0081 00F4 00FE FD00 86FE F5F7 00FE" /* ..... */ + $"FFF4 0000 FFF0 00FF FFF3 00FE FFCE 0000" /* ...... */ + $"FFFE 0000 FFFB 00F6 0000 FFF4 00FF FFFF" /* ...... */ + $"0000 FFF5 0000 FFFE 0000 FFED 0009 FF00" /* ........ */ + $"00FF FF00 00FF 0000 FEFF FE00 FEFF FC00" /* ....... */ + $"00FF FD00 00FF F600 00FF FB00 03FF 0000" /* ......... */ + $"FFF8 00FE 0000 FFFE 0000 FFFA 0000 FFEA" /* ....... */ + $"0003 FF00 00FF EF00 FFFF FD00 09FF 00FF" /* ....... */ + $"FF00 FFFF 0000 FFF5 0000 FFDB 00F4 00FE" /* ....... */ + $"FD00 79FE F5F8 0000 FFFE 0000 FFF5 0000" /* .y...... */ + $"FFF1 0000 FFF2 0000 FFFE 0000 FFCF 0000" /* ........ */ + $"FFF7 00F6 0000 FFF3 0000 FFF2 0000 FFEA" /* ....... */ + $"0000 FFFE 00FF FFFF 0002 FF00 FFFE 0002" /* ........ */ + $"FF00 FFFE 0000 FFFD 0000 FFFC 0000 FFF7" /* ....... */ + $"0000 FFFB 0003 FF00 00FF F800 FE00 00FF" /* ......... */ + $"FE00 00FF DF00 00FF F000 00FF FB00 06FF" /* ........ */ + $"0000 FF00 00FF CB00 F400 FEFD 012E FEF5" /* ........ */ + $"F800 00FF FB00 FFFF FF00 FEFF FF00 FEFF" /* ..... */ + $"FF00 FFFF FF00 03FF 00FF FFFD 00FE FFFF" /* ..... */ + $"00FF FFFF 0003 FF00 FFFF FD00 00FF FC00" /* ....... */ + $"04FF 0000 FF00 FEFF FE00 FFFF FF00 07FF" /* ....... */ + $"00FF FF00 00FF FFFE 00FF FFFF 00FE FF04" /* ...... */ + $"00FF FF00 00FE FFFF 0004 FF00 00FF 00FE" /* ........ */ + $"FF03 00FF FF00 FEFF FF00 0000 FEFF FB00" /* ....... */ + $"04FF 00FF 0000 FEFF FF00 FEFF FE00 07FF" /* ....... */ + $"00FF FF00 00FF FFFE 00FF FFFF 00FE FF08" /* ...... */ + $"00FF FF00 00FF FF00 00FE FFFE 00FE FFFD" /* ...... */ + $"0000 FFFE 0006 FF00 FF00 FF00 FFFC 0000" /* ......... */ + $"FFFA 0002 FF00 FFFD 0000 FFFC 00FF FFFF" /* ...... */ + $"00FE FFFD 00FE FF00 00FE FFFE 00FF FFFF" /* ..... */ + $"00FE 0000 FFFE 0001 FF00 FEFF FF00 FFFF" /* ....... */ + $"0100 FFFE 000C FF00 00FF FF00 00FF 00FF" /* ......... */ + $"FF00 00FE FF03 00FF FF00 FEFF 0400 FF00" /* ........ */ + $"00FF FB00 FFFF FF00 FEFF FC00 0AFF 0000" /* ...... */ + $"FF00 00FF 00FF FF00 FEFF FE00 FFFF FF00" /* ...... */ + $"FFFF FF00 FEFF E000 F400 FEFD 0134 FEF5" /* ....4 */ + $"F800 00FF FC00 14FF 0000 FF00 FF00 00FF" /* ......... */ + $"0000 FF00 00FF 0000 FF00 FFFF FA00 09FF" /* ........ */ + $"0000 FF00 00FF 00FF FFFA 00FE FFFF 0010" /* ........ */ + $"FF00 00FF 00FF 0000 FF00 FF00 00FF 00FF" /* ......... */ + $"FFFE 001D FF00 00FF 00FF 0000 FF00 FF00" /* ......... */ + $"00FF 0000 FF00 FF00 00FF 00FF 0000 FF00" /* .......... */ + $"00FF FE00 06FF 00FF 0000 FF00 03FF 0000" /* .......... */ + $"FFFB 0018 FF00 FF00 00FF 0000 FF00 FF00" /* ......... */ + $"00FF 0000 FF00 00FF 00FF 0000 FFFD 0003" /* .......... */ + $"FF00 00FF FE00 0CFF 00FF 0000 FF00 FF00" /* ......... */ + $"00FF 00FF FA00 00FF FE00 06FF 00FF 00FF" /* ........ */ + $"00FF FB00 FEFF FD00 02FF 00FF FD00 00FF" /* ....... */ + $"FA00 03FF 0000 FFFB 000C FF00 00FF 0000" /* .......... */ + $"FF00 FF00 00FF 00FE 0000 FFFE 0016 FF00" /* ......... */ + $"FF00 00FF 0000 FF00 00FF 00FF 0000 FF00" /* .......... */ + $"00FF 00FF FFFE 0000 FFFC 0009 FF00 00FF" /* ....... */ + $"0000 FF00 00FF FC00 06FF 0000 FF00 00FF" /* .......... */ + $"FB00 18FF 0000 FF00 00FF 0000 FF00 FF00" /* .......... */ + $"00FF 00FF 0000 FF00 00FF 00FF DD00 F400" /* ......... */ + $"FEFD 0126 FEF5 F800 00FF FC00 FDFF 0900" /* .&.... */ + $"FF00 00FF 0000 FF00 00FD FF01 00FF F900" /* ......... */ + $"08FF 0000 FF00 00FF 00FF F600 0BFF 00FF" /* ......... */ + $"0000 FF00 FF00 00FF 00FD FF01 00FF FD00" /* ......... */ + $"00FF FD00 18FF 0000 FF00 FF00 00FF 0000" /* .......... */ + $"FF00 FF00 00FF 00FF 0000 FF00 00FF FE00" /* ......... */ + $"06FF 00FF 0000 FF00 03FF 0000 FFFC 00FC" /* ......... */ + $"FF11 00FF 0000 FF00 FF00 00FF 0000 FF00" /* .......... */ + $"00FF 00FF FC00 FEFF FF00 00FF FE00 0EFF" /* ....... */ + $"00FF 0000 FF00 FF00 00FF 0000 FFFF FC00" /* ......... */ + $"00FF FE00 06FF 0000 FFFF 00FF F800 02FF" /* ........ */ + $"0000 FCFF FE00 00FF FC00 FEFF FF00 00FF" /* ....... */ + $"FB00 07FF 0000 FF00 00FF 00FD FF00 00FE" /* ......... */ + $"0000 FFFE 000F FF00 FF00 00FF 0000 FF00" /* .......... */ + $"00FF 00FF 0000 FDFF 0100 FFFC 00FF FFFE" /* ....... */ + $"0009 FF00 00FF 0000 FF00 00FF FC00 06FF" /* ......... */ + $"0000 FF00 00FF FB00 1AFF 0000 FF00 00FF" /* .......... */ + $"0000 FF00 FF00 00FF 00FF 0000 FF00 00FF" /* .......... */ + $"0000 FFFF DF00 F400 FEFD 013D FEF5 F800" /* .....=. */ + $"00FF FE00 02FF 00FF FD00 09FF 0000 FF00" /* ........ */ + $"00FF 0000 FFFD 0000 FFF9 0008 FF00 00FF" /* ......... */ + $"0000 FF00 FFFA 0000 FFFE 000C FF00 FF00" /* ......... */ + $"00FF 00FF 0000 FF00 FFFD 0000 FFFD 001D" /* ......... */ + $"FF00 00FF 00FF 0000 FF00 FF00 00FF 0000" /* .......... */ + $"FF00 FF00 00FF 00FF 0000 FF00 00FF FE00" /* ......... */ + $"06FF 00FF 0000 FF00 03FF 0000 FFFC 0000" /* .......... */ + $"FFFE 001D FF00 FF00 00FF 00FF 0000 FF00" /* ......... */ + $"00FF 0000 FF00 FF00 00FF 00FF 0000 FF00" /* .......... */ + $"00FF FE00 0AFF 00FF 0000 FF00 FF00 00FF" /* ........ */ + $"FD00 00FF FD00 00FF FE00 06FF 0000 FFFF" /* ........ */ + $"00FF FE00 02FF 00FF FE00 03FF 0000 FFFE" /* ........ */ + $"0000 FFFE 0000 FFFD 0006 FF00 00FF 0000" /* .......... */ + $"FFFB 0008 FF00 00FF 0000 FF00 FFFD 00FE" /* ........ */ + $"0000 FFFE 0008 FF00 FF00 00FF 0000 FFFE" /* ......... */ + $"0000 FFFE 0000 FFFD 0000 FFFA 000C FF00" /* ......... */ + $"00FF 0000 FF00 00FF 0000 FFFC 0006 FF00" /* .......... */ + $"00FF 0000 FFFB 0016 FF00 00FF 0000 FF00" /* .......... */ + $"00FF 00FF 0000 FF00 FF00 00FF 0000 FFFD" /* ......... */ + $"0000 FFE0 00F4 00FE FD01 22FE F5F7 00FE" /* .....". */ + $"FFFE 00FF FFFF 0003 FF00 00FF FE00 07FF" /* ....... */ + $"0000 FFFF 0000 FFF9 0000 FFFE 00FF FFFF" /* ....... */ + $"0000 FFF9 00FE FFFE 00FE FF00 00FE FFFE" /* ...... */ + $"00FF FFFF 0000 FFFC 00FF FFFE 00FF FFFF" /* ..... */ + $"0007 FF00 00FF 0000 FF00 FEFF FE00 FEFF" /* ........ */ + $"FE00 09FF 0000 FF00 FF00 00FF 0000 00FE" /* ......... */ + $"FFFC 0000 FFFE 0001 FF00 FEFF FF00 FEFF" /* ...... */ + $"FE00 07FF 0000 FF00 00FF FFFE 00FE FFFE" /* ....... */ + $"000E FF00 00FF 0000 FFFF 0000 FF00 00FF" /* .......... */ + $"00FE FFFB 0003 FF00 00FF FE00 02FF 0000" /* ......... */ + $"FEFF FE00 FEFF FE00 00FF FE00 03FF 0000" /* ....... */ + $"FFFB 00FE FFFE 0000 FFFB 000B FF00 FF00" /* ....... */ + $"00FF 0000 FFFF 0000 FD00 FEFF FF00 06FF" /* ........ */ + $"0000 FF00 00FF FE00 00FF FD00 FFFF FF00" /* ........ */ + $"00FF FD00 FEFF FE00 00FF FE00 02FF 0000" /* ........ */ + $"FEFF FB00 FFFF FE00 00FF FB00 12FF 0000" /* ....... */ + $"FF00 00FF 0000 FF00 FF00 00FF 0000 FFFF" /* ......... */ + $"FE00 01FF 00FE FFDF 00F4 00FE FD00 2CFE" /* ......, */ + $"F5BB 0000 FFE1 0000 FFEC 00FE 0000 FFF6" /* ....... */ + $"0000 FFFD 0000 FFD2 0000 FFE7 0000 FFE1" /* ........ */ + $"00D1 0000 FFB2 00F4 00FE FD00 24FE F5BB" /* ......$ */ + $"0000 FFE1 0000 FFEC 0002 00FF FFF5 0000" /* ......... */ + $"FFFD 0000 FF96 00D3 00FF FFB1 00F4 00FE" /* ...... */ $"FD00 0CFE F584 0081 0081 00F4 00FE FD00" /* ....... */ - $"0CFE F584 0081 0081 00F4 00FE FD00 6FFE" /* ......o */ - $"F5F8 0000 FFFE 0000 FFEE 00FD FFFE 00FE" /* ...... */ - $"FFFC 0000 FFFB 00FE FFF8 0000 FFF6 00FE" /* ...... */ - $"FFEA 0003 FF00 00FF F100 00FF F000 00FF" /* ........ */ - $"FC00 01FF 00FE FFFB 0000 FFEF 0000 FFFD" /* ....... */ - $"0000 FFFC 0001 FF00 FEFF FE00 FCFF D100" /* ....... */ - $"01FF 0001 00FF F000 00FF F700 FFFF F000" /* ........ */ - $"06FF 0000 FF00 00FF B900 F400 FEFD 0078" /* ........x */ - $"FEF5 F800 00FF FE00 00FF EE00 00FF FE00" /* ....... */ - $"02FF 00FF FE00 00FF FD00 00FF FB00 03FF" /* ........ */ - $"0000 FFF9 0000 FFF7 0000 FFFE 0000 FFE8" /* ........ */ - $"0000 FFF1 0000 FFF0 00FF FFFE 00FF FF04" /* ....... */ - $"00FF 0000 FFFD 00FF FFEF 0000 FFFD 00FF" /* ....... */ - $"FFFE 00FF FF07 00FF 0000 FF00 00FF CD00" /* ........ */ - $"01FF 00EE 0000 FFF6 0000 FFED 0003 FF00" /* ......... */ - $"00FF B900 F400 FEFD 0108 FEF5 F800 00FF" /* ....... */ - $"FE00 02FF 0000 FEFF FF00 FFFF FE00 FEFF" /* ...... */ - $"FD00 00FF FE00 02FF 00FF FA00 02FF 00FF" /* ........ */ - $"FC00 00FF FE00 06FF 0000 FFFF 0000 FEFF" /* ........ */ - $"FF00 FFFF FC00 00FF FB00 FFFF FE00 FFFF" /* ..... */ - $"FF00 0CFF 0000 FF00 FF00 FFFF 00FF FF00" /* ........ */ - $"FEFF 0400 FF00 00FF F700 01FF 00FE FFFE" /* ....... */ - $"00FF FFF9 0008 FF00 FF00 FF00 FF00 FFFE" /* ....... */ - $"0005 FF00 00FF 00FF FB00 FFFF FF00 FEFF" /* ....... */ - $"FE00 FEFF FD00 08FF 00FF 00FF 00FF 00FF" /* ....... */ - $"FE00 01FF 00FD FFFC 00FE FF02 00FF FFFE" /* ...... */ - $"00FF FFFE 00FE FFFF 00FE FFFF 00FF FFFE" /* .... */ - $"00FE FFFF 00FF FFFB 00FE FF00 00FF FFFF" /* ..... */ - $"00FE FFFF 00FF FFFE 00FE FF00 00FE FFFC" /* ..... */ - $"00FF FFFE 0002 FF00 00FE FFFF 00FF FFFF" /* ...... */ - $"0007 FF00 FFFF 00FF FF00 FEFF 0000 FEFF" /* ....... */ - $"FF00 FEFF 0200 FFFF FE00 FEFF C900 F400" /* ...... */ - $"FEFD 010F FEF5 F800 00FF FE00 02FF 00FF" /* ....... */ - $"FD00 05FF 0000 FF00 FFFA 00FD FFFE 00FE" /* ....... */ - $"FFFD 0002 FF00 FFFC 0000 FFFE 0000 FFFD" /* ....... */ - $"0003 FF00 00FF FC00 00FF FC00 FEFF FF00" /* ........ */ - $"10FF 0000 FF00 FF00 00FF 00FF 0000 FF00" /* .......... */ - $"FFFF FD00 09FF 0000 FF00 00FF 0000 FFF7" /* ....... */ - $"000A FF00 FF00 00FF 00FF 0000 FFFA 0008" /* ......... */ - $"FF00 00FF 0000 FF00 FFFE 0005 FF00 FF00" /* ......... */ - $"00FF F900 0AFF 00FF 0000 FF00 FF00 00FF" /* ........ */ - $"FD00 08FF 0000 FF00 00FF 00FF FE00 00FF" /* ......... */ - $"FC00 00FF FD00 0DFF 0000 FF00 00FF 00FF" /* ......... */ - $"0000 FF00 FFFD 0000 FFFA 000A FF00 FF00" /* ........ */ - $"00FF 00FF 0000 FFFD 0004 FF00 00FF 000D" /* .......... */ - $"00FF 00FF 0000 FF00 FF00 00FF 00FF FC00" /* ......... */ - $"00FF F900 10FF 0000 FF00 FF00 00FF 00FF" /* ......... */ - $"0000 FF00 FFFF FD00 13FF 0000 FF00 00FF" /* ......... */ - $"0000 FF00 FF00 00FF 0000 FF00 FFC6 00F4" /* ......... */ - $"00FE FD01 05FE F5F8 0000 FFFE 0006 FF00" /* ........ */ - $"00FF FF00 00FD FFFF 00FF FFFC 0002 FF00" /* ....... */ - $"FFFA 0002 FF00 00FC FFFD 0000 FFFE 0002" /* ........ */ - $"FF00 00FE FFFF 0000 FFFE 00FE FFF9 0001" /* ....... */ - $"FF00 FDFF 0100 FFFD 0005 FF00 00FF 00FF" /* ........ */ - $"FC00 09FF 0000 FF00 00FF 0000 FFF7 0007" /* ......... */ - $"FF00 FF00 00FF 00FF F700 00FF FC00 02FF" /* ........ */ - $"00FF FE00 01FF 00FC FFFC 00FE FF09 00FF" /* ...... */ - $"0000 FF00 FF00 00FF FD00 00FF FC00 02FF" /* ......... */ - $"00FF FE00 00FF FC00 00FF FD00 07FF 0000" /* ......... */ - $"FF00 00FF 00FD FFFF 00FF FFFE 00FF FFFE" /* ..... */ - $"00FE FF05 00FF 0000 FF00 FDFF FD00 04FF" /* ........ */ - $"0000 FF00 0700 FF00 FF00 00FF 00FD FFFF" /* ......... */ - $"00FF FFFE 0000 FFFB 00FE FFFF 000C FF00" /* ....... */ - $"FF00 00FF 00FF 0000 FF00 FFFC 0015 FF00" /* ......... */ - $"00FF 0000 FF00 00FF 00FF 0000 FF00 00FF" /* .......... */ - $"0000 FFFF C800 F400 FEFD 0116 FEF5 F800" /* ....... */ - $"00FF FE00 00FF FD00 02FF 00FF FA00 00FF" /* ........ */ - $"FD00 06FF 0000 FF00 00FF FE00 03FF 0000" /* .......... */ - $"FFFE 0000 FFFD 0012 FF00 00FF 0000 FF00" /* ......... */ - $"00FF 0000 FF00 00FF 0000 FFFD 0000 FFFE" /* ......... */ - $"0002 FF00 FFFD 000A FF00 00FF 00FF 0000" /* ......... */ - $"FF00 FFFC 0009 FF00 00FF 0000 FF00 00FF" /* ........ */ - $"F700 0AFF 00FF 0000 FF00 FF00 00FF FA00" /* ........ */ - $"00FF FC00 05FF 00FF 0000 FFFC 0000 FFFC" /* ........ */ - $"000D FF00 00FF 00FF 0000 FF00 FF00 00FF" /* .......... */ - $"FD00 00FF FC00 08FF 00FF 0000 FF00 00FF" /* ......... */ - $"FE00 00FF FD00 08FF 0000 FF00 00FF 00FF" /* ......... */ - $"FA00 00FF FD00 0CFF 00FF 0000 FF00 FF00" /* ......... */ - $"00FF 00FF FA00 04FF 0000 FF00 0800 FF00" /* .......... */ - $"FF00 00FF 00FF FA00 03FF 0000 FFFC 0012" /* ......... */ - $"FF00 00FF 0000 FF00 FF00 00FF 00FF 0000" /* .......... */ - $"FF00 FFFC 0011 FF00 00FF 0000 FF00 00FF" /* ......... */ - $"00FF 0000 FF00 00FF FD00 00FF C900 F400" /* ......... */ - $"FEFD 0107 FEF5 F700 FEFF FF00 FEFF FE00" /* ..... */ - $"FFFF FF00 FEFF FC00 00FF FE00 02FF 0000" /* ....... */ - $"FEFF FE00 00FF FE00 00FF FD00 FEFF FD00" /* ...... */ - $"FEFF FE00 02FF 0000 FEFF FC00 FEFF FE00" /* ...... */ - $"FFFF FE00 FFFF FE00 FEFF 0100 FFFC 0000" /* ...... */ - $"FFFE 0002 FF00 00FE FFFD 0000 FFFC 0009" /* ....... */ - $"FF00 FF00 00FF 0000 FFFF FE00 00FF FD00" /* ........ */ - $"00FF FC00 01FF 00FE FFFB 0000 FFFB 00FE" /* ....... */ - $"FF06 00FF 0000 FF00 00FE FFFD 0000 FFFC" /* ........ */ - $"0001 FF00 FEFF FD00 FEFF FC00 0CFF 0000" /* ........ */ - $"FF00 00FF 0000 FFFF 0000 FEFF FF00 FEFF" /* ....... */ - $"FE00 FEFF FF00 FEFF FF00 FFFF FB00 FEFF" /* .... */ - $"0000 0300 FF00 00FE FFFF 00FF FFFF 00FE" /* ........ */ - $"FFFD 0000 FFFC 00FE FFFF 0002 FF00 00FE" /* ....... */ - $"FFFF 00FF FFFF 0000 FFFC 0000 FFFE 000E" /* ....... */ - $"FF00 FF00 00FF 00FF 0000 FF00 00FF 00FE" /* ......... */ - $"FFFE 0000 FFCC 00F4 00FE FD00 20FE F58F" /* ..... */ - $"0000 FFFD 0000 FFFC 0090 0000 FFF3 00FB" /* ........ */ - $"0000 FFE4 0000 FFA6 00F4 00FE FD00 20FE" /* ....... */ - $"F591 00FF FFFD 0000 FFFB 0092 00FF FFF2" /* ..... */ - $"00FD 00FF FFE5 00FF FFA5 00F4 00FE FD00" /* ...... */ - $"0CFE F584 0081 0081 00F4 00FE FD00 0CFE" /* ....... */ - $"F584 0081 0081 00F4 00FE FD00 21FE F5A7" /* .....! */ - $"0002 FF00 FFEC 0000 FFF7 00E4 0002 FF00" /* ......... */ - $"FFA1 0083 0001 F5FF 00F6 F500 FEFD 0063" /* ......c */ - $"FEF5 F800 FCFF FB00 00FF EA00 00FF F500" /* ...... */ - $"FFFF FB00 FFFF EB00 02FF 00FF FA00 03FF" /* ...... */ - $"0000 FFF6 0000 FFF7 00FE FFFF 00FE FFFE" /* ...... */ - $"00FD FF00 00FD FFF8 0002 FF00 FFFD 0000" /* ........ */ - $"FFF0 0000 FFE5 00FE FFF8 00FE FFFE 0000" /* ...... */ - $"FFF4 0000 FFF5 0084 0002 F5FE AB00 F5F5" /* ...... */ - $"00FE FD00 6AFE F5F6 0000 FFF9 0000 FFEA" /* ..j.... */ - $"0000 FFF4 0000 FFFC 0000 FFE9 0002 FF00" /* ......... */ - $"FFFA 0000 FFF4 0000 FFF7 0000 FFFE 0008" /* ........ */ - $"FF00 FF00 00FF 0000 FFFD 0000 FFF6 0002" /* ......... */ - $"FF00 FFFC 0000 FFF0 0000 FFE6 0000 FFFE" /* ....... */ - $"0000 FFFA 0000 FFFE 0003 FF00 00FF F400" /* ......... */ - $"00FF F500 8500 03F5 A9FD 00F4 00FE FD00" /* ....... */ - $"C9FE F5F6 0000 FFFD 00FF FFFF 00FE FFFB" /* .... */ - $"00FF FFFE 00FF FFFF 00FE FFFF 00FE FF08" /* ..... */ - $"00FF 00FF FF00 00FF FFFE 0000 FFFD 00FE" /* ....... */ - $"FF0A 00FF 00FF FF00 00FF FF00 00FE FF02" /* ....... */ - $"00FF FFF1 0004 FF00 FFFF 00FE FF02 00FF" /* ....... */ - $"FFFA 00FE FFFD 0000 FFFC 0000 FFFE 0002" /* ....... */ - $"FF00 FFFD 0000 FFFC 00FE FFF6 00FE FFFF" /* ..... */ - $"0003 FF00 00FF F800 06FF 0000 FFFF 0000" /* .......... */ - $"FEFF 0200 FFFF FE00 FFFF FE00 FEFF FD00" /* ..... */ - $"00FF F600 00FF FC00 FEFF FF00 FFFF FF00" /* ...... */ - $"04FF 0000 FF00 FEFF F600 9100 0FA3 7FA3" /* ........ */ - $"7FA3 7FA3 7FA3 7FA3 7FA3 FF81 F807 78F8" /* ......x */ - $"78F8 78F8 78F8 FC00 FEFD 00D5 FEF5 F600" /* xxx... */ - $"00FF FB00 05FF 00FF 0000 FFFD 0014 FF00" /* ......... */ - $"00FF 00FF 0000 FF00 FF00 00FF 0000 FF00" /* .......... */ - $"00FF FFFE 0006 FF00 00FF 0000 FFFC 0004" /* ......... */ - $"FF00 00FF FFFE 000B FF00 00FF 00FF 0000" /* ......... */ - $"FF00 00FF F200 0BFF 0000 FF00 FF00 00FF" /* ......... */ - $"0000 FFFC 0000 FFFA 0000 FFFC 0000 FFFE" /* ........ */ - $"0001 FF00 FEFF FF00 FEFF FF00 00FF F300" /* ....... */ - $"08FF 0000 FF00 FF00 00FF F800 00FF FD00" /* ......... */ - $"0FFF 00FF 0000 FF00 00FF 00FF 0000 FF00" /* .......... */ - $"FFFA 0004 FF00 00FF FFF9 00FE FFFE 000E" /* ....... */ - $"FF00 00FF 0000 FF00 FF00 00FF 0000 FFF5" /* ......... */ - $"0091 000F 7FA3 7FA3 7FA3 7FA3 7FA3 7FA3" /* ......... */ - $"A9AC F878 07F8 78F8 78F8 78F8 78FC 00FE" /* x.xxxx. */ - $"FD00 DAFE F5F6 0000 FFFD 00FE FF04 00FF" /* ...... */ - $"0000 FFFD 0000 FFFD 000E FF00 00FF 00FF" /* ......... */ - $"0000 FF00 00FF 0000 FFFD 0006 FF00 00FF" /* .......... */ - $"0000 FFFC 0003 FF00 00FF FD00 0BFF 0000" /* .......... */ - $"FF00 FF00 00FF 0000 FFF6 0000 FFFE 000B" /* ......... */ - $"FF00 00FF 00FF 0000 FF00 00FF FB00 FFFF" /* ........ */ - $"FC00 00FF FC00 00FF FE00 02FF 00FF FD00" /* ........ */ - $"00FF FC00 FFFF F500 08FF 0000 FF00 FF00" /* ........ */ - $"00FF FC00 00FF FE00 02FF 0000 FEFF 0800" /* ......... */ - $"FF00 00FF 0000 FF00 FDFF FF00 FFFF FC00" /* ....... */ - $"00FF FE00 00FF F600 11FF 0000 FF00 00FF" /* ......... */ - $"0000 FF00 FF00 00FF 0000 FFF5 0091 000F" /* .......... */ - $"A37F A37F A37F AAAA A37F A37F FD81 78F8" /* .....x */ - $"07D0 CF78 F878 F878 F8FC 00FE FD00 E2FE" /* .xxx.. */ - $"F5F6 0000 FFFE 0008 FF00 00FF 00FF 0000" /* ......... */ - $"FFFD 0013 FF00 00FF 00FF 0000 FF00 FF00" /* ......... */ - $"00FF 0000 FF00 00FF FD00 06FF 0000 FF00" /* .......... */ - $"00FF FC00 03FF 0000 FFFD 000B FF00 00FF" /* ......... */ - $"00FF 0000 FF00 00FF F600 00FF FE00 0BFF" /* ......... */ - $"0000 FF00 FF00 00FF 0000 FFF9 0000 FFFD" /* ......... */ - $"0000 FFFE 0008 FF00 FF00 00FF 0000 FFFD" /* ......... */ - $"0000 FFFA 0000 FFF6 0008 FF00 00FF 00FF" /* ......... */ - $"0000 FFFC 0000 FFFE 000F FF00 FF00 00FF" /* ......... */ - $"00FF 0000 FF00 00FF 00FF FA00 00FF FD00" /* ......... */ - $"00FF FE00 00FF FA00 00FF FE00 11FF 0000" /* ......... */ - $"FF00 00FF 0000 FF00 FF00 00FF 0000 FFF5" /* ......... */ - $"0091 000F 7FA3 7FA3 7FA3 AAEF 7FA3 7FA9" /* ........ */ - $"AC78 F878 07FF CFF8 78F8 78F8 78FC 00FE" /* xx.xxx. */ - $"FD00 C9FE F5F6 0000 FFFD 00FE FF00 00FE" /* ...... */ - $"FFFB 00FF FFFE 00FF FFFF 0003 FF00 00FF" /* ...... */ - $"FE00 02FF 00FF FC00 FFFF FE00 00FF FC00" /* ....... */ - $"03FF 0000 FFFC 00FF FFFF 0006 FF00 00FF" /* ........ */ - $"0000 FFF5 00FE FFFE 0008 FF00 FF00 00FF" /* ........ */ - $"0000 FFFC 00FE FFFB 00FE FFFF 00FE FFFE" /* ..... */ - $"00FD FF01 00FF FD00 FEFF F500 FEFF FE00" /* ...... */ - $"FEFF FB00 FEFF FE00 FEFF 0D00 FF00 00FF" /* ...... */ - $"0000 FF00 00FF FF00 00FE FFFB 00FE FFFE" /* ....... */ - $"0000 FFFC 00FE FFFD 0004 FF00 00FF FFFE" /* ....... */ - $"00FE FFFE 0003 FF00 00FF F900 9100 0FA3" /* ........ */ - $"7FA3 7FA3 7FAA EFA3 7FA3 FE81 F878 F807" /* ....x. */ - $"FFCF 78F8 78F8 78F8 FC00 FEFD 002A FEF5" /* xxx..* */ - $"8400 D500 00FF AE00 9100 0F7F A37F A37F" /* ......... */ - $"A3CD EF7F A3FB FFF8 78F8 7907 FFCF F878" /* .xy.x */ - $"F878 F878 FC00 FEFD 002A FEF5 8400 D700" /* xx..*.. */ - $"FFFF AD00 9100 0FA3 7FA3 7FA3 7FA3 7FA3" /* ....... */ - $"7FA9 AC78 F878 F807 78F8 78F8 78F8 78F8" /* .xx.xxxx */ - $"FC00 FEFD 0026 FEF5 8400 8100 9100 0F7F" /* ..&..... */ - $"A37F A37F A37F A37F A3FF 80F8 78F8 7807" /* ....xx. */ - $"F878 F878 F878 F878 FC00 FEFD 0026 FEF5" /* xxxx..& */ - $"8400 8100 9100 0FA3 7FA3 7FA3 7FA3 7FA3" /* ........ */ - $"FBFF 8078 F878 F807 78F8 78F8 78F8 78F8" /* xx.xxxx */ - $"FC00 FEFD 0026 FEF5 8400 8100 9100 0F7F" /* ..&..... */ - $"A37F A37F A37F A37F A9FF 80F8 79F8 7807" /* ....yx. */ - $"F878 F878 F878 F878 FC00 FEFD 0026 FEF5" /* xxxx..& */ - $"8400 8100 9100 0AA3 7FA3 7FA3 7FA3 7FA3" /* ...£.... */ - $"A9E0 FEFF 0180 5507 78F8 78F8 78F8 78F8" /* .U.xxxx */ - $"FC00 FEFD 0026 FEF5 8400 8100 9100 0F7F" /* ..&..... */ - $"A37F A37F A37F A37F A37F A37F FF80 7907" /* ......y. */ - $"F878 F878 F878 F878 FC00 FEFD 0062 FEF5" /* xxxx..b */ - $"F700 FEFF F900 00FF F400 00FF AE00 00FF" /* ....... */ - $"FC00 F900 FDFF E400 00FF FA00 00FF FC00" /* ....... */ - $"00FF F400 00FF F600 00FF F700 00FF FC00" /* ........ */ - $"00FF F200 00FF FD00 FFFF FA00 F900 00FF" /* ....... */ - $"9A00 0FA3 7FA3 7FEF AAA3 7FA3 7FA3 7FA3" /* ....画... */ - $"FF80 F807 79F8 79A4 CFF8 78F8 FC00 FEFD" /* .yyx. */ - $"0063 FEF5 F800 00FF F600 00FF F400 00FF" /* .c...... */ - $"AE00 00FF FC00 F900 00FF FE00 00FF E500" /* ........ */ - $"00FF FA00 00FF FC00 00FF F400 00FF F600" /* ........ */ - $"00FF F700 00FF FC00 00FF F200 00FF FE00" /* ........ */ - $"00FF F800 F900 00FF 9A00 067F A37F A3AA" /* ........ */ - $"EFD4 FBAA 02FF A481 07A4 81FF FFA4 78F8" /* ..x */ - $"78FC 00FE FD00 F6FE F5F8 0000 FFFC 00FE" /* x..... */ - $"FFFE 0004 FF00 00FF FFFD 00FE FFFF 0003" /* ....... */ - $"FF00 FFFF FD00 FEFF FE00 FEFF 0800 FF00" /* ...... */ - $"FFFF 0000 FFFF FD00 FFFF FE00 03FF 00FF" /* ...... */ - $"FFFD 000A FF00 FFFF 0000 FFFF 0000 FFFE" /* ...... */ - $"0004 FF00 00FF FFFD 0006 FF00 FFFF 00FF" /* ........ */ - $"FFFE 00FE FFFC 00FE FFFE 0000 FFFE 0000" /* ...... */ - $"FFFE 0000 FFFE 0007 FF00 FF00 FFFF 00FF" /* ....... */ - $"FE00 03FF 00FF FFFD 0003 FF00 FFFF FB00" /* ....... */ - $"00FF FA00 FFFF FE00 FFFF FF00 00FF FE00" /* ...... */ - $"02FF 0000 FEFF 0800 FF00 FFFF 0000 FFFF" /* ........ */ - $"FD00 00FF FE00 FFFF FC00 FFFF FE00 FFFF" /* ..... */ - $"FE00 FEFF FE00 04FF 00FF FF00 FAFF FF00" /* ...... */ - $"FEFF FE00 05FF 00FF FF00 00FE FF9A 0008" /* ....... */ - $"A37F A37F A37F A9B0 EFFE D403 EFFF D6FF" /* .... */ - $"07FF AC81 7955 F878 F8FC 00FE FD01 07FE" /* .yUx... */ - $"F5F7 00FF FFFE 0006 FF00 00FF 0000 FFFD" /* ....... */ - $"0003 FF00 00FF FC00 FFFF 0100 FFFE 0000" /* ......... */ - $"FFFC 0000 FFFD 00FF FF12 00FF 00FF 0000" /* ........ */ - $"FF00 00FF 0000 FF00 00FF FF00 FFFD 00FF" /* ........ */ - $"FF0B 00FF 00FF 0000 FF00 00FF 00FF FC00" /* ......... */ - $"00FF FE00 FFFF 0400 FFFF 00FF FE00 03FF" /* ....... */ - $"0000 FFFD 0005 FF00 00FF 0000 0300 FF00" /* ........... */ - $"FFFD 00FD FFFF 00FF FF06 00FF 0000 FF00" /* ....... */ - $"FFFD 0000 FFFE 00FF FF01 00FF FB00 00FF" /* ....... */ - $"FA00 FFFF FE00 FFFF FE00 05FF 00FF 0000" /* ....... */ - $"FFFD 00FF FF01 00FF FD00 00FF FE00 06FF" /* ....... */ - $"0000 FF00 00FF FD00 FFFF FE00 FFFF FF00" /* ....... */ - $"00FF FE00 09FF 0000 FFFF 00FF 0000 FFFE" /* ....... */ - $"0003 FF00 00FF FE00 02FF 0000 FFFF 0600" /* .......... */ - $"FF00 FF00 00FF 9A00 0F7F A37F A37F A37F" /* ......... */ - $"A380 A380 A3AA FF80 7807 F878 F878 F878" /* x.xxx */ - $"F878 FC00 FEFD 00FF FEF5 F500 0BFF 0000" /* x...... */ - $"FF00 00FF 0000 FF00 00FE FFFE 00FF FFFE" /* ....... */ - $"0003 FF00 00FF FD00 FFFF FE00 00FF FD00" /* ........ */ - $"00FF FD00 FDFF FF00 FDFF FF00 03FF 0000" /* ....... */ - $"FFFD 0000 FFFD 00FD FFFF 0002 FF00 FFFE" /* ...... */ - $"00FE FFFE 0006 FF00 00FF 0000 FFFE 0003" /* ......... */ - $"FF00 00FF FD00 05FF 0000 FF00 0003 00FF" /* .......... */ - $"00FF FD00 00FF FE00 02FF 00FF FC00 04FF" /* ........ */ - $"00FF 0000 FEFF FE00 03FF 0000 FFFB 0000" /* ......... */ - $"FFFA 0006 FF00 FF00 FF00 FFFE 0005 FF00" /* ........ */ - $"FF00 00FF FD00 05FF 0000 FF00 00FE FFFE" /* ........ */ - $"0002 FF00 00FD FFFD 0009 FF00 FF00 FF00" /* ........ */ - $"FF00 00FF FE00 09FF 0000 FF00 00FF 0000" /* ......... */ - $"FFFE 0003 FF00 00FF FE00 02FF 0000 00FF" /* ......... */ - $"FD00 03FF 0000 FF9A 000F A37F A37F A37F" /* ......... */ - $"A37F A37F A37F A3FE 8055 0778 F878 F878" /* ...U.xxx */ - $"F878 F8FC 00FE FD01 03FE F5F5 000E FF00" /* x...... */ - $"00FF 0000 FF00 00FF 00FF 0000 FFFC 0006" /* .......... */ - $"FF00 00FF 0000 FFFB 0003 FF00 00FF FD00" /* ......... */ - $"00FF FD00 00FF FC00 00FF FC00 03FF 0000" /* ......... */ - $"FFFD 0000 FFFD 0000 FFFB 0000 FFFE 0003" /* ........ */ - $"FF00 00FF FE00 06FF 0000 FF00 00FF FE00" /* ......... */ - $"03FF 0000 FFFD 0005 FF00 00FF 0000 0300" /* ........... */ - $"FF00 FFFD 0000 FFFE 0002 FF00 FFFC 0007" /* ........ */ - $"FF00 FF00 FF00 00FF FE00 03FF 0000 FFFB" /* ........ */ - $"0003 FF00 00FF FD00 06FF 00FF 00FF 00FF" /* ......... */ - $"FE00 05FF 00FF 0000 FFFD 0008 FF00 00FF" /* ......... */ - $"00FF 0000 FFFE 0003 FF00 00FF FA00 09FF" /* ........ */ - $"00FF 00FF 00FF 0000 FFFE 0009 FF00 00FF" /* ........ */ - $"0000 FF00 00FF FE00 03FF 0000 FFFE 0002" /* .......... */ - $"FF00 0000 FFFD 0003 FF00 00FF 9A00 0F7F" /* .......... */ - $"A37F A37F A37F A37F A37F A37F A9FD 7907" /* ......y. */ - $"F879 F878 F878 F878 FC00 FEFD 00D4 FEF5" /* yxxx.. */ - $"F800 FEFF FE00 FEFF FE00 02FF 0000 FEFF" /* ...... */ - $"FF00 FEFF FE00 03FF 0000 FFFE 00FE FFFD" /* ...... */ - $"00FE FF01 00FF FC00 FEFF FE00 FEFF FF00" /* ...... */ - $"03FF 0000 FFFD 0000 FFFC 00FE FFFE 0000" /* ........ */ - $"FFFD 00FE FFFE 0006 FF00 00FF 0000 FFFE" /* ....... */ - $"00FE FFFC 00FE FFFE 00FF 0000 FFFC 00FD" /* ...... */ - $"FFFF 0000 FFFB 0000 FFFE 00FE FFFE 0003" /* ....... */ - $"FF00 00FF FE00 FEFF FE00 00FF FD00 06FF" /* ....... */ - $"0000 FF00 00FF FD00 00FF FD00 FEFF 0600" /* ......... */ - $"FF00 00FF 0000 FEFF FE00 00FF FE00 FEFF" /* ....... */ - $"FD00 06FF 0000 FF00 00FF FE00 FEFF FE00" /* ........ */ - $"03FF 0000 FFFE 00FF FF01 00FF FE00 FEFF" /* ....... */ - $"FE00 00FF FC00 FEFF 8D00 02F9 F400 F400" /* ....... */ - $"FEFD 0024 FEF5 F200 00FF A200 00FF F400" /* .$..... */ - $"FF00 00FF EF00 00FF DB00 00FF BE00 8400" /* ........ */ - $"02F5 FFF8 F400 FEFD 0024 FEF5 F200 00FF" /* ...$.. */ - $"A200 00FF F400 0100 FFEF 0000 FFDB 0000" /* ......... */ - $"FFBD 0083 0001 81FE 00F6 F500 FEFD 0010" /* ....... */ - $"FEF5 8400 8100 8200 0056 00F6 F500 FEFD" /* ....V.. */ + $"0CFE F584 0081 0081 00F4 00FE FD00 14FE" /* ....... */ + $"F594 0000 FFF2 00FA 0000 FF89 0081 00F4" /* ....... */ + $"00FE FD00 42FE F5F2 0000 FFFC 0000 FFFE" /* ..B.... */ + $"0000 FFFB 0000 FFE8 00FE FFFF 0000 FFE5" /* ....... */ + $"0000 FFF2 0003 FF00 00FF FE00 05FF 0000" /* .......... */ + $"FF00 FFFE 0000 FFFF 00FE FFFE 0000 FF8A" /* ...... */ + $"0081 00F4 00FE FD00 44FE F5F2 0000 FFFC" /* ....D.. */ + $"0000 FFFE 0000 FFFB 0000 FFE9 0000 FFFE" /* ........ */ + $"0002 FF00 FFD6 0000 FFFE 0000 FFFE 0005" /* ......... */ + $"FF00 00FF 00FF FE00 00FF 0100 FFFE 0000" /* ......... */ + $"FFFE 0000 FF8B 0081 00F4 00FE FD00 72FE" /* ......r */ + $"F5F7 00FF FFFF 00FE FFFD 0000 FFFE 0006" /* ...... */ + $"FF00 FF00 FFFF 00FE FFFE 00FF FFFF 00FE" /* ..... */ + $"FFFE 00FF FFFA 0000 FFFC 00FE FFFE 00FF" /* ..... */ + $"FFFF 00FE FF04 00FF FF00 00FE FFFE 00FF" /* ...... */ + $"FFFF 00FF FFFF 00FE FF00 00FE FFFC 0000" /* ...... */ + $"FFFE 0000 FFFE 0005 FF00 00FF 00FF FE00" /* ........ */ + $"00FF 0100 FFFA 0000 FF8B 0081 00F4 00FE" /* ........ */ + $"FD00 7BFE F5F5 0003 FF00 00FF FC00 00FF" /* .{...... */ + $"FE00 03FF 00FF FFFE 0003 FF00 00FF FD00" /* ........ */ + $"05FF 00FF 0000 FFFD 0001 FF00 FDFF 0100" /* ......... */ + $"FFFC 0003 FF00 00FF FD00 0DFF 00FF 0000" /* ......... */ + $"FF00 00FF 00FF 0000 FFFD 000D FF00 00FF" /* ......... */ + $"00FF 0000 FF00 FF00 00FF FD00 00FF FE00" /* ......... */ + $"00FF FE00 05FF 0000 FF00 FFFE 0000 FF01" /* ......... */ + $"00FF FA00 00FF 8B00 8100 F400 FEFD 007C" /* .......| */ + $"FEF5 F700 FEFF FF00 00FF FC00 00FF FE00" /* ...... */ + $"02FF 00FF FD00 05FF 0000 FF00 00FE FF06" /* ......... */ + $"00FF 0000 FF00 00FE FFFB 0000 FFFC 0005" /* ......... */ + $"FF00 00FF 0000 FEFF 0E00 FF00 00FF 0000" /* .......... */ + $"FF00 FF00 00FF 0000 FEFF FF00 0AFF 00FF" /* ....... */ + $"0000 FF00 FF00 00FF FD00 00FF FE00 00FF" /* ......... */ + $"FE00 05FF 0000 FF00 FFFE 0000 FF01 00FF" /* ......... */ + $"FA00 00FF 8B00 8100 F400 FEFD 0085 FEF5" /* ...... */ + $"F800 06FF 0000 FF00 00FF FC00 00FF FE00" /* ......... */ + $"02FF 00FF FD00 12FF 0000 FF00 FF00 00FF" /* ......... */ + $"00FF 0000 FF00 FF00 00FF FB00 00FF FE00" /* ......... */ + $"29FF 00FF 0000 FF00 FF00 00FF 00FF 0000" /* )......... */ + $"FF00 00FF 00FF 0000 FF00 FF00 00FF 0000" /* .......... */ + $"FF00 FF00 00FF 00FF 0000 FFFD 0000 FFFE" /* ........ */ + $"0000 FFFE 0005 FF00 00FF 00FF FE00 00FF" /* ......... */ + $"0100 FFFE 0000 FFFE 0000 FF8B 0081 00F4" /* ........ */ + $"00FE FD00 77FE F5F7 00FE FFFE 0000 FFFC" /* ..w... */ + $"00FE FFFF 0000 FFFD 00FE FFFE 00FE FF06" /* ...... */ + $"00FF 0000 FF00 00FE FFFA 00FE FFFF 0005" /* ........ */ + $"FF00 00FF 0000 FEFF 0800 FF00 00FF 0000" /* .......... */ + $"FF00 FEFF FE00 FEFF FF00 02FF 0000 FEFF" /* ...... */ + $"0400 FF00 00FF FC00 00FF FE00 FEFF FE00" /* ........ */ + $"02FF 0000 FEFF 0000 FF00 FEFF FE00 00FF" /* ........ */ + $"FE00 00FF 8E00 8100 F400 FEFD 001C FEF5" /* ....... */ + $"B000 00FF F200 00FF F600 00FF F200 FA00" /* ........ */ + $"00FF 8900 8100 F400 FEFD 0014 FEF5 B000" /* ....... */ + $"00FF F400 FFFF E500 8100 8100 F400 FEFD" /* ...... */ + $"000C FEF5 8400 8100 8100 F400 FEFD 000C" /* ........ */ + $"FEF5 8400 8100 8100 F400 FEFD 000C FEF5" /* ...... */ + $"8400 8100 8100 F400 FEFD 000C FEF5 8400" /* ....... */ + $"8100 8100 F400 FEFD 000C FEF5 8400 8100" /* ....... */ + $"8100 F400 FEFD 000C FEF5 8400 8100 8100" /* ....... */ + $"F400 FEFD 000C FEF5 8400 8100 8100 F400" /* ....... */ + $"FEFD 000C FEF5 8400 8100 8100 F400 FEFD" /* ...... */ + $"000C FEF5 8400 8100 8100 F400 FEFD 000C" /* ........ */ + $"FEF5 8400 8100 8100 F400 FEFD 000C FEF5" /* ...... */ + $"8400 8100 8100 F400 FEFD 000C FEF5 8400" /* ....... */ + $"8100 8100 F400 FEFD 000C FEF5 8400 8100" /* ....... */ + $"8100 F400 FEFD 0024 FEF5 A700 00FF FC00" /* ...$... */ + $"00FF E500 CF00 00FF D800 00FF EA00 00FF" /* ........ */ + $"F600 ED00 00FF 9600 F400 FEFD 0065 FEF5" /* ......e */ + $"F800 FFFF FD00 FFFF FA00 FFFF F800 FDFF" /* .... */ + $"FE00 FFFF FF00 FFFF F100 00FF FC00 00FF" /* ...... */ + $"FE00 00FF F200 00FF FC00 00FF E500 F600" /* ........ */ + $"00FF E200 00FF FB00 06FF 0000 FFFF 00FF" /* ........ */ + $"FB00 00FF E500 00FF EA00 03FF 0000 FFFA" /* ........ */ + $"0000 FF00 FFF5 0000 FFFB 0000 FF96 00F4" /* ........ */ + $"00FE FD00 64FE F5F8 00FF FFFD 00FF FFFA" /* ..d.. */ + $"00FF FFF9 00FF FFFF 00FF FFFB 00FF FFF1" /* .... */ + $"0000 FFFC 0000 FFFE 0000 FFF3 0000 FFFC" /* ........ */ + $"0000 FFE4 00F6 0000 FFE2 0000 FFFC 0006" /* ......... */ + $"FF00 00FF 00FF FFFA 0000 FFE6 0000 FFEA" /* ....... */ + $"0000 FFFE 0000 FFF9 0000 FFF5 0000 FFFC" /* ........ */ + $"0000 FF95 00F4 00FE FD00 D2FE F5F7 00FB" /* ...... */ + $"FFFE 00FE FFFF 00FD FFFB 00FF FFFC 00FE" /* .... */ + $"FF00 00FD FFFF 00FE FFFD 00FF FFFD 00FE" /* ..... */ + $"FFFF 00FE FF00 00FE FF00 00FE FFFD 0000" /* ....... */ + $"FFFD 0000 FFFC 0003 FF00 00FF FC00 02FF" /* ........ */ + $"00FF FC00 02FF 00FF FC00 00FF FD00 0200" /* ......... */ + $"FFFF FE00 FEFF 0000 FEFF FF00 FFFF FF00" /* ..... */ + $"FEFF FE00 FFFF FC00 FEFF FE00 FFFF FF00" /* .... */ + $"FEFF FD00 00FF F900 04FF 00FF FF00 FEFF" /* ...... */ + $"FF00 0EFF 00FF FF00 00FF FF00 00FF 0000" /* ......... */ + $"FF00 FEFF FC00 02FF 0000 FEFF 0200 FFFF" /* ....... */ + $"FE00 FFFF FE00 FFFF FC00 02FF 0000 FEFF" /* ...... */ + $"FF00 FFFF FE00 01FF 00FE FFFE 00FF FFFF" /* ..... */ + $"00FE FFFD 0000 FF95 00F4 00FE FD00 E8FE" /* ...... */ + $"F5F7 00FB FFFF 00FF FF08 00FF FF00 FFFF" /* ..... */ + $"00FF FFFB 00FD FFFE 00FF FFFF 00FF FFFF" /* .... */ + $"00FF FF02 00FF FFF8 0006 FF00 00FF 0000" /* ......... */ + $"FFFE 0006 FF00 00FF 0000 FFFA 0000 FFFC" /* ........ */ + $"0000 FFFD 0004 FF00 FF00 FFFE 0004 FF00" /* ......... */ + $"FF00 FFFE 0004 FF00 FF00 FFFC 0005 FF00" /* ........ */ + $"00FF 00FF FC00 10FF 0000 FF00 00FF 00FF" /* ......... */ + $"0000 FF00 FF00 00FF FD00 0BFF 0000 FF00" /* .......... */ + $"FF00 00FF 0000 FFFD 0000 FFF8 00FF FFFE" /* ....... */ + $"0006 FF00 00FF 00FF FFFB 000A FF00 FF00" /* ........ */ + $"00FF 00FF 0000 FFFE 0000 FFFE 0006 FF00" /* ......... */ + $"00FF 0000 FFFD 0005 FF00 FF00 00FF FE00" /* ......... */ + $"00FF FD00 08FF 0000 FF00 00FF 0000 0DFF" /* .......... */ + $"00FF 0000 FF00 FF00 00FF 0000 FFFD 0000" /* .......... */ + $"FF94 00F4 00FE FD00 D8FE F5F6 00FD FFFE" /* .... */ + $"00FC FF05 00FF FF00 FFFF F800 FFFF FF00" /* ...... */ + $"FFFF FF00 FFFF FF00 FCFF F800 06FF 0000" /* ...... */ + $"FF00 00FF FE00 06FF 0000 FF00 00FF FA00" /* ......... */ + $"00FF FC00 00FF FD00 04FF 00FF 00FF FE00" /* ........ */ + $"04FF 00FF 00FF FE00 04FF 00FF 00FF FC00" /* ........ */ + $"00FF FC00 FFFF FE00 0CFF 0000 FF00 00FF" /* ........ */ + $"00FF 0000 FF00 FDFF FD00 04FF 0000 FF00" /* ......... */ + $"FDFF FF00 00FF FD00 00FF F800 00FF FD00" /* ....... */ + $"05FF 0000 FF00 FFFC 00FE FF09 00FF 0000" /* ........ */ + $"FF00 FF00 00FF FE00 00FF FE00 08FF 0000" /* ......... */ + $"FF00 00FF 0000 FEFF 0100 FFFB 0000 FFFD" /* ........ */ + $"0002 FF00 00FD FFFF 0006 FF00 FF00 00FF" /* ......... */ + $"00FD FFFF 0000 FFFD 0000 FF94 00F4 00FE" /* ....... */ + $"FD00 D8FE F5F6 00FD FFFE 00FF FFFD 00FF" /* .... */ + $"FF02 00FF FFFC 00FF FFFF 00FF FFFF 00FF" /* ..... */ + $"FFFF 00FF FFFF 00FF FFF5 0006 FF00 00FF" /* ...... */ + $"0000 FFFE 0006 FF00 00FF 0000 FFFB 0000" /* .......... */ + $"FFFC 0000 FFFB 0002 FF00 FFFC 0002 FF00" /* ........ */ + $"FFFC 0002 FF00 FFFB 0003 FF00 00FF FD00" /* ........ */ + $"10FF 0000 FF00 00FF 0000 FF00 FF00 00FF" /* .......... */ + $"00FF FA00 05FF 0000 FF00 FFFC 0000 FFFE" /* ........ */ + $"0000 FFF7 0000 FFFD 0005 FF00 00FF 00FF" /* ......... */ + $"FD00 10FF 0000 FF00 FF00 00FF 00FF 0000" /* .......... */ + $"FF00 00FF FD00 13FF 0000 FF00 00FF 00FF" /* ......... */ + $"0000 FF00 FF00 00FF 0000 FFFC 0003 FF00" /* .......... */ + $"00FF FC00 07FF 00FF 0000 FF00 FFFC 0000" /* ......... */ + $"FFFE 0000 FF93 00F4 00FE FD00 D9FE F5F6" /* ..... */ + $"00FD FFFD 00FE FFFF 00FD FFFA 00FD FFFE" /* .... */ + $"00FF FFFE 00FF FFFF 00FE FFFD 00FF FFFD" /* .... */ + $"0003 FF00 00FF FE00 00FF FE00 01FF 00FE" /* ......... */ + $"FFFD 0003 FF00 00FF FC00 00FF FB00 02FF" /* ........ */ + $"00FF FC00 02FF 00FF FC00 02FF 00FF FD00" /* ........ */ + $"01FF 0004 00FF FF00 00FE FFFD 000E FF00" /* ......... */ + $"00FF FF00 00FF 0000 FF00 00FF FFFE 0009" /* ........ */ + $"FF00 FF00 00FF 0000 FFFF FD00 03FF 0000" /* ......... */ + $"FFF7 0000 FFFD 00FE FFFF 0000 FFFC 00FE" /* ...... */ + $"FFFF 00FE FF07 00FF 0000 FF00 00FF FD00" /* ........ */ + $"08FF 0000 FF00 00FF 0000 FEFF FF00 FFFF" /* ........ */ + $"FE00 00FF FB00 04FF 0000 FFFF FE00 09FF" /* ....... */ + $"00FF 0000 FF00 00FF FFFD 0003 FF00 00FF" /* ......... */ + $"9300 F400 FEFD 0010 FEF5 B400 00FF D200" /* ....... */ + $"8100 8100 F400 FEFD 0010 FEF5 B400 00FF" /* ....... */ + $"D200 8100 8100 F400 FEFD 000C FEF5 8400" /* ....... */ + $"8100 8100 F400 FEFD 000C FEF5 8400 8100" /* ....... */ + $"8100 F400 FEFD 000C FEF5 8400 8100 8100" /* ....... */ + $"F400 FEFD 000C FEF5 8400 8100 8100 F400" /* ....... */ + $"FEFD 000C FEF5 8400 8100 8100 F400 FEFD" /* ...... */ $"000C FEF5 8400 8100 8100 F400 FEFD 000C" /* ........ */ $"FEF5 8400 8100 8100 F400 FEFD 000C FEF5" /* ...... */ $"8400 8100 8100 F400 FEFD 000C FEF5 8400" /* ....... */ - $"8100 8100 F400 FEFD 0010 FFF5 0056 84AC" /* ......V */ - $"81AC 81AC F4AC 02FE FDFD 000E 01F5 5683" /* ....V */ - $"AC81 AC81 ACF3 AC01 FEFD 000C 0056 82AC" /* ....V */ - $"81AC 81AC F2AC 00FE 00FF" /* .. */ + $"8100 8100 F400 FEFD 000C FEF5 8400 8100" /* ....... */ + $"8100 F400 FEFD 000C FEF5 8400 8100 8100" /* ....... */ + $"F400 FEFD 000C FEF5 8400 8100 8100 F400" /* ....... */ + $"FEFD 000C FEF5 8400 8100 8100 F400 FEFD" /* ...... */ + $"006F FEF5 F800 00FF FE00 00FF EE00 FDFF" /* .o..... */ + $"FE00 FEFF FC00 00FF FB00 FEFF F800 00FF" /* ...... */ + $"F600 FEFF EA00 03FF 0000 FFF1 0000 FFF0" /* ....... */ + $"0000 FFFC 0001 FF00 FEFF FB00 00FF EF00" /* ........ */ + $"00FF FD00 00FF FC00 01FF 00FE FFFE 00FC" /* ....... */ + $"FFD1 0001 FF00 0100 FFF0 0000 FFF7 00FF" /* ........ */ + $"FFF0 0006 FF00 00FF 0000 FFB9 00F4 00FE" /* ........ */ + $"FD00 78FE F5F8 0000 FFFE 0000 FFEE 0000" /* .x...... */ + $"FFFE 0002 FF00 FFFE 0000 FFFD 0000 FFFB" /* ....... */ + $"0003 FF00 00FF F900 00FF F700 00FF FE00" /* ......... */ + $"00FF E800 00FF F100 00FF F000 FFFF FE00" /* ....... */ + $"FFFF 0400 FF00 00FF FD00 FFFF EF00 00FF" /* ....... */ + $"FD00 FFFF FE00 FFFF 0700 FF00 00FF 0000" /* ........ */ + $"FFCD 0001 FF00 EE00 00FF F600 00FF ED00" /* ........ */ + $"03FF 0000 FFB9 00F4 00FE FD01 08FE F5F8" /* ....... */ + $"0000 FFFE 0002 FF00 00FE FFFF 00FF FFFE" /* ....... */ + $"00FE FFFD 0000 FFFE 0002 FF00 FFFA 0002" /* ........ */ + $"FF00 FFFC 0000 FFFE 0006 FF00 00FF FF00" /* ........ */ + $"00FE FFFF 00FF FFFC 0000 FFFB 00FF FFFE" /* ..... */ + $"00FF FFFF 000C FF00 00FF 00FF 00FF FF00" /* ........ */ + $"FFFF 00FE FF04 00FF 0000 FFF7 0001 FF00" /* ........ */ + $"FEFF FE00 FFFF F900 08FF 00FF 00FF 00FF" /* ...... */ + $"00FF FE00 05FF 0000 FF00 FFFB 00FF FFFF" /* ....... */ + $"00FE FFFE 00FE FFFD 0008 FF00 FF00 FF00" /* ....... */ + $"FF00 FFFE 0001 FF00 FDFF FC00 FEFF 0200" /* ....... */ + $"FFFF FE00 FFFF FE00 FEFF FF00 FEFF FF00" /* .... */ + $"FFFF FE00 FEFF FF00 FFFF FB00 FEFF 0000" /* ..... */ + $"FFFF FF00 FEFF FF00 FFFF FE00 FEFF 0000" /* ..... */ + $"FEFF FC00 FFFF FE00 02FF 0000 FEFF FF00" /* ...... */ + $"FFFF FF00 07FF 00FF FF00 FFFF 00FE FF00" /* ...... */ + $"00FE FFFF 00FE FF02 00FF FFFE 00FE FFC9" /* ..... */ + $"00F4 00FE FD01 0FFE F5F8 0000 FFFE 0002" /* ........ */ + $"FF00 FFFD 0005 FF00 00FF 00FF FA00 FDFF" /* ....... */ + $"FE00 FEFF FD00 02FF 00FF FC00 00FF FE00" /* ....... */ + $"00FF FD00 03FF 0000 FFFC 0000 FFFC 00FE" /* ........ */ + $"FFFF 0010 FF00 00FF 00FF 0000 FF00 FF00" /* ......... */ + $"00FF 00FF FFFD 0009 FF00 00FF 0000 FF00" /* ........ */ + $"00FF F700 0AFF 00FF 0000 FF00 FF00 00FF" /* ........ */ + $"FA00 08FF 0000 FF00 00FF 00FF FE00 05FF" /* ......... */ + $"00FF 0000 FFF9 000A FF00 FF00 00FF 00FF" /* ........ */ + $"0000 FFFD 0008 FF00 00FF 0000 FF00 FFFE" /* ......... */ + $"0000 FFFC 0000 FFFD 000D FF00 00FF 0000" /* .......... */ + $"FF00 FF00 00FF 00FF FD00 00FF FA00 0AFF" /* ....... */ + $"00FF 0000 FF00 FF00 00FF FD00 04FF 0000" /* .......... */ + $"FF00 0D00 FF00 FF00 00FF 00FF 0000 FF00" /* .......... */ + $"FFFC 0000 FFF9 0010 FF00 00FF 00FF 0000" /* ......... */ + $"FF00 FF00 00FF 00FF FFFD 0013 FF00 00FF" /* ........ */ + $"0000 FF00 00FF 00FF 0000 FF00 00FF 00FF" /* .......... */ + $"C600 F400 FEFD 0105 FEF5 F800 00FF FE00" /* ....... */ + $"06FF 0000 FFFF 0000 FDFF FF00 FFFF FC00" /* ....... */ + $"02FF 00FF FA00 02FF 0000 FCFF FD00 00FF" /* ........ */ + $"FE00 02FF 0000 FEFF FF00 00FF FE00 FEFF" /* ....... */ + $"F900 01FF 00FD FF01 00FF FD00 05FF 0000" /* ......... */ + $"FF00 FFFC 0009 FF00 00FF 0000 FF00 00FF" /* ........ */ + $"F700 07FF 00FF 0000 FF00 FFF7 0000 FFFC" /* ........ */ + $"0002 FF00 FFFE 0001 FF00 FCFF FC00 FEFF" /* ....... */ + $"0900 FF00 00FF 00FF 0000 FFFD 0000 FFFC" /* ........ */ + $"0002 FF00 FFFE 0000 FFFC 0000 FFFD 0007" /* ......... */ + $"FF00 00FF 0000 FF00 FDFF FF00 FFFF FE00" /* ....... */ + $"FFFF FE00 FEFF 0500 FF00 00FF 00FD FFFD" /* ...... */ + $"0004 FF00 00FF 0007 00FF 00FF 0000 FF00" /* ........... */ + $"FDFF FF00 FFFF FE00 00FF FB00 FEFF FF00" /* ..... */ + $"0CFF 00FF 0000 FF00 FF00 00FF 00FF FC00" /* ......... */ + $"15FF 0000 FF00 00FF 0000 FF00 FF00 00FF" /* .......... */ + $"0000 FF00 00FF FFC8 00F4 00FE FD01 16FE" /* ........ */ + $"F5F8 0000 FFFE 0000 FFFD 0002 FF00 FFFA" /* ....... */ + $"0000 FFFD 0006 FF00 00FF 0000 FFFE 0003" /* .......... */ + $"FF00 00FF FE00 00FF FD00 12FF 0000 FF00" /* ......... */ + $"00FF 0000 FF00 00FF 0000 FF00 00FF FD00" /* .......... */ + $"00FF FE00 02FF 00FF FD00 0AFF 0000 FF00" /* ........ */ + $"FF00 00FF 00FF FC00 09FF 0000 FF00 00FF" /* ........ */ + $"0000 FFF7 000A FF00 FF00 00FF 00FF 0000" /* ......... */ + $"FFFA 0000 FFFC 0005 FF00 FF00 00FF FC00" /* ........ */ + $"00FF FC00 0DFF 0000 FF00 FF00 00FF 00FF" /* ......... */ + $"0000 FFFD 0000 FFFC 0008 FF00 FF00 00FF" /* ......... */ + $"0000 FFFE 0000 FFFD 0008 FF00 00FF 0000" /* .......... */ + $"FF00 FFFA 0000 FFFD 000C FF00 FF00 00FF" /* ........ */ + $"00FF 0000 FF00 FFFA 0004 FF00 00FF 0008" /* .......... */ + $"00FF 00FF 0000 FF00 FFFA 0003 FF00 00FF" /* ......... */ + $"FC00 12FF 0000 FF00 00FF 00FF 0000 FF00" /* .......... */ + $"FF00 00FF 00FF FC00 11FF 0000 FF00 00FF" /* ......... */ + $"0000 FF00 FF00 00FF 0000 FFFD 0000 FFC9" /* ......... */ + $"00F4 00FE FD01 07FE F5F7 00FE FFFF 00FE" /* ...... */ + $"FFFE 00FF FFFF 00FE FFFC 0000 FFFE 0002" /* ...... */ + $"FF00 00FE FFFE 0000 FFFE 0000 FFFD 00FE" /* ....... */ + $"FFFD 00FE FFFE 0002 FF00 00FE FFFC 00FE" /* ...... */ + $"FFFE 00FF FFFE 00FF FFFE 00FE FF01 00FF" /* ..... */ + $"FC00 00FF FE00 02FF 0000 FEFF FD00 00FF" /* ........ */ + $"FC00 09FF 00FF 0000 FF00 00FF FFFE 0000" /* ........ */ + $"FFFD 0000 FFFC 0001 FF00 FEFF FB00 00FF" /* ....... */ + $"FB00 FEFF 0600 FF00 00FF 0000 FEFF FD00" /* ........ */ + $"00FF FC00 01FF 00FE FFFD 00FE FFFC 000C" /* ....... */ + $"FF00 00FF 0000 FF00 00FF FF00 00FE FFFF" /* ........ */ + $"00FE FFFE 00FE FFFF 00FE FFFF 00FF FFFB" /* .... */ + $"00FE FF00 0003 00FF 0000 FEFF FF00 FFFF" /* ........ */ + $"FF00 FEFF FD00 00FF FC00 FEFF FF00 02FF" /* ...... */ + $"0000 FEFF FF00 FFFF FF00 00FF FC00 00FF" /* ....... */ + $"FE00 0EFF 00FF 0000 FF00 FF00 00FF 0000" /* .......... */ + $"FF00 FEFF FE00 00FF CC00 F400 FEFD 0020" /* ...... */ + $"FEF5 8F00 00FF FD00 00FF FC00 9000 00FF" /* ....... */ + $"F300 FB00 00FF E400 00FF A600 F400 FEFD" /* ....... */ + $"0020 FEF5 9100 FFFF FD00 00FF FB00 9200" /* . ..... */ + $"FFFF F200 FD00 FFFF E500 FFFF A500 F400" /* ..... */ + $"FEFD 000C FEF5 8400 8100 8100 F400 FEFD" /* ...... */ + $"000C FEF5 8400 8100 8100 F400 FEFD 0021" /* .......! */ + $"FEF5 A700 02FF 00FF EC00 00FF F700 E400" /* ....... */ + $"02FF 00FF A100 8300 01F5 FF00 F6F5 00FE" /* ....... */ + $"FD00 63FE F5F8 00FC FFFB 0000 FFEA 0000" /* .c..... */ + $"FFF5 00FF FFFB 00FF FFEB 0002 FF00 FFFA" /* ..... */ + $"0003 FF00 00FF F600 00FF F700 FEFF FF00" /* ........ */ + $"FEFF FE00 FDFF 0000 FDFF F800 02FF 00FF" /* ...... */ + $"FD00 00FF F000 00FF E500 FEFF F800 FEFF" /* ...... */ + $"FE00 00FF F400 00FF F500 8400 02F5 FEAB" /* ....... */ + $"00F5 F500 FEFD 006A FEF5 F600 00FF F900" /* ...j... */ + $"00FF EA00 00FF F400 00FF FC00 00FF E900" /* ........ */ + $"02FF 00FF FA00 00FF F400 00FF F700 00FF" /* ........ */ + $"FE00 08FF 00FF 0000 FF00 00FF FD00 00FF" /* ......... */ + $"F600 02FF 00FF FC00 00FF F000 00FF E600" /* ........ */ + $"00FF FE00 00FF FA00 00FF FE00 03FF 0000" /* ......... */ + $"FFF4 0000 FFF5 0085 0003 F5A9 FD00 F400" /* ....... */ + $"FEFD 00C9 FEF5 F600 00FF FD00 FFFF FF00" /* ..... */ + $"FEFF FB00 FFFF FE00 FFFF FF00 FEFF FF00" /* .... */ + $"FEFF 0800 FF00 FFFF 0000 FFFF FE00 00FF" /* ....... */ + $"FD00 FEFF 0A00 FF00 FFFF 0000 FFFF 0000" /* ....... */ + $"FEFF 0200 FFFF F100 04FF 00FF FF00 FEFF" /* ...... */ + $"0200 FFFF FA00 FEFF FD00 00FF FC00 00FF" /* ....... */ + $"FE00 02FF 00FF FD00 00FF FC00 FEFF F600" /* ....... */ + $"FEFF FF00 03FF 0000 FFF8 0006 FF00 00FF" /* ........ */ + $"FF00 00FE FF02 00FF FFFE 00FF FFFE 00FE" /* ...... */ + $"FFFD 0000 FFF6 0000 FFFC 00FE FFFF 00FF" /* ...... */ + $"FFFF 0004 FF00 00FF 00FE FFF6 0091 000F" /* ........ */ + $"A37F A37F A37F A37F A37F A37F A3FF 81F8" /* ...... */ + $"0778 F878 F878 F878 F8FC 00FE FD00 D5FE" /* .xxxx.. */ + $"F5F6 0000 FFFB 0005 FF00 FF00 00FF FD00" /* ........ */ + $"14FF 0000 FF00 FF00 00FF 00FF 0000 FF00" /* .......... */ + $"00FF 0000 FFFF FE00 06FF 0000 FF00 00FF" /* ......... */ + $"FC00 04FF 0000 FFFF FE00 0BFF 0000 FF00" /* ......... */ + $"FF00 00FF 0000 FFF2 000B FF00 00FF 00FF" /* ......... */ + $"0000 FF00 00FF FC00 00FF FA00 00FF FC00" /* ......... */ + $"00FF FE00 01FF 00FE FFFF 00FE FFFF 0000" /* ....... */ + $"FFF3 0008 FF00 00FF 00FF 0000 FFF8 0000" /* ......... */ + $"FFFD 000F FF00 FF00 00FF 0000 FF00 FF00" /* ......... */ + $"00FF 00FF FA00 04FF 0000 FFFF F900 FEFF" /* ....... */ + $"FE00 0EFF 0000 FF00 00FF 00FF 0000 FF00" /* .......... */ + $"00FF F500 9100 0F7F A37F A37F A37F A37F" /* ......... */ + $"A37F A3A9 ACF8 7807 F878 F878 F878 F878" /* .x.xxxx */ + $"FC00 FEFD 00DA FEF5 F600 00FF FD00 FEFF" /* ..... */ + $"0400 FF00 00FF FD00 00FF FD00 0EFF 0000" /* .......... */ + $"FF00 FF00 00FF 0000 FF00 00FF FD00 06FF" /* ......... */ + $"0000 FF00 00FF FC00 03FF 0000 FFFD 000B" /* .......... */ + $"FF00 00FF 00FF 0000 FF00 00FF F600 00FF" /* ......... */ + $"FE00 0BFF 0000 FF00 FF00 00FF 0000 FFFB" /* ......... */ + $"00FF FFFC 0000 FFFC 0000 FFFE 0002 FF00" /* ........ */ + $"FFFD 0000 FFFC 00FF FFF5 0008 FF00 00FF" /* ....... */ + $"00FF 0000 FFFC 0000 FFFE 0002 FF00 00FE" /* ......... */ + $"FF08 00FF 0000 FF00 00FF 00FD FFFF 00FF" /* ........ */ + $"FFFC 0000 FFFE 0000 FFF6 0011 FF00 00FF" /* ........ */ + $"0000 FF00 00FF 00FF 0000 FF00 00FF F500" /* .......... */ + $"9100 0FA3 7FA3 7FA3 7FAA AAA3 7FA3 7FFD" /* ....... */ + $"8178 F807 D0CF 78F8 78F8 78F8 FC00 FEFD" /* x.xxx. */ + $"00E2 FEF5 F600 00FF FE00 08FF 0000 FF00" /* ........ */ + $"FF00 00FF FD00 13FF 0000 FF00 FF00 00FF" /* ......... */ + $"00FF 0000 FF00 00FF 0000 FFFD 0006 FF00" /* .......... */ + $"00FF 0000 FFFC 0003 FF00 00FF FD00 0BFF" /* ......... */ + $"0000 FF00 FF00 00FF 0000 FFF6 0000 FFFE" /* ......... */ + $"000B FF00 00FF 00FF 0000 FF00 00FF F900" /* .......... */ + $"00FF FD00 00FF FE00 08FF 00FF 0000 FF00" /* ......... */ + $"00FF FD00 00FF FA00 00FF F600 08FF 0000" /* ......... */ + $"FF00 FF00 00FF FC00 00FF FE00 0FFF 00FF" /* ........ */ + $"0000 FF00 FF00 00FF 0000 FF00 FFFA 0000" /* .......... */ + $"FFFD 0000 FFFE 0000 FFFA 0000 FFFE 0011" /* ........ */ + $"FF00 00FF 0000 FF00 00FF 00FF 0000 FF00" /* .......... */ + $"00FF F500 9100 0F7F A37F A37F A3AA EF7F" /* ........ */ + $"A37F A9AC 78F8 7807 FFCF F878 F878 F878" /* .xx.xxx */ + $"FC00 FEFD 00C9 FEF5 F600 00FF FD00 FEFF" /* ..... */ + $"0000 FEFF FB00 FFFF FE00 FFFF FF00 03FF" /* ...... */ + $"0000 FFFE 0002 FF00 FFFC 00FF FFFE 0000" /* ........ */ + $"FFFC 0003 FF00 00FF FC00 FFFF FF00 06FF" /* ....... */ + $"0000 FF00 00FF F500 FEFF FE00 08FF 00FF" /* ........ */ + $"0000 FF00 00FF FC00 FEFF FB00 FEFF FF00" /* ....... */ + $"FEFF FE00 FDFF 0100 FFFD 00FE FFF5 00FE" /* ..... */ + $"FFFE 00FE FFFB 00FE FFFE 00FE FF0D 00FF" /* ..... */ + $"0000 FF00 00FF 0000 FFFF 0000 FEFF FB00" /* ......... */ + $"FEFF FE00 00FF FC00 FEFF FD00 04FF 0000" /* ....... */ + $"FFFF FE00 FEFF FE00 03FF 0000 FFF9 0091" /* ...... */ + $"000F A37F A37F A37F AAEF A37F A3FE 81F8" /* ...... */ + $"78F8 07FF CF78 F878 F878 F8FC 00FE FD00" /* x.xxx.. */ + $"2AFE F584 00D5 0000 FFAE 0091 000F 7FA3" /* *....... */ + $"7FA3 7FA3 CDEF 7FA3 FBFF F878 F879 07FF" /* ...xy. */ + $"CFF8 78F8 78F8 78FC 00FE FD00 2AFE F584" /* xxx..* */ + $"00D7 00FF FFAD 0091 000F A37F A37F A37F" /* ........ */ + $"A37F A37F A9AC 78F8 78F8 0778 F878 F878" /* ..xx.xxx */ + $"F878 F8FC 00FE FD00 26FE F584 0081 0091" /* x..&.. */ + $"000F 7FA3 7FA3 7FA3 7FA3 7FA3 FF80 F878" /* .......x */ + $"F878 07F8 78F8 78F8 78F8 78FC 00FE FD00" /* x.xxxx.. */ + $"26FE F584 0081 0091 000F A37F A37F A37F" /* &....... */ + $"A37F A3FB FF80 78F8 78F8 0778 F878 F878" /* .xx.xxx */ + $"F878 F8FC 00FE FD00 26FE F584 0081 0091" /* x..&.. */ + $"000F 7FA3 7FA3 7FA3 7FA3 7FA9 FF80 F879" /* .......y */ + $"F878 07F8 78F8 78F8 78F8 78FC 00FE FD00" /* x.xxxx.. */ + $"26FE F584 0081 0091 000A A37F A37F A37F" /* &...£... */ + $"A37F A3A9 E0FE FF01 8055 0778 F878 F878" /* ..U.xxx */ + $"F878 F8FC 00FE FD00 26FE F584 0081 0091" /* x..&.. */ + $"000F 7FA3 7FA3 7FA3 7FA3 7FA3 7FA3 7FFF" /* ......... */ + $"8079 07F8 78F8 78F8 78F8 78FC 00FE FD00" /* y.xxxx.. */ + $"62FE F5F7 00FE FFF9 0000 FFF4 0000 FFAE" /* b..... */ + $"0000 FFFC 00F9 00FD FFE4 0000 FFFA 0000" /* ........ */ + $"FFFC 0000 FFF4 0000 FFF6 0000 FFF7 0000" /* ........ */ + $"FFFC 0000 FFF2 0000 FFFD 00FF FFFA 00F9" /* ...... */ + $"0000 FF9A 000F A37F A37F EFAA A37F A37F" /* ......画.. */ + $"A37F A3FF 80F8 0779 F879 A4CF F878 F8FC" /* ..yyx */ + $"00FE FD00 63FE F5F8 0000 FFF6 0000 FFF4" /* ..c.... */ + $"0000 FFAE 0000 FFFC 00F9 0000 FFFE 0000" /* ......... */ + $"FFE5 0000 FFFA 0000 FFFC 0000 FFF4 0000" /* ........ */ + $"FFF6 0000 FFF7 0000 FFFC 0000 FFF2 0000" /* ........ */ + $"FFFE 0000 FFF8 00F9 0000 FF9A 0006 7FA3" /* ........ */ + $"7FA3 AAEF D4FB AA02 FFA4 8107 A481 FFFF" /* ... */ + $"A478 F878 FC00 FEFD 00F6 FEF5 F800 00FF" /* xx.... */ + $"FC00 FEFF FE00 04FF 0000 FFFF FD00 FEFF" /* ...... */ + $"FF00 03FF 00FF FFFD 00FE FFFE 00FE FF08" /* ...... */ + $"00FF 00FF FF00 00FF FFFD 00FF FFFE 0003" /* ....... */ + $"FF00 FFFF FD00 0AFF 00FF FF00 00FF FF00" /* ...... */ + $"00FF FE00 04FF 0000 FFFF FD00 06FF 00FF" /* ........ */ + $"FF00 FFFF FE00 FEFF FC00 FEFF FE00 00FF" /* ..... */ + $"FE00 00FF FE00 00FF FE00 07FF 00FF 00FF" /* ........ */ + $"FF00 FFFE 0003 FF00 FFFF FD00 03FF 00FF" /* ....... */ + $"FFFB 0000 FFFA 00FF FFFE 00FF FFFF 0000" /* ...... */ + $"FFFE 0002 FF00 00FE FF08 00FF 00FF FF00" /* ........ */ + $"00FF FFFD 0000 FFFE 00FF FFFC 00FF FFFE" /* ..... */ + $"00FF FFFE 00FE FFFE 0004 FF00 FFFF 00FA" /* ...... */ + $"FFFF 00FE FFFE 0005 FF00 FFFF 0000 FEFF" /* ...... */ + $"9A00 08A3 7FA3 7FA3 7FA9 B0EF FED4 03EF" /* ...... */ + $"FFD6 FF07 FFAC 8179 55F8 78F8 FC00 FEFD" /* .yUx. */ + $"0107 FEF5 F700 FFFF FE00 06FF 0000 FF00" /* ........ */ + $"00FF FD00 03FF 0000 FFFC 00FF FF01 00FF" /* ........ */ + $"FE00 00FF FC00 00FF FD00 FFFF 1200 FF00" /* ........ */ + $"FF00 00FF 0000 FF00 00FF 0000 FFFF 00FF" /* ......... */ + $"FD00 FFFF 0B00 FF00 FF00 00FF 0000 FF00" /* ......... */ + $"FFFC 0000 FFFE 00FF FF04 00FF FF00 FFFE" /* ...... */ + $"0003 FF00 00FF FD00 05FF 0000 FF00 0003" /* ........... */ + $"00FF 00FF FD00 FDFF FF00 FFFF 0600 FF00" /* ....... */ + $"00FF 00FF FD00 00FF FE00 FFFF 0100 FFFB" /* ....... */ + $"0000 FFFA 00FF FFFE 00FF FFFE 0005 FF00" /* ....... */ + $"FF00 00FF FD00 FFFF 0100 FFFD 0000 FFFE" /* ....... */ + $"0006 FF00 00FF 0000 FFFD 00FF FFFE 00FF" /* ........ */ + $"FFFF 0000 FFFE 0009 FF00 00FF FF00 FF00" /* ....... */ + $"00FF FE00 03FF 0000 FFFE 0002 FF00 00FF" /* ......... */ + $"FF06 00FF 00FF 0000 FF9A 000F 7FA3 7FA3" /* ......... */ + $"7FA3 7FA3 80A3 80A3 AAFF 8078 07F8 78F8" /* ..x.x */ + $"78F8 78F8 78FC 00FE FD00 FFFE F5F5 000B" /* xxx.... */ + $"FF00 00FF 0000 FF00 00FF 0000 FEFF FE00" /* ......... */ + $"FFFF FE00 03FF 0000 FFFD 00FF FFFE 0000" /* ....... */ + $"FFFD 0000 FFFD 00FD FFFF 00FD FFFF 0003" /* ...... */ + $"FF00 00FF FD00 00FF FD00 FDFF FF00 02FF" /* ....... */ + $"00FF FE00 FEFF FE00 06FF 0000 FF00 00FF" /* ........ */ + $"FE00 03FF 0000 FFFD 0005 FF00 00FF 0000" /* .......... */ + $"0300 FF00 FFFD 0000 FFFE 0002 FF00 FFFC" /* ........ */ + $"0004 FF00 FF00 00FE FFFE 0003 FF00 00FF" /* ......... */ + $"FB00 00FF FA00 06FF 00FF 00FF 00FF FE00" /* ........ */ + $"05FF 00FF 0000 FFFD 0005 FF00 00FF 0000" /* .......... */ + $"FEFF FE00 02FF 0000 FDFF FD00 09FF 00FF" /* ...... */ + $"00FF 00FF 0000 FFFE 0009 FF00 00FF 0000" /* ......... */ + $"FF00 00FF FE00 03FF 0000 FFFE 0002 FF00" /* ......... */ + $"0000 FFFD 0003 FF00 00FF 9A00 0FA3 7FA3" /* ......... */ + $"7FA3 7FA3 7FA3 7FA3 7FA3 FE80 5507 78F8" /* .....U.x */ + $"78F8 78F8 78F8 FC00 FEFD 0103 FEF5 F500" /* xxx.... */ + $"0EFF 0000 FF00 00FF 0000 FF00 FF00 00FF" /* .......... */ + $"FC00 06FF 0000 FF00 00FF FB00 03FF 0000" /* .......... */ + $"FFFD 0000 FFFD 0000 FFFC 0000 FFFC 0003" /* ........ */ + $"FF00 00FF FD00 00FF FD00 00FF FB00 00FF" /* ........ */ + $"FE00 03FF 0000 FFFE 0006 FF00 00FF 0000" /* .......... */ + $"FFFE 0003 FF00 00FF FD00 05FF 0000 FF00" /* ......... */ + $"0003 00FF 00FF FD00 00FF FE00 02FF 00FF" /* ......... */ + $"FC00 07FF 00FF 00FF 0000 FFFE 0003 FF00" /* ......... */ + $"00FF FB00 03FF 0000 FFFD 0006 FF00 FF00" /* ......... */ + $"FF00 FFFE 0005 FF00 FF00 00FF FD00 08FF" /* ........ */ + $"0000 FF00 FF00 00FF FE00 03FF 0000 FFFA" /* ......... */ + $"0009 FF00 FF00 FF00 FF00 00FF FE00 09FF" /* ....... */ + $"0000 FF00 00FF 0000 FFFE 0003 FF00 00FF" /* .......... */ + $"FE00 02FF 0000 00FF FD00 03FF 0000 FF9A" /* ......... */ + $"000F 7FA3 7FA3 7FA3 7FA3 7FA3 7FA3 7FA9" /* ......... */ + $"FD79 07F8 79F8 78F8 78F8 78FC 00FE FD00" /* y.yxxx.. */ + $"D4FE F5F8 00FE FFFE 00FE FFFE 0002 FF00" /* ..... */ + $"00FE FFFF 00FE FFFE 0003 FF00 00FF FE00" /* ....... */ + $"FEFF FD00 FEFF 0100 FFFC 00FE FFFE 00FE" /* ..... */ + $"FFFF 0003 FF00 00FF FD00 00FF FC00 FEFF" /* ....... */ + $"FE00 00FF FD00 FEFF FE00 06FF 0000 FF00" /* ........ */ + $"00FF FE00 FEFF FC00 FEFF FE00 FF00 00FF" /* ...... */ + $"FC00 FDFF FF00 00FF FB00 00FF FE00 FEFF" /* ...... */ + $"FE00 03FF 0000 FFFE 00FE FFFE 0000 FFFD" /* ....... */ + $"0006 FF00 00FF 0000 FFFD 0000 FFFD 00FE" /* ......... */ + $"FF06 00FF 0000 FF00 00FE FFFE 0000 FFFE" /* ........ */ + $"00FE FFFD 0006 FF00 00FF 0000 FFFE 00FE" /* ........ */ + $"FFFE 0003 FF00 00FF FE00 FFFF 0100 FFFE" /* ....... */ + $"00FE FFFE 0000 FFFC 00FE FF8D 0002 F9F4" /* ...... */ + $"00F4 00FE FD00 24FE F5F2 0000 FFA2 0000" /* ...$.... */ + $"FFF4 00FF 0000 FFEF 0000 FFDB 0000 FFBE" /* ....... */ + $"0084 0002 F5FF F8F4 00FE FD00 24FE F5F2" /* .....$ */ + $"0000 FFA2 0000 FFF4 0001 00FF EF00 00FF" /* ......... */ + $"DB00 00FF BD00 8300 0181 FE00 F6F5 00FE" /* ....... */ + $"FD00 10FE F584 0081 0082 0000 5600 F6F5" /* ......V. */ + $"00FE FD00 0CFE F584 0081 0081 00F4 00FE" /* ....... */ + $"FD00 0CFE F584 0081 0081 00F4 00FE FD00" /* ....... */ + $"0CFE F584 0081 0081 00F4 00FE FD00 0CFE" /* ....... */ + $"F584 0081 0081 00F4 00FE FD00 10FF F500" /* ....... */ + $"5684 AC81 AC81 ACF4 AC02 FEFD FD00 0E01" /* V.... */ + $"F556 83AC 81AC 81AC F3AC 01FE FD00 0C00" /* V.... */ + $"5682 AC81 AC81 ACF2 AC00 FE00 00FF" /* V... */ }; data 'PRCT' (1000, "Keypad") { @@ -5695,7 +6007,7 @@ data 'STR ' (1991, "Preferences File Name", purgeable) { }; data 'STR#' (2001, "Operation Failed Messages", preload) { - $"0005 1E74 6865 2066 696C 6520 636F 756C" /* ...the file coul */ + $"0006 1E74 6865 2066 696C 6520 636F 756C" /* ...the file coul */ $"6420 6E6F 7420 6265 2063 7265 6174 6564" /* d not be created */ $"2E1D 7468 6520 6669 6C65 2063 6F75 6C64" /* ..the file could */ $"206E 6F74 2062 6520 6F70 656E 6564 2E20" /* not be opened. */ @@ -5705,7 +6017,12 @@ data 'STR#' (2001, "Operation Failed Messages", preload) { $"7320 616E 2069 6E76 616C 6964 206B 6579" /* s an invalid key */ $"776F 7264 2E20 796F 7520 6361 6E6E 6F74" /* word. you cannot */ $"206F 7065 6E20 6120 6E75 6C6C 2068 6F73" /* open a null hos */ - $"746E 616D 652E" /* tname. */ + $"746E 616D 652E 4E74 6869 7320 6973 2061" /* tname.Nthis is a */ + $"6E20 6578 706F 7274 2076 6572 7369 6F6E" /* n export version */ + $"206F 6620 4265 7474 6572 5465 6C6E 6574" /* of BetterTelnet */ + $"2077 6869 6368 2064 6F65 7320 6E6F 7420" /* which does not */ + $"7375 7070 6F72 7420 7365 6375 7265 2073" /* support secure s */ + $"6865 6C6C 2E" /* hell. */ }; data 'STR#' (2004, "DNR Error Messages", purgeable) { @@ -5731,7 +6048,7 @@ data 'STR#' (2004, "DNR Error Messages", purgeable) { }; data 'STR#' (23227, "Server info", purgeable) { - $"0024 2A32 3230 204D 6163 696E 746F 7368" /* .$*220 Macintosh */ + $"0028 2A32 3230 204D 6163 696E 746F 7368" /* .(*220 Macintosh */ $"2052 6573 6964 656E 7420 4654 5020 7365" /* Resident FTP se */ $"7276 6572 2C20 7265 6164 790D 0A26 3435" /* rver, ready.&45 */ $"3120 4572 726F 7220 696E 2070 726F 6365" /* 1 Error in proce */ @@ -5814,7 +6131,17 @@ data 'STR#' (23227, "Server info", purgeable) { $"7361 626C 6564 5D0D 0A32 3530 3520 4150" /* sabled].2505 AP */ $"5045 4E44 206F 6E6C 7920 7375 7070 6F72" /* PEND only suppor */ $"7465 6420 696E 2041 5343 4949 2074 7261" /* ted in ASCII tra */ - $"6E73 6665 7220 6D6F 6465 0D0A" /* nsfer mode. */ + $"6E73 6665 7220 6D6F 6465 0D0A 1732 3030" /* nsfer mode..200 */ + $"2044 6972 6563 746F 7279 2063 7265 6174" /* Directory creat */ + $"6564 0D0A 2735 3031 2044 6972 6563 746F" /* ed.'501 Directo */ + $"7279 2070 7265 7365 6E74 206F 7220 7379" /* ry present or sy */ + $"6E74 6178 2065 7272 6F72 0D0A 1732 3030" /* ntax error..200 */ + $"2044 6972 6563 746F 7279 2064 656C 6574" /* Directory delet */ + $"6564 0D0A 3F35 3031 2044 6972 6563 746F" /* ed.?501 Directo */ + $"7279 206E 6F74 2070 7265 7365 6E74 206F" /* ry not present o */ + $"7220 636F 6E74 6169 6E73 2065 6E74 7269" /* r contains entri */ + $"6573 206F 7220 7379 6E74 6178 2065 7272" /* es or syntax err */ + $"6F72 0D0A" /* or. */ }; data 'STR#' (23228, "ftp cmds", purgeable) { @@ -6090,7 +6417,7 @@ data 'STR#' (7005, "FTP User Config Strings", purgeable) { }; data 'STR#' (7004, "Session Config Strings", purgeable) { - $"0036 022D 3100 0007 496E 6869 6269 7404" /* .6.-1...Inhibit. */ + $"0043 022D 3100 0007 496E 6869 6269 7404" /* .C.-1...Inhibit. */ $"3430 3134 0434 3130 3505 5175 6963 6B05" /* 4014.4105.Quick. */ $"426C 6F63 6B06 4465 6C65 7465 0942 6163" /* Block.DeleteBac */ $"6B73 7061 6365 0946 6F72 6365 7361 7665" /* kspaceForcesave */ @@ -6117,7 +6444,11 @@ data 'STR#' (7004, "Session Config Strings", purgeable) { $"6F6D 7074 2069 6620 756E 6E65 6365 7373" /* ompt if unnecess */ $"6172 7900 0024 5265 6D65 6D62 6572 204F" /* ary..$Remember O */ $"5450 2070 6173 7377 6F72 6420 7769 7468" /* TP password with */ - $"696E 2073 6573 7369 6F6E" /* in session */ + $"696E 2073 6573 7369 6F6E 0000 0000 0000" /* in session...... */ + $"0000 0000 0014 5573 6520 534F 434B 5320" /* ......Use SOCKS */ + $"3420 6669 7265 7761 6C6C 1A2E 2E2E 616E" /* 4 firewall....an */ + $"6420 534F 434B 5320 3461 2044 4E53 206C" /* d SOCKS 4a DNS l */ + $"6F6F 6B75 70" /* ookup */ }; data 'STR#' (2000, "Misc. messages", purgeable) { @@ -6165,24 +6496,23 @@ data 'STR#' (2000, "Misc. messages", purgeable) { $"7420 7265 7175 6972 6573 2048 4653 2E22" /* t requires HFS." */ $"5072 6F62 6C65 6D20 7769 7468 2074 6865" /* Problem with the */ $"2053 7973 456E 7669 726F 6E73 2063 6F64" /* SysEnvirons cod */ - $"652E 2C54 656C 6E65 7420 7265 7175 6972" /* e.,Telnet requir */ - $"6573 2061 7420 6C65 6173 7420 5379 7374" /* es at least Syst */ - $"656D 2076 6572 7369 6F6E 2036 2E30 2E23" /* em version 6.0.# */ - $"5465 6C6E 6574 2072 6571 7569 7265 7320" /* Telnet requires */ - $"6174 206C 6561 7374 2031 3238 6B20 524F" /* at least 128k RO */ - $"4D53 2E2B 4661 7461 6C20 6572 726F 7220" /* MS.+Fatal error */ - $"696E 7374 616C 6C69 6E67 2041 7070 6C65" /* installing Apple */ - $"4576 656E 7420 6861 6E64 6C65 7273 2E52" /* Event handlers.R */ - $"5468 6572 6520 6172 6520 636F 6E6E 6563" /* There are connec */ - $"7469 6F6E 7320 7374 696C 6C20 6163 7469" /* tions still acti */ - $"7665 2E20 2044 6F20 796F 7520 7265 616C" /* ve. Do you real */ - $"6C79 2077 616E 7420 746F 2063 6C6F 7365" /* ly want to close */ - $"2061 6C6C 2074 6865 2077 696E 646F 7773" /* all the windows */ - $"3F0D" /* ?. */ + $"652E 2454 656C 6E65 7420 7265 7175 6972" /* e.$Telnet requir */ + $"6573 204D 6163 204F 5320 372E 3020 6F72" /* es Mac OS 7.0 or */ + $"206C 6174 6572 2E23 5465 6C6E 6574 2072" /* later.#Telnet r */ + $"6571 7569 7265 7320 6174 206C 6561 7374" /* equires at least */ + $"2031 3238 6B20 524F 4D73 2E2B 4661 7461" /* 128k ROMs.+Fata */ + $"6C20 6572 726F 7220 696E 7374 616C 6C69" /* l error installi */ + $"6E67 2041 7070 6C65 4576 656E 7420 6861" /* ng AppleEvent ha */ + $"6E64 6C65 7273 2E52 5468 6572 6520 6172" /* ndlers.RThere ar */ + $"6520 636F 6E6E 6563 7469 6F6E 7320 7374" /* e connections st */ + $"696C 6C20 6163 7469 7665 2E20 2044 6F20" /* ill active. Do */ + $"796F 7520 7265 616C 6C79 2077 616E 7420" /* you really want */ + $"746F 2063 6C6F 7365 2061 6C6C 2074 6865" /* to close all the */ + $"2077 696E 646F 7773 3F0D" /* windows?. */ }; data 'STR#' (7003, "Terminal Config Strings", purgeable) { - $"001A 0232 3214 414E 5349 2063 6F6C 6F72" /* ...22.ANSI color */ + $"001C 0232 3214 414E 5349 2063 6F6C 6F72" /* ...22.ANSI color */ $"2073 6571 7565 6E63 6573 0F58 7465 726D" /* sequences.Xterm */ $"2073 6571 7565 6E63 6573 1055 7365 2056" /* sequences.Use V */ $"5420 7772 6170 206D 6F64 6508 4E4F 5420" /* T wrap mode.NOT */ @@ -6201,7 +6531,10 @@ data 'STR#' (7003, "Terminal Config Strings", purgeable) { $"2066 6F72 2062 6F6C 6400 0004 426F 6C64" /* for bold...Bold */ $"2344 6F6E 2774 2073 6176 6520 6174 7472" /* #Don't save attr */ $"6962 7574 6573 2069 6E20 7363 726F 6C6C" /* ibutes in scroll */ - $"6261 636B" /* back */ + $"6261 636B 1B55 7365 206A 756D 7020 7363" /* back.Use jump sc */ + $"726F 6C6C 696E 6720 2866 6173 7465 7229" /* rolling (faster) */ + $"1155 7365 2072 6561 6C20 626C 696E 6B69" /* .Use real blinki */ + $"6E67" /* ng */ }; data 'STR#' (4000, "Good Fonts", purgeable) { @@ -6213,7 +6546,7 @@ data 'STR#' (5000, "Bad Fonts", purgeable) { }; data 'STR#' (7001, "Main Prefs Strings", purgeable) { - $"0026 022D 3100 0015 5769 6E64 6F77 7320" /* .&.-1...Windows */ + $"0027 022D 3100 0015 5769 6E64 6F77 7320" /* .'.-1...Windows */ $"646F 6E27 7420 676F 2061 7761 7911 5374" /* don't go away.St */ $"6167 6765 7265 6420 5769 6E64 6F77 730C" /* aggered Windows. */ $"436F 6D6D 616E 6420 4B65 7973 1952 656D" /* Command Keys.Rem */ @@ -6225,7 +6558,7 @@ data 'STR#' (7001, "Main Prefs Strings", purgeable) { $"7469 6361 6C20 4261 7223 496E 2062 6163" /* tical Bar#In bac */ $"6B67 726F 756E 642C 206E 6F74 6966 7920" /* kground, notify */ $"7573 6572 206F 6620 6265 6570 7320 4578" /* user of beeps Ex */ - $"7069 7265 206B 6572 6265 726F 7320 7469" /* pire kerberos ti */ + $"7069 7265 204B 6572 6265 726F 7320 7469" /* pire Kerberos ti */ $"636B 6574 7320 6F6E 2063 6C6F 7365 0000" /* ckets on close.. */ $"0000 0000 0000 0000 0000 0000 0000 23D2" /* ..............# */ $"4F70 656E 2043 6F6E 6E65 6374 696F 6ED3" /* Open Connection */ @@ -6239,11 +6572,12 @@ data 'STR#' (7001, "Main Prefs Strings", purgeable) { $"7973 2063 6C69 7020 7472 6169 6C69 6E67" /* ys clip trailing */ $"2073 7061 6365 731E 476C 6F62 616C 6C79" /* spaces.Globally */ $"2072 656D 656D 6265 7220 4F54 5020 7061" /* remember OTP pa */ - $"7373 776F 7264" /* ssword */ + $"7373 776F 7264 1255 7365 206C 6976 6520" /* ssword.Use live */ + $"7363 726F 6C6C 696E 67" /* scrolling */ }; data 'STR#' (2002, "Misc Strings", purgeable) { - $"001A 0C43 6170 7475 7265 2046 696C 650B" /* ...Capture File. */ + $"001C 0C43 6170 7475 7265 2046 696C 650B" /* ...Capture File. */ $"4E65 7720 5365 7373 696F 6E0C 4E65 7720" /* New Session.New */ $"5465 726D 696E 616C 0D55 7365 2075 7365" /* Terminal.Use use */ $"726E 616D 653D 0B2C 2070 6173 7377 6F72" /* rname=., passwor */ @@ -6263,9 +6597,11 @@ data 'STR#' (2002, "Misc Strings", purgeable) { $"2063 6170 7475 7265 6420 7465 7874 2061" /* captured text a */ $"733A 1050 7265 7669 6F75 7320 5365 7373" /* s:.Previous Sess */ $"696F 6E0C 4E65 7874 2053 6573 7369 6F6E" /* ion.Next Session */ - $"2552 6562 7569 6C64 696E 6720 466F 6E74" /* %Rebuilding Font */ - $"204D 656E 7520 2D20 506C 6561 7365 2057" /* Menu - Please W */ - $"6169 742E 2E2E" /* ait... */ + $"1752 6562 7569 6C64 696E 6720 466F 6E74" /* .Rebuilding Font */ + $"204D 656E 752E 2E2E 1549 6E69 7469 616C" /* Menu....Initial */ + $"697A 696E 6720 4D65 6E75 732E 2E2E 1849" /* izing Menus....I */ + $"6E69 7469 616C 697A 696E 6720 5465 726D" /* nitializing Term */ + $"696E 616C 2E2E 2E" /* inal... */ }; data 'STR#' (23239, "Save Set Strings", purgeable) { @@ -6308,6 +6644,41 @@ data 'STR#' (23239, "Save Set Strings", purgeable) { $"6B" /* k */ }; +data 'STR#' (7100, "Key Names") { + $"005A 0211 3002 1131 0211 3202 1133 0211" /* .Z..0..1..2..3.. */ + $"3402 1135 0211 3602 1137 0211 3802 1139" /* 4..5..6..7..8..9 */ + $"0853 6869 6674 2D11 3008 5368 6966 742D" /* .Shift-.0.Shift- */ + $"1131 0853 6869 6674 2D11 3208 5368 6966" /* .1.Shift-.2.Shif */ + $"742D 1133 0853 6869 6674 2D11 3408 5368" /* t-.3.Shift-.4.Sh */ + $"6966 742D 1135 0853 6869 6674 2D11 3608" /* ift-.5.Shift-.6. */ + $"5368 6966 742D 1137 0853 6869 6674 2D11" /* Shift-.7.Shift-. */ + $"3808 5368 6966 742D 1139 0246 3102 4632" /* 8.Shift-.9.F1.F2 */ + $"0246 3302 4634 0246 3502 4636 0246 3702" /* .F3.F4.F5.F6.F7. */ + $"4638 0246 3903 4631 3008 5368 6966 742D" /* F8.F9.F10.Shift- */ + $"4631 0853 6869 6674 2D46 3208 5368 6966" /* F1.Shift-F2.Shif */ + $"742D 4633 0853 6869 6674 2D46 3408 5368" /* t-F3.Shift-F4.Sh */ + $"6966 742D 4635 0853 6869 6674 2D46 3608" /* ift-F5.Shift-F6. */ + $"5368 6966 742D 4637 0853 6869 6674 2D46" /* Shift-F7.Shift-F */ + $"3808 5368 6966 742D 4639 0953 6869 6674" /* 8.Shift-F9Shift */ + $"2D46 3130 0346 3131 0346 3132 0346 3133" /* -F10.F11.F12.F13 */ + $"0346 3134 0346 3135 0953 6869 6674 2D46" /* .F14.F15Shift-F */ + $"3131 0953 6869 6674 2D46 3132 0953 6869" /* 11Shift-F12Shi */ + $"6674 2D46 3133 0953 6869 6674 2D46 3134" /* ft-F13Shift-F14 */ + $"0953 6869 6674 2D46 3135 0B50 4631 2028" /* Shift-F15.PF1 ( */ + $"436C 6561 7229 0750 4632 2028 3D29 0750" /* Clear).PF2 (=).P */ + $"4633 2028 2F29 0750 4634 2028 2A29 0450" /* F3 (/).PF4 (*).P */ + $"6755 7006 5067 446F 776E 0448 6F6D 6503" /* gUp.PgDown.Home. */ + $"456E 6404 4865 6C70 0344 656C 0130 0131" /* End.Help.Del.0.1 */ + $"0132 0133 0134 0135 0136 0137 0138 0139" /* .2.3.4.5.6.7.8.9 */ + $"012D 012B 012E 0A45 6E74 6572 2028 414D" /* .-.+..Enter (AM */ + $"290B 456E 7465 7220 2821 414D 2900 0000" /* ).Enter (!AM)... */ + $"0000 0255 7004 446F 776E 044C 6566 7405" /* ...Up.Down.Left. */ + $"5269 6768 7400 0855 7020 2843 4B4D 290A" /* Right..Up (CKM) */ + $"446F 776E 2028 434B 4D29 0A4C 6566 7420" /* Down (CKM)Left */ + $"2843 4B4D 290B 5269 6768 7420 2843 4B4D" /* (CKM).Right (CKM */ + $"2900" /* ). */ +}; + data 'taBL' (265, "DEC Multinational") { $"0001 0203 0405 0607 0809 0A0B 0C0D 0E0F" /* .............. */ $"1011 1213 1415 1617 1819 1A1B 1C1D 1E1F" /* ................ */ @@ -6798,6 +7169,41 @@ data 'taBL' (270, "Windows-1253", purgeable) { $"F0FE F1F3 F4E8 F9F2 F7F5 E6FA FBC0 E0FF" /* */ }; +data 'taBL' (170, "Scandinavian 7bit ") { + $"0001 0203 0405 0607 0809 0A0B 0C0D 0E0F" /* .............. */ + $"1011 1213 1415 1617 1819 1A1B 1C1D 1E1F" /* ................ */ + $"2021 2223 2425 2627 2829 2A2B 2C2D 2E2F" /* !"#$%&'()*+,-./ */ + $"3031 3233 3435 3637 3839 3A3B 3C3D 3E3F" /* 0123456789:;<=>? */ + $"4041 4243 4445 4647 4849 4A4B 4C4D 4E4F" /* @ABCDEFGHIJKLMNO */ + $"5051 5253 5455 5657 5859 5A80 8581 5E5F" /* PQRSTUVWXYZ^_ */ + $"6061 6263 6465 6667 6869 6A6B 6C6D 6E6F" /* `abcdefghijklmno */ + $"7071 7273 7475 7677 7879 7A8A 9A8C 7E7F" /* pqrstuvwxyz~. */ + $"4141 4345 4E4F 5561 6161 6161 6163 6565" /* AACENOUaaaaaacee */ + $"6565 6969 6969 6E6F 6F6F 6F6F 7575 7575" /* eeiiiinooooouuuu */ + $"2B6F 634C 536F 5053 5243 2260 2223 414F" /* +ocLSoPSRC"`"#AO */ + $"3823 3C3E 5975 6453 5070 5361 6F4F 616F" /* 8#<>YudSPpSaoOao */ + $"3F69 2D56 663D 643C 3E2E 2041 414F 4F6F" /* ?i-Vf=d<>. AAOOo */ + $"2D2D 2222 6060 2F6F 793D 2020 2020 2020" /* --""``/oy= */ + $"2020 2020 2020 2020 2020 2020 2020 2020" /* */ + $"2020 2020 2020 2020 2020 2020 2020 2020" /* */ + $"0001 0203 0405 0607 0809 0A0B 0C0D 0E0F" /* .............. */ + $"1011 1213 1415 1617 1819 1A1B 1C1D 1E1F" /* ................ */ + $"2021 2223 2425 2627 2829 2A2B 2C2D 2E2F" /* !"#$%&'()*+,-./ */ + $"3031 3233 3435 3637 3839 3A3B 3C3D 3E3F" /* 0123456789:;<=>? */ + $"4041 4243 4445 4647 4849 4A4B 4C4D 4E4F" /* @ABCDEFGHIJKLMNO */ + $"5051 5253 5455 5657 5859 5A5B 5C5D 5E5F" /* PQRSTUVWXYZ[\]^_ */ + $"6061 6263 6465 6667 6869 6A6B 6C6D 6E6F" /* `abcdefghijklmno */ + $"7071 7273 7475 7677 7879 7A7B 7C7D 7E7F" /* pqrstuvwxyz{|}~. */ + $"5B5D 4340 4E5C 7E61 6161 7B61 7D63 7E65" /* []C@N\~aaa{a}c~e */ + $"6565 6969 6969 6E6F 6F6F 7C7C 7575 7575" /* eeiiiinooo||uuuu */ + $"2B6F 634C 536F 5053 5243 5427 2223 414F" /* +ocLSoPSRCT'"#AO */ + $"3823 3C3E 5975 6453 5070 5361 6F4F 616F" /* 8#<>YudSPpSaoOao */ + $"3F21 2D56 663D 643C 3E2E 2041 414F 4F6F" /* ?!-Vf=d<>. AAOOo */ + $"2D2D 2222 2727 2F6F 7959 2F6F 3C3E 6666" /* --""''/oyY/o<>ff */ + $"2B2E 2722 2541 4541 4545 4949 4949 4F4F" /* +.'"%AEAEEIIIIOO */ + $"204F 5555 5569 5E7E 2D5E 2E6F 2C22 2C5E" /* OUUUi^~-^.o,",^ */ +}; + data 'TMPL' (128, "PRCT", purgeable) { $"052A 2A2A 2A2A 4C53 5442 0641 2052 6563" /* .*****LSTB.A Rec */ $"7452 4543 5405 2A2A 2A2A 2A4C 5354 45" /* tRECT.*****LSTE */ @@ -6837,8 +7243,12 @@ data 'TMPL' (129, "PrEf") { $"6179 7320 636C 6970 2074 7261 696C 696E" /* ays clip trailin */ $"6720 7370 6163 6573 4457 5244 1D64 6566" /* g spacesDWRD.def */ $"6175 6C74 2041 4E53 4920 626F 6C64 2063" /* ault ANSI bold c */ - $"6F6C 6F72 2069 6E64 6578 4457 5244 0770" /* olor indexDWRD.p */ - $"6164 6469 6E67 4845 5844" /* addingHEXD */ + $"6F6C 6F72 2069 6E64 6578 4457 5244 1A73" /* olor indexDWRD.s */ + $"6176 6520 4F54 5020 7061 7373 776F 7264" /* ave OTP password */ + $"2067 6C6F 6261 6C6C 7944 5752 4416 6469" /* globallyDWRD.di */ + $"7361 626C 6520 6C69 7665 2073 6372 6F6C" /* sable live scrol */ + $"6C69 6E67 4457 5244 0770 6164 6469 6E67" /* lingDWRD.padding */ + $"4845 5844" /* HEXD */ }; data 'TMPL' (130, "TeRm") { @@ -6925,7 +7335,22 @@ data 'TMPL' (131, "SeSn") { $"6D70 7444 5752 4415 4F54 5020 6865 7861" /* mptDWRD.OTP hexa */ $"6465 6369 6D61 6C20 7265 706C 7944 5752" /* decimal replyDWR */ $"440C 4F54 5020 7061 7373 776F 7264 5030" /* D.OTP passwordP0 */ - $"3346 0770 6164 6469 6E67 4845 5844" /* 3F.paddingHEXD */ + $"3346 1173 6176 6520 4F54 5020 7061 7373" /* 3F.save OTP pass */ + $"776F 7264 4457 5244 0875 7365 726E 616D" /* wordDWRD.usernam */ + $"6550 3046 4608 7061 7373 776F 7264 5030" /* eP0FF.passwordP0 */ + $"4646 0F63 6C69 656E 7420 7573 6572 6E61" /* FF.client userna */ + $"6D65 5030 4646 0763 6F6D 6D61 6E64 5030" /* meP0FF.commandP0 */ + $"4646 0870 726F 746F 636F 6C44 5752 4411" /* FF.protocolDWRD. */ + $"656E 6372 7970 7469 6F6E 206D 6574 686F" /* encryption metho */ + $"6444 5752 4414 7573 6520 534F 434B 5320" /* dDWRD.use SOCKS */ + $"3420 6669 7265 7761 6C6C 4457 5244 1775" /* 4 firewallDWRD.u */ + $"7365 2053 4F43 4B53 2034 6120 444E 5320" /* se SOCKS 4a DNS */ + $"6C6F 6F6B 7570 4457 5244 1553 4F43 4B53" /* lookupDWRD.SOCKS */ + $"2070 6F72 7420 6E75 6D20 2831 3038 3029" /* port num (1080) */ + $"4457 5244 0E53 4F43 4B53 2068 6F73 746E" /* DWRD.SOCKS hostn */ + $"616D 6550 3046 460E 534F 434B 5320 7573" /* ameP0FF.SOCKS us */ + $"6572 6E61 6D65 5030 4646 0770 6164 6469" /* ernameP0FF.paddi */ + $"6E67 4845 5844" /* ngHEXD */ }; data 'TMPL' (132, "TeR2") { @@ -6972,8 +7397,10 @@ data 'TMPL' (132, "TeR2") { $"6420 7665 7273 696F 6E20 6F66 2062 6F6C" /* d version of bol */ $"6420 666F 6E74 4457 5244 2064 6F6E 2774" /* d fontDWRD don't */ $"2073 6176 6520 6174 7472 6962 7320 696E" /* save attribs in */ - $"2073 6372 6F6C 6C62 6163 6B44 5752 4407" /* scrollbackDWRD. */ - $"7061 6464 696E 6748 4558 44" /* paddingHEXD */ + $"2073 6372 6F6C 6C62 6163 6B44 5752 4411" /* scrollbackDWRD. */ + $"7573 6520 7265 616C 2062 6C69 6E6B 696E" /* use real blinkin */ + $"6744 5752 4407 7061 6464 696E 6748 4558" /* gDWRD.paddingHEX */ + $"44" /* D */ }; data 'TMPL' (133, "FTPs") { @@ -7099,33 +7526,9 @@ data 'PrEf' (1990, "Application Prefs Master Copy") { $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ - $"0000 0000 0000 0000 0000 0000" /* ............ */ -}; - -data 'SeSn' (1991, "<Default>") { - $"0001 0017 FFFF 0001 0078 0000 0000 0000" /* .......x...... */ - $"0000 0000 01FF FFFF 093C 4465 6661 756C" /* .....<Defaul */ - $"743E 0000 0000 0000 0000 0000 0000 0000" /* t>.............. */ - $"0000 0000 0000 0000 0004 4E6F 6E65 0000" /* ..........None.. */ - $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ - $"0000 0000 0000 0000 0000 146E 6F77 6865" /* ...........nowhe */ - $"7265 2E6C 6F6F 7062 6163 6B2E 6564 7500" /* re.loopback.edu. */ - $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ - $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ - $"0000 0000 0000 0000 0000 0000 0000 0400" /* ................ */ - $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ - $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ - $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ - $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ - $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ - $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ - $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ - $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ - $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ - $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ - $"0000" /* .. */ + $"0000 0000 0000 0000" /* ........ */ }; data 'TeRm' (1991, "<Default>") { @@ -7161,12 +7564,6 @@ data 'BNDL' (18371) { $"0003 0083 0004 0084 0005 0085" /* ......... */ }; -data 'cctb' (1000) { - $"0000 0000 0000 0003 0000 0000 0000 0000" /* ................ */ - $"0001 FFFF FFFF FFFF 0002 0000 0000 0000" /* .......... */ - $"0003 FFFF FFFF FFFF" /* .. */ -}; - data 'FTPs' (1990, "FTP Server Prefs Master Copy") { $"0000 0000 3F3F 3F3F 4249 4E41 7474 7874" /* ....????BINAttxt */ $"0001 0100 0000 0000 0000 0000 0000 0000" /* ................ */ @@ -7215,7 +7612,8 @@ data 'TeR2' (1991, "<Default>") { $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ - $"0000 0000 0000 0000 0000 0000" /* ............ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000" /* .. */ }; data 'CDEF' (1109, "Tab Panel mw68", purgeable) { @@ -7580,3 +7978,256 @@ data 'pltt' (9999, "16 ANSI Colors") { $"FFFF FFFF FFFF 0002 0000 0000 0000 0000" /* .......... */ }; +data 'dlgx' (7001) { + $"0000 0000 0009" /* ..... */ +}; + +data 'dlgx' (7003) { + $"0000 0000 0009" /* ..... */ +}; + +data 'dlgx' (7004) { + $"0000 0000 0009" /* ..... */ +}; + +data 'dlgx' (1001) { + $"0000 0000 0009" /* ..... */ +}; + +data 'dlgx' (1002) { + $"0000 0000 0009" /* ..... */ +}; + +data 'dlgx' (273) { + $"0000 0000 0009" /* ..... */ +}; + +data 'dlgx' (280) { + $"0000 0000 0009" /* ..... */ +}; + +data 'dlgx' (150) { + $"0000 0000 0009" /* ..... */ +}; + +data 'dlgx' (8000) { + $"0000 0000 0009" /* ..... */ +}; + +data 'dlgx' (10000) { + $"0000 0000 0009" /* ..... */ +}; + +data 'SeSn' (1991, "<Default>") { + $"0001 0017 FFFF 0001 0078 0000 0000 0000" /* .......x...... */ + $"0000 0000 01FF FFFF 093C 4465 6661 756C" /* .....<Defaul */ + $"743E 0000 0000 0000 0000 0000 0000 0000" /* t>.............. */ + $"0000 0000 0000 0000 0004 4E6F 6E65 0000" /* ..........None.. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 146E 6F77 6865" /* ...........nowhe */ + $"7265 2E6C 6F6F 7062 6163 6B2E 6564 7500" /* re.loopback.edu. */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0400" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0438 0000 0000" /* ...........8.... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000" /* .... */ +}; + +data 'cicn' (129) { + $"0000 0000 8008 0000 0000 0020 0020 0000" /* .......... . .. */ + $"0000 0000 0000 0048 0000 0048 0000 0000" /* .......H...H.... */ + $"0002 0001 0002 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0004 0000 0000 0020 0020" /* ............. . */ + $"0000 0000 0004 0000 0000 0020 0020 0000" /* ........... . .. */ + $"0000 0000 0000 0000 000C 0000 001E 0000" /* ................ */ + $"003E 0000 007C 0000 00F8 0000 01FC 0000" /* .>...|........ */ + $"03FE 0000 07FF 0000 0FFE 0000 1FF4 0000" /* ............ */ + $"3EE0 0000 7C70 0000 F820 0001 F000 0003" /* >..|p.. ..... */ + $"E000 0007 C000 000F 8000 001F 0000 003E" /* ............> */ + $"0000 1F7C 0000 3FF8 0000 7FF0 0000 FFE0" /* ...|..?..... */ + $"0000 F1F0 0000 F0F0 0000 F0F0 0000 F8F0" /* ........ */ + $"0000 7FF0 0000 3FE0 0000 1FC0 0000 0780" /* .....?...... */ + $"0000 0000 0000 0000 000C 0000 0012 0000" /* ................ */ + $"0022 0000 0044 0000 0088 0000 0104 0000" /* ."...D......... */ + $"0202 0000 0401 0000 080A 0000 1114 0000" /* ............... */ + $"22A0 0000 4450 0000 8820 0001 1000 0002" /* "..DP.. ...... */ + $"2000 0004 4000 0008 8000 0011 0000 0022" /* ...@........." */ + $"0000 0E44 0000 3188 0000 4010 0000 8E20" /* ...D..1..@... */ + $"0000 9120 0000 9090 0000 9090 0000 4890" /* .. ......H */ + $"0000 4720 0000 2020 0000 1840 0000 0780" /* ..G .. ...@... */ + $"0000 0000 0000 0000 0003 0000 FFFF FFFF" /* ............ */ + $"FFFF 0001 CCCC CCCC CCCC 0002 8888 8888" /* .... */ + $"8888 0003 0000 0000 0000 0000 0000 0000" /* .............. */ + $"0000 0000 0000 0000 00F0 0000 0000 0000" /* ............... */ + $"031C 0000 0000 0000 0C6C 0000 0000 0000" /* .........l...... */ + $"31B0 0000 0000 0000 C6C0 0000 0000 0003" /* 1............ */ + $"1AB0 0000 0000 000C 6A5C 0000 0000 0031" /* .......j\.....1 */ + $"A957 0000 0000 00C6 A5EC 0000 0000 031B" /* W.....ƥ...... */ + $"9730 0000 0000 0C6C DC00 0000 0000 31B0" /* 0.....l.....1 */ + $"3B00 0000 0000 C6C0 0C00 0000 0003 1B00" /* ;............. */ + $"0000 0000 000C 6C00 0000 0000 0031 B000" /* ......l......1. */ + $"0000 0000 00C6 C000 0000 0000 031B 0000" /* .............. */ + $"0000 0000 0C6C 0000 0000 02FE 31B0 0000" /* .....l.....1.. */ + $"0000 0F17 C6C0 0000 0000 3155 5B00 0000" /* ........1U[... */ + $"0000 C6FD 5C00 0000 0000 C703 1E00 0000" /* ..\.......... */ + $"0000 C700 D700 0000 0000 C700 D700 0000" /* ............ */ + $"0000 B6C0 D700 0000 0000 35BF 1E00 0000" /* .......5.... */ + $"0000 0D55 6C00 0000 0000 03EA B000 0000" /* ...Ul......... */ + $"0000 003F C000 0000 0000" /* ...?..... */ +}; + +data 'ICON' (129) { + $"0000 0000 0000 000C 0000 0012 0000 0022" /* ..............." */ + $"0000 0044 0000 0088 0000 0114 0000 0222" /* ...D.........." */ + $"0000 0441 0000 088A 0000 1114 0000 22A0" /* ...A........." */ + $"0000 4450 0000 8820 0001 1000 0002 2000" /* ..DP.. ...... . */ + $"0004 4000 0008 8000 0011 0000 0022 0000" /* ..@.........".. */ + $"0E44 0000 3188 0000 4010 0000 8E20 0000" /* .D..1..@... .. */ + $"9120 0000 9090 0000 9090 0000 4890 0000" /* ......H.. */ + $"4720 0000 2020 0000 1840 0000 0780 0000" /* G .. ...@..... */ +}; + +data 'Mcro' (128) { + $"210D 0D0D 0D0D 0D0D 0D0D 0D0D 0D0D 0D0D" /* !............... */ + $"0D0D 0D0D 0D0D 5C30 3333 5B31 377E 0D5C" /* ......\033[17~.\ */ + $"3033 335B 3138 7E0D 5C30 3333 5B31 397E" /* 033[18~.\033[19~ */ + $"0D5C 3033 335B 3230 7E0D 5C30 3333 5B32" /* .\033[20~.\033[2 */ + $"317E 0D5C 3033 335B 3233 7E0D 5C30 3333" /* 1~.\033[23~.\033 */ + $"5B32 347E 0D5C 3033 335B 3235 7E0D 5C30" /* [24~.\033[25~.\0 */ + $"3333 5B32 367E 0D5C 3033 335B 3238 7E0D" /* 33[26~.\033[28~. */ + $"0D0D 0D0D 0D0D 0D0D 0D0D 5C30 3333 5B32" /* ..........\033[2 */ + $"397E 0D5C 3033 335B 3331 7E0D 5C30 3333" /* 9~.\033[31~.\033 */ + $"5B33 327E 0D5C 3033 335B 3333 7E0D 5C30" /* [32~.\033[33~.\0 */ + $"3333 5B33 347E 0D0D 0D0D 0D0D 5C30 3333" /* 33[34~......\033 */ + $"4F50 0D5C 3033 334F 510D 5C30 3333 4F52" /* OP.\033OQ.\033OR */ + $"0D5C 3033 334F 530D 5C30 3333 5B33 7E0D" /* .\033OS.\033[3~. */ + $"5C30 3333 5B36 7E0D 5C30 3333 5B32 7E0D" /* \033[6~.\033[2~. */ + $"5C30 3333 5B35 7E0D 5C30 3333 5B31 7E0D" /* \033[5~.\033[1~. */ + $"5C30 3333 5B34 7E0D 5C30 3333 4F70 0D5C" /* \033[4~.\033Op.\ */ + $"3033 334F 710D 5C30 3333 4F72 0D5C 3033" /* 033Oq.\033Or.\03 */ + $"334F 730D 5C30 3333 4F74 0D5C 3033 334F" /* 3Os.\033Ot.\033O */ + $"750D 5C30 3333 4F76 0D5C 3033 334F 770D" /* u.\033Ov.\033Ow. */ + $"5C30 3333 4F78 0D5C 3033 334F 790D 5C30" /* \033Ox.\033Oy.\0 */ + $"3333 4F6D 0D5C 3033 334F 6C0D 5C30 3333" /* 33Om.\033Ol.\033 */ + $"4F6E 0D5C 3033 334F 4D0D 5C30 3135 5C30" /* On.\033OM.\015\0 */ + $"3132 0D0D 0D0D 0D0D 5C30 3333 5B41 0D5C" /* 12......\033[A.\ */ + $"3033 335B 420D 5C30 3333 5B44 0D5C 3033" /* 033[B.\033[D.\03 */ + $"335B 430D 0D5C 3033 334F 410D 5C30 3333" /* 3[C..\033OA.\033 */ + $"4F42 0D5C 3033 334F 440D 5C30 3333 4F43" /* OB.\033OD.\033OC */ + $"0D0D 0D0D 0D0D 0D0D 0D0D 0D0D 0D0D 0D0D" /* ................ */ + $"0D0D 0D0D 0D0D" /* ...... */ +}; + diff --git a/source/wdef/wdefpatch.c b/source/wdef/wdefpatch.c index 32802a8..50004b9 100755 --- a/source/wdef/wdefpatch.c +++ b/source/wdef/wdefpatch.c @@ -1 +1 @@ -/******************************************* WDEF Patcher Steve Falkenburg MacDTS 1991 Apple Computer This snippet shows how you can add a simple extra part to a WDEF without writing an entire WDEF. It also shows how to access the new part via FindWindow(). Roberto Avanzi (independent programmer), June 18, 1992 Added support for tracking the extra part, in a way similar to the one used by the system. given back to Apple as an enhanced snippet (mmmh, sounds quite absurd) 6/1/92 SJF fixed a5 problem in WDEF patch (StripAddress is glue, and a5 wasn't set up) 6/1/92 SJF fixed varCode bug that made zoom boxes not work (masked out high 8 bits) *******************************************/ #ifdef MPW #pragma segment WDEFPatch #endif #include "wind.h" #include "wdefpatch.proto.h" #include "tnae.h" static void drawicon(short id, Rect *dest); /* 931112, ragge, NADA, KTH */ static void drawSize(Rect *wSize, WindowPtr window); /* add 2 to this when checking with FindWindow() ! */ #define kOurHit 32 /* * this struct allows us to insert a WDEF patch safely. It contains a jump instruction * and stores the old handle to the WDEF */ typedef struct { #ifdef __powerpc__ RoutineDescriptor rd; #else short jmpInst; ProcPtr patchAddr; #endif Handle oldAddr; Boolean partState; /* roberto avanzi jun 18 1992 */ long ourA5; struct WindRec *tw; } WDEFPatch, *WDEFPatchPtr, **WDEFPatchHndl; /* * RePatchWindowWDEF * this adjusts the tw pointer for a patched window * We have to do this since the tw for a window can change when other * windows are killed. */ void RePatchWindowWDEF (WindowPtr window, struct WindRec *tw) { WDEFPatchHndl wdPatch; wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc; (**wdPatch).tw = tw; } /* * GetPatchStuffHandle * This returns the handle to our patch block so we can release it * when killing windows. The tw is verified to insure that this * window is really patched. */ Handle GetPatchStuffHandle (WindowPtr window, struct WindRec *tw) { WDEFPatchHndl wdPatch; wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc; if ((**wdPatch).tw == tw) return ((Handle)wdPatch); else return ((Handle)0); } #ifdef __powerpc__ enum { uppMyWDEFPatch = kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(long))) | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr))) | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short))) | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long))) }; #endif pascal long MyWDEFPatch (short varCode, WindowPtr window, short message, long param) { WDEFPatchHndl wdPatch; pascal long (*wdefProc)(short varCode,WindowPtr window,short message,long param); Handle oldWDEF; long result; Rect ourRect,ourElementRect; GrafPtr savePort; GrafPtr aPort; RgnHandle aRgn; Rect aRect; struct WindRec *tw; long appA5, saveA5; wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc; appA5 = (**wdPatch).ourA5; saveA5 = SetA5(appA5); ourRect = (**((WindowPeek)window)->strucRgn).rgnBBox; /* our 16x16 rectangle */ SetRect(&ourElementRect,ourRect.right-55,ourRect.top+1,ourRect.right-39,ourRect.top+17); tw = (**wdPatch).tw; oldWDEF = (**wdPatch).oldAddr; HLock(oldWDEF); wdefProc = (void *)*oldWDEF; wdefProc = (void *)StripAddress(wdefProc); /* * now, folks, WHY do I check it, u'll ask me ? Heh, it's a funny quirk in * the sys WDEF (at least, sys 7's, dunno whattabout older ones) . * Suppose You click once in the grow icon and DO NOT resize the window. * (remember, just click and do not move the mouse in the meantime). * Then you click on the added part. That part is tracked in the right way, * * BUT * * ALSO the zoom box gets hilited. Dunno why should happen, but It's a lot * of FUN. Sadly, cannot find its place in any useful app. Therefore we * do this check. * APPLE says: if you write your own WDEF and receive unknown messages, do not * do anything. pass along and do NOTHING. * APPLE does: we get something new ? therefore we process it anyway, just to * keep developers writing workarounds and keep their minds afresh. * What else can we say ? Thanks !!!!! (Roberto Avanzi june 19, 1992) */ if ( (message == wDraw) ? (((short)param) != kOurHit ) : true ) { #ifdef __powerpc__ result = CallUniversalProc((UniversalProcPtr)wdefProc, uppMyWDEFPatch, varCode, window, message, param); #else result = (wdefProc)(varCode,window,message,param); #endif } if (((WindowPeek)window)->visible) if (((WindowPeek)window)->hilited) { switch (message) { case wDraw: GetPort(&savePort); GetWMgrPort(&aPort); SetPort(aPort); aRgn = NewRgn(); GetClip(aRgn); SetRect(&aRect,-32000,-32000,32000,32000); ClipRect(&aRect); switch ( (short) param ) { // Roberto Avanzi 18-06-1992: support for // tracking of the new part case 0: (**wdPatch).partState = false; case kOurHit: PenNormal(); // draw our part if (tw->aedata != NULL) { tnParams *ae = (tnParams *)tw->aedata; if (ae->encrypting || ae->decrypting) { /* * erase 18 x 11. This gives us a 1 pixel margin * on the left and right, and matches the mask that * we're using in our crsr resources. */ InsetRect(&ourElementRect, -1, 0); ourElementRect.top += 3; ourElementRect.bottom -= 2; EraseRect(&ourElementRect); ourElementRect.top -= 3; ourElementRect.bottom += 2; InsetRect(&ourElementRect, 1, 0); } if (ae->encrypting && ae->decrypting) drawicon(lockcrsr, &ourElementRect); else if (ae->encrypting) drawicon(rightcrsr, &ourElementRect); else if (ae->decrypting) drawicon(leftcrsr, &ourElementRect); } break; default: break; } SetClip(aRgn); DisposeRgn(aRgn); SetPort(savePort); break; // removed this test so that one can move the window // also when clicking on the icon area. // 931112, ragge, NADA, KTH #ifdef NOTDEF case wHit: hitPt = (Point *)¶m; // hit test our part if (PtInRect(*hitPt,&ourElementRect)) { //result = kOurHit; } break; #endif case wGrow: /* 931112, ragge, NADA, KTH */ drawSize((Rect *) param, window); break; default: break; } // switch } // if hilited (otherwise we dont see the new box, addition by Roberto Avanzi) HUnlock(oldWDEF); SetA5(saveA5); return result; } #ifdef __powerpc__ RoutineDescriptor MyWDEFPatchUniversal = BUILD_ROUTINE_DESCRIPTOR(uppMyWDEFPatch, MyWDEFPatch); #endif /* * this installs the WDEF patch into a window */ void PatchWindowWDEF (WindowPtr window, struct WindRec *tw) { WDEFPatchHndl wdefHndl; WDEFPatchPtr wdefPatch; Handle oldAddr; unsigned long wdefEntry; wdefHndl = (WDEFPatchHndl)myNewHandle(sizeof(WDEFPatch)); oldAddr = ((WindowPeek)window)->windowDefProc; if (GetMMUMode()) // 32-bit wdefEntry = (unsigned long)wdefHndl; else wdefEntry = (unsigned long)StripAddress(wdefHndl) | ((unsigned long)oldAddr&0xff000000); HLock((Handle)wdefHndl); wdefPatch = *wdefHndl; wdefPatch->oldAddr = oldAddr; #ifdef __powerpc__ BlockMove(&MyWDEFPatchUniversal, &wdefPatch->rd, sizeof(wdefPatch->rd)); #else wdefPatch->jmpInst = 0x4ef9; /*JMP*/ wdefPatch->patchAddr = (ProcPtr)MyWDEFPatch; #endif wdefPatch->ourA5 = (long)LMGetCurrentA5(); /* Use universal access (RW) */ wdefPatch->tw = tw; HUnlock((Handle)wdefHndl); ((WindowPeek)window)->windowDefProc = (Handle)wdefEntry; } /* * drawicon */ void drawicon (short id, Rect *dest) { long qdv; Handle ih = 0; Rect source_rect; BitMap mask_bitmap; GrafPtr local_port; PixMap *pm; Ptr colormap; CCrsr *ccrsr; BitMap src_bitmap; GetPort(&local_port); ih = GetResource ('crsr', id); /* color cursor */ if (!ih) return; DetachResource(ih); /* ... need to save handle somewhere ... */ HLock(ih); /* ... to avoid reloading the resource all the time */ /* * Set source Rect and intialize source BitMaps. * A few PixMap fields must be munged; */ SetRect (&source_rect, 0, 0, 16, 16); ccrsr = (CCrsr *)(*ih); mask_bitmap.bounds = source_rect; mask_bitmap.rowBytes = 2; mask_bitmap.baseAddr = (Ptr)&ccrsr->crsrMask; /* (Ptr)(((Byte *)(*ih)) + 52); */ /* * if gestalt fails or no color quickdraw, just use the b/w bitmap. */ if (Gestalt(gestaltQuickdrawVersion, &qdv) || ((qdv & gestalt32BitQD) == 0)) { src_bitmap.bounds = source_rect; src_bitmap.rowBytes = 2; src_bitmap.baseAddr = (Ptr)&ccrsr->crsr1Data; CopyBits(&src_bitmap, &(local_port->portBits), &source_rect, dest, srcCopy, nil); } else { pm = (PixMap *) ((unsigned char *)ccrsr + (long)ccrsr->crsrMap); pm->baseAddr = (Ptr) ((unsigned char *)ccrsr + (long)ccrsr->crsrData); colormap = (Ptr) ((unsigned char *)ccrsr + (long)pm->pmTable); pm->pmTable = (CTabHandle) &colormap; /* handle to colormap */ /* * Draw the crsr using its mask. * Do we need the mask ??? ... */ CopyMask((BitMap *)pm, &mask_bitmap, &(local_port->portBits), &source_rect, &source_rect, dest); } // HUnlock(ih); // ReleaseResource((Handle)ih); DisposHandle((Handle)ih); } /* 931112, ragge, NADA, KTH */ #define HOFFSET 2 #define VOFFSET 2 static Rect gGrowTextBox; static Rect gGrowTextBoxInset; Boolean gDoGrowSize = false; static struct growSavedStruct { Point charSize; Point charInset; Boolean eraseIt; PenState savedPen; short txFont; Style txFace; short txMode; short txSize; } gGrowSaved; /* 931112, ragge, NADA, KTH */ void setupForGrow(WindowPtr window, short hCharInset, short vCharInset, short hCharSize, short vCharSize) { GrafPtr savedPort; FontInfo fInfo; GetPort(&savedPort); SetPort(window); gGrowSaved.charSize.h = hCharSize; gGrowSaved.charSize.v = vCharSize; gGrowSaved.charInset.h = hCharInset; gGrowSaved.charInset.v = vCharInset; if(gGrowSaved.charSize.h == 0) // don't want zero-div gGrowSaved.charSize.h = 1; if(gGrowSaved.charSize.v == 0) gGrowSaved.charSize.v = 1; gGrowSaved.eraseIt = false; GetPenState(&gGrowSaved.savedPen); gGrowSaved.txFont = window->txFont; gGrowSaved.txFace = window->txFace; gGrowSaved.txMode = window->txMode; gGrowSaved.txSize = window->txSize; PenNormal(); TextFont(1); TextSize(9); TextFace(0); TextMode(srcCopy); GetFontInfo(&fInfo); gGrowTextBox.top = VOFFSET; gGrowTextBox.left = HOFFSET; gGrowTextBox.bottom = VOFFSET + fInfo.ascent + fInfo.descent + fInfo.leading + 3; // Yes, 3! gGrowTextBox.right = HOFFSET + StringWidth("\p000 * 000") + 6; gGrowTextBoxInset = gGrowTextBox; InsetRect(&gGrowTextBoxInset, 1, 1); gDoGrowSize = true; SetPort(savedPort); } /* 931112, ragge, NADA, KTH */ void cleanupForGrow(WindowPtr window) { GrafPtr savedPort; GetPort(&savedPort); SetPort(window); gDoGrowSize = false; InvalRect(&gGrowTextBox); SetPenState(&gGrowSaved.savedPen); window->txFont = gGrowSaved.txFont; window->txFace = gGrowSaved.txFace; window->txMode = gGrowSaved.txMode; window->txSize = gGrowSaved.txSize; SetPort(savedPort); } /* 931112, ragge, NADA, KTH */ void drawSize(Rect *wSize, WindowPtr window) { unsigned char string[50], yValLen; GrafPtr savedPort; if(!gDoGrowSize) return; GetPort(&savedPort); SetPort(window); if(!gGrowSaved.eraseIt) { NumToString((wSize->right - wSize->left - 15 - gGrowSaved.charInset.h) / gGrowSaved.charSize.h, string); string[++string[0]] = ' '; string[++string[0]] = '*'; NumToString((wSize->bottom - wSize->top - 15 - gGrowSaved.charInset.v) / gGrowSaved.charSize.v, string + string[0] + 1); yValLen = string[string[0] + 1]; string[++string[0]] = ' '; string[0] += yValLen; TextBox(string + 1, string[0], &gGrowTextBoxInset, 1); FrameRect(&gGrowTextBox); } else { Rect rGlob = gGrowTextBox; LocalToGlobal((Point *) &(rGlob.top)); LocalToGlobal((Point *) &(rGlob.bottom)); } gGrowSaved.eraseIt = !gGrowSaved.eraseIt; SetPort(savedPort); } //empty function so we can load this high at initTime void loadWDEF(void) { } \ No newline at end of file +/******************************************* WDEF Patcher Steve Falkenburg MacDTS 1991 Apple Computer This snippet shows how you can add a simple extra part to a WDEF without writing an entire WDEF. It also shows how to access the new part via FindWindow(). Roberto Avanzi (independent programmer), June 18, 1992 Added support for tracking the extra part, in a way similar to the one used by the system. given back to Apple as an enhanced snippet (mmmh, sounds quite absurd) 6/1/92 SJF fixed a5 problem in WDEF patch (StripAddress is glue, and a5 wasn't set up) 6/1/92 SJF fixed varCode bug that made zoom boxes not work (masked out high 8 bits) *******************************************/ #include "wind.h" #include "wdefpatch.proto.h" #include "tnae.h" static void drawicon(short id, Rect *dest); /* 931112, ragge, NADA, KTH */ static void drawSize(Rect *wSize, WindowPtr window); /* add 2 to this when checking with FindWindow() ! */ #define kOurHit 32 /* * this struct allows us to insert a WDEF patch safely. It contains a jump instruction * and stores the old handle to the WDEF */ typedef struct { #ifdef __powerpc__ RoutineDescriptor rd; #else short jmpInst; ProcPtr patchAddr; #endif Handle oldAddr; Boolean partState; /* roberto avanzi jun 18 1992 */ long ourA5; struct WindRec *tw; } WDEFPatch, *WDEFPatchPtr, **WDEFPatchHndl; /* * RePatchWindowWDEF * this adjusts the tw pointer for a patched window * We have to do this since the tw for a window can change when other * windows are killed. */ void RePatchWindowWDEF (WindowPtr window, struct WindRec *tw) { WDEFPatchHndl wdPatch; wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc; (**wdPatch).tw = tw; } /* * GetPatchStuffHandle * This returns the handle to our patch block so we can release it * when killing windows. The tw is verified to insure that this * window is really patched. */ Handle GetPatchStuffHandle (WindowPtr window, struct WindRec *tw) { WDEFPatchHndl wdPatch; wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc; if ((**wdPatch).tw == tw) return ((Handle)wdPatch); else return ((Handle)0); } #ifdef __powerpc__ enum { uppMyWDEFPatch = kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(long))) | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr))) | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short))) | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long))) }; #endif pascal long MyWDEFPatch (short varCode, WindowPtr window, short message, long param) { WDEFPatchHndl wdPatch; pascal long (*wdefProc)(short varCode,WindowPtr window,short message,long param); Handle oldWDEF; long result; Rect ourRect,ourElementRect; GrafPtr savePort; GrafPtr aPort; RgnHandle aRgn; Rect aRect; struct WindRec *tw; long appA5, saveA5; wdPatch = (WDEFPatchHndl) ((WindowPeek)window)->windowDefProc; appA5 = (**wdPatch).ourA5; saveA5 = SetA5(appA5); ourRect = (**((WindowPeek)window)->strucRgn).rgnBBox; /* our 16x16 rectangle */ SetRect(&ourElementRect,ourRect.right-55,ourRect.top+1,ourRect.right-39,ourRect.top+17); tw = (**wdPatch).tw; oldWDEF = (**wdPatch).oldAddr; HLock(oldWDEF); wdefProc = (void *)*oldWDEF; wdefProc = (void *)StripAddress(wdefProc); /* * now, folks, WHY do I check it, u'll ask me ? Heh, it's a funny quirk in * the sys WDEF (at least, sys 7's, dunno whattabout older ones) . * Suppose You click once in the grow icon and DO NOT resize the window. * (remember, just click and do not move the mouse in the meantime). * Then you click on the added part. That part is tracked in the right way, * * BUT * * ALSO the zoom box gets hilited. Dunno why should happen, but It's a lot * of FUN. Sadly, cannot find its place in any useful app. Therefore we * do this check. * APPLE says: if you write your own WDEF and receive unknown messages, do not * do anything. pass along and do NOTHING. * APPLE does: we get something new ? therefore we process it anyway, just to * keep developers writing workarounds and keep their minds afresh. * What else can we say ? Thanks !!!!! (Roberto Avanzi june 19, 1992) */ if ( (message == wDraw) ? (((short)param) != kOurHit ) : true ) { #ifdef __powerpc__ result = CallUniversalProc((UniversalProcPtr)wdefProc, uppMyWDEFPatch, varCode, window, message, param); #else result = (wdefProc)(varCode,window,message,param); #endif } if (((WindowPeek)window)->visible) if (((WindowPeek)window)->hilited) { switch (message) { case wDraw: GetPort(&savePort); GetWMgrPort(&aPort); SetPort(aPort); aRgn = NewRgn(); GetClip(aRgn); SetRect(&aRect,-32000,-32000,32000,32000); ClipRect(&aRect); switch ( (short) param ) { // Roberto Avanzi 18-06-1992: support for // tracking of the new part case 0: (**wdPatch).partState = false; case kOurHit: PenNormal(); // draw our part if (tw->aedata != NULL) { tnParams *ae = (tnParams *)tw->aedata; if (ae->encrypting || ae->decrypting) { /* * erase 18 x 11. This gives us a 1 pixel margin * on the left and right, and matches the mask that * we're using in our crsr resources. */ InsetRect(&ourElementRect, -1, 0); ourElementRect.top += 3; ourElementRect.bottom -= 2; EraseRect(&ourElementRect); ourElementRect.top -= 3; ourElementRect.bottom += 2; InsetRect(&ourElementRect, 1, 0); } if (ae->encrypting && ae->decrypting) drawicon(lockcrsr, &ourElementRect); else if (ae->encrypting) drawicon(rightcrsr, &ourElementRect); else if (ae->decrypting) drawicon(leftcrsr, &ourElementRect); } break; default: break; } SetClip(aRgn); DisposeRgn(aRgn); SetPort(savePort); break; // removed this test so that one can move the window // also when clicking on the icon area. // 931112, ragge, NADA, KTH #ifdef NOTDEF case wHit: hitPt = (Point *)¶m; // hit test our part if (PtInRect(*hitPt,&ourElementRect)) { //result = kOurHit; } break; #endif case wGrow: /* 931112, ragge, NADA, KTH */ drawSize((Rect *) param, window); break; default: break; } // switch } // if hilited (otherwise we dont see the new box, addition by Roberto Avanzi) HUnlock(oldWDEF); SetA5(saveA5); return result; } #ifdef __powerpc__ RoutineDescriptor MyWDEFPatchUniversal = BUILD_ROUTINE_DESCRIPTOR(uppMyWDEFPatch, MyWDEFPatch); #endif /* * this installs the WDEF patch into a window */ void PatchWindowWDEF (WindowPtr window, struct WindRec *tw) { WDEFPatchHndl wdefHndl; WDEFPatchPtr wdefPatch; Handle oldAddr; unsigned long wdefEntry; wdefHndl = (WDEFPatchHndl)myNewHandle(sizeof(WDEFPatch)); oldAddr = ((WindowPeek)window)->windowDefProc; if (GetMMUMode()) // 32-bit wdefEntry = (unsigned long)wdefHndl; else wdefEntry = (unsigned long)StripAddress(wdefHndl) | ((unsigned long)oldAddr&0xff000000); HLock((Handle)wdefHndl); wdefPatch = *wdefHndl; wdefPatch->oldAddr = oldAddr; #ifdef __powerpc__ BlockMove(&MyWDEFPatchUniversal, &wdefPatch->rd, sizeof(wdefPatch->rd)); #else wdefPatch->jmpInst = 0x4ef9; /*JMP*/ wdefPatch->patchAddr = (ProcPtr)MyWDEFPatch; #endif wdefPatch->ourA5 = (long)LMGetCurrentA5(); /* Use universal access (RW) */ wdefPatch->tw = tw; HUnlock((Handle)wdefHndl); ((WindowPeek)window)->windowDefProc = (Handle)wdefEntry; } /* * drawicon */ void drawicon (short id, Rect *dest) { long qdv; Handle ih = 0; Rect source_rect; BitMap mask_bitmap; GrafPtr local_port; PixMap *pm; Ptr colormap; CCrsr *ccrsr; BitMap src_bitmap; GetPort(&local_port); ih = GetResource ('crsr', id); /* color cursor */ if (!ih) return; DetachResource(ih); /* ... need to save handle somewhere ... */ HLock(ih); /* ... to avoid reloading the resource all the time */ /* * Set source Rect and intialize source BitMaps. * A few PixMap fields must be munged; */ SetRect (&source_rect, 0, 0, 16, 16); ccrsr = (CCrsr *)(*ih); mask_bitmap.bounds = source_rect; mask_bitmap.rowBytes = 2; mask_bitmap.baseAddr = (Ptr)&ccrsr->crsrMask; /* (Ptr)(((Byte *)(*ih)) + 52); */ /* * if gestalt fails or no color quickdraw, just use the b/w bitmap. */ if (Gestalt(gestaltQuickdrawVersion, &qdv) || ((qdv & gestalt32BitQD) == 0)) { src_bitmap.bounds = source_rect; src_bitmap.rowBytes = 2; src_bitmap.baseAddr = (Ptr)&ccrsr->crsr1Data; CopyBits(&src_bitmap, &(local_port->portBits), &source_rect, dest, srcCopy, nil); } else { pm = (PixMap *) ((unsigned char *)ccrsr + (long)ccrsr->crsrMap); pm->baseAddr = (Ptr) ((unsigned char *)ccrsr + (long)ccrsr->crsrData); colormap = (Ptr) ((unsigned char *)ccrsr + (long)pm->pmTable); pm->pmTable = (CTabHandle) &colormap; /* handle to colormap */ /* * Draw the crsr using its mask. * Do we need the mask ??? ... */ CopyMask((BitMap *)pm, &mask_bitmap, &(local_port->portBits), &source_rect, &source_rect, dest); } // HUnlock(ih); // ReleaseResource((Handle)ih); DisposeHandle((Handle)ih); } /* 931112, ragge, NADA, KTH */ #define HOFFSET 2 #define VOFFSET 2 static Rect gGrowTextBox; static Rect gGrowTextBoxInset; Boolean gDoGrowSize = false; static struct growSavedStruct { Point charSize; Point charInset; Boolean eraseIt; PenState savedPen; short txFont; Style txFace; short txMode; short txSize; } gGrowSaved; /* 931112, ragge, NADA, KTH */ void setupForGrow(WindowPtr window, short hCharInset, short vCharInset, short hCharSize, short vCharSize) { GrafPtr savedPort; FontInfo fInfo; GetPort(&savedPort); SetPort(window); gGrowSaved.charSize.h = hCharSize; gGrowSaved.charSize.v = vCharSize; gGrowSaved.charInset.h = hCharInset; gGrowSaved.charInset.v = vCharInset; if(gGrowSaved.charSize.h == 0) // don't want zero-div gGrowSaved.charSize.h = 1; if(gGrowSaved.charSize.v == 0) gGrowSaved.charSize.v = 1; gGrowSaved.eraseIt = false; GetPenState(&gGrowSaved.savedPen); gGrowSaved.txFont = window->txFont; gGrowSaved.txFace = window->txFace; gGrowSaved.txMode = window->txMode; gGrowSaved.txSize = window->txSize; PenNormal(); TextFont(1); TextSize(9); TextFace(0); TextMode(srcCopy); GetFontInfo(&fInfo); gGrowTextBox.top = VOFFSET; gGrowTextBox.left = HOFFSET; gGrowTextBox.bottom = VOFFSET + fInfo.ascent + fInfo.descent + fInfo.leading + 3; // Yes, 3! gGrowTextBox.right = HOFFSET + StringWidth("\p000 * 000") + 6; gGrowTextBoxInset = gGrowTextBox; InsetRect(&gGrowTextBoxInset, 1, 1); gDoGrowSize = true; SetPort(savedPort); } /* 931112, ragge, NADA, KTH */ void cleanupForGrow(WindowPtr window) { GrafPtr savedPort; GetPort(&savedPort); SetPort(window); gDoGrowSize = false; InvalRect(&gGrowTextBox); SetPenState(&gGrowSaved.savedPen); window->txFont = gGrowSaved.txFont; window->txFace = gGrowSaved.txFace; window->txMode = gGrowSaved.txMode; window->txSize = gGrowSaved.txSize; SetPort(savedPort); } /* 931112, ragge, NADA, KTH */ void drawSize(Rect *wSize, WindowPtr window) { unsigned char string[50], yValLen; GrafPtr savedPort; if(!gDoGrowSize) return; GetPort(&savedPort); SetPort(window); if(!gGrowSaved.eraseIt) { NumToString((wSize->right - wSize->left - 15 - gGrowSaved.charInset.h) / gGrowSaved.charSize.h, string); string[++string[0]] = ' '; string[++string[0]] = '*'; NumToString((wSize->bottom - wSize->top - 15 - gGrowSaved.charInset.v) / gGrowSaved.charSize.v, string + string[0] + 1); yValLen = string[string[0] + 1]; string[++string[0]] = ' '; string[0] += yValLen; TETextBox(string + 1, string[0], &gGrowTextBoxInset, 1); FrameRect(&gGrowTextBox); } else { Rect rGlob = gGrowTextBox; LocalToGlobal((Point *) &(rGlob.top)); LocalToGlobal((Point *) &(rGlob.bottom)); } gGrowSaved.eraseIt = !gGrowSaved.eraseIt; SetPort(savedPort); } //empty function so we can load this high at initTime void loadWDEF(void) { } \ No newline at end of file diff --git "a/telnet.68k.\302\265.bin" "b/telnet.68k.\302\265.bin" index a0a444a..c503988 100644 Binary files "a/telnet.68k.\302\265.bin" and "b/telnet.68k.\302\265.bin" differ diff --git "a/telnet.ppc.\302\265.bin" "b/telnet.ppc.\302\265.bin" index be47127..184a6d4 100644 Binary files "a/telnet.ppc.\302\265.bin" and "b/telnet.ppc.\302\265.bin" differ