home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / applic / ncsa / Mac / Telnet2.6 / prerelease / d5 / Telnet 2.6.1d5.src.sit.hqx / Telnet 2.6.1d5 src / source / config / configure.c next >
Encoding:
C/C++ Source or Header  |  1995-01-11  |  37.0 KB  |  1,182 lines

  1. /*    Configure.c
  2. *    New Configuration scheme (the death of config.tel)
  3. *
  4. *****************************************************************
  5. *    NCSA Telnet for the Macintosh                                *
  6. *                                                                *
  7. *    National Center for Supercomputing Applications                *
  8. *    Software Development Group                                    *
  9. *    152 Computing Applications Building                            *
  10. *    605 E. Springfield Ave.                                        *
  11. *    Champaign, IL  61820                                        *
  12. *                                                                *
  13. *    Copyright (c) 1986-1993,                                    *
  14. *    Board of Trustees of the University of Illinois                *
  15. *****************************************************************
  16. *  Revisions:
  17. *  8/92        Telnet 2.6:    Initial version.  Jim Browne
  18. */
  19.  
  20. #ifdef MPW
  21. #pragma segment Configure
  22. #endif
  23.  
  24. #include "TelnetHeader.h"
  25. #include "dialog_resrcdefs.h"
  26. #include "string_resrcdefs.h"
  27. #include "general_resrcdefs.h"
  28. #include <stdio.h>
  29. #include <ctype.h>
  30. #include <Picker.h>
  31.  
  32. #include "newresrc.h"
  33.  
  34. #include "DlogUtils.proto.h"
  35. #include "popup.h"
  36. #include "popup.proto.h"
  37. #include "configure.proto.h"
  38. #include "netevent.proto.h"        /* For Stask proto */
  39. #include "prefs.proto.h"
  40. #include "bkgr.proto.h"            // For StartUpFTP proto
  41. #include "menuseg.proto.h"
  42. #include "macutil.proto.h"        
  43.  
  44. static    pascal short TerminalModalProc( DialogPtr dptr, EventRecord *evt, short *item);
  45. PROTO_UPP(TerminalModalProc, ModalFilter);
  46. static    pascal short SessionModalProc(DialogPtr dptr, EventRecord *evt, short *item);
  47. PROTO_UPP(SessionModalProc, ModalFilter);
  48. static    pascal short MyDlogWListFilter( DialogPtr dptr, EventRecord *evt, short *item);
  49. PROTO_UPP(MyDlogWListFilter, ModalFilter);
  50.  
  51. static    pascal void    listDitemproc(DialogPtr theDlg, short itemNo);
  52. PROTO_UPP(listDitemproc, UserItem);
  53.  
  54. extern SysEnvRec theWorld;        /* BYU 2.4.18 - System Environment record */
  55. extern    FTPServerPrefs*        gFTPServerPrefs;
  56. extern    ApplicationPrefs*    gApplicationPrefs;
  57.  
  58. static    void ZeroNumOnly(void);
  59. static    Boolean InNumOnly(short item);
  60.  
  61. #define NUMONLYSIZE 8
  62. short NumOnly[NUMONLYSIZE];        /* Items for which non-number keys are ignored */
  63.                                 // NumOnly[0] is number of "safe" item to return
  64.  
  65. void    CONFIGUREunload(void) {}
  66.                         
  67. void Cenviron( void)
  68. {
  69.     DialogPtr    dptr;
  70.     short         ditem;
  71.     Str255        scratchPstring;
  72.     long         scratchlong;
  73.     OSType        newtype;
  74.     
  75.     dptr = GetNewMySmallStrangeDialog( PrefDLOG, NULL, kInFront, (void *)ThirdCenterDialog);    
  76.     
  77.     SetCntrl(dptr, PrefDClose, gApplicationPrefs->WindowsDontGoAway);
  78.     SetCntrl(dptr, PrefStag, gApplicationPrefs->StaggerWindows);
  79.     SetCntrl(dptr, PrefCMDkey, gApplicationPrefs->CommandKeys);
  80.     SetCntrl(dptr, PrefTMap, gApplicationPrefs->RemapTilde);
  81.     SetCntrl(dptr, PrefBlink, gApplicationPrefs->BlinkCursor);
  82.     SetCntrl(dptr, PrefKeyFuncMenus, gApplicationPrefs->KeyPadAndFuncMenus);
  83.  
  84.     SetCntrl(dptr, PrefBlockCursor, (gApplicationPrefs->CursorType == 0));
  85.     SetCntrl(dptr, PrefUnderscoreCursor, (gApplicationPrefs->CursorType == 1));
  86.     SetCntrl(dptr, PrefVerticalCursor, (gApplicationPrefs->CursorType == 2));
  87.  
  88.     scratchPstring[0] = 4;
  89.     BlockMove(&(gApplicationPrefs->CaptureFileCreator), &scratchPstring[1], sizeof(OSType));
  90.     SetTEText(dptr, PrefCaptTE, scratchPstring);
  91.     newtype = gApplicationPrefs->CaptureFileCreator;
  92.  
  93.     scratchlong = gApplicationPrefs->CopyTableThresh;
  94.     NumToString(scratchlong, scratchPstring);
  95.     SetTEText(dptr, PrefCTt, scratchPstring);
  96.     SelIText(dptr, PrefCTt, 0, 32767);
  97.  
  98.     NumToString(gApplicationPrefs->TimeSlice, scratchPstring);
  99.     SetTEText(dptr, PrefTimeSlice, scratchPstring);
  100.     
  101.     scratchlong = (long) gApplicationPrefs->ConnectionTimeout;
  102.     NumToString(scratchlong,scratchPstring);
  103.     SetTEText(dptr,PrefConnTime, scratchPstring);     
  104.  
  105.     ShowWindow(dptr);
  106.     ditem=0;                                /* initially no hits */
  107.     while((ditem>2) || (ditem==0)) {    
  108.         ModalDialog(DLOGwOK_CancelUPP,&ditem);
  109.         switch(ditem) {
  110.             case PrefDClose:
  111.             case PrefStag:
  112.             case PrefCMDkey:
  113.             case PrefTMap:
  114.             case PrefBlink:
  115.             case PrefKeyFuncMenus:
  116.                 FlipCheckBox( dptr, ditem);
  117.                 break;
  118.  
  119.             case PrefBlockCursor:
  120.                 SetCntrl(dptr, PrefBlockCursor, 1);
  121.                 SetCntrl(dptr, PrefUnderscoreCursor, 0);
  122.                 SetCntrl(dptr, PrefVerticalCursor, 0);
  123.                 break;
  124.             case PrefUnderscoreCursor:
  125.                 SetCntrl(dptr, PrefBlockCursor, 0);
  126.                 SetCntrl(dptr, PrefUnderscoreCursor, 1);
  127.                 SetCntrl(dptr, PrefVerticalCursor, 0);
  128.                 break;
  129.             case PrefVerticalCursor:
  130.                 SetCntrl(dptr, PrefBlockCursor, 0);
  131.                 SetCntrl(dptr, PrefUnderscoreCursor, 0);
  132.                 SetCntrl(dptr, PrefVerticalCursor, 1);
  133.                 break;
  134.  
  135.             case PrefCaptCreat:
  136.                 GetApplicationType(&newtype);
  137.                 scratchPstring[0] = 4;
  138.                 BlockMove(&newtype, &scratchPstring[1], sizeof(OSType));
  139.                 SetTEText(dptr, PrefCaptTE, scratchPstring);
  140.             default:
  141.                 break;
  142.             } /* switch */
  143.         }
  144.     
  145.     if (ditem==DLOGCancel) {
  146.             DisposDialog( dptr);
  147.             return;
  148.             }
  149.  
  150.     GetTEText(dptr, PrefCTt, scratchPstring);
  151.     StringToNum(scratchPstring, &scratchlong);
  152.     gApplicationPrefs->CopyTableThresh = (short) scratchlong;
  153.  
  154.     GetTEText(dptr, PrefTimeSlice, scratchPstring);
  155.     StringToNum(scratchPstring, &scratchlong);
  156.     BoundsCheck(&scratchlong, 100, 2);
  157.     gApplicationPrefs->TimeSlice = scratchlong;
  158.  
  159.     GetTEText(dptr,PrefConnTime, scratchPstring);
  160.     StringToNum(scratchPstring, &scratchlong);
  161.     gApplicationPrefs->ConnectionTimeout = (short) scratchlong;
  162.     TelInfo->ConnTimeout = (short) scratchlong; 
  163.  
  164.     GetTEText(dptr, PrefCaptTE, scratchPstring);
  165.     BlockMove(&scratchPstring[1], &(gApplicationPrefs->CaptureFileCreator), sizeof(OSType));
  166.  
  167.     gApplicationPrefs->CommandKeys = GetCntlVal(dptr, PrefCMDkey);                    
  168.     gApplicationPrefs->WindowsDontGoAway = GetCntlVal(dptr, PrefDClose);
  169.     gApplicationPrefs->RemapTilde =    GetCntlVal(dptr, PrefTMap);
  170.     gApplicationPrefs->StaggerWindows = GetCntlVal(dptr, PrefStag);
  171.     gApplicationPrefs->BlinkCursor = GetCntlVal(dptr, PrefBlink);
  172.     gApplicationPrefs->KeyPadAndFuncMenus = GetCntlVal(dptr, PrefKeyFuncMenus);
  173.  
  174.     gApplicationPrefs->CursorType = (GetCntlVal(dptr, PrefUnderscoreCursor) == 1) + (2 *
  175.                                      (GetCntlVal(dptr, PrefVerticalCursor) == 1));
  176.                                      
  177.     switchMenus(gApplicationPrefs->CommandKeys);
  178.     SavePreferences();
  179.     
  180.     DisposDialog( dptr);
  181. }
  182.  
  183.  
  184. void Cftp(void)
  185. {
  186.     DialogPtr            dptr;
  187.     short                ditem;
  188.     Str255                scratchPstring;
  189.     OSType                scratchOSType;
  190.     SFReply                sfr;
  191.     FInfo                fi;            
  192.     Point                where = {100,100};
  193.     
  194.     dptr = GetNewMySmallStrangeDialog( FTPDLOG, NULL, kInFront, (void *)ThirdCenterDialog);    
  195.  
  196.     SetCntrl(dptr, FTPServerOff, (gFTPServerPrefs->ServerState == 0));
  197.     SetCntrl(dptr, FTPServerUnsecure, (gFTPServerPrefs->ServerState == 1));
  198.     SetCntrl(dptr, FTPServerPswdPlease, (gFTPServerPrefs->ServerState == 2));
  199.     SetCntrl(dptr, FTPShowFTPlog, gFTPServerPrefs->ShowFTPlog);
  200.     SetCntrl(dptr, FTPrevDNS, gFTPServerPrefs->DNSlookupconnections);
  201.     SetCntrl(dptr, FTPUseMacBinaryII, gFTPServerPrefs->UseMacBinaryII);
  202.     SetCntrl(dptr, FTPResetMacBinary, gFTPServerPrefs->ResetMacBinary);
  203.     SetCntrl(dptr, FTPISO, gFTPServerPrefs->DoISOtranslation);
  204.  
  205.     HideDItem(dptr, FTPrevDNS);        // Sometime later, perhaps.
  206.     
  207.     scratchPstring[0] = 4;
  208.  
  209.     BlockMove(&(gFTPServerPrefs->BinaryCreator), &scratchPstring[1], sizeof(OSType));
  210.     SetTEText(dptr, FTPbincreatTE, scratchPstring);
  211.     
  212.     BlockMove(&(gFTPServerPrefs->BinaryType), &scratchPstring[1], sizeof(OSType));
  213.     SetTEText(dptr, FTPbintypeTE, scratchPstring);
  214.     SelIText(dptr, FTPbintypeTE, 0, 32767);
  215.  
  216.     BlockMove(&(gFTPServerPrefs->TextCreator), &scratchPstring[1], sizeof(OSType));
  217.     SetTEText(dptr, FTPtextcreatTE, scratchPstring);
  218.  
  219.     ShowWindow(dptr);
  220.     ditem=0;                                    /* initially no hits */
  221.     while((ditem>2) || (ditem==0)) {    
  222.         ModalDialog(DLOGwOK_CancelUPP,&ditem);
  223.         switch(ditem) {
  224.             case    FTPShowFTPlog:
  225.             case    FTPrevDNS:
  226.             case    FTPUseMacBinaryII:
  227.             case    FTPResetMacBinary:
  228.             case    FTPISO:
  229.                 FlipCheckBox( dptr, ditem);
  230.                 break;
  231.  
  232.             case    FTPServerOff:
  233.                 SetCntrl(dptr, FTPServerOff, 1);
  234.                 SetCntrl(dptr, FTPServerUnsecure, 0);
  235.                 SetCntrl(dptr, FTPServerPswdPlease, 0);
  236.                 break;
  237.             case    FTPServerUnsecure:
  238.                 SetCntrl(dptr, FTPServerOff, 0);
  239.                 SetCntrl(dptr, FTPServerUnsecure, 1);
  240.                 SetCntrl(dptr, FTPServerPswdPlease, 0);
  241.                 break;
  242.             case    FTPServerPswdPlease:
  243.                 SetCntrl(dptr, FTPServerOff, 0);
  244.                 SetCntrl(dptr, FTPServerUnsecure, 0);
  245.                 SetCntrl(dptr, FTPServerPswdPlease, 1);
  246.                 break;
  247.  
  248.             case    FTPtextcreatorbutton:
  249.                 if (GetApplicationType(&scratchOSType)) {
  250.                     BlockMove(&scratchOSType, &scratchPstring[1], sizeof(OSType));
  251.                     SetTEText(dptr, FTPtextcreatTE, scratchPstring);
  252.                     }
  253.                 break;
  254.             
  255.             case    FTPbinexamplebutton:
  256.                 SFGetFile(where, NULL, NULL, -1, NULL, NULL, &sfr);
  257.                 if (sfr.good) {
  258.                     GetFInfo(sfr.fName, sfr.vRefNum, &fi);
  259.                     scratchPstring[0] = sizeof(OSType);
  260.                     BlockMove(&fi.fdCreator, &scratchPstring[1], sizeof(OSType));
  261.                     SetTEText(dptr, FTPbincreatTE, scratchPstring);
  262.                     BlockMove(&fi.fdType, &scratchPstring[1], sizeof(OSType));
  263.                     SetTEText(dptr, FTPbintypeTE, scratchPstring);
  264.                     }
  265.                 break;    
  266.             default:
  267.                 break;
  268.             } /* switch */
  269.         } /* while */
  270.     
  271.     if (ditem==DLOGCancel) {
  272.             DisposDialog( dptr);
  273.             return;
  274.             }
  275.  
  276.     gFTPServerPrefs->ServerState = GetCntlVal(dptr, FTPServerUnsecure) + 
  277.         GetCntlVal(dptr, FTPServerPswdPlease) * 2;
  278.     StartUpFTP();            // Make sure FTP server recognizes new mode.
  279.     
  280.     gFTPServerPrefs->ShowFTPlog = GetCntlVal(dptr, FTPShowFTPlog);
  281.     gFTPServerPrefs->DNSlookupconnections = GetCntlVal(dptr, FTPrevDNS);
  282.     gFTPServerPrefs->UseMacBinaryII = GetCntlVal(dptr, FTPUseMacBinaryII);
  283.     gFTPServerPrefs->ResetMacBinary = GetCntlVal(dptr, FTPResetMacBinary);
  284.     gFTPServerPrefs->DoISOtranslation = GetCntlVal(dptr, FTPISO);
  285.  
  286.     GetTEText(dptr, FTPbincreatTE, scratchPstring);
  287.     BlockMove(&scratchPstring[1], &(gFTPServerPrefs->BinaryCreator), sizeof(OSType));
  288.     
  289.     GetTEText(dptr, FTPbintypeTE, scratchPstring);
  290.     BlockMove(&scratchPstring[1], &(gFTPServerPrefs->BinaryType), sizeof(OSType));
  291.  
  292.     GetTEText(dptr, FTPtextcreatTE, scratchPstring);
  293.     BlockMove(&scratchPstring[1], &(gFTPServerPrefs->TextCreator), sizeof(OSType));
  294.  
  295.     SavePreferences();
  296.     
  297.     DisposDialog( dptr);
  298. }
  299.  
  300. Boolean GetApplicationType(OSType *type)
  301. {
  302.     SFTypeList types;
  303.     SFReply sfr;
  304.     FInfo fi;
  305.     Point where;
  306.     
  307.     SetPt(&where, 100, 100);
  308.     types[0] = 'APPL';
  309.     SFGetFile(where, NULL, NULL, 1, types, NULL, &sfr);
  310.     if (sfr.good) {
  311.         GetFInfo(sfr.fName, sfr.vRefNum, &fi);
  312.         BlockMove(&fi.fdCreator, type, sizeof(OSType));        // Copy the application creator type
  313.         }
  314.         
  315.     return(sfr.good);
  316. }
  317.  
  318. //    Our standard modal dialog filter with code for handling user items containing lists.
  319. SIMPLE_UPP(MyDlogWListFilter, ModalFilter);
  320. pascal short MyDlogWListFilter( DialogPtr dptr, EventRecord *evt, short *item)
  321. {
  322.     short keyCode, key, iType;
  323.     Handle iHndl;
  324.     Rect iRect;
  325.     Point scratchPoint;
  326.  
  327.     SetPort(dptr);
  328.     if (evt->what == keyDown) {
  329.         key = evt->message & charCodeMask;
  330.         keyCode = (evt->message >>8) & 0xff ;
  331.         if ((key == 0x0d) || (key == 0x03)) { // 0x0d == return, 0x03 == enter
  332.             *item = 1;                // ok
  333.             FlashButton(dptr, 1);
  334.             return(-1);
  335.             }
  336.         }
  337.     else if (evt->what == updateEvt) {
  338.         if ((WindowPtr)evt->message == dptr) {
  339.             GetDItem(dptr,1,&iType,&iHndl,&iRect);    // ok
  340.             PenSize(3,3);
  341.             InsetRect(&iRect,-4,-4);
  342.             FrameRoundRect(&iRect,16,16);
  343.             }
  344.     }
  345.     
  346.     if (evt->what == mouseDown) {
  347.         GetDItem(dptr, kItemList, &iType, &iHndl, &iRect);
  348.         scratchPoint = evt->where;
  349.         GlobalToLocal(&scratchPoint);
  350.         if (PtInRect(scratchPoint, &iRect)) {
  351.             *item = kItemList;
  352.             if (LClick(scratchPoint, evt->modifiers, (ListHandle)GetWRefCon(dptr))) {
  353.                 *item = kChange;
  354.                 FlashButton(dptr, kChange);
  355.                 }    
  356.             return(-1);
  357.         }
  358.     }
  359.     
  360.     return(FALSE);
  361. }
  362.  
  363. //    User Dialog Item Procedure for a list.  Assumes the Dialog's refcon contains the list
  364. //    handle.
  365. SIMPLE_UPP(listDitemproc, UserItem);
  366. pascal void    listDitemproc(DialogPtr theDlg, short itemNo)
  367. {
  368.     short        itemType;
  369.     Handle        ControlHndl;
  370.     Rect        scratchRect;
  371.     
  372.     GetDItem(theDlg, itemNo, &itemType, &ControlHndl, &scratchRect);
  373.     
  374.     PenNormal();
  375.     InsetRect(&scratchRect, -1, -1);
  376.     FrameRect(&scratchRect);
  377.     LUpdate(theDlg->visRgn, (ListHandle)GetWRefCon(theDlg));
  378. }
  379.  
  380. void    BoundsCheck(long *value, long high, long low)
  381. {
  382.     if (*value > high) *value = high;
  383.     if (*value < low) *value = low;
  384. }
  385.  
  386. void    EditConfigType(ResType ConfigResourceType, Boolean (*EditFunction)(StringPtr))
  387. {
  388.     DialogPtr    dptr;
  389.     Handle         iHndl;
  390.     short         iType, length, ditem, numberofitems, index, resID;
  391.     Rect         ListBox, ListBounds;
  392.     Point         cellSize, theCell;
  393.     ListHandle    thelist;
  394.     Handle        ItemResource;
  395.     Str255        ItemName;
  396.     ResType        restype;
  397.  
  398.     dptr = GetNewMySmallDialog(kItemDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  399.     ditem = 3;
  400.  
  401.     GetDItem(dptr, kItemList, &iType, &iHndl, &ListBox);
  402.     SetDItem(dptr, kItemList, iType, (Handle)listDitemprocUPP, &ListBox);
  403.     
  404.  
  405.     ListBox.right -= 15;        // Make room for scrollbar
  406.     SetRect(&ListBounds, 0,0,1,0);
  407.     SetPt(&cellSize,(ListBox.right-ListBox.left),16);
  408.     thelist = LNew(&ListBox, &ListBounds, cellSize, 0, (WindowPtr)dptr,0,0,0,1);
  409. #define kSCListMods lNoNilHilite+lOnlyOne
  410.     (*(thelist))->listFlags = kSCListMods;
  411.     
  412.     SetWRefCon(dptr, (long)thelist);        // So the Ditem proc can find the list
  413.     
  414.     UseResFile(TelInfo->SettingsFile);
  415.     numberofitems = Count1Resources(ConfigResourceType);
  416.     
  417.     for(index = 1, theCell.v = 0, theCell.h = 0; index <= numberofitems;
  418.                  index++, theCell.v++) {
  419.         ItemResource = Get1IndResource(ConfigResourceType, index);
  420.         GetResInfo(ItemResource, &resID, &restype, (StringPtr)&ItemName);
  421.         LAddRow(1,-1, thelist);
  422.         LSetCell(ItemName+1, Length(ItemName), theCell, thelist);
  423.         ReleaseResource(ItemResource);
  424.         }
  425.         
  426.     theCell.v = 0;
  427.     theCell.h = 0;
  428.     if (numberofitems) LSetSelect(1, theCell, thelist);
  429.     LDoDraw(1, thelist);
  430. //    LUpdate(dptr->visRgn, thelist); Is this needed?
  431.     
  432.     while (ditem > 1) {
  433.         ModalDialog(MyDlogWListFilterUPP, &ditem);
  434.         
  435.         switch(ditem) {
  436.             case kRemove:
  437.                 SetPt(&theCell, 0, 0);
  438.                 if (LGetSelect(TRUE, &theCell, thelist)) {
  439.                     length = 254;
  440.                     LGetCell(ItemName+1, &length, theCell, thelist);
  441.                     ItemName[0] = (char)length;
  442.                     if (!(EqualString(ItemName, "\p<Default>", TRUE, FALSE))) {
  443.                         LDelRow(1,theCell.v,thelist);
  444.                         UseResFile(TelInfo->SettingsFile);
  445.                         ItemResource = Get1NamedResource(ConfigResourceType, ItemName);
  446.                         RmveResource(ItemResource);
  447.                         ReleaseResource(ItemResource);
  448.                         UpdateResFile(TelInfo->SettingsFile);
  449.                         }
  450.                     }
  451.             break;
  452.             
  453.             case kChange:
  454.                 SetPt(&theCell, 0, 0);
  455.                 if (LGetSelect(TRUE, &theCell, thelist)) {
  456.                     length = 254;
  457.                     LGetCell(ItemName+1, &length, theCell, thelist);
  458.                     ItemName[0] = (char)length;
  459.                     if ((*EditFunction)((StringPtr)&ItemName)) {
  460.                         LSetCell(ItemName+1, Length(ItemName), theCell, thelist);
  461.                     }
  462.                 }
  463.             break;
  464.             
  465.             case kNew:        
  466.                 ItemName[0] = 0;                    // Signal new shortcut
  467.                 if ((*EditFunction)((StringPtr)&ItemName)) {
  468.                     theCell.v = LAddRow(1, -1, thelist);
  469.                     LSetCell(ItemName+1, Length(ItemName), theCell, thelist);
  470.                 }
  471.             break;
  472.         } // switch
  473.         
  474.         SetPt(&theCell, 0, 0);
  475.         if (LGetSelect(TRUE, &theCell, thelist)) {
  476.             Hilite(dptr, kRemove, 0);
  477.             Hilite(dptr, kChange, 0);
  478.             }
  479.         else {
  480.             Hilite(dptr, kRemove, 255);
  481.             Hilite(dptr, kChange, 255);
  482.             }
  483.         
  484.     } // while
  485.     
  486.     LDispose(thelist);
  487.     DisposDialog(dptr);
  488. }
  489.  
  490. void ZeroNumOnly(void)
  491. {
  492.     short i;
  493.     
  494.     for(i=0; i<NUMONLYSIZE; i++) NumOnly[i]=0;
  495. }
  496.  
  497. Boolean InNumOnly(short item)
  498. {
  499.     short index = 1;
  500.     
  501.     while ((NumOnly[index] != item) && (NumOnly[index] != 0)) index++;
  502.     
  503.     return(NumOnly[index] == item);
  504. }
  505.  
  506. short        NumberOfColorBoxes;
  507. short        BoxColorItems[8];
  508. RGBColor    BoxColorData[8];
  509.  
  510. SIMPLE_UPP(ColorBoxItemProc, UserItem);
  511. pascal void    ColorBoxItemProc(DialogPtr theDlg, short itemNo)
  512. {
  513.     short        itemType, index = 0;
  514.     Handle        ControlHndl;
  515.     Rect        scratchRect;
  516.     RGBColor    rgb;
  517.  
  518.     GetDItem(theDlg, itemNo, &itemType, &ControlHndl, &scratchRect);
  519.     PenNormal();
  520.     FrameRect(&scratchRect);
  521.     InsetRect(&scratchRect, 1, 1);            // Why isn't this framing the boxes?
  522.     
  523.     GetForeColor(&rgb);
  524.  
  525.     while ((index < NumberOfColorBoxes) && (BoxColorItems[index] != itemNo)) index++;
  526.     
  527.     RGBForeColor(&BoxColorData[index]);        /* color corresponding to item */
  528.     PaintRect(&scratchRect);
  529.  
  530.     RGBForeColor(&rgb);            /* restore previous foreground color */
  531. }
  532.  
  533. SIMPLE_UPP(ColorBoxModalProc, ModalFilter);
  534. pascal short ColorBoxModalProc( DialogPtr dptr, EventRecord *evt, short *item)
  535. {
  536.     short keyCode, key, iType, index;
  537.     Handle    iHndl;
  538.     Rect    iRect;
  539.     
  540.     if ((evt->what == keyDown) || (evt->what == autoKey)) {
  541.         key = evt->message & charCodeMask;
  542.         keyCode = (evt->message >>8) & 0xff;
  543.         if ((key == 0x0d) || (key == 0x03)) { // 0x0d == return, 0x03 == enter
  544.             *item = DLOGOk;
  545.             return(-1);                /* BYU LSC - pascal doesn't like "1" as true */
  546.             }
  547.         if (((key == '.') && (evt->modifiers & cmdKey)) ||
  548.             ((key == 0x1b) && (keyCode == 0x35)) ) {    // 0x35 == escKey
  549.             *item = DLOGCancel;
  550.             return(-1);                /* BYU LSC - pascal doesn't like "1" as true */
  551.             }
  552.  
  553.         if ((key < '0' || key > '9') && 
  554.             !(key == 0x08 || key == 0x09 || (key > 0x1B && key < 0x20))
  555.             && InNumOnly(((DialogPeek)dptr)->editField + 1)) {
  556.                 /* Reject non-numbers for this TE */
  557.                 *item = NumOnly[0];    /* Kludge -- Return "safe" item */
  558.                 return(-1);
  559.                 }   
  560.            }
  561.            
  562.     if (evt->what == updateEvt) {
  563.         if ((WindowPtr)evt->message == dptr) {
  564.             GetDItem(dptr,DLOGOk,&iType,&iHndl,&iRect);    // ok
  565.             PenSize(3,3);
  566.             InsetRect(&iRect,-4,-4);
  567.             FrameRoundRect(&iRect,16,16);
  568.             for (index = 0; index < NumberOfColorBoxes; index++)
  569.                 ColorBoxItemProc(dptr, BoxColorItems[index]);        // update color boxes
  570.             }
  571.     }
  572.     
  573.     Stask();
  574.     return(FALSE);
  575. }
  576.  
  577. SIMPLE_UPP(TerminalModalProc, ModalFilter);
  578. pascal short TerminalModalProc( DialogPtr dptr, EventRecord *evt, short *item)
  579. {
  580.     if (evt->what == mouseDown) return(PopupMousedown(dptr, evt, item));
  581.  
  582.     return(ColorBoxModalProc(dptr, evt, item));
  583. }
  584.  
  585. SIMPLE_UPP(SessionModalProc, ModalFilter);
  586. pascal short SessionModalProc(DialogPtr dptr, EventRecord *evt, short *item)
  587. {
  588.     if ((evt->what == keyDown) || (evt->what == autoKey))
  589.         if ((evt->message & charCodeMask) == ' ') {
  590.             *item = NumOnly[0];    /* Kludge -- Return "safe" item */
  591.             return(-1);
  592.             }
  593.     
  594.     return(TerminalModalProc(dptr, evt, item));
  595. }
  596.  
  597. Boolean EditTerminal(StringPtr PrefRecordNamePtr)
  598. {
  599.     DialogPtr        dptr;
  600.     short            ditem, scratchshort, resourceID;
  601.     long            scratchlong;
  602.     ResType            scratchResType;
  603.     Boolean            IsNewPrefRecord, UserLikesNewColor;
  604.     TerminalPrefs**    TermPrefsHdl;
  605.     TerminalPrefs*    TermPrefsPtr;
  606.     Str255            scratchPstring;
  607.     RGBColor        scratchRGBcolor;
  608.     Point            ColorBoxPoint;
  609.     MenuHandle        WeNeedAFontMenuHandle;
  610.     popup TPopup[] = {{TermFontPopup, (MenuHandle) 0, 1},
  611.                         {0, (MenuHandle) 0, 0}};
  612.  
  613.     dptr = GetNewMySmallStrangeDialog(TermDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  614.     ditem = 3;
  615.     
  616.     WeNeedAFontMenuHandle = NewMenu(666, "\p");
  617.     AddResMenu(WeNeedAFontMenuHandle, 'FONT');
  618.     TPopup[0].h = WeNeedAFontMenuHandle;
  619.     PopupInit(dptr, TPopup);
  620.     
  621.     if (PrefRecordNamePtr[0] != 0) {
  622.         IsNewPrefRecord = FALSE;
  623.         UseResFile(TelInfo->SettingsFile);
  624.         TermPrefsHdl = (TerminalPrefs **)Get1NamedResource(TERMINALPREFS_RESTYPE, PrefRecordNamePtr);
  625.         if (EqualString(PrefRecordNamePtr, "\p<Default>", FALSE, FALSE)) {
  626.             HideDItem(dptr, TermNameStatText);
  627.             HideDItem(dptr, TermName);
  628.             }
  629.         }
  630.     else {
  631.         TermPrefsHdl = GetDefaultTerminal();
  632.         IsNewPrefRecord = TRUE;
  633.         GetIndString(PrefRecordNamePtr, MISC_STRINGS, MISC_NEWTERM);
  634.         }
  635.  
  636.     HLock((Handle) TermPrefsHdl);
  637.     TermPrefsPtr = *TermPrefsHdl;
  638.     SetTEText(dptr, TermName, PrefRecordNamePtr);
  639.     SetCntrl(dptr, TermANSI, TermPrefsPtr->ANSIgraphics);
  640.     HideDItem(dptr, TermANSI);                // Perhaps later
  641.     SetCntrl(dptr, TermXterm, TermPrefsPtr->Xtermsequences);
  642.     SetCntrl(dptr, Termvtwrap, TermPrefsPtr->vtwrap);
  643.     SetCntrl(dptr, Termmeta, TermPrefsPtr->emacsmetakey);
  644.     SetCntrl(dptr, Termarrow, TermPrefsPtr->emacsarrows);
  645.     SetCntrl(dptr, TermMAT, TermPrefsPtr->MATmappings);
  646.     SetCntrl(dptr, Termeightbit, TermPrefsPtr->eightbit);
  647.     SetCntrl(dptr, Termclearsave, TermPrefsPtr->clearsave);
  648.     SetCntrl(dptr, TermVT100, (TermPrefsPtr->vtemulation == 0));
  649.     SetCntrl(dptr, TermVT220, (TermPrefsPtr->vtemulation == 1));
  650.     scratchlong = (long)(TermPrefsPtr->vtwidth);
  651.     NumToString(scratchlong, scratchPstring);
  652.     SetTEText(dptr, TermWidth, scratchPstring);
  653.     scratchlong = (short)(TermPrefsPtr->vtheight);
  654.     NumToString(scratchlong, scratchPstring);
  655.     SetTEText(dptr, TermHeight, scratchPstring);
  656.     scratchlong = TermPrefsPtr->fontsize;
  657.     NumToString(scratchlong, scratchPstring);
  658.     SetTEText(dptr, TermFontSize, scratchPstring);
  659.     scratchlong = TermPrefsPtr->numbkscroll;
  660.     NumToString(scratchlong, scratchPstring);
  661.     SetTEText(dptr, TermScrollback, scratchPstring);
  662.     SetTEText(dptr, TermAnswerback, TermPrefsPtr->AnswerBackMessage);
  663.     
  664.     for(scratchshort = CountMItems(TPopup[0].h); scratchshort; scratchshort--) {
  665.         GetItem(TPopup[0].h, scratchshort, scratchPstring);
  666.         if (EqualString(scratchPstring, (TermPrefsPtr->DisplayFont), TRUE, FALSE))
  667.             TPopup[0].choice = scratchshort;
  668.         }
  669.     
  670.     ZeroNumOnly();
  671.     NumOnly[0] = TermSafeItem;
  672.     NumOnly[1] = TermWidth; NumOnly[2] = TermHeight; NumOnly[3] = TermFontSize;
  673.     NumOnly[4] = TermScrollback;  NumOnly[5] = 0;
  674.     
  675.     if (theWorld.hasColorQD) {
  676.         for (scratchshort = 0, NumberOfColorBoxes = 4; scratchshort < NumberOfColorBoxes; scratchshort++) {
  677.             BoxColorItems[scratchshort] = TermNFcolor + scratchshort;
  678.             BlockMove(&(TermPrefsPtr->nfcolor) + scratchshort,
  679.                 &BoxColorData[scratchshort], sizeof(RGBColor));
  680.             UItemAssign( dptr, TermNFcolor + scratchshort, ColorBoxItemProcUPP);
  681.             }
  682.         }
  683.     else
  684.         NumberOfColorBoxes = 0;        // B&W machine
  685.         
  686.     ColorBoxPoint.h = 0;            // Have the color picker center the box on the main
  687.     ColorBoxPoint.v = 0;            // screen
  688.         
  689.     SelIText(dptr, TermName, 0, 32767);
  690.     ShowWindow(dptr);
  691.     
  692.     while (ditem > 2) {
  693.         ModalDialog(TerminalModalProcUPP, &ditem);
  694.         switch (ditem) {
  695.             case    TermANSI:
  696.             case    TermXterm:
  697.             case    Termvtwrap:
  698.             case    Termmeta:
  699.             case    Termarrow:
  700.             case    TermMAT:
  701.             case    Termeightbit:
  702.             case    Termclearsave:
  703.                 FlipCheckBox(dptr, ditem);
  704.                 break;
  705.             
  706.             case    TermVT100:
  707.                 SetCntrl(dptr, TermVT100, 1);
  708.                 SetCntrl(dptr, TermVT220, 0);
  709.                 SetTEText(dptr, TermAnswerback, "\pVT100");
  710.                 break;
  711.  
  712.             case    TermVT220:
  713.                 SetCntrl(dptr, TermVT100, 0);
  714.                 SetCntrl(dptr, TermVT220, 1);
  715.                 SetTEText(dptr, TermAnswerback, "\pVT220");
  716.                 break;
  717.             
  718.             case    TermNFcolor:    
  719.             case    TermNBcolor:    
  720.             case    TermBFcolor:    
  721.             case    TermBBcolor:    
  722.                 if (theWorld.hasColorQD) {
  723.                     UserLikesNewColor = GetColor(ColorBoxPoint, "\pPlease Select New Color",
  724.                          &BoxColorData[ditem-TermNFcolor], &scratchRGBcolor);
  725.                     if (UserLikesNewColor)
  726.                         BoxColorData[ditem-TermNFcolor] = scratchRGBcolor;
  727.                     }
  728.                 break;
  729.                 
  730.             default:
  731.                 break;
  732.             
  733.             } // switch
  734.         } // while
  735.             
  736.     GetItem(TPopup[0].h, TPopup[0].choice, scratchPstring);
  737.     PopupCleanup();
  738.     
  739.     if (ditem == 2) {
  740.         if (IsNewPrefRecord) DisposeHandle((Handle) TermPrefsHdl);
  741.         else ReleaseResource((Handle) TermPrefsHdl);
  742.         
  743.         DisposeDialog(dptr);
  744.         return(FALSE);            // No changes should be made.
  745.         }
  746.     
  747.         
  748.     if (theWorld.hasColorQD) {
  749.         for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) {
  750.                 BlockMove(&BoxColorData[scratchshort], 
  751.                     &(TermPrefsPtr->nfcolor) + scratchshort, sizeof(RGBColor));
  752.             }
  753.         }
  754.         
  755.     if (Length(scratchPstring) > 63) scratchPstring[0] = 63;
  756.     BlockMove(scratchPstring, (TermPrefsPtr->DisplayFont), scratchPstring[0]+1);
  757.     
  758.     TermPrefsPtr->ANSIgraphics = GetCntlVal(dptr, TermANSI);
  759.     TermPrefsPtr->Xtermsequences = GetCntlVal(dptr, TermXterm);
  760.     TermPrefsPtr->vtwrap = GetCntlVal(dptr, Termvtwrap);
  761.     TermPrefsPtr->emacsmetakey = GetCntlVal(dptr, Termmeta);
  762.     TermPrefsPtr->emacsarrows = GetCntlVal(dptr, Termarrow);
  763.     TermPrefsPtr->MATmappings = GetCntlVal(dptr, TermMAT);
  764.     TermPrefsPtr->eightbit = GetCntlVal(dptr, Termeightbit);
  765.     TermPrefsPtr->clearsave = GetCntlVal(dptr, Termclearsave);
  766.     
  767.     TermPrefsPtr->vtemulation = (GetCntlVal(dptr, TermVT220) != 0);
  768.  
  769.     GetTEText(dptr, TermWidth, scratchPstring);
  770.     StringToNum(scratchPstring, &scratchlong);
  771.     BoundsCheck(&scratchlong, 133, 10);
  772.     TermPrefsPtr->vtwidth = (short) scratchlong;
  773.     
  774.     GetTEText(dptr, TermHeight, scratchPstring);
  775.     StringToNum(scratchPstring, &scratchlong);
  776.     BoundsCheck(&scratchlong, 80, 10);
  777.     TermPrefsPtr->vtheight = (short) scratchlong;
  778.  
  779.     GetTEText(dptr, TermFontSize, scratchPstring);
  780.     StringToNum(scratchPstring, &scratchlong);
  781.     BoundsCheck(&scratchlong, 24, 4);
  782.     TermPrefsPtr->fontsize = (short) scratchlong;
  783.  
  784.     GetTEText(dptr, TermScrollback, scratchPstring);
  785.     StringToNum(scratchPstring, &scratchlong);
  786.     BoundsCheck(&scratchlong, 50000, 24);
  787.     TermPrefsPtr->numbkscroll = (short) scratchlong;
  788.  
  789.     GetTEText(dptr, TermAnswerback, scratchPstring);
  790.     if (Length(scratchPstring) > 63) scratchPstring[0] = 63;
  791.     BlockMove(scratchPstring, TermPrefsPtr->AnswerBackMessage, scratchPstring[0]+1);
  792.     
  793.     GetTEText(dptr, TermName, PrefRecordNamePtr);
  794.     
  795.     if (IsNewPrefRecord) {
  796.         UseResFile(TelInfo->SettingsFile);
  797.         resourceID = UniqueID(TERMINALPREFS_RESTYPE);
  798.         AddResource((Handle)TermPrefsHdl, TERMINALPREFS_RESTYPE, resourceID, PrefRecordNamePtr);
  799.         UpdateResFile(TelInfo->SettingsFile);
  800.         ReleaseResource((Handle)TermPrefsHdl);
  801.         }
  802.     else {
  803.         UseResFile(TelInfo->SettingsFile);
  804.         GetResInfo((Handle)TermPrefsHdl, &resourceID, &scratchResType,(StringPtr) &scratchPstring);
  805.         SetResInfo((Handle)TermPrefsHdl, resourceID, PrefRecordNamePtr);
  806.         ChangedResource((Handle)TermPrefsHdl);
  807.         UpdateResFile(TelInfo->SettingsFile);
  808.         ReleaseResource((Handle)TermPrefsHdl);
  809.         }
  810.     
  811.     DisposeDialog(dptr);
  812.     return(TRUE);            // A resource has changed or been added.    
  813. }
  814.  
  815. Boolean EditSession(StringPtr PrefRecordNamePtr)
  816. {
  817.     DialogPtr        dptr;
  818.     short            ditem, scratchshort, resourceID;
  819.     long            scratchlong;
  820.     ResType            scratchResType;
  821.     Boolean            IsNewPrefRecord;
  822.     SessionPrefs**    SessPrefsHdl;
  823.     SessionPrefs*    SessPrefsPtr;
  824.     Str255            scratchPstring, scratchPstring2;
  825.     popup SPopup[] = {{SessTermPopup, (MenuHandle) 0, 1},
  826.                         {SessTransTablePopup, (MenuHandle) 0, 1},
  827.                         {0, (MenuHandle) 0, 0}};
  828.  
  829.     dptr = GetNewMySmallStrangeDialog(SessionConfigDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  830.     ditem = 3;
  831.         
  832.     SPopup[0].h = NewMenu(666, "\p");
  833.     UseResFile(TelInfo->SettingsFile);
  834.     AddResMenu(SPopup[0].h, TERMINALPREFS_RESTYPE);
  835.     EnableItem(SPopup[0].h, 0);        // Make sure the entire menu is enabled
  836.     
  837.     SPopup[1].h = NewMenu(667, "\p");
  838.     AppendMenu(SPopup[1].h, "\pNone");
  839.     AddResMenu(SPopup[1].h, USER_TRSL);
  840.     EnableItem(SPopup[1].h, 0);        // Make sure the entire menu is enabled
  841.  
  842.     PopupInit(dptr, SPopup);
  843.     
  844.     if (PrefRecordNamePtr[0] != 0) {
  845.         IsNewPrefRecord = FALSE;
  846.         UseResFile(TelInfo->SettingsFile);
  847.         SessPrefsHdl = (SessionPrefs **)Get1NamedResource(SESSIONPREFS_RESTYPE, PrefRecordNamePtr);
  848.         if (EqualString(PrefRecordNamePtr, "\p<Default>", FALSE, FALSE)) {
  849.             HideDItem(dptr, SessAlias);
  850.             HideDItem(dptr, SessAliasStatText);
  851.             }
  852.         }
  853.     else {
  854.         SessPrefsHdl = GetDefaultSession();
  855.         IsNewPrefRecord = TRUE;
  856.         GetIndString(PrefRecordNamePtr, MISC_STRINGS, MISC_NEWSESSION);
  857.         }
  858.         
  859.     HLock((Handle) SessPrefsHdl);
  860.     SessPrefsPtr = *SessPrefsHdl;
  861.     SetCntrl(dptr, SessTEKinhib, (SessPrefsPtr->tektype == -1));
  862.     SetCntrl(dptr, SessTEK4014, (SessPrefsPtr->tektype == 0));
  863.     SetCntrl(dptr, SessTEK4105, (SessPrefsPtr->tektype == 1));
  864.     SetCntrl(dptr, SessPasteQuick, (SessPrefsPtr->pastemethod == 0));
  865.     SetCntrl(dptr, SessPasteBlock, (SessPrefsPtr->pastemethod == 1));
  866.     SetCntrl(dptr, SessDeleteDel, (SessPrefsPtr->bksp == 1));
  867.     SetCntrl(dptr, SessDeleteBS, (SessPrefsPtr->bksp == 0));
  868.     SetCntrl(dptr, SessForceSave, SessPrefsPtr->forcesave);
  869.     SetCntrl(dptr, SessBezerkeley, SessPrefsPtr->crmap);
  870.     SetCntrl(dptr, SessLinemode, SessPrefsPtr->linemode);
  871.     SetCntrl(dptr, SessTEKclear, SessPrefsPtr->tekclear);
  872.     SetCntrl(dptr, SessHalfDuplex, SessPrefsPtr->halfdup);
  873.     SetCntrl(dptr, SessLowLevelErrs, SessPrefsPtr->showlowlevelerrors);
  874.     SetCntrl(dptr, SessAuthenticate, SessPrefsPtr->authenticate);
  875.     SetCntrl(dptr, SessEncrypt, SessPrefsPtr->encrypt);
  876.     SetCntrl(dptr, SessLocalEcho, SessPrefsPtr->localecho);
  877.     SetTEText(dptr, SessHostName, SessPrefsPtr->hostname);
  878.     SetTEText(dptr, SessAlias, PrefRecordNamePtr);
  879.     NumToString(SessPrefsPtr->port, scratchPstring);
  880.     SetTEText(dptr, SessPort, scratchPstring);
  881.     NumToString(SessPrefsPtr->pasteblocksize, scratchPstring);
  882.     SetTEText(dptr, SessBlockSize, scratchPstring);
  883.     
  884.     if (SessPrefsPtr->NetBlockSize <= 512)
  885.         SessPrefsPtr->NetBlockSize = 512;
  886.     NumToString(SessPrefsPtr->NetBlockSize, scratchPstring);
  887.     SetTEText(dptr, SessBlockSizeTE, scratchPstring);
  888.     
  889.     scratchPstring[0] = 2;
  890.     scratchPstring[1] = '^';
  891.     if (SessPrefsPtr->ckey != -1) {
  892.         scratchPstring[2] = SessPrefsPtr->ckey ^ 64;
  893.         SetTEText(dptr, SessInterrupt, scratchPstring);
  894.         }
  895.     if (SessPrefsPtr->skey != -1) {
  896.         scratchPstring[2] = SessPrefsPtr->skey ^ 64;
  897.         SetTEText(dptr, SessSuspend, scratchPstring);
  898.         }
  899.     if (SessPrefsPtr->qkey != -1) {
  900.         scratchPstring[2] = SessPrefsPtr->qkey ^ 64;
  901.         SetTEText(dptr, SessResume, scratchPstring);
  902.         }
  903.     for(scratchshort = CountMItems(SPopup[0].h); scratchshort; scratchshort--) {
  904.         GetItem(SPopup[0].h, scratchshort, scratchPstring);
  905.         if (EqualString(scratchPstring, (SessPrefsPtr->TerminalEmulation), TRUE, FALSE))
  906.             SPopup[0].choice = scratchshort;
  907.         }
  908.     for(scratchshort = CountMItems(SPopup[1].h); scratchshort; scratchshort--) {
  909.         GetItem(SPopup[1].h, scratchshort, scratchPstring);
  910.         if (EqualString(scratchPstring, (SessPrefsPtr->TranslationTable), TRUE, FALSE))
  911.             SPopup[1].choice = scratchshort;
  912.         }
  913.     
  914.     NumberOfColorBoxes = 0;
  915.     ZeroNumOnly();
  916.     NumOnly[0] = SessSafeItem;
  917.     NumOnly[1] = SessPort;  NumOnly[2] = SessBlockSize;
  918.     
  919.     SelIText(dptr, SessAlias, 0, 32767);
  920.     ShowWindow(dptr);
  921.     
  922.     while (ditem > 2) {
  923.         ModalDialog(SessionModalProcUPP, &ditem);
  924.         switch (ditem) {
  925.             case    SessForceSave:
  926.             case    SessBezerkeley:
  927.             case    SessLinemode:
  928.             case    SessTEKclear:
  929.             case    SessHalfDuplex:
  930.             case    SessLowLevelErrs:
  931.             case    SessAuthenticate:
  932.             case    SessEncrypt:
  933.             case    SessLocalEcho:
  934.                 FlipCheckBox(dptr, ditem);
  935.                 break;
  936.             
  937.             case    SessTEKinhib:
  938.                 SetCntrl(dptr, SessTEKinhib, 1);
  939.                 SetCntrl(dptr, SessTEK4014, 0);
  940.                 SetCntrl(dptr, SessTEK4105, 0);
  941.                 break;
  942.             case    SessTEK4014:
  943.                 SetCntrl(dptr, SessTEKinhib, 0);
  944.                 SetCntrl(dptr, SessTEK4014, 1);
  945.                 SetCntrl(dptr, SessTEK4105, 0);
  946.                 break;
  947.             case    SessTEK4105:
  948.                 SetCntrl(dptr, SessTEKinhib, 0);
  949.                 SetCntrl(dptr, SessTEK4014, 0);
  950.                 SetCntrl(dptr, SessTEK4105, 1);
  951.                 break;
  952.                 
  953.             case    SessPasteQuick:
  954.                 SetCntrl(dptr, SessPasteQuick, 1);
  955.                 SetCntrl(dptr, SessPasteBlock, 0);
  956.                 break;
  957.  
  958.             case    SessPasteBlock:
  959.                 SetCntrl(dptr, SessPasteQuick, 0);
  960.                 SetCntrl(dptr, SessPasteBlock, 1);
  961.                 break;
  962.  
  963.             case    SessDeleteDel:
  964.                 SetCntrl(dptr, SessDeleteDel, 1);
  965.                 SetCntrl(dptr, SessDeleteBS, 0);
  966.                 break;
  967.  
  968.             case    SessDeleteBS:
  969.                 SetCntrl(dptr, SessDeleteDel, 0);
  970.                 SetCntrl(dptr, SessDeleteBS, 1);
  971.                 break;
  972.  
  973.             case    SessInterrupt:
  974.             case    SessSuspend:
  975.             case    SessResume:
  976.                 GetTEText(dptr, ditem, scratchPstring);
  977.                 if ((scratchPstring[1] < 32) && (scratchPstring[1] > 0)) {
  978.                     scratchPstring[0] = 2;
  979.                     scratchPstring[2] = scratchPstring[1] ^ 64;
  980.                     scratchPstring[1] = '^';
  981.                     SetTEText(dptr, ditem, scratchPstring);
  982.                     }
  983.                 break;
  984.             default:
  985.                 break;
  986.             
  987.             } // switch
  988.         } // while
  989.         
  990.     GetItem(SPopup[0].h, SPopup[0].choice, scratchPstring);
  991.     GetItem(SPopup[1].h, SPopup[1].choice, scratchPstring2);
  992.     PopupCleanup();
  993.  
  994.     if (ditem == 2) {
  995.         if (IsNewPrefRecord) DisposeHandle((Handle) SessPrefsHdl);
  996.         else ReleaseResource((Handle) SessPrefsHdl);
  997.         
  998.         DisposeDialog(dptr);
  999.         return(FALSE);            // No changes should be made.
  1000.         }
  1001.         
  1002.     if (Length(scratchPstring) > 63) scratchPstring[0] = 63;
  1003.     BlockMove(scratchPstring, (SessPrefsPtr->TerminalEmulation), scratchPstring[0]+1);
  1004.  
  1005.     if (Length(scratchPstring2) > 63) scratchPstring[0] = 63;
  1006.     BlockMove(scratchPstring2, (SessPrefsPtr->TranslationTable), scratchPstring2[0]+1);
  1007.  
  1008.     SessPrefsPtr->tektype = (-1 * GetCntlVal(dptr, SessTEKinhib)) + GetCntlVal(dptr, SessTEK4105);
  1009.     SessPrefsPtr->pastemethod = !GetCntlVal(dptr, SessPasteQuick);
  1010.     SessPrefsPtr->bksp = GetCntlVal(dptr, SessDeleteDel);
  1011.     SessPrefsPtr->forcesave = GetCntlVal(dptr, SessForceSave);
  1012.     SessPrefsPtr->crmap = GetCntlVal(dptr, SessBezerkeley);
  1013.     SessPrefsPtr->linemode = GetCntlVal(dptr, SessLinemode);
  1014.     SessPrefsPtr->tekclear = GetCntlVal(dptr, SessTEKclear);
  1015.     SessPrefsPtr->halfdup = GetCntlVal(dptr, SessHalfDuplex);
  1016.     SessPrefsPtr->showlowlevelerrors = GetCntlVal(dptr, SessLowLevelErrs);
  1017.     SessPrefsPtr->authenticate = GetCntlVal(dptr, SessAuthenticate);
  1018.     SessPrefsPtr->encrypt = GetCntlVal(dptr, SessEncrypt);
  1019.     SessPrefsPtr->localecho = GetCntlVal(dptr, SessLocalEcho);
  1020.  
  1021.     GetTEText(dptr, SessPort, scratchPstring);
  1022.     StringToNum(scratchPstring, &scratchlong);
  1023.     BoundsCheck(&scratchlong, 65530, 1);
  1024.     SessPrefsPtr->port = (short) scratchlong;
  1025.  
  1026.     GetTEText(dptr, SessBlockSize, scratchPstring);
  1027.     StringToNum(scratchPstring, &scratchlong);
  1028.     BoundsCheck(&scratchlong, 4097, 100);
  1029.     SessPrefsPtr->pasteblocksize = (short) scratchlong;
  1030.  
  1031.     GetTEText(dptr, SessHostName, scratchPstring);
  1032.     if (Length(scratchPstring) > 63) scratchPstring[0] = 63;
  1033.     BlockMove(scratchPstring, SessPrefsPtr->hostname, scratchPstring[0]+1);
  1034.     
  1035.     GetTEText(dptr, SessHostName, scratchPstring);
  1036.     if (Length(scratchPstring) > 63) scratchPstring[0] = 63;
  1037.     BlockMove(scratchPstring, SessPrefsPtr->hostname, scratchPstring[0]+1);
  1038.  
  1039.     GetTEText(dptr, SessAlias, PrefRecordNamePtr);
  1040.  
  1041.     GetTEText(dptr, SessInterrupt, scratchPstring);
  1042.     if (scratchPstring[0]) SessPrefsPtr->ckey = toupper(scratchPstring[2]) ^ 64;
  1043.     else SessPrefsPtr->ckey = -1;
  1044.     
  1045.     GetTEText(dptr, SessSuspend, scratchPstring);
  1046.     if (scratchPstring[0]) SessPrefsPtr->skey = toupper(scratchPstring[2]) ^ 64;
  1047.     else SessPrefsPtr->skey = -1;
  1048.     
  1049.     GetTEText(dptr, SessResume, scratchPstring);
  1050.     if (scratchPstring[0]) SessPrefsPtr->qkey = toupper(scratchPstring[2]) ^ 64;
  1051.     else SessPrefsPtr->qkey = -1;
  1052.     
  1053.     GetTEText(dptr,SessBlockSizeTE,scratchPstring);
  1054.     StringToNum(scratchPstring,&scratchlong);
  1055.     BoundsCheck(&scratchlong, 4096, 512);
  1056.     SessPrefsPtr->NetBlockSize = (short) scratchlong;
  1057.  
  1058.     if (IsNewPrefRecord) {
  1059.         UseResFile(TelInfo->SettingsFile);
  1060.         resourceID = UniqueID(SESSIONPREFS_RESTYPE);
  1061.         AddResource((Handle)SessPrefsHdl, SESSIONPREFS_RESTYPE, resourceID, PrefRecordNamePtr);
  1062.         UpdateResFile(TelInfo->SettingsFile);
  1063.         ReleaseResource((Handle)SessPrefsHdl);
  1064.         }
  1065.     else {
  1066.         UseResFile(TelInfo->SettingsFile);
  1067.         GetResInfo((Handle)SessPrefsHdl, &resourceID, &scratchResType,(StringPtr) &scratchPstring);
  1068.         SetResInfo((Handle)SessPrefsHdl, resourceID, PrefRecordNamePtr);
  1069.         ChangedResource((Handle)SessPrefsHdl);
  1070.         UpdateResFile(TelInfo->SettingsFile);
  1071.         ReleaseResource((Handle)SessPrefsHdl);
  1072.         }
  1073.     
  1074.     DisposeDialog(dptr);
  1075.     return(TRUE);            // A resource has changed or been added.    
  1076. }
  1077.  
  1078. Boolean EditFTPUser(StringPtr PrefRecordNamePtr)
  1079. {
  1080.     DialogPtr    dptr;
  1081.     short        ditem, scratchshort, resourceID, vRefNum;
  1082.     ResType        scratchResType;
  1083.     Boolean        IsNewPrefRecord;
  1084.     FTPUser**    FTPUHdl;
  1085.     FTPUser*    FTPUptr;
  1086.     Str255        scratchPstring, scratchPstring2;
  1087.  
  1088.     dptr = GetNewMySmallStrangeDialog(FTPUserDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  1089.     ditem = 3;
  1090.  
  1091.     HideDItem(dptr, FTPUcanchangeCWD);        // Sometime later, perhaps
  1092.         
  1093.     if (PrefRecordNamePtr[0] != 0) {
  1094.         IsNewPrefRecord = FALSE;
  1095.         UseResFile(TelInfo->SettingsFile);
  1096.         FTPUHdl = (FTPUser **)Get1NamedResource(FTPUSER, PrefRecordNamePtr);
  1097.         HLock((Handle) FTPUHdl);
  1098.         FTPUptr = *FTPUHdl;
  1099.         SetCntrl(dptr, FTPUcanchangeCWD, FTPUptr->UserCanCWD);
  1100.         SetTEText(dptr, FTPUusername, PrefRecordNamePtr);
  1101.         for (scratchshort = 8, scratchPstring[0] = 8; scratchshort > 0; scratchshort--)
  1102.             scratchPstring[scratchshort] = 'Ñ';
  1103.          SetTEText(dptr, FTPUpassword, scratchPstring);
  1104.         vRefNum = VolumeNameToRefNum(FTPUptr->DefaultDirVolName);
  1105.         }
  1106.     else {
  1107.         IsNewPrefRecord = TRUE;
  1108.         FTPUHdl = (FTPUser **)NewHandleClear(sizeof(FTPUser));
  1109.         HLock((Handle) FTPUHdl);
  1110.         FTPUptr = *FTPUHdl;
  1111.         vRefNum = -1;                        // Default Volume
  1112.         FTPUptr->DefaultDirDirID = 2;        // Root directory
  1113.         SetCntrl(dptr, FTPUcanchangeCWD, 0);
  1114.         }
  1115.  
  1116.     PathNameFromDirID(FTPUptr->DefaultDirDirID, vRefNum, scratchPstring);
  1117.     SetTEText(dptr, FTPUDfltDirDsply, scratchPstring);
  1118.     
  1119.     SelIText(dptr, FTPUusername, 0, 32767);
  1120.     ShowWindow(dptr);
  1121.     
  1122.     while (ditem > 2) {
  1123.         ModalDialog(DLOGwOK_CancelUPP, &ditem);
  1124.         switch (ditem) {
  1125.             case    FTPUcanchangeCWD:
  1126.                 FlipCheckBox(dptr, ditem);
  1127.                 break;
  1128.             
  1129.             case    FTPUDfltDirButton:
  1130.                 SelectDirectory(&vRefNum, &(FTPUptr->DefaultDirDirID));
  1131.                 PathNameFromDirID(FTPUptr->DefaultDirDirID, vRefNum, scratchPstring);
  1132.                 SetTEText(dptr, FTPUDfltDirDsply, scratchPstring);
  1133.                 break;
  1134.                 
  1135.             default:
  1136.                 break;
  1137.             
  1138.             } // switch
  1139.         } // while
  1140.         
  1141.     if (ditem == 2) {
  1142.         if (IsNewPrefRecord) DisposeHandle((Handle) FTPUHdl);
  1143.         else ReleaseResource((Handle) FTPUHdl);
  1144.         
  1145.         DisposeDialog(dptr);
  1146.         return(FALSE);            // No changes should be made.
  1147.         }
  1148.         
  1149.     FTPUptr->UserCanCWD = GetCntlVal(dptr, FTPUcanchangeCWD);
  1150.     GetDirectoryName(vRefNum, 2, FTPUptr->DefaultDirVolName);
  1151.     
  1152.     GetTEText(dptr, FTPUusername, PrefRecordNamePtr);
  1153.     GetTEText(dptr, FTPUpassword, scratchPstring);
  1154.     
  1155.     if (scratchPstring[0] != 'Ñ') {
  1156.         // Encrypt the new (or possibly modified) password.
  1157.         PtoCstr(scratchPstring);
  1158.         Sencompass((char *)scratchPstring, (char *)scratchPstring2);
  1159.         CtoPstr((char *)scratchPstring2);
  1160.         BlockMove(scratchPstring2, FTPUptr->EncryptedPassword, Length(scratchPstring2)+1);
  1161.         }
  1162.             
  1163.     if (IsNewPrefRecord) {
  1164.         UseResFile(TelInfo->SettingsFile);
  1165.         resourceID = UniqueID(FTPUSER);
  1166.         AddResource((Handle)FTPUHdl, FTPUSER, resourceID, PrefRecordNamePtr);
  1167.         UpdateResFile(TelInfo->SettingsFile);
  1168.         ReleaseResource((Handle)FTPUHdl);
  1169.         }
  1170.     else {
  1171.         UseResFile(TelInfo->SettingsFile);
  1172.         GetResInfo((Handle)FTPUHdl, &resourceID, &scratchResType,(StringPtr) &scratchPstring);
  1173.         SetResInfo((Handle)FTPUHdl, resourceID, PrefRecordNamePtr);
  1174.         ChangedResource((Handle)FTPUHdl);
  1175.         UpdateResFile(TelInfo->SettingsFile);
  1176.         ReleaseResource((Handle)FTPUHdl);
  1177.         }
  1178.     
  1179.     DisposeDialog(dptr);
  1180.     return(TRUE);            // A resource has changed or been added.    
  1181. }
  1182.