home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / CODE4-1.ZIP / SOURCE.ZIP / G4.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-10  |  21.4 KB  |  994 lines

  1. /* g4.c    (c)Copyright Sequiter Software Inc., 1987, 1988, 1989.  All rights reserved.
  2.  
  3.    GET Routines
  4. */
  5.  
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #ifndef UNIX
  9.    #include <io.h>
  10.    #include <dos.h>
  11. #endif
  12.  
  13. #include "w4.h"
  14. #include "d4base.h"
  15. #include "g4char.h"
  16.  
  17. #ifdef OS2
  18.    typedef struct
  19.    {
  20.       unsigned char   char_code ;
  21.       unsigned char   scan_code ;
  22.       unsigned char   char_status ;
  23.       unsigned char   shift_status ;
  24.       int    shift_state ;
  25.       double time_stamp ;
  26.    }  KBD_INFO ;
  27.  
  28.    extern far pascal KBDCHARIN( KBD_INFO far *, int, int ) ;
  29. #endif
  30.  
  31. extern    CB_WINDOW *v4window_ptr ;
  32. extern  int     v4cur_window ;
  33. extern  int     toupper(int) ;
  34.  
  35. extern  GET   *v4get ;
  36. static    int   insert =    0 ;
  37. static  long  prev_attribute = 7 ;
  38.  
  39. static void  g4check_get( GET * ) ;
  40. static int   g4from_data( GET *, char * ) ;
  41. static void  g4display_get( GET * ) ;
  42. static int   g4fill_data( GET *, char *, char * ) ;
  43. static int   g4right_pos( int, int, char * ) ;
  44. static int   g4num_pos( int, int, char * ) ;
  45.  
  46.  
  47. /* Allocates some get memory */
  48.  
  49. GET *  g4alloc( row, col, data_ptr, type )
  50. int   row, col ;
  51. char  type ;
  52. void *data_ptr ;
  53. {
  54.    GET *  get_ptr ;
  55.  
  56.    if (v4get == (GET *) 0)  
  57.       if ( h4create( (char **) &v4get, 20, sizeof(GET), 10) < 0)  return( (GET *) 0 ) ;
  58.  
  59.    v4window_ptr->last_get =  h4get( (char **) &v4get, v4window_ptr->last_get ) ;
  60.    if ( v4window_ptr->last_get < 0 )  return( (GET *) 0 ) ;
  61.  
  62.    if ( v4window_ptr->first_get < 0 )
  63.       v4window_ptr->first_get =  v4window_ptr->last_get ;
  64.  
  65.    get_ptr =  v4get+  v4window_ptr->last_get ;
  66.    get_ptr->window_ref =  v4cur_window ;
  67.    get_ptr->num_decimals =  -1 ;   /* Not Yet Set Flag */
  68.    get_ptr->attribute =  v4window_ptr->get_attribute ;
  69.    memcpy( get_ptr->delimiter, v4window_ptr->get_delimiter,
  70.        sizeof(get_ptr->delimiter) ) ;
  71.  
  72.    get_ptr->row  =  row ;
  73.    get_ptr->col  =  col ;
  74.    get_ptr->type =  type ;
  75.    get_ptr->data =  data_ptr ;
  76.  
  77.    return( get_ptr ) ;
  78. }
  79.  
  80.  
  81. void  g4( row, col, buffer )
  82. int   row, col ;
  83. char *buffer ;
  84. {
  85.    g4alloc( row, col, (void *) buffer, 'C' ) ;
  86. }
  87.  
  88.  
  89. long  g4attribute( attribute )
  90. long  attribute ;
  91. {
  92.    v4window_ptr->get_attribute =  attribute ;
  93.    return ( v4window_ptr->get_attribute ) ;
  94. }
  95.  
  96.  
  97. void  g4call( routine, call_data )
  98. GET_ROUTINE *routine ;
  99. int  call_data ;
  100. {
  101.    v4get[ v4window_ptr->last_get].call =  routine ;
  102.    v4get[ v4window_ptr->last_get].call_data =  call_data ;
  103. }
  104.  
  105.  
  106. /* The character is returned according to the IBM scan code format. */
  107.  
  108. #ifdef OS2
  109. int  g4char()
  110. {
  111.    KBD_INFO  kbd_info ;
  112.  
  113.    KBDCHARIN( (KBD_INFO far *) &kbd_info, 0, 0 ) ;
  114.  
  115.    if ( kbd_info.char_code )
  116.    {
  117.       if ( kbd_info.char_code == (unsigned char) 0xE0 )
  118.      kbd_info.char_code =  0 ;
  119.       else
  120.      return ( (int) kbd_info.char_code ) ;
  121.    }
  122.  
  123.    return ( *((int *) &kbd_info.char_code) ) ;
  124. }
  125. #else
  126. #ifdef UNIX
  127. int  g4char()
  128. {
  129.    int  rc ;
  130.  
  131.    for( rc = -1; rc <= 0; rc =  getch() ) ;
  132.  
  133.    return ( rc ) ;
  134. }
  135.  
  136. #else
  137. int  g4char()
  138. {
  139.    union  REGS    regs ;
  140.  
  141.    regs.h.ah = 0x7 ;
  142.    int86( 0x21, ®s, ®s ) ;
  143.  
  144.    if ( regs.h.al != 0 )   return ( (int) regs.h.al ) ;
  145.  
  146.    int86( 0x21, ®s, ®s ) ;
  147.    return ( (int) (regs.h.al << 8) ) ;
  148. }
  149. #endif
  150. #endif
  151.  
  152.  
  153. void  g4date( row, column, date_ptr )
  154. int   row, column ;
  155. char *date_ptr ;
  156. {
  157.    g4alloc( row, column, date_ptr, 'D' ) ;
  158. }
  159.  
  160.  
  161. void  g4delimiter( delimiter )
  162. char *delimiter ;
  163. {
  164.    memcpy( v4window_ptr->get_delimiter, delimiter, 2 ) ;
  165. }
  166.  
  167.  
  168. void  g4double( row, column, double_ptr )
  169. int    row, column ;
  170. double *double_ptr ;
  171. {
  172.    g4alloc( row, column, (void *) double_ptr, 'd' ) ;
  173. }
  174.  
  175.  
  176. void  g4int( row, column, int_ptr )
  177. int   row, column ;
  178. int  *int_ptr ;
  179. {
  180.    g4alloc( row, column, int_ptr, 'i' ) ;
  181. }
  182.  
  183.  
  184. void  g4logical( row, column, logical_ptr )
  185. int   row, column ;
  186. int  *logical_ptr ;
  187. {
  188.    g4alloc( row, column, (void *) logical_ptr, 'L' ) ;
  189. }
  190.  
  191.  
  192. void  g4long( row, column, long_ptr )
  193. int   row, column ;
  194. long *long_ptr ;
  195. {
  196.    g4alloc( row, column, (void *) long_ptr, 'l' ) ;
  197. }
  198.  
  199.  
  200. void  g4message( message )
  201. char *message ;
  202. {
  203.    if ( v4window_ptr->last_get < 0 )  return ;
  204.    v4get[ v4window_ptr->last_get].message =  message ;
  205. }
  206.  
  207.  
  208. void  g4numeric( row, column, num_ptr )
  209. int  row, column ;
  210. char *num_ptr ;
  211. {
  212.    g4alloc( row, column, num_ptr, 'N' ) ;
  213. }
  214.  
  215.  
  216. void  g4picture( picture )
  217. char *picture ;
  218. {
  219.    if ( v4window_ptr->last_get < 0 )  return ;
  220.    v4get[ v4window_ptr->last_get].picture  =    picture ;
  221. }
  222.  
  223.  
  224. void  g4upper()
  225. {
  226.    v4get[ v4window_ptr->last_get].upper_convert =  1 ;
  227. }
  228.  
  229.  
  230. void  g4valid( routine )
  231. int  (*routine)(GET *) ;
  232. {
  233.    if ( v4window_ptr->last_get < 0 )  return ;
  234.    v4get[ v4window_ptr->last_get].valid  =  routine ;
  235. }
  236.  
  237.  
  238. void  g4width( width_data, width_scr )
  239. int   width_data, width_scr ;
  240. {
  241.    GET *get_ptr ;
  242.    if ( v4window_ptr->last_get < 0 ) return ;
  243.  
  244.    get_ptr =  v4get+ v4window_ptr->last_get ;
  245.  
  246.    if ( width_data > 0 )
  247.       get_ptr->width_data =   width_data ;
  248.    if ( width_scr > 0 )
  249.       v4get[ v4window_ptr->last_get].width_scr =   width_scr ;
  250. }
  251.  
  252.  
  253. static void  g4check_get( get_ptr )
  254. GET  *get_ptr ;
  255. {
  256.    int      picture_len, i ;
  257.    char  *ptr ;
  258.  
  259.    if ( get_ptr->picture == (char *) 0)
  260.       picture_len =  0 ;
  261.    else
  262.    {
  263.       picture_len =  strlen( get_ptr->picture) ;
  264.    }
  265.  
  266.    switch( get_ptr->type )
  267.    {
  268.       case 'C':
  269.       case 'N':
  270.       case 'D':
  271.      if ( get_ptr->width_data <= 0)
  272.         get_ptr->width_data =  picture_len ;
  273.      if ( get_ptr->width_data <= 0)
  274.      {
  275.         if ( get_ptr->type == 'D' )
  276.            get_ptr->width_data =  9 ; /* MMM/DD/YY */
  277.         else
  278.            get_ptr->width_data =  strlen( get_ptr->data ) ;
  279.      }
  280.      if ( get_ptr->width_data <= 0 )
  281.         get_ptr->width_data =  1 ;
  282.      if ( get_ptr->width_scr <= 0 || get_ptr->width_scr > get_ptr->width_data)
  283.         get_ptr->width_scr =  get_ptr->width_data ;
  284.  
  285.      if ( get_ptr->type == 'N' )
  286.      {
  287.         if ( picture_len > 0 )
  288.            ptr =  get_ptr->picture ;
  289.         else
  290.            ptr =  get_ptr->data ;
  291.  
  292.         for ( i=1; i<= get_ptr->width_data && *ptr != '\0'; i++, ptr++ )
  293.            if ( *ptr == '.' )
  294.            {
  295.           get_ptr->num_decimals =  get_ptr->width_data - i ;
  296.           break ;
  297.            }
  298.  
  299.         if ( get_ptr->num_decimals < 0 )  get_ptr->num_decimals = 0 ;
  300.      }
  301.      break ;
  302.  
  303.       case 'L':
  304.      get_ptr->width_data =    get_ptr->width_scr =  1 ;
  305.      break ;
  306.  
  307.       case 'l':
  308.       case 'i':
  309.      if ( get_ptr->width_scr <= 0)
  310.      {
  311.         if ( picture_len > 0 )
  312.            get_ptr->width_scr =  picture_len ;
  313.         else
  314.         {
  315.            if ( get_ptr->type == 'l' )
  316.           get_ptr->width_scr =  8 ;
  317.            else
  318.           get_ptr->width_scr =  4 ;
  319.         }
  320.      }
  321.      get_ptr->width_data =    get_ptr->width_scr ;
  322.      break ;
  323.  
  324.       case 'd':
  325.      if ( picture_len > 0 )
  326.      {
  327.         ptr =  strchr( get_ptr->picture, '.' ) ;
  328.         if ( ptr == (char *) 0)
  329.            get_ptr->num_decimals =    0 ;
  330.         else
  331.            get_ptr->num_decimals =
  332.              picture_len - (int) (ptr-get_ptr->picture) -1;
  333.  
  334.         get_ptr->width_scr =  picture_len ;
  335.      }
  336.      else
  337.      {
  338.         if ( get_ptr->width_scr <= 0)  get_ptr->width_scr =  8 ;
  339.         if ( get_ptr->num_decimals < 0)
  340.            get_ptr->num_decimals =    2 ;
  341.         if ( get_ptr->num_decimals >= get_ptr->width_scr)
  342.            get_ptr->num_decimals = 0 ;
  343.      }
  344.  
  345.      get_ptr->width_data =    get_ptr->width_scr ;
  346.      break ;
  347.    }
  348. }
  349.  
  350.  
  351. #define  PICTURE_CHRS  "!9#ALNYXCMD"
  352.  
  353. static int  g4from_data( get_ptr, chr_buf )
  354. GET  *get_ptr ;
  355. char *chr_buf ;
  356. {
  357.    char *ptr, pict_char ;
  358.    int    i, len ;
  359.  
  360.    if ( get_ptr->type == 'd' )
  361.    {
  362.       ptr = c4dtoa( * ((double *) get_ptr->data), get_ptr->width_scr,
  363.                   get_ptr->num_decimals);
  364.       memcpy( chr_buf, ptr, get_ptr->width_scr ) ;
  365.       return( get_ptr->width_scr ) ;
  366.    }
  367.  
  368.    if ( get_ptr->type == 'l' )
  369.    {
  370.       c4ltoa( * ((long *) get_ptr->data), chr_buf, get_ptr->width_scr ) ;
  371.       return( get_ptr->width_scr ) ;
  372.    }
  373.  
  374.    if ( get_ptr->type == 'i' )
  375.    {
  376.       c4ltoa((long) (* ((int *)get_ptr->data)), chr_buf, get_ptr->width_scr) ;
  377.       return( get_ptr->width_scr ) ;
  378.    }
  379.  
  380.    if ( get_ptr->type == 'D' )
  381.    {
  382.       if ( get_ptr->picture == (char *) 0 )
  383.       {
  384.      ptr =    c4dt_format( get_ptr->data, DEFAULT_DATE ) ;
  385.      len =  strlen(DEFAULT_DATE ) ;
  386.       }
  387.       else
  388.       {
  389.      ptr =    c4dt_format( get_ptr->data, get_ptr->picture ) ;
  390.      len =  strlen( get_ptr->picture ) ;
  391.       }
  392.  
  393.       memcpy( chr_buf, ptr, len ) ;
  394.       return( len ) ;
  395.    }
  396.  
  397.    if ( get_ptr->type == 'L' )
  398.    {
  399.       if ( get_ptr->picture == (char *) 0 )
  400.      pict_char =  'L' ;
  401.       else
  402.      pict_char =  get_ptr->picture[0] ;
  403.  
  404.       if ( * ((int *) get_ptr->data) )
  405.       {
  406.      if ( pict_char == 'L' )
  407.         chr_buf[0] = 'T' ;
  408.      else
  409.         chr_buf[0] = 'Y' ;
  410.       }
  411.       else
  412.       {
  413.      if ( pict_char == 'L' )
  414.         chr_buf[0] =  'F' ;
  415.      else
  416.         chr_buf[0] =  'N' ;
  417.       }
  418.       return 1 ;
  419.    }
  420.  
  421.    if ( get_ptr->type == 'N' && get_ptr->num_decimals > 0 )
  422.    {
  423.       ( (char *)get_ptr->data )
  424.      [ get_ptr->width_data - get_ptr->num_decimals - 1] = '.' ;
  425.    }
  426.  
  427.    memcpy( chr_buf, get_ptr->data, get_ptr->width_data ) ;
  428.  
  429.    ptr =  get_ptr->picture ;
  430.    if ( ptr != (char *) 0)
  431.       for ( i= 0; *ptr != '\0'; i++, ptr++ )
  432.       {
  433.      if ( strchr( PICTURE_CHRS, *ptr) == (char *) 0 )
  434.         chr_buf[i] =  get_ptr->picture[i] ;
  435.       }
  436.  
  437.    return( get_ptr->width_data ) ;
  438. }
  439.  
  440.  
  441. static void  g4display_get( get_ptr )
  442. GET  *get_ptr ;
  443. {
  444.    char  buf[MAX_GET_WIDTH] ;
  445.  
  446.    g4from_data( get_ptr, buf ) ;
  447.  
  448.    if ( get_ptr->delimiter[0] != '\0' )
  449.    {
  450.       w4attribute( prev_attribute ) ;
  451.       w4num( get_ptr->row, get_ptr->col-1, get_ptr->delimiter, 1 ) ;
  452.    }
  453.  
  454.    w4attribute( get_ptr->attribute ) ;
  455.    w4num( get_ptr->row, get_ptr->col, buf, get_ptr->width_scr ) ;
  456.  
  457.    if ( get_ptr->delimiter[1] != '\0' )
  458.    {
  459.       w4attribute( prev_attribute ) ;
  460.       w4num( get_ptr->row, get_ptr->col+get_ptr->width_scr,
  461.          get_ptr->delimiter+1, 1 ) ;
  462.    }
  463. }
  464.  
  465.  
  466. void  g4display()
  467. {
  468.    GET     *get_ptr  ;
  469.    int      on_get   ;
  470.  
  471.    prev_attribute =  v4window_ptr->attribute ;
  472.  
  473.    on_get =  v4window_ptr->last_get ;
  474.  
  475.    while ( on_get >= 0 )
  476.    {
  477.       get_ptr =  v4get+ on_get ;
  478.  
  479.       g4check_get( get_ptr ) ;
  480.       g4display_get( get_ptr ) ;
  481.  
  482.       on_get =    get_ptr->prev ;
  483.    }
  484.  
  485.    v4window_ptr->attribute =  prev_attribute ;
  486. }
  487.  
  488.  
  489. static g4fill_data( get_ptr, buffer, picture )
  490. GET  *get_ptr ;
  491. char *buffer ;
  492. char *picture ;
  493. {
  494.    /* Transfer Back to    get_ptr->data */
  495.    switch ( get_ptr->type )
  496.    {
  497.       case 'd':
  498.      *((double *)get_ptr->data) =
  499.              c4atod( buffer, get_ptr->width_scr ) ;
  500.      break ;
  501.  
  502.       case 'N':
  503.      memcpy( get_ptr->data,
  504.          c4dtoa( c4atod(buffer, get_ptr->width_data),
  505.              get_ptr->width_data, get_ptr->num_decimals),
  506.          get_ptr->width_data ) ;
  507.      break ;
  508.  
  509.       case 'i':
  510.      *((int *)get_ptr->data) =
  511.          (int) c4atoi( (char *) buffer, get_ptr->width_scr ) ;
  512.      break ;
  513.  
  514.       case 'l':
  515.      buffer[get_ptr->width_scr] =  '\0' ;
  516.      *((long *)get_ptr->data) =  (long) atol( (char *) buffer ) ;
  517.      break ;
  518.  
  519.       case 'D':
  520.      memcpy( get_ptr->data, c4dt_unformat((char *) buffer, picture), 8) ;
  521.      break;
  522.  
  523.       case 'L':
  524.      if ( buffer[0] == (int) 'Y'  ||  buffer[0] == (int) 'T' ||
  525.           buffer[0] == (int) 't' || buffer[0] == (int) 'y' )
  526.         *((int *)get_ptr->data) =  1 ;
  527.      else
  528.         *((int *)get_ptr->data) =  0 ;
  529.      break ;
  530.  
  531.       default:
  532.      memcpy( get_ptr->data, buffer, get_ptr->width_data ) ;
  533.      break ;
  534.    }
  535.  
  536.    return 0 ;
  537. }
  538.  
  539.  
  540. static    g4right_pos( buffer_pos, width_data, picture )
  541. char *picture ;
  542. int   buffer_pos, width_data ;
  543. {
  544.    buffer_pos++ ;
  545.  
  546.    while ( buffer_pos < width_data )
  547.       if ( strchr(PICTURE_CHRS,picture[buffer_pos]) == 0)
  548.      buffer_pos++ ;
  549.       else
  550.      break ;
  551.  
  552.    if ( buffer_pos == width_data)
  553.    {
  554.       buffer_pos-- ;
  555.       while (buffer_pos > 0 &&
  556.        strchr(PICTURE_CHRS,picture[buffer_pos]) == 0) buffer_pos-- ;
  557.    }
  558.  
  559.    return  buffer_pos ;
  560. }
  561.  
  562.  
  563. /* Counts the Number of Positions to the Next Picture Data Character */
  564.  
  565. static    g4num_pos( buffer_pos, width_data, picture )
  566. char *picture ;
  567. int   buffer_pos, width_data ;
  568. {
  569.    int    on_pos ;
  570.  
  571.    on_pos =  buffer_pos ;
  572.  
  573.    while ( on_pos < width_data )
  574.       if ( strchr(PICTURE_CHRS,picture[on_pos]) == 0)
  575.      break ;
  576.       else
  577.      on_pos++ ;
  578.  
  579.    return ( on_pos - buffer_pos ) ;
  580. }
  581.  
  582.  
  583. static int  bell_flag =  0 ;
  584.  
  585. int  g4bell_set( set_flag )
  586. int  set_flag ;
  587. {
  588.    if ( set_flag >= 0 )   bell_flag =  set_flag ;
  589.  
  590.    return ( bell_flag ) ;
  591. }
  592.  
  593.  
  594. void  g4bell()
  595. {
  596.    if ( bell_flag )  write( 1, "\7", 1 ) ;
  597. }
  598.  
  599.  
  600. g4read()
  601. {
  602.    int      get_on, first, buffer_pos, buffer_off, buffer_width ;
  603.    int      cur_pos, num, ok, i ;
  604.    int    rc ;
  605.    GET     *get_ptr ;
  606.    char   chr ;
  607.    unsigned char   buffer[MAX_GET_WIDTH], picture[MAX_GET_WIDTH] ;
  608.  
  609.    g4display() ;
  610.    prev_attribute =  v4window_ptr->attribute ;
  611.  
  612.    first  =  1 ;
  613.    get_on =  v4window_ptr->first_get ;
  614.    if ( get_on < 0 )  return 0 ;
  615.  
  616.    for (;;)
  617.    {
  618.       if ( first )  /* First time for this 'get' */
  619.       {
  620.      first =  0 ;
  621.      buffer_pos =  buffer_off =  0 ;
  622.  
  623.      get_ptr =  v4get +  get_on ;
  624.      g4message_do( get_ptr->message ) ;
  625.  
  626.      /* Buffer is filled and the width is returned by 'g4from_data' */
  627.      buffer_width =  g4from_data( get_ptr, buffer ) ;
  628.      buffer[buffer_width] =  '\0' ;
  629.  
  630.      memset( picture, 0, (size_t) sizeof(picture) ) ;
  631.      if ( get_ptr->picture != (char *) 0 )
  632.         strncpy( picture, get_ptr->picture, sizeof(picture) ) ;
  633.      else
  634.      {
  635.         switch( get_ptr->type )
  636.         {
  637.            case 'D':
  638.           strcpy( picture, DEFAULT_DATE ) ;
  639.           break ;
  640.  
  641.            case 'N':
  642.            case 'd':
  643.            case 'i':
  644.           memset( picture, (int) '#', (size_t) get_ptr->width_scr ) ;
  645.           if ( get_ptr->num_decimals > 0)
  646.           {
  647.              i =  get_ptr->width_scr - get_ptr->num_decimals - 1 ;
  648.              buffer[i] =  picture[i] =    '.' ;
  649.           }
  650.           break ;
  651.  
  652.            case 'L':
  653.           picture[0] = 'L' ;
  654.           picture[1] = '\0' ;
  655.           break ;
  656.         }
  657.      }
  658.       }
  659.  
  660.       w4attribute( get_ptr->attribute ) ;
  661.  
  662.       if ( buffer_pos >= buffer_width )
  663.       {
  664.      rc =  RETURN ;
  665.      w4num( get_ptr->row, get_ptr->col, buffer, get_ptr->width_scr ) ;
  666.       }
  667.       else
  668.       {
  669.      rc =  0 ;
  670.  
  671.      if ( strchr( PICTURE_CHRS, picture[buffer_pos] ) == (char *) 0  &&
  672.           picture[buffer_pos] >= 0x20  &&  picture[buffer_pos] <= 0xFF)
  673.      {
  674.         buffer[buffer_pos] =  picture[buffer_pos] ;
  675.         buffer_pos++ ;
  676.         continue ;
  677.      }
  678.  
  679.      if ( buffer_off <= buffer_pos - get_ptr->width_scr )
  680.           buffer_off =  1+ buffer_pos - get_ptr->width_scr ;
  681.      if ( buffer_pos < buffer_off )  buffer_off =  buffer_pos ;
  682.      w4num(get_ptr->row,get_ptr->col,buffer+buffer_off,get_ptr->width_scr);
  683.      w4cursor( get_ptr->row, get_ptr->col+ buffer_pos - buffer_off ) ;
  684.  
  685.      if ( get_ptr->call != (GET_ROUTINE *) 0 )
  686.      {
  687.         buffer[buffer_width] = '\0' ;
  688.         rc = (*get_ptr->call)( get_ptr, buffer, get_ptr->call_data);
  689.         if ( rc == -1 )  continue ;
  690.      }
  691.      if ( rc == 0 )
  692.         rc =  g4char() ;
  693.      if ( (get_ptr->upper_convert ||  picture[buffer_pos] == '!')  &&  rc >= 0x20  &&  rc <= 0xFF )
  694.         rc =  toupper( rc ) ;
  695.       }
  696.  
  697.       switch ( rc )
  698.       {
  699.      case INS:
  700.      case CTRL_V:
  701.         insert =  ! insert ;
  702.         if ( insert )
  703.            w4cursor_size( 4, 7 ) ;
  704.         else
  705.            w4cursor_size( 6, 7 ) ;
  706.         continue ;
  707.  
  708.      case BACK_SPACE:
  709.      case LEFT:
  710.      case CTRL_S:
  711.         cur_pos =  buffer_pos - 1 ;
  712.  
  713.         while (cur_pos >= 0)
  714.            if ( strchr(PICTURE_CHRS,picture[cur_pos]) == 0 )
  715.           cur_pos-- ;
  716.            else
  717.           break ;
  718.  
  719.         if ( cur_pos < 0 )    continue ;
  720.  
  721.         buffer_pos =  cur_pos ;
  722.         if ( rc == LEFT || rc == CTRL_S )  continue ;
  723.  
  724.         /* BACK_SPACE is a LEFT and a DEL */
  725.  
  726.      case DEL:
  727.      case CTRL_G:
  728.  
  729.         num =  g4num_pos( buffer_pos, get_ptr->width_data, picture) ;
  730.         if ( num == 0 )  continue ;
  731.         memcpy( buffer+ buffer_pos, buffer + buffer_pos+1, num ) ;
  732.         buffer[buffer_pos+num-1] = ' ' ;
  733.         continue ;
  734.  
  735.      case CTRL_Y:
  736.         cur_pos =  buffer_pos ;
  737.         memset( buffer + buffer_pos, (int) ' ',
  738.          (size_t) g4num_pos( buffer_pos, get_ptr->width_data, picture));
  739.         continue ;
  740.  
  741.      case RIGHT:
  742.      case CTRL_D:
  743.         buffer_pos =
  744.          g4right_pos( buffer_pos, get_ptr->width_data, picture);
  745.         continue ;
  746.  
  747.      case HOME:
  748.      case CTRL_A:
  749.         buffer_pos = 0;
  750.         continue;
  751.  
  752.      case END:
  753.      case CTRL_F:
  754.         buffer_pos =  get_ptr->width_data - 1;
  755.         while ( buffer_pos >= 0 )
  756.            if (buffer[buffer_pos] == ' ' || buffer[buffer_pos] == '\0')
  757.           buffer_pos-- ;
  758.            else
  759.           break ;
  760.  
  761.         buffer_pos =
  762.          g4right_pos( buffer_pos, get_ptr->width_data, picture);
  763.         continue ;
  764.       }
  765.  
  766.       if ( rc < 0x20 || rc > 0xFF )
  767.       {
  768.      switch( rc )
  769.      {
  770.         case CTRL_HOME:
  771.            first =    1 ;
  772.            get_on =  v4window_ptr->first_get ;
  773.            g4bell() ;
  774.            break ;
  775.  
  776.         case CTRL_END:
  777.            first =    1 ;
  778.            get_on =  v4window_ptr->last_get ;
  779.            g4bell() ;
  780.            break ;
  781.  
  782.         case UP:
  783.         case SHIFT_TAB:
  784.         case CTRL_Z:
  785.            first =    1 ;
  786.            if ( get_ptr->prev >= 0 )   get_on =  get_ptr->prev ;
  787.            g4bell() ;
  788.            break ;
  789.  
  790.         case DOWN:
  791.         case RETURN:
  792.         case TAB:
  793.         case CTRL_B:
  794.            first =    1 ;
  795.            buffer_pos =  0 ;
  796.            get_on =  get_ptr->next ;
  797.            g4bell() ;
  798.            break ;
  799.  
  800.         /* Also Return if a Function Key was Pressed */
  801.         default:
  802.            if (rc == CTRL_W  ||  rc == CTRL_Q  ||  rc == ESC || rc > 0xFF)
  803.            {
  804.           get_on =  first =  -1 ;
  805.           g4bell() ;
  806.            }
  807.            break ;
  808.      }
  809.  
  810.      w4attribute( prev_attribute ) ;
  811.  
  812.      if ( first )
  813.      {
  814.         g4fill_data( get_ptr, buffer, picture ) ;
  815.  
  816.         if ( get_ptr->valid != 0 &&  rc != ESC && rc != CTRL_Q )
  817.            if ( (*get_ptr->valid)( get_ptr ) )
  818.            {
  819.           first = 0 ;  /* Not Valid */
  820.           continue ;
  821.            }
  822.  
  823.         if ( get_ptr->type == 'D' && rc != ESC && rc != CTRL_Q )
  824.         {
  825.            double  temp_data ;
  826.            int     date_rc ;
  827.  
  828.            /* Date Check */
  829.            date_rc =  c4dt_index( (char *) get_ptr->data, &temp_data ) ;
  830.            if ( date_rc == -1 )
  831.            {
  832.           first = 0 ;
  833.           buffer[buffer_width] =  '\0' ;
  834.           w4display( " Illegal Date: ", buffer, (char *) 0) ;
  835.           continue ;
  836.            }
  837.         }
  838.  
  839.         g4display_get( get_ptr ) ;
  840.      }
  841.  
  842.      if ( get_on < 0 )
  843.      {
  844.         if ( v4window_ptr->release )   g4release(1) ;
  845.  
  846.         w4attribute( prev_attribute ) ;
  847.         g4message_do( "" ) ;
  848.         w4cursor( -1,-1 ) ;
  849.         return rc ;
  850.      }
  851.  
  852.      continue ;
  853.       }
  854.  
  855.       /* Check the Picture Template */
  856.  
  857.       if ( picture[buffer_pos] != '\0' )
  858.       {
  859.      ok  =    0 ;
  860.      chr =    (char) rc ;
  861.  
  862.      switch( picture[buffer_pos] )
  863.      {
  864.         case '9':
  865.         case '#':
  866.            if ( chr >= '0' && chr <= '9' )  ok = 1 ;
  867.            if ( (chr == '+' || chr == '-' || chr == ' ')    &&
  868.                    picture[buffer_pos] == '#')
  869.           ok =    1 ;
  870.  
  871.            if ( chr == '.'  &&  get_ptr->num_decimals > 0 )
  872.            {
  873.           int  num_shift ;
  874.  
  875.           num_shift =  get_ptr->width_scr - get_ptr->num_decimals -
  876.                    buffer_pos - 1 ;
  877.  
  878.           if ( --buffer_pos < 0 )  buffer_pos = 0 ;
  879.  
  880.           if ( num_shift > 0  &&  buffer[buffer_pos] != ' ' )
  881.           {
  882.              memmove( buffer+ num_shift, buffer,
  883.                   get_ptr->width_scr - num_shift ) ;
  884.              memset( buffer, (int) ' ', (size_t) num_shift ) ;
  885.           }
  886.  
  887.           buffer_pos = get_ptr->width_scr - get_ptr->num_decimals-1;
  888.           memset( buffer+ buffer_pos+1, (int) '0',
  889.               (size_t) get_ptr->num_decimals);
  890.           ok = 1 ;
  891.            }
  892.            break ;
  893.  
  894.         case 'A':
  895.            if ( chr >= 'A' && chr <= 'Z'  ||
  896.             chr >= 'a' && chr <= 'z' )     ok =  1 ;
  897.            break ;
  898.  
  899.         case 'L':
  900.            rc =  (char) toupper( rc ) ;
  901.            if ( rc == 'Y' || rc == 'N' || rc == 'T' || rc == 'F' )
  902.           ok = 1;
  903.            break ;
  904.  
  905.         case 'N':
  906.            if ( chr >= 'A' && chr <= 'Z'  ||
  907.             chr >= 'a' && chr <= 'z'  ||
  908.             chr >= '0' && chr <= '9'  )     ok =  1 ;
  909.            break ;
  910.  
  911.         case 'Y':
  912.            if ( get_ptr->type == 'D' )  /* Date Type: 'Y' for year */
  913.            {
  914.           if ( chr >= '0'  &&  chr <= '9' || chr == ' ' )  ok =  1 ;
  915.            }
  916.            else
  917.            {
  918.           rc =  (char) toupper( rc ) ;
  919.           if ( rc == 'Y' ||  rc == 'N' )  ok =  1 ;
  920.            }
  921.            break ;
  922.  
  923.         case 'X':
  924.         case '!':
  925.            ok =  1 ;
  926.            break ;
  927.  
  928.         case 'C':
  929.         case 'D':
  930.            if ( get_ptr->type == 'D' &&
  931.             (chr >= '0'  &&  chr <= '9' ||  chr == ' ')  )
  932.           ok =    1 ;
  933.            break ;
  934.  
  935.         case 'M':
  936.            if ( get_ptr->type == 'D' )
  937.            {
  938.           if ( chr == ' ' )
  939.           {
  940.              ok = 1 ;
  941.              break ;
  942.           }
  943.  
  944.           for ( num= i=0; picture[i] != '\0'; i++ )
  945.              if ( picture[i] == 'M' ) num++ ;
  946.  
  947.           if ( num > 2 )
  948.           {
  949.              if ( chr >= 'A' && chr <= 'Z'  ||
  950.               chr >= 'a' && chr <= 'z')  ok =  1 ;
  951.           } else
  952.           {
  953.              if ( chr >= '0' && chr <= '9')  ok =  1 ;
  954.           }
  955.            }
  956.            break ;
  957.      }
  958.       }
  959.       else
  960.      ok =  1 ;
  961.  
  962.       if ( ok )
  963.       {
  964.      if ( insert )
  965.      {
  966.         /* Insert the Character */
  967.         num =  g4num_pos( buffer_pos, get_ptr->width_data, picture) ;
  968.         if ( num > 1 )
  969.            memmove( buffer+buffer_pos+1, buffer+buffer_pos, num-1) ;
  970.      }
  971.  
  972.      buffer[buffer_pos++] =  (char) rc ;
  973.       }
  974.       else
  975.      write( 1, "\7", 1 ) ;  /* Sound the Bell */
  976.    }
  977. }
  978.  
  979.  
  980. g4release( do_release )
  981. int  do_release ;
  982. {
  983.    v4window_ptr->release =    do_release ;
  984.  
  985.    if ( do_release )
  986.    {
  987.       h4free_chain( (char **) &v4get, v4window_ptr->last_get ) ;
  988.       v4window_ptr->last_get  =  -1 ;
  989.       v4window_ptr->first_get =  -1 ;
  990.    }
  991.  
  992.    return 0 ;
  993. }
  994.