/* * File ckmscr.c * * Mac Kermit file transfer display. * * Original by: Bill Schilit, May 1984 * Modified by many others since then. */ /* Copyright (C) 1984, 1995, Trustees of Columbia University in the City of New York. The C-Kermit software may not be, in whole or in part, licensed or sold for profit as a software product itself, nor may it be included in or distributed with commercial products or otherwise distributed by commercial concerns to their clients or customers without written permission of the Office of Kermit Development and Distribution, Columbia University. This copyright notice must not be removed, altered, or obscured. */ #include "ckcdeb.h" #include "ckcker.h" #include "ckmdef.h" /* General Mac defs */ #include "ckmres.h" /* Mac resource equates */ #include "ckmptp.h" /* ckm* Prototypes */ int scrpkt, scrnak; /* NAK, packet counts */ long scrck; /* char (K) count */ int scrpacln, scrcksum, scrwslots, scrbufnum; /* pkt len, checksum, win size */ long scrfsize, scrffc; DialogPtr scrdlg = (DialogPtr) NULL; /* screen's dialog */ extern char filnam[]; extern int what, binary; void update_scr_therm(); static pascal void draw_screen_xfr_therm (WindowPtr win, short itemno); static char cwdbuf[81]; /****************************************************************************/ /* scrcreate - create the status display. Called when a protocol * menu item is selected and a display is desired (I don't * think you'd want to see this for REMOTE command). * */ /****************************************************************************/ scrcreate() { Rect itemr; short itype; Handle itemhdl; if (scrdlg != NULL) printerr ("scrcreate with active screen!", 0); scrdlg = GetNewDialog (SCRBOXID, NILPTR, (WindowPtr) -1); scrck = -1; scrnak = scrpkt = 0; scrpacln = scrcksum = 0; scrwslots = scrbufnum = -1; scrfsize = scrffc = 0; ffc = 0; SetStrText (SRES_PTTXT, "\pEmergency exit: hold down \021 and type a period.", scrdlg); /* yes, so set the text */ SetStrText (SRES_BTEXT, "\p", scrdlg); strcpy(cwdbuf,"Current Directory: "); strncat(cwdbuf,zgtdir(),60); c2pstr(cwdbuf); SetStrText (SRES_BTEXT, (unsigned char *)cwdbuf, scrdlg); debug(F101,"scrcreate what","",what); debug(F101,"scrcreate protocmd","",protocmd); switch (what) { /* What are we doing? */ case W_SEND: SetStrText (SRES_DIR,"\p Sending",scrdlg); break; case W_REMO: case W_RECV: if (protocmd == SERV_REMO) SetStrText (SRES_DIR,"\p Server",scrdlg); else SetStrText (SRES_DIR,"\pReceiving",scrdlg); break; default: SetStrText (SRES_DIR, (protocmd == SEND_REMO) ? "\p Sending" : "\pReceiving", scrdlg); break; } GetDItem (scrdlg, SRES_THERM, &itype, &itemhdl, &itemr); SetDItem (scrdlg, SRES_THERM, itype, (Handle) draw_screen_xfr_therm, &itemr); update_scr_therm(); miniparser (TRUE); /* keep things moving */ } /* scrcreate */ /****************************************************************************/ /* scrdispose - called to finish up the status display, on a * transaction complete screen() call. */ /****************************************************************************/ void scrdispose (Boolean wait) { EventRecord dummyEvt; if (scrdlg == NULL) printerr ("scrdispose called with no screen active!", 0); SysBeep (3); if (wait) { /* deactivate buttons */ HiliteControl (getctlhdl (SRES_CANF, scrdlg), 255); HiliteControl (getctlhdl (SRES_CANG, scrdlg), 255); if (tlevel < 0) { /* if no takefile running */ SetStrText (SRES_PTTXT, "\pType a key or click the mouse to continue.", scrdlg); /* yes, so set the text */ /* wait for mouse or key down and discard the event when it happens */ while (!GetNextEvent (keyDownMask + mDownMask, &dummyEvt)) /* do nothing */ ; } } else { SetStrText (SRES_PTTXT, "\pNormal cleanupŠ", scrdlg); } DisposDialog (scrdlg); scrdlg = NULL; } /* scrdispose */ void update_scr_therm() { GrafPtr savePort; GetPort (&savePort); /* there just has to be a better way */ SetPort (scrdlg); draw_screen_xfr_therm (scrdlg, SRES_THERM); SetPort (savePort); } static pascal void draw_screen_xfr_therm (WindowPtr win, short itemno) { #pragma unused (win) Rect r, itemr; short itype; Handle itemhdl; PenState oldpenstate; if (itemno != SRES_THERM) /* Shouldn't ever happen */ return; GetPenState(&oldpenstate); /* save so we can fuss with */ PenNormal(); GetDItem (scrdlg, itemno, &itype, &itemhdl, &itemr); /* EraseRect(&itemr); */ if (fsize <= 0L) { /* Frame the thermometer in gray */ PenPat(qd.gray); PenSize (2, 2); FrameRect(&itemr); InsetRect(&itemr, 2, 2); EraseRect(&itemr); } else { /* Frame the thermometer */ PenSize (2, 2); FrameRect(&itemr); InsetRect(&itemr, 2, 2); PenPat (qd.white); FrameRect(&itemr); InsetRect(&itemr, 2, 2); /* * We want to fill first (ffc / fsize) of (itemr.right - itemr.left) * with black, and the rest with gray. */ r.top = itemr.top; r.bottom = itemr.bottom; r.left = itemr.left; r.right = itemr.left + (((long) (itemr.right - itemr.left) * (long) ffc) / (long) fsize); if (r.right > itemr.right) /* reality check */ r.right = itemr.right; if (r.left < r.right) /* has any been transfered? */ FillRect (&r, qd.dkGray); if (r.right < itemr.right) { /* any left to transfer? */ r.left = r.right; r.right = itemr.right; FillRect (&r, qd.ltGray); } } scrfsize = fsize; scrffc = ffc; SetPenState(&oldpenstate); /* restore old pen state */ } /* ststrings - translation of SCR_ST subfunctions to descriptive text */ char *ststrings[] = { ": Transferred OK", /* ST_OK */ ": Discarded", /* ST_DISC */ ": Interrupted", /* ST_INT */ ": Skipped ", /* ST_SKIP */ ": Fatal error" /* ST_ERR */ }; /* scrtosresnum - table to translate from SCR_XXX values into resource * item numbers. Entries we aren't interested in are * set to SRES_UNDEF. */ int scrtoresnum[] = { SRES_UNDEF, /* 0 - nothing */ SRES_FILN, /* SCR_FN - filename */ SRES_AFILN, /* SCR_AN - as filename */ SRES_UNDEF, /* SCR_FS - file size */ SRES_UNDEF, /* SCR_XD - x-packet data */ SRES_PTEXT, /* SCR_ST - status (goes in prev. text area) */ SRES_UNDEF, /* SCR_PN - packet number */ SRES_UNDEF, /* SCR_PT - packet type (special) */ SRES_BTEXT, /* SCR_TC - transaction complete */ SRES_ITEXT, /* SCR_EM - error msg (does alert) */ SRES_ITEXT, /* SCR_WM - warning message */ SRES_BTEXT, /* SCR_TU - arb text */ SRES_BTEXT, /* SCR_TN - arb text */ SRES_BTEXT, /* SCR_TZ - arb text */ SRES_BTEXT, /* SCR_QE - arb text */ SRES_ITEXT /* SCR_DT - date text */ }; /****************************************************************************/ /* screen - display status information on the screen during protocol. * Here we just set the items in their StatText dialog boxes, * updates occur through the miniparser, which we are nice * enough to call here to handle things. */ /****************************************************************************/ _PROTOTYP( VOID screen, (int, char, long, char *) ); VOID screen (int f, char c, long n, char *s) { /* s is a C string (not a Pascal Str255) */ int rnum; long i; char buf[256]; extern int spktl, rln, bctu, wslots; static char last_st = ST_OK; static char got_err = 0; /* becomes true if we get an error message */ if (scrdlg == NULL) /* not using? */ return; miniparser (TRUE); /* keep the mac going */ if (quiet) /* Silent? Then just do miniparser(). */ return; #ifdef COMMENT if (f == SCR_EM) { /* error message? */ printerr (s, 0); /* display it */ return; /* and return */ } #endif /* * This is a really ugly hack (which *I* didn't create), but... * If we are seeing the name of an incoming file, then call * dorecvdialog() to give the user a possible chance (if they * have asked for interactive recieve dialogs) to put the file * somewhere interactively. * * Putting this hook in here is really a kludge. */ if (f == SCR_FN) { /* seeing a file name? */ SetStrText (SRES_AFILN, "\p", scrdlg); if (what == W_RECV) /* of an incoming file? */ dorecvdialog (s, &cmarg2); /* yes, allow user to do dialog */ } rnum = scrtoresnum[f]; /* load default DITL number */ /* where result will be posted */ switch (f) { /* according to function... */ case SCR_EM: /* error message */ case SCR_WM: /* warning message */ got_err = 1; SysBeep(3); /* get the user's attention */ Delay ((long) 10, &i); SysBeep(3); Delay ((long) 10, &i); SysBeep(3); if (n != 0L) { strcpy (buf, s); strcat (buf, " "); s = &buf[strlen(buf)]; NumToString(n, s); p2cstr(s); s = buf; } break; case SCR_FN: got_err = 0; /* Reset for this file */ SetStrText (SRES_ITEXT, "\p", scrdlg); break; case SCR_CD: SetStrText (SRES_BTEXT, "\p", scrdlg); strcpy(cwdbuf,"Current Directory: "); strncat(cwdbuf,zgtdir(),60); c2pstr(cwdbuf); SetStrText (SRES_BTEXT, (unsigned char *)cwdbuf, scrdlg); break; case SCR_FS: /* File Size */ case SCR_AN: /* "As-Name" */ if ((filargs.filflg & (FIL_RSRC | FIL_DATA)) == (FIL_RSRC | FIL_DATA)) { /* in MacBinary mode */ SetStrText (SRES_FFORK, "\p", scrdlg); SetStrText (SRES_FMODE, "\pMacBinary Mode", scrdlg); } else { SetStrText (SRES_FFORK, (filargs.filflg & FIL_RSRC) ? "\pRSRC Fork" : "\pData Fork", scrdlg); SetStrText (SRES_FMODE, (filargs.filflg & FIL_BINA) ? "\pBinary Mode" : "\pText Mode", scrdlg); } break; case SCR_PT: /* Packet type? */ if (what == W_SEND) { /* sent a packet... */ i = spktl-bctu; if (i+2 <= MAXPACK) i += 2; /* short packet */ } else { /* received a packet */ i = rln + bctu; if (rln <= MAXPACK) /* if it was a short packet */ i += 2; /* then add space for SEQ and TYPE */ } if (i != scrpacln) { /* Length */ scrpacln = i; SetNumText (SRES_PACSZ, scrpacln, scrdlg); } /* checksum type */ if (bctu != scrcksum) { scrcksum = bctu; SetNumText (SRES_CKSUM, scrcksum, scrdlg); } /* window size */ if ((wslots != scrwslots) || ((what == W_SEND) && (sbufnum != scrbufnum)) || ((what != W_SEND) && (rbufnum != scrbufnum))) { char *cp; scrwslots = wslots; if (what == W_SEND) scrbufnum = sbufnum; else scrbufnum = rbufnum; NumToString ((wslots - scrbufnum), buf); /* convert to number */ p2cstr(buf); strcat (buf, "/"); /* make it be a fraction */ cp = (char *) buf + strlen (buf); NumToString (scrwslots, cp); p2cstr(cp); c2pstr(buf); /* convert whole buf back to string */ SetStrText (SRES_WINSZ, (unsigned char *) buf, scrdlg); } if (c == 'Y') return; /* don't do anything for yaks */ if (c == 'N' || c == 'Q' || /* check for all types of */ c == 'T' || c == '%') /* NAK */ i = ++scrnak, rnum = SRES_NRTY; /* increment nak counter */ else i = ++scrpkt, rnum = SRES_NPKT; /* else increment pkt counter */ NumToString (i, buf); /* translate to number */ p2cstr(buf); s = buf; /* new buffer */ break; /* all done */ case SCR_ST: /* status */ last_st = c; /* PWP: save for later */ if (f == ST_SKIP) strcpy(buf, s); else /* file name; should be same as filargs.fillcl */ strcpy (buf, filnam); strcat (buf, ststrings[c]); /* add status */ s = buf; #ifdef COMMENT SetStrText (SRES_BTEXT, "\p", scrdlg); /* clear eg. remote size */ SetStrText (SRES_ITEXT, "\p", scrdlg); /* clear eg. date */ #endif break; case SCR_TC: /* transaction completed */ if (!server) { /* are we a server? */ /* if not, dispose the screen */ scrdispose ((last_st != ST_OK) || got_err); got_err = 0; /* reset this */ return; /* and we are done */ } s = "Server transaction complete"; break; #ifdef COMMENT case SCR_DT: /* file creation date */ strcpy (buf, "Creation date: __/__/__ "); buf[15] = s[4]; buf[16] = s[5]; buf[18] = s[6]; buf[19] = s[7]; buf[21] = s[2]; buf[22] = s[3]; strcat (buf, &s[8]); s = buf; break; #endif /* COMMENT */ case SCR_QE: /* Quantity equals */ strcpy (buf, s); strcat (buf, " = "); s = &buf[strlen(buf)]; NumToString(n, s); p2cstr(s); s = buf; scrck = -1; /* force update of # Ks transfered */ break; } if (rnum != SRES_UNDEF) /* have DITL number for this? */ SetStrText (rnum, c2p_tmp(s), scrdlg); /* yes, so set the text */ if ((scrfsize != fsize) || (scrffc != ffc)) update_scr_therm(); if ((i = (ffc + 512) / 1024) != scrck) { /* Size changed? */ scrck = i; /* remember new value */ NumToString (scrck, buf); /* convert to number */ p2cstr(buf); if (fsize != 0) { /* know the size? */ char *cp; strcat (buf, "/"); /* make it be a fraction */ cp = (char *) buf + strlen (buf); NumToString ((fsize + 512) / 1024, cp); p2cstr(cp); } c2pstr(buf); SetStrText (SRES_KXFER, (unsigned char *)buf, scrdlg); } } /* screen */ /****************************************************************************/ /* scrmydlg - handle dialog events occuring in the screen (status) * dialog. Called by the miniparser when a dialog event * occurs and we are supposed to handle it. */ /****************************************************************************/ scrmydlg (item) int item; { switch (item) { case SRES_CANF: cxseen = TRUE; break; case SRES_CANG: czseen = TRUE; break; } } /* scrmydlg */ /* * Junk so Emacs will set local variables to be compatible with Mac/MPW. * Should be at end of file. * * Local Variables: * tab-width: 4 * End: */