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 / N4.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-14  |  29.9 KB  |  1,307 lines

  1.  
  2. /* n4.c    (c)Copyright Sequiter Software Inc., 1987, 1988, 1989.  All rights reserved.
  3.  
  4.    Menu Routines
  5. */
  6.  
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <ctype.h>
  10. #include <stdarg.h>
  11.  
  12. #ifndef UNIX
  13.    #include <io.h>
  14.    #include <dos.h>
  15. #endif
  16.  
  17. #include "w4.h"
  18. #include "d4base.h"
  19. #include "g4char.h"
  20. #include "u4error.h"
  21.  
  22. extern GET     *v4get ;
  23. extern CB_WINDOW  *v4window ;
  24. extern CB_WINDOW  *v4window_ptr ;
  25. extern MENU  *v4menu ;
  26.  
  27. static char  key_data[20] ;   /* Key Data Entered When Searching Menus */
  28. static int   key_len = 0 ;
  29.  
  30. extern int  v4up_key ;
  31. extern int  v4exit_key ;
  32. extern int  v4return_start ;
  33. extern int  v4return_end ;
  34.  
  35. extern int  v4screen_width  ;     /* Width in display characters */
  36. extern int  v4screen_width2 ;     /* Width in storage bytes */
  37. extern int  v4screen_height ;
  38. extern int  v4display_bytes ;     /* Width in storage bytes */
  39.  
  40. extern int  v4cur_window ;    /* The Selected Window */
  41. extern int  v4first_window ;
  42.  
  43. #ifdef UNIX
  44.    extern int  v4refresh_on ;
  45. #endif
  46.  
  47. typedef struct
  48. {
  49.    int  ref ;      /* The reference number of the current menu selection */
  50.    int  pos ;      /* The position (from 0) of the current selection */
  51.  
  52.    int  tot_entries ; /* The total number of entries in the menu */
  53.    int  scr_entries ; /* The number of entries which fit on the screen */
  54.  
  55.    int  num_rows ;    /* The number of rows in each menu */
  56.    int  num_cols ;    /* The number of column positions in each menu */
  57.  
  58.    int  do_calc ;     /* 1 to calculate the (row,col) positions, otherwise 0 */
  59. }  MENU_DATA ;
  60.  
  61. static void  calc_pos( int, MENU_DATA *, int, int *, int *) ;
  62. static void  make_top( MENU_DATA * ) ;
  63. static void  refresh_menu( MENU_DATA * ) ;
  64. static void  display_item( MENU_DATA *, int ) ;
  65. static int   skip( MENU_DATA *, int ) ;
  66. static void  menu_home_end( MENU_DATA *, int ) ;
  67. static int   menu_top_bottom( MENU_DATA *, int ) ;
  68. static void  menu_pgup_pgdn( MENU_DATA *, int ) ;
  69. static void  menu_up_down( MENU_DATA *, int ) ;
  70. static int   menu_key( MENU_DATA *, int ) ;
  71. static int   top_bottom_ref( MENU_DATA *, int ) ;
  72.  
  73. static int   is_window_ref( int ) ;
  74.  
  75. static int  is_window_ref( w_ref )
  76. int  w_ref ;
  77. {
  78.    int  on_ref ;
  79.  
  80.    on_ref =  v4first_window ;
  81.    while ( on_ref >= 0 )
  82.    {
  83.       if ( w_ref == on_ref )  return 1 ;
  84.       on_ref =  v4window[on_ref].next ;
  85.    }
  86.    return 0 ;
  87. }
  88.  
  89. static  top_bottom_ref( m_ptr, sign )
  90. MENU_DATA *m_ptr ;
  91. int  sign ;
  92. {
  93.    int  on_pos, on_ref, num_pos ;
  94.  
  95.    on_pos =  m_ptr->pos ;
  96.    on_ref =  m_ptr->ref ;
  97.  
  98.    if ( sign < 0 )
  99.    {
  100.       while( on_pos-- > 0  &&  on_ref >= 0 )
  101.      on_ref =  v4menu[on_ref].prev ;
  102.    }
  103.    else
  104.    {
  105.       num_pos =  m_ptr->scr_entries - on_pos - 1 ;
  106.       while( num_pos-- > 0  &&  on_ref >= 0 )
  107.      on_ref =  v4menu[on_ref].next ;
  108.    }
  109.  
  110.    return( on_ref ) ;
  111. }
  112.  
  113. static void calc_pos( menu_ref, m_ptr, i, row_ptr, col_ptr )
  114. int  menu_ref ;
  115. MENU_DATA  *m_ptr ;
  116. int  i, *row_ptr, *col_ptr ;
  117. {
  118.    if ( ! m_ptr->do_calc )
  119.    {
  120.       *row_ptr =  v4menu[menu_ref].row ;
  121.       *col_ptr =  v4menu[menu_ref].col ;
  122.       return ;
  123.    }
  124.  
  125.    if ( v4window_ptr->horizontal )
  126.    {
  127.       *row_ptr =  i / m_ptr->num_cols ;
  128.       *col_ptr =  (i% m_ptr->num_cols) * v4window_ptr->item_width +1 ;
  129.    }
  130.    else
  131.    {
  132.       *row_ptr =  i % m_ptr->num_rows ;
  133.       *col_ptr =  (i/ m_ptr->num_rows) * v4window_ptr->item_width +1 ;
  134.    }
  135. }
  136.  
  137.  
  138. /* Makes the Current Entry as Close to the Top Entry as Possible */
  139. static void  make_top( m_ptr )
  140. MENU_DATA *m_ptr ;
  141. {
  142.    int  ref, n ;
  143.  
  144.    n =  0 ;
  145.    ref =  m_ptr->ref ;
  146.  
  147.    while ( ref >= 0  &&  ++n < m_ptr->scr_entries )
  148.       ref =  v4menu[ref].next ;
  149.  
  150.    m_ptr->pos =  m_ptr->scr_entries - n ;
  151. }
  152.  
  153.  
  154. static void  refresh_menu( m_ptr )
  155. MENU_DATA  *m_ptr ;
  156. {
  157.    int  save_ref, save_pos ;
  158.  
  159.    w4clear( 0 ) ;
  160.  
  161.    if ( m_ptr->pos < 0 )  m_ptr->pos =  0 ;
  162.    if ( m_ptr->pos >= m_ptr->scr_entries )
  163.         m_ptr->pos =  m_ptr->scr_entries - 1 ;
  164.  
  165.    save_ref =  m_ptr->ref ;
  166.    save_pos =  m_ptr->pos ;
  167.    display_item( m_ptr, -1 ) ;
  168.  
  169.    for( ;; )
  170.    {
  171.       m_ptr->pos++ ;
  172.       m_ptr->ref =  v4menu[m_ptr->ref].next ;
  173.       if ( m_ptr->pos >= m_ptr->scr_entries  || m_ptr->ref < 0 )  break ;
  174.  
  175.       display_item( m_ptr, 0 ) ;
  176.    }
  177.  
  178.    m_ptr->ref =  save_ref ;
  179.    m_ptr->pos =  save_pos ;
  180.  
  181.    for( ;; )
  182.    {
  183.       m_ptr->pos-- ;
  184.       m_ptr->ref =  v4menu[m_ptr->ref].prev ;
  185.       if ( m_ptr->pos < 0  || m_ptr->ref < 0 )  break ;
  186.  
  187.       display_item( m_ptr, 0 ) ;
  188.    }
  189.  
  190.    m_ptr->ref =  save_ref ;
  191.    m_ptr->pos =  save_pos ;
  192. }
  193.  
  194.  
  195. /*  display_item
  196.  
  197.     do_att Value    Meaning
  198.  
  199.        -1       Display completely with selected attribute
  200.       >= 0      Display that number of characters blinking and
  201.             intense.  This is used to display the matching
  202.             search characters in a different manner.
  203.     0       Display normally.  If their is a special key
  204.             highlight position, the character will be
  205.             displayed intensely.  Their will be no
  206.             special highlight key for search windows.
  207. */
  208.  
  209. static void  display_item( m_ptr, do_att )
  210. MENU_DATA  *m_ptr ;
  211. int  do_att ;
  212. {
  213.    int   row, col, len, pos ;
  214.    char *ptr ;
  215.    MENU *menu_ptr ;
  216.  
  217.    calc_pos( m_ptr->ref, m_ptr, m_ptr->pos, &row, &col ) ;
  218.    menu_ptr =  v4menu +  m_ptr->ref ;
  219.  
  220.    ptr =  menu_ptr->item_ptr ;
  221.    len =  strlen(ptr) ;
  222.    if ( len > v4window_ptr->item_width )
  223.       len =  v4window_ptr->item_width ;
  224.  
  225.    if ( do_att )
  226.    {
  227.       if ( do_att < 0 )
  228.       {
  229.      w4num_att( row, col, ptr, len, v4window_ptr->menu_att_active) ;
  230.       }
  231.       else
  232.       {
  233.      if ( do_att > len )  do_att =  len ;
  234.      w4num_att( row, col, ptr, do_att,
  235.              v4window_ptr->menu_att_active | B_BLINK | F_INTENSE ) ;
  236.      w4num_att( row, col+do_att, ptr+ do_att, len- do_att,
  237.              v4window_ptr->menu_att_active) ;
  238.       }
  239.    }
  240.    else
  241.    {
  242.       if ( menu_ptr->key_highlight_pos < 0  ||
  243.        menu_ptr->key_highlight_pos >= len ||
  244.        v4window_ptr->key_read != 1 ||
  245.        menu_ptr->skip_over )
  246.       {
  247.      w4num_att( row, col, ptr, len, menu_ptr->attribute ) ;
  248.       }
  249.       else
  250.       {
  251.      pos =  menu_ptr->key_highlight_pos ;
  252.  
  253.      w4num_att( row, col, ptr, pos, menu_ptr->attribute ) ;
  254.      w4num_att( row, col+pos, ptr+pos, 1, menu_ptr->attribute | F_INTENSE) ;
  255.      pos++ ;
  256.      w4num_att( row, col+pos, ptr+pos, len-pos, menu_ptr->attribute ) ;
  257.       }
  258.    }
  259. }
  260.  
  261. /* Skips if necessary in the specified direction to a valid menu option */
  262.  
  263. static int  skip( m_ptr, sign )
  264. MENU_DATA  *m_ptr ;
  265. int  sign ;
  266. {
  267.    int  ref, pos ;
  268.  
  269.    ref =  m_ptr->ref ;
  270.    pos =  m_ptr->pos ;
  271.  
  272.    while ( v4menu[ref].skip_over )
  273.    {
  274.       if ( sign < 0 )
  275.       {
  276.      ref =  v4menu[ref].prev ;
  277.      pos-- ;
  278.      if ( ref < 0 )
  279.      {
  280.         if ( m_ptr->ref == v4window_ptr->last_menu)  return -1 ;
  281.  
  282.         m_ptr->ref =  v4window_ptr->first_menu ;
  283.         m_ptr->pos =  0 ;
  284.         skip( m_ptr, 1) ;
  285.         return -1 ;
  286.      }
  287.       }
  288.       else
  289.       {
  290.      ref =  v4menu[ref].next ;
  291.      pos++ ;
  292.      if ( ref < 0 )
  293.      {
  294.         if ( m_ptr->ref == v4window_ptr->first_menu)  return 1 ;
  295.  
  296.         m_ptr->ref =  v4window_ptr->last_menu ;
  297.         m_ptr->pos =  m_ptr->scr_entries-1 ;
  298.         skip( m_ptr, -1) ;
  299.         return 1 ;
  300.      }
  301.       }
  302.    }
  303.  
  304.    m_ptr->pos =  pos ;
  305.    m_ptr->ref =  ref ;
  306.  
  307.    return 0 ;
  308. }
  309.  
  310. static void  menu_home_end( m_ptr, sign )
  311. MENU_DATA  *m_ptr ;
  312. int  sign ;
  313. {
  314.    MENU_DATA  old_data ;
  315.  
  316.    key_len =  0 ;
  317.  
  318.    memcpy( (char *) &old_data, (char *) m_ptr, sizeof(MENU_DATA) ) ;
  319.    if ( sign < 0 )
  320.    {
  321.       m_ptr->pos =  0 ;
  322.       m_ptr->ref =  v4window_ptr->first_menu ;
  323.    }
  324.    else
  325.    {
  326.       m_ptr->pos =  m_ptr->scr_entries-1 ;
  327.       m_ptr->ref =  v4window_ptr->last_menu ;
  328.    }
  329.  
  330.    skip(m_ptr, sign) ;
  331.  
  332.    if ( top_bottom_ref(m_ptr,sign) != top_bottom_ref(&old_data,sign) )
  333.    {
  334.       refresh_menu( m_ptr ) ;
  335.       return ;
  336.    }
  337.  
  338.    display_item( &old_data, 0 ) ;
  339.    display_item( m_ptr, -1 ) ;
  340. }
  341.  
  342. /* Returns TRUE if already on top or bottom; otherwise, moves to top or bottom */
  343. static int  menu_top_bottom( m_ptr, sign )
  344. MENU_DATA  *m_ptr ;
  345. int  sign ;
  346. {
  347.    MENU_DATA  test ;
  348.  
  349.    memcpy( (char *) &test, (char *) m_ptr, sizeof(MENU_DATA) ) ;
  350.    test.ref =  top_bottom_ref( &test, sign ) ;
  351.  
  352.    if ( sign < 0 )
  353.       test.pos =  0 ;
  354.    else
  355.       test.pos =  m_ptr->scr_entries- 1 ;
  356.  
  357.    if ( m_ptr->ref == test.ref )  return( 1 ) ;
  358.  
  359.    skip( &test, sign ) ;
  360.    if ( test.ref == m_ptr->ref )  return( 1 ) ;
  361.  
  362.    display_item( m_ptr, 0 ) ;   /* Display Current Item # */
  363.    memcpy( (char *) m_ptr, (char *) &test, sizeof(MENU_DATA) ) ;
  364.    display_item( m_ptr, -1 ) ;
  365.  
  366.    return ( 0 ) ;
  367. }
  368.  
  369.  
  370. static void  menu_pgup_pgdn( m_ptr, sign )
  371. MENU_DATA  *m_ptr ;
  372. int  sign ;
  373. {
  374.    int  i, next_ref ;
  375.  
  376.    key_len =  0 ;
  377.  
  378.    if ( menu_top_bottom(m_ptr, sign)  )
  379.    {
  380.       for ( i=0; i< m_ptr->scr_entries; i++ )
  381.       {
  382.      if ( sign < 0 )
  383.         next_ref =  v4menu[m_ptr->ref].prev ;
  384.      else
  385.         next_ref =  v4menu[m_ptr->ref].next ;
  386.      if (next_ref < 0)  break ;
  387.      m_ptr->ref =  next_ref ;
  388.       }
  389.  
  390.       if ( sign < 0 )
  391.      m_ptr->pos =  0 ;
  392.       else
  393.      m_ptr->pos =  m_ptr->scr_entries - 1;
  394.  
  395.       skip( m_ptr, sign ) ;
  396.       refresh_menu( m_ptr ) ;
  397.    }
  398. }
  399.  
  400. static void  menu_up_down( m_ptr, sign )
  401. MENU_DATA *m_ptr ;
  402. int  sign ;
  403. {
  404.    MENU_DATA  old_data ;
  405.    int  next_ref ;
  406.  
  407.    if ( sign < 0 )
  408.       next_ref =  v4menu[m_ptr->ref].prev ;
  409.    else
  410.       next_ref =  v4menu[m_ptr->ref].next ;
  411.  
  412.    if ( next_ref < 0 )
  413.    {
  414.       menu_home_end( m_ptr, -sign ) ;
  415.       return ;
  416.    }
  417.  
  418.    key_len =  0 ;
  419.    memcpy( (char *) &old_data, (char *) m_ptr, sizeof(MENU_DATA) ) ;
  420.  
  421.    m_ptr->ref  =  next_ref ;
  422.    m_ptr->pos +=  sign ;
  423.  
  424.    if ( skip( m_ptr, sign ) )
  425.    {
  426.       memcpy( (char *) m_ptr, (char *) &old_data, sizeof(MENU_DATA) ) ;
  427.       menu_home_end( m_ptr, -sign ) ;
  428.       return ;
  429.    }
  430.  
  431.    if ( m_ptr->pos < 0 || m_ptr->pos >= m_ptr->scr_entries )
  432.       refresh_menu( m_ptr ) ;
  433.    else
  434.    {
  435.       display_item( &old_data, 0 ) ;
  436.       display_item( m_ptr, -1 ) ;
  437.    }
  438. }
  439.  
  440. static  int  menu_key( m_ptr, ch )  /* Returns -2 if not found; else 0 */
  441. MENU_DATA *m_ptr ;
  442. int   ch ;
  443. {
  444.    int  ref, i, pos, is_found, ch_upper, ch_lower ;
  445.  
  446.    if ( v4window_ptr->ignore_case &&  ch <= 0x7E )
  447.    {
  448.       ch_upper =  toupper( ch ) ;
  449.       ch_lower =  tolower( ch ) ;
  450.    }
  451.    else
  452.       ch_upper =  ch_lower =  ch ;
  453.  
  454.    if ( v4window_ptr->key_read > 0 )
  455.    {
  456.       pos =  m_ptr->pos ;
  457.       ref =  m_ptr->ref ;
  458.  
  459.       is_found =  0 ;
  460.  
  461.       if ( v4window_ptr->key_read == 2  &&  key_len < sizeof(key_data) )
  462.      key_data[key_len++] =  (char) ch ;
  463.  
  464.       for ( i = 0; i<= m_ptr->tot_entries; i++, pos++ )
  465.       {
  466.      if ( ref < 0 )
  467.      {
  468.         pos -=  m_ptr->tot_entries ;
  469.         ref  =  v4window_ptr->first_menu ;
  470.      }
  471.  
  472.      if ( ! v4menu[ref].skip_over )
  473.      {
  474.         if ( v4window_ptr->key_read == 1 )
  475.         {
  476.            if ( (ch_upper == (int) v4menu[ref].key_value ||
  477.              ch_lower == (int) v4menu[ref].key_value)  &&
  478.              (ref != m_ptr->ref || i > 0) )  is_found =  1 ;
  479.         }
  480.         else
  481.         {
  482.            /* String Compare */
  483.            if ( v4window_ptr->ignore_case )
  484.            {
  485.           if ( strnicmp( key_data, v4menu[ref].item_ptr, key_len ) == 0 )
  486.              is_found =  1 ;
  487.            }
  488.            else
  489.            {
  490.           if ( strncmp( key_data, v4menu[ref].item_ptr, key_len ) == 0 )
  491.              is_found =  1 ;
  492.            }
  493.         }
  494.      }
  495.  
  496.      if ( is_found )
  497.      {
  498.         if ( pos >= m_ptr->scr_entries || pos < 0 )
  499.         {
  500.            m_ptr->ref =  ref ;
  501.            make_top( m_ptr ) ;  /* Make Found Entry the Top if Possible */
  502.            refresh_menu( m_ptr ) ;
  503.            if ( v4window_ptr->key_read == 2 )
  504.           display_item( m_ptr, key_len ) ;
  505.            else
  506.           if ( v4menu[m_ptr->ref].key_activate )  return (RETURN) ;
  507.            return 0 ;
  508.         }
  509.         else
  510.         {
  511.            display_item( m_ptr, 0 ) ;
  512.            m_ptr->ref =  ref ;
  513.            m_ptr->pos =  pos ;
  514.            if ( v4window_ptr->key_read == 2 )
  515.           display_item( m_ptr, key_len ) ;
  516.            else
  517.            {
  518.           display_item( m_ptr, -1 ) ;
  519.           if ( v4menu[m_ptr->ref].key_activate )  return (RETURN) ;
  520.            }
  521.            return 0 ;
  522.         }
  523.      }
  524.  
  525.      ref =  v4menu[ref].next ;
  526.       }
  527.       if ( key_len > 0 )  key_len-- ;
  528.    }
  529.  
  530.    return -2 ;
  531. }
  532.  
  533.  
  534. int  n4( label )
  535. char   *label ;
  536. {
  537.    return( n4item( -1, -1, label )  ) ;
  538. }
  539.  
  540.  
  541. #ifdef UNIX
  542. static int   n4char(void) ;
  543.  
  544. static int  n4char()
  545. {
  546.    int  rc ;
  547.  
  548.    v4refresh_on =  1 ;
  549.    w4refresh(-1) ;
  550.  
  551.    rc =  g4char() ;
  552.    v4refresh_on =  0 ;
  553.  
  554.    return( rc ) ;
  555. }
  556. #else
  557.    #define  n4char   g4char
  558. #endif
  559.  
  560. static void  n4act_return( int, int, int ) ;
  561.  
  562. static void  n4act_return( menu_ref, prev_ref, save_refresh_on )
  563. int  menu_ref, prev_ref, save_refresh_on ;
  564. {
  565.    n4message_do( "" ) ;
  566.    w4deactivate( v4menu[menu_ref].window_ref ) ;
  567.    w4select( prev_ref ) ;
  568.  
  569.    #ifdef UNIX
  570.       v4refresh_on =  save_refresh_on ;
  571.       w4refresh(-1) ;
  572.    #endif
  573. }
  574.  
  575.  
  576. int  n4activate( w_ptr )
  577. int  *w_ptr ;
  578. {
  579.    int    ch, up_ch, down_ch, up_ch2, down_ch2, new_ch, *int_ptr ;
  580.    int    max_width, cur_width, prev_ref ;
  581.    MENU      *menu_ptr ;
  582.    MENU_DATA  m ;
  583.    int  save_refresh_on ;
  584.  
  585.    prev_ref =  w4select( *w_ptr ) ;
  586.    save_refresh_on =  v4window_ptr->force_refresh =  0 ;
  587.  
  588.    new_ch =  key_len =  max_width =  m.do_calc =  m.tot_entries =  0 ;
  589.  
  590.    for( m.ref =  v4window_ptr->first_menu; m.ref >= 0;
  591.     m.ref =  v4menu[m.ref].next )
  592.    {
  593.       menu_ptr =  v4menu +  m.ref ;
  594.       m.tot_entries ++ ;
  595.       cur_width =  strlen( menu_ptr->item_ptr ) ;
  596.       if ( cur_width > max_width )  max_width =  cur_width ;
  597.  
  598.       if ( menu_ptr->row < 0  ||  menu_ptr->col < 0 )  m.do_calc =  1 ;
  599.    }
  600.    if ( m.tot_entries < 0 )
  601.    {
  602.       w4select( prev_ref ) ;
  603.       return 0 ;
  604.    }
  605.  
  606.    /* Initialize the menu data */
  607.    m.num_rows =  v4window_ptr->height ;
  608.    m.num_cols =  v4window_ptr->width-2 ;
  609.    if ( v4window_ptr->item_width <= 0 )
  610.       v4window_ptr->item_width =  v4window_ptr->width-2 ;
  611.    m.num_cols   /=  v4window_ptr->item_width ;
  612.    if ( m.do_calc )
  613.       m.scr_entries =  m.num_rows * m.num_cols ;
  614.    else
  615.    {
  616.       m.num_rows =  m.tot_entries ;
  617.       m.num_cols =  1 ;
  618.       m.scr_entries =  m.tot_entries ;
  619.    }
  620.    if ( m.scr_entries > m.tot_entries )  m.scr_entries =  m.tot_entries ;
  621.    if ( m.scr_entries <= 0 )
  622.    {
  623.       w4select( prev_ref ) ;
  624.       return 0 ;
  625.    }
  626.  
  627.    #ifdef UNIX
  628.       save_refresh_on =  v4refresh_on ;
  629.       v4refresh_on =  0 ;
  630.    #endif
  631.  
  632.    w4activate( *w_ptr ) ;
  633.  
  634.    if ( v4window_ptr->start_item < 0 )
  635.       menu_home_end( &m, -1 ) ;
  636.    else
  637.    {
  638.       m.ref =  v4window_ptr->start_item ;
  639.       make_top( &m ) ;
  640.       refresh_menu( &m ) ;
  641.    }
  642.  
  643.    if ( v4window_ptr->horizontal )
  644.    {
  645.       up_ch   =  LEFT ;
  646.       down_ch =  RIGHT ;
  647.       up_ch2  =  CTRL_S ;
  648.       down_ch2=  CTRL_D ;
  649.    }
  650.    else
  651.    {
  652.       up_ch   =  UP ;
  653.       down_ch =  DOWN ;
  654.       up_ch2  =  CTRL_E ;
  655.       down_ch2=  CTRL_X ;
  656.    }
  657.  
  658.    for(;;)
  659.    {
  660.       w4select( v4menu[m.ref].window_ref ) ;
  661.  
  662.       if ( v4window_ptr->force_refresh )
  663.       {
  664.      v4window_ptr->force_refresh =  0 ;
  665.      refresh_menu( &m ) ;
  666.       }
  667.  
  668.       if ( new_ch > 0 )
  669.       {
  670.      ch =  new_ch ;
  671.      new_ch =  0 ;
  672.      if ( ch == v4window_ptr->up_key )
  673.         ch =  0 ; /* Only Up One at a Time */
  674.      n4message_do( v4menu[m.ref].message ) ;
  675.       }
  676.       else
  677.       {
  678.      if ( v4menu[m.ref].reaction != (ACTION *) 0 )
  679.      {
  680.         int_ptr =  v4menu[m.ref].reaction_parms ;
  681.         #ifdef UNIX
  682.            if ( v4menu[m.ref].reaction != n4activate )
  683.            {
  684.           v4refresh_on =  1 ;
  685.           w4refresh(-1) ;
  686.            }
  687.         #endif
  688.         ch =  (*v4menu[m.ref].reaction)(int_ptr[0], int_ptr[1], int_ptr[2], int_ptr[3] ) ;
  689.  
  690.         #ifdef UNIX
  691.            v4refresh_on =  0 ;
  692.         #endif
  693.         if ( ch < 0 )
  694.         {
  695.            n4act_return( m.ref, prev_ref, save_refresh_on ) ;
  696.            return( ch ) ;
  697.         }
  698.         if ( ch == 0 )
  699.         {
  700.            n4message_do( v4menu[m.ref].message ) ;
  701.            ch = n4char() ;
  702.         }
  703.      }
  704.      else
  705.      {
  706.         n4message_do( v4menu[m.ref].message ) ;
  707.         ch =  n4char() ;
  708.      }
  709.       }
  710.  
  711.  
  712.       w4select( v4menu[m.ref].window_ref ) ;
  713.  
  714.       switch( ch )
  715.       {
  716.      case UP:
  717.      case LEFT:
  718.      case CTRL_E:
  719.      case CTRL_S:
  720.         if ( ch == up_ch  || ch == up_ch2 )
  721.         {
  722.            menu_up_down( &m, -1 ) ;
  723.         }
  724.         else
  725.         {
  726.            if ( v4window_ptr->arrow_exit )
  727.            {
  728.                  n4act_return( m.ref, prev_ref, save_refresh_on ) ;
  729.           return( ch ) ;
  730.            }
  731.         }
  732.         break ;
  733.  
  734.      case DOWN:
  735.      case RIGHT:
  736.      case CTRL_X:
  737.      case CTRL_D:
  738.         if ( ch == down_ch  ||  ch == down_ch2 )
  739.         {
  740.            menu_up_down( &m, 1 ) ;
  741.         }
  742.         else
  743.         {
  744.            if ( v4window_ptr->arrow_exit )
  745.            {
  746.                  n4act_return( m.ref, prev_ref, save_refresh_on ) ;
  747.           return( ch ) ;
  748.            }
  749.         }
  750.         break ;
  751.  
  752.      case HOME:
  753.      case CTRL_A:
  754.         menu_home_end( &m, -1 ) ;
  755.         break ;
  756.  
  757.      case END:
  758.         menu_home_end( &m, 1 ) ;
  759.         break ;
  760.  
  761.      case PGUP:
  762.      case CTRL_R:
  763.         menu_pgup_pgdn( &m, -1 ) ;
  764.         break ;
  765.  
  766.      case PGDN:
  767.      case CTRL_N:
  768.         menu_pgup_pgdn( &m, 1 ) ;
  769.         break ;
  770.  
  771.      case BACK_SPACE:
  772.         if (key_len > 0)
  773.         {
  774.            if ( --key_len > 0 )
  775.           display_item( &m, key_len ) ;
  776.            else
  777.           display_item( &m, -1 ) ;
  778.         }
  779.         break ;
  780.  
  781.      case RETURN:
  782.         if ( key_len > 0 )
  783.         {
  784.            key_len =  0 ;
  785.            display_item( &m, -1 ) ;
  786.         }
  787.         if ( v4menu[m.ref].action == (ACTION *) 0 )
  788.         {
  789.            if ( v4menu[m.ref].action_parms[0] != 0 )
  790.            {
  791.               n4act_return( m.ref, prev_ref, save_refresh_on ) ;
  792.           return ( v4menu[m.ref].action_parms[0] ) ;
  793.            }
  794.            else
  795.           break ;
  796.         }
  797.         int_ptr =  v4menu[m.ref].action_parms ;
  798.         #ifdef UNIX
  799.            if (v4menu[m.ref].action != n4activate )
  800.            {
  801.           v4refresh_on =  1 ;
  802.           w4refresh(-1) ;
  803.            }
  804.         #endif
  805.         new_ch = (*v4menu[m.ref].action)(int_ptr[0], int_ptr[1], int_ptr[2], int_ptr[3] ) ;
  806.         #ifdef UNIX
  807.            v4refresh_on =  0 ;
  808.         #endif
  809.         if ( new_ch < 0 )
  810.         {
  811.            n4act_return( m.ref, prev_ref, save_refresh_on ) ;
  812.            return ( new_ch ) ;
  813.         }
  814.         w4select( v4menu[m.ref].window_ref ) ;
  815.         display_item( &m, -1 ) ;
  816.         break ;
  817.  
  818.      default:
  819.         if ( ch == v4window_ptr->exit_key ||
  820.          ch == v4window_ptr->up_key )
  821.         {
  822.            n4act_return( m.ref, prev_ref, save_refresh_on ) ;
  823.            return( ch ) ;
  824.         }
  825.  
  826.         if ( ch >= 0x1 && ch <= 0x7F00 )
  827.         {
  828.            new_ch =  menu_key( &m, ch ) ;
  829.            if ( new_ch == -2 )
  830.            {
  831.           new_ch =  0 ;
  832.           if ( ch >= v4window_ptr->return_start &&
  833.                ch <= v4window_ptr->return_end )
  834.           {
  835.                   n4act_return( m.ref, prev_ref, save_refresh_on ) ;
  836.              return( ch ) ;
  837.           }
  838.            }
  839.         }
  840.         break ;
  841.       }
  842.    }
  843. }
  844.  
  845.  
  846. void  n4arrow_exit()
  847. {
  848.    v4window_ptr->arrow_exit =  1 ;
  849. }
  850.  
  851.  
  852. void  n4attribute( attribute, attribute_active )
  853. long  attribute, attribute_active ;
  854. {
  855.    v4window_ptr->menu_attribute  =  attribute ;
  856.    v4window_ptr->menu_att_active =  attribute_active ;
  857. }
  858.  
  859.  
  860. void  n4attribute_item( item_ref, attribute )
  861. int  item_ref ;
  862. long attribute ;
  863. {
  864.    MENU *menu_ptr ;
  865.  
  866.    menu_ptr =  v4menu +  item_ref ;
  867.    menu_ptr->attribute =  attribute ;
  868. }
  869.  
  870.  
  871. void  n4get_calc( w_ref )
  872. int  w_ref ;
  873. {
  874.    int  on_get, on_menu ;
  875.    GET    *get_ptr ;
  876.    CB_WINDOW    *w2_ptr, *w_ptr ;
  877.  
  878.    w_ptr =  v4window + w_ref ;
  879.  
  880.    for (on_get= w_ptr->first_get; on_get >= 0; on_get = get_ptr->next)
  881.    {
  882.        get_ptr =  v4get+ on_get ;
  883.  
  884.        if ( get_ptr->call == g4menu  ||  get_ptr->call == g4menu_help )
  885.        {
  886.       w2_ptr =  v4window + get_ptr->call_data ;
  887.       #ifdef UNIX
  888.          w2_ptr->up_key    =  CTRL_Q ;
  889.       #else
  890.          w2_ptr->up_key    =  ESC ;
  891.       #endif
  892.       w2_ptr->exit_key     =  SHIFT_TAB ;
  893.       w2_ptr->return_start =  0 ;
  894.       w2_ptr->return_end   =  0x7F ;
  895.  
  896.       n4calc( get_ptr->call_data,
  897.              w_ptr->start_row + get_ptr->row +1,
  898.              w_ptr->start_col + get_ptr->col ) ;
  899.  
  900.       for ( on_menu=w2_ptr->first_menu; on_menu>=0; on_menu=v4menu[on_menu].next)
  901.       {
  902.          v4menu[on_menu].action_parms[0] =  -on_menu ;
  903.          if ( on_menu == 0 )
  904.         v4menu[on_menu].action_parms[0] =  0x7FFF ;
  905.       }
  906.        }
  907.    }
  908. }
  909.  
  910.  
  911. void  n4horizontal()
  912. {
  913.    v4window_ptr->horizontal =  1 ;
  914. }
  915.  
  916. int  n4item( row, col, label )
  917. int     row, col ;
  918. char   *label ;
  919. {
  920.    MENU *menu_ptr ;
  921.  
  922.    if ( v4menu == (MENU *) 0 )
  923.       if(  h4create( (char **) &v4menu, 20, (int) sizeof(MENU), 20) < 0 ) return -1 ;
  924.  
  925.    v4window_ptr->last_menu =  h4get( (char **) &v4menu, v4window_ptr->last_menu ) ;
  926.    if ( v4window_ptr->last_menu < 0 )  return -1 ;
  927.  
  928.    if ( v4window_ptr->first_menu < 0 )
  929.       v4window_ptr->first_menu =  v4window_ptr->last_menu ;
  930.    menu_ptr =  v4menu+ v4window_ptr->last_menu ;
  931.  
  932.    menu_ptr->row =  row ;
  933.    menu_ptr->col =  col ;
  934.    menu_ptr->window_ref =  v4cur_window ;
  935.    menu_ptr->item_ptr =  label ;
  936.    menu_ptr->attribute =  v4window_ptr->menu_attribute ;
  937.    n4key( (int) label[0], 1, 0 ) ;
  938.  
  939.    return ( v4window_ptr->last_menu ) ;
  940. }
  941.  
  942. char *  n4item_text( i_ref )
  943. int  i_ref ;
  944. {
  945.    return ( v4menu[i_ref].item_ptr ) ;
  946. }
  947.  
  948. void  n4item_width( item_width )
  949. int  item_width ;
  950. {
  951.    v4window_ptr->item_width =  item_width ;
  952. }
  953.  
  954.  
  955. void  n4key( chr, active, highlight_pos )
  956. int chr, active, highlight_pos ;
  957. {
  958.    MENU *menu_ptr ;
  959.  
  960.    if ( v4window_ptr->last_menu < 0 )  return ;
  961.    menu_ptr =  v4menu +  v4window_ptr->last_menu ;
  962.    menu_ptr->key_value    =  chr ;
  963.    menu_ptr->key_activate     =  active ;
  964.    menu_ptr->key_highlight_pos=  highlight_pos ;
  965. }
  966.  
  967.  
  968. void  n4key_set( set_code, ignore_case )
  969. int  set_code, ignore_case ;
  970. {
  971.    v4window_ptr->key_read    =  set_code ;
  972.    v4window_ptr->ignore_case =  ignore_case ;
  973. }
  974.  
  975.  
  976. void  n4key_special( up_key, exit_key, return_start, return_end )
  977. int  up_key, exit_key, return_start, return_end ;
  978. {
  979.    v4up_key      =  up_key ;
  980.    v4exit_key    =  exit_key ;
  981.    v4return_start=  return_start ;
  982.    v4return_end  =  return_end ;
  983. }
  984.  
  985. extern int  v4menu_row, v4menu_col ;
  986. static void  calc_lotus(int, int, int) ;
  987.  
  988. void  n4lotus( w_ref )
  989. int  w_ref ;
  990. {
  991.    CB_WINDOW  *w_ptr ;
  992.  
  993.    if ( ! is_window_ref( w_ref ) )
  994.    {
  995.       u4error( E_WINDOW_REF, "(n4pulldown)", (char *) 0 ) ;
  996.       return ;
  997.    }
  998.  
  999.    w_ptr =  v4window +  w_ref ;
  1000.  
  1001.    if ( w_ptr->start_row < 0 )  w_ptr->start_row =  0 ;
  1002.    if ( w_ptr->start_col < 0 )  w_ptr->start_col =  0 ;
  1003.  
  1004.    calc_lotus( w_ref, w_ptr->start_row, w_ptr->start_col ) ;
  1005.    v4menu_row =  w_ptr->start_row+1 ;
  1006.    v4menu_col =  w_ptr->start_col ;
  1007. }
  1008.  
  1009.  
  1010. static void  calc_lotus( window_ref, start_row, start_col )
  1011. int  window_ref, start_row, start_col ;
  1012. {
  1013.    int    menu_on, cur_col, start_window ;
  1014.    MENU  *menu_ptr ;
  1015.    struct  { int  *ptr ; }  ptr ;
  1016.  
  1017.    if ( ! is_window_ref( window_ref ) )
  1018.    {
  1019.       u4error( E_WINDOW_REF, "(n4pulldown)", (char *) 0 ) ;
  1020.       return ;
  1021.    }
  1022.  
  1023.    start_window =  w4select( window_ref ) ;
  1024.  
  1025.    v4window_ptr->start_row =  start_row ;
  1026.    v4window_ptr->start_col =  start_col ;
  1027.    v4window_ptr->return_start =  0 ;
  1028.    v4window_ptr->return_end   =  0 ;
  1029.    #ifdef UNIX
  1030.       v4window_ptr->up_key    =  CTRL_Q ;
  1031.    #else
  1032.       v4window_ptr->up_key    =  ESC ;
  1033.    #endif
  1034.    v4window_ptr->exit_key     =  '/' ;
  1035.  
  1036.    cur_col =  0 ;
  1037.  
  1038.    for( menu_on= v4window_ptr->first_menu; menu_on >= 0; menu_on = menu_ptr->next)
  1039.    {
  1040.       menu_ptr =  v4menu +  menu_on ;
  1041.  
  1042.       menu_ptr->row =  0 ;
  1043.       menu_ptr->col =  cur_col ;
  1044.  
  1045.       ptr.ptr = (int *) 0 ;
  1046.       if ( menu_ptr->reaction == n4activate )
  1047.      memcpy( (char *) &ptr, (char *) menu_ptr->reaction_parms, sizeof(ptr) ) ;
  1048.       if ( menu_ptr->action == n4activate )
  1049.      memcpy( (char *) &ptr, (char *) menu_ptr->action_parms, sizeof(ptr) ) ;
  1050.  
  1051.       if ( ptr.ptr != (int *) 0 )
  1052.      calc_lotus( *ptr.ptr, start_row, start_col ) ;
  1053.  
  1054.       cur_col +=  strlen( menu_ptr->item_ptr ) + 3 ;
  1055.    }
  1056.  
  1057.    v4window_ptr->height =  1 ;
  1058.    v4window_ptr->width  =  v4screen_width - start_col ;
  1059.  
  1060.    w4popup() ;
  1061.    n4horizontal() ;
  1062.  
  1063.    w4select( start_window ) ;
  1064. }
  1065.  
  1066.  
  1067. void  n4message( message_ptr )
  1068. char *message_ptr ;
  1069. {
  1070.    MENU *menu_ptr ;
  1071.  
  1072.    if ( v4window_ptr->last_menu < 0 )  return ;
  1073.    menu_ptr =  v4menu +  v4window_ptr->last_menu ;
  1074.    menu_ptr->message =  message_ptr ;
  1075. }
  1076.  
  1077.  
  1078. void  n4action( action, p1,p2,p3,p4 )
  1079. ACTION *action ;
  1080. int     p1,p2,p3,p4 ;
  1081. {
  1082.    MENU *menu_ptr ;
  1083.  
  1084.    if ( v4window_ptr->last_menu < 0 )  return ;
  1085.    menu_ptr =  v4menu +  v4window_ptr->last_menu ;
  1086.  
  1087.    menu_ptr->action =  action ;
  1088.    menu_ptr->action_parms[0] =  p1 ;
  1089.    menu_ptr->action_parms[1] =  p2 ;
  1090.    menu_ptr->action_parms[2] =  p3 ;
  1091.    menu_ptr->action_parms[3] =  p4 ;
  1092. }
  1093.  
  1094. void  n4reaction( action, p1,p2,p3,p4 )
  1095. ACTION *action ;
  1096. int     p1,p2,p3,p4 ;
  1097. {
  1098.    MENU *menu_ptr ;
  1099.  
  1100.    if ( v4window_ptr->last_menu < 0 )  return ;
  1101.    menu_ptr =  v4menu +  v4window_ptr->last_menu ;
  1102.  
  1103.    menu_ptr->reaction =  action ;
  1104.    menu_ptr->reaction_parms[0] =  p1 ;
  1105.    menu_ptr->reaction_parms[1] =  p2 ;
  1106.    menu_ptr->reaction_parms[2] =  p3 ;
  1107.    menu_ptr->reaction_parms[3] =  p4 ;
  1108. }
  1109.  
  1110.  
  1111. /* Makes a Pull Down Menu out of the Currently Selected Menu */
  1112. void  n4pulldown( w_ref )
  1113. int  w_ref ;
  1114. {
  1115.    int    menu_on, cur_col, old_window_ref ;
  1116.    MENU  *menu_ptr ;
  1117.    struct  { int  *ptr ; }  ptr ;
  1118.  
  1119.    if ( ! is_window_ref( w_ref ) )
  1120.    {
  1121.       u4error( E_WINDOW_REF, "(n4pulldown)", (char *) 0 ) ;
  1122.       return ;
  1123.    }
  1124.  
  1125.    old_window_ref =  v4cur_window ;
  1126.    w4select( w_ref ) ;
  1127.  
  1128.    if ( v4window_ptr->start_row < 0 )  v4window_ptr->start_row =  0 ;
  1129.    if ( v4window_ptr->start_col < 0 )  v4window_ptr->start_col =  0 ;
  1130.  
  1131.    cur_col =  1 ;
  1132.  
  1133.    for (menu_on= v4window_ptr->first_menu; menu_on>= 0; menu_on= menu_ptr->next)
  1134.    {
  1135.       menu_ptr =  v4menu +  menu_on ;
  1136.  
  1137.       menu_ptr->row =  0 ;
  1138.       menu_ptr->col =  cur_col ;
  1139.  
  1140.       ptr.ptr = (int *) 0 ;
  1141.       if ( menu_ptr->reaction == n4activate )
  1142.      memcpy( (char *) &ptr, (char *) menu_ptr->reaction_parms, sizeof(ptr) ) ;
  1143.       if ( menu_ptr->action == n4activate )
  1144.      memcpy( (char *) &ptr, (char *) menu_ptr->action_parms, sizeof(ptr) ) ;
  1145.  
  1146.       if ( ptr.ptr != (int *) 0 )
  1147.       {
  1148.      n4calc( *ptr.ptr, v4window_ptr->start_row+1,
  1149.                v4window_ptr->start_col+cur_col ) ;
  1150.      v4window[*ptr.ptr].arrow_exit =  1 ;
  1151.       }
  1152.  
  1153.       cur_col +=  strlen( menu_ptr->item_ptr ) + 3 ;
  1154.    }
  1155.  
  1156.    v4window_ptr->width =  cur_col-2 ;
  1157.    v4window_ptr->height=  1 ;
  1158.    w4popup() ;
  1159.    n4horizontal() ;
  1160.  
  1161.    w4select( old_window_ref ) ;
  1162. }
  1163.  
  1164.  
  1165. /* Assume not popped up, no border, and (start_row,start_col) is
  1166.    the upper left hand corner of the new window.
  1167.  
  1168.    Calculate the coordinate of the window and underlying windows.
  1169.    Assign the border and specify the window to be 'popup'.
  1170.    Adjust the (start_row,start_col) if necessary.
  1171. */
  1172.  
  1173. void  n4calc( w_ref, start_row, start_col )
  1174. int  w_ref, start_row, start_col ;
  1175. {
  1176.    int  start_ref, on_menu ;
  1177.    int  max_width, width, num, i ;
  1178.    MENU  *menu_ptr ;
  1179.    struct  { int  *ptr ; }  ptr ;
  1180.  
  1181.    if ( ! is_window_ref( w_ref ) )
  1182.    {
  1183.       u4error( E_WINDOW_REF, "(n4pulldown)", (char *) 0 ) ;
  1184.       return ;
  1185.    }
  1186.  
  1187.    start_ref =  w4select( w_ref ) ;
  1188.  
  1189.    if ( v4window_ptr->title != (char *) 0 )
  1190.       max_width =  strlen( v4window_ptr->title ) -2 ;
  1191.    else
  1192.       max_width =  0 ;
  1193.  
  1194.    if ( v4window_ptr->border_chars == (char *) 0 )
  1195.       w4border( SINGLE, F_WHITE ) ;
  1196.  
  1197.    num =  0 ;
  1198.  
  1199.    for (on_menu= v4window_ptr->first_menu; on_menu>= 0; on_menu= menu_ptr->next)
  1200.    {
  1201.       menu_ptr =  v4menu +  on_menu ;
  1202.       num ++ ;
  1203.  
  1204.       width =  strlen( menu_ptr->item_ptr ) ;
  1205.       if ( width > max_width )  max_width =  width ;
  1206.  
  1207.       menu_ptr->row =  -1 ;
  1208.       menu_ptr->col =  -1 ;
  1209.    }
  1210.  
  1211.    max_width += 2 ;  /* Two columns for the edges */
  1212.    if ( num >  v4screen_height -2 - start_row )
  1213.       num =  v4screen_height -2 - start_row ;
  1214.    if ( max_width > v4screen_width -2 )  max_width =  v4screen_width  -2 ;
  1215.  
  1216.    v4window_ptr->width  =  max_width ;
  1217.    v4window_ptr->height =  num ;
  1218.  
  1219.    if ( start_col + max_width+2 >  v4screen_width )
  1220.       start_col =  v4screen_width -max_width -2 ;
  1221.  
  1222.    v4window_ptr->start_row =  start_row+1 ;
  1223.    v4window_ptr->start_col =  start_col+1 ;
  1224.  
  1225.    i = start_row+1 ;
  1226.  
  1227.    for (on_menu= v4window_ptr->first_menu; on_menu>= 0; on_menu= menu_ptr->next)
  1228.    {
  1229.       menu_ptr =  v4menu +  on_menu ;
  1230.       i++ ;
  1231.  
  1232.       ptr.ptr = (int *) 0 ;
  1233.       if ( menu_ptr->reaction == n4activate )
  1234.      memcpy( (char *) &ptr, (char *) menu_ptr->reaction_parms, sizeof(ptr) ) ;
  1235.       if ( menu_ptr->action == n4activate )
  1236.      memcpy( (char *) &ptr, (char *) menu_ptr->action_parms, sizeof(ptr) ) ;
  1237.  
  1238.       if ( ptr.ptr != (int *) 0 )
  1239.      n4calc( *ptr.ptr, i, v4window_ptr->start_col+ 1 ) ;
  1240.    }
  1241.  
  1242.    w4border( v4window_ptr->border_chars, v4window_ptr->border_attribute ) ;
  1243.    w4popup() ;
  1244.  
  1245.    w4select( start_ref ) ;
  1246. }
  1247.  
  1248.  
  1249. void  n4refresh( w_ref )
  1250. int  w_ref ;
  1251. {
  1252.    v4window[w_ref].force_refresh =  1 ;
  1253.    return ;
  1254. }
  1255.  
  1256.  
  1257. int  n4search( ptr )
  1258. char *ptr ;
  1259. {
  1260.    int  on_menu, len, total_len, i ;
  1261.    char *item_ptr ;
  1262.  
  1263.    /* Len is the number of non-blank characters in 'ptr' */
  1264.    len =  total_len =  strlen(ptr) ;
  1265.    len--;
  1266.    while ( len >= 0  && ptr[len] == ' ' )  len-- ;
  1267.    len++ ;
  1268.  
  1269.    for( on_menu= v4window_ptr->first_menu; on_menu>= 0; on_menu= v4menu[on_menu].next)
  1270.    {
  1271.       if ( v4menu[on_menu].skip_over )  continue ;
  1272.  
  1273.       if ( strncmp( (item_ptr = v4menu[on_menu].item_ptr), ptr, len ) == 0 )
  1274.       {
  1275.      for(i=len;; i++)
  1276.      {
  1277.         if ( item_ptr[i] == '\0' || i==total_len )  return( on_menu ) ;
  1278.         /* If there is another non-blank character, there is no match */
  1279.         if ( item_ptr[i] != ' ' )  break ;
  1280.      }
  1281.       }
  1282.    }
  1283.  
  1284.    return -1 ;
  1285. }
  1286.  
  1287.  
  1288. int  n4skip_over( item_ref, flag )
  1289. int  item_ref, flag ;
  1290. {
  1291.    int  rc ;
  1292.    if ( item_ref < 0 )  return -1;
  1293.  
  1294.    rc =  v4menu[item_ref].skip_over ;
  1295.    v4menu[item_ref].skip_over =  flag ;
  1296.  
  1297.    return  rc ;
  1298. }
  1299.  
  1300.  
  1301. void  n4start_item( start_item_ref )
  1302. int  start_item_ref ;
  1303. {
  1304.    v4window[v4menu[start_item_ref].window_ref].start_item =  start_item_ref ;
  1305. }
  1306.  
  1307.