home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / PROCWRKB.ZIP / BENCH1.ZIP / BENCH / INPUT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-23  |  32.2 KB  |  1,556 lines

  1. /* ==( memo/inputt.c )== */
  2.  
  3. /* ----------------------------------------------- */
  4. /* Pro-C  Copyright (C) 1989 - 1990 Vestronix Inc. */
  5. /* Modification to this source is not supported    */
  6. /* by Vestronix Inc.                               */
  7. /*            All Rights Reserved                  */
  8. /* ----------------------------------------------- */
  9. /* Written   JPK   1-May-89                        */
  10. /* Modified  Geo  12-Dec-89  See comments below    */
  11. /* ----------------------------------------------- */
  12. /* %W%  (%H% %T%) */
  13.  
  14. /*
  15.  *  Modifications
  16.  *
  17.  *  16-Dec-89  JH  - rewrite of input masks, bug fixes
  18.  *  12-Dec-89  Geo - V2 version
  19.  *
  20. */
  21.  
  22. /*
  23.  * Inputt.c contains the routines to implement text field input. These include
  24.  * mask validation, character input and validation and field formatting for 
  25.  * display.
  26. */
  27. # include <stdio.h>
  28. # include <bench.h>
  29. # include "field.h"
  30. # include <time.h>
  31.  
  32. # ifndef MIN
  33. #  define MIN(a,b)    (a > b ? b : a)
  34. # endif
  35. # ifndef MAX
  36. #  define MAX(a,b)    (a < b ? b : a)
  37. # endif
  38.  
  39. char InvalidEntry[] = "Invalid data entry - Please retry";
  40.  
  41. /*
  42. # define INDEBUG
  43. */
  44.  
  45. /* Function prototypes */
  46. static PROTO (void init_field, (FIELD *, char *));
  47. static PROTO (void leave_field, (FIELD *));
  48. static PROTO (void build_display_buff, (FIELD *, char *));
  49. static PROTO (void int_disp_text, (FIELD *, int, char *));
  50. PROTO (int length_mask, (FIELD *));
  51. PROTO (char *home_field, (FIELD *, char *));
  52. static PROTO (char *end_field, (FIELD *, char *));
  53. static PROTO (char *backspace, (FIELD *, char *));
  54. static PROTO (char *forward, (FIELD *, char *));
  55. static PROTO (char *bleep_over_mask, (FIELD *, char *, int));
  56. static PROTO (char *del_text_char, (FIELD *, char *));
  57. static PROTO (void scroll_field_left, (FIELD *));
  58. static PROTO (void scroll_field_right, (void));
  59. static PROTO (void put_cursor, (FIELD *, int));
  60. static PROTO (void forward_cursor, (FIELD *));
  61. static PROTO (void back_cursor, (FIELD *));
  62. static PROTO (void home_cursor, (FIELD *));
  63. static PROTO (int check_char, (int *, char *, FIELD *));
  64. static PROTO (int realign_decimals, (FIELD *, char *));
  65. static PROTO (int set_negative_flag, (char *));
  66. static PROTO (void set_calculator_flag, (char *));
  67. static PROTO (void fill_mask, (int, char *));
  68. static PROTO (int text_mask, (FIELD *, char));
  69. static PROTO (int endinput, (int));
  70. static PROTO (void setcur_shape, (void));
  71.  
  72. extern int instos;    /* inchar.c */
  73.  
  74. /* static variables */
  75. static char *field_buffer;            /* internal field buffer */
  76. static char display_buff[MAX_MASK]; /* display buff, should alloc dynamically */
  77. static char *disp_buff_ptr;    /*points to current screen start of display_buff*/
  78. static int end_display;        /* TRUE if leaving a field, display buffer in full*/
  79. static int number_negative;
  80. static int calculator_flag;
  81. static int field_numeric;
  82. static char *save_buff;
  83.  
  84. char *glob_mask;                /* internal mask */
  85. int doing_memos = FALSE;
  86. int field_overflow = FALSE;
  87. int cursor_col;        /* column of cursor , used again in memo.c */
  88. int homed_field = FALSE;
  89. int delete_key = FALSE;
  90.  
  91. # ifdef MSDOS
  92. static int numlock_on;
  93. # endif
  94.  
  95.  
  96.  
  97. # ifdef UNIX
  98. int input_wx(fld, va_alist)
  99. FIELD *fld;
  100. va_dcl
  101. # else
  102. int input_wx(FIELD *fld, int va_alist, ...)
  103. # endif
  104. {
  105.     va_list ap;
  106.     int key;
  107.     int done = FALSE;
  108.     int buff_len;
  109.     static int prev_buff_len = 0;
  110.  
  111.  
  112.     /* call the pre input function if it is defined */
  113.     if (fld->f_pre)
  114.         if ((*fld->f_pre)(fld) == FALSE)
  115.             return(K_ESC);
  116.  
  117.     /* save the fbuff, if K_ESC is hit we'll restore the buffer to its
  118.     * previous contents
  119.     */
  120.     if (!doing_memos && (buff_len = strlen(fld->fbuff)) != 0)
  121.     {
  122.         if (buff_len > prev_buff_len)
  123.         {
  124.             if (save_buff)
  125.                 free (save_buff);
  126.             save_buff = (char *)alloc(buff_len + 1);
  127.             prev_buff_len = buff_len;
  128.         }
  129.         else
  130.             zerorec(save_buff, buff_len);
  131.         bytecpy(save_buff, fld->fbuff, buff_len);
  132.     }
  133.  
  134.     /* loop getting input until valid end key is pressed */
  135.     while (TRUE)
  136.     {
  137. if_bad_input:
  138.         if (fld->f_input)
  139.             ichar = (*fld->f_input)(fld);
  140.  
  141.         if (ichar == K_CR)
  142.         {
  143.             if (fld->f_val && (*fld->f_val)(fld) == FALSE)
  144.                     continue;
  145.             break;
  146.         }
  147.         else if (ichar == K_ESC)
  148.         {
  149.             if (!doing_memos && buff_len)
  150.             {
  151.                 zerorec(fld->fbuff, buff_len);
  152.                 bytecpy(fld->fbuff, save_buff, buff_len);
  153.             }
  154.             break;
  155.         }
  156.  
  157. # ifdef UNIX
  158.         va_start(ap);
  159.         key = va_arg(ap, int);
  160. # else
  161.         va_start(ap, va_alist);
  162.         key = va_alist;
  163. # endif
  164.  
  165.         while (key != 0)
  166.         {
  167.             if (ichar == key)
  168.             {
  169.                 if (fld->f_val && (*fld->f_val)(fld) == FALSE)
  170.                         goto if_bad_input;
  171.                 done = TRUE;
  172.             }
  173.             key = va_arg(ap, int);
  174.         }
  175.         va_end(ap);
  176.  
  177.  
  178.         /* check if field has over flowed before continuing */
  179.         if (field_overflow)
  180.             done = TRUE;
  181.  
  182.         /* if we're done, then we're done - and I don't mean maybe */
  183.         if (done)
  184.             break;
  185.     
  186.     }
  187.     if (ichar != K_ESC)
  188.     {
  189.         /* post input function */
  190.         if (fld->f_post)
  191.             (*fld->f_post)(fld);
  192.     }
  193.  
  194.     /* set ichar to the exitcode and return */
  195.     return(ichar);
  196. }
  197.  
  198.  
  199.  
  200. /* 
  201.  * Display a field by building the output string and displaying it.
  202. */
  203. void disp_text(field, attr)
  204.     FIELD *field;
  205.     int attr;
  206. {
  207.     char *mask;
  208.     int disp_length;
  209.  
  210.     if (field->fieldlen == 0 || !length_mask(field))
  211.         return;
  212.  
  213.     mask = field->fmask;
  214.     init_field(field, mask);
  215.     end_display = TRUE;
  216.  
  217.     /* need a routine to build the display string from the mask and the 
  218.     * buffer. Then simply display the buffer.
  219.     */
  220.     build_display_buff(field, mask);
  221.     disp_length = length_mask(field);
  222.  
  223. # ifdef INDEBUG
  224.     errmsg("disp_text(): frow %d fcol %d attr %d\n\t\tdisp_length %d buff '%s'", field->frow, field->fcol, attr, disp_length, disp_buff_ptr);
  225. # endif
  226.     ndisp_w(field->frow, field->fcol, attr, disp_length, disp_buff_ptr);
  227.     put_cursor(field, 0);
  228.  
  229.     leave_field(field);
  230. }
  231.  
  232. /*
  233.  * Return a formatted string, built from the fields contents and mask.
  234.  * Same as disp_text but don't display it
  235. */
  236. char *fmt_text(field)
  237. FIELD *field;
  238. {
  239.     char *mask;
  240.  
  241.     if (field->fieldlen == 0 || !length_mask(field))
  242.         return("");
  243.  
  244.     mask = field->fmask;
  245.     init_field(field, mask);
  246.     end_display = TRUE;
  247.  
  248.     /* need a routine to build the display string from the mask and the 
  249.     * buffer. Then simply display the buffer.
  250.     */
  251.     build_display_buff(field, field->fmask);
  252.  
  253.     leave_field(field);
  254.     return(disp_buff_ptr);
  255. }
  256.  
  257.  
  258. /*
  259.  * Read in a text, numeric, date or memo field in from the keyboard 
  260. */
  261. int text_input(field)
  262.     FIELD *field;
  263. {
  264.     char *mask;
  265.     int c;
  266.     int done = FALSE;
  267.     int curstate;
  268.     int field_negative;
  269.  
  270. #ifdef MOUSE
  271.  
  272.     int mr, mc, mh, mw;
  273.  
  274.     abs_w(&mr, &mc, &mw, &mh);
  275.     mouse_add_object(mr + field->frow, mc + field->fcol, mr + field->frow, mc + field->fcol + length_mask(field) - 1, 0, 0, "INPUT");
  276.  
  277. #endif
  278.  
  279.     curstate = cursor(ON);
  280.     setcur_shape();
  281.  
  282.     /* allocate new buffer for mask; allows for local modification
  283.     */
  284.     glob_mask= (char *)alloc(MAX(strlen(field->fmask), field->fieldlen)+1);
  285.     strcpy(glob_mask, field->fmask);
  286.     mask = glob_mask;
  287. # ifdef INDEBUG
  288.     errmsg("text_input(): after alloc(): mask '%s'\n\t\tMAX length %d", mask, MAX(strlen(field->fmask), field->fieldlen));
  289. # endif
  290.  
  291.     init_field(field, mask);
  292.  
  293.     /* if strlen(mask) < fieldlen then
  294.     *            mask is filled up to fieldlen with the last occuring mask char
  295.     *            scrolling field with input up to fieldlen chars is created
  296.     *  else strlen(mask) > fieldlen then
  297.     *            input allowed up to fieldlen chars, extra mask ignored
  298.     *
  299.     *    field->fieldlen controls length of field displayed on screen
  300.     */
  301.     if (field->ftype == F_TEXT && strlen(mask) != field->fieldlen)
  302.         fill_mask(field->fieldlen, mask);
  303.  
  304.     field_negative = set_negative_flag(mask);
  305.  
  306.  
  307.     /* this bit is gross but memos need it for the time being
  308.     */
  309.     if (!homed_field)
  310.         mask = home_field(field, mask);
  311.     else
  312.     {
  313.         int i, fx;
  314.  
  315.         for (homed_field = 0, fx = field->fx, field->fx = i = 0; i<fx; i++)
  316.             mask = forward(field, mask);
  317.     }
  318.  
  319.  
  320.     /* have a case for all of the characters possible for input
  321.     */
  322.     while (TRUE)
  323.     {
  324.         mask = bleep_over_mask(field, mask, 1);
  325.  
  326.         int_disp_text(field, field->fattrib_on, glob_mask);
  327.         c = inchar();
  328.  
  329.         switch (c)
  330.         {
  331. #ifdef MOUSE
  332.         case M_PRESS :
  333.             if (!mouse_check_bounds())
  334.                 break;
  335.         case M_RELEASE :
  336.             {
  337.                 int dummy;
  338.                 if (mouse_row == w_nrows)
  339.                     mouse_click(&dummy, c);
  340.                 else if (mouse_click(&dummy, M_PRESS))
  341.                 {
  342.                     if (c == M_PRESS)
  343.                     {
  344.                         dummy = cursor_col + mc;
  345.                         if (mouse_col > dummy)
  346.                             while (mouse_col > dummy++)
  347.                             {
  348.                                 if (dummy > (mc + field->fcol + strlen(field->fbuff)))
  349.                                     break;
  350.                                 unget_inchar(K_RIGHT);
  351.                             }
  352.                         else if (mouse_col < dummy)
  353.                             while (mouse_col < dummy--)
  354.                                 unget_inchar(K_LEFT);
  355.                     }
  356.                 }
  357.             }
  358.             break;
  359. #endif
  360.         case K_HOME :
  361.             if ((field->fcontrol&NO_HOME_END) != NO_HOME_END && !field_numeric)
  362.             {
  363.                 mask = home_field(field, mask);
  364.                 break;
  365.             }
  366.             else
  367.                 goto is_default;
  368.  
  369.         case K_END :
  370.             if ((field->fcontrol&NO_HOME_END) != NO_HOME_END && !field_numeric)
  371.             {
  372.                 mask = end_field(field, mask);
  373.                 break;
  374.             }
  375.             else
  376.                 goto is_default;
  377.  
  378.         case K_RIGHT :
  379.             if (!*field_buffer || field_buffer == field->fbuff + field->fieldlen || (doing_memos && field->fx == field->fieldlen))
  380.                 done = TRUE;
  381.             else if ((!calculator_flag && field_numeric) || !field_numeric)
  382.             {
  383.                 mask = forward(field, mask);
  384.                 if (*field_buffer == '.' && field_numeric)
  385.                 {
  386.                     while (*mask != '.')
  387.                     {
  388.                         forward_cursor(field);
  389.                         field->fx++;
  390.                         mask++;
  391.                     }
  392.                     /* do once more past decimal position */
  393.                     /*
  394.                     forward_cursor(field);
  395.                     field->fx++;
  396.                     mask++;
  397.                     */
  398. # ifdef INDEBUG
  399.                     errmsg("K_RIGHT mask '%s' cursor_col '%d'", mask, cursor_col);
  400. # endif
  401.                 }
  402.             }
  403.             break;
  404.  
  405.         case K_LEFT :
  406.             if (field_buffer != field->fbuff && !calculator_flag)
  407.             {
  408.                 mask = backspace(field, mask);
  409.                 if (*field_buffer == '.' && !calculator_flag && field_numeric)
  410.                 {
  411.                     int tmp = (int)(strchr(field->fbuff, '.') - field->fbuff);
  412.                     mask = home_field(field, mask);
  413.                     while (tmp--)
  414.                         mask = forward(field, mask);
  415. # ifdef INDEBUG
  416.                     errmsg("K_LEFT mask '%s' cursor_col '%d'", mask, cursor_col);
  417. # endif
  418.                 }
  419.             }
  420.             else
  421.                 done = TRUE;
  422.             break;
  423.  
  424.         case K_BS :
  425.             if (field_buffer != field->fbuff)
  426.             {
  427.                 if (calculator_flag && (*field_buffer == '.' || (strchr(mask, MASK_8) && strchr(field->fbuff, '.'))))
  428.                     forward_cursor(field); /* fake out */
  429.                 mask = backspace(field, mask);
  430.             }
  431.             else
  432.                 done = TRUE;
  433.  
  434.         case K_DEL :
  435.             if (c == K_DEL)
  436.                 delete_key = TRUE;
  437.             mask = del_text_char(field, mask);
  438.             if (doing_memos && !strlen(field->fbuff))
  439.                 done = TRUE;
  440.             delete_key = FALSE;
  441.             break;
  442.  
  443.         case K_INS :
  444.             instos ^= TRUE;
  445.             setcur_shape();
  446.             break;
  447.  
  448.         case K_F1 :
  449.             help_msg(field->fhelp);
  450.             break;
  451.  
  452.         case '-' :
  453.             if (field_numeric && field_negative)
  454.             {
  455.                 number_negative ^= TRUE;
  456.                 break;
  457.             }
  458.  
  459.         case '.' :
  460.             /* make sure it is not a fall thru */
  461.             if (field_numeric && *mask != '.' && strchr(mask, '.') && c == '.')
  462.             {
  463.                 /* move the data to the decimal */
  464.                 while (*mask != '.')
  465.                 {
  466.                     if (!calculator_flag)
  467.                         forward_cursor(field);
  468.                     field->fx++;
  469.                     mask++;
  470.                 }
  471.                 if (strchr(field_buffer, '.'))
  472.                     while(*field_buffer != '.')
  473.                         field_buffer++;
  474.  
  475.                 if (calculator_flag)
  476.                     forward_cursor(field);
  477.             }
  478.  
  479.         case K_UP :
  480.         case K_F4 :
  481.         case K_DOWN :
  482.         case K_F3 :
  483.  
  484.         default :
  485.         is_default:
  486.             if (endinput(c))
  487.             {
  488.                 done = TRUE;
  489.                 end_display = TRUE;
  490.                 break;
  491.             }
  492.  
  493.             if (*mask)
  494.             {
  495.                 if (!check_char(&c, mask, field))
  496.                 {
  497.                     do_bell();
  498.                     break;
  499.                 }
  500.                 if ((field_numeric && *field_buffer == '.' && c != '.') || (instos && strlen(field->fbuff) < field->fieldlen))
  501.                     move_text(field_buffer+1, field_buffer, strlen(field_buffer)-1);
  502.             }
  503.             else
  504.             {
  505.                 if ((field->fcontrol&OVERFLOW_RETURN) == OVERFLOW_RETURN)
  506.                 {
  507.                     field_overflow = TRUE;
  508.                     break;
  509.                 }
  510.                 else if ((field->fcontrol&CONFIRM_NEEDED) != CONFIRM_NEEDED)
  511.                 {    
  512.                     /* quit and return K_CR to application */
  513.                     done = TRUE;
  514.                     c = K_CR;
  515.                     break;
  516.                 }
  517.  
  518.                 mask = backspace(field, mask);
  519.                 if (!check_char(&c, mask, field))
  520.                 {
  521.                     errmsg(InvalidEntry);
  522.                     mask = forward(field, mask);
  523.                     break;
  524.                 }
  525.             }
  526.             *field_buffer = (char) c;
  527.             mask = forward(field, mask);
  528.             if (!doing_memos && !*mask && (field->fcontrol&CONFIRM_NEEDED) != CONFIRM_NEEDED)
  529.                /* last char in field, do overflow */
  530.                 field_overflow = TRUE;
  531.             break;
  532.         }
  533.         if (done || field_overflow)
  534.         {
  535.             if (field_overflow)
  536.                 c = K_CR;
  537.             break;
  538.         }
  539.     }
  540.     if (field_numeric && !*field->fbuff)
  541.         *field->fbuff = '0';
  542.  
  543.     disp_buff_ptr = display_buff;
  544.     int_disp_text(field, field->fattrib_off, glob_mask);
  545.  
  546.     leave_field(field);
  547.  
  548. # ifdef MOUSE
  549.     mouse_delete_object(0, 0, "INPUT");
  550. # endif
  551.     cursor(OFF);
  552.     free(glob_mask);
  553.     return(c);
  554. }
  555.  
  556.  
  557. /*  static void init_field(FIELD *, char *)
  558. *
  559. * sets up all the variables to appropriate defaults.
  560. */
  561. static void init_field(field, mask)
  562.     FIELD *field;
  563.     char *mask;
  564. {
  565.     end_display = FALSE;
  566.     field_overflow = FALSE;
  567.     number_negative = FALSE;
  568.     field_numeric = FALSE;
  569.     calculator_flag = FALSE;
  570.     disp_buff_ptr = display_buff;
  571.  
  572.     if (field->ftype == F_NUMERIC)
  573.         field_numeric = TRUE;
  574.  
  575.     if (input_type && field_numeric)
  576.         set_calculator_flag(mask);
  577.  
  578.     if (field_numeric && *field->fbuff == '-')
  579.     {
  580.         /* increment the fbuff past the negative sign, it gets in the way */
  581.         move_text(field->fbuff, field->fbuff+1, strlen(field->fbuff)-1);
  582.         number_negative = TRUE;
  583.     }
  584.     
  585.     clean_buffer(field);
  586.  
  587. # ifdef INDEBUG
  588.     errmsg("init_field(): mask '%s'\n\tfield->fbuff '%s'\n\tcursor_col %d", mask, field->fbuff, cursor_col);
  589. # endif
  590. }
  591.  
  592.  
  593. /*
  594. *  undo things left by init_field
  595. */
  596. static void leave_field(field)
  597.     FIELD *field;
  598. {
  599.     if (number_negative)
  600.     {
  601.         move_text(field->fbuff+1, field->fbuff, strlen(field->fbuff)-1);
  602.         *field->fbuff = '-';
  603.     }
  604. # ifdef INDEBUG
  605.     errmsg("leave_field(): field->fbuff '%s'", field->fbuff);
  606. # endif
  607. }
  608.  
  609.  
  610. /*
  611. * This routine takes the data buffer and together with the mask fills
  612. * the display buffer with the properly formatted data
  613. */
  614. static void build_display_buff(field, mask)
  615.     FIELD *field;
  616.     char *mask;
  617. {
  618.     char *m = mask;
  619.     char *b = field->fbuff;
  620.     char *d = display_buff;
  621.     char fill_char;
  622.     int decimal_increment = 0;
  623.     int save_decimal_inc = 0;
  624.     int first = TRUE;
  625.     char *last_num;   /* store the position of the last digit so we can round it
  626.                             */
  627.  
  628.     byteset(d, HARDSPACE, MAX_MASK);
  629.  
  630.     if (field_numeric)
  631.         save_decimal_inc = realign_decimals(field, m);
  632.  
  633.     if (calculator_flag || end_display)
  634.         decimal_increment = save_decimal_inc;
  635.  
  636. # ifdef INDEBUG
  637.     errmsg("begin - build_display_buff(): field->fbuff '%s'\n\t\tmask '%s'\n\t\tdecimal_increment %d", b, m, decimal_increment);
  638. # endif
  639.  
  640.     while (*m)
  641.     {
  642.         if (*b == '.' && first && field_numeric && !calculator_flag && !end_display)
  643.         {
  644.             decimal_increment = save_decimal_inc;
  645.             first = FALSE;
  646.         }
  647.  
  648.         switch(text_mask(field, *m))
  649.         {
  650.         case TEMPLATE :
  651.             switch (*m)
  652.             {
  653.             case MASK_YEAR :
  654.             case MASK_MONTH :
  655.             case MASK_DAY :
  656.             case MASK_HOUR :
  657.             case MASK_MINUTE :
  658.             case MASK_SECOND :
  659.             case MASK_WEEKDAY :
  660.             case MASK_DAY_SUFFIX :
  661.                 if (field->ftype == F_DATE || field->ftype == F_TIME)
  662.                     *d++ = ( *b ? *b++ : *m);
  663.                 break;
  664.  
  665.             case MASK_8 :
  666.             case MASK_z :
  667.             case MASK_Z :
  668.                 last_num = d;   /* allow fall through */
  669.  
  670.             case MASK_I :
  671.             case MASK_C :
  672.             case MASK_c :
  673.             case MASK_P :
  674.             case MASK_p :
  675.             case MASK_Q :
  676.             case MASK_A :
  677.             case MASK_a :
  678.             case MASK_B :
  679.             case MASK_x :
  680.             case MASK_X :
  681.             case MASK_Y :
  682.                 *d++ = (*b && !decimal_increment ? *b : HARDSPACE);
  683.                 if (!decimal_increment)
  684.                     b++;
  685.                 if (decimal_increment)
  686.                     decimal_increment--;
  687.                 break;
  688.  
  689.             case MASK_9 :
  690.                 last_num = d;
  691.                 if (end_display)
  692.                     fill_char = '0';
  693.                 else
  694.                     fill_char = HARDSPACE;
  695.  
  696.                 *d++ = ( *b && !decimal_increment ? *b : fill_char);
  697.                 if (!decimal_increment)
  698.                     b++;
  699.                 if (decimal_increment)
  700.                     decimal_increment--;
  701.                 break;
  702.  
  703.             case MASK_MONEY :
  704.                 last_num = d;
  705.                 *d++ = ( *b && !decimal_increment ? *b : DOLLAR_SIGN);
  706.                 if (!decimal_increment)
  707.                     b++;
  708.                 if (decimal_increment)
  709.                     decimal_increment--;
  710.                 break;
  711.  
  712.             case '.' :
  713.                 *d++ = '.';
  714.                 if (*b && *b != '.')
  715.                     *display_buff = '?';
  716.                 b++;
  717.                 break;
  718.  
  719.             case '(' :
  720.             case ')' :
  721.             case '-' :
  722.                 if (field_numeric && number_negative)
  723.                     *d++ = *m;
  724.                 else
  725.                     *d++ = HARDSPACE;
  726.                 break;
  727.  
  728.             default :
  729.                 *d++ = HARDSPACE;
  730.                 break;
  731.             }
  732.             break;
  733.  
  734.         case PASSWORD :
  735.             *d++ = ( *b++ ? '*' : HARDSPACE);
  736.             break;
  737.  
  738.         case FILL :
  739.             if (*m == ',' && *(d-1) == HARDSPACE)
  740.                 *d++ = HARDSPACE;
  741.             else if (*m == ',' && *(d-1) == DOLLAR_SIGN)
  742.                 *d++ = DOLLAR_SIGN;
  743.             else
  744.                 *d++ = *m;
  745.  
  746.         case SPECIAL :
  747.         default :
  748.             break;
  749.         }
  750.         m++;
  751.     }
  752.  
  753. # ifdef INDEBUG
  754.     errmsg("middle - build_disp_buff(): display_buff '%s'", display_buff);
  755. # endif
  756.  
  757.     /* round of the decimal portion */
  758.     if (field_numeric && *b && isdigit(*b) && *b >= '5')
  759.     {
  760.         while (last_num != display_buff)
  761.         {
  762.             if (*last_num < '9')
  763.                 break;
  764.             if (*last_num == '9' && *(last_num-1) == '9')
  765.                 *last_num-- = '0';
  766.             else if (*last_num == '9')
  767.             {
  768.                 *last_num-- = '0';
  769.                 if (*last_num == '.')
  770.                     last_num--;
  771.                 else
  772.                     break;
  773.             }
  774.         }
  775.         *last_num += 1;
  776.     }
  777.  
  778.     *d = '\0';
  779. # ifdef INDEBUG
  780.     errmsg("end - build_disp_buff(): field->fbuff '%s' display_buff '%s'", field->fbuff, display_buff);
  781. # endif
  782. }
  783.  
  784.  
  785. /* 
  786.  * disp_text for internal use only
  787.  */
  788. static void int_disp_text(field, attr, mask)
  789.     FIELD *field;
  790.     int attr;
  791.     char *mask;
  792. {
  793.     int disp_length;
  794.  
  795.     /* need a routine to build the display string from the mask and the 
  796.     * buffer. Then simply display the buffer.
  797.     */
  798.     build_display_buff(field, mask);
  799.     disp_length = length_mask(field);
  800.  
  801. # ifdef INDEBUG
  802.     errmsg("int_disp_text(): display_buff '%s'\n\t\tdisp_length %d", disp_buff_ptr, disp_length);
  803. # endif
  804.  
  805.     ndisp_w(field->frow, field->fcol, attr, disp_length, disp_buff_ptr);
  806.     put_cursor(field, 0);
  807. }
  808.  
  809.  
  810. /*
  811. * This routine calculates the character length of a mask
  812. * it ignores MASK_SPECIAL chars
  813. */
  814. int length_mask(field)
  815.     FIELD *field;
  816. {
  817.     char *m;
  818.     int msk_count = 0;
  819.  
  820.     for (m = field->fmask; *m; m++)
  821.     {
  822.         switch(text_mask(field, *m))
  823.         {
  824.         case PASSWORD :
  825.         case TEMPLATE :
  826.         case FILL :
  827.             msk_count++;
  828.         default :
  829.             break;
  830.         }
  831.     }
  832.     return(msk_count);
  833. }
  834.  
  835.  
  836. /* 
  837. * This routine moves the cursor to the beginning of the field
  838. */
  839. char *home_field(field, mask)
  840.     FIELD *field;
  841.     char *mask;
  842. {
  843.     field_buffer = field->fbuff;
  844.     field->fx = 0;
  845.     mask = glob_mask;
  846.     disp_buff_ptr = display_buff;
  847.     cursor_col = field->fcol;
  848.  
  849.     if (calculator_flag && strlen(field->fbuff))
  850.         while(*field_buffer && *field_buffer != '.' && *mask && field->fx < field->fieldlen)
  851.             mask = forward(field, mask);
  852.  
  853.     home_cursor(field);
  854.  
  855. # ifdef INDEBUG
  856.     errmsg("home_field(): mask '%s'\n\tfield_buffer '%s'\n\tcursor_col %d", mask, field_buffer, cursor_col);
  857. # endif
  858.     return(mask);
  859. }
  860.  
  861.  
  862. /*
  863. * This routine moves the cursor to the end of the field
  864. */
  865. static char *end_field(field, mask)
  866.     FIELD *field;
  867.     char *mask;
  868. {
  869.     field_buffer = field->fbuff;
  870.     field->fx = 0;
  871.     mask = glob_mask;
  872.     disp_buff_ptr = display_buff;
  873.     home_cursor(field);
  874.  
  875.     while(*field_buffer && *mask && field->fx < field->fieldlen)
  876.         mask = forward(field, mask);
  877.  
  878.     return(mask);
  879. }
  880.  
  881.  
  882. /*
  883. *  This routine moves the cursor back one position 
  884. */
  885. static char *backspace(field, mask)
  886.     FIELD *field;
  887.     char *mask;
  888. {
  889.     field_buffer--;
  890.     mask--;
  891.     if (field->fx > 1)
  892.         field->fx--;
  893.  
  894.     mask = bleep_over_mask(field, mask, 0);
  895.  
  896.     /* scroll the text if possible */
  897.     if ( cursor_col - field->fcol == 0)
  898.         scroll_field_right();
  899.     else
  900.     {
  901.         if ((field_buffer == field->fbuff + field->fieldlen - 1) && (cursor_col != field->fcol + field->fieldlen - 1))
  902.             back_cursor(field);
  903.         else if ( *(mask+1) && ((calculator_flag && strchr(field->fbuff, '.')) || !calculator_flag))
  904.             back_cursor(field);
  905.     }
  906.  
  907.     return(mask);
  908. }
  909.  
  910.  
  911. /*
  912. * This routine moves the cursor forward one space
  913. */
  914. static char *forward(field, mask)
  915.     FIELD *field;
  916.     char *mask;
  917. {
  918.     field_buffer++;
  919.     field->fx++;
  920.  
  921.     mask = bleep_over_mask(field, mask, 1);
  922.     mask++;
  923.  
  924.     /* if at end of display space do not move cursor, 
  925.     * scroll through field_buffer
  926.     */
  927.     if ( cursor_col - field->fcol + 1 >= length_mask(field))
  928.         scroll_field_left(field);
  929.     else if ( cursor_col - field->fcol +1 < length_mask(field))
  930.     {
  931.         if ((calculator_flag && !strchr(field_buffer, '.') && strchr(field->fbuff, '.')) || !field_numeric || !input_type)
  932.             forward_cursor(field);
  933.     }
  934.  
  935.     return(mask);
  936. }
  937.  
  938.  
  939. /*
  940. *  moves over special mask chars that cannot be inputted into
  941. *  parameter direction  -  0 = left
  942. *                                    1 = right
  943. */
  944. static char *bleep_over_mask(field, mask, direction)
  945.     FIELD *field;
  946.     char *mask;
  947.     int direction;
  948. {
  949.     while (*mask)
  950.     {
  951.         int done = FALSE;
  952.  
  953.         switch (text_mask(field, *mask))
  954.         {
  955.         case FILL :
  956.             if ((!input_type && field_numeric) || !field_numeric)
  957.             {
  958.                 if (direction)
  959.                     forward_cursor(field);
  960.                 else
  961.                     back_cursor(field);
  962.             }
  963.  
  964.         case SPECIAL :
  965.             if (direction)
  966.                 mask++;
  967.             else
  968.                 mask--;
  969.             break;
  970.  
  971.         default :
  972.             switch(*mask)
  973.             {
  974.             case '(' :
  975.             case '-' :
  976.                 if (field_numeric && !calculator_flag && *(mask+1))
  977.                 {
  978.                     if (direction)
  979.                         forward_cursor(field);
  980.                     else
  981.                         back_cursor(field);
  982.                 }
  983.             case ')' :
  984.                 if (field_numeric)
  985.                 {
  986.                     if (direction)
  987.                         mask++;
  988.                     else
  989.                         mask--;
  990.                 }
  991.                 break;
  992.             default :
  993.                 done = TRUE;
  994.                 break;
  995.             }
  996.             break;
  997.         }
  998.         if (done)
  999.             break;
  1000.     }
  1001. # ifdef INDEBUG
  1002.     errmsg("bleep_over_mask(): mask '%s'\n\tcursor_col %d", mask, cursor_col);
  1003. # endif
  1004.  
  1005.     return(mask);
  1006. }
  1007.  
  1008.  
  1009. /* 
  1010. * This routine deletes a character from the buffer
  1011. */
  1012. static char *del_text_char(field, mask)
  1013.     FIELD *field;
  1014.     char *mask;
  1015. {
  1016.  
  1017.     int tmp_len;
  1018.  
  1019.     tmp_len = field->fieldlen - (field_buffer - field->fbuff) - 1;
  1020.     if (tmp_len < 0)
  1021.         tmp_len = 0;
  1022.  
  1023.     if (*field_buffer)
  1024.     {
  1025.         char tmp = *field_buffer;
  1026.  
  1027.         if (tmp_len)
  1028.             move_text(field_buffer, field_buffer+1, tmp_len);
  1029.         field_buffer[tmp_len] = '\0';
  1030.  
  1031.         if (tmp == '.' && field_numeric && !delete_key)
  1032.             mask = end_field(field, mask);
  1033.     }
  1034.     return(mask);
  1035. }
  1036.  
  1037.  
  1038. /* 
  1039. * The next two routines handle the scrolling.  We have the display buffer
  1040. * and a pointer to it.  We increment and decrement the pointer to the 
  1041. * start of the display buffer and then display the buffer from the start 
  1042. * of the pointer
  1043. */
  1044.  
  1045. static void scroll_field_left(field)
  1046. FIELD *field;
  1047. {
  1048.     if (*disp_buff_ptr && strlen(disp_buff_ptr) > length_mask(field))
  1049.         disp_buff_ptr++;
  1050. }
  1051.  
  1052. static void scroll_field_right()
  1053. {
  1054.     if (*disp_buff_ptr && disp_buff_ptr != display_buff)
  1055.         disp_buff_ptr--;
  1056. }
  1057.  
  1058.  
  1059.  
  1060. /*
  1061. * The next 4 routines handle the cursor position.  We keep the cursor
  1062. * column in a static variable so that moving the cursor becomes
  1063. * an elementary task, so long as the cursor_col variable does not
  1064. * get screwed up.
  1065. */
  1066.  
  1067. static void put_cursor(field, pos)
  1068.     FIELD *field;
  1069.     int pos;
  1070. {
  1071.     if (pos)
  1072.         cursor_col = pos + field->fcol;
  1073.     moveto_w(field->frow, cursor_col);
  1074. }
  1075.  
  1076. static void forward_cursor(field)
  1077.     FIELD *field;
  1078. {
  1079.     cursor_col++;
  1080.     moveto_w(field->frow, cursor_col);
  1081. }
  1082.  
  1083. static void back_cursor(field)
  1084.     FIELD *field;
  1085. {
  1086.     cursor_col--;
  1087.     moveto_w(field->frow, cursor_col);
  1088. }
  1089.  
  1090. static void home_cursor(field)
  1091.     FIELD *field;
  1092. {
  1093.     cursor_col = field->fcol;
  1094.  
  1095.     if (calculator_flag)
  1096.     {
  1097.         char *tmp;
  1098.  
  1099.         if (tmp = strchr(glob_mask, '.'))
  1100.             cursor_col += (int)(tmp - glob_mask) - 1;
  1101.         else
  1102.         {
  1103.             tmp = (char *)(glob_mask + length_mask(field) - 1);
  1104.             if (*tmp == ')' || *tmp == '-')
  1105.                 tmp--;
  1106.             cursor_col += (int)(tmp - glob_mask);
  1107.         }
  1108.     }
  1109. # ifdef INDEBUG
  1110.     errmsg("home_cursor(): cursor_col = %d", cursor_col);
  1111. # endif
  1112.     moveto_w(field->frow, cursor_col);
  1113. }
  1114.  
  1115.  
  1116. /*
  1117.  * Check that an input character is valid by looking at the current mask
  1118.  * character. 
  1119. */
  1120. static int check_char(c, mask, field)
  1121.     int *c;
  1122.     char *mask;
  1123.     FIELD *field;
  1124. {
  1125.     if (*mask == MASK_I && !iscntrl(*c))
  1126.         return(TRUE);
  1127.     else if (!isprint(*c))
  1128.         return(FALSE);
  1129.  
  1130.     switch(*mask)
  1131.     {
  1132.     case MASK_c : /* alphanumeric _ - convert to lower case */
  1133.         if (isupper(*c))
  1134.             *c = tolower(*c);
  1135.         return(isalpha(*c) || isdigit(*c) || *c == '_');
  1136.  
  1137.     case MASK_P : /* alphanumeric _ and space - convert to upper case */
  1138.         if (islower(*c))
  1139.             *c = toupper(*c);
  1140.  
  1141.     case MASK_p : /* alphanumeric _ and space */
  1142.         return(isalpha(*c) || isdigit(*c) || *c == '_' || isspace(*c));
  1143.  
  1144.     case MASK_Q : /* alphanumeric _ and space - convert to lower case */
  1145.         if (isupper(*c))
  1146.             *c = tolower(*c);
  1147.         return(isalpha(*c) || isdigit(*c) || *c == '_' || isspace(*c));
  1148.  
  1149.     case MASK_A : /* alphabetic and space - convert to upper case */
  1150.         if (islower(*c))
  1151.              *c = toupper(*c);
  1152.  
  1153.     case MASK_a : /* alphabetic and space - ^ fall through */
  1154.         return(isalpha(*c) || isspace(*c));
  1155.  
  1156.     case MASK_B : /* alphabetic and space - convert to lower case */
  1157.         if (isupper(*c))
  1158.              *c = tolower(*c);
  1159.         return(isalpha(*c) || isspace(*c));
  1160.  
  1161.     case MASK_C : /* alphabetic - convert to lower case */
  1162.         if (isupper(*c))
  1163.              *c = tolower(*c);
  1164.         return(isalpha(*c));
  1165.  
  1166.     case MASK_8 : /* numeric or decimal place */
  1167.         return(isdigit(*c) || (*c == '.' && !strchr(field->fbuff, '.')));
  1168.  
  1169.     case MASK_MONEY :  /* numeric */
  1170.     case MASK_9 :
  1171.     case MASK_Z :
  1172.     case MASK_z :
  1173.         return(isdigit(*c));
  1174.  
  1175.     case MASK_AT :
  1176.         return(TRUE);
  1177.  
  1178.     case MASK_PSWD :
  1179.         return(!(*c == HARDSPACE));
  1180.  
  1181.     case '.' :
  1182.         return(*c == '.');
  1183.  
  1184.     case MASK_YEAR :
  1185.     case MASK_MONTH :
  1186.     case MASK_DAY :
  1187.     case MASK_HOUR :
  1188.     case MASK_MINUTE :
  1189.     case MASK_SECOND :
  1190.     case MASK_WEEKDAY :
  1191.     case MASK_DAY_SUFFIX :
  1192.         return(isdigit(*c));
  1193.  
  1194.     case MASK_Y : /* any character - convert to lower case */
  1195.         if (isupper(*c))
  1196.              *c = tolower(*c);
  1197.         return(TRUE);
  1198.  
  1199.     case MASK_X : /* any character - convert to upper case */
  1200.         if (islower(*c))
  1201.              *c = toupper(*c);
  1202.  
  1203.     case MASK_x : /* any character - ^ fall through */
  1204.     default:
  1205.         return(TRUE);
  1206.  
  1207.     }
  1208. }
  1209.  
  1210.  
  1211. static int realign_decimals(field, mask)
  1212.     FIELD *field;
  1213.     char *mask;
  1214. {
  1215.     int buf_count= 0;
  1216.     int msk_count= 0;
  1217.     int move_amount = 0;
  1218.     char *m = mask;
  1219.  
  1220.     if (*field->fbuff)
  1221.     {
  1222.         char *tmp1;
  1223.  
  1224.         if (strchr(mask, MASK_8))
  1225.             buf_count = strlen(field->fbuff);
  1226.         else if (tmp1 = strchr(field->fbuff, '.'))
  1227.             buf_count = (int)(tmp1 - field->fbuff);
  1228.         else if (end_display)
  1229.         {
  1230.             int space_count = 0;
  1231.  
  1232.             for (tmp1 = field->fbuff; *tmp1 && *tmp1 != ' '; tmp1++);
  1233.             for (space_count = 0; *tmp1 && *tmp1 == ' '; tmp1++, space_count++);
  1234.  
  1235.             buf_count = strlen(field->fbuff) - space_count;
  1236.         }
  1237.         else if (input_type)
  1238.             buf_count = strlen(field->fbuff);
  1239.         else
  1240.             buf_count = 0;
  1241.     }
  1242.  
  1243.     while (*m)
  1244.     {
  1245.         int done = FALSE;
  1246.  
  1247.         switch (text_mask(field, *m))
  1248.         {
  1249.         case TEMPLATE :
  1250.             if (*m == '.')
  1251.                 done = TRUE;
  1252.             else if (*m != '-' && *m != ')' && *m != '(') 
  1253.                 msk_count++;
  1254.             break;
  1255.         case FILL :
  1256.             if (*m == '*' && *(m-1) == '*')
  1257.                 msk_count++;
  1258.         default :
  1259.             break;
  1260.         }
  1261.         if (done)
  1262.             break;
  1263.         m++;
  1264.     }
  1265.  
  1266. # ifdef INDEBUG
  1267.     errmsg("realign_decimals(): msk_count %d buf_count %d", msk_count, buf_count);
  1268. # endif
  1269.  
  1270.     if (input_type || buf_count)
  1271.         move_amount = msk_count - buf_count;
  1272.     else if (*field->fbuff == '.')
  1273.         move_amount = msk_count;
  1274.  
  1275.     return(move_amount > 0 ? move_amount : 0);
  1276. }
  1277.  
  1278.  
  1279. static int set_negative_flag(mask)
  1280.     char *mask;
  1281. {
  1282. # ifdef MSDOS
  1283.     /* set numlock flag */
  1284.     numlock_on = FALSE;
  1285.     if (*mask == '&')
  1286.     {
  1287.         numlock_on = TRUE;
  1288.         mask++;
  1289.     }
  1290. # endif
  1291.  
  1292.     /* set the negative flags */
  1293.     return(*mask == '-' || *mask == '(' || *(mask + strlen(mask) -1) == '-' );
  1294. }
  1295.  
  1296.  
  1297. /*
  1298. * determine whether the mask is suitable for calculator style of input
  1299. */
  1300. static void set_calculator_flag(mask)
  1301. char *mask;
  1302. {
  1303.     char *tmp;
  1304.  
  1305.     calculator_flag = TRUE;
  1306.  
  1307.     for(tmp = mask; *tmp; tmp++)
  1308.         if (*tmp != MASK_9 &&
  1309.             *tmp != MASK_Z &&
  1310.             *tmp != MASK_z &&
  1311.             *tmp != MASK_8 &&
  1312.             *tmp != MASK_MONEY &&
  1313.             *tmp != ',' &&
  1314.             *tmp != '.' &&
  1315.             *tmp != '-' &&
  1316.             *tmp != '(' &&
  1317.             *tmp != ')' )
  1318.                 calculator_flag = FALSE;
  1319.  
  1320. # ifdef INDEBUG
  1321.     errmsg("set_calculator_flag(): calculator_flag = %d", calculator_flag);
  1322. # endif
  1323. }
  1324.  
  1325.  
  1326. void clean_buffer(field)
  1327.     FIELD *field;
  1328. {
  1329.     char *b = field->fbuff;
  1330.     int i;
  1331.  
  1332.     for (i=0; i<field->fieldlen; i++, b++)
  1333.         if (!*b || (field_numeric && *b == ' '))
  1334.             byteset(b, '\0', field->fieldlen - i);
  1335.  
  1336.     if (calculator_flag)
  1337.     {
  1338.         if (!strcmp(field->fbuff, "0"))
  1339.             *field->fbuff = '\0';
  1340.         while (*field->fbuff && *field->fbuff == '0')     /* no leading zeros */
  1341.             move_text(field->fbuff, field->fbuff+1, strlen(field->fbuff) - 1);
  1342.     }
  1343.  
  1344. # ifdef INDEBUG
  1345.     errmsg("clean_buffer(): field->fbuff = '%s'", field->fbuff);
  1346. # endif
  1347. }
  1348.  
  1349.  
  1350. /* static void fill_mask(int, char *)
  1351. *
  1352. *    fills the mask with the last occuring mask char to the length of 
  1353. *  field->fieldlen.  There should be enough space in mask; it was alloc'd
  1354. *  in the calling routine.
  1355. */
  1356. static void fill_mask(fieldlen, mask)
  1357.     int fieldlen;
  1358.     char *mask;
  1359. {
  1360.     char *m = mask;
  1361.     char msk_sav;
  1362.     int i;
  1363.  
  1364.     if ((i = strlen(m)) < fieldlen)
  1365.     {
  1366.         m += i-1;
  1367.         msk_sav = *m++;
  1368.         byteset(m, msk_sav, fieldlen - i);
  1369.     }
  1370.     *(mask + fieldlen) = '\0';
  1371.  
  1372. # ifdef INDEBUG
  1373.     errmsg("fill_mask(): mask = '%s'", mask);
  1374. # endif
  1375. }
  1376.  
  1377.  
  1378.  
  1379. /*
  1380.  * Check a character against all the valid mask characters for a text type
  1381.  * of field
  1382. */
  1383. static int text_mask(fld, c)
  1384.     FIELD *fld;
  1385.     char c;
  1386. {
  1387.     static int special = FALSE;
  1388.  
  1389.     /* check if c is a valid mask character */
  1390.     if (fld->ftype == F_NUMERIC)
  1391.     {
  1392.         switch (c)
  1393.         {
  1394.         case MASK_8 :
  1395.         case MASK_MONEY :
  1396.         case MASK_9 :
  1397.         case MASK_Z :
  1398.         case MASK_z :
  1399.             return(special ? FILL : TEMPLATE);
  1400.         case MASK_SPECIAL :
  1401.             special ^= TRUE;
  1402.             return(SPECIAL);
  1403.         default :
  1404.             switch (c)
  1405.             {
  1406.             case '.' :
  1407.             case '-' :
  1408.             case '(' :
  1409.             case ')' :
  1410.                 return(TEMPLATE);
  1411.             default :
  1412.                 return(FILL);
  1413.             }
  1414.         }
  1415.     }
  1416.     else if (fld->ftype == F_TEXT)
  1417.     {
  1418.         switch (c)
  1419.         {
  1420.         case MASK_I :
  1421.         case MASK_C :
  1422.         case MASK_c :
  1423.         case MASK_x :
  1424.         case MASK_X :
  1425.         case MASK_Y :
  1426.         case MASK_P :
  1427.         case MASK_p :
  1428.         case MASK_Q :
  1429.         case MASK_a :
  1430.         case MASK_A :
  1431.         case MASK_B :
  1432.         case MASK_8 :
  1433.         case MASK_MONEY :
  1434.         case MASK_9 :
  1435.         case MASK_Z :
  1436.         case MASK_z :
  1437.         case MASK_AT :
  1438.             return(special ? FILL : TEMPLATE);
  1439.         case MASK_PSWD :
  1440.             return(special ? FILL : PASSWORD);
  1441.         case MASK_SPECIAL :
  1442.             special ^= TRUE;
  1443.             return(SPECIAL);
  1444.         default :
  1445.             return(FILL);
  1446.         }
  1447.     }
  1448.     else  /* F_DATE or F_TIME */
  1449.     {
  1450.         switch (c)
  1451.         {
  1452.         case MASK_YEAR :
  1453.         case MASK_MONTH :
  1454.         case MASK_DAY :
  1455.         case MASK_HOUR :
  1456.         case MASK_MINUTE :
  1457.         case MASK_SECOND :
  1458.         case MASK_WEEKDAY :
  1459.         case MASK_DAY_SUFFIX :
  1460.             return(special ? FILL : TEMPLATE);
  1461.         case MASK_SPECIAL :
  1462.             special ^= TRUE;
  1463.             return(SPECIAL);
  1464.         default :
  1465.             return(FILL);
  1466.         }
  1467.     }
  1468. }
  1469.  
  1470.  
  1471. /* 
  1472.  * Test to see if a character is a end of input character 
  1473. */
  1474. static int endinput(c)
  1475. int c;
  1476. {
  1477.     switch (c)
  1478.     {
  1479.     case K_CR :
  1480.     case K_ESC :
  1481.     case K_UP :
  1482.     case K_DOWN :
  1483.     case K_RIGHT :
  1484.     case K_LEFT :
  1485.     case K_PGUP :
  1486.     case K_PGDN :
  1487.     case K_HOME :
  1488.     case K_END :
  1489.     case K_TAB :
  1490.     case K_F1 :
  1491.     case K_F2 :
  1492.     case K_F3 :
  1493.     case K_F4 :
  1494.     case K_F5 :
  1495.     case K_F6 :
  1496.     case K_F7 :
  1497.     case K_F8 :
  1498.     case K_F9 :
  1499.     case K_F10 :
  1500.         return TRUE;
  1501.  
  1502.     default:
  1503.         return FALSE;
  1504.     }
  1505. }
  1506.  
  1507. /* 
  1508.  * Set the cursor shape.
  1509. */
  1510. # ifdef MSDOS
  1511. # include "../win/dos/pregs.h"
  1512. # endif
  1513.  
  1514. /* keep in os dependent code */
  1515. static void setcur_shape()
  1516. {
  1517. # ifdef MSDOS
  1518.  
  1519.     RegStorage;
  1520.     unsigned int cursor_size;
  1521.  
  1522.     /* set instos for inchar() and set the shape of the cursor */
  1523.    cursor_size = (instos ? 0x0106 : 0x0607);
  1524.  
  1525.     Regs_ah = 0x01;
  1526.     Regs_cx = cursor_size;
  1527.     Video();
  1528.  
  1529. # endif
  1530. }
  1531.  
  1532. /*
  1533.  * Move specified amount of text to destination from source. Do the move
  1534.  * intelligently by checking which memory location is greater.
  1535.  * (from GEO.)
  1536. */
  1537. void move_text(dest, src, cnt)
  1538.     char *dest;
  1539.     char *src;
  1540.     int cnt;
  1541. {
  1542.     int i;
  1543.     if (src == NULL || dest == NULL)
  1544.         return;
  1545.     if (src == dest)
  1546.         return;
  1547.     if (src < dest)
  1548.         /* Move up */
  1549.         for (i = cnt; i >= 0; i--)
  1550.             *(dest+i) = *(src+i);
  1551.     else
  1552.         /* Move down */
  1553.         for (i = 0; i <= cnt; i++)
  1554.             *(dest+i) = *(src+i);
  1555. }
  1556.