home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / lynx2.8.1dev.10.tar.gz / lynx2.8.1dev.10.tar / lynx2-8 / src / LYOptions.c < prev    next >
C/C++ Source or Header  |  1998-05-10  |  79KB  |  3,106 lines

  1. #include <HTUtils.h>
  2. #include <tcp.h>
  3. #include <HTFTP.h>
  4. #include <HTML.h>
  5. #include <LYCurses.h>
  6. #include <LYUtils.h>
  7. #include <LYStrings.h>
  8. #include <LYGlobalDefs.h>
  9. #include <LYOptions.h>
  10. #include <LYSignal.h>
  11. #include <LYClean.h>
  12. #include <LYCharSets.h>
  13. #include <LYCharUtils.h>
  14. #include <UCMap.h>
  15. #include <UCAux.h>
  16. #include <LYKeymap.h>
  17. #include <LYrcFile.h>
  18. #include <HTAlert.h>
  19. #include <LYBookmark.h>
  20. #include <GridText.h>
  21.  
  22. #include <LYLeaks.h>
  23.  
  24. #define FREE(x) if (x) {free(x); x = NULL;}
  25.  
  26. #ifdef VMS
  27. #define DISPLAY "DECW$DISPLAY"
  28. #else
  29. #define DISPLAY "DISPLAY"
  30. #endif /* VMS */
  31.  
  32. #define COL_OPTION_VALUES 36  /* display column where option values start */
  33.  
  34. BOOLEAN term_options;
  35. PRIVATE void terminate_options    PARAMS((int sig));
  36. PRIVATE int boolean_choice PARAMS((
  37.     int        status,
  38.     int        line,
  39.     int        column,
  40.     char **     choices));
  41. PRIVATE int popup_choice PARAMS((
  42.     int        cur_choice,
  43.     int        line,
  44.     int        column,
  45.     char **     choices,
  46.     int        i_length,
  47.     int        disabled));
  48.  
  49. #define MAXCHOICES 10
  50.  
  51. #define L_Bool_A (use_assume_charset ? L_BOOL_A + 1 : L_BOOL_A)
  52. #define L_Bool_B (use_assume_charset ? L_BOOL_B + 1 : L_BOOL_B)
  53. #define L_Exec (use_assume_charset ? L_EXEC + 1 : L_EXEC)
  54. #define L_Rawmode (use_assume_charset ? L_RAWMODE + 1 : L_RAWMODE)
  55. #define L_Charset (use_assume_charset ? L_CHARSET + 1 : L_CHARSET)
  56. #define L_Color (use_assume_charset ? L_COLOR + 1 : L_COLOR)
  57. #define L_Keypad (use_assume_charset ? L_KEYPAD + 1 : L_KEYPAD)
  58. #define L_Lineed (use_assume_charset ? L_LINEED + 1 : L_LINEED)
  59. #define L_Dired (use_assume_charset ? L_DIRED + 1 : L_DIRED)
  60. #define L_User_Mode (use_assume_charset ? L_USER_MODE + 1 : L_USER_MODE)
  61. #define L_User_Agent (use_assume_charset ? L_USER_AGENT + 1 : L_USER_AGENT)
  62.  
  63. PRIVATE void option_statusline ARGS1(
  64.     CONST char *,        text)
  65. {
  66.     /*
  67.      *    Make sure we have a pointer to a string.
  68.      */
  69.     if (text == NULL)
  70.     return;
  71.  
  72.     /*
  73.      *    Don't print statusline messages if dumping to stdout.
  74.      */
  75.     if (dump_output_immediately)
  76.     return;
  77.  
  78.     /*
  79.      *    Use _statusline() set to output on the bottom line. - FM
  80.      */
  81.     LYStatusLine = (LYlines - 1);
  82.     _statusline(text);
  83.     LYStatusLine = -1;
  84. }
  85.  
  86. PRIVATE void option_user_message ARGS2(
  87.     CONST char *,        message,
  88.     char *,         argument)
  89. {
  90.     /*
  91.      *    Make sure we have a pointer to a string.
  92.      */
  93.     if (message == NULL || argument == NULL)
  94.     return;
  95.  
  96.     /*
  97.      *    Don't print statusline messages if dumping to stdout.
  98.      */
  99.     if (dump_output_immediately)
  100.     return;
  101.  
  102.     /*
  103.      *    Use _user_message() set to output on the bottom line.
  104.      */
  105.     LYStatusLine = (LYlines - 1);
  106.     _user_message(message, argument);
  107.     LYStatusLine = -1;
  108. }
  109.  
  110. PUBLIC void options NOARGS
  111. {
  112. #ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS
  113.     int itmp;
  114. #endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */
  115.     int response, ch;
  116.     /*
  117.      *    If the user changes the display we need memory to put it in.
  118.      */
  119.     char display_option[256];
  120. #ifndef VMS
  121.     static char putenv_command[142];
  122. #endif /* !VMS */
  123.     char *choices[MAXCHOICES];
  124.     int CurrentCharSet = current_char_set;
  125.     int CurrentAssumeCharSet = UCLYhndl_for_unspec;
  126.     int CurrentAssumeLocalCharSet = UCLYhndl_HTFile_for_unspec;
  127.     int CurrentShowColor = LYShowColor;
  128.     BOOLEAN CurrentRawMode = LYRawMode;
  129.     BOOLEAN AddValueAccepted = FALSE;
  130.     char *cp = NULL;
  131.     BOOL use_assume_charset, old_use_assume_charset;
  132.  
  133. #ifdef DIRED_SUPPORT
  134. #ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS
  135.     if (LYlines < 24) {
  136.     HTAlert(OPTION_SCREEN_NEEDS_24);
  137.     return;
  138.     }
  139. #else
  140.     if (LYlines < 23) {
  141.     HTAlert(OPTION_SCREEN_NEEDS_23);
  142.     return;
  143.     }
  144. #endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */
  145. #else
  146. #ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS
  147.     if (LYlines < 23) {
  148.     HTAlert(
  149.     "Screen height must be at least 23 lines for the Options menu!");
  150.     return;
  151.     }
  152. #else
  153.     if (LYlines < 22) {
  154.     HTAlert(OPTION_SCREEN_NEEDS_22);
  155.     return;
  156.     }
  157. #endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */
  158. #endif /* DIRED_SUPPORT */
  159.  
  160.     term_options = FALSE;
  161.     signal(SIGINT, terminate_options);
  162.     if (no_option_save) {
  163.     if (LYShowColor == SHOW_COLOR_NEVER) {
  164.         LYShowColor = SHOW_COLOR_OFF;
  165.     } else if (LYShowColor == SHOW_COLOR_ALWAYS) {
  166.         LYShowColor = SHOW_COLOR_ON;
  167.     }
  168. #if defined(USE_SLANG) || defined(COLOR_CURSES)
  169.     } else {
  170.     if (LYChosenShowColor == SHOW_COLOR_UNKNOWN) {
  171.         switch (LYrcShowColor) {
  172.         case SHOW_COLOR_NEVER:
  173.         LYChosenShowColor =
  174.             (LYShowColor >= SHOW_COLOR_ON) ?
  175.                      SHOW_COLOR_ON :
  176.                      SHOW_COLOR_NEVER;
  177.         break;
  178.         case SHOW_COLOR_ALWAYS:
  179. #if defined(COLOR_CURSES)
  180.         if (!has_colors())
  181.             LYChosenShowColor = SHOW_COLOR_ALWAYS;
  182.         else
  183. #endif
  184.             LYChosenShowColor =
  185.             (LYShowColor >= SHOW_COLOR_ON) ?
  186.                      SHOW_COLOR_ALWAYS :
  187.                      SHOW_COLOR_OFF;
  188.         break;
  189.         default:
  190.         LYChosenShowColor =
  191.             (LYShowColor >= SHOW_COLOR_ON) ?
  192.                      SHOW_COLOR_ON :
  193.                      SHOW_COLOR_OFF;
  194.         }
  195.     }
  196. #endif /* USE_SLANG || COLOR_CURSES */
  197.     }
  198.  
  199.     old_use_assume_charset =
  200.     use_assume_charset = (user_mode == ADVANCED_MODE);
  201.  
  202. draw_options:
  203.  
  204.     old_use_assume_charset = use_assume_charset;
  205.     /*
  206.      *    NOTE that printw() should be avoided for strings that
  207.      *    might have non-ASCII or multibyte/CJK characters. - FM
  208.      */
  209.     response = 0;
  210. #if defined(FANCY_CURSES) || defined (USE_SLANG)
  211.     if (enable_scrollback) {
  212.     clear();
  213.     } else {
  214.     erase();
  215.     }
  216. #else
  217.     clear();
  218. #endif /* FANCY_CURSES || USE_SLANG */
  219.     move(0, 5);
  220.  
  221.     lynx_start_h1_color ();
  222.     addstr("         Options Menu (");
  223.     addstr(LYNX_NAME);
  224.     addstr(" Version ");
  225.     addstr(LYNX_VERSION);
  226.     addch(')');
  227.     lynx_stop_h1_color ();
  228.     move(L_EDITOR, 5);
  229.     addstr("E)ditor                      : ");
  230.     addstr((editor && *editor) ? editor : "NONE");
  231.  
  232.     move(L_DISPLAY, 5);
  233.     addstr("D)ISPLAY variable            : ");
  234.     addstr((display && *display) ? display : "NONE");
  235.  
  236.     move(L_HOME, 5);
  237.     addstr("mu(L)ti-bookmarks: ");
  238.     addstr((LYMultiBookmarks ?
  239.           (LYMBMAdvanced ? "ADVANCED"
  240.                  : "STANDARD")
  241.                  : "OFF     "));
  242.     move(L_HOME, B_BOOK);
  243.     if (LYMultiBookmarks) {
  244.     addstr("review/edit B)ookmarks files");
  245.     } else {
  246.     addstr("B)ookmark file: ");
  247.     addstr((bookmark_page && *bookmark_page) ? bookmark_page : "NONE");
  248.     }
  249.  
  250.     move(L_FTPSTYPE, 5);
  251.     addstr("F)TP sort criteria           : ");
  252.     addstr((HTfileSortMethod == FILE_BY_NAME ? "By Filename" :
  253.        (HTfileSortMethod == FILE_BY_SIZE ? "By Size    " :
  254.        (HTfileSortMethod == FILE_BY_TYPE ? "By Type    " :
  255.                            "By Date    "))));
  256.  
  257.     move(L_MAIL_ADDRESS, 5);
  258.     addstr("P)ersonal mail address       : ");
  259.     addstr((personal_mail_address && *personal_mail_address) ?
  260.                        personal_mail_address : "NONE");
  261.  
  262.     move(L_SSEARCH, 5);
  263.     addstr("S)earching type              : ");
  264.     addstr(case_sensitive ? "CASE SENSITIVE  " : "CASE INSENSITIVE");
  265.  
  266.     move(L_Charset, 5);
  267.     addstr("display (C)haracter set      : ");
  268.     addstr((char *)LYchar_set_names[current_char_set]);
  269.  
  270.     move(L_LANGUAGE, 5);
  271.     addstr("preferred document lan(G)uage: ");
  272.     addstr((language && *language) ? language : "NONE");
  273.  
  274.     move(L_PREF_CHARSET, 5);
  275.     addstr("preferred document c(H)arset : ");
  276.     addstr((pref_charset && *pref_charset) ? pref_charset : "NONE");
  277.  
  278.     if (use_assume_charset) {
  279.     move(L_ASSUME_CHARSET, 5);
  280.     addstr("^A)ssume charset if unknown  : ");
  281.     if (UCAssume_MIMEcharset)
  282.         addstr(UCAssume_MIMEcharset);
  283.     else
  284.         addstr((UCLYhndl_for_unspec >= 0) ?
  285.            (char *)LYCharSet_UC[UCLYhndl_for_unspec].MIMEname
  286.                           : "NONE");
  287.     }
  288.  
  289.     move(L_Rawmode, 5);
  290.     addstr("Raw 8-bit or CJK m(O)de      : ");
  291.     addstr(LYRawMode ? "ON " : "OFF");
  292.  
  293. #if defined(USE_SLANG) || defined(COLOR_CURSES)
  294.     move(L_Color, B_COLOR);
  295.     addstr("show color (&)  : ");
  296.     if (no_option_save) {
  297.     addstr((LYShowColor == SHOW_COLOR_OFF ? "OFF" :
  298.                         "ON "));
  299.     } else {
  300.     switch (LYChosenShowColor) {
  301.     case SHOW_COLOR_NEVER:
  302.                 addstr("NEVER     ");
  303.         break;
  304.     case SHOW_COLOR_OFF:
  305.         addstr("OFF");
  306.         break;
  307.     case SHOW_COLOR_ON:
  308.         addstr("ON ");
  309.         break;
  310.     case SHOW_COLOR_ALWAYS:
  311. #if defined(COLOR_CURSES)
  312.         if (!has_colors())
  313.             addstr("Always try");
  314.         else
  315. #endif
  316.             addstr("ALWAYS    ");
  317.     }
  318.     }
  319. #endif /* USE_SLANG || COLOR_CURSES */
  320.  
  321.     move(L_Bool_A, B_VIKEYS);
  322.     addstr("V)I keys: ");
  323.     addstr(vi_keys ? "ON " : "OFF");
  324.  
  325.     move(L_Bool_A, B_EMACSKEYS);
  326.     addstr("e(M)acs keys: ");
  327.     addstr(emacs_keys ? "ON " : "OFF");
  328.  
  329.     move(L_Bool_A, B_SHOW_DOTFILES);
  330.     addstr("sho(W) dot files: ");
  331.     addstr((!no_dotfiles && show_dotfiles) ? "ON " : "OFF");
  332.  
  333.     move(L_Bool_B, B_SELECT_POPUPS);
  334.     addstr("popups for selec(T) fields   : ");
  335.     addstr(LYSelectPopups ? "ON " : "OFF");
  336.  
  337.     move(L_Bool_B, B_SHOW_CURSOR);
  338.     addstr("show cursor (@) : ");
  339.     addstr(LYShowCursor ? "ON " : "OFF");
  340.  
  341.     move(L_Keypad, 5);
  342.     addstr("K)eypad mode                 : ");
  343.     addstr((keypad_mode == NUMBERS_AS_ARROWS) ?
  344.                 "Numbers act as arrows             " :
  345.      ((keypad_mode == LINKS_ARE_NUMBERED) ?
  346.                 "Links are numbered                " :
  347.                 "Links and form fields are numbered"));
  348.  
  349.     move(L_Lineed, 5);
  350.     addstr("li(N)e edit style            : ");
  351.     addstr(LYLineeditNames[current_lineedit]);
  352.  
  353. #ifdef DIRED_SUPPORT
  354.     move(L_Dired, 5);
  355.     addstr("l(I)st directory style       : ");
  356.     addstr((dir_list_style == FILES_FIRST) ? "Files first      " :
  357.       ((dir_list_style == MIXED_STYLE) ? "Mixed style      " :
  358.                          "Directories first"));
  359. #endif /* DIRED_SUPPORT */
  360.  
  361.     move(L_User_Mode, 5);
  362.     addstr("U)ser mode                   : ");
  363.     addstr(  (user_mode == NOVICE_MODE) ? "Novice      " :
  364.       ((user_mode == INTERMEDIATE_MODE) ? "Intermediate" :
  365.                       "Advanced    "));
  366.  
  367.     move(L_User_Agent, 5);
  368.     addstr("user (A)gent                 : ");
  369.     addstr((LYUserAgent && *LYUserAgent) ? LYUserAgent : "NONE");
  370.  
  371. #ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS
  372.     move(L_Exec, 5);
  373.     addstr("local e(X)ecution links      : ");
  374. #ifndef NEVER_ALLOW_REMOTE_EXEC
  375.     addstr(               local_exec ? "ALWAYS ON           " :
  376.       (local_exec_on_local_files ? "FOR LOCAL FILES ONLY" :
  377.                        "ALWAYS OFF          "));
  378. #else
  379.     addstr(local_exec_on_local_files ? "FOR LOCAL FILES ONLY" :
  380.                        "ALWAYS OFF          ");
  381. #endif /* !NEVER_ALLOW_REMOTE_EXEC */
  382. #endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */
  383.  
  384.     move(LYlines-3, 2);
  385.     addstr(SELECT_SEGMENT);
  386.     start_bold();
  387.     addstr(CAP_LETT_SEGMENT);
  388.     stop_bold();
  389.     addstr(OF_OPT_LINE_SEGMENT);
  390.     if (!no_option_save) {
  391.     addstr(" '");
  392.     start_bold();
  393.     addstr(">");
  394.     stop_bold();
  395.     addstr("'");
  396.     addstr(TO_SAVE_SEGMENT);
  397.     }
  398.     addstr(OR_SEGMENT);
  399.     addstr("'");
  400.     start_bold();
  401.     addstr("r");
  402.     stop_bold();
  403.     addstr("'");
  404.     addstr(TO_RETURN_SEGMENT);
  405.  
  406.     while (TOUPPER(response) != 'R' &&
  407.        !LYisNonAlnumKeyname(response, LYK_PREV_DOC) &&
  408.        response != '>' && !term_options &&
  409.        response != 7 &&  response != 3) {
  410.     if (AddValueAccepted == TRUE) {
  411.         option_statusline(VALUE_ACCEPTED);
  412.         AddValueAccepted = FALSE;
  413.     }
  414.     move((LYlines - 2), 0);
  415.     lynx_start_prompt_color ();
  416.     addstr(COMMAND_PROMPT);
  417.     lynx_stop_prompt_color ();
  418.  
  419.     refresh();
  420.     response = LYgetch();
  421.     if (term_options || response == 7 || response == 3)
  422.         response = 'R';
  423.     if (LYisNonAlnumKeyname(response, LYK_REFRESH)) {
  424.         lynx_force_repaint();
  425.         goto draw_options;
  426.     }
  427.     switch (response) {
  428.         case 'e':    /* Change the editor. */
  429.         case 'E':
  430.         if (no_editor) {
  431.             option_statusline(EDIT_DISABLED);
  432.         } else if (system_editor ) {
  433.             option_statusline(EDITOR_LOCKED);
  434.         } else {
  435.             if (editor && *editor)
  436.             strcpy(display_option, editor);
  437.             else {  /* clear the NONE */
  438.             move(L_EDITOR, COL_OPTION_VALUES);
  439.             addstr("    ");
  440.             *display_option = '\0';
  441.             }
  442.             option_statusline(ACCEPT_DATA);
  443.             move(L_EDITOR, COL_OPTION_VALUES);
  444.             start_bold();
  445.             ch = LYgetstr(display_option, VISIBLE,
  446.                   sizeof(display_option), NORECALL);
  447.             stop_bold();
  448.             move(L_EDITOR, COL_OPTION_VALUES);
  449.             if (term_options || ch == -1) {
  450.             addstr((editor && *editor) ?
  451.                         editor : "NONE");
  452.             } else if (*display_option == '\0') {
  453.             FREE(editor);
  454.             addstr("NONE");
  455.             } else {
  456.             StrAllocCopy(editor, display_option);
  457.             addstr(display_option);
  458.             }
  459.             clrtoeol();
  460.             if (ch == -1) {
  461.             option_statusline(CANCELLED);
  462.             sleep(InfoSecs);
  463.             option_statusline("");
  464.             } else {
  465.             option_statusline(VALUE_ACCEPTED);
  466.             }
  467.         }
  468.         response = ' ';
  469.         break;
  470.  
  471.         case 'd':    /* Change the display. */
  472.         case 'D':
  473.         if (display && *display) {
  474.             strcpy(display_option, display);
  475.         } else {  /* clear the NONE */
  476.             move(L_DISPLAY, COL_OPTION_VALUES);
  477.             addstr("    ");
  478.             *display_option = '\0';
  479.         }
  480.         option_statusline(ACCEPT_DATA);
  481.         move(L_DISPLAY, COL_OPTION_VALUES);
  482.         start_bold();
  483.         ch = LYgetstr(display_option, VISIBLE,
  484.                   sizeof(display_option), NORECALL);
  485.         stop_bold();
  486.         move(L_DISPLAY, COL_OPTION_VALUES);
  487.         if ((term_options || ch == -1) ||
  488.             (display != NULL &&
  489. #ifdef VMS
  490.              !strcasecomp(display, display_option)))
  491. #else
  492.              !strcmp(display, display_option)))
  493. #endif /* VMS */
  494.         {
  495.             /*
  496.              *    Cancelled, or a non-NULL display string
  497.              *    wasn't changed. - FM
  498.              */
  499.             addstr((display && *display) ? display : "NONE");
  500.             clrtoeol();
  501.             if (ch == -1) {
  502.             option_statusline(CANCELLED);
  503.             sleep(InfoSecs);
  504.             option_statusline("");
  505.             } else {
  506.             option_statusline(VALUE_ACCEPTED);
  507.             }
  508.             response = ' ';
  509.             break;
  510.         } else if (*display_option == '\0') {
  511.             if ((display == NULL) ||
  512.             (display != NULL && *display == '\0')) {
  513.             /*
  514.              *  NULL or zero-length display string
  515.              *  wasn't changed. - FM
  516.              */
  517.             addstr("NONE");
  518.             clrtoeol();
  519.             option_statusline(VALUE_ACCEPTED);
  520.             response = ' ';
  521.             break;
  522.             }
  523.         }
  524.         /*
  525.          *  Set the new DISPLAY variable. - FM
  526.          */
  527. #ifdef VMS
  528.         LYUpperCase(display_option);
  529.         Define_VMSLogical(DISPLAY, display_option);
  530. #else
  531.         sprintf(putenv_command, "DISPLAY=%s", display_option);
  532.         putenv(putenv_command);
  533. #endif /* VMS */
  534.         if ((cp = getenv(DISPLAY)) != NULL && *cp != '\0') {
  535.             StrAllocCopy(display, cp);
  536.         } else {
  537.             FREE(display);
  538.         }
  539.         cp = NULL;
  540.         addstr(display ? display : "NONE");
  541.         clrtoeol();
  542.         if ((display == NULL && *display_option == '\0') ||
  543.             (display != NULL &&
  544.              !strcmp(display, display_option))) {
  545.             if (display == NULL &&
  546.             LYisConfiguredForX == TRUE) {
  547.             option_statusline(VALUE_ACCEPTED_WARNING_X);
  548.             } else if (display != NULL &&
  549.             LYisConfiguredForX == FALSE) {
  550.             option_statusline(VALUE_ACCEPTED_WARNING_NONX);
  551.             } else {
  552.             option_statusline(VALUE_ACCEPTED);
  553.             }
  554.         } else {
  555.             if (*display_option) {
  556.             option_statusline(FAILED_TO_SET_DISPLAY);
  557.             } else {
  558.             option_statusline(FAILED_CLEAR_SET_DISPLAY);
  559.             }
  560.         }
  561.         response = ' ';
  562.         break;
  563.  
  564.         case 'l':    /* Change multibookmarks option. */
  565.         case 'L':
  566.         if (LYMBMBlocked) {
  567.             option_statusline(MULTIBOOKMARKS_DISALLOWED);
  568.             response = ' ';
  569.             break;
  570.         }
  571.         choices[0] = NULL;
  572.         StrAllocCopy(choices[0], "OFF     ");
  573.         choices[1] = NULL;
  574.         StrAllocCopy(choices[1], "STANDARD");
  575.         choices[2] = NULL;
  576.         StrAllocCopy(choices[2], "ADVANCED");
  577.         choices[3] = NULL;
  578.         if (!LYSelectPopups) {
  579.             LYMultiBookmarks = boolean_choice((LYMultiBookmarks *
  580.                                (1 + LYMBMAdvanced)),
  581.                               L_HOME, C_MULTI,
  582.                               choices);
  583.         } else {
  584.             LYMultiBookmarks = popup_choice((LYMultiBookmarks *
  585.                              (1 + LYMBMAdvanced)),
  586.                             L_HOME, (C_MULTI - 1),
  587.                             choices,
  588.                             3, FALSE);
  589.         }
  590.         if (LYMultiBookmarks == 2) {
  591.             LYMultiBookmarks = TRUE;
  592.             LYMBMAdvanced = TRUE;
  593.         } else {
  594.             LYMBMAdvanced = FALSE;
  595.         }
  596. #if defined(VMS) || defined(USE_SLANG)
  597.         if (LYSelectPopups) {
  598.             move(L_HOME, C_MULTI);
  599.             clrtoeol();
  600.             addstr(choices[(LYMultiBookmarks * (1 + LYMBMAdvanced))]);
  601.         }
  602. #endif /* VMS || USE_SLANG */
  603.         FREE(choices[0]);
  604.         FREE(choices[1]);
  605.         FREE(choices[2]);
  606. #if !defined(VMS) && !defined(USE_SLANG)
  607.         if (!LYSelectPopups)
  608. #endif /* !VMS && !USE_SLANG */
  609.         {
  610.             move(L_HOME, B_BOOK);
  611.             clrtoeol();
  612.             if (LYMultiBookmarks) {
  613.             addstr("review/edit B)ookmarks files");
  614.             } else {
  615.             addstr("B)ookmark file: ");
  616.             addstr((bookmark_page && *bookmark_page) ?
  617.                            bookmark_page : "NONE");
  618.             }
  619.         }
  620.         response = ' ';
  621.         if (LYSelectPopups) {
  622. #if !defined(VMS) || defined(USE_SLANG)
  623.             if (term_options) {
  624.             term_options = FALSE;
  625.             } else {
  626.             AddValueAccepted = TRUE;
  627.             }
  628.             goto draw_options;
  629. #else
  630.             term_options = FALSE;
  631. #endif /* !VMS || USE_SLANG */
  632.         }
  633.         break;
  634.  
  635.         case 'b':    /* Change the bookmark page location. */
  636.         case 'B':
  637.         /*
  638.          *  Anonymous users should not be allowed to
  639.          *  change the bookmark page.
  640.          */
  641.         if (!no_bookmark) {
  642.             if (LYMultiBookmarks) {
  643.             edit_bookmarks();
  644.             signal(SIGINT, terminate_options);
  645.             goto draw_options;
  646.             }
  647.             if (bookmark_page && *bookmark_page) {
  648.             strcpy(display_option, bookmark_page);
  649.             } else {  /* clear the NONE */
  650.             move(L_HOME, C_DEFAULT);
  651.             clrtoeol();
  652.             *display_option = '\0';
  653.             }
  654.             option_statusline(ACCEPT_DATA);
  655.             move(L_HOME, C_DEFAULT);
  656.             start_bold();
  657.             ch = LYgetstr(display_option, VISIBLE,
  658.                   sizeof(display_option), NORECALL);
  659.             stop_bold();
  660.             move(L_HOME, C_DEFAULT);
  661.             if (term_options ||
  662.             ch == -1 || *display_option == '\0') {
  663.             addstr((bookmark_page && *bookmark_page) ?
  664.                            bookmark_page : "NONE");
  665.             } else if (!LYPathOffHomeOK(display_option,
  666.                         sizeof(display_option))) {
  667.             addstr((bookmark_page && *bookmark_page) ?
  668.                            bookmark_page : "NONE");
  669.             clrtoeol();
  670.             option_statusline(USE_PATH_OFF_HOME);
  671.             response = ' ';
  672.             break;
  673.             } else {
  674.             StrAllocCopy(bookmark_page, display_option);
  675.             StrAllocCopy(MBM_A_subbookmark[0],
  676.                      bookmark_page);
  677.             addstr(bookmark_page);
  678.             }
  679.             clrtoeol();
  680.             if (ch == -1) {
  681.             option_statusline(CANCELLED);
  682.             sleep(InfoSecs);
  683.             option_statusline("");
  684.             } else {
  685.             option_statusline(VALUE_ACCEPTED);
  686.             }
  687.         } else { /* anonymous */
  688.             option_statusline(BOOKMARK_CHANGE_DISALLOWED);
  689.         }
  690.         response = ' ';
  691.         break;
  692.  
  693.         case 'f':    /* Change ftp directory sorting. */
  694.         case 'F':    /*  (also local for non-DIRED)     */
  695.         /*
  696.          *  Copy strings into choice array.
  697.          */
  698.         choices[0] = NULL;
  699.         StrAllocCopy(choices[0], "By Filename");
  700.         choices[1] = NULL;
  701.         StrAllocCopy(choices[1], "By Type    ");
  702.         choices[2] = NULL;
  703.         StrAllocCopy(choices[2], "By Size    ");
  704.         choices[3] = NULL;
  705.         StrAllocCopy(choices[3], "By Date    ");
  706.         choices[4] = NULL;
  707.         if (!LYSelectPopups) {
  708.             HTfileSortMethod = boolean_choice(HTfileSortMethod,
  709.                               L_FTPSTYPE, -1,
  710.                               choices);
  711.         } else {
  712.             HTfileSortMethod = popup_choice(HTfileSortMethod,
  713.                             L_FTPSTYPE, -1,
  714.                             choices,
  715.                             4, FALSE);
  716. #if defined(VMS) || defined(USE_SLANG)
  717.             move(L_FTPSTYPE, COL_OPTION_VALUES);
  718.             clrtoeol();
  719.             addstr(choices[HTfileSortMethod]);
  720. #endif /* VMS || USE_SLANG */
  721.         }
  722.         FREE(choices[0]);
  723.         FREE(choices[1]);
  724.         FREE(choices[2]);
  725.         FREE(choices[3]);
  726.         response = ' ';
  727.         if (LYSelectPopups) {
  728. #if !defined(VMS) || defined(USE_SLANG)
  729.             if (term_options) {
  730.             term_options = FALSE;
  731.             } else {
  732.             AddValueAccepted = TRUE;
  733.             }
  734.             goto draw_options;
  735. #else
  736.             term_options = FALSE;
  737. #endif /* !VMS || USE_SLANG */
  738.         }
  739.         break;
  740.  
  741.         case 'p': /* Change personal mail address for From headers. */
  742.         case 'P':
  743.         if (personal_mail_address && *personal_mail_address) {
  744.             strcpy(display_option, personal_mail_address);
  745.         } else {  /* clear the NONE */
  746.             move(L_MAIL_ADDRESS, COL_OPTION_VALUES);
  747.             addstr("    ");
  748.             *display_option = '\0';
  749.         }
  750.         option_statusline(ACCEPT_DATA);
  751.         move(L_MAIL_ADDRESS, COL_OPTION_VALUES);
  752.         start_bold();
  753.         ch = LYgetstr(display_option, VISIBLE,
  754.                   sizeof(display_option), NORECALL);
  755.         stop_bold();
  756.         move(L_MAIL_ADDRESS, COL_OPTION_VALUES);
  757.         if (term_options || ch == -1) {
  758.             addstr((personal_mail_address &&
  759.                 *personal_mail_address) ?
  760.                   personal_mail_address : "NONE");
  761.         } else if (*display_option == '\0') {
  762.             FREE(personal_mail_address);
  763.             addstr("NONE");
  764.         } else {
  765.             StrAllocCopy(personal_mail_address, display_option);
  766.             addstr(display_option);
  767.         }
  768.         clrtoeol();
  769.         if (ch == -1) {
  770.             option_statusline(CANCELLED);
  771.             sleep(InfoSecs);
  772.             option_statusline("");
  773.         } else {
  774.             option_statusline(VALUE_ACCEPTED);
  775.         }
  776.         response = ' ';
  777.         break;
  778.  
  779.         case 's':    /* Change case sentitivity for searches. */
  780.         case 'S':
  781.         /*
  782.          *  Copy strings into choice array.
  783.          */
  784.         choices[0] = NULL;
  785.         StrAllocCopy(choices[0], "CASE INSENSITIVE");
  786.         choices[1] = NULL;
  787.         StrAllocCopy(choices[1], "CASE SENSITIVE  ");
  788.         choices[2] = NULL;
  789.         case_sensitive = boolean_choice(case_sensitive,
  790.                         L_SSEARCH, -1, choices);
  791.         FREE(choices[0]);
  792.         FREE(choices[1]);
  793.         response = ' ';
  794.         break;
  795.  
  796.         case '\001':    /* Change assume_charset setting. */
  797.         if (use_assume_charset) {
  798.             int i, curval;
  799.             char ** assume_list;
  800.             assume_list = (char **)calloc(LYNumCharsets + 1, sizeof(char *));
  801.             if (!assume_list) {
  802.             outofmem(__FILE__, "options");
  803.             }
  804.             for (i = 0; i < LYNumCharsets; i++) {
  805.             assume_list[i] = (char *)LYCharSet_UC[i].MIMEname;
  806.             }
  807.             curval = UCLYhndl_for_unspec;
  808.             if (curval == current_char_set && UCAssume_MIMEcharset) {
  809.             curval = UCGetLYhndl_byMIME(UCAssume_MIMEcharset);
  810.             }
  811.             if (curval < 0)
  812.             curval = LYRawMode ? current_char_set : 0;
  813.             if (!LYSelectPopups) {
  814.             UCLYhndl_for_unspec = boolean_choice(curval,
  815.                                  L_ASSUME_CHARSET, -1,
  816.                                  assume_list);
  817.             } else {
  818.             UCLYhndl_for_unspec = popup_choice(curval,
  819.                                L_ASSUME_CHARSET, -1,
  820.                                assume_list,
  821.                                0, FALSE);
  822. #if defined(VMS) || defined(USE_SLANG)
  823.             move(L_ASSUME_CHARSET, COL_OPTION_VALUES);
  824.             clrtoeol();
  825.             if (UCLYhndl_for_unspec >= 0)
  826.                 addstr((char *)
  827.                    LYCharSet_UC[UCLYhndl_for_unspec].MIMEname);
  828. #endif /* VMS || USE_SLANG */
  829.             }
  830.  
  831.             /*
  832.          *  Set the raw 8-bit or CJK mode defaults and
  833.          *  character set if changed. - FM
  834.          */
  835.             if (CurrentAssumeCharSet != UCLYhndl_for_unspec ||
  836.             UCLYhndl_for_unspec != curval) {
  837.             if (UCLYhndl_for_unspec != CurrentAssumeCharSet) {
  838.                 StrAllocCopy(UCAssume_MIMEcharset,
  839.                      LYCharSet_UC[UCLYhndl_for_unspec].MIMEname);
  840.             }
  841.             LYRawMode = (UCLYhndl_for_unspec == current_char_set);
  842.             HTMLSetUseDefaultRawMode(current_char_set, LYRawMode);
  843.             HTMLUseCharacterSet(current_char_set);
  844.             CurrentAssumeCharSet = UCLYhndl_for_unspec;
  845.             CurrentAssumeLocalCharSet = UCLYhndl_HTFile_for_unspec;
  846.             CurrentRawMode = LYRawMode;
  847. #if !defined(VMS) && !defined(USE_SLANG)
  848.             if (!LYSelectPopups)
  849. #endif /* !VMS && !USE_SLANG */
  850.             {
  851.                 move(L_Rawmode, COL_OPTION_VALUES);
  852.                 clrtoeol();
  853.                 addstr(LYRawMode ? "ON " : "OFF");
  854.             }
  855.             }
  856.             FREE(assume_list);
  857.             response = ' ';
  858.             if (LYSelectPopups) {
  859. #if !defined(VMS) || defined(USE_SLANG)
  860.             if (term_options) {
  861.                 term_options = FALSE;
  862.             } else {
  863.                 AddValueAccepted = TRUE;
  864.             }
  865.             goto draw_options;
  866. #else
  867.             term_options = FALSE;
  868. #endif /* !VMS || USE_SLANG */
  869.             }
  870.         } else {
  871.             option_statusline(NEED_ADVANCED_USER_MODE);
  872.             AddValueAccepted = FALSE;
  873.         }
  874.         break;
  875.  
  876.         case 'c':    /* Change display charset setting. */
  877.         case 'C':
  878.         if (!LYSelectPopups) {
  879.             current_char_set = boolean_choice(current_char_set,
  880.                               L_Charset, -1,
  881.                               (char **)LYchar_set_names);
  882.         } else {
  883.             current_char_set = popup_choice(current_char_set,
  884.                             L_Charset, -1,
  885.                             (char **)LYchar_set_names,
  886.                             0, FALSE);
  887. #if defined(VMS) || defined(USE_SLANG)
  888.             move(L_Charset, COL_OPTION_VALUES);
  889.             clrtoeol();
  890.             addstr((char *)LYchar_set_names[current_char_set]);
  891. #endif /* VMS || USE_SLANG */
  892.         }
  893.         /*
  894.          *  Set the raw 8-bit or CJK mode defaults and
  895.          *  character set if changed. - FM
  896.          */
  897.         if (CurrentCharSet != current_char_set) {
  898.             HTMLSetRawModeDefault(current_char_set);
  899.             LYUseDefaultRawMode = TRUE;
  900.             HTMLUseCharacterSet(current_char_set);
  901.             CurrentCharSet = current_char_set;
  902.             CurrentRawMode = LYRawMode;
  903. #if !defined(VMS) && !defined(USE_SLANG)
  904.             if (!LYSelectPopups)
  905. #endif /* !VMS && !USE_SLANG */
  906.             {
  907.             move(L_Rawmode, COL_OPTION_VALUES);
  908.             clrtoeol();
  909.             addstr(LYRawMode ? "ON " : "OFF");
  910.             }
  911.         }
  912.         response = ' ';
  913.         if (LYSelectPopups) {
  914. #if !defined(VMS) || defined(USE_SLANG)
  915.             if (term_options) {
  916.             term_options = FALSE;
  917.             } else {
  918.             AddValueAccepted = TRUE;
  919.             }
  920.             goto draw_options;
  921. #else
  922.             term_options = FALSE;
  923. #endif /* !VMS || USE_SLANG */
  924.         }
  925.         break;
  926.  
  927.         case 'o':    /* Change raw mode setting. */
  928.         case 'O':
  929.         /*
  930.          *  Copy strings into choice array.
  931.          */
  932.         choices[0] = NULL;
  933.         StrAllocCopy(choices[0], "OFF");
  934.         choices[1] = NULL;
  935.         StrAllocCopy(choices[1], "ON ");
  936.         choices[2] = NULL;
  937.         LYRawMode = boolean_choice(LYRawMode, L_Rawmode, -1, choices);
  938.         /*
  939.          *  Set the LYUseDefaultRawMode value and character
  940.          *  handling if LYRawMode was changed. - FM
  941.          */
  942.         if (CurrentRawMode != LYRawMode) {
  943.             HTMLSetUseDefaultRawMode(current_char_set, LYRawMode);
  944.             HTMLSetCharacterHandling(current_char_set);
  945.             CurrentRawMode = LYRawMode;
  946.         }
  947.         FREE(choices[0]);
  948.         FREE(choices[1]);
  949.         response = ' ';
  950.         break;
  951.  
  952.         case 'g':    /* Change language preference. */
  953.         case 'G':
  954.         if (language && *language) {
  955.             strcpy(display_option, language);
  956.         } else {  /* clear the NONE */
  957.             move(L_LANGUAGE, COL_OPTION_VALUES);
  958.             addstr("    ");
  959.             *display_option = '\0';
  960.         }
  961.         option_statusline(ACCEPT_DATA);
  962.         move(L_LANGUAGE, COL_OPTION_VALUES);
  963.         start_bold();
  964.         ch = LYgetstr(display_option, VISIBLE,
  965.                   sizeof(display_option), NORECALL);
  966.         stop_bold();
  967.         move(L_LANGUAGE, COL_OPTION_VALUES);
  968.         if (term_options || ch == -1) {
  969.             addstr((language && *language) ?
  970.                       language : "NONE");
  971.         } else if (*display_option == '\0') {
  972.             FREE(language);
  973.             addstr("NONE");
  974.         } else {
  975.             StrAllocCopy(language, display_option);
  976.             addstr(display_option);
  977.         }
  978.         clrtoeol();
  979.         if (ch == -1) {
  980.             option_statusline(CANCELLED);
  981.             sleep(InfoSecs);
  982.             option_statusline("");
  983.         } else {
  984.             option_statusline(VALUE_ACCEPTED);
  985.         }
  986.         response = ' ';
  987.         break;
  988.  
  989.         case 'h':    /* Change charset preference. */
  990.         case 'H':
  991.         if (pref_charset && *pref_charset) {
  992.             strcpy(display_option, pref_charset);
  993.         } else {  /* clear the NONE */
  994.             move(L_PREF_CHARSET, COL_OPTION_VALUES);
  995.             addstr("    ");
  996.             *display_option = '\0';
  997.         }
  998.         option_statusline(ACCEPT_DATA);
  999.         move(L_PREF_CHARSET, COL_OPTION_VALUES);
  1000.         start_bold();
  1001.         ch = LYgetstr(display_option, VISIBLE,
  1002.                   sizeof(display_option), NORECALL);
  1003.         stop_bold();
  1004.         move(L_PREF_CHARSET, COL_OPTION_VALUES);
  1005.         if (term_options || ch == -1) {
  1006.             addstr((pref_charset && *pref_charset) ?
  1007.                pref_charset : "NONE");
  1008.         } else if (*display_option == '\0') {
  1009.             FREE(pref_charset);
  1010.             addstr("NONE");
  1011.         } else {
  1012.             StrAllocCopy(pref_charset, display_option);
  1013.             addstr(display_option);
  1014.         }
  1015.         clrtoeol();
  1016.         if (ch == -1) {
  1017.             option_statusline(CANCELLED);
  1018.             sleep(InfoSecs);
  1019.             option_statusline("");
  1020.         } else {
  1021.             option_statusline(VALUE_ACCEPTED);
  1022.         }
  1023.         response = ' ';
  1024.         break;
  1025.  
  1026.         case 'v':    /* Change VI keys setting. */
  1027.         case 'V':
  1028.         /*
  1029.          *  Copy strings into choice array.
  1030.          */
  1031.         choices[0] = NULL;
  1032.         StrAllocCopy(choices[0], "OFF");
  1033.         choices[1] = NULL;
  1034.         StrAllocCopy(choices[1], "ON ");
  1035.         choices[2] = NULL;
  1036.         vi_keys = boolean_choice(vi_keys,
  1037.                      L_Bool_A, C_VIKEYS,
  1038.                      choices);
  1039.         if (vi_keys) {
  1040.             set_vi_keys();
  1041.         } else {
  1042.             reset_vi_keys();
  1043.         }
  1044.         FREE(choices[0]);
  1045.         FREE(choices[1]);
  1046.         response = ' ';
  1047.         break;
  1048.  
  1049.         case 'M':    /* Change emacs keys setting. */
  1050.         case 'm':
  1051.         /*
  1052.          *  Copy strings into choice array.
  1053.          */
  1054.         choices[0] = NULL;
  1055.         StrAllocCopy(choices[0], "OFF");
  1056.         choices[1] = NULL;
  1057.         StrAllocCopy(choices[1], "ON ");
  1058.         choices[2] = NULL;
  1059.         emacs_keys = boolean_choice(emacs_keys,
  1060.                         L_Bool_A, C_EMACSKEYS,
  1061.                         choices);
  1062.         if (emacs_keys) {
  1063.             set_emacs_keys();
  1064.         } else {
  1065.             reset_emacs_keys();
  1066.         }
  1067.         FREE(choices[0]);
  1068.         FREE(choices[1]);
  1069.         response = ' ';
  1070.         break;
  1071.  
  1072.         case 'W':    /* Change show dotfiles setting. */
  1073.         case 'w':
  1074.         if (no_dotfiles) {
  1075.             option_statusline(DOTFILE_ACCESS_DISABLED);
  1076.         } else {
  1077.             /*
  1078.              *    Copy strings into choice array.
  1079.              */
  1080.             choices[0] = NULL;
  1081.             StrAllocCopy(choices[0], "OFF");
  1082.             choices[1] = NULL;
  1083.             StrAllocCopy(choices[1], "ON ");
  1084.             choices[2] = NULL;
  1085.             show_dotfiles = boolean_choice(show_dotfiles,
  1086.                            L_Bool_A,
  1087.                            C_SHOW_DOTFILES,
  1088.                            choices);
  1089.             FREE(choices[0]);
  1090.             FREE(choices[1]);
  1091.         }
  1092.         response = ' ';
  1093.         break;
  1094.  
  1095.         case 't':    /* Change select popups setting. */
  1096.         case 'T':
  1097.         /*
  1098.          *  Copy strings into choice array.
  1099.          */
  1100.         choices[0] = NULL;
  1101.         StrAllocCopy(choices[0], "OFF");
  1102.         choices[1] = NULL;
  1103.         StrAllocCopy(choices[1], "ON ");
  1104.         choices[2] = NULL;
  1105.         LYSelectPopups = boolean_choice(LYSelectPopups,
  1106.                         L_Bool_B,
  1107.                         C_SELECT_POPUPS,
  1108.                         choices);
  1109.         FREE(choices[0]);
  1110.         FREE(choices[1]);
  1111.         response = ' ';
  1112.         break;
  1113.  
  1114. #if defined(USE_SLANG) || defined(COLOR_CURSES)
  1115.         case '&':    /* Change show color setting. */
  1116.         if (no_option_save) {
  1117. #if defined(COLOR_CURSES)
  1118.             if (!has_colors()) {
  1119.             char * terminal = getenv("TERM");
  1120.             if (terminal)
  1121.                 option_user_message(
  1122.                 COLOR_TOGGLE_DISABLED_FOR_TERM,
  1123.                 terminal);
  1124.             else
  1125.                 option_statusline(COLOR_TOGGLE_DISABLED);
  1126.             sleep(AlertSecs);
  1127.             }
  1128. #endif
  1129.         /*
  1130.          *  Copy strings into choice array.
  1131.          */
  1132.             choices[0] = NULL;
  1133.             StrAllocCopy(choices[0], "OFF");
  1134.             choices[1] = NULL;
  1135.             StrAllocCopy(choices[1], "ON ");
  1136.             choices[2] = NULL;
  1137.             LYShowColor = boolean_choice((LYShowColor - 1),
  1138.                          L_Color,
  1139.                          C_COLOR,
  1140.                          choices);
  1141.             if (LYShowColor == 0) {
  1142.             LYShowColor = SHOW_COLOR_OFF;
  1143.             } else {
  1144.             LYShowColor = SHOW_COLOR_ON;
  1145.             }
  1146.         } else {        /* !no_option_save */
  1147.             BOOLEAN again = FALSE;
  1148.             int chosen;
  1149.         /*
  1150.          *  Copy strings into choice array.
  1151.          */
  1152.             choices[0] = NULL;
  1153.             StrAllocCopy(choices[0], "NEVER     ");
  1154.             choices[1] = NULL;
  1155.             StrAllocCopy(choices[1], "OFF       ");
  1156.             choices[2] = NULL;
  1157.             StrAllocCopy(choices[2], "ON        ");
  1158.             choices[3] = NULL;
  1159. #if defined(COLOR_CURSES)
  1160.             if (!has_colors())
  1161.             StrAllocCopy(choices[3], "Always try");
  1162.             else
  1163. #endif
  1164.             StrAllocCopy(choices[3], "ALWAYS    ");
  1165.             choices[4] = NULL;
  1166.             do {
  1167.             if (!LYSelectPopups) {
  1168.                 chosen = boolean_choice(LYChosenShowColor,
  1169.                             L_Color,
  1170.                             C_COLOR,
  1171.                             choices);
  1172.             } else {
  1173.                 chosen = popup_choice(LYChosenShowColor,
  1174.                           L_Color,
  1175.                           C_COLOR,
  1176.                           choices, 4, FALSE);
  1177.             }
  1178. #if defined(COLOR_CURSES)
  1179.             again = (chosen == 2 && !has_colors());
  1180.             if (again) {
  1181.                 char * terminal = getenv("TERM");
  1182.                 if (terminal)
  1183.                 option_user_message(
  1184.                     COLOR_TOGGLE_DISABLED_FOR_TERM,
  1185.                     terminal);
  1186.                 else
  1187.                 option_statusline(COLOR_TOGGLE_DISABLED);
  1188.                 sleep(AlertSecs);
  1189.             }
  1190. #endif
  1191.             } while (again);
  1192.             LYChosenShowColor = chosen;
  1193. #if defined(VMS)
  1194.             if (LYSelectPopups) {
  1195.             move(L_Color, C_COLOR);
  1196.             clrtoeol();
  1197.             addstr(choices[LYChosenShowColor]);
  1198.             }
  1199. #endif /* VMS */
  1200. #if defined(COLOR_CURSES)
  1201.             if (has_colors())
  1202. #endif
  1203.             LYShowColor = chosen;
  1204.             FREE(choices[2]);
  1205.             FREE(choices[3]);
  1206.         }
  1207.         FREE(choices[0]);
  1208.         FREE(choices[1]);
  1209.         if (CurrentShowColor != LYShowColor) {
  1210.             lynx_force_repaint();
  1211.         }
  1212.         CurrentShowColor = LYShowColor;
  1213. #ifdef USE_SLANG
  1214.         SLtt_Use_Ansi_Colors = (LYShowColor > 1 ? 1 : 0);
  1215. #endif
  1216.         response = ' ';
  1217.         if (LYSelectPopups && !no_option_save) {
  1218. #if !defined(VMS) || defined(USE_SLANG)
  1219.             if (term_options) {
  1220.             term_options = FALSE;
  1221.             } else {
  1222.             AddValueAccepted = TRUE;
  1223.             }
  1224.             goto draw_options;
  1225. #else
  1226.             term_options = FALSE;
  1227. #endif /* !VMS || USE_SLANG */
  1228.         }
  1229.         break;
  1230. #endif /* USE_SLANG or COLOR_CURSES */
  1231.  
  1232.         case '@':    /* Change show cursor setting. */
  1233.         /*
  1234.          *  Copy strings into choice array.
  1235.          */
  1236.         choices[0] = NULL;
  1237.         StrAllocCopy(choices[0], "OFF");
  1238.         choices[1] = NULL;
  1239.         StrAllocCopy(choices[1], "ON ");
  1240.         choices[2] = NULL;
  1241.         LYShowCursor = boolean_choice(LYShowCursor,
  1242.                           L_Bool_B,
  1243.                           C_SHOW_CURSOR,
  1244.                           choices);
  1245.         FREE(choices[0]);
  1246.         FREE(choices[1]);
  1247.         response = ' ';
  1248.         break;
  1249.  
  1250.         case 'k':    /* Change keypad mode. */
  1251.         case 'K':
  1252.         /*
  1253.          *  Copy strings into choice array.
  1254.          */
  1255.         choices[0] = NULL;
  1256.         StrAllocCopy(choices[0],
  1257.                  "Numbers act as arrows             ");
  1258.         choices[1] = NULL;
  1259.         StrAllocCopy(choices[1],
  1260.                  "Links are numbered                ");
  1261.         choices[2] = NULL;
  1262.         StrAllocCopy(choices[2],
  1263.                  "Links and form fields are numbered");
  1264.         choices[3] = NULL;
  1265.         if (!LYSelectPopups) {
  1266.             keypad_mode = boolean_choice(keypad_mode,
  1267.                          L_Keypad, -1,
  1268.                          choices);
  1269.         } else {
  1270.             keypad_mode = popup_choice(keypad_mode,
  1271.                            L_Keypad, -1,
  1272.                            choices,
  1273.                            3, FALSE);
  1274. #if defined(VMS) || defined(USE_SLANG)
  1275.             move(L_Keypad, COL_OPTION_VALUES);
  1276.             clrtoeol();
  1277.             addstr(choices[keypad_mode]);
  1278. #endif /* VMS || USE_SLANG */
  1279.         }
  1280.         if (keypad_mode == NUMBERS_AS_ARROWS) {
  1281.             set_numbers_as_arrows();
  1282.         } else {
  1283.             reset_numbers_as_arrows();
  1284.         }
  1285.         FREE(choices[0]);
  1286.         FREE(choices[1]);
  1287.         FREE(choices[2]);
  1288.         response = ' ';
  1289.         if (LYSelectPopups) {
  1290. #if !defined(VMS) || defined(USE_SLANG)
  1291.             if (term_options) {
  1292.             term_options = FALSE;
  1293.             } else {
  1294.             AddValueAccepted = TRUE;
  1295.             }
  1296.             goto draw_options;
  1297. #else
  1298.             term_options = FALSE;
  1299. #endif /* !VMS || USE_SLANG */
  1300.         }
  1301.         break;
  1302.  
  1303.         case 'n':    /* Change line editor key bindings. */
  1304.         case 'N':
  1305.         if (!LYSelectPopups) {
  1306.             current_lineedit = boolean_choice(current_lineedit,
  1307.                               L_Lineed, -1,
  1308.                               LYLineeditNames);
  1309.         } else {
  1310.             current_lineedit = popup_choice(current_lineedit,
  1311.                             L_Lineed, -1,
  1312.                             LYLineeditNames,
  1313.                             0, FALSE);
  1314. #if defined(VMS) || defined(USE_SLANG)
  1315.             move(L_Lineed, COL_OPTION_VALUES);
  1316.             clrtoeol();
  1317.             addstr(LYLineeditNames[current_lineedit]);
  1318. #endif /* VMS || USE_SLANG */
  1319.         }
  1320.         response = ' ';
  1321.         if (LYSelectPopups) {
  1322. #if !defined(VMS) || defined(USE_SLANG)
  1323.             if (term_options) {
  1324.             term_options = FALSE;
  1325.             } else {
  1326.             AddValueAccepted = TRUE;
  1327.             }
  1328.             goto draw_options;
  1329. #else
  1330.             term_options = FALSE;
  1331. #endif /* !VMS || USE_SLANG */
  1332.         }
  1333.         break;
  1334.  
  1335. #ifdef DIRED_SUPPORT
  1336.         case 'i':    /* Change local directory sorting. */
  1337.         case 'I':
  1338.         /*
  1339.          *  Copy strings into choice array.
  1340.          */
  1341.         choices[0] = NULL;
  1342.         StrAllocCopy(choices[0], "Directories first");
  1343.         choices[1] = NULL;
  1344.         StrAllocCopy(choices[1], "Files first      ");
  1345.         choices[2] = NULL;
  1346.         StrAllocCopy(choices[2], "Mixed style      ");
  1347.         choices[3] = NULL;
  1348.         if (!LYSelectPopups) {
  1349.             dir_list_style = boolean_choice(dir_list_style,
  1350.                             L_Dired, -1,
  1351.                             choices);
  1352.         } else {
  1353.             dir_list_style = popup_choice(dir_list_style,
  1354.                           L_Dired, -1,
  1355.                           choices,
  1356.                           3, FALSE);
  1357. #if defined(VMS) || defined(USE_SLANG)
  1358.             move(L_Dired, COL_OPTION_VALUES);
  1359.             clrtoeol();
  1360.             addstr(choices[dir_list_style]);
  1361. #endif /* VMS || USE_SLANG */
  1362.         }
  1363.         FREE(choices[0]);
  1364.         FREE(choices[1]);
  1365.         FREE(choices[2]);
  1366.         response = ' ';
  1367.         if (LYSelectPopups) {
  1368. #if !defined(VMS) || defined(USE_SLANG)
  1369.             if (term_options) {
  1370.             term_options = FALSE;
  1371.             } else {
  1372.             AddValueAccepted = TRUE;
  1373.             }
  1374.             goto draw_options;
  1375. #else
  1376.             term_options = FALSE;
  1377. #endif /* !VMS || USE_SLANG */
  1378.         }
  1379.         break;
  1380. #endif /* DIRED_SUPPORT */
  1381.  
  1382.         case 'u':    /* Change user mode. */
  1383.         case 'U':
  1384.         /*
  1385.          *  Copy strings into choice array.
  1386.          */
  1387.         choices[0] = NULL;
  1388.         StrAllocCopy(choices[0], "Novice      ");
  1389.         choices[1] = NULL;
  1390.         StrAllocCopy(choices[1], "Intermediate");
  1391.         choices[2] = NULL;
  1392.         StrAllocCopy(choices[2], "Advanced    ");
  1393.         choices[3] = NULL;
  1394.         if (!LYSelectPopups) {
  1395.             user_mode = boolean_choice(user_mode,
  1396.                            L_User_Mode, -1,
  1397.                            choices);
  1398.             use_assume_charset = (user_mode >= 2);
  1399.         } else {
  1400.             user_mode = popup_choice(user_mode,
  1401.                          L_User_Mode, -1,
  1402.                          choices,
  1403.                          3, FALSE);
  1404.             use_assume_charset = (user_mode >= 2);
  1405. #if defined(VMS) || defined(USE_SLANG)
  1406.             if (use_assume_charset == old_use_assume_charset) {
  1407.             move(L_User_Mode, COL_OPTION_VALUES);
  1408.             clrtoeol();
  1409.             addstr(choices[user_mode]);
  1410.             }
  1411. #endif /* VMS || USE_SLANG */
  1412.         }
  1413.         FREE(choices[0]);
  1414.         FREE(choices[1]);
  1415.         FREE(choices[2]);
  1416.         if (user_mode == NOVICE_MODE) {
  1417.             display_lines = (LYlines - 4);
  1418.         } else {
  1419.             display_lines = LYlines-2;
  1420.         }
  1421.         response = ' ';
  1422.         if (LYSelectPopups) {
  1423. #if !defined(VMS) || defined(USE_SLANG)
  1424.             if (term_options) {
  1425.             term_options = FALSE;
  1426.             } else {
  1427.             AddValueAccepted = TRUE;
  1428.             }
  1429.             goto draw_options;
  1430. #else
  1431.             term_options = FALSE;
  1432.             if (use_assume_charset != old_use_assume_charset)
  1433.             goto draw_options;
  1434. #endif /* !VMS || USE_SLANG */
  1435.         }
  1436.         break;
  1437.  
  1438.         case 'a':    /* Change user agent string. */
  1439.         case 'A':
  1440.         if (!no_useragent) {
  1441.             if (LYUserAgent && *LYUserAgent) {
  1442.             strcpy(display_option, LYUserAgent);
  1443.             } else {  /* clear the NONE */
  1444.             move(L_HOME, COL_OPTION_VALUES);
  1445.             addstr("    ");
  1446.             *display_option = '\0';
  1447.             }
  1448.             option_statusline(ACCEPT_DATA_OR_DEFAULT);
  1449.             move(L_User_Agent, COL_OPTION_VALUES);
  1450.             start_bold();
  1451.             ch = LYgetstr(display_option, VISIBLE,
  1452.                   sizeof(display_option), NORECALL);
  1453.             stop_bold();
  1454.             move(L_User_Agent, COL_OPTION_VALUES);
  1455.             if (term_options || ch == -1) {
  1456.             addstr((LYUserAgent &&
  1457.                 *LYUserAgent) ?
  1458.                   LYUserAgent : "NONE");
  1459.             } else if (*display_option == '\0') {
  1460.             StrAllocCopy(LYUserAgent, LYUserAgentDefault);
  1461.             addstr((LYUserAgent &&
  1462.                 *LYUserAgent) ?
  1463.                   LYUserAgent : "NONE");
  1464.             } else {
  1465.             StrAllocCopy(LYUserAgent, display_option);
  1466.             addstr(display_option);
  1467.             }
  1468.             clrtoeol();
  1469.             if (ch == -1) {
  1470.             option_statusline(CANCELLED);
  1471.             sleep(InfoSecs);
  1472.             option_statusline("");
  1473.             } else if (LYUserAgent && *LYUserAgent &&
  1474.             !strstr(LYUserAgent, "Lynx") &&
  1475.             !strstr(LYUserAgent, "lynx")) {
  1476.             option_statusline(UA_COPYRIGHT_WARNING);
  1477.             } else {
  1478.             option_statusline(VALUE_ACCEPTED);
  1479.             }
  1480.         } else { /* disallowed */
  1481.             option_statusline(UA_COPYRIGHT_WARNING);
  1482.         }
  1483.         response = ' ';
  1484.         break;
  1485.  
  1486. #ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS
  1487.         case 'x':    /* Change local exec restriction. */
  1488.         case 'X':
  1489.         if (exec_frozen && !LYSelectPopups) {
  1490.             option_statusline(CHANGE_OF_SETTING_DISALLOWED);
  1491.             response = ' ';
  1492.             break;
  1493.         }
  1494. #ifndef NEVER_ALLOW_REMOTE_EXEC
  1495.         if (local_exec) {
  1496.             itmp = 2;
  1497.         } else
  1498. #endif /* !NEVER_ALLOW_REMOTE_EXEC */
  1499.         {
  1500.             if (local_exec_on_local_files) {
  1501.             itmp= 1;
  1502.             } else {
  1503.             itmp = 0;
  1504.             }
  1505.         }
  1506.         /*
  1507.          *  Copy strings into choice array.
  1508.          */
  1509.         choices[0] = NULL;
  1510.         StrAllocCopy(choices[0], "ALWAYS OFF          ");
  1511.         choices[1] = NULL;
  1512.         StrAllocCopy(choices[1], "FOR LOCAL FILES ONLY");
  1513.         choices[2] = NULL;
  1514. #ifndef NEVER_ALLOW_REMOTE_EXEC
  1515.         StrAllocCopy(choices[2], "ALWAYS ON           ");
  1516.         choices[3] = NULL;
  1517. #endif /* !NEVER_ALLOW_REMOTE_EXEC */
  1518.         if (!LYSelectPopups) {
  1519.             itmp = boolean_choice(itmp,
  1520.                       L_Exec, -1,
  1521.                       choices);
  1522.         } else {
  1523.             itmp = popup_choice(itmp,
  1524.                     L_Exec, -1,
  1525.                     choices,
  1526.                     0, (exec_frozen ? TRUE : FALSE));
  1527. #if defined(VMS) || defined(USE_SLANG)
  1528.             move(L_Exec, COL_OPTION_VALUES);
  1529.             clrtoeol();
  1530.             addstr(choices[itmp]);
  1531. #endif /* VMS || USE_SLANG */
  1532.         }
  1533.         FREE(choices[0]);
  1534.         FREE(choices[1]);
  1535. #ifndef NEVER_ALLOW_REMOTE_EXEC
  1536.         FREE(choices[2]);
  1537. #endif /* !NEVER_ALLOW_REMOTE_EXEC */
  1538.         if (!exec_frozen) {
  1539.             switch (itmp) {
  1540.             case 0:
  1541.                 local_exec = FALSE;
  1542.                 local_exec_on_local_files = FALSE;
  1543.                 break;
  1544.             case 1:
  1545.                 local_exec = FALSE;
  1546.                 local_exec_on_local_files = TRUE;
  1547.                 break;
  1548. #ifndef NEVER_ALLOW_REMOTE_EXEC
  1549.             case 2:
  1550.                 local_exec = TRUE;
  1551.                 local_exec_on_local_files = FALSE;
  1552.                 break;
  1553. #endif /* !NEVER_ALLOW_REMOTE_EXEC */
  1554.             } /* end switch */
  1555.         }
  1556.         response = ' ';
  1557.         if (LYSelectPopups) {
  1558. #if !defined(VMS) || defined(USE_SLANG)
  1559.             if (exec_frozen || term_options) {
  1560.             term_options = FALSE;
  1561.             } else {
  1562.             AddValueAccepted = TRUE;
  1563.             }
  1564.             goto draw_options;
  1565. #else
  1566.             term_options = FALSE;
  1567. #endif /* !VMS || USE_SLANG */
  1568.         }
  1569.         break;
  1570. #endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */
  1571.  
  1572.         case '>':    /* Save current options to RC file. */
  1573.         if (!no_option_save) {
  1574.             option_statusline(SAVING_OPTIONS);
  1575.             if (save_rc()) {
  1576.             LYrcShowColor = LYChosenShowColor;
  1577.             option_statusline(OPTIONS_SAVED);
  1578.             } else {
  1579.             HTAlert(OPTIONS_NOT_SAVED);
  1580.             }
  1581.         } else {
  1582.             option_statusline(R_TO_RETURN_TO_LYNX);
  1583.             /*
  1584.              *    Change response so that we don't exit
  1585.              *    the options menu.
  1586.              */
  1587.             response = ' ';
  1588.         }
  1589.         break;
  1590.  
  1591.         case 'r':    /* Return to document (quit options menu). */
  1592.         case 'R':
  1593.         break;
  1594.  
  1595.         default:
  1596.         if (!no_option_save) {
  1597.             option_statusline(SAVE_OR_R_TO_RETURN_TO_LYNX);
  1598.         } else {
  1599.             option_statusline(R_TO_RETURN_TO_LYNX);
  1600.         }
  1601.     }  /* end switch */
  1602.     }  /* end while */
  1603.  
  1604.     term_options = FALSE;
  1605.     signal(SIGINT, cleanup_sig);
  1606. }
  1607.  
  1608. /*
  1609.  *  Take a boolean status,prompt the user for a new status,
  1610.  *  and return it.
  1611.  */
  1612. PRIVATE int boolean_choice ARGS4(
  1613.     int,        cur_choice,
  1614.     int,        line,
  1615.     int,        column,
  1616.     char **,    choices)
  1617. {
  1618.     int response = 0;
  1619.     int cmd = 0;
  1620.     int number = 0;
  1621.     int col = (column >= 0 ? column : COL_OPTION_VALUES);
  1622.     int orig_choice = cur_choice;
  1623. #ifdef VMS
  1624.     extern BOOLEAN HadVMSInterrupt; /* Flag from cleanup_sig() AST */
  1625. #endif /* VMS */
  1626.  
  1627.     /*
  1628.      *    Get the number of choices and then make
  1629.      *    number zero-based.
  1630.      */
  1631.     for (number = 0; choices[number] != NULL; number++)
  1632.     ;  /* empty loop body */
  1633.     number--;
  1634.  
  1635.     /*
  1636.      *    Update the statusline.
  1637.      */
  1638.     option_statusline(ANY_KEY_CHANGE_RET_ACCEPT);
  1639.  
  1640.     /*
  1641.      *    Highlight the current choice.
  1642.      */
  1643.     move(line, col);
  1644.     start_reverse();
  1645.     addstr(choices[cur_choice]);
  1646.     if (LYShowCursor)
  1647.     move(line, (col - 1));
  1648.     refresh();
  1649.  
  1650.     /*
  1651.      *    Get the keyboard entry, and leave the
  1652.      *    cursor at the choice, to indicate that
  1653.      *    it can be changed, until the user accepts
  1654.      *    the current choice.
  1655.      */
  1656.     term_options = FALSE;
  1657.     while (1) {
  1658.     move(line, col);
  1659.     if (term_options == FALSE) {
  1660.         response = LYgetch();
  1661.     }
  1662.     if (term_options || response == 7 || response == 3) {
  1663.          /*
  1664.           *  Control-C or Control-G.
  1665.           */
  1666.         response = '\n';
  1667.         term_options = TRUE;
  1668.         cur_choice = orig_choice;
  1669.     }
  1670. #ifdef VMS
  1671.     if (HadVMSInterrupt) {
  1672.         HadVMSInterrupt = FALSE;
  1673.         response = '\n';
  1674.         term_options = TRUE;
  1675.         cur_choice = orig_choice;
  1676.     }
  1677. #endif /* VMS */
  1678.     if ((response != '\n' && response != '\r') &&
  1679.         (cmd = keymap[response+1]) != LYK_ACTIVATE) {
  1680.         switch (cmd) {
  1681.         case LYK_HOME:
  1682.             cur_choice = 0;
  1683.             break;
  1684.  
  1685.         case LYK_END:
  1686.             cur_choice = number;
  1687.             break;
  1688.  
  1689.         case LYK_REFRESH:
  1690.             lynx_force_repaint();
  1691.             refresh();
  1692.             break;
  1693.  
  1694.         case LYK_QUIT:
  1695.         case LYK_ABORT:
  1696.         case LYK_PREV_DOC:
  1697.             cur_choice = orig_choice;
  1698.             term_options = TRUE;
  1699.             break;
  1700.  
  1701.         case LYK_PREV_PAGE:
  1702.         case LYK_UP_HALF:
  1703.         case LYK_UP_TWO:
  1704.         case LYK_PREV_LINK:
  1705.         case LYK_UP_LINK:
  1706.         case LYK_LEFT_LINK:
  1707.             if (cur_choice == 0)
  1708.             cur_choice = number;  /* go back to end */
  1709.             else
  1710.             cur_choice--;
  1711.             break;
  1712.  
  1713.         case LYK_1:
  1714.         case LYK_2:
  1715.         case LYK_3:
  1716.         case LYK_4:
  1717.         case LYK_5:
  1718.         case LYK_6:
  1719.         case LYK_7:
  1720.         case LYK_8:
  1721.         case LYK_9:
  1722.             if((cmd - LYK_1 + 1) <= number) {
  1723.             cur_choice = cmd -LYK_1 + 1;
  1724.             break;
  1725.             }  /* else fall through! */
  1726.         default:
  1727.             if (cur_choice == number)
  1728.             cur_choice = 0;  /* go over the top and around */
  1729.             else
  1730.             cur_choice++;
  1731.         }  /* end of switch */
  1732.         addstr(choices[cur_choice]);
  1733.         if (LYShowCursor)
  1734.         move(line, (col - 1));
  1735.         refresh();
  1736.     } else {
  1737.         /*
  1738.          *    Unhighlight choice.
  1739.          */
  1740.         move(line, col);
  1741.         stop_reverse();
  1742.         addstr(choices[cur_choice]);
  1743.  
  1744.         if (term_options) {
  1745.         term_options = FALSE;
  1746.         option_statusline(CANCELLED);
  1747.         sleep(InfoSecs);
  1748.         option_statusline("");
  1749.         } else {
  1750.         option_statusline(VALUE_ACCEPTED);
  1751.         }
  1752.         return(cur_choice);
  1753.     }
  1754.     }
  1755. }
  1756.  
  1757. PRIVATE void terminate_options ARGS1(
  1758.     int,        sig GCC_UNUSED)
  1759. {
  1760.     term_options = TRUE;
  1761.     /*
  1762.      *    Reassert the AST.
  1763.      */
  1764.     signal(SIGINT, terminate_options);
  1765. #ifdef VMS
  1766.     /*
  1767.      *    Refresh the screen to get rid of the "interrupt" message.
  1768.      */
  1769.     if (!dump_output_immediately) {
  1770.     lynx_force_repaint();
  1771.     refresh();
  1772.     }
  1773. #endif /* VMS */
  1774. }
  1775.  
  1776. /*
  1777.  *  Multi-Bookmark On-Line editing support. - FMG & FM
  1778.  */
  1779. PUBLIC void edit_bookmarks NOARGS
  1780. {
  1781.     int response = 0, def_response = 0, ch;
  1782.     int MBM_current = 1;
  1783. #define MULTI_OFFSET 8
  1784.     int a; /* misc counter */
  1785.     char MBM_tmp_line[256]; /* buffer for LYgetstr */
  1786.     char ehead_buffer[265];
  1787.  
  1788.     /*
  1789.      *    We need (MBM_V_MAXFILES + MULTI_OFFSET) lines to display
  1790.      *    the whole list at once.  Otherwise break it up into two
  1791.      *    segments.  We know it won't be less than that because
  1792.      *    'o'ptions needs 23-24 at LEAST.
  1793.      */
  1794.     term_options = FALSE;
  1795.     signal(SIGINT, terminate_options);
  1796.  
  1797. draw_bookmark_list:
  1798.     /*
  1799.      *    Display menu of bookmarks.  NOTE that we avoid printw()'s
  1800.      *    to increase the chances that any non-ASCII or multibyte/CJK
  1801.      *    characters will be handled properly. - FM
  1802.      */
  1803. #if defined(FANCY_CURSES) || defined (USE_SLANG)
  1804.     if (enable_scrollback) {
  1805.     clear();
  1806.     } else {
  1807.     erase();
  1808.     }
  1809. #else
  1810.     clear();
  1811. #endif /* FANCY_CURSES || USE_SLANG */
  1812.     move(0, 5);
  1813.     lynx_start_h1_color ();
  1814.     if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
  1815.     sprintf(ehead_buffer, MULTIBOOKMARKS_EHEAD_MASK, MBM_current);
  1816.     addstr(ehead_buffer);
  1817.     } else {
  1818.     addstr(MULTIBOOKMARKS_EHEAD);
  1819.     }
  1820.     lynx_stop_h1_color ();
  1821.  
  1822.     if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
  1823.     for (a = ((MBM_V_MAXFILES/2 + 1) * (MBM_current - 1));
  1824.               a <= ((float)MBM_V_MAXFILES/2 * MBM_current); a++) {
  1825.         move((3 + a) - ((MBM_V_MAXFILES/2 + 1)*(MBM_current - 1)), 5);
  1826.         addch((unsigned char)(a + 'A'));
  1827.         addstr(" : ");
  1828.         if (MBM_A_subdescript[a])
  1829.         addstr(MBM_A_subdescript[a]);
  1830.         move((3 + a) - ((MBM_V_MAXFILES/2 + 1)*(MBM_current - 1)), 35);
  1831.         addstr("| ");
  1832.         if (MBM_A_subbookmark[a]) {
  1833.         addstr(MBM_A_subbookmark[a]);
  1834.         }
  1835.     }
  1836.     } else {
  1837.     for (a = 0; a <= MBM_V_MAXFILES; a++) {
  1838.         move(3 + a, 5);
  1839.         addch((unsigned char)(a + 'A'));
  1840.         addstr(" : ");
  1841.         if (MBM_A_subdescript[a])
  1842.         addstr(MBM_A_subdescript[a]);
  1843.         move(3 + a, 35);
  1844.         addstr("| ");
  1845.         if (MBM_A_subbookmark[a]) {
  1846.         addstr(MBM_A_subbookmark[a]);
  1847.         }
  1848.     }
  1849.     }
  1850.  
  1851.     /*
  1852.      *    Only needed when we have 2 screens.
  1853.      */
  1854.     if (LYlines < MBM_V_MAXFILES + MULTI_OFFSET) {
  1855.     move((LYlines - 4), 0);
  1856.     addstr("'");
  1857.     start_bold();
  1858.     addstr("[");
  1859.     stop_bold();
  1860.     addstr("' ");
  1861.     addstr(PREVIOUS);
  1862.     addstr(", '");
  1863.     start_bold();
  1864.     addstr("]");
  1865.     stop_bold();
  1866.     addstr("' ");
  1867.     addstr(NEXT_SCREEN);
  1868.     }
  1869.  
  1870.     move((LYlines - 3), 0);
  1871.     if (!no_option_save) {
  1872.     addstr("'");
  1873.     start_bold();
  1874.     addstr(">");
  1875.     stop_bold();
  1876.     addstr("'");
  1877.     addstr(TO_SAVE_SEGMENT);
  1878.     }
  1879.     addstr(OR_SEGMENT);
  1880.     addstr("'");
  1881.     start_bold();
  1882.     addstr("^G");
  1883.     stop_bold();
  1884.     addstr("'");
  1885.     addstr(TO_RETURN_SEGMENT);
  1886.  
  1887.     while (!term_options &&
  1888.        !LYisNonAlnumKeyname(response, LYK_PREV_DOC) &&
  1889.        response != 7 && response != 3 &&
  1890.        response != '>') {
  1891.  
  1892.     move((LYlines - 2), 0);
  1893.     lynx_start_prompt_color ();
  1894.     addstr(MULTIBOOKMARKS_LETTER);
  1895.     lynx_stop_prompt_color ();
  1896.  
  1897.     refresh();
  1898.     response = (def_response ? def_response : LYgetch());
  1899.     def_response = 0;
  1900.  
  1901.     /*
  1902.      *  Check for a cancel.
  1903.      */
  1904.     if (term_options ||
  1905.         response == 7 || response == 3 ||
  1906.         LYisNonAlnumKeyname(response, LYK_PREV_DOC))
  1907.         continue;
  1908.  
  1909.     /*
  1910.      *  Check for a save.
  1911.      */
  1912.     if (response == '>') {
  1913.         if (!no_option_save) {
  1914.         option_statusline(SAVING_OPTIONS);
  1915.         if (save_rc())
  1916.             option_statusline(OPTIONS_SAVED);
  1917.         else
  1918.             HTAlert(OPTIONS_NOT_SAVED);
  1919.         } else {
  1920.         option_statusline(R_TO_RETURN_TO_LYNX);
  1921.         /*
  1922.          *  Change response so that we don't exit
  1923.          *  the options menu.
  1924.          */
  1925.         response = ' ';
  1926.         }
  1927.         continue;
  1928.     }
  1929.  
  1930.     /*
  1931.      *  Check for a refresh.
  1932.      */
  1933.     if (LYisNonAlnumKeyname(response, LYK_REFRESH)) {
  1934.         lynx_force_repaint();
  1935.         continue;
  1936.     }
  1937.  
  1938.     /*
  1939.      *  Move between the screens - if we can't show it all at once.
  1940.      */
  1941.     if ((response == ']' ||
  1942.          LYisNonAlnumKeyname(response, LYK_NEXT_PAGE)) &&
  1943.         LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
  1944.         MBM_current++;
  1945.         if (MBM_current >= 3)
  1946.         MBM_current = 1;
  1947.         goto draw_bookmark_list;
  1948.     }
  1949.     if ((response == '[' ||
  1950.          LYisNonAlnumKeyname(response, LYK_PREV_PAGE)) &&
  1951.         LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
  1952.         MBM_current--;
  1953.         if (MBM_current <= 0)
  1954.         MBM_current = 2;
  1955.         goto draw_bookmark_list;
  1956.     }
  1957.  
  1958.     /*
  1959.      *  Instead of using 26 case statements, we set up
  1960.      *  a scan through the letters and edit the lines
  1961.      *  that way.
  1962.      */
  1963.     for (a = 0; a <= MBM_V_MAXFILES; a++) {
  1964.         if ((TOUPPER(response) - 'A') == a) {
  1965.         if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
  1966.             if (MBM_current == 1 && a > (MBM_V_MAXFILES/2)) {
  1967.             MBM_current = 2;
  1968.             def_response = response;
  1969.             goto draw_bookmark_list;
  1970.             }
  1971.             if (MBM_current == 2 && a < (MBM_V_MAXFILES/2)) {
  1972.             MBM_current = 1;
  1973.             def_response = response;
  1974.             goto draw_bookmark_list;
  1975.             }
  1976.         }
  1977.         option_statusline(ACCEPT_DATA);
  1978.  
  1979.         if (a > 0) {
  1980.             start_bold();
  1981.             if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET))
  1982.             move(
  1983.              (3 + a) - ((MBM_V_MAXFILES/2 + 1)*(MBM_current - 1)),
  1984.                  9);
  1985.             else
  1986.             move((3 + a), 9);
  1987.             strcpy(MBM_tmp_line,
  1988.                (!MBM_A_subdescript[a] ?
  1989.                            "" : MBM_A_subdescript[a]));
  1990.             ch = LYgetstr(MBM_tmp_line, VISIBLE,
  1991.                   sizeof(MBM_tmp_line), NORECALL);
  1992.             stop_bold();
  1993.  
  1994.             if (strlen(MBM_tmp_line) < 1) {
  1995.             FREE(MBM_A_subdescript[a]);
  1996.             } else {
  1997.             StrAllocCopy(MBM_A_subdescript[a], MBM_tmp_line);
  1998.             }
  1999.             if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET))
  2000.             move(
  2001.              (3 + a) - ((MBM_V_MAXFILES/2 + 1)*(MBM_current - 1)),
  2002.                  5);
  2003.             else
  2004.             move((3 + a), 5);
  2005.             addch((unsigned char)(a + 'A'));
  2006.             addstr(" : ");
  2007.             if (MBM_A_subdescript[a])
  2008.             addstr(MBM_A_subdescript[a]);
  2009.             clrtoeol();
  2010.             refresh();
  2011.         }
  2012.  
  2013.         if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET))
  2014.             move((3 + a) - ((MBM_V_MAXFILES/2 + 1)*(MBM_current - 1)),
  2015.              35);
  2016.         else
  2017.             move((3 + a), 35);
  2018.         addstr("| ");
  2019.  
  2020.         start_bold();
  2021.         strcpy(MBM_tmp_line,
  2022.                (!MBM_A_subbookmark[a] ? "" : MBM_A_subbookmark[a]));
  2023.         ch = LYgetstr(MBM_tmp_line, VISIBLE,
  2024.                   sizeof(MBM_tmp_line), NORECALL);
  2025.         stop_bold();
  2026.  
  2027.         if (*MBM_tmp_line == '\0') {
  2028.             if (a == 0)
  2029.             StrAllocCopy(MBM_A_subbookmark[a], bookmark_page);
  2030.             else
  2031.             FREE(MBM_A_subbookmark[a]);
  2032.         } else if (!LYPathOffHomeOK(MBM_tmp_line,
  2033.                         sizeof(MBM_tmp_line))) {
  2034.             LYMBM_statusline(USE_PATH_OFF_HOME);
  2035.             sleep(AlertSecs);
  2036.         } else {
  2037.             StrAllocCopy(MBM_A_subbookmark[a], MBM_tmp_line);
  2038.             if (a == 0) {
  2039.             StrAllocCopy(bookmark_page, MBM_A_subbookmark[a]);
  2040.             }
  2041.         }
  2042.         if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET))
  2043.             move((3 + a) - ((MBM_V_MAXFILES/2 + 1)*(MBM_current-1)),
  2044.              35);
  2045.         else
  2046.             move((3 + a), 35);
  2047.         addstr("| ");
  2048.         if (MBM_A_subbookmark[a])
  2049.             addstr(MBM_A_subbookmark[a]);
  2050.         clrtoeol();
  2051.         move(LYlines-1, 0);
  2052.         clrtoeol();
  2053.         break;
  2054.         }
  2055.     }  /* end for */
  2056.     } /* end while */
  2057.  
  2058.     term_options = FALSE;
  2059.     signal(SIGINT, cleanup_sig);
  2060. }
  2061.  
  2062. /*
  2063. **  This function prompts for a choice or page number.
  2064. **  If a 'g' or 'p' suffix is included, that will be
  2065. **  loaded into c.  Otherwise, c is zeroed. - FM
  2066. */
  2067. PRIVATE int get_popup_choice_number ARGS1(
  2068.     int *,        c)
  2069. {
  2070.     char temp[120];
  2071.  
  2072.     /*
  2073.      *    Load the c argument into the prompt buffer.
  2074.      */
  2075.     temp[0] = *c;
  2076.     temp[1] = '\0';
  2077.     option_statusline(OPTION_CHOICE_NUMBER);
  2078.  
  2079.     /*
  2080.      *    Get the number, possibly with a suffix, from the user.
  2081.      */
  2082.     if (LYgetstr(temp, VISIBLE, sizeof(temp), NORECALL) < 0 ||
  2083.     *temp == 0 || term_options) {
  2084.     option_statusline(CANCELLED);
  2085.     sleep(InfoSecs);
  2086.     *c = '\0';
  2087.     term_options = FALSE;
  2088.     return(0);
  2089.     }
  2090.  
  2091.     /*
  2092.      *    If we had a 'g' or 'p' suffix, load it into c.
  2093.      *    Otherwise, zero c.  Then return the number.
  2094.      */
  2095.     if (strchr(temp, 'g') != NULL || strchr(temp, 'G') != NULL) {
  2096.     *c = 'g';
  2097.     } else if (strchr(temp, 'p') != NULL || strchr(temp, 'P') != NULL) {
  2098.     *c = 'p';
  2099.     } else {
  2100.     *c = '\0';
  2101.     }
  2102.     return(atoi(temp));
  2103. }
  2104.  
  2105. /*
  2106.  *  This function offers the choices for values of an
  2107.  *  option via a popup window which functions like
  2108.  *  that for selection of options in a form. - FM
  2109.  */
  2110. PRIVATE int popup_choice ARGS6(
  2111.     int,        cur_choice,
  2112.     int,        line,
  2113.     int,        column,
  2114.     char **,    choices,
  2115.     int,        i_length,
  2116.     int,        disabled)
  2117. {
  2118.     int ly = line;
  2119.     int lx = (column >= 0 ? column : (COL_OPTION_VALUES - 1));
  2120.     int c = 0, cmd = 0, i = 0, j = 0;
  2121.     int orig_choice = cur_choice;
  2122. #ifndef USE_SLANG
  2123.     WINDOW * form_window;
  2124. #endif /* !USE_SLANG */
  2125.     int num_choices = 0, top, bottom, length = -1, width = 0;
  2126.     char ** Cptr = choices;
  2127.     int window_offset = 0;
  2128.     int DisplayLines = (LYlines - 2);
  2129.     char Cnum[64];
  2130.     int Lnum;
  2131.     int npages;
  2132. #ifdef VMS
  2133.     extern BOOLEAN HadVMSInterrupt; /* Flag from cleanup_sig() AST */
  2134. #endif /* VMS */
  2135.     static char prev_target[512];        /* Search string buffer */
  2136.     static char prev_target_buffer[512];    /* Next search buffer */
  2137.     static BOOL first = TRUE;
  2138.     char *cp;
  2139.     int ch = 0, recall;
  2140.     int QueryTotal;
  2141.     int QueryNum;
  2142.     BOOLEAN FirstRecall = TRUE;
  2143.     BOOLEAN ReDraw = FALSE;
  2144.     int number;
  2145.     char buffer[512];
  2146.  
  2147.     /*
  2148.      * Initialize the search string buffer. - FM
  2149.      */
  2150.     if (first) {
  2151.     *prev_target_buffer = '\0';
  2152.     first = FALSE;
  2153.     }
  2154.     *prev_target = '\0';
  2155.     QueryTotal = (search_queries ? HTList_count(search_queries) : 0);
  2156.     recall = ((QueryTotal >= 1) ? RECALL : NORECALL);
  2157.     QueryNum = QueryTotal;
  2158.  
  2159.     /*
  2160.      *    Count the number of choices to be displayed, where
  2161.      *    num_choices ranges from 0 to n, and set width to the
  2162.      *    longest choice string length.  Also set Lnum to the
  2163.      *    length for the highest choice number, then decrement
  2164.      *    num_choices so as to be zero-based.  The window width
  2165.      *    will be based on the sum of width and Lnum. - FM
  2166.      */
  2167.     for (num_choices = 0; Cptr[num_choices] != NULL; num_choices++) {
  2168.     if (strlen(Cptr[num_choices]) > width) {
  2169.         width = strlen(Cptr[num_choices]);
  2170.     }
  2171.     }
  2172.     sprintf(Cnum, "%d: ", num_choices);
  2173.     Lnum = strlen(Cnum);
  2174.     num_choices--;
  2175.  
  2176.     /*
  2177.      *    Let's assume for the sake of sanity that ly is the number
  2178.      *     corresponding to the line the option is on.
  2179.      *    Let's also assume that cur_choice is the number of the
  2180.      *     choice that should be initially selected, with 0 being
  2181.      *     the first choice.
  2182.      *    So what we have, is the top equal to the current screen line
  2183.      *     subtracting the cur_choice + 1 (the one must be for the top
  2184.      *     line we will draw in a box).  If the top goes under 0, then
  2185.      *     consider it 0.
  2186.      */
  2187.     top = ly - (cur_choice + 1);
  2188.     if (top < 0)
  2189.     top = 0;
  2190.  
  2191.     /*
  2192.      *    Check and see if we need to put the i_length parameter up to
  2193.      *    the number of real choices.
  2194.      */
  2195.     if (i_length < 1) {
  2196.     i_length = num_choices;
  2197.     } else {
  2198.     /*
  2199.      *  Otherwise, it is really one number too high.
  2200.      */
  2201.     i_length--;
  2202.     }
  2203.  
  2204.     /*
  2205.      *    The bottom is the value of the top plus the number of choices
  2206.      *    to view plus 3 (one for the top line, one for the bottom line,
  2207.      *    and one to offset the 0 counted in the num_choices).
  2208.      */
  2209.     bottom = top + i_length + 3;
  2210.  
  2211.     /*
  2212.      *    Hmm...    If the bottom goes beyond the number of lines available,
  2213.      */
  2214.     if (bottom > DisplayLines) {
  2215.     /*
  2216.      *  Position the window at the top if we have more
  2217.      *  choices than will fit in the window.
  2218.      */
  2219.     if ((i_length + 3) > DisplayLines) {
  2220.         top = 0;
  2221.         bottom = (top + (i_length + 3));
  2222.         if (bottom > DisplayLines)
  2223.         bottom = (DisplayLines + 1);
  2224.     } else {
  2225.         /*
  2226.          *    Try to position the window so that the selected choice will
  2227.          *      appear where the choice box currently is positioned.
  2228.          *    It could end up too high, at this point, but we'll move it
  2229.          *      down latter, if that has happened.
  2230.          */
  2231.         top = (DisplayLines + 1) - (i_length + 3);
  2232.         bottom = (DisplayLines + 1);
  2233.     }
  2234.     }
  2235.  
  2236.     /*
  2237.      *    This is really fun, when the length is 4, it means 0 to 4, or 5.
  2238.      */
  2239.     length = (bottom - top) - 2;
  2240.  
  2241.     /*
  2242.      *    Move the window down if it's too high.
  2243.      */
  2244.     if (bottom < ly + 2) {
  2245.     bottom = ly + 2;
  2246.     if (bottom > DisplayLines + 1)
  2247.         bottom = DisplayLines + 1;
  2248.     top = bottom - length - 2;
  2249.     }
  2250.  
  2251.     /*
  2252.      *    Set up the overall window, including the boxing characters ('*'),
  2253.      *    if it all fits.  Otherwise, set up the widest window possible. - FM
  2254.      */
  2255. #ifdef USE_SLANG
  2256.     SLsmg_fill_region(top, lx - 1, bottom - top, (Lnum + width + 4), ' ');
  2257. #else
  2258.     if (!(form_window = newwin(bottom - top, (Lnum + width + 4),
  2259.                    top, (lx - 1))) &&
  2260.     !(form_window = newwin(bottom - top, 0, top, 0))) {
  2261.     option_statusline(POPUP_FAILED);
  2262.     return(orig_choice);
  2263.     }
  2264.     scrollok(form_window, TRUE);
  2265. #ifdef PDCURSES
  2266.     keypad(form_window, TRUE);
  2267. #endif /* PDCURSES */
  2268. #ifdef NCURSES
  2269.     LYsubwindow(form_window);
  2270. #endif
  2271. #if defined(HAVE_GETBKGD) /* not defined in ncurses 1.8.7 */
  2272.     wbkgd(form_window, getbkgd(stdscr));
  2273.     wbkgdset(form_window, getbkgd(stdscr));
  2274. #endif
  2275. #endif /* USE_SLANG */
  2276.  
  2277.     /*
  2278.      *    Clear the command line and write
  2279.      *    the popup statusline. - FM
  2280.      */
  2281.     move((LYlines - 2), 0);
  2282.     clrtoeol();
  2283.     if (disabled) {
  2284.     option_statusline(CHOICE_LIST_UNM_MSG);
  2285.     } else {
  2286.     option_statusline(CHOICE_LIST_MESSAGE);
  2287.     }
  2288.  
  2289.     /*
  2290.      *    Set up the window_offset for choices.
  2291.      *     cur_choice ranges from 0...n
  2292.      *     length ranges from 0...m
  2293.      */
  2294.     if (cur_choice >= length) {
  2295.     window_offset = cur_choice - length + 1;
  2296.     }
  2297.  
  2298.     /*
  2299.      *    Compute the number of popup window pages. - FM
  2300.      */
  2301.     npages = ((num_choices + 1) > length) ?
  2302.         (((num_choices + 1) + (length - 1))/(length))
  2303.                       : 1;
  2304. /*
  2305.  *  OH!  I LOVE GOTOs! hack hack hack
  2306.  */
  2307. redraw:
  2308.     Cptr = choices;
  2309.  
  2310.     /*
  2311.      *    Display the boxed choices.
  2312.      */
  2313.     for (i = 0; i <= num_choices; i++) {
  2314.     if (i >= window_offset && i - window_offset < length) {
  2315.         sprintf(Cnum, "%s%d: ",
  2316.                ((num_choices > 8 && i < 9) ?
  2317.                            " " : ""),
  2318.                (i + 1));
  2319. #ifdef USE_SLANG
  2320.         SLsmg_gotorc(top + ((i + 1) - window_offset), (lx - 1 + 2));
  2321.         addstr(Cnum);
  2322.         SLsmg_write_nstring(Cptr[i], width);
  2323. #else
  2324.         wmove(form_window, ((i + 1) - window_offset), 2);
  2325.         wclrtoeol(form_window);
  2326.         waddstr(form_window, Cnum);
  2327.         waddstr(form_window, Cptr[i]);
  2328. #endif /* USE_SLANG */
  2329.     }
  2330.     }
  2331. #ifdef USE_SLANG
  2332.     SLsmg_draw_box(top, (lx - 1), (bottom - top), (Lnum + width + 4));
  2333. #else
  2334. #ifdef VMS
  2335.     VMSbox(form_window, (bottom - top), (Lnum + width + 4));
  2336. #else
  2337.     LYbox(form_window, FALSE);
  2338. #endif /* VMS */
  2339.     wrefresh(form_window);
  2340. #endif /* USE_SLANG */
  2341.     Cptr = NULL;
  2342.  
  2343.     /*
  2344.      *    Loop on user input.
  2345.      */
  2346.     while (cmd != LYK_ACTIVATE) {
  2347.     /*
  2348.      *  Unreverse cur choice.
  2349.      */
  2350.     if (Cptr != NULL) {
  2351.         sprintf(Cnum, "%s%d: ",
  2352.               ((num_choices > 8 && i < 9) ?
  2353.                           " " : ""),
  2354.               (i + 1));
  2355. #ifdef USE_SLANG
  2356.         SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 2));
  2357.         addstr(Cnum);
  2358.         SLsmg_write_nstring(Cptr[i], width);
  2359. #else
  2360.         wmove(form_window, ((i + 1) - window_offset), 2);
  2361.         waddstr(form_window, Cnum);
  2362.         waddstr(form_window, Cptr[i]);
  2363. #endif /* USE_SLANG */
  2364.     }
  2365.     Cptr = choices;
  2366.     i = cur_choice;
  2367.     sprintf(Cnum, "%s%d: ",
  2368.               ((num_choices > 8 && i < 9) ?
  2369.                           " " : ""),
  2370.               (i + 1));
  2371. #ifdef USE_SLANG
  2372.     SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 2));
  2373.     addstr(Cnum);
  2374.     SLsmg_set_color(2);
  2375.     SLsmg_write_nstring(Cptr[i], width);
  2376.     SLsmg_set_color(0);
  2377.     /*
  2378.      *  If LYShowCursor is ON, move the cursor to the left
  2379.      *  of the current choice, so that blind users, who are
  2380.      *  most likely to have LYShowCursor ON, will have it's
  2381.      *  string spoken or passed to the braille interface as
  2382.      *  each choice is made current.  Otherwise, move it to
  2383.      *  the bottom, right column of the screen, to "hide"
  2384.      *  the cursor as for the main document, and let sighted
  2385.      *  users rely on the current choice's highlighting or
  2386.      *  color without the distraction of a blinking cursor
  2387.      *  in the window. - FM
  2388.      */
  2389.     if (LYShowCursor)
  2390.         SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 1));
  2391.     else
  2392.         SLsmg_gotorc((LYlines - 1), (LYcols - 1));
  2393.     SLsmg_refresh();
  2394. #else
  2395.     wmove(form_window, ((i + 1) - window_offset), 2);
  2396.     waddstr(form_window, Cnum);
  2397.     wstart_reverse(form_window);
  2398.     waddstr(form_window, Cptr[i]);
  2399.     wstop_reverse(form_window);
  2400.     /*
  2401.      *  If LYShowCursor is ON, move the cursor to the left
  2402.      *  of the current choice, so that blind users, who are
  2403.      *  most likely to have LYShowCursor ON, will have it's
  2404.      *  string spoken or passed to the braille interface as
  2405.      *  each choice is made current.  Otherwise, leave it to
  2406.      *  the right of the current choice, since we can't move
  2407.      *  it out of the window, and let sighted users rely on
  2408.      *  the highlighting of the current choice without the
  2409.      *  distraction of a blinking cursor preceding it. - FM
  2410.      */
  2411.     if (LYShowCursor)
  2412.         wmove(form_window, ((i + 1) - window_offset), 1);
  2413.     wrefresh(form_window);
  2414. #endif /* USE_SLANG  */
  2415.  
  2416.     term_options = FALSE;
  2417.     c = LYgetch();
  2418.     if (term_options || c == 3 || c == 7) {
  2419.          /*
  2420.           *  Control-C or Control-G
  2421.           */
  2422.         cmd = LYK_QUIT;
  2423.     } else {
  2424.         cmd = keymap[c+1];
  2425.     }
  2426. #ifdef VMS
  2427.     if (HadVMSInterrupt) {
  2428.         HadVMSInterrupt = FALSE;
  2429.         cmd = LYK_QUIT;
  2430.     }
  2431. #endif /* VMS */
  2432.  
  2433.     switch(cmd) {
  2434.         case LYK_F_LINK_NUM:
  2435.         c = '\0';
  2436.         case LYK_1:
  2437.         case LYK_2:
  2438.         case LYK_3:
  2439.         case LYK_4:
  2440.         case LYK_5:
  2441.         case LYK_6:
  2442.         case LYK_7:
  2443.         case LYK_8:
  2444.         case LYK_9:
  2445.         /*
  2446.          *  Get a number from the user, possibly with
  2447.          *  a 'g' or 'p' suffix (which will be loaded
  2448.          *  into c). - FM & LE
  2449.          */
  2450.         number = get_popup_choice_number((int *)&c);
  2451.  
  2452.         /*
  2453.          *  Check for a 'p' suffix. - FM
  2454.          */
  2455.         if (c == 'p') {
  2456.             /*
  2457.              *    Treat 1 or less as the first page. - FM
  2458.              */
  2459.             if (number <= 1) {
  2460.             if (window_offset == 0) {
  2461.                 option_statusline(ALREADY_AT_CHOICE_BEGIN);
  2462.                 sleep(MessageSecs);
  2463.                 if (disabled) {
  2464.                 option_statusline(CHOICE_LIST_UNM_MSG);
  2465.                 } else {
  2466.                 option_statusline(CHOICE_LIST_MESSAGE);
  2467.                 }
  2468.                 break;
  2469.             }
  2470.             window_offset = 0;
  2471.             cur_choice = 0;
  2472.             if (disabled) {
  2473.                 option_statusline(CHOICE_LIST_UNM_MSG);
  2474.             } else {
  2475.                 option_statusline(CHOICE_LIST_MESSAGE);
  2476.             }
  2477.             goto redraw;
  2478.             }
  2479.  
  2480.             /*
  2481.              *    Treat a number equal to or greater than the
  2482.              *    number of pages as the last page. - FM
  2483.              */
  2484.             if (number >= npages) {
  2485.             if (window_offset >= ((num_choices - length) + 1)) {
  2486.                 option_statusline(ALREADY_AT_CHOICE_END);
  2487.                 sleep(MessageSecs);
  2488.                 if (disabled) {
  2489.                 option_statusline(CHOICE_LIST_UNM_MSG);
  2490.                 } else {
  2491.                 option_statusline(CHOICE_LIST_MESSAGE);
  2492.                 }
  2493.                 break;
  2494.             }
  2495.             window_offset = ((npages - 1) * length);
  2496.             if (window_offset > (num_choices - length)) {
  2497.                 window_offset = (num_choices - length + 1);
  2498.             }
  2499.             if (cur_choice < window_offset)
  2500.                 cur_choice = window_offset;
  2501.             if (disabled) {
  2502.                 option_statusline(CHOICE_LIST_UNM_MSG);
  2503.             } else {
  2504.                 option_statusline(CHOICE_LIST_MESSAGE);
  2505.             }
  2506.             goto redraw;
  2507.             }
  2508.  
  2509.             /*
  2510.              *    We want an intermediate page. - FM
  2511.              */
  2512.             if (((number - 1) * length) == window_offset) {
  2513.             sprintf(buffer, ALREADY_AT_CHOICE_PAGE, number);
  2514.             option_statusline(buffer);
  2515.             sleep(MessageSecs);
  2516.             if (disabled) {
  2517.                 option_statusline(CHOICE_LIST_UNM_MSG);
  2518.             } else {
  2519.                 option_statusline(CHOICE_LIST_MESSAGE);
  2520.             }
  2521.             break;
  2522.             }
  2523.             cur_choice = window_offset = ((number - 1) * length);
  2524.             if (disabled) {
  2525.             option_statusline(CHOICE_LIST_UNM_MSG);
  2526.             } else {
  2527.             option_statusline(CHOICE_LIST_MESSAGE);
  2528.             }
  2529.             goto redraw;
  2530.  
  2531.         }
  2532.  
  2533.         /*
  2534.          *  Check for a positive number, which signifies
  2535.          *  that a choice should be sought. - FM
  2536.          */
  2537.         if (number > 0) {
  2538.             /*
  2539.              *    Decrement the number so as to correspond
  2540.              *    with our cur_choice values. - FM
  2541.              */
  2542.             number--;
  2543.  
  2544.             /*
  2545.              *    If the number is in range and had no legal
  2546.              *    suffix, select the indicated choice. - FM
  2547.              */
  2548.             if (number <= num_choices && c == '\0') {
  2549.             cur_choice = number;
  2550.             cmd = LYK_ACTIVATE;
  2551.             break;
  2552.             }
  2553.  
  2554.             /*
  2555.              *    Verify that we had a 'g' suffix,
  2556.              *    and act on the number. - FM
  2557.              */
  2558.             if (c == 'g') {
  2559.             if (cur_choice == number) {
  2560.                 /*
  2561.                  *    The choice already is current. - FM
  2562.                  */
  2563.                 sprintf(buffer,
  2564.                     CHOICE_ALREADY_CURRENT, (number + 1));
  2565.                 option_statusline(buffer);
  2566.                 sleep(MessageSecs);
  2567.                 if (disabled) {
  2568.                 option_statusline(CHOICE_LIST_UNM_MSG);
  2569.                 } else {
  2570.                 option_statusline(CHOICE_LIST_MESSAGE);
  2571.                 }
  2572.                 break;
  2573.             }
  2574.  
  2575.             if (number <= num_choices) {
  2576.                 /*
  2577.                  *    The number is in range and had a 'g'
  2578.                  *    suffix, so make it the current choice,
  2579.                  *    scrolling if needed. - FM
  2580.                  */
  2581.                 j = (number - cur_choice);
  2582.                 cur_choice = number;
  2583.                 if ((j > 0) &&
  2584.                 (cur_choice - window_offset) >= length) {
  2585.                 window_offset += j;
  2586.                 if (window_offset > (num_choices - length + 1))
  2587.                     window_offset = (num_choices - length + 1);
  2588.                 } else if ((cur_choice - window_offset) < 0) {
  2589.                 window_offset -= abs(j);
  2590.                 if (window_offset < 0)
  2591.                     window_offset = 0;
  2592.                 }
  2593.                 if (disabled) {
  2594.                 option_statusline(CHOICE_LIST_UNM_MSG);
  2595.                 } else {
  2596.                 option_statusline(CHOICE_LIST_MESSAGE);
  2597.                 }
  2598.                 goto redraw;
  2599.             }
  2600.  
  2601.             /*
  2602.              *  Not in range. - FM
  2603.              */
  2604.             option_statusline(BAD_CHOICE_NUM_ENTERED);
  2605.             sleep(MessageSecs);
  2606.             }
  2607.         }
  2608.  
  2609.         /*
  2610.          *  Restore the popup statusline. - FM
  2611.          */
  2612.         if (disabled) {
  2613.             option_statusline(CHOICE_LIST_UNM_MSG);
  2614.         } else {
  2615.             option_statusline(CHOICE_LIST_MESSAGE);
  2616.         }
  2617.         break;
  2618.  
  2619.         case LYK_PREV_LINK:
  2620.         case LYK_UP_LINK:
  2621.  
  2622.         if (cur_choice > 0)
  2623.             cur_choice--;
  2624.  
  2625.         /*
  2626.          *  Scroll the window up if necessary.
  2627.          */
  2628.         if ((cur_choice - window_offset) < 0) {
  2629.             window_offset--;
  2630.             goto redraw;
  2631.         }
  2632.         break;
  2633.  
  2634.         case LYK_NEXT_LINK:
  2635.         case LYK_DOWN_LINK:
  2636.         if (cur_choice < num_choices)
  2637.             cur_choice++;
  2638.  
  2639.         /*
  2640.          *  Scroll the window down if necessary
  2641.          */
  2642.         if ((cur_choice - window_offset) >= length) {
  2643.             window_offset++;
  2644.             goto redraw;
  2645.         }
  2646.         break;
  2647.  
  2648.         case LYK_NEXT_PAGE:
  2649.         /*
  2650.          *  Okay, are we on the last page of the choices list?
  2651.          *  If not then,
  2652.          */
  2653.         if (window_offset != (num_choices - length + 1)) {
  2654.             /*
  2655.              *    Modify the current choice to not be a
  2656.              *    coordinate in the list, but a coordinate
  2657.              *    on the item selected in the window.
  2658.              */
  2659.             cur_choice -= window_offset;
  2660.  
  2661.             /*
  2662.              *    Page down the proper length for the list.
  2663.              *    If simply to far, back up.
  2664.              */
  2665.             window_offset += length;
  2666.             if (window_offset > (num_choices - length)) {
  2667.             window_offset = (num_choices - length + 1);
  2668.             }
  2669.  
  2670.             /*
  2671.              *    Readjust the current choice to be a choice
  2672.              *    list coordinate rather than window.
  2673.              *    Redraw this thing.
  2674.              */
  2675.             cur_choice += window_offset;
  2676.             goto redraw;
  2677.         }
  2678.         else if (cur_choice < num_choices) {
  2679.             /*
  2680.              *    Already on last page of the choice list so
  2681.              *    just redraw it with the last item selected.
  2682.              */
  2683.             cur_choice = num_choices;
  2684.         }
  2685.         break;
  2686.  
  2687.         case LYK_PREV_PAGE:
  2688.         /*
  2689.          *  Are we on the first page of the choice list?
  2690.          *  If not then,
  2691.          */
  2692.         if (window_offset != 0) {
  2693.             /*
  2694.              *    Modify the current choice to not be a choice
  2695.              *    list coordinate, but a window coordinate.
  2696.              */
  2697.             cur_choice -= window_offset;
  2698.  
  2699.             /*
  2700.              *    Page up the proper length.
  2701.              *    If too far, back up.
  2702.              */
  2703.             window_offset -= length;
  2704.             if (window_offset < 0) {
  2705.             window_offset = 0;
  2706.             }
  2707.  
  2708.             /*
  2709.              *    Readjust the current choice.
  2710.              */
  2711.             cur_choice += window_offset;
  2712.             goto redraw;
  2713.         } else if (cur_choice > 0) {
  2714.             /*
  2715.              *    Already on the first page so just
  2716.              *    back up to the first item.
  2717.              */
  2718.             cur_choice = 0;
  2719.         }
  2720.         break;
  2721.  
  2722.         case LYK_HOME:
  2723.         cur_choice = 0;
  2724.         if (window_offset > 0) {
  2725.             window_offset = 0;
  2726.             goto redraw;
  2727.         }
  2728.         break;
  2729.  
  2730.         case LYK_END:
  2731.         cur_choice = num_choices;
  2732.         if (window_offset != (num_choices - length + 1)) {
  2733.             window_offset = (num_choices - length + 1);
  2734.             goto redraw;
  2735.         }
  2736.         break;
  2737.  
  2738.         case LYK_DOWN_TWO:
  2739.         cur_choice += 2;
  2740.         if (cur_choice > num_choices)
  2741.             cur_choice = num_choices;
  2742.  
  2743.         /*
  2744.          *  Scroll the window down if necessary.
  2745.          */
  2746.         if ((cur_choice - window_offset) >= length) {
  2747.             window_offset += 2;
  2748.             if (window_offset > (num_choices - length + 1))
  2749.             window_offset = (num_choices - length + 1);
  2750.             goto redraw;
  2751.         }
  2752.         break;
  2753.  
  2754.         case LYK_UP_TWO:
  2755.         cur_choice -= 2;
  2756.         if (cur_choice < 0)
  2757.             cur_choice = 0;
  2758.  
  2759.         /*
  2760.          *  Scroll the window up if necessary.
  2761.          */
  2762.         if ((cur_choice - window_offset) < 0) {
  2763.             window_offset -= 2;
  2764.             if (window_offset < 0)
  2765.             window_offset = 0;
  2766.             goto redraw;
  2767.         }
  2768.         break;
  2769.  
  2770.         case LYK_DOWN_HALF:
  2771.         cur_choice += (length/2);
  2772.         if (cur_choice > num_choices)
  2773.             cur_choice = num_choices;
  2774.  
  2775.         /*
  2776.          *  Scroll the window down if necessary.
  2777.          */
  2778.         if ((cur_choice - window_offset) >= length) {
  2779.             window_offset += (length/2);
  2780.             if (window_offset > (num_choices - length + 1))
  2781.             window_offset = (num_choices - length + 1);
  2782.             goto redraw;
  2783.         }
  2784.         break;
  2785.  
  2786.         case LYK_UP_HALF:
  2787.         cur_choice -= (length/2);
  2788.         if (cur_choice < 0)
  2789.             cur_choice = 0;
  2790.  
  2791.         /*
  2792.          *  Scroll the window up if necessary.
  2793.          */
  2794.         if ((cur_choice - window_offset) < 0) {
  2795.             window_offset -= (length/2);
  2796.             if (window_offset < 0)
  2797.             window_offset = 0;
  2798.             goto redraw;
  2799.         }
  2800.         break;
  2801.  
  2802.         case LYK_REFRESH:
  2803.         lynx_force_repaint();
  2804.         refresh();
  2805.         break;
  2806.  
  2807.         case LYK_NEXT:
  2808.         if (recall && *prev_target_buffer == '\0') {
  2809.             /*
  2810.              *    We got a 'n'ext command with no prior query
  2811.              *    specified within the popup window.  See if
  2812.              *    one was entered when the popup was retracted,
  2813.              *    and if so, assume that's what's wanted.  Note
  2814.              *    that it will become the default within popups,
  2815.              *    unless another is entered within a popup.  If
  2816.              *    the within popup default is to be changed at
  2817.              *    that point, use WHEREIS ('/') and enter it,
  2818.              *    or the up- or down-arrow keys to seek any of
  2819.              *    the previously entered queries, regardless of
  2820.              *    whether they were entered within or outside
  2821.              *    of a popup window. - FM
  2822.              */
  2823.             if ((cp = (char *)HTList_objectAt(search_queries,
  2824.                               0)) != NULL) {
  2825.             strcpy(prev_target_buffer, cp);
  2826.             QueryNum = 0;
  2827.             FirstRecall = FALSE;
  2828.             }
  2829.         }
  2830.         strcpy(prev_target, prev_target_buffer);
  2831.         case LYK_WHEREIS:
  2832.         if (*prev_target == '\0' ) {
  2833.             option_statusline(ENTER_WHEREIS_QUERY);
  2834.             if ((ch = LYgetstr(prev_target, VISIBLE,
  2835.                        sizeof(prev_target_buffer),
  2836.                        recall)) < 0) {
  2837.             /*
  2838.              *  User cancelled the search via ^G. - FM
  2839.              */
  2840.             option_statusline(CANCELLED);
  2841.             sleep(InfoSecs);
  2842.             goto restore_popup_statusline;
  2843.             }
  2844.         }
  2845.  
  2846. check_recall:
  2847.         if (*prev_target == '\0' &&
  2848.             !(recall && (ch == UPARROW || ch == DNARROW))) {
  2849.             /*
  2850.              *    No entry.  Simply break.   - FM
  2851.              */
  2852.             option_statusline(CANCELLED);
  2853.             sleep(InfoSecs);
  2854.             goto restore_popup_statusline;
  2855.         }
  2856.  
  2857.         if (recall && ch == UPARROW) {
  2858.             if (FirstRecall) {
  2859.             /*
  2860.              *  Use the current string or
  2861.              *  last query in the list. - FM
  2862.              */
  2863.             FirstRecall = FALSE;
  2864.             if (*prev_target_buffer) {
  2865.                 for (QueryNum = (QueryTotal - 1);
  2866.                  QueryNum > 0; QueryNum--) {
  2867.                 if ((cp = (char *)HTList_objectAt(
  2868.                             search_queries,
  2869.                             QueryNum)) != NULL &&
  2870.                     !strcmp(prev_target_buffer, cp)) {
  2871.                     break;
  2872.                 }
  2873.                 }
  2874.             } else {
  2875.                 QueryNum = 0;
  2876.             }
  2877.             } else {
  2878.             /*
  2879.              *  Go back to the previous query in the list. - FM
  2880.              */
  2881.             QueryNum++;
  2882.             }
  2883.             if (QueryNum >= QueryTotal)
  2884.             /*
  2885.              *  Roll around to the last query in the list. - FM
  2886.              */
  2887.             QueryNum = 0;
  2888.             if ((cp = (char *)HTList_objectAt(search_queries,
  2889.                               QueryNum)) != NULL) {
  2890.             strcpy(prev_target, cp);
  2891.             if (*prev_target_buffer &&
  2892.                 !strcmp(prev_target_buffer, prev_target)) {
  2893.                 option_statusline(EDIT_CURRENT_QUERY);
  2894.             } else if ((*prev_target_buffer && QueryTotal == 2) ||
  2895.                    (!(*prev_target_buffer) &&
  2896.                       QueryTotal == 1)) {
  2897.                 option_statusline(EDIT_THE_PREV_QUERY);
  2898.             } else {
  2899.                 option_statusline(EDIT_A_PREV_QUERY);
  2900.             }
  2901.             if ((ch = LYgetstr(prev_target, VISIBLE,
  2902.                 sizeof(prev_target_buffer), recall)) < 0) {
  2903.                 /*
  2904.                  *    User cancelled the search via ^G. - FM
  2905.                  */
  2906.                 option_statusline(CANCELLED);
  2907.                 sleep(InfoSecs);
  2908.                 goto restore_popup_statusline;
  2909.             }
  2910.             goto check_recall;
  2911.             }
  2912.         } else if (recall && ch == DNARROW) {
  2913.             if (FirstRecall) {
  2914.             /*
  2915.              *    Use the current string or
  2916.              *    first query in the list. - FM
  2917.              */
  2918.             FirstRecall = FALSE;
  2919.             if (*prev_target_buffer) {
  2920.             for (QueryNum = 0;
  2921.                  QueryNum < (QueryTotal - 1); QueryNum++) {
  2922.                 if ((cp = (char *)HTList_objectAt(
  2923.                             search_queries,
  2924.                             QueryNum)) != NULL &&
  2925.                 !strcmp(prev_target_buffer, cp)) {
  2926.                     break;
  2927.                 }
  2928.             }
  2929.             } else {
  2930.             QueryNum = (QueryTotal - 1);
  2931.             }
  2932.         } else {
  2933.             /*
  2934.              *    Advance to the next query in the list. - FM
  2935.              */
  2936.             QueryNum--;
  2937.         }
  2938.         if (QueryNum < 0)
  2939.             /*
  2940.              *    Roll around to the first query in the list. - FM
  2941.              */
  2942.             QueryNum = (QueryTotal - 1);
  2943.             if ((cp = (char *)HTList_objectAt(search_queries,
  2944.                               QueryNum)) != NULL) {
  2945.             strcpy(prev_target, cp);
  2946.             if (*prev_target_buffer &&
  2947.                 !strcmp(prev_target_buffer, prev_target)) {
  2948.                 option_statusline(EDIT_CURRENT_QUERY);
  2949.             } else if ((*prev_target_buffer &&
  2950.                     QueryTotal == 2) ||
  2951.                    (!(*prev_target_buffer) &&
  2952.                     QueryTotal == 1)) {
  2953.                 option_statusline(EDIT_THE_PREV_QUERY);
  2954.             } else {
  2955.                 option_statusline(EDIT_A_PREV_QUERY);
  2956.             }
  2957.             if ((ch = LYgetstr(prev_target, VISIBLE,
  2958.                        sizeof(prev_target_buffer),
  2959.                        recall)) < 0) {
  2960.                 /*
  2961.                  * User cancelled the search via ^G. - FM
  2962.                  */
  2963.                 option_statusline(CANCELLED);
  2964.                 sleep(InfoSecs);
  2965.                 goto restore_popup_statusline;
  2966.             }
  2967.             goto check_recall;
  2968.             }
  2969.         }
  2970.         /*
  2971.          *  Replace the search string buffer with the new target. - FM
  2972.          */
  2973.         strcpy(prev_target_buffer, prev_target);
  2974.         HTAddSearchQuery(prev_target_buffer);
  2975.  
  2976.         /*
  2977.          *  Start search at the next choice. - FM
  2978.          */
  2979.         for (j = 1; Cptr[i+j] != NULL; j++) {
  2980.             sprintf(buffer, "%s%d: %s",
  2981.                     ((num_choices > 8 && (j + i) < 9) ?
  2982.                                   " " : ""),
  2983.                     (i + j + 1),
  2984.                     Cptr[i+j]);
  2985.             if (case_sensitive) {
  2986.             if (strstr(buffer, prev_target_buffer) != NULL)
  2987.                 break;
  2988.             } else {
  2989.             if (LYstrstr(buffer, prev_target_buffer) != NULL)
  2990.                 break;
  2991.             }
  2992.         }
  2993.         if (Cptr[i+j] != NULL) {
  2994.             /*
  2995.              *    We have a hit, so make that choice the current. - FM
  2996.              */
  2997.             cur_choice += j;
  2998.             /*
  2999.              *    Scroll the window down if necessary.
  3000.              */
  3001.             if ((cur_choice - window_offset) >= length) {
  3002.             window_offset += j;
  3003.             if (window_offset > (num_choices - length + 1))
  3004.                 window_offset = (num_choices - length + 1);
  3005.             ReDraw = TRUE;
  3006.             }
  3007.             goto restore_popup_statusline;
  3008.         }
  3009.  
  3010.         /*
  3011.          *  If we started at the beginning, it can't be present. - FM
  3012.          */
  3013.         if (cur_choice == 0) {
  3014.             option_user_message(STRING_NOT_FOUND, prev_target_buffer);
  3015.             sleep(MessageSecs);
  3016.             goto restore_popup_statusline;
  3017.         }
  3018.  
  3019.         /*
  3020.          *  Search from the beginning to the current choice. - FM
  3021.          */
  3022.         for (j = 0; j < cur_choice; j++) {
  3023.             sprintf(buffer, "%s%d: %s",
  3024.                     ((num_choices > 8 && j < 9) ?
  3025.                                 " " : ""),
  3026.                     (j + 1),
  3027.                     Cptr[j]);
  3028.             if (case_sensitive) {
  3029.             if (strstr(buffer, prev_target_buffer) != NULL)
  3030.                 break;
  3031.             } else {
  3032.             if (LYstrstr(buffer, prev_target_buffer) != NULL)
  3033.                 break;
  3034.             }
  3035.         }
  3036.         if (j < cur_choice) {
  3037.             /*
  3038.              *    We have a hit, so make that choice the current. - FM
  3039.              */
  3040.             j = (cur_choice - j);
  3041.             cur_choice -= j;
  3042.             /*
  3043.              *    Scroll the window up if necessary.
  3044.              */
  3045.             if ((cur_choice - window_offset) < 0) {
  3046.             window_offset -= j;
  3047.             if (window_offset < 0)
  3048.                 window_offset = 0;
  3049.             ReDraw = TRUE;
  3050.             }
  3051.             goto restore_popup_statusline;
  3052.         }
  3053.  
  3054.         /*
  3055.          *  Didn't find it in the preceding choices either. - FM
  3056.          */
  3057.         option_user_message(STRING_NOT_FOUND, prev_target_buffer);
  3058.         sleep(MessageSecs);
  3059.  
  3060. restore_popup_statusline:
  3061.         /*
  3062.          *  Restore the popup statusline and
  3063.          *  reset the search variables. - FM
  3064.          */
  3065.         if (disabled)
  3066.             option_statusline(CHOICE_LIST_UNM_MSG);
  3067.         else
  3068.             option_statusline(CHOICE_LIST_MESSAGE);
  3069.         *prev_target = '\0';
  3070.         QueryTotal = (search_queries ? HTList_count(search_queries)
  3071.                          : 0);
  3072.         recall = ((QueryTotal >= 1) ? RECALL : NORECALL);
  3073.         QueryNum = QueryTotal;
  3074.         if (ReDraw == TRUE) {
  3075.             ReDraw = FALSE;
  3076.             goto redraw;
  3077.         }
  3078.         break;
  3079.  
  3080.         case LYK_QUIT:
  3081.         case LYK_ABORT:
  3082.         case LYK_PREV_DOC:
  3083.         cur_choice = orig_choice;
  3084.         term_options = TRUE;
  3085.         option_statusline(CANCELLED);
  3086.         sleep(MessageSecs);
  3087.         cmd = LYK_ACTIVATE; /* to exit */
  3088.         break;
  3089.     }
  3090.     }
  3091. #ifndef USE_SLANG
  3092.     delwin(form_window);
  3093. #ifdef NCURSES
  3094.     LYsubwindow(0);
  3095. #endif
  3096. #endif /* !USE_SLANG */
  3097.  
  3098.     if (disabled || term_options) {
  3099.     option_statusline("");
  3100.     return(orig_choice);
  3101.     } else {
  3102.     option_statusline(VALUE_ACCEPTED);
  3103.     return(cur_choice);
  3104.     }
  3105. }
  3106.