home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / os2sdk / os2sdk12 / terminal / options.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-06  |  26.0 KB  |  1,104 lines

  1. /***
  2.  *
  3.  * TITLE 
  4.  *
  5.  *    options.c
  6.  *    Created by Microsoft Corporation 1987
  7.  *
  8.  * DESCRIPTION
  9.  *
  10.  *    This module handles the user interface for setting the options for
  11.  *      the COM port and the MODEM.
  12.  *
  13.  *     If a filename was specified in the command line, the initialisation 
  14.  *    of the COM port and the MODEM will be performed as indicated in 
  15.  *    the file (creation of this file will be described later). If an error 
  16.  *    is encountered in opening the file or, if no file was specified in the 
  17.  *    command line, an option screen is displayed. The user is then required 
  18.  *    to specify the appropriate options for initialisation of the COM port 
  19.  *    and the MODEM.
  20.  * 
  21.  *     The program will request the following information from the user via 
  22.  *    the option screen:
  23.  *
  24.  *        Port        :
  25.  *            Baud Rate   :
  26.  *        Data Bits   :
  27.  *        Stop Bits   :
  28.  *        Parity      :
  29.  *        Connect     : 
  30.  *        Dial Type   : 
  31.  *        Wait Tone   :
  32.  *        Wait Carrier:
  33.  *        Phone Number:
  34.  *        Setup File  :
  35.  *
  36.  *    Port:
  37.  *        Specify com port. The available options are com1, com2.
  38.  *    Baud Rate:
  39.  *        The available options are 1200, 2400, 4800, 9600, 110,
  40.  *        150, 300, 600.
  41.  *    Data Bits:
  42.  *        The available options are 7 and 8.
  43.  *    Stop Bits:
  44.  *        The available options are 1 and 2.
  45.  *    Parity:
  46.  *        The available options are even, none and odd.
  47.  *    Connect: 
  48.  *        The available options are computer and modem.
  49.  *    Dial Type:
  50.  *        The available options are tone and pulse.
  51.  *    Wait Tone:
  52.  *        The available options are 10, 15, 20, 25, 50, 75, 100, 
  53.  *        125, 150, 175, 200, 225 and 250 seconds.
  54.  *        Determines how long the modem waits after "picking up
  55.  *        the telephone" before it dials the first digit of the
  56.  *        telephone number. This delay allows time for the central
  57.  *        office to detect the "off-hook" condition of the line and
  58.  *        apply a dial tone.
  59.  *    Wait Carrier: 
  60.  *        The available options are 10, 15, 20, 25, and 30.
  61.  *        Sets the time that the local modem waits for carrier from
  62.  *        the remote modem before hanging up.
  63.  *    Phone Number:
  64.  *        Type the telephone number of the service. Type the entire
  65.  *        number including 1 and the area code if necessary. 
  66.  *        Commas instruct the modem to pause before dialing a number.
  67.  *        For example, if you must dial 9 to get an outside line, type
  68.  *        a comma after the 9. This allows time to wait for a dial
  69.  *        tone before the modem dials the number. You can use hyphens 
  70.  *        in the number for clarity; the modem ignores them.
  71.  *    Setup File:
  72.  *        This is the name of file in which the options will be saved.
  73.  *        The default file name is terminal.ini . If you prefer
  74.  *              a different name, delete the default name and type the
  75.  *              name you prefer. You may include the path name.
  76.  *
  77.  */
  78.  
  79. #define     INCL_DOSSIGNALS
  80. #define     INCL_SUB
  81.  
  82. #include    <os2def.h>
  83. #include    <bse.h>
  84. #include    <stdio.h>
  85. #include    <malloc.h>
  86. #include    <string.h>
  87. #include     <memory.h>
  88. #include     <conio.h>
  89. #include     "term.h"
  90.  
  91. extern void far error (int, int);
  92.  
  93. extern char     *ErrMsg[NUM_MSG];
  94.  
  95. #define Z_ALPHA     0x01
  96. #define Z_DIGIT     0x02
  97. #define Z_WHITE     0x04
  98. #define Z_PATH        0x08
  99. #define Z_PHONE     0x10
  100.  
  101. #define     O_WIDTH    62
  102. #define     O_HEIGHT    21
  103.  
  104. char optScreen[O_HEIGHT][O_WIDTH+1] = {
  105.    /* 123456789 123456789 123456789 123456789 123456789 123456789 1 */
  106.     "                    [ Terminal Parameters ]                   ", /*  0 */
  107.     "                                                              ", /*  1 */
  108.     "   Port        :     com1                                     ", /*  2 */
  109.     "   Baud Rate   :     1200                                     ", /*  3 */
  110.     "   Data Bits   :        7                                     ", /*  4 */
  111.     "   Stop Bits   :        2                                     ", /*  5 */
  112.     "   Parity      :     even                                     ", /*  6 */
  113.     "   Connect     : computer                                     ", /*  7 */
  114.     "   Dial Type   :     tone                                     ", /*  8 */
  115.     "   Wait Tone   :       30                                     ", /*  9 */
  116.     "   Wait Carrier:       10                                     ", /* 10 */
  117.     "                                                              ", /* 11 */
  118.     "   Phone Number: 9,555-1212                                   ", /* 12 */
  119.     "                                                              ", /* 13 */
  120.     "   Setup File  : terminal.ini                                 ", /* 14 */
  121.     "                                                              ", /* 15 */
  122.     "                                                              ", /* 16 */
  123.     "       Use UP and DOWN cursor keys to move between fields.    ", /* 17 */
  124.     "       Use LEFT and RIGHT cursor keys to change a field.      ", /* 18 */
  125.     "                                                              ", /* 19 */
  126.     "                   [ Press Enter to return ]                  "  /* 20 */
  127. };
  128.  
  129. #define     rowPort    2
  130. #define     colPort    21
  131.  
  132. #define     rowBaud    3
  133. #define     colBaud    21
  134.  
  135. #define     rowData    4
  136. #define     colData    24
  137.  
  138. #define     rowStop    5
  139. #define     colStop    24
  140.  
  141. #define     rowParity    6
  142. #define     colParity  21
  143.  
  144. #define        rowConnect  7
  145. #define     colConnect 17
  146.  
  147. #define     rowDial     8
  148. #define     colDial    20
  149.  
  150. #define     rowTone     9
  151. #define     colTone    22
  152.  
  153. #define     rowCarrier  10
  154. #define     colCarrier  23
  155.  
  156. #define     rowPhone   12
  157. #define     colPhone   17
  158. #define     wPhone     20        /* width of phone string */
  159. #define     sPhone  (Z_DIGIT | Z_PHONE)
  160.              /*012345678901234567890*/
  161. char strPhone[wPhone+1] = "9,555-1212           ";
  162. #define     lenPhone   12
  163.  
  164. #define     rowFile    14
  165. #define     colFile    17
  166. #define     wFile      40
  167. #define     sFile   (Z_PATH | Z_ALPHA | Z_DIGIT)
  168.              /*01234567890123456789012345678901234567890*/
  169. char strFile[wFile+1]="terminal.ini                             ";
  170. #define     lenFile    13
  171.  
  172. int O_ROW;    /* Coordinates of top left corner of option menu */
  173. int O_COL;
  174.  
  175. char *csBaud[] = {
  176.     "1200",
  177.     "2400",
  178.     "4800",
  179.     "9600",
  180.     " 110",
  181.     " 150",
  182.     " 300",
  183.     " 600"
  184. };
  185.  
  186. #define nBaud    (sizeof(csBaud)/sizeof(char*))
  187. #define wBaud   4    
  188. int intBaud[nBaud] = {
  189.    1200,
  190.    2400,
  191.    4800,
  192.    9600,
  193.     110,
  194.     150,
  195.     300,
  196.     600
  197. };
  198.  
  199. char *csPort[] = {
  200.     "com1",
  201.     "com2"
  202. };
  203. #define nPort    (sizeof(csPort)/sizeof(char*))
  204. #define wPort    4
  205.  
  206. char *csData[] = {
  207.     "7",
  208.     "8"
  209. };
  210. #define nData    (sizeof(csData)/sizeof(char*))
  211. #define wData    1
  212.  
  213. UCHAR chData[nData] = {
  214.     7,
  215.     8
  216. };
  217.  
  218. NPCH csStop[] = {
  219.     "1",
  220.     "2"
  221. };
  222. #define nStop    (sizeof(csStop)/sizeof(char*))
  223. #define wStop    1
  224.  
  225. UCHAR chStop[nStop] = {
  226.     0,
  227.     2
  228. };
  229.  
  230. NPCH csParity[] = {
  231.     "even",
  232.     " odd",
  233.     "none"
  234. };
  235. #define nParity   (sizeof(csParity)/sizeof(char*))
  236. #define wParity   4
  237.  
  238. UCHAR chParity[nParity] = {
  239.     EVEN,
  240.     ODD,
  241.     NONE
  242. };
  243.  
  244. NPCH csConnect[] = {
  245.     "computer",
  246.     "   modem"
  247. };
  248. #define nConnect   (sizeof(csConnect)/sizeof(char*))
  249. #define wConnect   8
  250. UCHAR chConnect[nConnect] = {
  251.     COMPUTER,
  252.     MODEM
  253. };
  254.  
  255. NPCH csDial[] = {
  256.     " tone",
  257.     "pulse"
  258. };
  259. #define nDial   (sizeof(csDial)/sizeof(char*))
  260. #define wDial   5
  261. UCHAR chDial[nConnect] = {
  262.     TONE,
  263.     PULSE
  264. };
  265.  
  266. NPCH csTone[] = {
  267.     " 10",
  268.     " 15",
  269.     " 20",
  270.     " 25",
  271.     " 50",
  272.     " 75",
  273.     "100",
  274.     "125",
  275.     "150",
  276.     "175",
  277.     "200",
  278.     "225",
  279.     "250"
  280. };
  281. /* register S6 in Hayes Modem */
  282. #define nTone   (sizeof(csTone)/sizeof(char*))
  283. #define wTone   3
  284. int iTone[nTone] = {10,15,20,25,50,75,100,125,150,175,200,225,250};
  285.  
  286. NPCH csCarrier[] = {
  287.     "30",
  288.     "25",
  289.     "20",
  290.     "15",
  291.     "10",
  292.     " 5"
  293. };
  294. /* register S7 in Hayes Modem */
  295. #define nCarrier   (sizeof(csCarrier)/sizeof(char*))
  296. #define wCarrier   2
  297. int iCarrier[nCarrier] = {30, 25, 20, 15, 10, 5};
  298.  
  299. #define OT_SET        0        /* Option types */
  300. #define OT_ASCIIZ   1
  301.  
  302. UCHAR cMap[256];
  303.  
  304. typedef struct {
  305.     int sc_n;            /* number of different values */
  306.     char **sc_name;        /* array of value names */
  307. } setControl_s;
  308.  
  309. typedef struct {
  310.     UCHAR az_Set;    /* flags of valid characters */
  311. } azControl_s;
  312.  
  313. typedef struct {
  314.     int ctl_type;        /* Type of control */
  315.     int ctl_row;        /* row to display value name */
  316.     int ctl_col;        /* column to display value name */
  317.     int ctl_width;        /* width of value names */
  318.     union {
  319.     setControl_s  sc;
  320.     azControl_s   az;
  321.     } ctl_union;
  322. } control_s;
  323.  
  324. typedef union {
  325.     struct {
  326.     char *oaz_str;
  327.     int   oaz_cur;        /* cursor position */
  328.     } oaz;
  329.     int   osc;
  330. } option_u;
  331.  
  332. control_s  control[] = {
  333.     {OT_SET   ,rowPort      ,colPort    ,wPort    ,{nPort    ,csPort    }},
  334.     {OT_SET   ,rowBaud      ,colBaud    ,wBaud    ,{nBaud    ,csBaud    }},
  335.     {OT_SET   ,rowData      ,colData    ,wData    ,{nData    ,csData    }},
  336.     {OT_SET   ,rowStop      ,colStop    ,wStop    ,{nStop    ,csStop    }},
  337.     {OT_SET   ,rowParity  ,colParity  ,wParity  ,{nParity  ,csParity  }},
  338.     {OT_SET   ,rowConnect ,colConnect ,wConnect ,{nConnect ,csConnect }},
  339.     {OT_SET   ,rowDial    ,colDial    ,wDial    ,{nDial    ,csDial    }},
  340.     {OT_SET   ,rowTone    ,colTone    ,wTone    ,{nTone    ,csTone    }},
  341.     {OT_SET   ,rowCarrier ,colCarrier ,wCarrier ,{nCarrier ,csCarrier }},
  342.     {OT_ASCIIZ,rowPhone   ,colPhone   ,wPhone   ,{sPhone          }},
  343.     {OT_ASCIIZ,rowFile      ,colFile    ,wFile    ,{sFile                  }}
  344. };
  345.  
  346. option_u option[] = {         /* Current option settings */
  347.     {0},            /* port        */    
  348.     {0},            /* baud        */    
  349.     {0},            /* data bits   */    
  350.     {0},            /* stop bits   */    
  351.     {0},            /* parity      */    
  352.     {0},            /* connect     */    
  353.     {0},            /* dial type   */    
  354.     {0},            /* wait tone   */    
  355.     {0},            /* wait carrier*/    
  356.     {strPhone,0},        /* phone       */    
  357.     {strFile ,0}        /* file        */    
  358. };
  359. #define nOption    (sizeof(option)/sizeof(option_u))
  360.  
  361. static char     AttrPanel  = COLOR_PANEL,
  362.                  AttrOption = COLOR_OPTION,
  363.                   AttrCursor = COLOR_CURSOR;
  364. static int    N_of_Cols,        /* number of columns on screen */
  365.         N_of_Rows;        /* number of rows on screen */
  366.  
  367.  
  368.  
  369.  
  370. /***     get_options - get COM port settings and modem settings
  371.  *
  372.  *    This routine determines the type of display and sets the display
  373.  *    attributes appropriately. If a filename was specified in the command
  374.  *    line, it opens the file and displays the COM port and the MODEM options
  375.  *    from the file. These options may be modified but the modifications will
  376.  *    not be written out to the file. If the file open failed, or, if no file
  377.  *    was specified in the command line, this routine wil display the default
  378.  *    options on the screen. The user may modify the options and it will be
  379.  *    writen out to the file specified in the options screen.
  380.  *
  381.  *    get_options(argc,argv)
  382.  *
  383.  *    ENTRY
  384.  *        argc - number of command line arguments
  385.  *        argv - pointer to an array of pointers (to command line args)
  386.  *
  387.  *    EXIT
  388.  *
  389.  *    WARNING
  390.  *
  391.  *    EFFECTS
  392.  *
  393.  ***/
  394.  
  395. void get_options(argc, argv)
  396. int     argc;
  397. char     *argv[];
  398. {
  399.     FILE        *fp;
  400.     char        OptionsSet = FALSE; /* indicate if options are set  */
  401.     unsigned    RetCode;
  402.     static VIOCONFIGINFO DispConfigData = {sizeof(DispConfigData),};
  403.  
  404.     /* if the display is monochrome, change the attributes */
  405.     if ((RetCode = VioGetConfig(RESERVED,&DispConfigData,RESERVED)) != 0)
  406.       error(ERR_VIOGETCONFIG, RetCode);
  407.     if ((DispConfigData.adapter == MONOCHROME) ||
  408.         (DispConfigData.display == MONOCHROME)) {
  409.       AttrPanel  = MONO_PANEL;
  410.       AttrOption = MONO_OPTION;
  411.       AttrCursor = MONO_CURSOR;
  412.     }
  413.  
  414.  
  415.     if (argc > 1) {      /* get com/modem settings from the file */
  416.       if ((fp = fopen(argv[1], "r")) != NULL) {
  417.  
  418.         /* clear the phone-number and file-name string buffers */
  419.         strnset(strPhone, ' ', wPhone+1);
  420.         strnset(strFile, ' ', sFile+1);
  421.  
  422.         /* read the option settings from the file */
  423.         fscanf(fp, "%d %d %d %d %d %d %d %d %d \n",
  424.                    &option[PORT_NAME].osc, &option[BAUD_RATE].osc, 
  425.            &option[DATA_BITS].osc, &option[STOP_BITS].osc, 
  426.            &option[PARITY].osc, &option[CONNECT].osc, 
  427.            &option[DIAL_TYPE].osc, &option[WAIT_TONE].osc, 
  428.            &option[WAIT_CARRIER].osc);
  429.         fscanf(fp, "%21s \n", option[PHONE_NUMBER].oaz.oaz_str);
  430.         fscanf(fp, "%41s \n", option[SETUP_FILE].oaz.oaz_str);
  431.         printf("file name = %s \n", option[SETUP_FILE].oaz.oaz_str);
  432.         option[PHONE_NUMBER].oaz.oaz_cur = 0;  /* init cursor position */
  433.         option[SETUP_FILE].oaz.oaz_cur = 0;    /* init cursor position */
  434.  
  435.         /* show the options on the screen */
  436.             screen_init();        /* init the physical screen */
  437.             option_init();
  438.             show_option();
  439.  
  440.         OptionsSet = TRUE;
  441.         fclose(fp);
  442.       }
  443.     }
  444.  
  445.     if (!OptionsSet) {        /* get options from the user */
  446.           screen_init();            /* init the physical screen */
  447.           option_init();
  448.           show_option();
  449.       /* write option settings to the file specified. */
  450.       if ((fp = fopen(option[SETUP_FILE].oaz.oaz_str, "w")) != NULL) {
  451.         DosHoldSignal(HLDSIG_DISABLE);
  452.         fprintf(fp, "%d %d %d %d %d %d %d %d %d \n",
  453.                     option[PORT_NAME].osc, option[BAUD_RATE].osc, 
  454.             option[DATA_BITS].osc, option[STOP_BITS].osc, 
  455.             option[PARITY].osc, option[CONNECT].osc, 
  456.             option[DIAL_TYPE].osc, option[WAIT_TONE].osc, 
  457.             option[WAIT_CARRIER].osc);
  458.         fprintf(fp, "%21s \n", option[PHONE_NUMBER].oaz.oaz_str);
  459.         fprintf(fp, "%41s \n", option[SETUP_FILE].oaz.oaz_str);
  460.         fclose(fp);
  461.         DosHoldSignal(HLDSIG_ENABLE);}
  462.         } 
  463. }
  464.  
  465.  
  466.  
  467.  
  468. /***    get_com_options - get Com port options
  469.  *
  470.  *    This routine copies the current com port options into a structure
  471.  *    provided by the caller. 
  472.  *
  473.  *    get_com_options(psComOptions)
  474.  *
  475.  *    ENTRY
  476.  *        psComOptions = ptr to structure of com port options
  477.  *
  478.  *    EXIT
  479.  *        the structure pointed by psComOptions is filled with com 
  480.  *        port options
  481.  *
  482.  *    WARNING
  483.  *
  484.  *    EFFECTS
  485.  *
  486.  */
  487.  
  488. void get_com_options(psComOptions)
  489. structComOptions *psComOptions;        /* ptr to struct of com port options */
  490. {
  491.     psComOptions->pPortName  = csPort[(option[PORT_NAME].osc)];
  492.     psComOptions->iBaudRate  = intBaud[(option[BAUD_RATE].osc)];
  493.     psComOptions->chDataBits = chData[(option[DATA_BITS].osc)];
  494.         psComOptions->chStopBits = chStop[(option[STOP_BITS].osc)];
  495.     psComOptions->chParity   = chParity[(option[PARITY].osc)];
  496. }
  497.  
  498.  
  499.  
  500.  
  501. /***    get_modem_options - get modem options 
  502.  *
  503.  *    This routine copies the current modem options into a structure
  504.  *    provided by the caller. 
  505.  *
  506.  *    get_modem_options(psModemOptions)
  507.  *
  508.  *    ENTRY
  509.  *        psModemOptions = ptr to structure of modem options
  510.  *
  511.  *    EXIT
  512.  *        the structure pointed by psModemOptions is filled with 
  513.  *        modem options
  514.  *
  515.  *    WARNING
  516.  *
  517.  *    EFFECTS
  518.  *
  519.  */
  520.  
  521. void get_modem_options(psModemOptions)
  522. structModemOptions *psModemOptions;    /* ptr to struct of modem options */
  523. {
  524.     psModemOptions->chDialType   = chDial[(option[DIAL_TYPE].osc)];
  525.     psModemOptions->iWaitTone    = iTone[(option[WAIT_TONE].osc)];
  526.     psModemOptions->iWaitCarrier = iCarrier[(option[WAIT_CARRIER].osc)];
  527.     psModemOptions->pPhoneNumber = option[PHONE_NUMBER].oaz.oaz_str;
  528. }
  529.  
  530.  
  531.  
  532.  
  533. /***    modem - determines if modem connection was requested
  534.  *
  535.  *    modem()
  536.  *
  537.  *    ENTRY
  538.  *
  539.  *    EXIT
  540.  *        modem = TRUE if modem connection was requested
  541.  *                FALSE otherwise
  542.  *
  543.  *    WARNING
  544.  *
  545.  *    EFFECTS
  546.  *
  547.  ***/
  548.  
  549. modem()
  550. {
  551.     return (chConnect[(option[CONNECT].osc)] == MODEM);
  552. }
  553.  
  554.  
  555.  
  556.  
  557. /***    clear_screen - blank out the entire screen
  558.  *
  559.  *    clear_screen()
  560.  *
  561.  *    ENTRY
  562.  *
  563.  *    EXIT
  564.  *
  565.  *    WARNING
  566.  *
  567.  *    EFFECTS
  568.  *
  569.  ***/
  570.  
  571. clear_screen()
  572. {
  573.     Cell         c;
  574.     int            RetCode;
  575.  
  576.     c.ch = ' ';
  577.     c.at = ATTR(WHITE,BLACK);
  578.     if ((RetCode = VioWrtNCell((PBYTE)(&c), N_of_Rows*N_of_Cols,
  579.                                0, 0, RESERVED)) != 0)
  580.       error(ERR_VIOWRTNCELL, RetCode);
  581. }   /* clear_screen */
  582.  
  583.  
  584.  
  585.  
  586. /***    option_init - initialize option screen 
  587.  *
  588.  *    option_init()
  589.  *
  590.  *    ENTRY
  591.  *
  592.  *    EXIT
  593.  *
  594.  *    WARNING
  595.  *
  596.  *    EFFECTS
  597.  *
  598.  ***/
  599.  
  600. option_init()
  601. {
  602.         int         i;
  603.  
  604.         O_ROW = (N_of_Rows - O_HEIGHT)/2;
  605.         O_COL = (N_of_Cols - O_WIDTH)/2;
  606.         for (i=0; i<nOption; i++) {   /* adjust to real screen coordinates */
  607.           control[i].ctl_row += O_ROW;
  608.           control[i].ctl_col += O_COL;
  609.         }
  610.         init_cmap();
  611. }       /* option_init */
  612.  
  613.  
  614.  
  615.  
  616. /***    init_cmap - initialise valid character set
  617.  *
  618.  *    init_cmap()
  619.  *
  620.  *    ENTRY
  621.  *
  622.  *    EXIT
  623.  *
  624.  *    WARNING
  625.  *
  626.  *    EFFECTS
  627.  *
  628.  ***/
  629.  
  630. init_cmap()
  631. {
  632.         register int     i;
  633.  
  634.         for (i=0; i<256; i++)
  635.           cMap[i] = 0;
  636.         for (i='a'; i<='z'; i++)
  637.           cMap[i] |= Z_ALPHA;
  638.         for (i='A'; i<='Z'; i++)
  639.           cMap[i] |= Z_ALPHA;
  640.         for (i='0'; i<='9'; i++)
  641.           cMap[i] |= Z_DIGIT;
  642.         cMap[':']  |= Z_PATH;
  643.         cMap['\\'] |= Z_PATH;
  644.         cMap['/']  |= Z_PATH;
  645.         cMap['.']  |= Z_PATH;
  646.         cMap['-']  |= Z_PATH;
  647.         cMap[' ']  |= Z_WHITE;
  648.         cMap['\t'] |= Z_WHITE;
  649.         cMap['-']  |= Z_PHONE;
  650.         cMap[',']  |= Z_PHONE;
  651. }       /* init_cmap */
  652.  
  653.  
  654.  
  655.  
  656. /***    show_option - display option screen and record user modifications
  657.  *
  658.  *    show_option()
  659.  *
  660.  *    ENTRY
  661.  *
  662.  *    EXIT
  663.  *
  664.  *    WARNING
  665.  *
  666.  *    EFFECTS
  667.  *
  668.  ***/
  669.  
  670. show_option()
  671. {
  672.     int        RetCode;
  673.  
  674.         do_option();
  675.     clear_screen();
  676.     if ((RetCode = VioSetCurPos(0, 0, RESERVED)) != 0)
  677.           error(ERR_VIOSETCURPOS, RetCode);
  678. }       /* show_option */
  679.  
  680.  
  681.  
  682.  
  683. /***    do_option - show and update option screen
  684.  *
  685.  *    do_option()
  686.  *
  687.  *    ENTRY
  688.  *
  689.  *    EXIT
  690.  *
  691.  *    WARNING
  692.  *
  693.  *    EFFECTS
  694.  *
  695.  ***/
  696.  
  697. do_option()
  698. {
  699.     USHORT        row, col;
  700.     BYTE        a;
  701.         int         RetCode,
  702.             i,
  703.                 key,
  704.                 iOpt,lastOpt;
  705.  
  706.         a = AttrPanel;
  707.         for (row=0; row<O_HEIGHT; row++)        /* display option panel */
  708.       if ((RetCode = VioWrtCharStrAtt(optScreen[row],O_WIDTH,row+O_ROW,
  709.                               O_COL, &a, RESERVED)) != 0)
  710.             error(ERR_VIOWRTCHARSTRATT, RetCode);
  711.         for (i=0; i<nOption; i++)       /* Fill in options */
  712.       show_opt(i, AttrOption);
  713.  
  714.         key = 0;
  715.         iOpt = 0;    /* Start with first option */
  716.         lastOpt = iOpt;
  717.         while (key != ENTER_KEY) {
  718.       if (iOpt != lastOpt)        /* user moved to different field */
  719.         show_opt(lastOpt, AttrOption); /* revert to normal color */
  720.       show_opt(iOpt, AttrCursor);    /* highlight current field */
  721.       lastOpt = iOpt;
  722.       key = get_key();
  723.       switch (key) {
  724.         case UP_KEY:
  725.             if (--iOpt < 0)
  726.                   iOpt = nOption - 1;
  727.             break;
  728.         case DOWN_KEY:
  729.             if (++iOpt > (nOption - 1))
  730.                   iOpt = 0;
  731.             break;
  732.         case RIGHT_KEY:
  733.             mod_option(iOpt,  1);
  734.             break;
  735.         case LEFT_KEY:
  736.             mod_option(iOpt, -1);
  737.             break;
  738.         case DEL_KEY:
  739.             if (control[iOpt].ctl_type == OT_ASCIIZ)
  740.                   do_right_del(iOpt);
  741.             break;
  742.         case HOME_KEY:
  743.             if (control[iOpt].ctl_type == OT_ASCIIZ)
  744.                   option[iOpt].oaz.oaz_cur = 0;
  745.             break;
  746.         case BKSP_KEY:
  747.             if (control[iOpt].ctl_type == OT_ASCIIZ)
  748.                   do_left_del(iOpt);
  749.             break;
  750.         default:
  751.             switch (control[iOpt].ctl_type) {
  752.                   case OT_SET:    /* Ignore other key strokes */
  753.                     break;
  754.                   case OT_ASCIIZ:
  755.                     do_insert(iOpt,key);
  756.                     break;
  757.                   default:
  758.                     error(ERR_DO_OPT_INVOPT, NO_RETCODE);
  759.             }
  760.             break;
  761.       }       /* switch */
  762.         }    /* while */
  763. }       /* do_option */
  764.  
  765.  
  766.  
  767.  
  768. /***    do_insert - insert character in a string
  769.  *
  770.  *    do_insert(iOpt,key)
  771.  *
  772.  *    ENTRY
  773.  *        iOpt = which option (setup File or Phone Number)
  774.  *        key  = character to insert
  775.  *
  776.  *    EXIT
  777.  *        char inserted into string (setup File name or Phone Number)
  778.  *
  779.  *    WARNING
  780.  *
  781.  *    EFFECTS
  782.  *
  783.  ***/
  784.  
  785. do_insert(iOpt,key)
  786. int      iOpt;
  787. unsigned key;
  788. {
  789.         int       ch;
  790.         int       cur;
  791.         int       i,n;
  792.         int       width;
  793.         char     *s,*d,*p;
  794.  
  795.         ch = key >> 8;
  796.         if (ch > 0x7F)    /* Ignore */
  797.       return(0);
  798.         if ((cMap[ch] & control[iOpt].ctl_union.az.az_Set) == 0)
  799.       return(0);     /* Not valid char */
  800.  
  801.         /*    oaz_cur - points to insertion point
  802.         We throw away characters at end of string.
  803.  
  804.         before: aaaaaaabbbbbbbbbbbbc
  805.                        ^
  806.         after:    aaaaaaaxbbbbbbbbbbbb
  807.                     ^
  808.         */
  809.         cur = option[iOpt].oaz.oaz_cur;
  810.         width = control[iOpt].ctl_width;
  811.         p = option[iOpt].oaz.oaz_str;
  812.  
  813.         d = p+width-1;        /* End of string */
  814.         s = d-1;        /* End of string - 1 */
  815.         n = (width-cur)-1;    /* Number of chars to shift */
  816.         for (i=n; i>0; i--)
  817.       *d-- = *s--;        /* Shift string */
  818.         p[cur] = ch;        /* Insert character */
  819.         cur++;            /* Advance insertion point */
  820.         if (cur > (width-1))    /* cursor wrapped */
  821.       cur = 0;
  822.         option[iOpt].oaz.oaz_cur = cur;
  823. }
  824.  
  825.  
  826.  
  827.  
  828. /***    do_left_del - delete a character which is to the left of the cursor
  829.  *
  830.  *    do_left_del(iOpt)
  831.  *
  832.  *    ENTRY
  833.  *        iOpt = which option (setup File or Phone Number)
  834.  *
  835.  *    EXIT
  836.  *        char deleted from string (setup File name or Phone Number)
  837.  *
  838.  *    WARNING
  839.  *
  840.  *    EFFECTS
  841.  *
  842.  ***/
  843.  
  844. do_left_del(iOpt)
  845. int     iOpt;
  846. {
  847.         if (option[iOpt].oaz.oaz_cur != 0)    /* Ignore at start of field */
  848.         /*
  849.         We delete the character to the left of the cursor and shift
  850.         rest of characters left 1.  Ignore at beginning of field.
  851.  
  852.         before: aaaaaaaxbbbbbbbbbbbb
  853.                 ^
  854.         after:    aaaaaaabbbbbbbbbbbb
  855.                           ^
  856.         */
  857.         do_del(iOpt,0,-1);
  858. }
  859.  
  860.  
  861.  
  862.  
  863. /***    do_right_del - delete a character which is at the cursor
  864.  *
  865.  *     do_right_del(iOpt)
  866.  *
  867.  *    ENTRY
  868.  *        iOpt = which option (setup File or Phone Number)
  869.  *
  870.  *    EXIT
  871.  *        char deleted from string (setup File name or Phone Number)
  872.  *
  873.  *    WARNING
  874.  *
  875.  *    EFFECTS
  876.  *
  877.  ***/
  878.  
  879. do_right_del(iOpt)
  880. int     iOpt;
  881. {
  882.         /*
  883.         We delete the character at the cursor and shift
  884.         rest of characters left 1.
  885.  
  886.         before: aaaaaaaxbbbbbbbbbbbb
  887.                           ^
  888.         after:    aaaaaaabbbbbbbbbbbb
  889.                        ^
  890.         */
  891.         do_del(iOpt,1,0);
  892. }
  893.  
  894.  
  895.  
  896.  
  897. /***    do_del - delete a character
  898.  *
  899.  *    do_del(iOpt,iShift,iCur)
  900.  *
  901.  *    ENTRY
  902.  *        iOpt = which option (setup File or Phone Number)
  903.  *        iShift = amount by which string should be shifted
  904.  *        iCur = amount by which cursor should be moved
  905.  *    EXIT
  906.  *        char deleted from string (setup File name or Phone Number)
  907.  *        cursor position within the string updated
  908.  *
  909.  *    WARNING
  910.  *
  911.  *    EFFECTS
  912.  *
  913.  ***/
  914.  
  915. do_del(iOpt,iShift,iCur)
  916. int     iOpt,
  917.         iShift,
  918.         iCur;
  919. {
  920.         int     cur,width,i,n;
  921.         char     *s,*d,*p;
  922.  
  923.         cur = option[iOpt].oaz.oaz_cur;
  924.         width = control[iOpt].ctl_width;
  925.         p = option[iOpt].oaz.oaz_str;
  926.  
  927.         s = p+cur+iShift;
  928.         d = s-1;
  929.         n = (width-(cur+iCur))-1;    /* Number of chars to shift */
  930.         for (i=n; i>0; i--)
  931.       *d++ = *s++;            /* Shift string */
  932.         cur += iCur;            /* Adjust cursor */
  933.         p[width-1] = ' ';        /* Put blank at end */
  934.         option[iOpt].oaz.oaz_cur = cur;
  935. }
  936.  
  937.  
  938.  
  939.  
  940. /***    mod_option - modify option
  941.  *
  942.  *    mod_option(iOpt, inc)
  943.  *
  944.  *    ENTRY
  945.  *        iOpt = which option (Port, Baud Rate, ..., setup File)
  946.  *        inc  =  1 ( -> key was pressed)
  947.  *               -1 ( <- key was pressed)
  948.  *
  949.  *    EXIT
  950.  *        option array entry 'osc' updated for all iOpt except for 
  951.  *        setupFile and PhoneNumber. In the case of setupFile and 
  952.  *        PhoneNumber, the cursor position is updated (cursor moved 
  953.  *        left if '<-' key was pressed; cursor moved right if '->' 
  954.  *        key was pressed)
  955.  *
  956.  *    WARNING
  957.  *
  958.  *    EFFECTS
  959.  *
  960.  ***/
  961.  
  962. mod_option(iOpt, inc)
  963. int     iOpt,
  964.     inc;
  965. {
  966.         int     col;
  967.         int     width;
  968.  
  969.     switch (control[iOpt].ctl_type) {
  970.     case OT_SET:    /* Ignore other key strokes */
  971.         if (inc > 0) {  /* Increment value */
  972.         if (++option[iOpt].osc > (control[iOpt].ctl_union.sc.sc_n - 1))
  973.             option[iOpt].osc = 0;
  974.         }
  975.         else        /* Decrement value */
  976.         if (--option[iOpt].osc < 0 )
  977.             option[iOpt].osc = control[iOpt].ctl_union.sc.sc_n - 1;
  978.         break;
  979.     case OT_ASCIIZ:
  980.         col = option[iOpt].oaz.oaz_cur;
  981.         width = control[iOpt].ctl_width;
  982.         if (inc > 0) {  /* move cursor right */
  983.         if (++col > (width-1))
  984.             col = 0;
  985.         }
  986.         else        /* move cursor left */
  987.         if (--col < 0 )
  988.             col = (width-1);
  989.         option[iOpt].oaz.oaz_cur = col;
  990.         break;
  991.     default:
  992.         error(ERR_MOD_OPT_INVOPT, NO_RETCODE);
  993.     }
  994. }
  995.  
  996.  
  997.  
  998.  
  999. /***    show_opt - show option
  1000.  *
  1001.  *    show_opt(iOpt, color)
  1002.  *
  1003.  *    ENTRY
  1004.  *        iOpt = which option (Port, Baud Rate, . . ., Phone Number)
  1005.  *        color = color in which the option is to be displayed
  1006.  *
  1007.  *    EXIT
  1008.  *        option indicated by iOpt is displayed on the screen
  1009.  *
  1010.  *    WARNING
  1011.  *
  1012.  *    EFFECTS
  1013.  *
  1014.  ***/
  1015.  
  1016. show_opt(iOpt, color)
  1017. int    iOpt;
  1018. char    color;
  1019. {
  1020.     USHORT        row,col,width,
  1021.             curCol;
  1022.         char         *name;
  1023.         unsigned     RetCode;
  1024.  
  1025.         row = control[iOpt].ctl_row;
  1026.         col = control[iOpt].ctl_col;
  1027.         width = control[iOpt].ctl_width;
  1028.         switch (control[iOpt].ctl_type) {
  1029.       case OT_SET:
  1030.         name = control[iOpt].ctl_union.sc.sc_name[option[iOpt].osc];
  1031.         curCol = col+width-1;
  1032.         break;
  1033.       case OT_ASCIIZ:
  1034.         name = option[iOpt].oaz.oaz_str;
  1035.         curCol = col+option[iOpt].oaz.oaz_cur;
  1036.         break;
  1037.       default:
  1038.         error(ERR_SHOW_OPT_INVOPT, NO_RETCODE);
  1039.         };
  1040.     if ((RetCode = VioWrtCharStrAtt(name, width, row, col,
  1041.                                         &color, RESERVED)) != 0)
  1042.           error(ERR_VIOWRTCHARSTRATT, RetCode);
  1043.     if ((RetCode = VioSetCurPos(row, curCol, RESERVED)) != 0)
  1044.           error(ERR_VIOSETCURPOS, RetCode);
  1045. }
  1046.  
  1047.  
  1048.  
  1049.  
  1050. /***    get_key - return two-byte key stroke; includes IBM extended ASCII codes
  1051.  *
  1052.  *    get_key()
  1053.  *
  1054.  *    ENTRY
  1055.  *
  1056.  *    EXIT
  1057.  *
  1058.  *    WARNING
  1059.  *
  1060.  *    EFFECTS
  1061.  *
  1062.  ***/
  1063.  
  1064. get_key()
  1065. {
  1066.     char     c;
  1067.     unsigned     key;
  1068.  
  1069.     if (c = getch())            /* Get character */
  1070.       key = c << 8;            /* Make scan code zero */
  1071.     else
  1072.       key = getch();            /* Get scan code */
  1073.     return(key);
  1074. }   /* get_key */
  1075.  
  1076.  
  1077.  
  1078.  
  1079. /***    screen_init - Initialize the screen
  1080.  *
  1081.  *    screen_init()
  1082.  *
  1083.  *    ENTRY
  1084.  *
  1085.  *    EXIT
  1086.  *
  1087.  *    WARNING
  1088.  *
  1089.  *    EFFECTS
  1090.  *
  1091.  ***/
  1092.  
  1093. screen_init()
  1094. {
  1095.     VIOMODEINFO TheModeData;    /* Mode data from VioGetMode */
  1096.     int        RetCode;
  1097.  
  1098.     if ((RetCode = VioGetMode(&TheModeData, RESERVED)) != 0)
  1099.           error(ERR_VIOGETMODE, RetCode);
  1100.         N_of_Cols = TheModeData.col;
  1101.         N_of_Rows = TheModeData.row;
  1102.     clear_screen();
  1103. }       /* screen_init */
  1104.