home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 11 / 11.iso / n / n002 / 4.ddi / DEMOS.ZIP / RESETERM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-16  |  28.5 KB  |  861 lines

  1. #include "tsr.h"
  2. unsigned int r_hello = 0x7273;
  3.  
  4. /* scan code for H key used with Alt here */
  5. #define SCAN_E 18
  6.  
  7. /* window save buffers declared globally */ 
  8. unsigned char  scrnbuf[4000];       /* for interrupted screen  */
  9. unsigned char  etermbuf[4000];    /* for eterm screen        */
  10.  
  11. /* save eterm cursor position here, restore it when popping up */
  12. int saverow, savecol;
  13. /* get xmodem statistics here */
  14. int acked,naked,timed,junked;
  15.  
  16.  
  17. #include    "im.h"                  /* Intelligent modem services */
  18. #include    "xm.h"                  /* XMODEM services */
  19. #include    "xc.h"                  /* Communications services */
  20. #include    <stdio.h>               /* Standard terminal stuff */
  21.  
  22. /*  Keyboard definitions   */
  23.  
  24. #define FK1         0x3B00          /* Function key 1 */
  25. #define FK2         0x3C00          /* Function key 2 */
  26. #define FK3         0x3D00          /* Function key 3 */
  27. #define FK4         0x3E00          /* Function key 4 */
  28. #define FK5         0x3F00          /* Function key 5 */
  29. #define FK6         0x4000          /* Function key 6 */
  30. #define RUB1        0x08            /* Rubout */
  31. #define RUB2        0x7F            /* Rubout */
  32. #define RET         0x0D            /* CR */
  33.  
  34. /*  Dirty definitions */
  35.  
  36. #define CLEAN       0               /* <dirty> no cleanup necessary */
  37. #define CLRSCREEN   1               /* <dirty> clear screen */
  38. #define CLRSTATUS   2               /* <dirty> clear status part only */
  39.  
  40. /*  Miscellaneous  */
  41.  
  42. #define MIN_BUFFERS  8              /* Minimum buffers required */
  43. #define SCROLL       1              /* Scroll flag value */
  44. #define CLEARS       0              /* Clear the screen value */
  45. #define MAXFIELD    79              /* Maximum field */
  46. #define STATUSROW   24              /* Row address of status row */
  47. #define SCRWIDTH    79              /* Last column */
  48. #define STATCOLUMN  57              /* Starting column of rightmost status */
  49. #define STATWIDTH   22              /* Width of the rightmost status */
  50.  
  51. /*  Field indices (into the <text> array structure) */
  52.  
  53. #define INTRO1      0               /* <text> structure entry */
  54. #define INTRO2      1
  55. #define INTRO3      2
  56. #define DATA_FILE   3
  57. #define ONLINEMSG   4
  58. #define DATA_DEFAUL 5
  59. #define MAIN_F1     6
  60. #define MAIN_F2     7
  61. #define MAIN_F3     8
  62. #define MAIN_F5     9
  63. #define DUMMY       10
  64. #define NOCONN      11
  65. #define CONN        12
  66. #define DIALING     13
  67. #define INITMODEM   14
  68. #define HANGUP      15
  69. #define XUPLOAD     16
  70. #define XDOWNLOAD   17
  71. #define XEXIT       18
  72.  
  73. #define XMODEM      19
  74. #define SESSION     20
  75. #define FAILED      21
  76. #define CANCELLD    22
  77. #define USERABORT   23
  78. #define FILEOPEN    24
  79. #define FILEIO      25
  80. #define GETUPLOAD   26
  81. #define GETDOWNLOAD 27
  82.  
  83. #define COMPORT     28
  84. #define COMBAUD     37
  85. #define COMPARITY   47
  86. #define COMDATA     50
  87. #define COMSTOP     52
  88.  
  89. #define COM_HELP    54
  90. #define COM_ACCEPT  55
  91. #define COM_ABORT   56
  92. #define COM_ACP     57
  93. #define XMODEM_STD  58
  94. #define XMODME_CRC  59
  95. #define XMODME_1K   60
  96. #define XMODEM_EXIT 61
  97. #define MAIN_F6      62
  98. #define NULL_STR    63                  /* The last one */
  99.  
  100. extern  long xc_test();
  101.  
  102. /*
  103.     === constants ========================================================
  104. */
  105.  
  106. char    config_file[]=  "ETERM.DAT";
  107.  
  108. struct {
  109.     int row;                            /* Row coordinate */
  110.     int col;                            /* Column coordinate */
  111.     int wid;                            /* Width */
  112.     char *str;                          /* Character string */
  113. } text[] = {
  114.     { 5, 9, 0, "Essential Terminal Emulator"},                        /* INTRO1 */
  115.     { 7, 9, 0, "Copyright (C) 1987, 1988, 1991 Essential Software Incorporated"}, /* INTRO2 */
  116.     { 9, 9, 0, "Revision 4.0"},
  117.  
  118.     { STATUSROW, STATCOLUMN, STATWIDTH, "Using ETERM.DAT setup" },
  119.     { STATUSROW, STATCOLUMN, STATWIDTH, "TTY emulation" },
  120.     { STATUSROW, STATCOLUMN, STATWIDTH, "Default setup" },
  121.  
  122.     { STATUSROW,  0, 11, "[F1] XMODEM" },
  123.     { STATUSROW, 12, 10, "[F2] Setup" },
  124.     { STATUSROW, 23, 12, "[F3] Refresh" },
  125.     { STATUSROW, 36,  9, "[F5] Exit" },
  126.     { STATUSROW, STATCOLUMN - 2, 1, "\360" },
  127.     { STATUSROW, STATCOLUMN, STATWIDTH, "No connection" },
  128.     { STATUSROW, STATCOLUMN, STATWIDTH, "Connected!" },
  129.     { STATUSROW, STATCOLUMN, STATWIDTH, "Dialing ..." },
  130.     { STATUSROW, STATCOLUMN, STATWIDTH, "Setup modem ..." },
  131.     { STATUSROW, STATCOLUMN, STATWIDTH, "Hanging up ..." },
  132.  
  133.     { STATUSROW, 0 , 11, "[F1] Upload" },
  134.     { STATUSROW, 13, 13, "[F2] Download" },
  135.     { STATUSROW, 27, 17, "[F6] Exit" },
  136.  
  137.     { STATUSROW, STATCOLUMN, STATWIDTH, "XMODEM successful" },
  138.     { STATUSROW, STATCOLUMN, STATWIDTH, "Session error" },
  139.     { STATUSROW, STATCOLUMN, STATWIDTH, "XMODEM failed" },
  140.     { STATUSROW, STATCOLUMN, STATWIDTH, "XMODEM cancelled" },
  141.     { STATUSROW, STATCOLUMN, STATWIDTH, "User aborted" },
  142.     { STATUSROW, STATCOLUMN, STATWIDTH, "File open error" },
  143.     { STATUSROW, STATCOLUMN, STATWIDTH, "File I/O error" },
  144.     { STATUSROW, 0, STATCOLUMN - 1, "Upload filename: " },
  145.     { STATUSROW, 0, STATCOLUMN - 1, "Download filename: " },
  146.  
  147.     { STATUSROW, 0, 9, "[F1] COM1" },
  148.     { STATUSROW, 0, 9, "[F1] COM2" },
  149.     { STATUSROW, 0, 9, "[F1] COM3" },
  150.     { STATUSROW, 0, 9, "[F1] COM4" },
  151.     { STATUSROW, 0, 9, "[F1] COM5" },
  152.     { STATUSROW, 0, 9, "[F1] COM6" },
  153.     { STATUSROW, 0, 9, "[F1] COM7" },
  154.     { STATUSROW, 0, 9, "[F1] COM8" },
  155.     { STATUSROW, 0, 9, "[F1] COM9" },
  156.  
  157.     { STATUSROW, 10,  9, "[F2] 110 " },
  158.     { STATUSROW, 10,  9, "[F2] 150 " },
  159.     { STATUSROW, 10,  9, "[F2] 300 " },
  160.     { STATUSROW, 10,  9, "[F2] 600 " },
  161.     { STATUSROW, 10,  9, "[F2] 1200" },
  162.     { STATUSROW, 10,  9, "[F2] 2400" },
  163.     { STATUSROW, 10,  9, "[F2] 4800" },
  164.     { STATUSROW, 10,  9, "[F2] 9600" },
  165.     { STATUSROW, 10,  9, "[F2] 19K " },
  166.     { STATUSROW, 10,  9, "[F2] 38K " },
  167.  
  168.     { STATUSROW, 20, 12, "[F3] NO PAR" },
  169.     { STATUSROW, 20, 12, "[F3] ODD PAR" },
  170.     { STATUSROW, 20, 12, "[F3] EVN PAR" },
  171.  
  172.     { STATUSROW, 33, 11, "[F4] 7 DATA" },
  173.     { STATUSROW, 33, 11, "[F4] 8 DATA" },
  174.  
  175.     { STATUSROW, 45, 11, "[F5] 1 STOP" },
  176.     { STATUSROW, 45, 11, "[F5] 2 STOP" },
  177.     
  178.     { STATUSROW, STATCOLUMN, STATWIDTH, "\021\304\304\331 or F6" },
  179.     { STATUSROW, STATCOLUMN, STATWIDTH, "Setup accepted" },
  180.     { STATUSROW, STATCOLUMN, STATWIDTH, "Setup cancelled" },
  181.     { STATUSROW, STATCOLUMN, STATWIDTH, "Accepted, reload ETERM" },
  182.  
  183.     { STATUSROW,  0, 11, "[F1] XMODEM" },
  184.     { STATUSROW, 12, 15, "[F2] XMODEM/CRC" },
  185.     { STATUSROW, 28, 14, "[F3] XMODEM-1K" },
  186.     { STATUSROW, 43, 17, "[F6] Exit" },
  187.  
  188.     { STATUSROW, 46, 9, "[F6] QUIT" },
  189.     { STATUSROW, 0, SCRWIDTH, "" },
  190.     { 0, 0, 0, "" }
  191. };
  192. /*
  193.     ======================================================================
  194. */
  195. /*
  196.     === global data base =================================================
  197.  
  198.     ETERM.DAT   Configuration data base format:
  199. */
  200.  
  201. int Port = COM1;                    /* Default communications port */
  202. int Baud = BAUD1200;                /* Default baud rate */
  203. int Parity = NOPAR;                 /* Default parity */
  204. int Data = DATA8;                   /* Default data bit size */
  205. int Stopbits = STOP1;                   /* Default stop bit */
  206. int attr_status = 0x70;             /* Default attribute */
  207. int attr_text   = 0x07;             /* Text window (emulator) attribute */
  208. int max_ports;                      /* Maximum supported ports - rev 2.0 */
  209. int in_xmodem = 0;
  210.  
  211. int dirty = CLRSCREEN;              /* Clear screen initially */
  212.  
  213.  
  214. #define            FILE_ERR    0
  215.  
  216.    FILE *fp;
  217.    int hit_count=0;
  218.    int fatal_error=0;
  219.  
  220.  
  221. char xmodeminfo[] = "";
  222. /***  "Blocks transferred [%d]  refused [%d]  timeouts [%d]  garbled [%d]";***/
  223.  
  224.  
  225. static int firsttime = 1;
  226. extern unsigned _hotkey_hit;    /* variable TRUE when Alt-E was hit */
  227. static int xm_status;
  228. int status = 2;                 /* Index into status messages */
  229.  
  230. main(argc, argv)
  231. int argc;                           /* Argument count */
  232. char *argv[];                       /* Argument variables */
  233. {
  234. int resprog();    
  235. int rc;
  236.  
  237. /***  inittsr2() is a resident_C function to create a TSR.     ***/
  238. /***  tsrloaded() is also a resident_C function to see if we   ***/
  239. /***  are loaded already.                                      ***/
  240. /***  See the resident_C user manual for more details.         ***/
  241.  
  242. int key;                        /* Scan code and ASCII key */
  243. if (!tsrloaded(r_hello)) 
  244.       {
  245.  
  246. /***  Go through the initialization code the first time into the   ***/
  247. /***  program.  You could have other initializions done here too. ***/
  248.  
  249.      rc =xc_entr(MIN_BUFFERS);
  250.       if(rc == 0){                   /* Enough buffers are available */
  251.          scrtomem(2000,0,scrnbuf);      /* save DOS screen before initializing */
  252.           savcur();                            /* save cursor position */
  253.         xm_status = 0;              /* Assume all is OK */
  254.         max_ports = xc_gport();     /* Return the maximum number of ports */
  255.         eterm_init();
  256.         main_menu(CLRSTATUS);
  257. /*        xck_link();   */       /* Enable Ctrl-Break processing */
  258.                                  /* Not a good idea for a TSR    */
  259.  
  260. /*  *** Optionally, dial the modem ***  */
  261. /*  The modem dialing code was commented because it did not        */
  262. /*  seem to fit a resident emulator example too well.              */
  263. /*  Perhaps a dialing menu once popped up would be a better idea.  */
  264. /***********
  265.         if (argc >1) {
  266.             dfield(INITMODEM);
  267.             im_fopen(Port);
  268.             dfield(DIALING);
  269.             if (im_dial(Port, argv[1]) < IM_OK)  
  270.                 dfield(NOCONN);
  271.             else    
  272.                 dfield(CONN);
  273.         }
  274. ***********/
  275.         xct_link();
  276.         xct_pend(20);
  277.         wclear();
  278.         xct_unlk();
  279.           _hotkey_hit = 1;                /* run resprog before going resident */
  280.           resprog();
  281.           firsttime = 0;                   /* so we know its not first time later */
  282.           _hotkey_hit = 0;                /* reset kotkey for resprog         */
  283.      }
  284.  
  285.        if ((rc = inittsr2(ALT_KEY, SCAN_E, resprog,
  286.             1024, r_hello, SIG,(void far *)NULL)) != 0)
  287.          { 
  288.           printf("Could Not Load. Error = %d \n",rc); 
  289.           exit(1); 
  290.          } 
  291.  }
  292.  else
  293.         printf(" already loaded\n");
  294.  
  295. /****   Could simulate inittsr2() without going resident with ****/
  296. /****   while loop below.                                     ****/
  297. /*
  298.    while(1){
  299.       rc = resprog();
  300.    }
  301. */
  302. }
  303.  
  304. /*** resprog will get control on timer tick or when Alt-E is hit ***/
  305. /*** and also gets control once before going resident.           ***/
  306.  
  307. resprog(argv,argc)
  308. int argc;
  309. char *argv[];                       /* Argument variables */
  310. {
  311.  
  312. int key;                        /* Scan code and ASCII key */
  313. int rc;
  314. int temprow,tempcol;
  315.  
  316. /***  If we are in an xmodem transfer, we get to the xmodem code  ***/
  317. /***  right away.  We do this because we do not want the xmodem   ***/
  318. /***  transfer to timeout and we are probably not interested in   ***/
  319. /***  doing anything else while the xmodem is taking place.       ***/
  320. /***  However, if the hotkey is hit, we will pop-up.              ***/
  321.  
  322.     if(in_xmodem && (!_hotkey_hit)){
  323.           xm_status = xmodem();
  324.           if(xm_status < 0 || xm_status == XM_COMPL){
  325.             in_xmodem = 0;
  326.                 putch(7);putch(7);    /* ring bell twice when xmodem done   */
  327.                                             /* could also force a pop-up or put   */
  328.                                             /* a message in a window or something */
  329.           }
  330. /*******
  331.     You might want to add some other checks here. For example, if the
  332.     user hit the hotkey, you might want to ask if he wants to abort
  333.    the xmodem session.  To abort the session is difficult now - unless
  334.    you just timeout or drop the connection.  If you do need to abort,
  335.    take a look at the code for xmk_putf() in xmk.c.  xmk_putf() uses
  336.    xmk_bputf() and allows for aborting by using Ctrl-Break.  You would
  337.    probably want to modify the abort logic in xmk.c to use something
  338.    other than Ctrl-Break in a resident (or background) program.
  339.  
  340.     In this example, we assume the xmodem session is the only
  341.     priority until it is done or it fails so we return.
  342.  
  343. *******/
  344.           return(xm_status);   /* we return status for simulation of TSR */
  345.     }                                 /* in main above. status has no meaning   */
  346.                               /* once the program is TSR.               */
  347.  
  348.  
  349.     if(!_hotkey_hit){    /* If hotkey has not been hit, we don't pop up */
  350.         return;
  351.    }
  352.    else
  353.      if (!firsttime){
  354.         _hotkey_hit = 0;                /* reset hotkey flag                        */
  355.         scrtomem(2000,0,scrnbuf);  /* resident_C function saves screen */
  356.         memtoscr(2000,0,etermbuf); /* res_C function to restore screen */
  357.       savcur();                        /* resident_C function saves cursor */
  358.     }
  359.  
  360.     xm_status = 0;
  361.     xcv_scur(saverow,savecol);
  362.         while (xm_status == 0) {  
  363.                 if(in_xmodem){            /* want to keep xmodem moving */
  364.                   xm_status = xmodem();
  365.                   if(xm_status < 0 || xm_status == XM_COMPL){
  366.                         in_xmodem = 0;
  367.                             putch(7);putch(7);    /* ring bell twice when done   */
  368.                      }else{
  369.                             xmk_stat(Port,&acked,&naked,&timed,&junked);
  370.                             xcv_gcur(&temprow,&tempcol);
  371.                             xcv_scur(23,0);
  372.                             printf("blocks completed [%4d]",acked);
  373.                             xcv_scur(temprow,tempcol);
  374.                      }
  375.                             
  376.                 }
  377.             if (xck_keyt()) {
  378.                 switch (key = xck_getc()) {
  379.                 case FK1:               /* XMODEM */
  380.                     if(!in_xmodem)
  381.                             xmodem();
  382.                     main_menu(CLRSTATUS);
  383.                           break;                                /* also not needed   */
  384.                 case FK2:               /* Setup */
  385.                     if(!in_xmodem)
  386.                                 config();
  387.                     main_menu(CLRSTATUS);
  388.                     break;
  389.                 case FK3:               /* Refresh */
  390.                     wclear();
  391.                     break;
  392.                     case FK5:
  393.                            xm_status = 99;
  394.                            break;
  395.                 case FK6:        /* replace ctrl-break below */
  396.                            xm_status = 98;
  397.                         break;
  398.                 default:                /* Send key out to the comm port */
  399.                         xc_putc(Port, (char) key);
  400.                 }
  401.             }
  402.             if (xc_test(Port) && !in_xmodem)  /* Display the incoming character */
  403.                 echo(xc_getc(Port));
  404.         }
  405.  
  406.      if(xm_status == 98 & !firsttime){     /* Was F6 hit  */
  407.         wclear();                   /* Clear the entire thing */
  408.         sclear(SCRWIDTH);
  409.         xc_dtr(Port, 0);
  410.         xc_rts(Port, 0);
  411.         xc_exit();                  /* Turn off interrupts (everything) */
  412.         fclose(fp);
  413.           xcv_gcur(&saverow,&savecol);  /* save eterm cursor */
  414.             rstcur();                            /* restore interrupted program cursor */
  415.             memtoscr(2000,0,scrnbuf);    /* restore interrupted screen */
  416.          if( freetsr()){                    /* remove TSR from memory     */
  417.                 printf("Couldn't free!!!!!!!!!!!!!\n");
  418.             printf("hit any key to continue.\n");
  419.             xck_getc();
  420.         }
  421.         exit();
  422.      }else{                                    /* must be F5 or F1 */
  423.           scrtomem(2000,0,etermbuf);    /* save eterm screen */
  424.           xcv_gcur(&saverow,&savecol);  /* save eterm cursor */
  425.           rstcur();                            /* restore interrupted program cursor */
  426.           memtoscr(2000,0,scrnbuf);    /* restore interrupted screen */
  427.           return;
  428.       }
  429. }
  430.  
  431.  
  432. /*
  433.     === support functions (in order of appearance) ======================
  434.  
  435.     is_break    Check for Ctrl-Break
  436.     eterm_init  Initialize the screen display, optionally read in
  437.                 the ETERM.DAT configuration file
  438.     main_menu   Display main menu
  439.     donline     Display on-line message
  440.     window      Perform a window scroll up or clear for an entire line
  441.                 or lines given the attribute
  442.     dfield      Display field on the bottom line using the 
  443.                 attr_status attribute
  444.     echo        Echo the character on screen and optionally scroll
  445.     sclear      Status line clear up to specified column
  446.     wclear      Window text screen clear
  447.     config      Process the configuration options and save 
  448.     xmodem      Transfer XMODEM files up or down
  449.     getinput    A simple in-line response reader function
  450.  
  451.     ======================================================================
  452. */  
  453.  
  454. int is_break()  /* Test for the presence of a Ctrl-Break abort */
  455. {
  456.     int status;
  457.     return(0);
  458.  
  459.     if (status = xck_test()) {
  460.         while (xck_keyt())
  461.             xck_getc();
  462.     }
  463.     return(status);
  464. }
  465.  
  466.  
  467. /*
  468.     eterm_init - Initialize the screen display, optionally read in
  469.                  the ETERM.DAT configuration file
  470.  
  471. */
  472.  
  473.  
  474. int eterm_init()    /* Load in the default ETERM data configuration file */
  475. {
  476.     FILE *Stream;
  477.     int setup_message;
  478.                                     /* Clear both window areas */
  479.     if ((Stream = fopen(config_file, "r")) != NULL) {
  480.         setup_message = DATA_FILE;
  481.         fread(&Port, sizeof(Port), 1, Stream);
  482.         fread(&Baud, sizeof(Baud), 1, Stream);
  483.         fread(&Parity, sizeof(Parity), 1, Stream);
  484.         fread(&Data, sizeof(Data), 1, Stream);
  485.         fread(&Stopbits, sizeof(Stopbits), 1, Stream);
  486.         fread(&attr_status, sizeof(attr_status), 1, Stream);
  487.         fread(&attr_text, sizeof(attr_text), 1, Stream);
  488.         
  489.         fclose(Stream);
  490.     } else {
  491.         setup_message = DATA_DEFAUL;
  492.     }
  493.     sclear(SCRWIDTH);
  494.     wclear();
  495.     dfield(setup_message);
  496.  
  497.     xcv_scur(text[INTRO1].row, text[INTRO1].col);
  498.     puts(text[INTRO1].str);
  499.     xcv_scur(text[INTRO2].row, text[INTRO2].col);
  500.     puts(text[INTRO2].str);
  501.     xcv_scur(text[INTRO3].row, text[INTRO3].col);
  502.     puts(text[INTRO3].str);
  503.     xcv_scur(0, 0);                 /* Home the cursor */
  504.  
  505.     main_menu(CLRSCREEN);           /* On-line message with function keys */
  506.     xc_link(Port, 0);               /* *** Rev 1.2 Used to be 1 instead of 0 */
  507.     xc_dtr(Port, 1);                /* *** Rev 1.2 New *** */
  508.     xc_rts(Port, 1);                /* *** Rev 1.2 New *** */
  509.     xc_init(Port, Baud, Parity, Data, Stopbits);
  510.     return(0);                      /* Always successful! */
  511. }
  512.  
  513. /*  Display the main_menu options except for the status field (at the right).
  514.     The dirty flag is passed and determines what to do when a character is
  515.     either received or typed.
  516. */
  517. int main_menu(dirty_flag)
  518. {
  519.     sclear(STATCOLUMN - 1); 
  520.     dfield(MAIN_F1);
  521.     dfield(MAIN_F2);
  522.     dfield(MAIN_F3);
  523.     dfield(MAIN_F5);
  524.     dfield(MAIN_F6);
  525.     dirty = dirty_flag;
  526.     return(0);                      /* Always successful! */
  527. }
  528.  
  529.  
  530. int donline()  /* donline - display on-line status message */
  531. {
  532.     dfield(ONLINEMSG);
  533.     return(0);                      /* Always successful! */
  534. }
  535.  
  536.  
  537. /*
  538.     window - perform a window scroll up or clear for an entire line
  539.              or lines given the attribute
  540.  
  541.              To clear the bottom line, do this:
  542.                 window(24, 1, SCRWIDTH, '\007', CLEARS);
  543.              To scroll the upper 24 lines, do this:
  544.                 window(0, 24, SCRWIDTH, '\007', SCROLL);
  545.  
  546.              The cursor address does NOT change!
  547.  
  548. */
  549. int window(row, row_count, column, attribute, flag)
  550. int row;                            /* Row address starting at 0 */
  551. int row_count;                      /* Number of rows to scroll or clear */
  552. int column;                         /* Last column number */
  553. char attribute;                     /* Attribute for the window */
  554. int flag;                           /* SCROLL or CLEARS flag */
  555. {
  556.     xcv_scrl(row, 0, row + row_count - 1, column, attribute, flag);    
  557.     return(0);                      /* Always succeeds! */
  558. }
  559.  
  560. /*
  561.     dfield - display field on the bottom line using the 
  562.              attr_status attribute
  563.  
  564.              To display "F2 Download" at column 16 in a 20 column width
  565.              pass a <text> structure array index that points to the
  566.              entry:
  567.  
  568.  
  569.             struct {
  570.                 int row;
  571.                 int col;
  572.                 int wid;
  573.                 char *str;
  574.             } text[] = {
  575.                     . . .
  576.                 { STATUSROW, 0, STATCOLUMN - 1, "Download filename: " },
  577.                     . . .
  578.  
  579.                 dfield(XDOWNLOAD);
  580.  
  581.              The cursor is not moved
  582.  
  583. */
  584. int dfield(index)
  585. int index;                          /* Index into text array */
  586. {
  587.     char _string[MAXFIELD];         /* Maximum string field width */
  588.     int i;                          /* Counter variable */
  589.     int width = text[index].wid;    /* Maximum LEGAL field width */
  590.     int column = text[index].col;   /* Number of columns */
  591.     char *string = text[index].str;
  592.     int oldrow, oldcol;             /* Old cursor address */
  593.  
  594.     if (width > MAXFIELD)
  595.         width = MAXFIELD;           /* Specified field is too big */
  596.                                     /* Create the fixed field */
  597.     for (i = 0; (_string[i] = *string++); ++i)
  598.         ;
  599.     for (; (i < width); ++i)
  600.         _string[i] = ' ';
  601.     xcv_gcur(&oldrow, &oldcol);     /* Save the cursor location */
  602.     
  603.                                     /* Write out the field */
  604.     for (i = 0; (i < width); ++i) {
  605.         xcv_scur(STATUSROW, column + i);
  606.         xcv_chat(_string[i], attr_status);    
  607.     }
  608.     xcv_scur(oldrow, oldcol);       /* Restore the cursor */
  609.     return(0);                      /* Always succeeds! */
  610. }
  611.  
  612. int echo(ch)    /* Display a character and optionally scroll up one line */
  613. char ch;
  614. {
  615.     int oldrow, oldcol;
  616.     xcv_wtty(ch);
  617.     xcv_gcur(&oldrow, &oldcol);
  618.     if (oldrow == STATUSROW) {
  619.         window(0, STATUSROW, SCRWIDTH, attr_text, SCROLL);
  620.         xcv_scur(oldrow - 1, oldcol);
  621.     }
  622.     return(0);                      /* Always succeeds! */
  623. }
  624.  
  625. int sclear(column)                  /* Clear status line */
  626. int column;                         /* Last column */
  627. {
  628.     window(STATUSROW, 1, column, attr_text, CLEARS);
  629.  
  630. }
  631.  
  632. int wclear()                        /* Clear window text area */
  633. {
  634.     xcv_scur(0, 0);                 /* Home cursor */
  635.     window(0, STATUSROW, SCRWIDTH, attr_text, CLEARS);
  636. }
  637.  
  638. int config()        /* Configure the comm port attributes onto disk file */
  639. {
  640.     int message = 0;
  641.     int ch;
  642.     FILE *Stream;
  643.     int old_port = Port;            /* Save the old port */
  644.  
  645.     sclear(STATCOLUMN - 1);
  646.     dfield(COM_HELP);
  647.  
  648.     while (message == 0) {
  649.     dfield(COMPORT + Port);
  650.     dfield(COMBAUD + Baud);
  651.     dfield(COMPARITY + Parity);
  652.     dfield(COMDATA + Data);
  653.     dfield(COMSTOP + Stopbits);
  654.     switch (ch = xck_getc()) {
  655.     case FK1:
  656.         if (++Port == max_ports)
  657.             Port = 0;
  658.         break;
  659.     case FK2:
  660.         if (++Baud > BAUD38400)
  661.             Baud = 0;
  662.         break;
  663.     case FK3:
  664.         if (++Parity > 2)
  665.             Parity = 0;
  666.         break;
  667.     case FK4:
  668.         if (++Data > 1)
  669.             Data = 0;
  670.         break;
  671.     case FK5:
  672.         if (++Stopbits > 1)
  673.             Stopbits = 0;
  674.         break;
  675.     default:
  676.         if (ch == FK6) 
  677.             message = COM_ABORT;
  678.         if ((ch & 0xFF) == RET) {
  679.             Stream = fopen(config_file, "w");
  680.             fwrite(&Port, sizeof(Port), 1, Stream);
  681.             fwrite(&Baud, sizeof(Baud), 1, Stream);
  682.             fwrite(&Parity, sizeof(Parity), 1, Stream);
  683.             fwrite(&Data, sizeof(Data), 1, Stream);
  684.             fwrite(&Stopbits, sizeof(Stopbits), 1, Stream);
  685.             fwrite(&attr_status, sizeof(attr_status), 1, Stream);
  686.             fwrite(&attr_text, sizeof(attr_text), 1, Stream);
  687.             fclose(Stream);
  688.             if (old_port == Port) {
  689.                 xc_init(Port, Baud, Parity, Data, Stopbits);
  690.                 message = COM_ACCEPT;
  691.             } else {
  692.                 message = COM_ACP;
  693.                 Port = old_port;
  694.             }
  695.         }
  696.         break;
  697.     }               /* End of character switch */
  698.     }               /* End of while loop */
  699.     dfield(message);
  700.     return(0);
  701. }
  702.  
  703. int xmodem()    /* Perform XMODEM upload or download */
  704. {
  705. int keyin;
  706. static    int exitflag = 2;
  707. int row, column;
  708. char answer[33];
  709. static  int transfer;
  710. int trans_status;
  711. /*  Ask the user to either upload or download */
  712.   
  713.     if(!in_xmodem){
  714.     exitflag = 2;
  715.     transfer = -1;
  716.     sclear(STATCOLUMN - 1);
  717.     dfield(XUPLOAD);
  718.     dfield(XDOWNLOAD);
  719.     dfield(XEXIT);
  720.         while (exitflag == 2) {
  721.             switch ((keyin = xck_getc())) {
  722.             case FK1:                           /* Upload */
  723.                 exitflag = 0;
  724.                 break;
  725.             case FK2:                           /* Download */
  726.                 exitflag = 1;
  727.                 break;
  728.             default:                            /* Exit abnormally */
  729.                 if (keyin == FK6)
  730.                     exitflag = -1;
  731.             }
  732.         }
  733.     if (exitflag == -1)
  734.         dfield(USERABORT);
  735.         else {
  736.         sclear(SCRWIDTH);
  737.         if (exitflag == 0)
  738.             dfield(GETUPLOAD);
  739.         else
  740.             dfield(GETDOWNLOAD);
  741.         xcv_gcur(&row,&column);
  742.         xcv_scur(STATUSROW,20);
  743.   
  744.             if (getinput(answer) <= 0) {
  745.             dfield(XMODEM + 4);
  746.             } else {
  747.             /* *********** REV 2.0 ask the type of XMODEM transfer ********* */
  748.             sclear(STATCOLUMN - 1);
  749.             dfield(XMODEM_STD);
  750.             dfield(XMODME_CRC);
  751.             dfield(XMODME_1K);
  752.             dfield(XMODEM_EXIT);
  753.                 switch (xck_getc()) {
  754.                 case FK1:                           /* Standard */
  755.                     transfer = 0;
  756.                     break;
  757.                 case FK2:                           /* CRC option*/
  758.                     transfer = 1;
  759.                     break;
  760.                 case FK3:                           /* 1K option*/
  761.                     transfer = 2;
  762.                     break;
  763.                 case FK6:                           /* 1K option*/
  764.                     exitflag = -1;
  765.                     dfield(USERABORT);
  766.                     break;
  767.                 default:                            /* Exit abnormally */
  768.                     exitflag = -1;
  769.                     dfield(USERABORT);
  770.                     break;
  771.                 }
  772.              /* ******************************************************** */
  773.             xcv_scur(row,column);
  774.   
  775.                 if (exitflag == -1) {
  776.                 dfield(NULL_STR);
  777.                 return(-1);
  778.                 }
  779.             }
  780.         }
  781.     }
  782.         if (exitflag == 0)  {                /* Execute upload/download */
  783.             switch (transfer) {
  784.             case 0:
  785.                 trans_status = xmk_bputf(Port, answer,  XMODEM_128, XMODEM_XSUM,1);
  786.                 in_xmodem = 1;
  787.                 break;
  788.             case 1:
  789.                 trans_status = xmk_bputf(Port, answer,  XMODEM_128, XMODEM_CRC,1);
  790.                 in_xmodem = 1;
  791.                 break;
  792.             case 2:
  793.                 trans_status = xmk_bputf(Port, answer,  XMODEM_1K, XMODEM_CRC,1);
  794.                 in_xmodem = 1;
  795.                 break;
  796.             }
  797.         } else {
  798.             switch (transfer) {
  799.             case 0:
  800.                 trans_status = xmk_bgetf(Port, answer,  XMODEM_128, XMODEM_XSUM,1);
  801.                 in_xmodem = 1;
  802.                 break;
  803.             case 1:
  804.                 trans_status = xmk_bgetf(Port, answer,  XMODEM_128, XMODEM_CRC,1);
  805.                    in_xmodem = 1;
  806.                 break;
  807.             case 2:
  808.                 trans_status = xmk_bgetf(Port, answer,  XMODEM_1K, XMODEM_CRC,1);
  809.                 in_xmodem = 1;
  810.                 break;
  811.             }
  812.         }
  813.   
  814.     
  815. return(trans_status);
  816. }
  817.   
  818.  
  819.  
  820. /*
  821.     getinput - Given the character string buffer address, accept the
  822.     user input string and return the number of characters entered.  Accept
  823.     input at the current cursor location.
  824.     Returns:
  825.  
  826.         0   Only Enter key pressed
  827.         >0  The character string of n characters returned
  828.         -1  Ctrl-Break pressed
  829. */
  830. int getinput(buffer)
  831. char buffer[];
  832. {
  833.     int i = 0;
  834.     int exitflag = 0;
  835.     char ch;
  836.     int row, column;
  837.  
  838.     while (exitflag == 0) {
  839.         switch ((ch = xck_getc()) & 0xFF) {
  840.         case RET:
  841.             buffer[i] = '\000';
  842.             exitflag = 1;               /* Exit file entry */
  843.             break;
  844.         case RUB1:
  845.         case RUB2:
  846.             if (i) {
  847.                 --i;
  848.                 xcv_gcur(&row, &column);
  849.                 xcv_scur(row, column - 1);
  850.                 xcv_wtty(' ');
  851.                 xcv_scur(row, column - 1);
  852.             }
  853.             break;
  854.         default:
  855.             buffer[i++] = ch;
  856.             xcv_wtty(ch);
  857.         }
  858.     }
  859.     return(i);                          /* Return size of answer */
  860. }
  861.