home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-A.06 / NETKIT-A / NetKit-A-0.06 / ytalk-3.0.1 / menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-27  |  18.4 KB  |  914 lines

  1. /* menu.c */
  2.  
  3. /*               NOTICE
  4.  *
  5.  * Copyright (c) 1990,1992,1993 Britt Yenne.  All rights reserved.
  6.  * 
  7.  * This software is provided AS-IS.  The author gives no warranty,
  8.  * real or assumed, and takes no responsibility whatsoever for any 
  9.  * use or misuse of this software, or any damage created by its use
  10.  * or misuse.
  11.  * 
  12.  * This software may be freely copied and distributed provided that
  13.  * no part of this NOTICE is deleted or edited in any manner.
  14.  * 
  15.  */
  16.  
  17. /* Mail comments or questions to ytalk@austin.eds.com */
  18.  
  19. #include "header.h"
  20. #include <fcntl.h>
  21. #include "menu.h"
  22.  
  23. /* This particular file was written real early one night (morning?)
  24.  * while trying to stay awake long enough to do laundry.  I hereby take
  25.  * extra-special pains to absolve myself of any and all responsibility
  26.  * for this source.
  27.  */
  28.  
  29. static void main_menu_sel();
  30. menu_item *menu_ptr = NULL;        /* current menu in processing */
  31. static int menu_len;            /* number of items in current menu */
  32. static int menu_long;            /* longest item of current menu */
  33. static int menu_line;            /* current line number of menu */
  34. static int text_pos = -1;        /* text offset if non-negative */
  35. static int text_ypos = -1, text_xpos = -1; /* text coord if non-negative */
  36.  
  37. extern void raw_term();            /* our raw interface to the terminal */
  38.  
  39. /* some menus... */
  40.  
  41. static menu_item main_menu[] = {
  42.     { "Main Menu",        NULL,        ' ' },
  43.     { "",            NULL,        ' ' },
  44.     { "add a user",        main_menu_sel,    'a' },
  45.     { "delete a user",        main_menu_sel,    'd' },
  46.     { "options",        main_menu_sel,    'o' },
  47.     { "shell",            main_menu_sel,    's' },
  48.     { "user list",        main_menu_sel,    'u' },
  49.     { "output user to file",    main_menu_sel,    'w' },
  50.     { "quit",            main_menu_sel,    'q' },
  51.     { "",            NULL,        '\0'}    /* MUST BE LAST */
  52. };
  53.  
  54. #define MAXUMENU 52
  55. static menu_item user_menu[MAXUMENU];    /* this one changes each time */
  56. static menu_item option_menu[20];    /* options menu buffer */
  57. static menu_item yes_no_menu[1];    /* yes/no entry menu */
  58. static menu_item mesg_menu[1];        /* message menu */
  59.  
  60. static char text_str[MAXTEXT+1];    /* string entry buffer */
  61. static menu_item text_menu[2];        /* string entry menu */
  62. static char user_buf[MAXUMENU][80];    /* user list buffers */
  63.  
  64. /* major hack below... [maniacal laughter] */
  65.  
  66. static int got_error = 0;
  67. static char err_str[8][MAXERR];
  68. static menu_item error_menu[] = {
  69.     { "Ytalk Error",        NULL,        ' ' },
  70.     { "",            NULL,        ' ' },
  71.     { NULL,            show_error,    ' ' },
  72.     { NULL,            show_error,    ' ' },
  73.     { "",            NULL,        ' ' },
  74.     { NULL,            show_error,    ' ' },
  75.     { NULL,            show_error,    ' ' },
  76.     { "",            NULL,        ' ' },
  77.     { NULL,            show_error,    ' ' },
  78.     { NULL,            show_error,    ' ' },
  79.     { "",            NULL,        ' ' },
  80.     { NULL,            show_error,    ' ' },
  81.     { NULL,            show_error,    ' ' },
  82.     { "",            NULL,        '\0'}    /* MUST BE LAST */
  83. };
  84.  
  85. /* ---- local functions ---- */
  86.  
  87. static yuser *output_user = NULL;
  88.  
  89. static void
  90. do_output(filename)
  91.   char *filename;
  92. {
  93.     int fd;
  94.  
  95.     if(output_user == NULL)
  96.     return;
  97.     if((fd = open(filename, O_RDWR | O_TRUNC | O_CREAT, 0600)) < 0)
  98.     {
  99.     show_error(filename);
  100.     return;
  101.     }
  102.     output_user->output_fd = fd;
  103.     spew_term(output_user, fd, output_user->rows, output_user->cols);
  104.     output_user = NULL;
  105. }
  106.  
  107. static void
  108. do_output_user(user)
  109.   yuser *user;
  110. {
  111.     /* if he has an open descriptor, close it */
  112.  
  113.     if(user->output_fd > 0)
  114.     {
  115.     close(user->output_fd);
  116.     user->output_fd = 0;
  117.     if(show_mesg("Output Terminated", NULL) >= 0)
  118.         update_menu();
  119.     return;
  120.     }
  121.  
  122.     /* else open one */
  123.  
  124.     output_user = user;
  125.     if(show_text("Output filename?", do_output) >= 0)
  126.     update_menu();
  127.     else
  128.     output_user = NULL;
  129. }
  130.  
  131. static void
  132. do_invite(name)
  133.   char *name;
  134. {
  135.     invite(name, 1);
  136. }
  137.  
  138. static void
  139. main_menu_sel(key)
  140.   ychar key;
  141. {
  142.     switch(key)
  143.     {
  144.     case 'a':    /* add a user */
  145.         if(show_text("Add Which User?", do_invite) >= 0)
  146.         update_menu();
  147.         break;
  148.     case 'd':    /* delete a user */
  149.         if(show_user_menu("Delete Which User?", free_user) >= 0)
  150.         update_menu();
  151.         break;
  152.     case 'o':    /* show options */
  153.         if(show_option_menu() >= 0)
  154.         update_menu();
  155.         break;
  156.     case 's':    /* invoke a shell */
  157.         kill_menu();
  158.         execute(NULL);
  159.         break;
  160.     case 'u':    /* show a user list */
  161.         if(show_user_list() >= 0)
  162.         update_menu();
  163.         break;
  164.     case 'w':    /* output user to file */
  165.         if(show_user_menu("Output Which User?", do_output_user) >= 0)
  166.         update_menu();
  167.         break;
  168.     case 'q':    /* quit */
  169.         bail(0);
  170.     }
  171. }
  172.  
  173. static void
  174. option_menu_sel(key)
  175.   ychar key;
  176. {
  177.     register yuser *u;
  178.     ylong old_flags;
  179.  
  180.     old_flags = def_flags;
  181.     switch(key)
  182.     {
  183.     case 'a':    /* toggle asides */
  184.         def_flags ^= FL_ASIDE;
  185.         break;
  186.     case 's':    /* toggle scrolling */
  187.         def_flags ^= FL_SCROLL;
  188.         break;
  189.     case 'w':    /* toggle word wrap */
  190.         def_flags ^= FL_WRAP;
  191.         break;
  192.     case 'i':    /* toggle automatic imports */
  193.         def_flags ^= FL_IMPORT;
  194.         break;
  195.     case 'v':    /* toggle automatic invitations */
  196.         def_flags ^= FL_INVITE;
  197.         break;
  198.     case 'r':    /* toggle automatic re-rings */
  199.         def_flags ^= FL_RING;
  200.         break;
  201.     }
  202.  
  203.     if(old_flags != def_flags)
  204.     {
  205.     for(u = user_list; u != NULL; u = u->unext)
  206.         if(!(u->flags & FL_LOCKED))
  207.         u->flags = def_flags;
  208.     }
  209.  
  210.     if(show_option_menu() >= 0)
  211.     update_menu();
  212.     else
  213.     kill_menu();
  214. }
  215.  
  216. static void
  217. user_menu_sel(key)
  218.   ychar key;
  219. {
  220.     register int i;
  221.     register yuser *u;
  222.  
  223.     /* Remember... the user list could have changed between the time
  224.      * I created the user menu and the time I just now selected one
  225.      * of the users from it.
  226.      */
  227.     for(i = 0; i < menu_len; i++)
  228.     if(user_menu[i].key == key)
  229.     {
  230.         for(u = user_list; u; u = u->unext)
  231.         if(u->key == key
  232.         && strcmp(u->full_name, user_menu[i].item) == 0)
  233.         {
  234.             user_menu[0].func(u);
  235.             break;
  236.         }
  237.         break;
  238.     }
  239.     if(menu_ptr == user_menu)
  240.     kill_menu();
  241. }
  242.  
  243. #define MENU_EXTRA 7    /* number of extra characters per menu screen item */
  244.  
  245. static void
  246. generate_text_length()
  247. {
  248.     menu_long = me->t_cols - MENU_EXTRA - 2;
  249.     if(menu_long < 5 || menu_long > MAXTEXT)
  250.     menu_long = MAXTEXT;
  251. }
  252.  
  253. static void
  254. generate_yes_no_length()
  255. {
  256.     menu_long = strlen(yes_no_menu[0].item) - 2;
  257. }
  258.  
  259. static void
  260. pad_str(from, len, to)
  261.   char *from, *to;
  262.   int len;
  263. {
  264.     for(; len > 0 && *from; len--, from++)
  265.     *(to++) = *from;
  266.     for(; len > 0; len--)
  267.     *(to++) = ' ';
  268.     *to = '\0';
  269. }
  270.  
  271. /* ---- global functions ---- */
  272.  
  273. /* End any menu processing.
  274.  */
  275. void
  276. kill_menu()
  277. {
  278.     register int i;
  279.  
  280.     if(menu_ptr != NULL)
  281.     {
  282.     menu_ptr = NULL;
  283.     redraw_term(me, 0);
  284.     flush_term(me);
  285.     text_pos = -1;
  286.     text_ypos = -1;
  287.     text_xpos = -1;
  288.     }
  289.     if(got_error)
  290.     {
  291.     got_error = 0;
  292.     for(i = 0; error_menu[i].key != '\0'; i++)
  293.         if(error_menu[i].func != NULL)
  294.         error_menu[i].item = NULL;
  295.     }
  296. }
  297.  
  298. /* Update menu information.
  299.  */
  300. void
  301. update_menu()
  302. {
  303.     register ychar *c;
  304.     register char *d;
  305.     register int j, i, y, x;
  306.     static ychar *buf = NULL;
  307.     static int buflen = 0;
  308.  
  309.     if(menu_ptr == NULL)
  310.     return;
  311.     
  312.     /* process any input */
  313.  
  314.     if(io_len > 0)
  315.     {
  316.     ychar ic;
  317.  
  318.     if(menu_ptr == text_menu)
  319.     {
  320.         for(; io_len > 0; io_len--)
  321.         {
  322.         ic = *(io_ptr++);
  323.  
  324.         if(ic > ' ' && ic <= '~')
  325.         {
  326.             if(text_pos >= menu_long)
  327.             putc(7, stderr);
  328.             else
  329.             {
  330.             text_str[text_pos] = (char)ic;
  331.             if(text_ypos >= 0)
  332.                 raw_term(me, text_ypos, text_xpos + text_pos,
  333.                 text_str + text_pos, 1);
  334.             text_str[++text_pos] = '\0';
  335.             }
  336.         }
  337.         else if(ic == me->old_rub)
  338.         {
  339.             if(text_pos > 0)
  340.             {
  341.             text_str[--text_pos] = '\0';
  342.             if(text_ypos >= 0)
  343.                 raw_term(me, text_ypos, text_xpos + text_pos,
  344.                 " ", 1);
  345.             }
  346.         }
  347.         else if(ic == me->KILL || ic == me->WORD)
  348.         {
  349.             if(text_pos > 0)
  350.             {
  351.             text_str[0] = '\0';
  352.             text_pos = 0;
  353.             if(text_ypos > 0)
  354.                 raw_term(me, text_ypos, text_xpos,
  355.                 "     ", menu_long);
  356.             }
  357.         }
  358.         else if(ic == '\n' || ic == '\r')
  359.         {
  360.             if(text_pos > 0)
  361.             {
  362.             text_str[text_pos] = '\0';    /* just to be sure */
  363.             kill_menu();
  364.             text_menu[0].func(text_str);
  365.             }
  366.             else
  367.             kill_menu();
  368.             return;
  369.         }
  370.         else if(ic == 27 || ic == 4)
  371.         {
  372.             kill_menu();
  373.             return;
  374.         }
  375.         }
  376.         if(text_ypos >= 0)
  377.         {
  378.         raw_term(me, text_ypos, text_xpos + text_pos, NULL, 0);
  379.         flush_term(me);
  380.         return;
  381.         }
  382.     }
  383.     else if(menu_ptr == yes_no_menu)
  384.     {
  385.         /* don't handle yes/no input here */
  386.     }
  387.     else if(menu_ptr == mesg_menu)
  388.     {
  389.         ic = *(io_ptr++);
  390.         io_len--;
  391.         kill_menu();
  392.         if(mesg_menu[0].func)
  393.         mesg_menu[0].func(ic);
  394.         return;
  395.     }
  396.     else
  397.     {
  398.         ic = *(io_ptr++);
  399.         io_len--;
  400.         if(ic == ' ' || ic == '\n' || ic == '\r')
  401.         {
  402.         /* scroll the menu */
  403.  
  404.         menu_line += me->t_rows - 1;
  405.         if(menu_line >= menu_len)
  406.         {
  407.             kill_menu();
  408.             return;
  409.         }
  410.         i = menu_len - (me->t_rows - 1);    /* last full screen */
  411.         if(i < menu_line)
  412.             menu_line = i;
  413.         }
  414.         else if(ic > ' ' && ic <= '~')
  415.         {
  416.         for(i = 0; i < menu_len; i++)
  417.             if(menu_ptr[i].key == ic && menu_ptr[i].func != NULL)
  418.             {
  419.             menu_ptr[i].func(ic);
  420.             /*
  421.              * THE WHOLE WORLD COULD BE DIFFERENT NOW.
  422.              */
  423.             i = -1;
  424.             break;
  425.             }
  426.         if(i >= 0)
  427.             kill_menu();
  428.         return;
  429.         }
  430.         else
  431.         {
  432.         kill_menu();
  433.         return;
  434.         }
  435.     }
  436.     }
  437.  
  438.     /* Check the buffer.  Keep in mind that we could be here because
  439.      * the window size has changed.
  440.      */
  441.  
  442.     if(menu_ptr == text_menu)
  443.     {
  444.     generate_text_length();
  445.     text_ypos = -1;        /* assume it's not displayed */
  446.     text_xpos = -1;
  447.     }
  448.     else if(menu_ptr == yes_no_menu)
  449.     {
  450.     menu_len = 1;
  451.     menu_line = 0;
  452.     generate_yes_no_length();
  453.     }
  454.     if(menu_long > buflen)
  455.     {
  456.     buflen = menu_long + 64;
  457.     buf = (ychar *)realloc_mem(buf, buflen + MENU_EXTRA);
  458.     }
  459.  
  460.     /* get starting X and Y coord */
  461.  
  462.     x = center(me->t_cols, menu_long + MENU_EXTRA);
  463.     if(menu_line == 0)
  464.     {
  465.     if(menu_len + 2 <= me->t_rows)
  466.     {
  467.         y = center(me->t_rows, menu_len + 2);
  468.         raw_term(me, y++, x, "#####", menu_long + MENU_EXTRA);
  469.     }
  470.     else
  471.         y = 0;
  472.     }
  473.     else
  474.     y = 0;
  475.  
  476.     /* show as many menu lines as we can */
  477.  
  478.     for(i = menu_line; y+1 < me->t_rows && i < menu_len; i++, y++)
  479.     {
  480.     c = buf;
  481.     *(c++) = '#';
  482.     *(c++) = ' ';
  483.     if(menu_ptr[i].key == ' ')
  484.     {
  485.         j = 0;
  486.         if(menu_ptr == text_menu)
  487.         {
  488.         if(i > 0)
  489.         {
  490.             *(c++) = '>';
  491.             *(c++) = ' ';
  492.             j += 2;
  493.             text_ypos = y;
  494.             text_xpos = x + j + 2;
  495.         }
  496.         }
  497.         else if(menu_ptr != yes_no_menu)
  498.         {
  499.         int temp;
  500.         temp = center(menu_long + 3, strlen(menu_ptr[i].item));
  501.         for(; j < temp; j++)
  502.             *(c++) = ' ';
  503.         }
  504.         for(d = menu_ptr[i].item; *d; d++, j++)
  505.         *(c++) = (ychar)*d;
  506.         for(; j < menu_long + 3; j++)
  507.         *(c++) = ' ';
  508.     }
  509.     else
  510.     {
  511.         *(c++) = menu_ptr[i].key;
  512.         *(c++) = ':';
  513.         *(c++) = ' ';
  514.         for(d = menu_ptr[i].item, j = 0; *d; d++, j++)
  515.         *(c++) = (ychar)*d;
  516.         for(; j < menu_long; j++)
  517.         *(c++) = ' ';
  518.     }
  519.     *(c++) = ' ';
  520.     *(c++) = '#';
  521.     raw_term(me, y, x, buf, c - buf);
  522.     }
  523.     if(y < me->t_rows)
  524.     {
  525.     if(i < menu_len)
  526.     {
  527.         c = buf;
  528.         *(c++) = '#';
  529.         *(c++) = ' ';
  530.         *(c++) = ' ';
  531.         *(c++) = ' ';
  532.         *(c++) = ' ';
  533.         for(d = "(more)", j = 0; *d; d++, j++)
  534.         *(c++) = (ychar)*d;
  535.         for(; j < menu_long; j++)
  536.         *(c++) = ' ';
  537.         *(c++) = ' ';
  538.         *(c++) = '#';
  539.         raw_term(me, y, x, buf, c - buf);
  540.         raw_term(me, y, x + 12, NULL, 0);
  541.     }
  542.     else
  543.     {
  544.         raw_term(me, y, x, "#####", menu_long + MENU_EXTRA);
  545.         if(menu_ptr == text_menu)
  546.         raw_term(me, text_ypos, text_xpos + text_pos, NULL, 0);
  547.         else if(menu_ptr == yes_no_menu)
  548.         raw_term(me, y-1, x + menu_long + MENU_EXTRA - 2, NULL, 0);
  549.         else
  550.         raw_term(me, y, me->t_cols / 2, NULL, 0);
  551.     }
  552.     }
  553.     flush_term(me);
  554. }
  555.  
  556. /* Show a menu, overriding any existing menu.
  557.  */
  558. int
  559. show_menu(menu, len)
  560.   menu_item *menu;
  561.   int len;
  562. {
  563.     register int i, j;
  564.  
  565.     if(me->t_rows < 2)
  566.     {
  567.     show_error("show_menu: window too small");
  568.     return -1;
  569.     }
  570.  
  571.     /* scan the menu for problems */
  572.  
  573.     menu_long = 0;
  574.     for(i = 0; i < len; i++)
  575.     {
  576.     if((j = strlen(menu[i].item)) > menu_long)
  577.         menu_long = j;
  578.     if(menu[i].key < ' ' || menu[i].key >= '~')
  579.     {
  580.         show_error("show_menu: invalid key");
  581.         return -1;
  582.     }
  583.     }
  584.     if(menu_long <= 0)
  585.     {
  586.     show_error("show_menu: menu too small");
  587.     return -1;
  588.     }
  589.     if(menu_long < 10)
  590.     menu_long = 10;
  591.     
  592.     /* set up the menu for display */
  593.  
  594.     menu_ptr = menu;
  595.     menu_len = len;
  596.     menu_line = 0;
  597.     
  598.     return 0;
  599. }
  600.  
  601. /* Show a text entry menu, overriding any existing menu.
  602.  */
  603. int
  604. show_text(prompt, func)
  605.   char *prompt;
  606.   void (*func)();
  607. {
  608.     if(me->t_rows < 3)
  609.     {
  610.     show_error("show_text: window too small");
  611.     return -1;
  612.     }
  613.  
  614.     /* set up the menu for display */
  615.  
  616.     text_menu[0].item = prompt;
  617.     text_menu[0].func = func;
  618.     text_menu[0].key = ' ';
  619.  
  620.     text_str[0] = '\0';
  621.     text_menu[1].item = text_str;
  622.     text_menu[1].func = NULL;
  623.     text_menu[1].key = ' ';
  624.  
  625.     menu_ptr = text_menu;
  626.     menu_len = 2;
  627.     menu_line = 0;
  628.     text_ypos = -1;
  629.     text_xpos = -1;
  630.     text_pos = 0;
  631.     generate_text_length();
  632.     
  633.     return 0;
  634. }
  635.  
  636. /* Show a message in a menu.
  637.  */
  638. int
  639. show_mesg(mesg, func)
  640.   char *mesg;
  641.   void (*func)();
  642. {
  643.     /* set up the menu for display */
  644.  
  645.     mesg_menu[0].item = mesg;
  646.     mesg_menu[0].func = func;
  647.     mesg_menu[0].key = ' ';
  648.  
  649.     return show_menu(mesg_menu, 1);
  650. }
  651.  
  652. int
  653. show_main_menu()
  654. {
  655.     static int main_items = 0;
  656.  
  657.     if(main_items == 0)
  658.     {
  659.     while(main_menu[main_items].key != '\0')
  660.         main_items++;
  661.     }
  662.     return show_menu(main_menu, main_items);
  663. }
  664.  
  665. int
  666. show_option_menu()
  667. {
  668.     register int i = 0;
  669.  
  670.     option_menu[i].item = "Options Menu";
  671.     option_menu[i].func = NULL;
  672.     option_menu[i].key = ' ';
  673.     i++;
  674.  
  675.     option_menu[i].item = "";
  676.     option_menu[i].func = NULL;
  677.     option_menu[i].key = ' ';
  678.     i++;
  679.  
  680.     if(def_flags & FL_SCROLL)
  681.     option_menu[i].item = "turn scrolling off";
  682.     else
  683.     option_menu[i].item = "turn scrolling on";
  684.     option_menu[i].func = option_menu_sel;
  685.     option_menu[i].key = 's';
  686.     i++;
  687.  
  688.     if(def_flags & FL_WRAP)
  689.     option_menu[i].item = "turn word-wrap off";
  690.     else
  691.     option_menu[i].item = "turn word-wrap on";
  692.     option_menu[i].func = option_menu_sel;
  693.     option_menu[i].key = 'w';
  694.     i++;
  695.  
  696.     if(def_flags & FL_IMPORT)
  697.     option_menu[i].item = "turn auto-import off";
  698.     else
  699.     option_menu[i].item = "turn auto-import on";
  700.     option_menu[i].func = option_menu_sel;
  701.     option_menu[i].key = 'i';
  702.     i++;
  703.  
  704.     if(def_flags & FL_INVITE)
  705.     option_menu[i].item = "turn auto-invite off";
  706.     else
  707.     option_menu[i].item = "turn auto-invite on";
  708.     option_menu[i].func = option_menu_sel;
  709.     option_menu[i].key = 'v';
  710.     i++;
  711.  
  712.     if(def_flags & FL_RING)
  713.     option_menu[i].item = "turn auto-rering off";
  714.     else
  715.     option_menu[i].item = "turn auto-rering on";
  716.     option_menu[i].func = option_menu_sel;
  717.     option_menu[i].key = 'r';
  718.     i++;
  719.  
  720.     if(term_does_asides())
  721.     {
  722.     if(def_flags & FL_ASIDE)
  723.         option_menu[i].item = "turn asides off";
  724.     else
  725.         option_menu[i].item = "turn asides on";
  726.     option_menu[i].func = option_menu_sel;
  727.     option_menu[i].key = 'a';
  728.     i++;
  729.     }
  730.  
  731.     return show_menu(option_menu, i);
  732. }
  733.  
  734. int
  735. show_user_menu(title, func)
  736.   char *title;
  737.   void (*func)();
  738. {
  739.     register int i;
  740.     register yuser *u;
  741.  
  742.     user_menu[0].item = title;
  743.     user_menu[0].func = func;
  744.     user_menu[0].key = ' ';
  745.  
  746.     user_menu[1].item = "";
  747.     user_menu[1].func = NULL;
  748.     user_menu[1].key = ' ';
  749.  
  750.     for(i = 2, u = user_list; u != NULL && i < MAXUMENU; u = u->unext)
  751.     if(u != me)
  752.     {
  753.         if(u->key != '\0')
  754.         {
  755.         strcpy(user_buf[i], u->full_name);
  756.         user_menu[i].item = user_buf[i];
  757.         user_menu[i].func = user_menu_sel;
  758.         user_menu[i].key = u->key;
  759.         i++;
  760.         }
  761.     }
  762.     
  763.     if(i > 2)
  764.     return show_menu(user_menu, i);
  765.     kill_menu();
  766.     return -1;
  767. }
  768.  
  769. int
  770. show_user_list()
  771. {
  772.     register int i;
  773.     register yuser *u;
  774.     static char name_buf[25], stat_buf[25];
  775.  
  776.     i = 0;
  777.  
  778.     user_menu[i].item = "User List";
  779.     user_menu[i].func = NULL;
  780.     user_menu[i].key = ' ';
  781.     i++;
  782.  
  783.     user_menu[i].item = "Name            Winsize [My_Size] Software       ";
  784.     user_menu[i].func = NULL;
  785.     user_menu[i].key = ' ';
  786.     i++;
  787.  
  788.     user_menu[i].item = "";
  789.     user_menu[i].func = NULL;
  790.     user_menu[i].key = ' ';
  791.     i++;
  792.  
  793.     for(u = connect_list; u && i < MAXUMENU; u = u->next)
  794.     if(u != me)
  795.     {
  796.         if(u->remote.vmajor > 2)
  797.         sprintf(stat_buf, "YTalk V%d.%d",
  798.             u->remote.vmajor, u->remote.vminor);
  799.         else if(u->remote.vmajor == 2)
  800.         sprintf(stat_buf, "YTalk V2.?");
  801.         else
  802.         sprintf(stat_buf, "UNIX Talk");
  803.         pad_str(u->full_name, 15, name_buf);
  804.         pad_str(stat_buf, 15, stat_buf);
  805.         sprintf(user_buf[i], "%s %3.3dx%3.3d [%3.3dx%3.3d] %s",
  806.         name_buf,
  807.         u->remote.cols, u->remote.rows,
  808.         u->remote.my_cols, u->remote.my_rows,
  809.         stat_buf);
  810.  
  811.         user_menu[i].item = user_buf[i];
  812.         user_menu[i].func = NULL;
  813.         user_menu[i].key = ' ';
  814.         i++;
  815.     }
  816.  
  817.     for(u = wait_list; u && i < MAXUMENU; u = u->next)
  818.     {
  819.     pad_str(u->full_name, 15, name_buf);
  820.     pad_str("<unconnected>", 15, stat_buf);
  821.     sprintf(user_buf[i], "%s                   %s",
  822.         name_buf,
  823.         stat_buf);
  824.  
  825.     user_menu[i].item = user_buf[i];
  826.     user_menu[i].func = NULL;
  827.     user_menu[i].key = ' ';
  828.     i++;
  829.     }
  830.     
  831.     return show_menu(user_menu, i);
  832. }
  833.  
  834. int
  835. show_error_menu(str1, str2)
  836.   char *str1, *str2;
  837. {
  838.     register int i;
  839.  
  840.     for(i = 0; error_menu[i].key != '\0'; i++)
  841.     if(error_menu[i].item == NULL)
  842.     {
  843.         strncpy(err_str[got_error], str1, MAXERR);
  844.         err_str[got_error][MAXERR-1] = '\0';
  845.         error_menu[i++].item = err_str[got_error++];
  846.  
  847.         strncpy(err_str[got_error], str2, MAXERR);
  848.         err_str[got_error][MAXERR-1] = '\0';
  849.         error_menu[i++].item = err_str[got_error++];
  850.  
  851.         return show_menu(error_menu, i);
  852.     }
  853.     return 0;
  854. }
  855.  
  856. /* Prompt user for yes/no response.  Return the response.  It is
  857.  * necessary for this function to hang until an answer is received.
  858.  */
  859. int
  860. yes_no(prompt)
  861.   char *prompt;
  862. {
  863.     int out = 0;
  864.  
  865.     yes_no_menu[0].func = NULL;
  866.     yes_no_menu[0].key = ' ';
  867.  
  868.     /* show the menu and call input_loop() */
  869.  
  870.     do {
  871.     yes_no_menu[0].item = prompt;
  872.     menu_ptr = yes_no_menu;
  873.     update_menu();
  874.     input_loop();
  875.     if(menu_ptr != yes_no_menu || yes_no_menu[0].item != prompt)
  876.     {
  877.         /* somebody pre-empted us */
  878.         kill_menu();
  879.         io_len = 0;
  880.     }
  881.     for(; io_len > 0; io_len--, io_ptr++)
  882.     {
  883.         if(*io_ptr == 'y' || *io_ptr == 'Y')
  884.         {
  885.         out = 'y';
  886.         break;
  887.         }
  888.         if(*io_ptr == 'n' || *io_ptr == 'N' || *io_ptr == 27)
  889.         {
  890.         out = 'n';
  891.         break;
  892.         }
  893.     }
  894.     } while(out == 0);
  895.  
  896.     kill_menu();
  897.     io_len = 0;
  898.     return out;
  899. }
  900.  
  901. void
  902. update_user_menu()
  903. {
  904.     if(menu_ptr == user_menu)
  905.     {
  906.     redraw_term(me, 0);
  907.     if(user_menu[0].func)    /* it's a user menu */
  908.         (void)show_user_menu(user_menu[0].item, user_menu[0].func);
  909.     else    /* it's a user status list */
  910.         (void)show_user_list();
  911.     update_menu();
  912.     }
  913. }
  914.