/* $Id: ckmsav.c,v 1.7 91/12/15 23:17:50 rick Exp $ * $Source: /uw/mackermit/RCS/ckmsav.c,v $ *------------------------------------------------------------------ * $Log: ckmsav.c,v $ * Revision 1.7 91/12/15 23:17:50 rick * ut9 * * Revision 1.6 91/10/13 13:43:36 rick * UT(7) * * Revision 1.5 91/10/01 12:16:56 rick * UT(5) * * Revision 1.4 91/09/25 12:17:32 rick * Command window in TE. Multiple vt100 windows for command window. * * Revision 1.3 91/09/12 21:50:51 rick * UT(3). Install on watsun * * Revision 1.2 1991/09/10 22:21:47 rick * Update to UTexas(2) * * Revision 1.1 1991/09/10 19:18:03 rick * Initial revision * *------------------------------------------------------------------ * $Endlog$ */ /* Paul Placeway, Ohio State -- changed the format of saved Is and Cs to */ /* {number, item, item, ...} */ /* Version 0.8(35) - Jim Noble at Planning Research Corporation, June 1987. */ /* Ported to Megamax native Macintosh C compiler. */ /* Edit by Frank on Jun 20 17:20 */ /* Don't set sio chip parity */ /* Edit by Bill on May 29 01:01 */ /* Add key configurator */ /* Edit by Bill on May 10 9:24 */ /* Saving settings file to a different disk doesn't work and may bomb */ /* Edit by Bill on May 8 7:17 */ /* Save default file settings, now incompatable with existing save files! */ /* Edit by Bill & Jeff on May 1 14:16 */ /* findfinderfiles was bombing because of fName[1] definition of myAppFile */ /* Edit by Bill on Apr 30 05:50 */ /* Call FlushVol after saving the settings */ /* * file ckmsav.c * * Module of MacKermit containing code for saving and restoring * various variables. * Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New York. Permission is granted to any individual or institution to use this software as long as it is not sold for profit. This copyright notice must be retained. This software may not be included in commercial products without written permission of Columbia University. * */ #include "ckcdeb.h" /* Kermit definitions */ #include "ckcker.h" /* Kermit definitions */ #include "ckmdef.h" /* Common Mac module definitions */ #include "ckmres.h" /* resource defs */ #include "ckmcon.h" #include "ckmptp.h" /* ckm* Prototypes */ /* * These are referenced externally */ OSType kermtype = ApplCreator, settingstype = 'KERS'; OSType texttype = 'TEXT'; OSType loadlist[] = {'KERS','TEXT'}; /* * Intermediate place holders for per-window values */ static int scr_invert; /* intermediate container for screeninvert */ static int scr_size; /* ditto for size */ static int scr_postop; /* screen position of terminal window -- top edge */ static int scr_poslft; /* ditto for left edge */ static int scr_fntsz; /* screen font size */ static int scr_newline; static int scr_autowrap; static int scr_autorepeat; static int scr_smoothscroll; static int scr_dispcontchar; static int scr_blockcursor; static int scr_mouse_arrows; static int scr_visible_bell; static int scr_eightbit_disp; static int scr_blinkcursor; static int savinnum; /* intermediate container for innum (I/O port) */ static char savmcmdactive; /* intermediate container for mcmdactive */ extern int drop_dtr; extern char *dftty; /* Default serial port */ extern int dfprty; /* Default parity */ extern int dfflow; /* Default flow control */ extern int fDTR, fCTS; /* * Some things have been moved to the ttermw struct. Keep * placeholders for them and fixup later. */ volatile int *inames[] = { &speed, &parity, &duplex, &delay, &mypadn, &npad, &timint, &rtimo, &urpsiz, &spsiz, &turnch, &turn, &bctr, &filargs.fildflg, &scr_newline, /* 14 termw->newline */ &scr_autowrap, /* 15 termw->autowrap */ &scr_invert, &scr_autorepeat, /* 17 termw->autorepeat */ &scr_smoothscroll, /* 18 termw->smoothscroll */ &scr_dispcontchar, /* 19 termw->dispcontchar */ &keep, /* Keep incomplete files */ &scr_blockcursor, /* 21 termw->blockcursor */ &scr_mouse_arrows, /* 22 termw->mouse_arrows */ &scr_visible_bell, /* 23 termw->visible_bell */ &scr_eightbit_disp, /* 24 termw->eightbit_disp */ &scr_blinkcursor, /* 25 termw->blinkcursor */ &scr_size, &savinnum, &sendusercvdef, &drop_dtr, &flow, &scr_postop, &scr_poslft, &scr_fntsz, &wslotr, &fDTR, &fCTS }; #define NINAMES (sizeof(inames) / sizeof(long *)) char *cnames[] = { &mypadc, &padch, &eol, &seol, &stchr, &mystch, (char *) &fkeysactive, (char *) &savmcmdactive }; #define NCNAMES (sizeof(cnames) / sizeof(char *)) typedef long **IHandle; /* handle to long[] */ typedef char **CHandle; /* handle to char[] */ struct lfile *lfiles = NULL; /* list of launched take files */ /****************************************************************************/ /* Delete the specified resource if it exists in the current resource file */ /****************************************************************************/ void KillResource (ResType type, int id) { Handle theRsrc; theRsrc = GetResource (type, id); if ((theRsrc != NIL) && (HomeResFile (theRsrc) == CurResFile ())) { RmveResource (theRsrc); if (ResError () != noErr) { /* check for error */ printerr ("Could not remove old resource: ", ResError ()); return; } DisposHandle (theRsrc); } } /* KillResource */ /****************************************************************************/ /* savevals - save variables for MacKermit */ /****************************************************************************/ void savevals() { volatile IHandle ihdl; volatile CHandle chdl, shdl; SFReply savr; Point where; int err, cerr; int rfnum; int i; FInfo finf; Str255 name; struct termw *termw; termw = ttermw; GetWTitle (termw->window, name); SetPt (&where, 75, 115); SFPutFile (where, "\pSave variables in file:", name, (DlgHookProcPtr) NILPROC, &savr); if (!savr.good) /* did they hit cancel? */ return; /* yes, so return now */ SetVol (NILPTR, savr.vRefNum); /* select volume for rsrc file */ rfnum = OpenResFile (&savr.fName); err = ResError (); if (err == noErr) { /* file exists, clear old resources */ /* Be sure to delete the old resources, if they alraedy */ /* exist. Otherwise the resources will be added to the */ /* existing file (adding more and more resources with */ /* the same type and number). Unfortunately, for setting */ /* the parameters, Kermit always uses the first, i.e. */ /* the !oldest! set of resources! */ KillResource (SAVI_TYPE, SIVER); KillResource (SAVC_TYPE, SCVER); KillResource (KSET_TYPE, KSVER); KillResource (MSET_TYPE, KMVER); KillResource (SAVS_TYPE, SAVS_ID_FONT); /* * Change the creator to us so that a TEXT file * will become launchable. [Are we allowed to do * this?] */ err = GetFInfo (&savr.fName, savr.vRefNum, &finf); if (err == noErr) { finf.fdCreator = kermtype; /* set creator */ err = SetFInfo (&savr.fName, savr.vRefNum, &finf); if (err != noErr) printerr ("Can't set finder info: ", err); } } else if ((err == resFNotFound) || (err == fnfErr) || (err == eofErr)) { cerr = err; /* file not existing ? */ CreateResFile (&savr.fName); /* try to create */ if (ResError () != noErr) { /* check for error */ printerr ("Unknown error from create: ", ResError ()); return; } /* set the file finder infos */ err = GetFInfo (&savr.fName, savr.vRefNum, &finf); if (err != noErr) printerr ("Can't get finder info for file: ", err); else { finf.fdFldr = filargs.filfldr; /* use same folder as * application */ if (cerr != eofErr) /* if was not data only */ finf.fdType = settingstype; /* set type */ finf.fdCreator = kermtype; /* set creator */ err = SetFInfo (&savr.fName, savr.vRefNum, &finf); if (err != noErr) printerr ("Can't set finder info: ", err); } /* try open again */ rfnum = OpenResFile (&savr.fName); if (rfnum == -1) { /* failed to open? */ printerr ("Couldn't Open resource file: ", ResError ()); return; } } else { printerr ("Couldn't Open resource file: ", err); return; } /* * Add things in ttermw manually. */ scr_invert = termw->screeninvert; /* save the current value */ scr_size = termw->screensize; scr_newline = termw->newline; scr_autowrap = termw->autowrap; scr_autorepeat = termw->autorepeat; scr_smoothscroll = termw->smoothscroll; scr_dispcontchar = termw->dispcontchar; scr_blockcursor = termw->blockcursor; scr_mouse_arrows = termw->mouse_arrows; scr_visible_bell = termw->visible_bell; scr_eightbit_disp = termw->eightbit_disp; scr_blinkcursor = termw->blinkcursor; savinnum = innum; /* save current port too */ savmcmdactive = mcmdactive; get_term_pos(termw, &scr_postop, &scr_poslft); /* in ckmco2.c */ scr_fntsz = termw->current_size; /* * PWP: changed the format so {count, item, item, ...} so that we can * load older versions without dying */ ihdl = (IHandle) NewHandle ((long) (NINAMES + 1) * sizeof (long)); if (ihdl == (IHandle) NIL) { printerr ("Could not save the int values (SAVI) (out of memory)", 0); return; } HLock((Handle) ihdl); /* play it safe with the C optimizer */ (*ihdl)[0] = NINAMES; for (i = 0; i < NINAMES; i++) /* copy from indirect table */ if (inames[i]) (*ihdl)[i + 1] = *inames[i]; /* $$$ this dies at i=18 */ /* Set the data for output AFTER DOING ALL SETTINGS!!!! */ AddResource ((Handle) ihdl, SAVI_TYPE, SIVER, ""); HUnlock((Handle) ihdl); /* we are done looking at this manually */ chdl = (CHandle) NewHandle ((long) (NCNAMES + 1) * sizeof (char)); if (chdl == (CHandle) NIL) { printerr ("Could not save the char values (SAVC) (out of memory)", 0); return; } HLock((Handle) chdl); /* play it safe with the C optimizer */ (*chdl)[0] = NCNAMES; for (i = 0; i < NCNAMES; i++) /* copy from indirect table */ (*chdl)[i + 1] = *cnames[i]; AddResource ((Handle) chdl, SAVC_TYPE, SCVER, ""); HUnlock((Handle) chdl); /* we are done looking at this manually */ savekset (); /* save key bit table */ savemset (); /* save key macros table */ /* save the screen font name */ GetFontName (termw->current_font, name); shdl = (CHandle) NewHandle ((long) (Length(name) + 1) * sizeof (char)); if (shdl == (CHandle) NIL) { printerr ("Could not save the string values (SAVS) (out of memory)", 0); return; } HLock((Handle) shdl); /* play it safe with the C optimizer */ SetString (shdl, name); AddResource ((Handle) shdl, SAVS_TYPE, SAVS_ID_FONT, "\pScreen font"); HUnlock((Handle) shdl); /* we are done looking at this manually */ CloseResFile (rfnum); /* this does an UpdateResFile too */ FlushVol (NILPTR, savr.vRefNum); /* flush the bits out */ DisposHandle((Handle) ihdl); DisposHandle((Handle) chdl); DisposHandle((Handle) shdl); SetWTitle (termw->window, &savr.fName); } /* savevals */ /****************************************************************************/ /* do a Load settings... dialog */ /****************************************************************************/ void loadvals () { int err; SFReply savr; Point where; FileParam pb; SetPt (&where, 75, 115); SFGetFile (where, "\pLoad variables from:", (FileFilterProcPtr) NILPROC, 2, &loadlist, (DlgHookProcPtr) NILPROC, &savr); if (!savr.good) /* did they hit cancel? */ return; /* yes, so return now */ /* * Due to the mstr# resource, we can be called by multifinder * with any file that has a KR09 creator. Files of type * TEXT probably contain scripts. File types of KERS are * Kermit settings resouces. A TEXT file may also contain * settings resources. Figure out which we have and * try to do the appropriate thing. */ pb.ioNamePtr = savr.fName; pb.ioVRefNum = savr.vRefNum; pb.ioFVersNum = pb.ioFDirIndex = 0; err = PBGetFInfo((ParmBlkPtr)&pb, FALSE); /* p2cstr (&savr.fName); */ if (err != noErr) { printfalert("Could not PBGetFInfo for %s", p2c_tmp(savr.fName)); return; } if (pb.ioFlRLgLen) /* if resources present */ doloadvals(p2c_tmp(savr.fName), savr.vRefNum); /* do the load */ if (pb.ioFlLgLen) { /* if data present */ kShowWindow(ctermw); kSelectWindow(ctermw->window); /* queue the take file */ getlfile((char *) p2c_tmp(savr.fName), savr.vRefNum); } } /* loadvals */ /* * takedialog * Do a Take Command File... dialog */ void takedialog () { SFReply savr; Point where; SetPt (&where, 75, 115); SFGetFile (where, "\pCommand File:", (FileFilterProcPtr) NILPROC, 1, &texttype, (DlgHookProcPtr) NILPROC, &savr); if (!savr.good) /* did they hit cancel? */ return; /* yes, so return now */ /* force command window */ kShowWindow(ctermw); kSelectWindow(ctermw->window); /* queue the take file */ p2cstr(&savr.fName); /* $$$ */ getlfile((char *) savr.fName, savr.vRefNum); } /* takedialog */ /****************************************************************************/ /****************************************************************************/ void findfinderfiles () { short msg, cnt; int err, rfnum; AppFile apf; FInfo ainfo; Str255 defvolname; FileParam pb; short defvolrefnum; int i; Boolean first; extern Boolean have_128roms; extern int startconnected; startconnected = TRUE; CountAppFiles (&msg, &cnt); /* anything clicked by user? */ if (cnt == 0 || msg == appPrint) { /* or they want us to print (?) */ /* filargs.filfldr = fDesktop; */ /* forget about loading values */ if (GetVol(&defvolname, &defvolrefnum) == noErr) filargs.filfldr = defvolrefnum; else filargs.filfldr = 0; loadkset (); /* make new files appear on desk */ return; /* use our default KSET */ } /* * Loop through all the applications files. If the data length * is nonzero, assume this is a take file and put it on our * list. Load resources from the first (only) file that has * Kermit resources. */ first = TRUE; for (i = 1; i <= cnt; i++) { GetAppFiles(i, &apf); err = GetFInfo (&apf.fName, /* get settings file info */ apf.vRefNum, &ainfo); if (err != noErr) { printerr ("Couldn't GetFInfo for an applications file: ", err); continue; } pb.ioNamePtr = apf.fName; /* WAS: pb.ioNamePtr = &apf.fName; */ pb.ioVRefNum = apf.vRefNum; pb.ioFVersNum = pb.ioFDirIndex = 0; err = PBGetFInfo((ParmBlkPtr)&pb, FALSE); if (err != noErr) { printerr("Couldn't PBGetFInfo for a file", err); continue; } /* * Load settings resources out of the first file we find * that has Kermit resources in it. */ if (first && (pb.ioFlRLgLen > 0)) { /* * Check to see that Kermit resources are present. Otherwise, * we might have a text file with some kind of edit resources. */ SetVol (NILPTR, apf.vRefNum); /* select volume */ rfnum = OpenResFile(apf.fName); /* open the resource file */ if (rfnum == -1) /* DEBUG!!!!!!!!!! */ printfalert("Couldn't OpenResFile: ", ResError ()); /* * If no 128k roms, just assme we found Kermit resources. */ if (!have_128roms || ((rfnum != -1) && (Count1Resources(SAVI_TYPE) > 0))) { first = FALSE; p2cstr (&apf.fName); doloadvals((char *) &apf.fName, apf.vRefNum); /* load the file */ c2pstr (&apf.fName); /* use appl or text file's folder */ filargs.filfldr = ainfo.fdFldr; } if (rfnum != -1) CloseResFile(rfnum); } /* * If there is data and the file is type TEXT assume this * is a take file for us. */ if ((pb.ioFlLgLen > 0) && (ainfo.fdType == 'TEXT')) { startconnected = FALSE; /* so we will take files */ p2cstr (apf.fName); getlfile((char *) apf.fName, apf.vRefNum); c2pstr (&apf.fName); } } } /* findfinderfiles */ /* * getlfile * Build an lfile entry and put it on the queue. */ void getlfile (char *name, short vref) { struct lfile *lfile, *lastlfile = NULL; lfile = (struct lfile *) malloc(sizeof(struct lfile)); bzero((char *)lfile, sizeof(struct lfile)); lfile->name = (char *)malloc(strlen(name)); if (!lfile->name) { printerr("Not enough memory for applications files", 0); return; } strcpy(lfile->name, name); lfile->vRefNum = vref; /* link on the list */ if (lastlfile) lastlfile->next = lfile; else lfiles = lfile; lastlfile = lfile; } /* * startlfile * Start up a mac take file the finder gave us. */ void startlfile () { struct lfile *lfile; if (!(lfile = lfiles)) return; lfiles = lfile->next; /* delink from list */ SetVol(NILPTR, lfile->vRefNum); /* make sure volume is correct */ /* Should we save current loc? */ dotake(lfile->name); /* release memory held by queue entry */ free(lfile->name); free(lfile); } extern MenuHandle menus[]; /* handle on our menus */ /****************************************************************************/ /****************************************************************************/ void doloadvals(char *fn, int refnum) { int rfnum; int i, n; volatile IHandle resinames; volatile CHandle rescnames, resstrs; short fntnum; struct termw *termw; termw = ttermw; /* * Set the place-holder vars to their current values so an update * of an older kermit save doesn't do wierd things to them */ scr_invert = termw->screeninvert; /* save the current value */ scr_size = termw->screensize; scr_newline = termw->newline; scr_autowrap = termw->autowrap; scr_autorepeat = termw->autorepeat; scr_smoothscroll = termw->smoothscroll; scr_dispcontchar = termw->dispcontchar; scr_blockcursor = termw->blockcursor; scr_mouse_arrows = termw->mouse_arrows; scr_visible_bell = termw->visible_bell; scr_eightbit_disp = termw->eightbit_disp; scr_blinkcursor = termw->blinkcursor; savinnum = innum; /* save current port too */ savmcmdactive = mcmdactive; get_term_pos(termw, &scr_postop, &scr_poslft); /* in ckmco2.c */ scr_fntsz = termw->current_size; SetVol (NILPTR, refnum); /* select volume */ rfnum = OpenResFile (c2p_tmp(fn)); /* open the resource file */ if (rfnum == -1) { printerr ("Couldn't open file: ", ResError ()); return; }; /* load 'SAVI' resource, the saved integer values, */ /* 'SAVC' saved characters */ if ((resinames = (IHandle) GetResource (SAVI_TYPE, SIVER)) == NIL || (rescnames = (CHandle) GetResource (SAVC_TYPE, SCVER)) == NIL) { CloseResFile (rfnum); printerr ("Can't load your settings, damaged file or wrong version.", 0); return; /* and return */ } cursor_erase (termw); /* hide the current cursor */ /* * PWP: changed the format to {count, item, item, ...} so that we can * load older versions without dieing */ HLock((Handle) resinames); n = (*resinames)[0]; if (n > NINAMES) n = NINAMES; for (i = 0; i < n; i++) if (inames[i]) *inames[i] = (*resinames)[i + 1]; HUnlock((Handle) resinames); ReleaseResource((Handle) resinames); HLock(rescnames); n = (*rescnames)[0]; if (n > NCNAMES) n = NCNAMES; for (i = 0; i < n; i++) *cnames[i] = (*rescnames)[i + 1]; HUnlock(rescnames); ReleaseResource(rescnames); /* restore the screen font name */ fntnum = 0; if ((resstrs = (CHandle) GetResource (SAVS_TYPE, SAVS_ID_FONT)) != NIL) { HLock(resstrs); GetFNum(*resstrs, &fntnum); if (fntnum != 0) termw->current_font = fntnum; HUnlock(resstrs); ReleaseResource(resstrs); } loadkset (); /* load new KSET */ loadmset (); /* release current MSET and load new one */ CloseResFile (rfnum); /* no longer needed */ set_term_pos(termw, scr_postop, scr_poslft); /* in ckmco2.c */ /* * Restore things in termw manually. */ termw->current_size = scr_fntsz; /* change font size */ termw->newline = scr_newline; termw->autowrap = scr_autowrap; termw->autorepeat = scr_autorepeat; termw->smoothscroll = scr_smoothscroll; termw->dispcontchar = scr_dispcontchar; termw->blockcursor = scr_blockcursor; termw->mouse_arrows = scr_mouse_arrows; termw->visible_bell = scr_visible_bell; termw->eightbit_disp = scr_eightbit_disp; termw->blinkcursor = scr_blinkcursor; /* we (may have) changed the font above */ term_new_font(termw); /* update what font to use, font constants */ setup_font_menu(); /* update font and sizes */ grow_term_to(termw, scr_size); /* change screen size */ if (scr_invert != termw->screeninvert) invert_term (termw); cursor_draw(termw); /* show the new cursor */ if ((savinnum != -6) && (savinnum != -8)) savinnum = -6; /* make sure savinnum is a legal port no */ if (savinnum != innum) { /* if using the other port */ int saved_drop_dtr; saved_drop_dtr = drop_dtr; drop_dtr = 1; /* so we don't confuse AppleTalk */ port_close(); drop_dtr = saved_drop_dtr; port_open(savinnum); } /* tell serial driver about new vals */ if (!setserial (innum, outnum, speed, KPARITY_NONE)) printfalert("Problem setting port speed"); (void) sershake(flow); /* Frank changed main() to call init and then set flow, parity, etc. so we make sure they will be set right (again) after we return. */ dfprty = parity; /* Set initial parity, */ dfflow = flow; /* and flow control. */ if (innum == -8) /* Also must set default serial port */ dftty = "Printer"; else dftty = "Modem"; /* set the two check menus */ enable_fkeys (fkeysactive); CheckItem (menus[SETG_MENU], SCRD_SETG, (fkeysactive)); if (savmcmdactive != mcmdactive) { mcmdactive = savmcmdactive; setup_menus(); } CheckItem (menus[SETG_MENU], MCDM_SETG, (mcmdactive)); SetWTitle (termw->window, c2p_tmp(fn)); /* (PWP) bounds check the values we just got to be double extra safe */ if (urpsiz > MAXRP-8) { printerr("Recieve packet lengh is too big", urpsiz); urpsiz = MAXRP-8; } if (spsiz > MAXSP) { printerr("Send packet length is too big", spsiz); spsiz = MAXSP; } if (wslotr < 1) wslotr = 1; if (wslotr > 1) swcapr = 1; else swcapr = 0; } /* doloadvals */ /* * Junk so Emacs will set local variables to be compatible with Mac/MPW. * Should be at end of file. * This module uses 8 * * Local Variables: * tab-width: 8 * End: */