home *** CD-ROM | disk | FTP | other *** search
- /*
- * In this file lines end with CR/LF, as our psion C-compiler lives in the
- * DOS-WORLD
- * Copyright GNU Public License
- */
-
- #include <plib.h> /* NFS Client V3.10 N.N */
- #include <p_serial.h>
- #include <wlib.h>
- #include <hwif.h>
- #include "nfsc.h"
-
- #define TXT_TYPE H_DTEXT_ALIGN_CENTRE
-
- /*======================================================== NFSC set ===*/
- #define NR_OF_DEVICES 5 /* do not change, configure over menu */
-
- #ifdef HAVE_NFSSUPPORT
- static char *dev_name[]={"LOC::M:", "LOC::A:", "LOC::B:", "LOC::C:", "ROM::"};
- #endif
- static char welcome[]= "Welcome to Nfsc 4.3b";
-
- struct settings set = {
- {P_BAUD_9600,P_BAUD_9600,P_DATA_8,0,P_IGN_CTS,0x11,0x13,0,0},
- {0,0,P_SRDTR_ON}, /* modem sense, DTR assert */
- {1,1,1,1,1}, /* all devices active */
- FLAGS_SHOW_STATS | FLAGS_SMALL_STATWIN | FLAGS_NFSD_NEW | FLAGS_JUMPSCROLL,
- WS_FONT_BASE+4, /* Roman 8 Point, s3 see bel. */
- XY_YMODEM1K
- };
-
-
-
- TEXT *EnvironmentName="NFSC_v32";
-
- /*========================================================== menu's used ===*/
- static H_MENU_DATA mdata[]= {
- #ifdef HAVE_NFSSUPPORT
- "Nfsc", 4,
- #else
- "Nfsc", 2,
- #endif
- "Serial Line", 7,
- #ifdef HAVE_TERMEMU
- "Emulator",6,
- #endif
- #ifdef HAVE_XYMODEM
- "XYmodem",3,
- #endif
- NULL
- };
-
- static TEXT * cmds[]= {
- /* nfsc */
- "aAbout...",
- #ifdef HAVE_NFSSUPPORT
- "dDevices...",
- "nNfsd support...",
- #endif
- "xExit",
- /* Serial Line */
- "pParameters...",
- "hHandshaking...",
- "HExpert settings...",
- "tToggle stats",
- "cClear stats",
- "uUpdate stats...",
- "bSend a break",
- #ifdef HAVE_TERMEMU
- /* Emulator */
- "rReset",
- "zZoom: bigger",
- "ZZoom: smaller",
- "fFont...",
- "FFn Keys...",
- "sSettings...",
- #endif
- #ifdef HAVE_XYMODEM
- /* XYmodem */
- "CConfigure...",
- "SSend file...",
- "RReceive file...",
- #endif
- NULL
- };
-
- TEXT ** _cmds=cmds;
- H_MENU_DATA * _mdata=mdata;
-
-
- /*===================================================== global variables ===*/
- ULONG stats_read, stats_write; /* Read / write statistics */
-
- P_RECT hisrect; /* Rectangle for nfscmd history scrolling */
- INT stat_y,modem_x,io_x; /* Y pos for stat printing (font descent),etc*/
- UBYTE charwidth,charheight, /* Character data */
- ascent, rows, cols;
- WORD screenx,screeny, /* Character width */
- t_w, t_h; /* terminal width & height in pixels */
- BYTE clkwin;
- BYTE debug = 0;
- BYTE isnfsd = 0; /* used for sending a resize event *gulp* */
-
- extern UWORD _UseFullScreen; /* use full s3a or only s3 screen */
- char buf[256], buf2[256]; /* serial read buffers, not on stack */
- char rfilename[256]; /* last filename read */
- VOID *rfile = 0; /* last read filehandle */
- LONG roff = 0; /* last read offset */
- INT hgc; /* handle to graphics context */
- UINT main_win; /* main window ID */
- VOID *serial = 0; /* handle serial port */
- LOCAL_D VOID *timH; /* handle timer */
- LOCAL_D ULONG timint = 20; /* poll interval in 100msec units */
- WORD zero=0,one=1; /* constants to interact with serial port */
- TEXT mfb[40]; /* message formatting buffer; */
- UBYTE pctrl = 0xff; /* store last pctrl */
- UBYTE protocol; /* nfsd protocol none=0,old=1,new=2
- * new = 0x80 as escape character for nfs cmd,
- * old = no terminal capability
- * none = only terminal
- */
- UBYTE sch; /* Serial character */
- WORD ttystat; /* We need it global */
- UBYTE is_rtscts;
-
-
- #ifdef HAVE_TERMEMU
-
- struct fkey *fk;
- static char logfile[129] = "\015\\opd\\nfsc.log";
- static char fnkeyname[129] = "\017\\opd\\fnkeys.nfs";
- char cur_appl; /* cursor keys in application mode */
- BYTE fnkey = 0;
- void *logfd = 0;
-
- #include "cnv.h" /* charset conversion */
-
- #endif
-
- static char c_handshaking[] = "Handshaking";
- static char c_ignore[] = "Ignore";
- static char c_load[] = "Load";
- static char c_save[] = "Save";
- static char c_cfgserial[] = "configure serial";
- static char c_dtr[] = "change DTR";
- static char c_query[] = "query modem";
-
- /*========================================================= AddToHistory ===*/
- void AddToHistory (char ch) {
- static char idle;
- P_POINT o;
- int i = hisrect.tl.x;
-
- if(! ( set.flags & FLAGS_SHOW_STATS) )
- return;
-
- if (!ch) /* a heart beat indicator */
- {
- idle++;
- if (idle != 2) /* Will wrap after 256 ticks. But that is o.k. */
- return;
- /* seen two heatbeats in a row. Print a '.' as idle indicator */
- ch = '.';
- }
- else
- idle = 0;
-
- gPrintText(hisrect.br.x-charwidth, stat_y, &ch, 1);
- o.y = 0;
- o.x = -charwidth;
- hisrect.tl.x += charwidth;
- wScrollRect(main_win, &hisrect, &o); /* scroll one character leftward */
- hisrect.tl.x = hisrect.br.x - charwidth;
- gClrRect(&hisrect, G_TRMODE_CLR); /* clear space for next character */
- hisrect.tl.x = i;
- }
-
- void Check (INT val,TEXT *msg)
- {
- if (!val) return;
- p_atos(&mfb[0],"Failed to %s",msg);
- if (!p_notifyerr(val,&mfb[0],"Abort",c_ignore,0))
- p_exit(0);
- }
-
- void UpdateModem()
- {
- if(serial == 0 || !(set.flags & FLAGS_SHOW_STATS) )
- return;
-
- Check(p_iow(serial, P_FCTRL, set.pctrl), c_query);
- if (set.pctrl[0] == pctrl)
- return;
-
- pctrl = set.pctrl[0];
-
- p_atos(mfb, "%s %s %s",
- (pctrl & P_SRCTRL_CTS) ? "CTS" : "cts",
- (pctrl & P_SRCTRL_DSR) ? "DSR" : "dsr",
- (pctrl & P_SRCTRL_DCD) ? "DCD" : "dcd");
- set.pctrl[1] = 0x00; /* in case we did set it here */
- gPrintText(modem_x, stat_y, mfb, p_slen(mfb));
- }
-
-
- /*=============== Check, if write would block, i.e. flow control is on === */
- void
- serial_write(char *p, int n)
- {
- int ret;
-
- if(!(set.tty.hand & P_IGN_CTS))
- {
- Check(p_iow(serial, P_FCTRL, set.pctrl), c_query);
- while(!(set.pctrl[0] & P_SRCTRL_CTS))
- {
- H_DI_TEXT line1={buf+ 0,TXT_TYPE},
- line2={buf+ 50,TXT_TYPE};
-
- uZTStoBCS (line1.str, "Hardware flowcontrol specified,");
- uZTStoBCS (line2.str, "but modem line CTS is not set");
- if ( uOpenDialog ("WARNING!")
- || uAddDialogItem (H_DIALOG_TEXT, NULL, &line1)
- || uAddDialogItem (H_DIALOG_TEXT, NULL, &line2)
- || (uAddButtonList ("Exit", 'x',
- c_ignore, 'i',
- "Retry", W_KEY_RETURN, NULL))
- || (ret = uRunDialog()) <= 0)
- continue;
- if(ret == 'x')
- p_exit(0);
- if(ret == 'i')
- {
- Sw_Serial(OFF);
- set.tty.hand |= P_IGN_CTS;
- p_waitstat (&ttystat);
- if ((ret=p_iow(serial,P_FSET,&set.tty)) != 0) p_panic (ret);
- Sw_Serial(ON);
- break;
- }
- Check(p_iow(serial, P_FCTRL, set.pctrl), c_query);
- }
- }
- p_write (serial, p, n);
- stats_write += n;
- }
-
- /*============================================================ ShowStats ===*/
- void ShowStats (void) {
-
- if(! ( set.flags & FLAGS_SHOW_STATS) )
- return;
-
- p_atos (mfb, "I/O:%07Lu/%07Lu", stats_read, stats_write);
- gPrintText(io_x, stat_y, mfb, p_slen(mfb));
- }
-
- /*=============================================================== Resize ===*/
- /* Compute every position & redraw everything */
- void Resize (void)
- {
- W_WINDATA wd;
- WORD havestat;
- P_RECT pr;
- G_FONT_INFO fi;
- G_GC gc;
- int ret, l1, l2;
-
- /*----------------------------------- draw screen with status window ---*/
-
- if(clkwin)
- {
- if (_UseFullScreen) /* S3a */
- {
- if(clkwin == 2)
- havestat = W_STATUS_WINDOW_BIG;
- else
- havestat = W_STATUS_WINDOW_SMALL;
- wInquireStatusWindow (havestat, &wd.extent);
- wd.extent.tl.x = wd.extent.tl.y = 0;
- wd.extent.width = screenx - wd.extent.width;
- wd.extent.height = screeny;
- }
- else
- wsScreenExt (&wd.extent); /* Much easier */
- }
- else
- {
- wd.extent.tl.x = wd.extent.tl.y = 0;
- wd.extent.width = screenx;
- wd.extent.height = screeny;
- }
-
- wSetWindow (main_win, W_WIN_EXTENT, &wd);
-
- if ((ret=wCheckPoint()) != 0) p_exit (ret);
-
- pr.tl.x = pr.tl.y = 0;
- pr.br.x = wd.extent.width;
- pr.br.y = wd.extent.height;
- gClrRect(&pr, G_TRMODE_CLR);
-
- if(clkwin)
- {
- if(_UseFullScreen)
- wStatusWindow(havestat);
- else
- wsEnable();
- }
- else
- wsDisable();
-
- /*-------------------------------------------------------- Change GC ---*/
- gc.style = G_STY_MONO;
- gc.font = WS_FONT_BASE + set.font;
- gSetGC(hgc, G_GC_MASK_STYLE|G_GC_MASK_FONT, &gc);
-
- /*----------------- compute layout of the graphics items: ---*/
- gFontInfo(gc.font, G_STY_MONO, &fi);
-
- charwidth = fi.max_width;
- charheight = fi.height;
- ascent = fi.ascent;
- t_w = wd.extent.width;
- t_h = screeny;
-
- if ( set.flags & FLAGS_SHOW_STATS )
- {
- t_h -= charheight;
-
- l1 = gTextWidth(gc.font, G_STY_MONO, "I/O:9999999/9999999", 19);
- l2 = gTextWidth(gc.font, G_STY_MONO, "CTS DSR DCD", 11);
-
- stat_y = screeny - fi.descent;
- io_x = 0;
-
- hisrect.tl.x = l1+1;
- hisrect.tl.y = screeny - charheight;
- hisrect.br.x = t_w - l2;
- hisrect.br.y = screeny;
-
- modem_x = hisrect.br.x;
-
- /*
- gDrawLine(0, t_y, t_w, t_y);
- */
-
- ShowStats();
- pctrl = 0xff;
- UpdateModem();
- }
-
- rows = t_h / charheight; t_h = charheight * rows;
- cols = t_w / charwidth; t_w = charwidth * cols;
- if(isnfsd)
- {
- /* Resize event ... */
- buf2[0] = 0; buf2[1] = rows; buf2[2] = cols;
- P_WRITE(serial, buf2, 3);
- }
-
- #ifdef HAVE_TERMEMU
- Reset();
-
- LoadFnKey(fnkeyname, 0);
-
- p_atos (mfb, "rows: %d, cols: %d", rows, cols);
- wInfoMsgCorner(mfb, W_CORNER_BOTTOM_RIGHT);
- #endif
- }
-
- /*=========================================== screen/menu initialization ===*/
- void ScreenInitialize (void) {
-
- INT len;
- G_GC gc;
-
- /*-------------------------------------------------- initialize HWIF ---*/
- _UseFullScreen = TRUE; /* Set this to False for testing S3 */
- hCrackCommandLine();
- uCommonInit();
- uEscape (FALSE);
-
- /*----------------------------------- read set from environment ---*/
- /* p_delenv (EnvironmentName);/* */
- len = p_getenviron (EnvironmentName, p_slen(EnvironmentName), buf);
- if (len==sizeof(set))
- p_bcpy (&set, buf, sizeof(set));
- else
- {
- if(!_UseFullScreen)
- set.font = 0; /* S3 font for the first time */
- }
- clkwin = (set.flags >> 2) & 0x3;
- protocol = (set.flags >> 4) & 0x3;
-
- /*--------------------------------------------- set process priority ---*/
- p_setpri (p_getpid(), E_MAX_PRIORITY);
- if (_UseFullScreen) wSetPriorityControl (FALSE); /* S3a only */
-
- /*----------------------------------------------------- first resize ---*/
- main_win = uFindMainWid();
- if(_UseFullScreen)
- {
- screenx = 480; screeny = 160;
- }
- else
- {
- screenx = 240; screeny = 80;
- }
-
- gc.textmode = G_TRMODE_REPL; /* Default ist _SET */
- hgc = gCreateGC(main_win, G_GC_MASK_TEXTMODE, &gc);
-
- Resize();
- }
-
- /*======================================== Cancel / Reenable serial input ==*/
- void Sw_Serial(char on)
- {
- if(on)
- {
- one=1;
- p_ioa (serial, P_FREAD, &ttystat, &sch, &one);
- }
- else
- {
- p_iow (serial, P_FCANCEL);
- }
- }
-
- /*=============================================================== DoExit ===*/
- void DoExit()
- {
- int ret;
-
- set.flags &= ~0x3c; /* Delete bits for clkwin & protocol */
- set.flags |= (clkwin << 2) | (protocol << 4);
- ret = p_setenviron(EnvironmentName, p_slen(EnvironmentName),
- &set, sizeof(set));
- uErrorValue(ret);
- p_exit(0);
- }
-
- #ifdef HAVE_TERMEMU
- /*=============================================================== iso2cp ===*/
- unsigned char
- iso2cp(unsigned char ch) /* Called only with ch > 127 */
- {
- if(set.flags & FLAGS_NOCHARCONV)
- return ch;
- else
- return tbl_iso2cp[ch-128];
- }
- #endif
-
- /*=================================================== ExecuteMenuCommand ===*/
- void ParseKey (UWORD key, UBYTE modifier) {
-
- INT ret;
-
- /*--------------------------------------------------- system event ---*/
- if (key == 0x404)
- {
- wGetCommand((UBYTE *)buf);
- if(*buf == 'X')
- DoExit();
- return;
- }
- if (key & 0x400) /* Some other system event */
- return;
- /*------------------------------------------- Function keys -----------*/
- #ifdef HAVE_TERMEMU
- if(fnkey) /* Define or delete it */
- {
- if(fnkey == 'd')
- {
- H_DI_TEXT l1={buf+ 0, TXT_TYPE},
- l2={buf+ 50, TXT_TYPE},
- l3={buf+100, TXT_TYPE},
- l4={buf+150, TXT_TYPE};
- H_DI_EDIT l5={buf+150, 100};
-
- fnkey = 0;
- uZTStoBCS(l1.str, "Type in the characters to be sent.");
- uZTStoBCS(l2.str, "Use \\<nnn> for nonprintable (e.g. \\027=ESC)");
- uZTStoBCS(l3.str, "and \\s<nn> for delay (e.g. \\s99=9.9 seconds)");
- uZTStoBCS(l4.str, "");
- if ( uOpenDialog ("Defining the function key")
- || uAddDialogItem (H_DIALOG_TEXT, NULL, &l1)
- || uAddDialogItem (H_DIALOG_TEXT, NULL, &l2)
- || uAddDialogItem (H_DIALOG_TEXT, NULL, &l3)
- || uAddDialogItem (H_DIALOG_TEXT, NULL, &l4)
- || uAddDialogItem (H_DIALOG_EDIT, NULL, &l5))
- return;
- if(uRunDialog() > 0)
- AddFnKey(key, modifier, l5.str);
- }
- if(fnkey == 'r')
- {
- struct fkey **fp, *f;
-
- for(fp = &fk, f = fk; *fp; f = *fp)
- if(f->key == key && f->modifier == modifier)
- {
- *fp = f->next;
- p_free(f);
- wInfoMsgCorner("FnKey deleted", W_CORNER_BOTTOM_RIGHT);
- }
- else
- fp = &f->next;
- }
- fnkey = 0;
- return;
- }
-
- { /* Was the key a function key ? */
- struct fkey *f;
-
- for(f = fk; f; f = f->next)
- if(f->key == key && f->modifier == modifier)
- {
- SendFnKey(f);
- return;
- }
- }
- #endif
-
- /*------------------------------------------- clock window ------------*/
- if (key == W_KEY_MENU && modifier == W_CTRL_MODIFIER)
- {
- if(--clkwin < 0)
- clkwin = _UseFullScreen ? 2 : 1;
- Resize();
- return;
- }
-
- /*------------------------------------- send key to the serial line ---*/
- if (!(key & W_SPECIAL_KEY) && (key!=W_KEY_MENU))
- {
- #ifdef HAVE_TERMEMU
- if(key >= 256 && key <= 259) /* Arrow key */
- {
- char mb[3];
-
- mb[0] = 0x1b;
- mb[1] = cur_appl ? 'O' : '[';
- mb[2] = 'A' + (key - 256);
- P_WRITE(serial, mb, 3);
- }
- else
- {
- key = key & 0xff;
- if(key > 127 && !(set.flags & FLAGS_NOCHARCONV))
- key = tbl_cp2iso[key-128];
- P_WRITE(serial, (char *)&key, 1); /* BigEndian!!! */
- }
- #endif
- return; /* terminal */
- }
-
- /*------------------------- strip Psion modifier and get menu option ---*/
- key &= ~W_SPECIAL_KEY;
- if((key==W_KEY_MENU) && ((key=uPresentMenus()) <= 0))
- return;
- if (modifier & W_SHIFT_MODIFIER)
- key -= 0x20;
-
- /*---------------------------------------- switch on command request ---*/
- switch (key) {
-
- case 'a': { /*-------------------------------------------- About ---*/
- H_DI_TEXT line1={buf+ 0,TXT_TYPE},
- line2={buf+ 50,TXT_TYPE},
- line3={buf+100,TXT_TYPE},
- line4={buf+150,TXT_TYPE},
- line5={buf+200,TXT_TYPE};
-
- uZTStoBCS (line1.str, "N.N, Rudolf König,");
- uZTStoBCS (line2.str, "Michael Schröder, Jürgen Weigert");
- uZTStoBCS (line3.str, "╕ 1995, 1996");
- uZTStoBCS (line4.str, "jnweiger / rfkoenig@immd4.uni-erlangen.de");
- uZTStoBCS (line5.str, "Distributed under GNU Copyleft (Version 2)");
-
- if ( uOpenDialog ("About NFSC v4.3b")
- || uAddDialogItem (H_DIALOG_TEXT, NULL, &line1)
- || uAddDialogItem (H_DIALOG_TEXT, NULL, &line2)
- || uAddDialogItem (H_DIALOG_TEXT, NULL, &line3)
- || uAddDialogItem (H_DIALOG_TEXT, NULL, &line4)
- || uAddDialogItem (H_DIALOG_TEXT, NULL, &line5)
- || (_UseFullScreen && uAddButtonList ("", W_KEY_RETURN, NULL)) /* S3 doesn't fit */
- || uRunDialog() <= 0)
- return;
-
- return;
- }
-
- case 'p': { /*--------------------------------------------- Port ---*/
- UWORD baud = set.tty.tbaud;
- UWORD databits = (set.tty.frame & P_DATA_FRM) + 1;
- UWORD stopbits = (set.tty.frame & P_TWOSTOP) ? 2 : 1;
- UWORD parity = (set.tty.frame & P_PARITY) ?
- set.tty.parity + 1 : 0x01 /*none*/;
- UWORD ignore = (set.tty.flags & P_IGNORE_PARITY) ? 1 : 2;
-
- if ( uOpenDialog ("Port")
- || uAddChoiceList ("Baud rate", &baud, "50","75","110","134",
- "150","300","600","1200","1800","2000","2400",
- "3600","4800","7200","9600",
- _UseFullScreen ? "19200" : NULL, NULL)
- || uAddChoiceList ("Data bits",&databits,"5","6","7","8",NULL)
- || uAddChoiceList ("Stop bits", &stopbits, "1", "2", NULL)
- || uAddChoiceList ("Parity",&parity,"none","even","odd",NULL)
- || uAddChoiceList ("Ignore parity", &ignore,"yes","no", NULL)
- || uRunDialog() <= 0)
- return;
-
- set.tty.tbaud = set.tty.rbaud = baud;
- set.tty.frame = databits - 1;
- set.tty.frame |= (stopbits == 2) ? P_TWOSTOP : 0x00;
- set.tty.frame |= (parity > 1 /*none*/) ? P_PARITY : 0x00;
- set.tty.parity = parity - 1;
- set.tty.flags = (ignore == 1) ? P_IGNORE_PARITY : 0x00;
-
- Sw_Serial(OFF); /* otherwise panic with P_FSET! */
- p_waitstat (&ttystat);
-
- if ((ret=p_iow(serial,P_FSET,&set.tty)) != 0) p_panic (ret);
-
- Sw_Serial(ON);
-
- return;
- }
-
- case 'h': { /*-------------------------------------- Handshaking ---*/
- UWORD flow;
-
- if(set.tty.hand & P_SEND_XOFF) /* Software flow control */
- flow = 1;
- else if(set.tty.hand & P_IGN_CTS)
- flow = 3;
- else
- flow = 2; /* Hw flow control */
-
- if ( uOpenDialog(c_handshaking)
- || uAddChoiceList("Flowcontrol:",&flow,
- "Software","Hardware","None", NULL)
- || uRunDialog() <= 0)
- return;
-
- if(flow == 1)
- set.tty.hand = P_SEND_XOFF | P_IGN_CTS;
- else if(flow == 2)
- set.tty.hand = 0;
- else
- set.tty.hand = P_IGN_CTS;
- set.pctrl[1] = set.pctrl[2] == P_SRDTR_ON;
-
- Sw_Serial(OFF); /* otherwise panic with P_FSET! */
- p_waitstat (&ttystat);
-
- Check(p_iow(serial,P_FSET,&set.tty), c_cfgserial);
- Check(p_iow(serial,P_FCTRL,&set.pctrl), c_dtr);
- set.pctrl[1] = 0x00; /* or ModemUpdate will do it again */
-
- Sw_Serial(ON);
- return;
- }
- case 'H': { /*------------------------------- Expert Handshaking ---*/
- UWORD xon_xoff = set.tty.hand & P_SEND_XOFF ? 2 : 1;
- UWORD rts_cts = set.tty.hand & P_IGN_CTS ? 2 : 1;
- UWORD dsr_dtr = set.tty.hand & P_OBEY_DSR ? 2 : 1;
- UWORD dcd = set.tty.hand & P_OBEY_DCD ? 2 : 1;
- UWORD dtr = set.pctrl[2] == P_SRDTR_ON ? 2 : 1;
-
- if ( uOpenDialog (c_handshaking)
- || uAddChoiceList ("Send Xon/Xoff", &xon_xoff, "Off","On",NULL)
- || uAddChoiceList ("Ignore RTS/CTS", &rts_cts, "Off","On",NULL)
- || uAddChoiceList ("Obey DSR/DTR", &dsr_dtr, "Off","On",NULL)
- || uAddChoiceList ("Obey DCD", &dcd, "Off","On",NULL)
- || uAddChoiceList ("Assert DTR", &dtr, "Off","On",NULL)
- || uRunDialog() <= 0)
- return;
-
- set.tty.hand = 0x00; /* default is ZERO for RTS/CTS */
- set.tty.hand |= (xon_xoff == 2) ? P_SEND_XOFF|P_OBEY_XOFF : 0;
- set.tty.hand |= (rts_cts == 2) ? P_IGN_CTS : 0x00;
- set.tty.hand |= (dsr_dtr == 2) ? P_OBEY_DSR : 0x00;
- set.tty.hand |= (dcd == 2) ? P_OBEY_DCD : 0x00;
- set.pctrl[2] = 0x00;
- set.pctrl[2] |= (dtr == 2) ? P_SRDTR_ON : P_SRDTR_OFF;
- set.pctrl[1] = set.pctrl[2];
-
- Sw_Serial(OFF); /* otherwise panic with P_FSET! */
- p_waitstat (&ttystat);
-
- Check(p_iow(serial,P_FSET,&set.tty), c_cfgserial);
- Check(p_iow(serial,P_FCTRL,&set.pctrl), c_dtr);
- set.pctrl[1] = 0x00; /* or ModemUpdate will do it again */
-
- Sw_Serial(ON);
- return;
- }
- #ifdef HAVE_NFSSUPPORT
- case 'd': { /*------------------------------------------ Devices ---*/
- UWORD dev[5];
- INT i;
-
- if(uOpenDialog ("Devices"))
- return;
- for(i=0; i<NR_OF_DEVICES; i++)
- {
- dev[i] = set.devices[i] + 1;
- if(uAddChoiceList(dev_name[i], &dev[i], "Off", "On", NULL))
- return;
- }
- if(uRunDialog() <= 0)
- return;
- for(i=0; i<NR_OF_DEVICES; i++)
- set.devices[i] = dev[i] - 1;
- return;
- }
- case 'n': { /*---------------------------------------- Nfsd support */
- UWORD prt = protocol+1;
-
- if ( uOpenDialog ("Protocol")
- || uAddChoiceList("Support:",&prt,
- "Terminal only", "Old p3nfsd", "Terminal + New p3nfsd", NULL)
- || uRunDialog() <= 0)
- return;
-
- protocol = prt-1;
- return;
- }
- #endif
-
- case 27: /* Psion-Esc */
- case 'x': /*--------------------------------------------- Exit ---*/
- DoExit();
-
- case 't': /*-------------------------------- Statistics:Toggle ---*/
- if ( set.flags & FLAGS_SHOW_STATS )
- set.flags &= ~FLAGS_SHOW_STATS;
- else
- set.flags |= FLAGS_SHOW_STATS;
- Resize();
- return;
-
- case 'c': /*--------------------------------- Statistics:Clear ---*/
- stats_read = stats_write = 0;
- ShowStats();
- return;
-
- case 'u': { /*------------------------------------------- Update ---*/
- /* dialog to change update frequency: timint */
- H_DI_NUMBER num;
-
- num.value= (LONG *)&timint;
- num.low = 5;
- num.high = 1000;
- if (uOpenDialog("Update frequency") ||
- uAddDialogItem(H_DIALOG_NUMBER, "10ths of secs", &num) ||
- uRunDialog() <= 0)
- return;
- return;
- }
- case 'b': { /*-------------------------------------- Send a break --*/
- /* We can send a break of 10/50sec = 200msec at most. Should be
- at least 250msec, but it could be better than nothing */
- P_SRCHAR tty;
- unsigned char z = 0, i;
-
- Sw_Serial(OFF);
- p_iow (serial, P_FFLUSH);
- p_waitstat (&ttystat);
-
- tty = set.tty;
- tty.tbaud = tty.rbaud = P_BAUD_50;
- tty.frame = P_DATA_8 | P_PARITY; /* This means 200ms */
- tty.parity = P_PAR_EVEN;
- tty.hand = P_IGN_CTS;
- Check(p_iow(serial, P_FSET, &tty), c_cfgserial);
- for(i = 0; i < 6; i++) /* little over 1 sec */
- P_WRITE(serial, (char *)&z, 1);
-
- Check(p_iow(serial,P_FSET,&set.tty), c_cfgserial);
- set.pctrl[1] = 0x00; /* or ModemUpdate will do it again */
- p_iow (serial, P_FFLUSH);
-
- Sw_Serial(ON);
- return;
- }
-
- #ifdef HAVE_TERMEMU
- case 'r': /*--------------------------------------- Reset term --*/
- Resize();
- return;
-
- case 'z': /*------------------------------------- Zoom bigger ---*/
- if(!_UseFullScreen)
- return;
- if(set.font == 12)
- set.font = 4;
- else
- set.font++;
- Resize();
- return;
- case 'Z': /*------------------------------------- Zoom smaller ---*/
- if(!_UseFullScreen)
- return;
- if(set.font == 4)
- set.font = 12;
- else
- set.font--;
- Resize();
- return;
-
- case 'f': { /*------------------------------------ Choose font ---*/
- UWORD font = set.font > 7 ? 2 : 1;
- UWORD size = set.font - (font == 1 ? 3 : 7);
-
- if ( uOpenDialog ("Font & size")
- || uAddChoiceList ("Font", &font, "Roman", "Swiss", NULL)
- || uAddChoiceList ("Size", &size, "8", "11", "13", "16", NULL)
- || uRunDialog() <= 0)
- return;
-
- font = (font == 1 ? 3 : 7) + size;
- if ( font != set.font )
- {
- set.font = font;
- Resize();
- }
- return;
- }
- case 'F': { /*--------------------------------------- Fn keys ---*/
-
- char title[] = "Function keys";
- if (uOpenDialog (title)
- || (uAddButtonList ("Define", 'd', "Remove", 'r',
- c_save, 's', c_load, 'l', NULL))
- || (ret = uRunDialog()) <= 0)
- return;
-
- if(ret == 'd' || ret == 'r')
- {
- wInfoMsgCorner("Type the function key",W_CORNER_BOTTOM_RIGHT);
- fnkey = ret;
- }
- if(ret == 's' || ret == 'l')
- {
- H_DI_TEXT line1={buf+ 0,TXT_TYPE},
- line2={buf+ 50,TXT_TYPE};
- H_DI_FSEL line3={ fnkeyname, 0 };
-
- if(ret=='s')
- line3.flags |= H_FILE_NEW_EDITOR;
- uZTStoBCS (line1.str, "nfsc is autoloading \\opd\\fnkeys.nfs");
- uZTStoBCS (line2.str, "");
-
- if ( uOpenDialog (title)
- || uAddDialogItem (H_DIALOG_TEXT, NULL, &line1)
- || uAddDialogItem (H_DIALOG_TEXT, NULL, &line2)
- || uAddDialogItem (H_DIALOG_FSEL,
- ret=='s' ? c_load : c_save, &line3)
- || uRunDialog() <= 0)
- return;
- if(ret == 's')
- SaveFnKey(fnkeyname);
- else
- LoadFnKey(fnkeyname, 1);
- }
- return;
- }
- case 's': { /*------------------------------ Settings ---*/
- UWORD cnv = (set.flags & FLAGS_NOCHARCONV) ? 2 : 1;
- UWORD jsc = (set.flags & FLAGS_JUMPSCROLL) ? 1 : 2;
- UWORD log = logfd ? 1 : 2;
- UWORD db = debug ? 1 : 2;
-
- if ( uOpenDialog ("Terminal emulator settings")
- || uAddChoiceList ("ISO8859-1 to IBM850", &cnv,"On","Off",NULL)
- || uAddChoiceList ("Enable jumpscroll", &jsc,"On","Off",NULL)
- || uAddChoiceList ("Debugging", &db, "On","Off",NULL)
- || uAddChoiceList ("Log terminal output", &log,"Yes","No",NULL)
- || uRunDialog() <= 0)
- return;
-
- if(cnv == 1)
- set.flags &= ~FLAGS_NOCHARCONV;
- else
- set.flags |= FLAGS_NOCHARCONV;
-
- if(jsc == 1)
- set.flags |= FLAGS_JUMPSCROLL;
- else
- set.flags &= ~FLAGS_JUMPSCROLL;
-
- debug = 2 - db;
-
- log = 2 - log;
-
- if((logfd && !log) || (!logfd && log)) /* Changed */
- {
- if(!log)
- {
- p_close(logfd);
- logfd = 0;
- wInfoMsgCorner("Logging terminated", W_CORNER_BOTTOM_RIGHT);
- }
- else
- {
- extern char cant_open_the_file[];
- H_DI_FSEL line3={ logfile, H_FILE_NEW_EDITOR };
-
- logfile[*logfile+1] = 0;
-
- if ( uOpenDialog ("Logging")
- || uAddDialogItem (H_DIALOG_FSEL, "Logfile:", &line3)
- || uRunDialog() <= 0)
- return;
-
- if(p_open(&logfd,logfile+1,P_FSTREAM|P_FREPLACE|P_FUPDATE))
- wInfoMsgCorner(cant_open_the_file, W_CORNER_BOTTOM_RIGHT);
- else
- wInfoMsgCorner("Logging started", W_CORNER_BOTTOM_RIGHT);
- }
- }
- return;
- }
- #endif /* HAVE_TERMEMU */
-
- #ifdef HAVE_XYMODEM
- case 'C': /*------------------------------------------ XYmodem ----*/
- case 'S':
- case 'R': /*------------------------------------------ XYmodem ----*/
- /* XYmodem commands are only allowed in terminal-only mode */
- if(protocol != 0)
- {
- H_DI_TEXT line1={buf+ 0,TXT_TYPE},
- line2={buf+ 50,TXT_TYPE};
- int ret;
-
- uZTStoBCS (line1.str, "Sorry, XYmodem commands are only");
- uZTStoBCS (line2.str, "allowed in the \"Terminal only\" mode");
-
- if ( uOpenDialog ("XYmodem commands:")
- || uAddDialogItem (H_DIALOG_TEXT, NULL, &line1)
- || uAddDialogItem (H_DIALOG_TEXT, NULL, &line2)
- || (uAddButtonList ("", W_KEY_RETURN, NULL))
- || (ret = uRunDialog()) <= 0)
- return;
- return;
- }
- DoXYmodem(key);
- return;
- #endif
- }
- }
-
-
- #ifdef HAVE_NFSSUPPORT
- /*============================================================== Respond ===*/
- VOID Respond(int rc) {
-
- if(protocol == 1)
- {
- P_WRITE (serial, (char *)&rc, 1); /* Big Endian!!! */
- }
- else
- {
- char ret[2];
-
- ret[0] = PREFIX;
- ret[1] = rc;
- P_WRITE (serial, ret, 2);
- }
- }
-
- /*=============================================================== DoWork ===*/
- VOID DoWork (void) {
-
- struct { LONG offset; UINT len; UBYTE req; } *parms;
- void *file;
- char *str;
- INT rc, to_read;
- LONG offset;
- P_INFO p_info;
- UWORD crc, crc2;
- WORD len;
-
- /*-------------------------------------------------- read length&data ---*/
-
- len = sch;
- if(protocol == 2) /* We are reading the length here for the new proto */
- {
- len = 0;
- P_READ (serial, &len, 1); /* Big Endian!! */
- }
- P_READ (serial, buf, len);
-
- /*------------------ last (few) bytes contain request type and parms ---*/
- parms = (void *) (buf + len - sizeof(*parms));
-
-
- /*---------------- string is PASCAL string with C string termination ---*/
- str = buf+1;
-
- /*---------------------------------- piggyback statd code onto gattr ---*/
- if (parms->req == 0x0C) {
- AddToHistory ('f');
- Respond(0);
- }
-
- /*------------------------------------ last byte in frame is request ---*/
- switch (parms->req) {
-
- case 0x01: /*------------------------------------------------- creat ---*/
- rc = p_open (&file, str, P_FSTREAM|P_FREPLACE|P_FUPDATE);
- AddToHistory ((rc == 0) ? 'c' : 'C');
- if(!rc)
- p_close (file);
- Respond(rc);
- return;
-
- case 0x02: /*------------------------------------------------- gattr ---*/
- rc = p_finfo (str, &p_info);
- AddToHistory ((rc == 0) ? 'g' : 'G');
- Respond(rc);
- if (rc) return;
-
- if (p_info.status & P_FADIR) {
- case 0x0C: /* statd */
- /* damned filesystem without linkcount :( */
- p_info.version = 0;
- p_scat (str, "\\");
- p_open (&file, str, P_FDIR);
- while(p_iow (file, P_FREAD, buf, (P_INFO*)buf2) != E_FILE_EOF)
- if(((P_INFO *)buf2)->status & P_FADIR)
- p_info.version++;
- p_close (file);
- }
- P_WRITE (serial, (char *)&p_info, 12);
- return;
-
- case 0x03: /*--------------------------------------------------- mkd ---*/
- AddToHistory ('m');
- Respond(p_mkdir(str));
- return;
-
- case 0x04: /*-------------------------------------------------- read ---*/
- /* Only close the read fd after the last file chunk was read */
- offset = parms->offset;
- len = parms->len;
- rc = 0;
-
- if(*rfilename == 0 || p_scmp(rfilename, str))
- {
- if(*rfilename)
- {
- p_close(rfile);
- *rfilename = 0;
- }
- rc = p_open (&rfile,str,P_FOPEN|P_FSTREAM|P_FRANDOM|P_FSHARE);
- if(!rc)
- {
- p_scpy(rfilename, str);
- roff = 0;
- }
- }
-
- if(rc == 0) rc = p_finfo (str, &p_info);
- if(offset > p_info.size) offset = p_info.size;
- if(offset + len > p_info.size) len = p_info.size - offset;
-
- if(rc == 0 && roff != offset)
- rc = p_seek (rfile, P_FABS, &offset);
- AddToHistory ((rc == 0) ? 'r' : 'R');
- Respond(rc);
- if(rc)
- return;
-
- roff = offset;
-
- P_WRITE (serial, (char *)&p_info, 12);
- crc = 0;
- while(len > 0) {
- to_read = (len > sizeof(buf)) ? sizeof(buf) : len;
- to_read = p_read (rfile, buf, to_read);
- len -= to_read;
- roff += to_read;
-
- if(protocol > 1)
- p_crc(&crc, (UBYTE *)buf, (UINT)to_read);
- P_WRITE (serial, buf, to_read);
- }
- if(protocol > 1)
- P_WRITE (serial, (char *)&crc, 2);
-
- if(roff == p_info.size)
- {
- p_close (rfile);
- *rfilename = 0;
- }
- return;
-
- case 0x05: /*-------------------------------------------------- rdir ---*/
- AddToHistory ('l');
- Respond(0);
- p_open (&file, str, P_FDIR);
- while (p_iow (file, P_FREAD, buf, NULL) != E_FILE_EOF)
- P_WRITE (serial, buf, p_slen(buf)+1);
- p_close (file);
- P_WRITE(serial, (char *)&zero, 1);
- return;
-
- case 0x06: /*-------------------------------------------------- remv ---*/
- AddToHistory ('d');
- Respond(p_delete(str));
- return;
-
- case 0x07: /*-------------------------------------------------- renm ---*/
- AddToHistory ('n');
- len = ((unsigned char *)(&parms->len))[1];
- P_READ (serial, buf2, len);
- buf2[len]=0;
- rc = p_rename (str, buf2+1);
- Respond(rc);
- return;
-
- case 0x08: /*--------------------------------------------------- rmd ---*/
- AddToHistory ('z');
- Respond(p_delete(str));
- return;
-
- case 0x09: /*------------------------------------------------- sattr ---*/
- AddToHistory ('s');
- Respond(p_sfstat (str, parms->len,/*attr*/ 0x0F2F));
- return;
-
- case 0x0A: /*------------------------------------------------- write ---*/
- offset = parms->offset;
- len = parms->len;
-
- rc = p_open (&file, str, P_FOPEN | P_FSTREAM | P_FUPDATE | P_FRANDOM);
- if(rc == 0 && offset > 0)
- rc = p_seek (file, P_FABS, &offset);
-
- crc = 0;
- while (len) {
- to_read = (len > sizeof(buf)) ? sizeof(buf) : len;
- P_READ(serial, buf, to_read);
- if(protocol > 1)
- p_crc(&crc, (UBYTE *)buf, (UINT)to_read);
- if(rc == 0)
- rc = p_write (file, buf, to_read);
- len -= to_read;
- }
- p_close (file);
-
- if(protocol > 1)
- {
- P_READ (serial, &crc2, 2);
- if(crc != crc2)
- {
- AddToHistory ('?');
- if(rc == 0)
- rc = 1;
- }
- }
-
- Respond(rc);
- AddToHistory ((rc == 0) ? 'w' : 'W');
- return;
-
- case 0x0B: /*-------------------------------------------------- getd ---*/
- AddToHistory ('>');
- Respond(0);
- for(len=0; len<NR_OF_DEVICES; len++)
- {
- if(set.devices[len] && p_dinfo(dev_name[len], (P_DINFO *)buf) == 0)
- {
- P_WRITE (serial, dev_name[len], p_slen(dev_name[len])+1);
- P_WRITE (serial, buf, 14);
- }
- }
- P_WRITE (serial, (char *)&zero, 1);
- return;
-
- #ifdef HAVE_TERMEMU
- case 0x0D: /*------------------------------------------------- ttydata -*/
- if(protocol == 2)
- {
- AddToHistory ('+');
- TtyEmu((UBYTE *)str, *(UBYTE *)buf); /* No return this time */
- if(isnfsd == 0)
- {
- isnfsd = 1;
- buf2[0] = 0; /* Resize event ... */
- buf2[1] = rows;
- buf2[2] = cols;
- P_WRITE(serial, buf2, 3);
- }
- }
- else
- {
- AddToHistory ('X');
- Respond(1);
- }
- return;
- #endif
-
- default: /*----------------------------------------------- default ---*/
- AddToHistory ('X');
- Respond(1);
- return;
- }
- }
- #endif /* HAVE_NFSSUPPORT */
-
- #define QueueTimer(when) p_ioa4(timH,P_FRELATIVE,&timstat,&when)
-
- /*================================================================= main ===*/
- void main (void) {
-
- WORD keystat, timstat;
- WMSG_KEY key;
- char *str;
-
- /*------------------------------------------- program initialization ---*/
- stats_read = stats_write = 0;
- ScreenInitialize ();
- for(str = welcome; *str; str++)
- AddToHistory(*str);
-
- /*------------------------------------------------- open serial port ---*/
- Check(p_open(&serial,"TTY:A",-1), "open TTY:A");
- Check(p_iow(serial,P_FSET,&set.tty), "init serial line");
- one=1; p_ioa (serial, P_FREAD, &ttystat, &sch, &one);
-
- if (set.flags & FLAGS_SHOW_STATS)
- UpdateModem();
-
- Check(p_open(&timH,"TIM:",-1), "open timer");
- QueueTimer(timint);
- uGetKeyA (&keystat, &key);
-
- /*-------------------------------------------------------- main loop ---*/
- for (;;) {
-
- /*--------------------------------- wait for something to happen ---*/
- p_iowait();
-
- /*------------------------------------------- was a key pressed? ---*/
- if (keystat != E_FILE_PENDING) {
- ParseKey (key.keycode, key.modifiers);
- uGetKeyA (&keystat, &key);
- continue;
- }
-
-
- /*------------------------------ did the serial port talk to us? ---*/
- if (ttystat != E_FILE_PENDING) {
- stats_read++;
- #ifdef HAVE_NFSSUPPORT
- if(protocol == 1 || (protocol == 2 && sch == PREFIX))
- DoWork ();
- else
- #endif
- {
- #ifdef HAVE_TERMEMU
- /*
- Problem: bytewise reading and screen update is too slow.
- Let's try to read more if there is available. The problem
- is that there may be a protocol 2 command in the data.
- Therefore this is restricted to the "terminal only" mode.
- */
- if(protocol == 0)
- {
- *buf = sch;
- p_iow(serial, P_FTEST, &one);
- if(one > 0) /* hmmm */
- {
- if(one > 255) one = 255;
- p_iow (serial, P_FREAD, buf+1, &one);
- }
- one++; /* the first byte is already read before */
- TtyEmu((unsigned char *)buf, one);
- }
- else
- TtyEmu(&sch, 1);
- #endif
- }
-
- ShowStats ();
- one=1; p_ioa (serial, P_FREAD, &ttystat, &sch, &one);
- continue;
- }
-
- /*------------------------------------------ time for a timeout? ---*/
- if (timstat != E_FILE_PENDING)
- {
- UpdateModem();
- AddToHistory (0);
- wFlush();
- QueueTimer(timint);
- }
- }
- }
-