/* $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 */ OSType kermtype = ApplCreator, settingstype = 'KERS'; OSType texttype = 'TEXT'; OSType loadlist[] = {'KERS','TEXT'}; int scrinvert; /* intermediate container for screeninvert */ int scrsize; /* ditto for size */ int scrpostop; /* screen position of terminal window -- top edge */ int scrposlft; /* ditto for left edge */ int scrfntsz; /* screen font size */ int savinnum; /* intermediate container for innum (I/O port) */ char savmcmdactive; /* intermediate container for mcmdactive */ extern int drop_dtr; 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. */ int *inames[] = { &speed, &parity, &duplex, &delay, &mypadn, &npad, &timint, &rtimo, &urpsiz, &spsiz, &turnch, &turn, &bctr, &filargs.fildflg, NULL, /* 14 termw->newline */ NULL, /* 15 termw->autowrap */ &scrinvert, NULL, /* 17 termw->autorepeat */ NULL, /* 18 termw->smoothscroll */ NULL, /* 19 termw->dispcontchar */ &keep, NULL, /* 21 termw->blockcursor */ NULL, /* 22 termw->mouse_arrows */ NULL, /* 23 termw->visible_bell */ NULL, /* 24 termw->eightbit_disp */ NULL, /* 25 termw->blinkcursor */ &scrsize, &savinnum, &sendusercvdef, &drop_dtr, &flow, &scrpostop, &scrposlft, &scrfntsz, &wslotr, &fDTR, &fCTS }; #define NINAMES (sizeof(inames) / sizeof(int *)) char *cnames[] = { &mypadc, &padch, &eol, &seol, &stchr, &mystch, &fkeysactive, &savmcmdactive }; #define NCNAMES (sizeof(cnames) / sizeof(char *)) typedef long **IHandle; /* handle to int[] */ 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 */ /****************************************************************************/ KillResource (type, id) 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 */ /****************************************************************************/ savevals() { IHandle ihdl; 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 */ /* p2cstr (&savr.fName); */ 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; } scrinvert = termw->screeninvert; /* save the current value */ scrsize = termw->screensize; savinnum = innum; /* save current port too */ savmcmdactive = mcmdactive; get_term_pos(termw, &scrpostop, &scrposlft); /* in ckmco2.c */ scrfntsz = 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 (int)); (*ihdl)[0] = NINAMES; for (i = 0; i < NINAMES; i++) /* copy from indirect table */ if (inames[i]) (*ihdl)[i + 1] = *inames[i]; AddResource ((Handle) ihdl, SAVI_TYPE, SIVER, ""); /* * Add things in ttermw manually. */ (*ihdl)[14 + 1] = termw->newline; (*ihdl)[15 + 1] = termw->autowrap; (*ihdl)[17 + 1] = termw->autorepeat; (*ihdl)[18 + 1] = termw->smoothscroll; (*ihdl)[19 + 1] = termw->dispcontchar; (*ihdl)[21 + 1] = termw->blockcursor; (*ihdl)[22 + 1] = termw->mouse_arrows; (*ihdl)[23 + 1] = termw->visible_bell; (*ihdl)[24 + 1] = termw->eightbit_disp; (*ihdl)[25 + 1] = termw->blinkcursor; chdl = (CHandle) NewHandle ((long) (NCNAMES + 1) * sizeof (char)); (*chdl)[0] = NCNAMES; for (i = 0; i < NCNAMES; i++) /* copy from indirect table */ (*chdl)[i + 1] = *cnames[i]; AddResource ((Handle) chdl, SAVC_TYPE, SCVER, ""); 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)); SetString (shdl, name); AddResource ((Handle) shdl, SAVS_TYPE, SAVS_ID_FONT, "\pScreen font"); 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 */ /****************************************************************************/ 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", savr.fName); return; } if (pb.ioFlRLgLen) /* if resources present */ doloadvals(&savr.fName, savr.vRefNum); /* do the load */ if (pb.ioFlLgLen) { /* if data present */ kShowWindow(ctermw); kSelectWindow(ctermw->window); /* queue the take file */ getlfile(savr.fName, savr.vRefNum); } } /* loadvals */ /* * takedialog * Do a Take Command File... dialog */ 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(savr.fName, savr.vRefNum); } /* takedialog */ /****************************************************************************/ /****************************************************************************/ 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; 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(&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(apf.fName, apf.vRefNum); c2pstr (&apf.fName); } } } /* findfinderfiles */ /* * getlfile * Build an lfile entry and put it on the queue. */ 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[LAST_MENU + 1]; /* handle on our menus */ /****************************************************************************/ /****************************************************************************/ doloadvals(fn, refnum) char *fn; int refnum; { int rfnum; int i, n; IHandle resinames; 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 */ scrinvert = termw->screeninvert; /* save the current value */ scrsize = termw->screensize; savinnum = innum; /* save current port too */ savmcmdactive = mcmdactive; get_term_pos(termw, &scrpostop, &scrposlft); /* in ckmco2.c */ scrfntsz = 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]; /* * Do the things in ttermw one by one. */ termw->newline = (*resinames)[14 + 1]; termw->autowrap = (*resinames)[15 + 1]; termw->autorepeat = (*resinames)[17 + 1]; termw->smoothscroll = (*resinames)[18 + 1]; termw->dispcontchar = (*resinames)[19 + 1]; termw->blockcursor = (*resinames)[21 + 1]; termw->mouse_arrows = (*resinames)[22 + 1]; termw->visible_bell = (*resinames)[23 + 1]; termw->eightbit_disp = (*resinames)[24 + 1]; termw->blinkcursor = (*resinames)[25 + 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, scrpostop, scrposlft); /* in ckmco2.c */ termw->current_size = scrfntsz; /* change font size */ /* 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, scrsize); /* change screen size */ if (scrinvert != termw->screeninvert) invert_term (termw); cursor_draw(termw); /* show the new cursor */ if (savinnum != innum) { /* if using the other port */ port_close(); port_open(savinnum); } /* tell serial driver about new vals */ (void) setserial (innum, outnum, speed, KPARITY_NONE); (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. */ /* 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: */