home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d114 / vt100.lha / Vt100 / vt100.c < prev    next >
C/C++ Source or Header  |  1987-11-22  |  20KB  |  785 lines

  1. /********************************************************************
  2.  *  vt100 terminal emulator with xmodem transfer capability
  3.  *
  4.  *    v2.7 870825 ACS - Provide handling of the msgs from the
  5.  *              info/status window.
  6.  *    v2.6 870227 DBW - bug fixes for all the stuff in v2.5
  7.  *    v2.5 870214 DBW - more additions (see readme file)
  8.  *    v2.4 861214 DBW - lots of fixes/additions (see readme file)
  9.  *    v2.3 861101 DBW - minor bug fixes
  10.  *    v2.2 861012 DBW - more of the same
  11.  *    v2.1 860915 DBW - new features (see README)
  12.  *         860901 ACS - Added Parity and Word Length and support code
  13.  *         860823 DBW - Integrated and rewrote lots of code
  14.  *    v2.0 860809 DBW - Major rewrite
  15.  *    v1.1 860720 DBW    - Switches, 80 cols, colors, bug fixes
  16.  *    v1.0 860712 DBW    - First version released
  17.  *
  18.  *  use <esc> to abort xmodem or kermit transfers
  19.  *
  20.  *  written by Michael Mounier
  21.  *  new version by Dave Wecker
  22.  *******************************************************************/
  23.  
  24. /*  all includes defines and globals */
  25. #include "vt100.h"
  26.  
  27. /**************************************************************/
  28. /* here are all the global definitions that appear in vt100.h */
  29. /**************************************************************/
  30.  
  31. char    bufr[BufSize];
  32. int     fd, timeout = FALSE, ttime;
  33. int    multi = FALSE, server;
  34. long    bytes_xferred;
  35. char    MyDir[60];
  36. #ifdef BUGFIXES
  37. BPTR    StartLock = 0;
  38. #else
  39. struct    FileLock *MyDirLock = NULL;
  40. struct    FileLock *StartLock = NULL;
  41. #endif
  42. struct    IntuitionBase *IntuitionBase;
  43. struct    GfxBase *GfxBase;
  44.  
  45. struct    TextAttr myattr = {
  46.     (STRPTR) "topaz.font",
  47.     8,
  48.     0,
  49.     0};
  50. struct    TextFont *myfont = NULL;
  51. struct NewScreen NewScreen = {
  52.    0,0,640,200,1,        /* left, top, width, height, depth */
  53.    0,1,HIRES,            /* DetailPen, BlockPen, ViewModes */
  54.    CUSTOMSCREEN,&myattr,    /* Type, Font */
  55.    (UBYTE *)"VT100",        /* Title */
  56.    NULL,NULL };            /* Gadgets, Bitmap */
  57. struct NewWindow NewWindow = {
  58.    0,0,640,200,            /* left, top, width, height */
  59.    0,1,                /* detailpen, blockpen */
  60.    MENUPICK|CLOSEWINDOW|RAWKEY|ACTIVEWINDOW|INACTIVEWINDOW,
  61.    SMART_REFRESH|ACTIVATE|BORDERLESS|WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG,
  62.    NULL,NULL,            /* FirstGadget, CheckMark */
  63.    (UBYTE *)NULL,
  64.    NULL,            /* set screen after open screen */
  65.    NULL,            /* bitmap */
  66.    640, 200, 640, 200,        /* minw, minh, maxw, maxh */
  67.    CUSTOMSCREEN            /* Type */
  68.    };
  69. struct NewWindow NewReqWindow = {
  70.    10, 15, ((54*8)+4+18), ((4*8)+11+2), /* left, top, width, height */
  71.    0, 1,            /* detailpen, blockpen */
  72.     /* IDCMP Flags... */
  73.    CLOSEWINDOW | ACTIVEWINDOW | REQCLEAR | REQSET | NEWSIZE,
  74.     /* Flags... */
  75.    SMART_REFRESH | NOCAREREFRESH | ACTIVATE | WINDOWSIZING | SIZEBRIGHT |
  76.    WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG,
  77.  
  78.    NULL,            /* First gadget */
  79.    NULL,            /* CheckMark */
  80.    (UBYTE *)"VT100 Info & Xfer Status",    /* Title */
  81.    NULL,            /* set screen after open screen */
  82.    NULL,            /* bitmap */
  83.    ((5*8)+4+18), ((1*8)+11+2), 640, 200,    /* minw, minh, maxw, maxh */
  84.    CUSTOMSCREEN            /* Type */
  85.    };
  86. struct IntuiText MyTitle = {
  87.     0,1,JAM2,26,0,        /* front pen, back pen, mode, left, top */
  88.     &myattr,            /* font */
  89.     (UBYTE *)VERSION,        /* title */
  90.     NULL};            /* next text */
  91.  
  92. struct Screen *myscreen = NULL;        /* ptr to applications screen */
  93. struct Window *mywindow = NULL;        /* ptr to applications window */
  94. struct Window *reqwindow = NULL;    /* ptr to requester's window */
  95. struct ViewPort *myviewport;
  96. struct RastPort *myrastport;
  97. struct IntuiMessage *NewMessage;    /* msg structure for GetMsg() */
  98. struct Preferences  *Prefs;        /* preferences from GetPrefs() */
  99.  
  100. /**** String requester support ******/
  101.  
  102. char    InpBuf[80],UndoBuf[80],Prompt[80];
  103. struct IntuiText donetxt = {
  104.     1,0,JAM2,0,0,    /* front pen, back pen, mode, left, top */
  105.     &myattr,        /* font */
  106.     (UBYTE *)"DONE",    /* question to ask */
  107.     NULL};        /* next text */
  108. struct Gadget mydonegad = {
  109.     &mystrgad,290,2,40,10,    /* next,left,top,width,height */
  110.     GADGHCOMP|REQGADGET,    /* flags */
  111.     RELVERIFY|ENDGADGET,    /* activation */
  112.     BOOLGADGET,            /* gadget type */
  113.     NULL,NULL,&donetxt,        /* gad render, sel render, gad text */
  114.     0L,NULL,2,NULL};        /* mutual exclude, special, ID, user data */
  115. struct    StringInfo mystrinfo = {
  116.     (UBYTE *)InpBuf,
  117.     (UBYTE *)UndoBuf,
  118.     0,80,0,0,0,0,    /* initial, max, disp, undo, #chrs, dsp chrs */
  119.     0,0,NULL,0L,NULL};    /* left,top,layer,longint,keymap */
  120. struct Gadget mystrgad = {
  121.     NULL,10,12,320,10,    /* next,left,top,width,height */
  122.     GADGHCOMP|REQGADGET,/* flags */
  123.     ENDGADGET,STRGADGET,/* activation, type */
  124.     NULL,NULL,NULL,    /* gad render, sel render, gad text */
  125.     0L,            /* mutual exclude */
  126.     (APTR)&mystrinfo,    /* special info */
  127.     1,NULL};        /* gadget ID, user data */
  128. struct IntuiText mystrtxt = {
  129.     0,1,JAM2,10,2,    /* front pen, back pen, mode, left, top */
  130.     &myattr,        /* font */
  131.     (UBYTE *)Prompt,    /* question to ask */
  132.     NULL};        /* next text */
  133. struct Requester myrequest = {
  134.     NULL,0,10,340,22,    /* older requester, left, top, width, height */
  135.     0,0,&mydonegad,    /* relleft reltop, gadgets */
  136.     NULL,        /* border */
  137.     &mystrtxt,        /* text */
  138.     NULL,1,NULL,    /* flags, back fill pen, layer */
  139.     {0,0,0,0,0,0,0,0,
  140.      0,0,0,0,0,0,0,0,
  141.      0,0,0,0,0,0,0,0,
  142.      0,0,0,0,0,0,0,0},    /* pad1 */
  143.     NULL,NULL,        /* image bit map, rquest window */
  144.     {0,0,0,0,0,0,0,0,0,
  145.      0,0,0,0,0,0,0,0,0,
  146.      0,0,0,0,0,0,0,0,0,
  147.      0,0,0,0,0,0,0,0,0} /* pad2 */
  148.     };
  149.  
  150. int numreqs = 0;        /* number of outstanding requestors */
  151. int reqwinup = 0;        /* Requester window is NOT displayed */
  152. extern int reqmaxx, reqmaxy, reqmaxlen;    /* Defined in window.c */
  153. extern void ReqNewSize();    /* New req window size -- window.c */
  154. extern void KillReq();        /* Kill requester window in window.c */    
  155.  
  156. /***** menu structures *****/
  157. struct MenuItem FileItem[FILEMAX];
  158. struct IntuiText FileText[FILEMAX];
  159. struct MenuItem CommItem[COMMAX];
  160. struct IntuiText CommText[COMMAX];
  161. struct MenuItem RSItem[RSMAX];
  162. struct IntuiText RSText[RSMAX];
  163. struct MenuItem ParItem[PARMAX];
  164. struct IntuiText ParText[PARMAX];
  165. struct MenuItem XFItem[XFMAX];
  166. struct IntuiText XFText[XFMAX];
  167. struct MenuItem ScriptItem[SCRIPTMAX];
  168. struct IntuiText ScriptText[SCRIPTMAX];
  169. struct MenuItem UtilItem[UTILMAX];
  170. struct IntuiText UtilText[UTILMAX];
  171. struct Menu menu[MAXMENU];
  172. struct IOExtSer *Read_Request;
  173. char *rs_in;
  174. struct IOExtSer *Write_Request;
  175. char rs_out[2];
  176. struct timerequest Timer;
  177. struct MsgPort *Timer_Port = NULL;
  178. struct timerequest Script_Timer;
  179. struct MsgPort *Script_Timer_Port = NULL;
  180. struct IOAudio Audio_Request;
  181. struct MsgPort *Audio_Port = NULL;
  182. UBYTE  *BeepWave;
  183. UBYTE  Audio_AllocMap[4] = { 1, 8, 2, 4 };
  184. int x,y,curmode;
  185. int MINX    = 0;
  186. int MAXX    = 632;
  187. int MINY    = 14;
  188. int MAXY    = 198;
  189. int top        = 14;
  190. int bot        = 198;
  191. int savx    = 0;
  192. int savy    = 14;
  193. int savmode    = 0;
  194. int nlmode    = 0;
  195. int alt        = 0;
  196. int savalt    = 0;
  197. int a[2]    = { 0, 0 };
  198. int sa[2]    = { 0, 0 };
  199. int  inesc    = -1;
  200. int  inctrl    = -1;
  201. int  private    = 0;
  202. int  badseq    = 0;
  203. int  maxcol    = 79;
  204.  
  205. /*************************** defaults *******************************/
  206. int    p_baud         = 1200;        /* baud rate */
  207. int    p_screen     = 0;        /* 0 = WORKBENCH,        1 = CUSTOM */
  208. int    p_wbcolors   = 1;        /* 0 = Custom, 1 = Workbench colors */
  209. int    p_interlace  = 0;        /* 0 = no interlace,    1 = interlace */
  210. int    p_depth         = 2;        /* number of bit planes (1 or 2) */
  211. int    p_foreground = 0x840;        /* default foreground RGB color */
  212. int    p_background = 0x000;        /* default background RGB color */
  213. int    p_bold         = 0x000;        /* default BOLD       RGB color */
  214. int    p_cursor     = 0x00d;        /* default Cursor      RGB color */
  215. int    p_lines         = 24;        /* number of lines on the screen */
  216. int    p_mode         = 0;        /* 0 = image, 1 = CRLF (for kermit) */
  217. int    p_buffer     = 512;        /* read buffer size (>= 512 bytes) */
  218. int     p_parity     = 0;        /* 0=none,1=mark,2=space,3=even,4=odd */
  219. long    p_break         = 750000;        /* break time (in micro seconds) */
  220. int    p_volume     = 64;        /* beep volume (0 = DisplayBeep) */
  221. int    p_wrap         = 1;        /* 0 = truncate, 1 = wrap long lines */
  222. int    p_keyapp     = 0;        /* 0 = numeric, 1 = application keypad */
  223. int    p_curapp     = 0;        /* 0 = cursor, 1 = application cursor */
  224. int    p_echo         = 0;        /* 0 = full duplex, 1 = half duplex */
  225. int    p_bs_del     = 0;        /* 0 = normal, 1 = swap bs and delete */
  226. int    p_convert    = 0;        /* 1 = convert filenames to lower case */
  227. char    p_keyscript  = 0x7E;        /* function key script introducer = ~ */
  228. char    *p_f[10]     = {        /* function key defaults */
  229.     "\033OP","\033OQ","\033OR","\033OS",
  230.     "f5","f6","f7","f8","f9","f10" };
  231.  
  232. char    *p_F[10]     = {        /* shifted function key defaults */
  233.     "F1","F2","F3","F4","F5",
  234.     "F6","F7","F8","F9","F10"};
  235.  
  236. /* for script file */
  237. int script_on;
  238. int script_wait;
  239. int doing_init = 0;
  240.  
  241. /******************************************************/
  242. /*                   Main Program                     */
  243. /*                                                    */
  244. /*      This is the main body of the program.         */
  245. /******************************************************/
  246.  
  247. char lookahead[80];
  248. FILE *tranr = NULL;
  249. FILE *trans = NULL;
  250. int capture,send;
  251. char name[80];
  252. struct MsgPort *mySerPort;
  253.  
  254. main(argc,argv)
  255. int    argc;
  256. char    **argv;
  257.     {
  258.     ULONG class, waitmask;
  259.     unsigned int code, qual;
  260.     int KeepGoing,i,la,dola,actual;
  261.     char c,*ptr;
  262.  
  263.     ptr = InitDefaults(argc,argv);
  264.     InitDevs();
  265.     InitFileItems();
  266.     InitCommItems();
  267.     InitScriptItems();
  268.     InitUtilItems();
  269.     InitMenu();
  270.     SetMenuStrip(mywindow,&menu[0]);
  271.     PrintIText(mywindow->RPort,&MyTitle,0L,0L);
  272.  
  273.     MyDir[0]  =        '\000';
  274. #ifdef BUGFIXES
  275.     StartLock =     ((struct Process *) FindTask(NULL))->pr_CurrentDir;
  276.                     CurrentDir(DupLock(StartLock));
  277. #else
  278.     StartLock =    (struct FileLock *)((ULONG)((struct Process *)
  279.             (FindTask(NULL)))->pr_CurrentDir);
  280.     MyDirLock = (struct FileLock *)DupLock(StartLock);
  281. #endif
  282.     KeepGoing =        TRUE;
  283.     capture   =        FALSE;
  284.     send      =        FALSE;
  285.     maxcol    =        MAXX / 8;
  286.     la          =        0;
  287.     x          =        MINX ;
  288.     y          =        MINY;
  289.     curmode   =        FS_NORMAL;
  290.     script_on =     FALSE;
  291.     script_wait=    TRUE;
  292.     SetAPen(mywindow->RPort,1L);
  293.     cursorflip();
  294.     cursorflip();
  295.     emit(12);
  296.     mySerPort = Read_Request->IOSer.io_Message.mn_ReplyPort;
  297.     SendIO(Read_Request);
  298.  
  299.     /* see if we had a startup script */
  300.     if (ptr != NULL) script_start(ptr);
  301.  
  302.     reqwinup = 0;
  303.     while( KeepGoing )
  304.         {
  305.         /* wait for window message or serial port message */
  306.         cursorflip();
  307.         if(reqwinup)
  308.         waitmask = (1L << mySerPort->mp_SigBit) |
  309.                (1L << mywindow->UserPort->mp_SigBit) |
  310.                (1L << Script_Timer_Port->mp_SigBit) |
  311.                (1L << reqwindow->UserPort->mp_SigBit);
  312.         else
  313.         waitmask = (1L << mySerPort->mp_SigBit) |
  314.                (1L << mywindow->UserPort->mp_SigBit) |
  315.                (1L << Script_Timer_Port->mp_SigBit);
  316.         if (script_wait)    /* if script ready dont wait here */
  317.         Wait(waitmask);
  318.         cursorflip();
  319.  
  320.         /* do ascii file send */
  321.         if (send)
  322.         {
  323.         if ((c=getc(trans)) != EOF) {
  324.             if (c == '\n') c = '\r';
  325.             sendchar(c);
  326.             }
  327.         else {
  328.             fclose(trans);
  329.             InfoMsg1Line("File Sent");
  330.             send=FALSE;
  331.             }
  332.         }
  333.  
  334.         /* see if there are any characters from the host */
  335.         if (CheckIO(Read_Request)) {
  336.         WaitIO(Read_Request);
  337.         c = rs_in[0] & 0x7F;
  338.         doremote(c);
  339.         if (script_on) chk_script(c);
  340.         if (capture && c != 10) {
  341.             if (c == 13) c = 10;
  342.             putc(c , tranr);
  343.             }
  344.         Read_Request->IOSer.io_Command = SDCMD_QUERY;
  345.         DoIO(Read_Request);
  346.         Read_Request->IOSer.io_Command = CMD_READ;
  347.         actual = (int)Read_Request->IOSer.io_Actual;
  348.         if (actual > 0) {
  349.             if (inesc   <  0 &&
  350.             inctrl  <  0 &&
  351.             a[alt]  == 0 &&
  352.             capture == FALSE) dola = 1;
  353.             else dola = 0;
  354.             Read_Request->IOSer.io_Length =
  355.             Read_Request->IOSer.io_Actual;
  356.             DoIO(Read_Request);
  357.             Read_Request->IOSer.io_Length = 1;
  358.  
  359.             for (i = 0; i < actual; i++) {
  360.             c=rs_in[i] & 0x7f;
  361.             if (script_on) chk_script(c);
  362.  
  363.             if (dola == 1) {
  364.                 if (c >= ' ' && c <= '~' && la < 80)
  365.                 lookahead[la++] = c;
  366.                 else {
  367.                 if (la > 0) {
  368.                     emitbatch(la,lookahead);
  369.                     la = 0;
  370.                     }
  371.                 doremote(c);
  372.                 dola = 0;
  373.                 }
  374.                 }
  375.             else {
  376.                 doremote(c);
  377.                 if (inesc   <  0 &&
  378.                 inctrl  <  0 &&
  379.                 a[alt]  == 0 &&
  380.                 capture == FALSE) dola = 1;
  381.                 if (capture && c != 10) {
  382.                 if (c == 13) c = 10;
  383.                 putc(c , tranr);
  384.                 }
  385.                 }
  386.             }
  387.  
  388.             /* dump anything left in the lookahead buffer */
  389.             if (la > 0) {
  390.             emitbatch(la,lookahead);
  391.             la = 0;
  392.             }
  393.             }
  394.         SendIO(Read_Request);
  395.         }
  396.  
  397.         while((NewMessage =
  398.             (struct IntuiMessage *)GetMsg(mywindow->UserPort))
  399.             != FALSE) {
  400.         class = NewMessage->Class;
  401.         code = NewMessage->Code;
  402.         qual = NewMessage->Qualifier;
  403.         ReplyMsg( NewMessage );
  404.         switch( class )
  405.             {
  406.             case CLOSEWINDOW:
  407.             KeepGoing = FALSE;
  408.             break;
  409.  
  410.             case RAWKEY:
  411.             c = toasc(code,qual,0);
  412.             if (p_echo) doremote(c);
  413.             break;
  414.  
  415.             case NEWSIZE:
  416.             emit(12);
  417.             break;
  418.  
  419.             case MENUPICK:
  420.             handle_menupick(class,code);
  421.             break;
  422.  
  423.             default:
  424.             PrintIText(mywindow->RPort,&MyTitle,0L,0L);
  425.             break;
  426.             }   /* end of switch (class) */
  427.         }   /* end of while ( newmessage )*/
  428.  
  429.         if (!script_wait ||
  430.          (CheckIO(&Script_Timer) &&
  431.             script_wait == WAIT_TIMER))
  432.         do_script_cmd(NEXTCOMMAND);
  433.  
  434.         while( reqwinup &&  
  435.            ((NewMessage = (struct IntuiMessage *)
  436.                   GetMsg(reqwindow->UserPort)) != FALSE)
  437.          ) {
  438.         class = NewMessage->Class;
  439.         ReplyMsg( NewMessage );
  440.         switch( class ) {
  441.             case REQCLEAR:
  442.             numreqs = 0;
  443.             break;
  444.  
  445.             case CLOSEWINDOW:
  446.             KillReq(); /* Kills requester window, set reqwinup = 0 */
  447.             break;
  448.  
  449.             case NEWSIZE:
  450.             ReqNewSize(reqwindow->Height, reqwindow->Width);
  451.             break;
  452.         }   /* end of switch (class) */
  453.         } /* end while */
  454.     }  /* end while ( keepgoing ) */
  455.  
  456.     /*   It must be time to quit, so we have to clean
  457.     *   up and exit.
  458.     */
  459.  
  460.     cleanup("",0);
  461.  
  462. } /* end of main */
  463.  
  464. /* cleanup code */
  465.  
  466. cleanup(reason, fault)
  467. char *reason;
  468. int fault;
  469.     {
  470.     switch(fault) {
  471.     case 0:        /* quitting close everything */
  472.     KillReq();    /* Kill the requester and its window */
  473.     ClearMenuStrip( mywindow );
  474.     CloseDevice(&Audio_Request);
  475. #ifdef BUGFIXES
  476.         UnLock(CurrentDir(StartLock));     /* back to original directory */
  477. #else
  478.     if (MyDirLock != NULL) UnLock(MyDirLock);
  479. #endif
  480.  
  481.     case 8:        /* error opening audio */
  482.     DeletePort(Audio_Port);
  483.     FreeMem(BeepWave,BEEPSIZE);
  484.     CloseDevice(&Timer);
  485.  
  486.     case 7:        /* error opening timer */
  487.     DeletePort(Timer_Port);
  488.     CloseDevice(&Script_Timer);
  489.     DeletePort(Script_Timer_Port);
  490.  
  491.     case 6:        /* error opening write device */
  492.     DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
  493.     FreeMem(Write_Request,(long)sizeof(*Write_Request));
  494.     CloseDevice(Read_Request);
  495.  
  496.     case 5:        /* error opening read device */
  497.     DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
  498.     FreeMem(Read_Request,(long)sizeof(*Read_Request));
  499.  
  500.     case 4:        /* error opening window */
  501.     if (myfont   != NULL) CloseFont( myfont );
  502.     if (mywindow != NULL) CloseWindow( mywindow );
  503.     if (p_screen != 0) CloseScreen( myscreen );
  504.  
  505.     case 3:        /* error opening screen */
  506.     case 2:        /* error opening graphics library */
  507.     case 1:        /* error opening intuition */
  508.     default:
  509.     if (*reason) puts (reason);
  510.     }
  511.     exit(fault);
  512.     }
  513.  
  514. do_capture(file)
  515. char *file;
  516.     {
  517.     if (capture == TRUE)
  518.     {
  519.     capture=FALSE;
  520.     fclose(tranr);
  521.     InfoMsg1Line("End File Capture");
  522.     }
  523.     else
  524.     {
  525.     if (file == NULL) {
  526.         name[0] = '\000';
  527.         req("Ascii Capture:",name,1);
  528.         }
  529.     else strcpy(name, file);
  530.     if ((tranr=fopen(name,"w")) == 0) {
  531.         capture=FALSE;
  532.         InfoMsg1Line("Error Opening File");
  533.         return(FALSE);
  534.         }
  535.     capture=TRUE;
  536.     }
  537.     }
  538.  
  539. do_send(file)
  540. char *file;
  541.     {
  542.     if (send == TRUE)
  543.     {
  544.     send=FALSE;
  545.     fclose(trans);
  546.     InfoMsg1Line("File Send Cancelled");
  547.     }
  548.     else
  549.     {
  550.     if (file == NULL) {
  551.         name[0] = '\000';
  552.         req("Ascii Send:",name,1);
  553.         }
  554.     else strcpy(name, file);
  555.     if ((trans=fopen(name,"r")) == 0) {
  556.         send=FALSE;
  557.         InfoMsg1Line("Error Opening File");
  558.         return(FALSE);
  559.         }
  560.     send=TRUE;
  561.     }
  562.     }
  563.  
  564. void setparams()
  565.     {
  566.     Read_Request->IOSer.io_Command =
  567.     Write_Request->IOSer.io_Command =
  568.         SDCMD_SETPARAMS;
  569.     DoIO(Read_Request); DoIO(Write_Request);
  570.     Read_Request->IOSer.io_Command = CMD_READ;
  571.     SendIO(Read_Request);
  572.     Write_Request->IOSer.io_Command = CMD_WRITE;
  573.     }
  574.  
  575. void hangup ()
  576.     {
  577.     AbortIO(Read_Request);
  578.     CloseDevice (Read_Request);
  579.     Timer.tr_time.tv_secs=0L;
  580.     Timer.tr_time.tv_micro=750000L;
  581.     DoIO((char *) &Timer.tr_node);
  582.     OpenDevice (SERIALNAME,NULL,Read_Request,NULL);
  583.     setparams();
  584.     }
  585.  
  586. void redocomm() {
  587.     ClearMenuStrip( mywindow );         /* Remove old menu */
  588.     InitCommItems();                    /* Re-do comm menu   */
  589.     SetMenuStrip(mywindow,&menu[0]);    /* Re-display the menu */
  590.     }
  591.  
  592. void setserbaud(baud, redomenu)
  593. int baud;
  594. LONG redomenu;
  595.     {
  596.     AbortIO(Read_Request);
  597.     Write_Request->io_Baud = Read_Request->io_Baud = baud;
  598.     setparams();
  599.     p_baud = baud;
  600.     if (redomenu) redocomm();
  601.     }
  602.  
  603. void redoutil() {
  604.     ClearMenuStrip(mywindow);
  605.     InitUtilItems();
  606.     SetMenuStrip(mywindow,&menu[0]);
  607.     }
  608.  
  609. void handle_menupick(class, code)
  610. ULONG class;
  611. unsigned int code;
  612.     {
  613.     unsigned int menunum, itemnum, subnum;
  614.  
  615.     if (code == MENUNULL) return;
  616.  
  617.     menunum = MENUNUM( code );
  618.     itemnum = ITEMNUM( code );
  619.     subnum  = SUBNUM( code );
  620.     switch( menunum ) {
  621.     case 0:
  622.     switch( itemnum ) {
  623.         case 0:
  624.         do_capture(NULL);
  625.         break;
  626.  
  627.         case 1:
  628.         do_send(NULL);
  629.         break;
  630.  
  631.         case 2:
  632.         if (p_parity > 0) {
  633.         InfoMsg1Line("Parity setting prevents this");
  634.         break;
  635.         }
  636.         name[0] = '\000';
  637.         req("Xmodem Receive:",name,1);
  638.         multi_xfer(name,XMODEM_Read_File,0);
  639.         break;
  640.  
  641.         case 3:
  642.         if (p_parity > 0) {
  643.         InfoMsg1Line("Parity setting prevents this");
  644.         break;
  645.         }
  646.         name[0] = '\000';
  647.         req("Xmodem Send:",name,1);
  648.         multi_xfer(name,XMODEM_Send_File,1);
  649.         break;
  650.  
  651.         case 4:
  652.         server = TRUE;
  653.         name[0] = '\000';
  654.         req("Kermit GET remote file(s):",name,1);
  655.         multi_xfer(name,dokreceive,0);
  656.         break;
  657.  
  658.         case 5:
  659.         multi_xfer("",dokreceive,0);
  660.         break;
  661.  
  662.         case 6:
  663.         server = TRUE;
  664.         name[0] = '\000';
  665.         req("Kermit Send local name:",name,1);
  666.         multi_xfer(name,doksend,1);
  667.         break;
  668.  
  669.         case 7:
  670.         saybye();
  671.         break;
  672.         }
  673.     break;
  674.  
  675.     case 1:
  676.     switch( itemnum ) {
  677.         case 0:
  678.         switch( subnum ) {
  679.         case 0:
  680.         setserbaud(300, FALSE);
  681.         break;
  682.  
  683.         case 1:
  684.         setserbaud(1200, FALSE);
  685.         break;
  686.  
  687.         case 2:
  688.         setserbaud(2400, FALSE);
  689.         break;
  690.  
  691.         case 3:
  692.         setserbaud(4800, FALSE);
  693.         break;
  694.  
  695.         case 4:
  696.         setserbaud(9600, FALSE);
  697.         break;
  698.         }
  699.         break;
  700.  
  701.         case 1:
  702.         /* Set  Parity */
  703.         p_parity = subnum;
  704.         break;
  705.  
  706.         case 2:
  707.         /* set transfer mode */
  708.         if (subnum < 2) p_mode = subnum;
  709.         else {
  710.         if (p_convert)    p_convert = 0;
  711.         else        p_convert = 1;
  712.         redocomm();
  713.         }
  714.         break;
  715.         }
  716.     break;
  717.  
  718.     case 2:
  719.     if (!itemnum && !script_on) {
  720.         name[0] = '\000';
  721.         req("Script file name:",name,1);
  722.         script_start(name);
  723.         }
  724.     if (itemnum && script_on) exit_script();
  725.     break;
  726.  
  727.     case 3:
  728.     switch( itemnum ) {
  729.         case 0:
  730.         sendbreak();
  731.         break;
  732.  
  733.         case 1:
  734.         hangup();
  735.         break;
  736.  
  737.         case 2:
  738.         strcpy(name,MyDir);
  739.         req("Directory:",name,1);
  740.         set_dir(name);
  741.         break;
  742.  
  743.         case 3:
  744.         top = MINY; bot = MAXY; savx = MINX; savy = MINY;
  745.         curmode = FS_NORMAL; inesc = -1;
  746.         a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
  747.         redoutil();
  748.         emit(12);
  749.         break;
  750.  
  751.         case 4:
  752.         if (p_echo) p_echo = 0;
  753.         else    p_echo = 1;
  754.         redoutil();
  755.         break;
  756.  
  757.         case 5:
  758.         if (p_wrap) p_wrap = 0;
  759.         else        p_wrap = 1;
  760.         redoutil();
  761.         break;
  762.  
  763.         case 6:
  764.         if (p_keyapp) p_keyapp = 0;
  765.         else          p_keyapp = 1;
  766.         redoutil();
  767.         break;
  768.  
  769.         case 7:
  770.         if (p_curapp) p_curapp = 0;
  771.         else          p_curapp = 1;
  772.         redoutil();
  773.         break;
  774.  
  775.         case 8:
  776.         swap_bs_del();
  777.         redoutil();
  778.         break;
  779.         }
  780.  
  781.     break;
  782.     } /* end of switch ( menunum ) */
  783.     }
  784.  
  785.