home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / GUILIB.ZIP / MENU.C < prev    next >
C/C++ Source or Header  |  1992-11-27  |  63KB  |  1,982 lines

  1. /*---------------------------------------------------------------------------*
  2. *  PLAIN DESIGN CORPORATION       COPYRIGHT (c)  1992                        *
  3. *----------------------------------------------------------------------------*
  4. *  PULL DOWN MENU SYSTEM for character based user interfaces                 *         
  5. *---------------------------------------------------------------------------*/
  6.  
  7. #include "stdio.h"
  8. #include "string.h"
  9. #include "conio.h"
  10. #include "stdlib.h"
  11. #include "bios.h"
  12. #include "ctype.h"
  13. #include "conio.h"
  14. #include "dos.h"
  15. #include "menu.h"
  16.  
  17. /*-------------------------------*/
  18. /* FOR MICROSOFT C COMPILER      */
  19. /*-------------------------------*/
  20. #ifdef MSC
  21. #define getvect(i) _dos_getvect(i)
  22. #define bioskey(i) _bios_keybrd(i)
  23. #endif
  24. /*-------------------------------*/
  25.  
  26. int  menu_descriptor=TEXT_FILE;   
  27.  
  28. FILE *fp;                         /* file pointer for the menu file        */
  29.  
  30. char menu_file[40]="MENUFILE";    /* menu descriptor file name             */
  31. int  menu_color=0x70;             /* menu color                            */
  32. int  menu_hotkey_color=0x74;      /* color of the hotkey                   */
  33. int  menu_sel_color=0x47;         /* selected menu item color              */
  34. int  menu_shadow=0x08;            /* shadow for expanded boxes             */
  35. int  menu_x=0;                    /* menu bar x locations                  */
  36. int  menu_y=0;                    /* menu bar y locations                  */
  37. int  menu_x_size=80;              /* size of the x axis of the bar         */
  38.  
  39.  
  40. char menu_title[MAX_TITLE][20];   /* menu title array                      */
  41. char title_hotkey[MAX_TITLE];     /* title hotkey array                    */
  42. char title_hotkey_loc[MAX_TITLE]; /* title hotkey location                 */
  43. long title_loc [MAX_TITLE];       /* each title location in menufile       */                                                   
  44. int  title_ident[MAX_TITLE];      /* title identifier number array         */                                   
  45. int  title_acc[MAX_TITLE];        /* title accelerator array               */
  46. int  title_x[MAX_TITLE];          /* title x location array                */
  47. int  title_num;                   /* number of titles in menufile          */
  48. int  title_ptr;                   /* title pointer variable                */
  49.  
  50. int  menu_acc_num;                /* number of menu accelerators           */
  51. int  menu_acc[MAX_ACC];           /* store the accelerator key code        */
  52. int  menu_ident[MAX_ACC];         /* return value for accelerated key code */
  53.  
  54. int  cur_ident;                   /* used to pass the current ident        */  
  55. int  key_return;                  /* key board status variable             */
  56. /*--------------------------------------------------------------------------*/
  57. union REGS iReg,oReg;          
  58. int   mousefound=NO;              /* mouse existance variable              */
  59. int   mousex;                     /* mouse cursor x location               */
  60. int   mousey;                     /* mouse cursor y location               */
  61. /*--------------------------------------------------------------------------*/
  62. int   txt_curs_x;                 /* text  cursor x location               */
  63. int   txt_curs_y;                 /* text  cursor y location               */
  64. int   curs_start_line=8;
  65. int   curs_end_line=8;
  66.  
  67. int   ms;                         /* mouse key status                      */
  68. int   mouse_display;              /* mouse cursor ON/OFF indicator         */
  69.  
  70. char  **menu;
  71. int   menu_lines;
  72. int   menu_line_ptr;
  73. /*--------------------------------------------------------------------------*/
  74. /*-------------------------------------*/
  75. /*          window  declerations       */
  76. /*-------------------------------------*/
  77. int           box_num;
  78. unsigned char *save_box [MAX_WINDOWS];
  79. unsigned char *gsave_box[MAX_WINDOWS];
  80. int           xwin      [MAX_WINDOWS];
  81. int           ywin      [MAX_WINDOWS];
  82. int           xwinsize  [MAX_WINDOWS];
  83. int           ywinsize  [MAX_WINDOWS];
  84. int           wincolor  [MAX_WINDOWS];
  85. int           winshadow [MAX_WINDOWS];
  86. int           winborder [MAX_WINDOWS];
  87. /*-------------------------------------*/
  88.  
  89.  
  90. int            initvar=1;   /* will indicate if initdisplay has been called */
  91. unsigned char  back_block;  /* block used by frect to fill a rectangle      */
  92.  
  93.  
  94.  
  95. /*--------------------------------------------------------------------------*/
  96. /*  int bar_menu(action);                                                    *
  97. *                                                                            *
  98. *    action : INIT         initialize the menu function by opening the menu  *
  99. *                          file and display menu titles on the screen.       *
  100. *             KEY_RETURN   returns keyboard input as it would be returned    *
  101. *                          by getkey function; return EOF if no key pressed  *
  102. *                          . If ALT key is pressed and released (ALONE), it  *
  103. *                            will turn the menu on; when appropriate menu is *
  104. *                            selected, it will return the menu identifier #. *
  105. *                          . If mouse left key is pressed on a menu title,   *
  106. *                            bar_menu will turn the menu on and return the   *
  107. *                            menu_identifier when an entry is selected.      *
  108. *                          . If an accelerator is detected, bar_menu will    *
  109. *                            return the identifier associated with the       *
  110. *                            accelerator without turning the menu on.        *
  111. /*--------------------------------------------------------------------------*/
  112. int  bar_menu(action)
  113. int  action;
  114. {
  115.    int  ch=0;
  116.    int  mouse_menu=NO;
  117.    int  acc_expand=OFF;
  118.    int  i;
  119.  
  120.    /*----------------------------------------------------*/
  121.    /* initilize the menu bar variables and read the menu */
  122.    /* file and display the unactivated menu              */
  123.    /*----------------------------------------------------*/
  124.    if(action==INIT)
  125.    { init_menu();
  126.      return(EOF);
  127.    }
  128.    /*--------------------------------------------------------------------*/
  129.    if(action==DISPLAY)
  130.    { display_menu();
  131.      return(EOF);
  132.    }
  133.    /*--------------------------------------------------------------------*/
  134.    /*                ACTIONS FOR   KEY_RETURN parameter                  */
  135.    /*--------------------------------------------------------------------*/
  136.  
  137.    /*-------------------------------------------*/
  138.    /* check if mouse is clicked on the menu bar */
  139.    /*-------------------------------------------*/
  140.    if(mouse_left_pressed()==YES)
  141.    { get_mouse_location();
  142.      if(mousey==menu_y)
  143.      { for(i=0;i<title_num;i++)
  144.        { if(mousex>=title_x[i] && mousex<=title_x[i]+strlen(menu_title[i])-1)
  145.          { mouse_menu=YES;
  146.            title_ptr=i;
  147.            break;
  148.          }
  149.        }
  150.      }
  151.    }
  152.    
  153.    /*-------------------------------------------*/
  154.    /*   check if the alt key is pressed         */
  155.    /*-------------------------------------------*/
  156.    if(mouse_menu==NO)
  157.    { if(alt_pressed()==NO)
  158.      { ch=getkey();
  159.        if(ch!=EOF)   /* check if an accelerator key has been pressed */
  160.        { for (i=0;i<menu_acc_num;i++)
  161.          { if(menu_acc[i]==ch)
  162.            { return(menu_ident[i]);
  163.            }
  164.          }
  165.          for (i=0;i<title_num;i++)
  166.          { if(title_acc[i]==ch)
  167.            { title_ptr=i;
  168.              acc_expand=ON;
  169.              break;
  170.            }
  171.          }
  172.        }
  173.        if(acc_expand==OFF)
  174.        { return(ch);  
  175.        }
  176.      }
  177.      /*----------------------*/
  178.      /* alt key is pressed   */
  179.      /*----------------------*/
  180.      else
  181.      { while(alt_pressed()==YES)
  182.        { ch=getkey();
  183.          
  184.          if(ch!=EOF)
  185.          { key_return=ON;
  186.            for (i=0;i<menu_acc_num;i++)
  187.            { if(menu_acc[i]==ch)
  188.              { return(menu_ident[i]);
  189.              }
  190.            }
  191.            for (i=0;i<title_num;i++)
  192.            { if(title_acc[i]==ch)
  193.              { title_ptr=i;
  194.                acc_expand=ON;
  195.                break;
  196.              }
  197.            }
  198.            if(acc_expand==OFF)
  199.            { return(ch);
  200.            }
  201.          }
  202.          if(acc_expand==ON)
  203.          { break;
  204.          }
  205.        }
  206.  
  207.  
  208.  
  209.  
  210.        if(key_return==ON && acc_expand==OFF)
  211.        { key_return=OFF;
  212.          return(EOF);
  213.        }
  214.  
  215.  
  216.  
  217.        if(acc_expand==OFF)
  218.        { title_ptr=0;
  219.        }
  220.        else
  221.        { title_ptr=i;
  222.        }
  223.      }
  224.    }
  225.  
  226.    /*--------------------------*/
  227.    /*   turn on the menu now   */
  228.    /*--------------------------*/
  229.    if(menu_descriptor==TEXT_FILE)
  230.    { fp=fopen(menu_file,"r");
  231.      if(fp==NULL)
  232.      { cls();
  233.        printf("\n cannot open file %s ",menu_file);
  234.        exit(-1);
  235.      }
  236.    }
  237.  
  238.    while(1)
  239.    { ch=expand(acc_expand);
  240.      if(acc_expand==ON)
  241.      { acc_expand=OFF;
  242.      }
  243.      switch(ch)
  244.      { case RIGHTKEY :
  245.         title_ptr++;
  246.         if(title_ptr==title_num)title_ptr=0;
  247.         continue;
  248.        case LEFTKEY  :
  249.         title_ptr--;
  250.         if(title_ptr<0)title_ptr=title_num-1;
  251.         continue;
  252.        case ESC      :
  253.         if(menu_descriptor==TEXT_FILE)
  254.         { fclose(fp);
  255.         }
  256.         return(EOF);
  257.        case ENTER    :
  258.         if(menu_descriptor==TEXT_FILE)
  259.         { fclose(fp);
  260.         }
  261.         return(cur_ident);
  262.      }
  263.    }
  264. }
  265. /*--------------------------------------------------------------------------*/
  266. /*                        initialize the menu system                        */
  267. /*--------------------------------------------------------------------------*/
  268. void init_menu(void)
  269. {
  270.   char buffer[100];
  271.   char dumy[40];
  272.   int  i;
  273.  
  274.   if(menu_descriptor==TEXT_FILE)
  275.   { fp=fopen(menu_file,"rb");
  276.     if(fp==NULL)
  277.     { cls();
  278.       printf("\n cannot open %s file \n press a key to exit to dos ",menu_file);
  279.       getch();
  280.       exit(-1);
  281.     }
  282.   }
  283.   frect(menu_x,menu_y,menu_x+menu_x_size-1,menu_y,menu_color,0);
  284.   title_num=0;
  285.   menu_acc_num=0;
  286.   while(next_line(buffer,sizeof(buffer))!=-1)
  287.   {       
  288.      if(strnicmp(buffer,"LINE",4)!=0 && strnicmp(buffer,"SUBMENU",7)!=0 &&
  289.         strnicmp(buffer,"END",3)!=0 && buffer[0]!='"')
  290.      { continue;
  291.      }
  292.  
  293.      if(buffer[1]!='%')
  294.      { if(menu_acc_num==MAX_ACC-1)
  295.        { continue;
  296.        }
  297.        if(strnicmp(buffer,"LINE",4)==0  ||
  298.            strnicmp(buffer,"SUBMENU",7)==0 ||
  299.             strnicmp(buffer,"END",3)==0        )
  300.        { continue;
  301.        }
  302.        menu_acc[menu_acc_num]=0;
  303.        seperate(buffer,dumy,&menu_ident[menu_acc_num],
  304.                             &menu_acc[menu_acc_num] ,ON  );
  305.        if( menu_acc[menu_acc_num]!=0)menu_acc_num++;
  306.        continue;  
  307.      }
  308.      title_hotkey[title_num]=seperate(buffer,menu_title[title_num],
  309.                          &title_ident[title_num],&title_acc[title_num],ON   );
  310.      if(title_hotkey[title_num]!=0)
  311.      { for(i=0;i<strlen(menu_title[title_num]);i++)
  312.        { if(menu_title[title_num][i]==title_hotkey[title_num])
  313.          { title_hotkey_loc[title_num]=i;
  314.            break;
  315.          }
  316.        }
  317.      }
  318.      title_loc[title_num]=get_pos();
  319.      title_x[title_num]=title_ptr;
  320.      pls(title_x[title_num],menu_y,menu_title[title_num]+1,menu_color);
  321.      place_title_hot(title_num);
  322.      title_ptr+=strlen(menu_title[title_num])+1;
  323.      title_num++;
  324.      if(title_num==MAX_TITLE)
  325.      { cls();
  326.        printf("\n too many menu titles ");
  327.        getch();
  328.        exit(-1);
  329.      }
  330.   }
  331.   if(menu_descriptor==TEXT_FILE)
  332.   { fclose(fp);
  333.   }
  334.  
  335. }
  336. /*--------------------------------------------------------------------------*/
  337. /*                        Display the menu bar                              */
  338. /*--------------------------------------------------------------------------*/
  339. void display_menu(void)
  340. {
  341.   int i;
  342.  
  343.   frect(menu_x,menu_y,menu_x+menu_x_size-1,menu_y,menu_color,0);
  344.   for(i=0;i<title_num;i++)
  345.   {  pls(title_x[i],menu_y,menu_title[i]+1,menu_color);
  346.      place_title_hot(i);
  347.   }
  348. }
  349. /*--------------------------------------------------------------------------*/
  350. /* seperate entry from identifier and accelerator, ad return the hotkey     */
  351. /*--------------------------------------------------------------------------*/
  352. unsigned char seperate(buffer,entry,ident,acc,hotkey_sep)
  353. char *buffer;
  354. char *entry;
  355. int  *ident;
  356. int  *acc;
  357. int  hotkey_sep;
  358. {
  359.  int i;
  360.  int j=0;
  361.  int s=0;
  362.  unsigned char hotkey=0;
  363.  
  364.  for(i=0;i<strlen(buffer);i++)
  365.  { if(buffer[i]=='"')
  366.    { s++;
  367.      continue;
  368.    }
  369.    if(s==1)
  370.    { if(buffer[i]=='^' )
  371.      { if(hotkey_sep==ON)
  372.        { i++;
  373.          hotkey=buffer[i];
  374.        }
  375.        else
  376.        { hotkey=buffer[i+1];
  377.        }
  378.      }
  379.      entry[j]=buffer[i];
  380.      j++;
  381.    }
  382.    if(s==2)
  383.    { entry[j]=0;
  384.      break;
  385.    }
  386.  }
  387.  
  388.  if  (s!=2)   
  389.  { cls();
  390.    printf("\n the following line in the menu descriptor file is illegal");
  391.    printf("\n var s=%d and ^%s^",s,buffer);
  392.    getch();
  393.    exit(-1);
  394.  }
  395.  sscanf(buffer+i+1,"%d %d",ident,acc);
  396.  return(hotkey);
  397. }
  398. /*--------------------------------------------------------------------------*/
  399. /* expand title # acc_expand                                                */
  400. /*--------------------------------------------------------------------------*/
  401. int expand(acc_expand)
  402. int acc_expand;
  403.   unsigned char entry[MAX_ENTRIES][50];
  404.   unsigned char hotkey[MAX_ENTRIES];
  405.   int hotkey_loc[MAX_ENTRIES];
  406.   unsigned char sep[42];
  407.   int  ident[MAX_ENTRIES];
  408.   int  acc  [MAX_ENTRIES];
  409.   long submenu_loc[MAX_ENTRIES];
  410.   int  entry_num=0;
  411.   int  entry_ptr=0;
  412.   char buffer[100];
  413.   int  box_x;
  414.   int  box_y;
  415.   int  box_width=0;
  416.   int  ch;
  417.   int  i;
  418.   int  mouse_left;
  419.   int  break_loop=OFF;
  420.   int  highlight;
  421.   /*---------------------------------*/
  422.   /* change color of the title first */
  423.   /*---------------------------------*/
  424.   pls(title_x[title_ptr],menu_y,menu_title[title_ptr]+1,menu_sel_color);
  425.   set_pos(&title_loc[title_ptr]);
  426.   while(next_line(buffer,sizeof(buffer))!=-1)
  427.   { 
  428.     if(strnicmp(buffer,"LINE",4)!=0 && strnicmp(buffer,"SUBMENU",7)!=0 &&
  429.        strnicmp(buffer,"END",3)!=0 && buffer[0]!='"')
  430.     { continue;
  431.     }
  432.     if(buffer[1]=='%')break;
  433.     submenu_loc[entry_num]=0L;
  434.     if(strnicmp(buffer,"LINE",4)==0)
  435.     { strcpy(entry[entry_num],"LINE");
  436.       entry_num++;
  437.       if(entry_num==MAX_ENTRIES)
  438.       { cls();
  439.         printf("\n too many entries for the title=%s",menu_title[title_ptr]);
  440.         getch();
  441.         exit(-1);
  442.       }
  443.       continue;
  444.     }
  445.     else if(strnicmp(buffer,"SUBMENU",7)==0)
  446.     { submenu_loc[entry_num-1]=get_pos();
  447.       i=1;
  448.       while(next_line(buffer,sizeof(buffer))!=-1)
  449.       { 
  450.         if(strnicmp(buffer,"LINE",4)!=0 && strnicmp(buffer,"SUBMENU",7)!=0 &&
  451.            strnicmp(buffer,"END",3)!=0 && buffer[0]!='"')
  452.         { continue;
  453.         }
  454.  
  455.         if(strnicmp(buffer,"SUBMENU",7)==0)
  456.         { i++;
  457.         }
  458.         if(strnicmp(buffer,"END",3)==0)
  459.         { i--;
  460.         }
  461.         if(i==0)break;
  462.       }
  463.       if(i!=0)
  464.       { cls();
  465.         printf("\n ERROR   SUBMENU without an END ");
  466.         getch();
  467.         exit(-1);
  468.       }
  469.       continue;
  470.     }
  471.     hotkey[entry_num]=seperate(buffer,entry[entry_num],&ident[entry_num],
  472.                                                        &acc[entry_num],ON )  ;
  473.     for(i=0;i<strlen(entry[entry_num]);i++)
  474.     { if(entry[entry_num][i]==hotkey[entry_num])
  475.       { hotkey_loc[entry_num]=i;
  476.         break;
  477.       }
  478.       else
  479.       { hotkey_loc[entry_num]=0;
  480.       }
  481.     }
  482.     if(hotkey[entry_num]>='a' && hotkey[entry_num]<='z')
  483.     { hotkey[entry_num]-=32;
  484.     }
  485.     if(strlen(entry[entry_num])>box_width)
  486.     { box_width=strlen(entry[entry_num]);
  487.     }
  488.     entry_num++;
  489.   }
  490.   /*-----------------------------------*/
  491.   /* show a box to expand the title on */
  492.   /*-----------------------------------*/
  493.   if(entry_num>0)
  494.   { box_x=title_x[title_ptr];
  495.     box_y=menu_y+1;
  496.   }
  497.   else
  498.   { if(acc_expand==ON)
  499.     { pls(title_x[title_ptr],menu_y,menu_title[title_ptr]+1,menu_sel_color);
  500.       cur_ident=title_ident[title_ptr];
  501.       return(ENTER);
  502.     }
  503.     box_x=-1;
  504.     box_y=-1;
  505.   }
  506.   strcpy(sep,"├");
  507.   for(i=0;i<box_width;i++)
  508.   { strcat(sep,"─");
  509.   }
  510.   strcat(sep,"┤");
  511.  
  512.  
  513.   if(entry_num>0)
  514.   { 
  515. /*-------------------------------------*/
  516. /* adjust box_x                        */
  517. /*-------------------------------------*/
  518.     if(box_x+box_width+3>79)
  519.     { box_x=79-box_width-3;
  520.       if(box_x+box_width+3>79)
  521.       { box_x=76-box_width;
  522.       }
  523.     }
  524.     messagebox(box_x,box_y,box_width+2,entry_num+2,menu_color,menu_shadow,1,YES);
  525.     for(i=0;i<entry_num;i++)
  526.     { if(stricmp(entry[i],"LINE")==0)
  527.       { pls(box_x,box_y+1+i,sep,menu_color);
  528.       }
  529.       else
  530.       { pls(box_x+1,box_y+1+i,entry[i],menu_color);
  531.         if(hotkey[i]!=0)
  532.         { writechar(box_x+1+hotkey_loc[i],box_y+1+i,entry[i][hotkey_loc[i]],
  533.                                                           menu_hotkey_color);
  534.         }
  535.         if(submenu_loc[i]!=0L)
  536.         { writechar(box_x+box_width,box_y+1+i,16,menu_color);
  537.         }
  538.       }
  539.     } 
  540.     chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_sel_color);
  541.     highlight=ON;
  542.   }
  543.   while(1)
  544.   { ch=getkey();
  545.     
  546.     if(ch!=EOF)
  547.     { for(i=0;i<title_num;i++)
  548.       { if(title_acc[i]==ch && title_ptr!=i)
  549.         { pls(title_x[title_ptr],menu_y,menu_title[title_ptr]+1,menu_color);
  550.           place_title_hot(title_ptr);
  551.           title_ptr=i;
  552.           break_loop=ON;
  553.           break;
  554.         }
  555.       }
  556.       for (i=0;i<menu_acc_num;i++)
  557.       { if(menu_acc[i]==ch)
  558.         { cur_ident=menu_ident[i];
  559.           ch=ENTER;
  560.           break_loop=ON;
  561.           break;
  562.         }
  563.       }
  564.     }
  565.     /*-------------------------------------*/
  566.     /* check if a hot key has been pressed */
  567.     /*-------------------------------------*/
  568.     if(ch>='a' && ch<='z')
  569.     { ch-=32;
  570.     }
  571.     for(i=0;i<entry_num;i++)
  572.     { if(ch==hotkey[i])
  573.       { cur_ident=ident[i];
  574.         chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_color);
  575.         if(hotkey[entry_ptr]!=0)
  576.         { writechar(box_x+1+hotkey_loc[entry_ptr],box_y+1+entry_ptr,
  577.                entry[entry_ptr][hotkey_loc[entry_ptr]],menu_hotkey_color);
  578.         }
  579.         entry_ptr=i;
  580.         chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_sel_color);
  581.         ch=ENTER;
  582.         break;
  583.       }
  584.     }
  585.     
  586.     mouse_left=mouse_state();
  587.     if(mouse_left==PRESSED)
  588.     { get_mouse_location();
  589.       if(mousex>=box_x+1 && mousex<=box_x+box_width &&
  590.          mousey>box_y && mousey<=box_y+entry_num )
  591.       { if(strnicmp(entry[mousey-box_y-1],"LINE",4)==0 && highlight==ON)
  592.         { chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_color);
  593.           if(hotkey[entry_ptr]!=0)
  594.           { writechar(box_x+1+hotkey_loc[entry_ptr],box_y+1+entry_ptr,
  595.                  entry[entry_ptr][hotkey_loc[entry_ptr]],menu_hotkey_color);
  596.           }
  597.           highlight=OFF;
  598.           continue;
  599.         }
  600.         if(entry_ptr != mousey-box_y-1 || highlight==OFF)
  601.         { if(strnicmp(entry[mousey-box_y-1],"LINE",4)==0)
  602.           { highlight=OFF;
  603.             continue;
  604.           }
  605.           chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_color);
  606.           if(hotkey[entry_ptr]!=0)
  607.           { writechar(box_x+1+hotkey_loc[entry_ptr],box_y+1+entry_ptr,
  608.                  entry[entry_ptr][hotkey_loc[entry_ptr]],menu_hotkey_color);
  609.           }
  610.           entry_ptr=mousey-box_y-1;
  611.           chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_sel_color);
  612.           highlight=ON;
  613.           continue;
  614.         }
  615.       }
  616.       else if(mousey==menu_y)     /* check for title change */
  617.       { for(i=0;i<title_num;i++)
  618.         { if(mousex>=title_x[i] && mousex<=title_x[i]+strlen(menu_title[i])-1
  619.                                 && title_ptr != i  )
  620.           { pls(title_x[title_ptr],menu_y,menu_title[title_ptr]+1,menu_color);
  621.             place_title_hot(title_ptr);
  622.             title_ptr=i;
  623.             break_loop=ON;
  624.             break;
  625.           }
  626.         }
  627.       }
  628.       else if(highlight==ON)
  629.       { chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_color);
  630.         if(hotkey[entry_ptr]!=0)
  631.         { writechar(box_x+1+hotkey_loc[entry_ptr],box_y+1+entry_ptr,
  632.                entry[entry_ptr][hotkey_loc[entry_ptr]],menu_hotkey_color);
  633.         }
  634.         highlight=OFF;
  635.       }
  636.     }
  637.     else if(mouse_left==PRESSEDRELEASED)
  638.     { if(mousex>=box_x+1 && mousex<=box_x+box_width &&
  639.          mousey>box_y && mousey<=box_y+entry_num)
  640.       { if(strnicmp(entry[mousey-box_y-1],"LINE",4)==0)
  641.         { ch=ESC;
  642.           break;
  643.         }
  644.         else
  645.         { cur_ident=ident[entry_ptr];
  646.           ch=ENTER;
  647.         }
  648.       }
  649.       else if(entry_num==0 && mousey==menu_y && mousex>=title_x[title_ptr]
  650.               && mousex<=title_x[title_ptr]+strlen(menu_title[title_ptr])-1 )
  651.       { ch=ENTER;
  652.         cur_ident=title_ident[title_ptr];
  653.       }
  654.       else if(entry_num>0 && mousey==menu_y && mousex>=title_x[title_ptr]
  655.               && mousex<=title_x[title_ptr]+strlen(menu_title[title_ptr])-1 )
  656.       { ms=RELEASED;
  657.         chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_sel_color);
  658.         continue;
  659.       }
  660.  
  661.       else
  662.       { ch=ESC;
  663.       }
  664.       ms=RELEASED;
  665.     }
  666.  
  667.  
  668.     if(ch==ENTER && entry_num>0 && submenu_loc[entry_ptr]!=0 )
  669.     { ch=submenu(submenu_loc[entry_ptr],box_x+box_width/2+1,box_y+entry_ptr+2);
  670.       if(ch==-2)
  671.       { get_mouse_location();
  672.         if(mousex>=box_x && mousex<=box_x+box_width+2 &&
  673.            mousey>=box_y+1 && mousey<=box_y+entry_num   )
  674.         { if(strnicmp(entry[mousey-box_y-1],"LINE",4)==0)
  675.           { ch=ESC;
  676.             break;
  677.           }
  678.           chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_color);
  679.           if(hotkey[entry_ptr]!=0)
  680.           { writechar(box_x+1+hotkey_loc[entry_ptr],box_y+1+entry_ptr,
  681.                  entry[entry_ptr][hotkey_loc[entry_ptr]],menu_hotkey_color);
  682.           }
  683.  
  684.           entry_ptr=mousey-box_y-1;
  685.           chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_sel_color);
  686.           continue;
  687.         }
  688.  
  689.         else if(mousey==menu_y)     /* check for title change */
  690.         { for(i=0;i<title_num;i++)
  691.           { if(mousex>=title_x[i] && mousex<=title_x[i]+strlen(menu_title[i])-1
  692.                                   && title_ptr != i  )
  693.             { pls(title_x[title_ptr],menu_y,menu_title[title_ptr]+1,menu_color);
  694.               place_title_hot(title_ptr);
  695.               title_ptr=i;
  696.               break_loop=ON;
  697.               break;
  698.             }
  699.           }
  700.           if(break_loop==OFF)
  701.           { ch=ESC;
  702.           }
  703.         }
  704.  
  705.         else
  706.         { ch=ESC;
  707.         }
  708.       }
  709.       
  710.       if(ch!=-1)
  711.       { break;
  712.       }
  713.     }
  714.     if(ch==RIGHTKEY || ch==LEFTKEY || ch==ESC || ch==ENTER)
  715.     { if(entry_num>0)
  716.       { cur_ident=ident[entry_ptr];
  717.       }
  718.       else
  719.       { cur_ident=title_ident[title_ptr];
  720.       }
  721.       break;
  722.     }
  723.  
  724.  
  725.     switch(ch)
  726.     { case DOWNKEY :
  727.        chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_color);
  728.        if(hotkey[entry_ptr]!=0)
  729.        { writechar(box_x+1+hotkey_loc[entry_ptr],box_y+1+entry_ptr,
  730.               entry[entry_ptr][hotkey_loc[entry_ptr]],menu_hotkey_color);
  731.        }
  732.        entry_ptr++;
  733.        if(entry_ptr==entry_num)entry_ptr=0;
  734.        if(stricmp(entry[entry_ptr],"LINE")==0)
  735.        { entry_ptr++;
  736.          if(entry_ptr==entry_num)entry_ptr=0;
  737.        }
  738.        chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_sel_color);
  739.        break;   
  740.       case UPKEY :
  741.        chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_color);
  742.        if(hotkey[entry_ptr]!=0)
  743.        { writechar(box_x+1+hotkey_loc[entry_ptr],box_y+1+entry_ptr,
  744.               entry[entry_ptr][hotkey_loc[entry_ptr]],menu_hotkey_color);
  745.        }
  746.        entry_ptr--;
  747.        if(entry_ptr<0)entry_ptr=entry_num-1;
  748.        if(stricmp(entry[entry_ptr],"LINE")==0)
  749.        { entry_ptr--;
  750.          if(entry_ptr<0)entry_ptr=entry_num-1;
  751.        }
  752.        chcolor(box_x+1,box_y+1+entry_ptr,box_width,1,menu_sel_color);
  753.        break;
  754.     }
  755.     if(break_loop==ON)break;
  756.   }
  757.  
  758.   /*-----------------------------------------*/
  759.   /* change the color of the menu title back */
  760.   /* remove the background box for entries   */
  761.   /*-----------------------------------------*/
  762.   pls(title_x[title_ptr],menu_y,menu_title[title_ptr]+1,menu_color);
  763.   place_title_hot(title_ptr);
  764.   if(entry_num>0)
  765.   { messagebox(box_x,box_y,box_width+2,entry_num+2,menu_color,menu_shadow,0,YES);
  766.   }
  767.   return(ch);
  768. }
  769. /*--------------------------------------------------------------------------*/
  770. /* Place the hotkey letter on the title using the hotkey color              */
  771. /*--------------------------------------------------------------------------*/
  772. void place_title_hot(tn)
  773. int tn;
  774.   if(title_hotkey[tn]!=0)
  775.   { writechar(title_x[tn]+title_hotkey_loc[tn]-1,
  776.                       menu_y,title_hotkey[tn],menu_hotkey_color);
  777.   }
  778.  
  779. }
  780. /*--------------------------------------------------------------------------*/
  781. /* display submenu associated with an entry                                 */
  782. /*--------------------------------------------------------------------------*/
  783. int submenu(location,xstart,ystart)
  784. long location;
  785. int  xstart;
  786. int  ystart;
  787. {
  788.   char     menu[20][40];
  789.   int      m_ident[20];
  790.   long     submenu_loc[20];
  791.   int      menu_num=0;
  792.   char     buffer[100];
  793.   int      box_width=0;
  794.   int      ch=0;
  795.   int      i;
  796.   int      sl;
  797.   int      def=0;
  798.  
  799.   memset(menu,0,(size_t)600);
  800.  
  801.   set_pos(&location);
  802.   
  803.   while(next_line(buffer,sizeof(buffer))!=-1)
  804.   { 
  805.     if(strnicmp(buffer,"LINE",4)!=0 && strnicmp(buffer,"SUBMENU",7)!=0 &&
  806.        strnicmp(buffer,"END",3)!=0 && buffer[0]!='"')
  807.     { continue;
  808.     }
  809.     if(strnicmp(buffer,"END",3)==0)
  810.     { break;
  811.     }
  812.     submenu_loc[menu_num]=0L;
  813.     if(strnicmp(buffer,"SUBMENU",7)==0)
  814.     { submenu_loc[menu_num-1]=get_pos();
  815.       
  816.       i=1;
  817.       while(next_line(buffer,sizeof(buffer))!=-1)
  818.       { 
  819.         if(strnicmp(buffer,"LINE",4)!=0 && strnicmp(buffer,"SUBMENU",7)!=0 &&
  820.            strnicmp(buffer,"END",3)!=0 && buffer[0]!='"')
  821.         { continue;
  822.         }
  823.         if(strnicmp(buffer,"SUBMENU",7)==0)
  824.         { i++;
  825.         }
  826.         if(strnicmp(buffer,"END",3)==0)
  827.         { i--;
  828.         }
  829.         if(i==0)break;
  830.       }
  831.       if(i!=0)
  832.       { cls();
  833.         printf("\n ERROR   SUBMENU without an END ");
  834.         getch();
  835.         exit(-1);
  836.       }
  837.       continue;
  838.     }
  839.     if(strnicmp(buffer,"LINE",4)==0)
  840.     { strcpy(menu[menu_num],"LINE");
  841.       menu_num++;
  842.       continue;
  843.     }
  844.     ch=seperate(buffer,menu[menu_num],&m_ident[menu_num],&i,OFF );
  845.     if(strlen(menu[menu_num])>box_width && ch==0)
  846.     { box_width=strlen(menu[menu_num]);
  847.     }
  848.     else if(strlen(menu[menu_num])-1>box_width && ch!=0)
  849.     { box_width=strlen(menu[menu_num])-1;
  850.     }
  851.     menu_num++;
  852.   }
  853.  
  854.   for(i=0;i<menu_num;i++)
  855.   { while(strlen(menu[i])<box_width)
  856.     { strcat(menu[i]," ");
  857.     }
  858.     if(submenu_loc[i]!=0)
  859.     { if(strchr(menu[i],'^')==NULL)
  860.       { menu[i][box_width-1]=16;
  861.       }
  862.       else
  863.       { menu[i][box_width]=16;
  864.       }
  865.     }
  866.   }
  867.   /*--------------------------------------------------*/
  868.   /* adjust xstart and ystart to stay on the screen   */
  869.   /*--------------------------------------------------*/
  870.   if (xstart+box_width+3>txt_scr_xsize-1)
  871.   { xstart-=box_width+3;
  872.   }
  873.   if (ystart+menu_num+1>txt_scr_ysize-1)
  874.   { ystart=txt_scr_ysize-3-menu_num;
  875.   }
  876.   /*--------------------------------------------------*/
  877.   messagebox(xstart,ystart,box_width+2,menu_num+2,menu_color,
  878.                                                            menu_shadow,1,YES);
  879.   while(1)
  880.   {
  881.     ch=menus(menu,menu_num,xstart+1,ystart+1,menu_color,menu_sel_color,def);
  882.     if(ch>=0 && ch<menu_num)
  883.     { def=ch;
  884.     }
  885.     if(submenu_loc[ch]!=0L && ch!=-1 && ch!=-2)
  886.     { ch=submenu(submenu_loc[ch],xstart+box_width/2+1,ystart+ch+2);
  887.       if(ch==ENTER)
  888.       { ch=ESC;
  889.         break;
  890.       }
  891.       if(ch==-1 )continue;
  892.       if(ch==-2)
  893.       { sl=0;
  894.         for(i=0;i<menu_num;i++)
  895.         { if(strlen(menu[i])>sl)
  896.           { sl=strlen(menu[i]);
  897.           }
  898.         }
  899.         get_mouse_location();
  900.         if(mousex>=xstart+1 && mousex<=xstart+sl+1 && 
  901.             mousey>=ystart+1 && mousey<=ystart+menu_num)
  902.         { def=mousey-ystart-1;
  903.           continue;
  904.         }
  905.       }
  906.     }
  907.     break;
  908.   }
  909.   messagebox(xstart,ystart,box_width+2,menu_num+2,menu_color,
  910.                                                            menu_shadow,0,YES);
  911.   if(ch==-1 || ch==-2)
  912.   { return(ch);
  913.   }
  914.   if(ch!=ESC)
  915.   { cur_ident=m_ident[ch];
  916.   }
  917.   return(ENTER);
  918.   
  919. }
  920. /*--------------------------------------------------------------------------*/
  921. /* return number of spaces in the begining of a line                        */
  922. /*--------------------------------------------------------------------------*/
  923. int remove_spaces(buffer)
  924. char *buffer;
  925. { int i=0;
  926.  
  927.   while (buffer[i]==' ')
  928.   { i++;
  929.   }
  930.   return(i);
  931. }
  932. /*--------------------------------------------------------------------------*/
  933. /*--------------------------------------------------------------------------*/
  934. /* menus function will create a vertical scrolling menu, when a menu is     */
  935. /* selected, it will return the menu number which was highlighted           */
  936. /* parameters :  menu     -> two dimentional array of the menu text         */
  937. /*                             menu[menu_number][field_length]              */
  938. /*               menu_num -> number of menus to be displayed                */
  939. /*               x        -> left coordinate of the left side of the menu   */
  940. /*               y        -> top  coordinate of the menu                    */
  941. /*               menu_col -> menu display color                             */
  942. /*               sel_col  -> highlighted menu color                         */
  943. /*               def_menu -> highlighted menu at default, if 0 first entry  */
  944. /*                           is highlighted.                                */
  945. /*--------------------------------------------------------------------------*/
  946.                                                                             
  947. int menus(menu,menu_num,x,y,menu_col,sel_col,def_menu)
  948.  
  949. char menu[20][40] ;                         /* menu array                */
  950. int  menu_num;                              /* number of menus           */
  951. int  x;                                     /* x coordinate of the menu  */
  952. int  y;                                     /* y coordinate of top left  */
  953. int  menu_col;                              /* color of the menu display */
  954. int  sel_col;                               /* selected menu color       */
  955. int  def_menu;                              /* default menu number       */
  956.                                             /* if -1 just display items  */
  957. {
  958.   int  i;
  959.   int  ch;
  960.   int  mp;                                   /* menu pointer              */
  961.   int  sl=0;
  962.   unsigned char sep[60];
  963.   int  highlight;
  964.   char *c;
  965.   unsigned char menu_hotkey[20];
  966.   int           hotkey_loc[20];
  967.   char          buffer[50];
  968.  
  969.   mp=def_menu;
  970.   ms=RELEASED;
  971.  
  972.   for(i=0;i<menu_num;i++)
  973.   { c=strchr(menu[i],'^');
  974.     if(c!=NULL)
  975.     { menu_hotkey[i]=c[1];
  976.       if(menu_hotkey[i]>='a' && menu_hotkey[i]<='z')
  977.       { menu_hotkey[i]-=32;
  978.       }
  979.       hotkey_loc[i]=c-menu[i];
  980.     }
  981.     else
  982.     { menu_hotkey[i]=0;
  983.       hotkey_loc[i]=-1;
  984.     }
  985.     if( (strlen(menu[i])>sl && menu_hotkey[i]==0) ||
  986.         (strlen(menu[i])-1 >sl && menu_hotkey[i]!=0 )  )
  987.     {  if(menu_hotkey[i]==0)
  988.        { sl=strlen(menu[i]);
  989.        }
  990.        else
  991.        { sl=strlen(menu[i])-1;
  992.        }
  993.     }
  994.   }
  995.  
  996.   strcpy(sep,(unsigned char *)"├");
  997.   for(i=0;i<sl;i++)
  998.   { strcat(sep,(unsigned char *)"─");
  999.   }
  1000.   strcat(sep,(unsigned char *)"┤");
  1001.  
  1002.  
  1003.   for(i=0;i<menu_num;i++)                   /* draw the menu with highlight */
  1004.   { if(strlen(menu[i])<sl)
  1005.     { while(strlen(menu[i])<sl)
  1006.       { strcat(menu[i]," ");
  1007.       }
  1008.     }
  1009.     if(strnicmp(menu[i],"LINE",4)==0)
  1010.     { pls(x-1,y+i,(unsigned char *)sep,menu_color);
  1011.       continue;
  1012.     }
  1013.     strcpy(buffer,menu[i]);
  1014.  
  1015.     if(menu_hotkey[i]!=0)
  1016.     { c=strchr(buffer,'^');
  1017.       strcpy(c,c+1);
  1018.     }
  1019.  
  1020.     if(i==def_menu)
  1021.     { pls(x,y+i,(unsigned char *)buffer,sel_col);
  1022.     }
  1023.     else 
  1024.     { pls(x,y+i,(unsigned char *)buffer,menu_col);
  1025.       if(menu_hotkey[i]!=0)
  1026.       { writechar(x+hotkey_loc[i],y+i,menu[i][hotkey_loc[i]+1],menu_hotkey_color);
  1027.       }
  1028.     }
  1029.   }
  1030.   if(def_menu==-1)return(-1);
  1031.   highlight=ON;
  1032.  
  1033.   while(1)
  1034.   { ch=getkey();
  1035.     
  1036.     if(ch>='a' && ch<='z')
  1037.     { ch-=32;
  1038.     }
  1039.     if(ch!=EOF)
  1040.     { for(i=0;i<menu_num;i++)
  1041.       { if(ch==menu_hotkey[i])
  1042.         { ch=ENTER;
  1043.           chcolor(x,y+mp,sl,1,menu_col);
  1044.           if(menu_hotkey[mp]!=0)
  1045.           { writechar(x+hotkey_loc[mp],y+mp,menu[mp][hotkey_loc[mp]+1],
  1046.                                                          menu_hotkey_color);
  1047.           }
  1048.           mp=i;
  1049.           chcolor(x,y+mp,sl,1,sel_col);
  1050.           break;
  1051.         }
  1052.       }
  1053.     }
  1054.  
  1055.     if(ch==EOF && mousefound==YES)     /* check mouse */
  1056.     { if(mouse_state()==PRESSED)
  1057.       { get_mouse_location();
  1058.  
  1059.         if(mousex>=x && mousex<x+strlen(menu[0]) &&
  1060.            mousey>=y && mousey<y+menu_num     )
  1061.         { if(strnicmp(menu[mousey-y],"LINE",4)==0)
  1062.           { if(highlight==ON)
  1063.             { chcolor(x,y+mp,sl,1,menu_col);
  1064.               if(menu_hotkey[mp]!=0)
  1065.               { writechar(x+hotkey_loc[mp],y+mp,menu[mp][hotkey_loc[mp]+1],
  1066.                                                           menu_hotkey_color);
  1067.               }
  1068.               highlight=OFF;
  1069.             }
  1070.           }
  1071.           else if(highlight==OFF)
  1072.           { mp=mousey-y;
  1073.             chcolor(x,mousey,sl,1,sel_col);
  1074.             highlight=ON;
  1075.           }
  1076.           else
  1077.           { if(mp+y>mousey)ch=UPKEY;
  1078.             else if(mp+y<mousey)ch=DOWNKEY;
  1079.             else ch=EOF;
  1080.           }
  1081.         }
  1082.         else
  1083.         { if(highlight==ON)
  1084.           { chcolor(x,y+mp,sl,1,menu_col);
  1085.             if(menu_hotkey[mp]!=0)
  1086.             { writechar(x+hotkey_loc[mp],y+mp,menu[mp][hotkey_loc[mp]+1],
  1087.                                                            menu_hotkey_color);
  1088.             }
  1089.             highlight=OFF;
  1090.           }
  1091.         }
  1092.       }
  1093.       else if(mouse_state()==PRESSEDRELEASED)
  1094.       { get_mouse_location();
  1095.         if(mousex>=x && mousex<x+strlen(menu[0]) &&
  1096.            mousey>=y && mousey<y+menu_num            )
  1097.         { ch=ENTER;
  1098.         }
  1099.         else ch=-2;
  1100.         ms=RELEASED;
  1101.       }
  1102.     }
  1103.  
  1104.     if(ch==UPKEY || ch==DOWNKEY)
  1105.     {  if(mousefound==YES)hide_mouse_cursor();
  1106.        chcolor(x,y+mp,sl,1,menu_col);
  1107.        if(menu_hotkey[mp]!=0)
  1108.        { writechar(x+hotkey_loc[mp],y+mp,menu[mp][hotkey_loc[mp]+1],
  1109.                                                            menu_hotkey_color);
  1110.        }
  1111.        if(ch==UPKEY)
  1112.        { mp--;
  1113.          if(strnicmp(menu[mp],"LINE",4)==0)mp--;
  1114.          if(mp<0)mp=menu_num-1;
  1115.        }
  1116.        if(ch==DOWNKEY)
  1117.        { mp++;
  1118.          if(strnicmp(menu[mp],"LINE",4)==0)mp++;
  1119.          if(mp==menu_num)mp=0;
  1120.        }
  1121.        chcolor(x,y+mp,sl,1,sel_col);
  1122.        if(mousefound==YES)show_mouse_cursor();
  1123.     }
  1124.     if(ch==ENTER)return(mp);
  1125.     if(ch==ESC)return(-1);
  1126.     if(ch==-2) return(-2);
  1127.   }
  1128. }
  1129.  
  1130. /*--------------------------------------------------------------------------*/
  1131. /* place a string on the screen at appropriate coordinates                  */
  1132. /*       parameters : xx1,yy1 -> coordinates                                */
  1133. /*                    c       -> character pointer                          */
  1134. /*                    cm      -> display color                              */ 
  1135. /*--------------------------------------------------------------------------*/
  1136.  
  1137. void pls (int xx1,int yy1,unsigned char c[],int cm)                         
  1138.  
  1139. { int i;
  1140.   int m;
  1141.  
  1142.  
  1143.   if(initvar==0)
  1144.   {  cls();
  1145.      printf("\a \n Display borad not initialized");
  1146.      getch();
  1147.      exit(-1);
  1148.   }
  1149.  
  1150.   m=mouse_display;
  1151.   if(mouse_display==YES) 
  1152.   { hide_mouse_cursor();
  1153.   }
  1154.   for (i = 0;i <strlen((char *)c) ;i++ )
  1155.   { writechar(xx1+i,yy1,c[i],cm);
  1156.   }
  1157.   if(m==YES)
  1158.   { show_mouse_cursor();
  1159.   }
  1160. }
  1161. /*--------------------------------------------------------------------------*/
  1162. /* display a text mode rectangle Parameters: xx1,yy1,xx2,yy2 -> coordinates */
  1163. /*                                           cm              -> color       */                                                                
  1164. /*--------------------------------------------------------------------------*/
  1165.  
  1166. void rect(int xx1,int yy1,int xx2,int yy2,int cm)
  1167.   int x,y ;
  1168.   int m;
  1169.  
  1170.   m=mouse_display;
  1171.   if(mouse_display==YES) 
  1172.   { hide_mouse_cursor();
  1173.   }
  1174.  
  1175.  
  1176.   if (xx1<=xx2 && yy1<=yy2)
  1177.   { for (x = xx1; x < xx2; x++)
  1178.     { writechar(x,yy1,196,cm);
  1179.       writechar(x,yy2,196,cm);
  1180.     }
  1181.  
  1182.      for (y = yy1+1; y < yy2; y++) 
  1183.     { writechar(xx1,y,179,cm);
  1184.       writechar(xx2,y,179,cm);
  1185.     }                          
  1186.  
  1187.     writechar(xx1,yy1,218,cm);
  1188.     writechar(xx2,yy1,191,cm);
  1189.     writechar(xx1,yy2,192,cm);
  1190.     writechar(xx2,yy2,217,cm);
  1191.  
  1192.   } 
  1193.   if(m==YES)
  1194.   { show_mouse_cursor();
  1195.   }
  1196. }
  1197.  
  1198. /*--------------------------------------------------------------------------*/
  1199. /* display a text mode filled rectangle.                                    */
  1200. /*                               Parameters: xx1,yy1,xx2,yy2 -> coordinates */
  1201. /*                                           cm              -> color       */                                                                
  1202. /*--------------------------------------------------------------------------*/
  1203. void frect(int xx1,int yy1,int xx2,int yy2,int cm,int shadow)
  1204. {
  1205.  int x,y;
  1206.  int m;    
  1207.  
  1208.  if(initvar==0)
  1209.  {  cls();
  1210.     printf("\a \n Display borad not initialized");
  1211.     getch();
  1212.     exit(-1);
  1213.  }
  1214.  
  1215.  m=mouse_display;
  1216.  if(mouse_display==YES) 
  1217.  { hide_mouse_cursor();
  1218.  }
  1219.  
  1220.  for (y=yy1;y<yy2+1;y++)
  1221.  { for (x=xx1;x<xx2+1;x++)
  1222.    { writechar(x,y,back_block,cm);
  1223.    }    
  1224.  }        
  1225.  if(shadow!=0)
  1226.  { chcolor(xx1+2,yy2+1,xx2-xx1+1,1,shadow);
  1227.    chcolor(xx2+1,yy1+1,2,yy2-yy1,shadow);
  1228.  }
  1229.  if(m==YES)
  1230.  { show_mouse_cursor();
  1231.  }
  1232. }
  1233. /*--------------------------------------------------------------------------*/
  1234. /* return a key from the keyboard, if non return EOF                        */
  1235. /*--------------------------------------------------------------------------*/
  1236. int getkey(void)
  1237. {
  1238.  int key, lo, hi;
  1239.  if(!kbhit())return(EOF);
  1240.  key = bioskey(0);
  1241.  lo = key & 0X00FF;
  1242.  hi = (key & 0XFF00) >> 8;
  1243.  if(lo==0)return(hi+256);
  1244.  return(lo);
  1245.  
  1246. /*  return((lo == 0) ? hi + 256 : lo);  */
  1247. }
  1248. /*--------------------------------------------------------------------------*/
  1249. /* display a filled rectangle, while preserving the background.  The        */
  1250. /* background is saved in an allocated memory.  If malloc failes, this      */
  1251. /* routine will exit to dos.  
  1252. /* and remove the box.                                                      */
  1253. /*                      Parameters : x,y       -> coordinates of top left.  */
  1254. /*                                   xsize     -> size in x direction.      */
  1255. /*                                   ysize     -> size in y direction.      */
  1256. /*                                   backcolor -> color of the box.         */
  1257. /*                                   forcolor  -> border line color.        */
  1258. /*                                   sw        -> display or remove switch  */
  1259. /*                                                  sw=1 : draw the box     */
  1260. /*                                                  sw=0 : remove the last  */
  1261. /*                                                         draw box         */
  1262. /*                                   border    -> draw border on the box    */
  1263. /*--------------------------------------------------------------------------*/
  1264.  
  1265. int messagebox(x,y,xsize,ysize,color,shadow,sw,border)
  1266. int x;
  1267. int y;
  1268. int xsize;
  1269. int ysize;
  1270. int color;
  1271. int shadow;
  1272. int sw;
  1273. int border;
  1274.   int i,j;
  1275.   unsigned char *temp;
  1276.   unsigned char far *scr_temp;
  1277.   int save_xsize;
  1278.   int save_ysize;
  1279.   int m;
  1280.  
  1281.  
  1282.  
  1283.   if(sw==-1)
  1284.   { box_num=0;
  1285.     return(-1);
  1286.   }   
  1287.  
  1288.   if(initvar==0)
  1289.   {  cls();
  1290.      printf("\a \n Display borad not initialized");
  1291.      getch();
  1292.      exit(-1);
  1293.   }
  1294.  
  1295.  if(shadow==0)
  1296.  { save_ysize=ysize;
  1297.    save_xsize=xsize;
  1298.  }
  1299.  else
  1300.  { save_ysize=ysize+1;
  1301.    save_xsize=xsize+2;
  1302.  }
  1303.  
  1304.  switch(sw)
  1305.  {
  1306.    case ON :
  1307.     m=mouse_display;
  1308.     if(mouse_display==YES) 
  1309.     { hide_mouse_cursor();
  1310.     }
  1311.  
  1312.     if(box_num==MAX_ENTRIES)
  1313.     { cls();
  1314.       printf("\n box_num has reached the maximum allowed submenu levels");
  1315.       printf("\n to increase the levels change MAX_WINDOWS in def.h    ");
  1316.       getch();
  1317.       exit(-1);
  1318.     }
  1319.     if( (save_box[box_num]=malloc(save_ysize*save_xsize*2))==NULL)
  1320.     { cls();
  1321.       printf("\n not enough memory for message box # %d",box_num);
  1322.       getch();
  1323.       exit(-1);
  1324.     }
  1325.  
  1326.     temp=save_box[box_num];
  1327.  
  1328.     for(i=y;i<y+save_ysize;i++)
  1329.     { 
  1330.       for(j=x;j<x+save_xsize;j++)
  1331.       { 
  1332.         *temp++=readchar(j,i);
  1333.         *temp++=readcolor(j,i);
  1334.       }
  1335.     }
  1336.     /*------------------------------*/
  1337.     /* text background is saved now */
  1338.     /*------------------------------*/
  1339.  
  1340.     /*------------------------------*/
  1341.     /* save graphics background now */
  1342.     /*------------------------------*/
  1343.  
  1344.     if(font_width>1)
  1345.     { /*
  1346.       if( (gsave_box[box_num]=malloc(save_ysize*save_xsize*font_width*font_height))==NULL)
  1347.       { cls();
  1348.         printf("\n not enough memory for graphics message box # %d",box_num);
  1349.         printf("\n tryed to allocate %u bytes",save_ysize*save_xsize*font_width*font_height);
  1350.         getch();
  1351.         exit(-1);
  1352.       }
  1353.       temp=gsave_box[box_num];
  1354.       */
  1355.     }
  1356.  
  1357.  
  1358.  
  1359.  
  1360.     frect(x,y,x+xsize-1,y+ysize-1,  color,shadow);
  1361.  
  1362.     if(border==YES)
  1363.     { rect(x,y,x+xsize-1,y+ysize-1,color);
  1364.     }
  1365.  
  1366.     xwin[box_num]=x;
  1367.     ywin[box_num]=y;
  1368.  
  1369.     xwinsize[box_num]=xsize;
  1370.     ywinsize[box_num]=ysize;
  1371.     
  1372.     wincolor[box_num]=color;
  1373.     winshadow[box_num]=shadow;
  1374.     winborder[box_num]=border;
  1375.  
  1376.     box_num++;
  1377.     break;
  1378.  
  1379.    case OFF :
  1380.     m=mouse_display;
  1381.     if(mouse_display==YES) 
  1382.     { hide_mouse_cursor();
  1383.     }
  1384.     box_num--;
  1385.     temp=save_box[box_num];
  1386.     for(i=y;i<y+save_ysize;i++)
  1387.     {  
  1388.        for(j=x;j<x+save_xsize;j++)
  1389.        { 
  1390.          writechar(j,i,*temp,*(temp+1) );
  1391.          temp+=2;
  1392.        }
  1393.     }
  1394.     free(save_box[box_num]);
  1395.     break;
  1396.  } /* end of the switch statement */
  1397.  if(m==YES)
  1398.  { show_mouse_cursor();
  1399.  }
  1400.  return(box_num-1);
  1401. }
  1402. /*--------------------------------------------------------------------------*/
  1403. /* change color of a rectangle without changing the characters.             */
  1404. /*--------------------------------------------------------------------------*/
  1405. void chcolor(x,y,xsize,ysize,color)
  1406. int x;
  1407. int y;
  1408. int xsize;
  1409. int ysize;
  1410. int color;
  1411. { int i;
  1412.   int j;
  1413.   int m;
  1414.   unsigned char far *scr_temp;
  1415.  
  1416.   m=mouse_display;
  1417.   if(mouse_display==YES) 
  1418.   { hide_mouse_cursor();
  1419.   }
  1420.  
  1421.   for(j=y;j<y+ysize;j++)
  1422.   { 
  1423.     for(i=x;i<x+xsize;i++)
  1424.     { writechar(i,j,readchar(i,j),color);
  1425.     }
  1426.   }
  1427.   if(m==YES)
  1428.   { show_mouse_cursor();
  1429.   }
  1430. }
  1431. /*--------------------------------------------------------------------------*/
  1432. /* Initialize the mouse driver                                              */
  1433. /*--------------------------------------------------------------------------*/
  1434. void init_mouse(void)
  1435. {
  1436.  int int_handler;
  1437.  long vector;
  1438.  unsigned char first_byte;
  1439.  
  1440.  
  1441.  int_handler=(int)getvect(0x33);
  1442.  first_byte=*(unsigned char far *)int_handler;
  1443.  vector = (long) int_handler;
  1444.  
  1445.  
  1446.  if((vector==0) || (first_byte==0xcf))
  1447.  { mousefound=NO;
  1448.    ms=RELEASED;
  1449.    return; /* mouse driver not found */
  1450.  }
  1451.  /* reset the mouse */
  1452.  iReg.x.ax=0;
  1453.  int86(0x33,&iReg,&oReg);
  1454.  mousefound=YES;
  1455.  if(mouse_left_pressed()==YES)
  1456.  { ms=PRESSED;
  1457.  }
  1458.  else
  1459.  { ms=RELEASED;
  1460.  }
  1461.  
  1462.  
  1463. }    /* end of set mouse */
  1464. /*--------------------------------------------------------------------------*/
  1465. /* Display the mouse cursor                                                 */
  1466. /*--------------------------------------------------------------------------*/
  1467. void show_mouse_cursor(void)
  1468. {
  1469.    if(mousefound==NO)return;
  1470.    iReg.x.ax=1;
  1471.    int86(0x33,&iReg,&oReg);
  1472.    mouse_display=YES;
  1473. }
  1474. /*--------------------------------------------------------------------------*/
  1475. /* Hide the mouse cursor                                                    */
  1476. /*--------------------------------------------------------------------------*/
  1477. void hide_mouse_cursor(void)
  1478. {  
  1479.    if(mousefound==NO)return;
  1480.    iReg.x.ax=2;
  1481.    int86(0x33,&iReg,&oReg);
  1482.    mouse_display=NO;
  1483. }
  1484. /*--------------------------------------------------------------------------*/
  1485. /* find the mouse location and assign it to mousex, and mousey.             */
  1486. /*--------------------------------------------------------------------------*/
  1487. void get_mouse_location(void)
  1488. {
  1489.   if(mousefound==NO)return;
  1490.   iReg.x.ax=3;
  1491.   int86(0x33,&iReg,&oReg);
  1492.   mousex=oReg.x.cx/8;
  1493.   mousey=oReg.x.dx/8;
  1494. }
  1495. /*--------------------------------------------------------------------------*/
  1496. /* return the state of the left mouse key  (YES) pressed     (NO) released  */
  1497. /*--------------------------------------------------------------------------*/
  1498. int mouse_left_pressed(void)
  1499. {
  1500.   if(mousefound==NO)return(NO);
  1501.   iReg.x.ax=3;
  1502.   int86(0x33,&iReg,&oReg);
  1503.   if(oReg.x.bx==1) return(YES);
  1504.   return(NO);
  1505. }
  1506. /*--------------------------------------------------------------------------*/
  1507. /* return the mouse state, and keep track of if mouse left key has been     */
  1508. /* pressed and released.                                                    */
  1509. /*--------------------------------------------------------------------------*/
  1510. int mouse_state(void)
  1511. {
  1512.   int a;
  1513.   a=mouse_left_pressed();
  1514.   if(a==YES)
  1515.   { ms=PRESSED;
  1516.     return(ms);
  1517.   }
  1518.   if(ms==PRESSED && a==NO)
  1519.   { ms=PRESSEDRELEASED;
  1520.     return(ms);
  1521.   }
  1522.   return(ms);
  1523. }
  1524. /*--------------------------------------------------------------------------*/
  1525. /* control the text cursor                                                  */
  1526. /*                 action :                                                 */
  1527. /*                             ON : turn on the text cursor                 */
  1528. /*                            OFF : turn off the text cursor                */
  1529. /*                          BLOCK : change the text cursor to a block       */
  1530. /*                         SQUARE : change the text cursor to a square      */
  1531. /*                           LINE : change the text cursor to a line        */
  1532. /*                       POSITION : set the text cursor location to         */
  1533. /*                                  txt_curs_x,txt_curs_y.                  */ 
  1534. /*--------------------------------------------------------------------------*/
  1535. void txt_curs(action)
  1536. int action;
  1537. {
  1538.   union REGS reg;
  1539.  
  1540.   return;
  1541.  
  1542.   switch(action)
  1543.   {
  1544.     case ON  :
  1545.      reg.h.ah=1;
  1546.      reg.h.ch=curs_start_line;
  1547.      reg.h.cl=curs_end_line;
  1548.      break;
  1549.     case OFF :
  1550.      reg.h.ah=1;
  1551.      reg.h.ch=1;
  1552.      reg.h.cl=0;
  1553.      break;
  1554.     case BLOCK :
  1555.      reg.h.ah=1;
  1556.      curs_start_line=0;
  1557.      curs_end_line=8;
  1558.      reg.h.ch=curs_start_line;
  1559.      reg.h.cl=curs_end_line;
  1560.      break;
  1561.     case SQUARE :
  1562.      reg.h.ah=1;
  1563.      curs_start_line=4;
  1564.      curs_end_line=8;
  1565.      reg.h.ch=curs_start_line;
  1566.      reg.h.cl=curs_end_line;
  1567.      break;
  1568.     case LINE  :
  1569.      reg.h.ah=1;
  1570.      curs_start_line=8;
  1571.      curs_end_line=8;
  1572.      reg.h.ch=curs_start_line;
  1573.      reg.h.cl=curs_end_line;
  1574.      break;
  1575.     case POSITION :
  1576.      reg.h.ah=2;
  1577.      reg.h.dh=txt_curs_y;
  1578.      reg.h.dl=txt_curs_x;
  1579.      reg.h.bh=0;
  1580.      break;
  1581.     default :
  1582.      return;
  1583.  
  1584.   }
  1585.  
  1586.   int86(0x10,®,®); 
  1587.  
  1588. }
  1589. /*--------------------------------------------------------------------------*/
  1590. /* clear the screen to black                                                */
  1591. /*--------------------------------------------------------------------------*/
  1592. void cls(void)
  1593. {
  1594.   if(initvar==0)
  1595.   {  system("CLS");
  1596.      printf("\a \n Display borad not initialized");
  1597.      getch();
  1598.      exit(-1);
  1599.   }
  1600.  
  1601.   frect(0,0,txt_scr_xsize-1,txt_scr_ysize-1,0x07,0);
  1602. }
  1603. /*--------------------------------------------------------------------------*/
  1604. /* return the state of the ALT key                                          */
  1605. /*--------------------------------------------------------------------------*/
  1606. int alt_pressed(void)
  1607. {
  1608.   if( (bioskey(2) & 0x08)!=0 ) return(YES);
  1609.   return(NO);
  1610. }
  1611. /*--------------------------------------------------------------------------*/
  1612. /* change the color of the menu.  Call this function before bar_menu(INIT)  */
  1613. /*--------------------------------------------------------------------------*/
  1614. void bg_menu_color(int color)
  1615. {
  1616.   menu_color&=0x0F;
  1617.   menu_color|=color;
  1618. }
  1619. void fg_menu_color(int color)
  1620. {
  1621.   menu_color&=0xF0;
  1622.   menu_color|=color;
  1623. }
  1624. /*--------------------------------------------------------------------------*/
  1625. /* change the color of the menu hotkeys.                                    */
  1626. /* Call this function before bar_menu(INIT)                                 */
  1627. /*--------------------------------------------------------------------------*/
  1628. void bg_menu_hotkey_color(int color)
  1629. {
  1630.   menu_hotkey_color&=0x0F;
  1631.   menu_hotkey_color|=color;
  1632. }
  1633. void fg_menu_hotkey_color(int color)
  1634. {
  1635.   menu_hotkey_color&=0xF0;
  1636.   menu_hotkey_color|=color;
  1637. }
  1638.  
  1639. /*--------------------------------------------------------------------------*/
  1640. /* change the color of the highlighted menu.                                */
  1641. /* Call this function before bar_menu(INIT)                                 */
  1642. /*--------------------------------------------------------------------------*/
  1643. void bg_menu_sel_color(int color)
  1644. {
  1645.   menu_sel_color&=0x0F;
  1646.   menu_sel_color|=color;
  1647. }
  1648. void fg_menu_sel_color(int color)
  1649. {
  1650.   menu_sel_color&=0xF0;
  1651.   menu_sel_color|=color;
  1652. }
  1653. /*--------------------------------------------------------------------------*/
  1654. /* change the color of the rectangle shadow.                                */
  1655. /* Call this function before bar_menu(INIT)                                 */
  1656. /*--------------------------------------------------------------------------*/
  1657. void bg_menu_shadow(int color)
  1658. {
  1659.   menu_shadow&=0x0F;
  1660.   menu_shadow|=color;
  1661. }
  1662. void fg_menu_shadow(int color)
  1663. {
  1664.   menu_shadow&=0x0F;
  1665.   menu_shadow|=color;
  1666. }
  1667. /*--------------------------------------------------------------------------*/
  1668. /* change the menu bar's x location.                                        */
  1669. /* Call this function before bar_menu(INIT)                                 */
  1670. /*--------------------------------------------------------------------------*/
  1671. void ch_menu_x(int x)
  1672. {
  1673.   menu_x=x;
  1674. }
  1675. /*--------------------------------------------------------------------------*/
  1676. /* change the menu bar's y location.                                        */
  1677. /* Call this function before bar_menu(INIT)                                 */
  1678. /*--------------------------------------------------------------------------*/
  1679. void ch_menu_y(int y)
  1680. {
  1681.   menu_y=y;
  1682. }
  1683. /*--------------------------------------------------------------------------*/
  1684. /* change the menu bar's x size.   .                                        */
  1685. /* Call this function before bar_menu(INIT)                                 */
  1686. /*--------------------------------------------------------------------------*/
  1687. void ch_menu_xsize(int xsize)
  1688. {
  1689.   menu_x_size=xsize;
  1690. }
  1691. /*--------------------------------------------------------------------------*/
  1692. /* set the menu file descriptor name                                        */
  1693. /* Call this function before bar_menu(INIT)                                 */
  1694. /*--------------------------------------------------------------------------*/
  1695. void ch_menu_filename(char *f)
  1696. {
  1697.   strcpy(menu_file,f);
  1698. }
  1699. /*--------------------------------------------------------------------------*/
  1700. /* return the next line from the menu descriptor                            */
  1701. /*--------------------------------------------------------------------------*/
  1702. int next_line(char *buffer,int buf_size)
  1703. {
  1704.   switch(menu_descriptor)
  1705.   { case TEXT_FILE :
  1706.      if(fgets(buffer,buf_size,fp)!=NULL)
  1707.      { strcpy(buffer,buffer+remove_spaces(buffer));
  1708.        return(0);
  1709.      }
  1710.      return(-1);
  1711.     case VARIABLE  :
  1712.      if(menu_line_ptr==menu_lines)
  1713.      { return(-1);
  1714.      }
  1715.      strcpy(buffer,*menu);
  1716.      menu++;
  1717.      menu_line_ptr++;
  1718.      break;
  1719.   }
  1720.   return(0);
  1721. }
  1722. /*--------------------------------------------------------------------------*/
  1723. /* set the position in the menu descriptor                                  */
  1724. /*--------------------------------------------------------------------------*/
  1725. void set_pos(long *l )
  1726. {
  1727.   switch(menu_descriptor)
  1728.   { case TEXT_FILE :
  1729.      fsetpos(fp,l);
  1730.      break;
  1731.     case VARIABLE :
  1732.      menu+=(int)(*l-(long)menu_line_ptr);
  1733.      menu_line_ptr=(int)*l;
  1734.      break;
  1735.   }
  1736. }
  1737. /*--------------------------------------------------------------------------*/
  1738. /* return the position in the menu descriptor                               */
  1739. /*--------------------------------------------------------------------------*/
  1740. long get_pos( void)
  1741. {
  1742.   switch(menu_descriptor)
  1743.   { case TEXT_FILE :
  1744.      return(ftell(fp));
  1745.     case VARIABLE :
  1746.      return((long)menu_line_ptr);
  1747.   }
  1748.   return(-1);
  1749. }
  1750. /*--------------------------------------------------------------------------*/
  1751. /* set the menu descriptor to TEXT_FILE, or VARIABLE                        */
  1752. /* when setting to VARIABLE, mv will be pointer to the menu descriptor,     */
  1753. /* and l is the number of lines in the descriptor                           */
  1754. /* when setting to TEXT_FILE, set mv to NULL, and l to 0                    */
  1755. /*--------------------------------------------------------------------------*/
  1756. void set_menu_descriptor(int md, char **mv,int l)
  1757. {
  1758.   if(md==TEXT_FILE)   /* default is set for text file */
  1759.   { menu_descriptor=TEXT_FILE;
  1760.     return;
  1761.   }
  1762.   menu_descriptor=VARIABLE;
  1763.   menu=mv;
  1764.   menu_lines=l;
  1765.   menu_line_ptr=0;
  1766. }
  1767. /*--------------------------------------------------------------------------*/
  1768. /* change the character used by frect to filled rectangle.  This character  */
  1769. /* by default is 32.                                                        */
  1770. /*--------------------------------------------------------------------------*/
  1771. void frect_char(unsigned char c)
  1772. {
  1773.   back_block=c;
  1774. }
  1775. /*--------------------------------------------------------------------------*/
  1776. /*--------------------------------------------------------------------------*/
  1777. /* display a field with the structure of field : all parameters must be     */
  1778. /* passed, the field routine will return with return keys of ESC            */
  1779. /*                                                           UPKEY          */
  1780. /*                                                           DOWNKEY        */
  1781. /*                                                           ENTER          */
  1782. /*                                                           TAB            */
  1783. /*                                                           SHIFTTAB       */
  1784. /*    struct field                                                          */
  1785. /*      { int  x;                   field's X coordinate                    */
  1786. /*        int  y;                   field's Y coordinate                    */ 
  1787. /*        int  length;              field length                            */
  1788. /*        char title[20];           title of the field                      */
  1789. /*        char f[80];               field content                           */
  1790. /*        int  fcolor;              field color                             */
  1791. /*        int  tcolor;              title color                             */
  1792. /*        int  xstart;              default x location for the cursor       */
  1793. /*                                  as character #,  first char=0           */
  1794. /*      };                                                                  */
  1795. /*                                                                          */
  1796. /*                                                                          */
  1797. /*    When returned, the variable f[80] and xstart are updated with the     */
  1798. /*    new content of the field, and xstart is set to the location of the    */
  1799. /*    cursor with respect to the first character.                           */
  1800. /*                                                                          */
  1801. /*    When the function is called, the addres of the structure must be      */
  1802. /*    passed.                                                               */
  1803. /*--------------------------------------------------------------------------*/
  1804. int  displayfield(field,action)
  1805. struct field *field;
  1806. int    action;
  1807. {
  1808.   int i;
  1809.   int ch;
  1810.   int xcurs;
  1811.  
  1812.   txt_curs(ON);
  1813.   hide_mouse_cursor();
  1814.   for (i=0;i<field->length;i++) 
  1815.                          writechar(field->x+i,field->y,' ',field->fcolor);
  1816.   pls (field->x,field->y,(unsigned char *)field->f,field->fcolor);
  1817.   pls (field->x,field->y-1,(unsigned char *)field->title,field->tcolor);
  1818.   if(action==INIT)return EOF;
  1819.  
  1820.   show_mouse_cursor();
  1821.   xcurs=field->x+field->xstart;
  1822.   txt_curs_x=xcurs;
  1823.   txt_curs_y=field->y;
  1824.   txt_curs(POSITION);
  1825.  
  1826.   while(1)
  1827.   { ch=getkey();
  1828.  
  1829.     if(mouse_state()==PRESSED)
  1830.     { get_mouse_location();
  1831.       if(mousey==field->y && mousex>=field->x && mousex<=field->x+field->length)
  1832.       { xcurs=mousex;
  1833.  
  1834.         txt_curs_x=xcurs;
  1835.         txt_curs_y=field->y;
  1836.         txt_curs(POSITION);
  1837.       }
  1838.       else
  1839.       { field->xstart=xcurs-field->x;
  1840.         strncpy(field->f,"",sizeof((unsigned char *)field->f) );  /* set all to \0 */
  1841.         txt_curs(OFF);
  1842.         for(i=0;i<field->length;i++)
  1843.         { field->f[i]=readchar(i+field->x,field->y);
  1844.         }
  1845.         return(EOF);
  1846.       }
  1847.     }
  1848.  
  1849.     if( (ch>=',' && ch<='~') || ch==' ') /* a valid character was pressed */
  1850.     { 
  1851.       /*-------------------------------------------------*/
  1852.       /* check the last character in the field; if it is */
  1853.       /* a space, shift all characters in between, else  */
  1854.       /* write over what is there                        */
  1855.       /*-------------------------------------------------*/
  1856.       i=readchar(field->x+field->length-1,field->y);
  1857.       if(i==' ')       /* shift characters to the right */
  1858.       { txt_curs(OFF);
  1859.         for(i=field->x+field->length-1;i!=xcurs; i--)
  1860.         { writechar(i,field->y,readchar(i-1,field->y),field->fcolor);
  1861.         }
  1862.         txt_curs(ON);
  1863.       }
  1864.       writechar(xcurs,field->y,ch,field->fcolor);
  1865.       if(xcurs!=field->x+field->length-1)xcurs++;
  1866.       txt_curs_x=xcurs;
  1867.       txt_curs_y=field->y;
  1868.       txt_curs(POSITION);
  1869.       continue;
  1870.     }
  1871.  
  1872.     switch(ch)
  1873.     { 
  1874.       case RIGHTKEY :
  1875.        if(xcurs!=field->x+field->length-1)xcurs++;
  1876.        else
  1877.        { field->xstart=xcurs-field->x;
  1878.          strncpy(field->f,"",sizeof((unsigned char *)field->f) );  /* set all to \0 */
  1879.          for(i=0;i<field->length;i++)
  1880.          { field->f[i]=readchar(field->x,field->y);
  1881.          }
  1882.          txt_curs(OFF);
  1883.          return(ch);
  1884.        }
  1885.        break;
  1886.       case LEFTKEY  :
  1887.        if(xcurs!=field->x)xcurs--;
  1888.        else
  1889.        { field->xstart=xcurs-field->x;
  1890.          strncpy(field->f,"",sizeof((unsigned char *)field->f) );  /* set all to \0 */
  1891.          for(i=0;i<field->length;i++)
  1892.          { field->f[i]=readchar(i+field->x,field->y);
  1893.          }
  1894.          txt_curs(OFF);
  1895.          return(ch);
  1896.        }
  1897.        break;
  1898.       case ESC      :
  1899.       case UPKEY    :
  1900.       case DOWNKEY  :
  1901.       case ENTER    :
  1902.       case TAB      :
  1903.       case SHIFTTAB :
  1904.        /*-------------------------------*/
  1905.        /* assign the current variables  */
  1906.        /*-------------------------------*/
  1907.        field->xstart=xcurs-field->x;
  1908.        strncpy(field->f,"",sizeof((unsigned char *)field->f) );  /* set all to \0 */
  1909.        for(i=0;i<field->length;i++)
  1910.        { field->f[i]=readchar(i+field->x,field->y);
  1911.        }
  1912.        txt_curs(OFF);
  1913.        return(ch);
  1914.       case DELKEY   :
  1915.        if(xcurs==field->x+field->length-1)
  1916.        { writechar(xcurs,field->y,' ',field->fcolor);
  1917.          break;
  1918.        }
  1919.        xcurs++;
  1920.        ch=BS;
  1921.       case BS       :
  1922.        if(xcurs==field->x)continue;
  1923.        txt_curs(OFF);
  1924.        for(i=xcurs-1;i<field->x+field->length;i++)
  1925.        { writechar(i,field->y,readchar(i+1,field->y),field->fcolor);
  1926.        }
  1927.        writechar(field->x+field->length-1,field->y,' ',field->fcolor);
  1928.        xcurs--;
  1929.        txt_curs(ON);
  1930.     }
  1931.     txt_curs_x=xcurs;
  1932.     txt_curs_y=field->y;
  1933.     txt_curs(POSITION);
  1934.   }
  1935. }
  1936. /*--------------------------------------------------------------------------*/
  1937. /* read a string in to the string variable from the screen                  */
  1938. /* string coordinate starts at x,y  and the size of the string is size      */
  1939. /*--------------------------------------------------------------------------*/
  1940. void readstring(x,y,size,string)
  1941. int  x;
  1942. int  y;
  1943. int  size;
  1944. char *string;
  1945. {
  1946.   int i;
  1947.   char c;
  1948.  
  1949.   for(i=x;i<x+size;i++)
  1950.   { c=readchar(i,y);
  1951.     string[i-x]=c;
  1952.   }               
  1953.   string[size]=0;
  1954. }
  1955. /*--------------------------------------------------------------------------*/
  1956. int set_video_mode(int v)
  1957. {
  1958.   union REGS reg;          
  1959.  
  1960.   reg.x.ax=v;
  1961.   int86(0x10,®,®);
  1962.  
  1963.   return  v;        
  1964. }
  1965. /*--------------------------------------------------------------------------*/
  1966. int get_video_mode(void)
  1967. {
  1968.   union REGS reg;          
  1969.  
  1970.   reg.h.ah=15;
  1971.  
  1972.   int86(0x10,®,®);
  1973.   return reg.h.al;
  1974.  
  1975. }
  1976. /*--------------------------------------------------------------------------*/
  1977.  
  1978.