home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / os2sdk / os2sdk10 / apps / terminal / options.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-11  |  26.1 KB  |  1,103 lines

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