#include "HTUtils.h" #include "tcp.h" #include "HTFTP.h" #include "HTML.h" #include "LYCurses.h" #include "LYUtils.h" #include "LYStrings.h" #include "LYGlobalDefs.h" #include "LYOptions.h" #include "LYSignal.h" #include "LYClean.h" #include "LYCharSets.h" #include "LYCharUtils.h" #include "UCMap.h" #include "UCAux.h" #include "LYKeymap.h" #include "LYrcFile.h" #include "HTAlert.h" #include "LYBookmark.h" #include "GridText.h" #include "LYLeaks.h" #define FREE(x) if (x) {free(x); x = NULL;} #ifdef VMS #define DISPLAY "DECW$DISPLAY" #else #define DISPLAY "DISPLAY" #endif /* VMS */ #define COL_OPTION_VALUES 36 /* display column where option values start */ BOOLEAN term_options; PRIVATE void terminate_options PARAMS((int sig)); PRIVATE int boolean_choice PARAMS(( int status, int line, int column, char ** choices)); PRIVATE int popup_choice PARAMS(( int cur_choice, int line, int column, char ** choices, int i_length, int disabled)); #define MAXCHOICES 10 #define L_Bool_A (use_assume_charset ? L_BOOL_A + 1 : L_BOOL_A) #define L_Bool_B (use_assume_charset ? L_BOOL_B + 1 : L_BOOL_B) #define L_Exec (use_assume_charset ? L_EXEC + 1 : L_EXEC) #define L_Rawmode (use_assume_charset ? L_RAWMODE + 1 : L_RAWMODE) #define L_Charset (use_assume_charset ? L_CHARSET + 1 : L_CHARSET) #define L_Color (use_assume_charset ? L_COLOR + 1 : L_COLOR) #define L_Keypad (use_assume_charset ? L_KEYPAD + 1 : L_KEYPAD) #define L_Lineed (use_assume_charset ? L_LINEED + 1 : L_LINEED) #define L_Dired (use_assume_charset ? L_DIRED + 1 : L_DIRED) #define L_User_Mode (use_assume_charset ? L_USER_MODE + 1 : L_USER_MODE) #define L_User_Agent (use_assume_charset ? L_USER_AGENT + 1 : L_USER_AGENT) PRIVATE void option_statusline ARGS1( CONST char *, text) { /* * Make sure we have a pointer to a string. */ if (text == NULL) return; /* * Don't print statusline messages if dumping to stdout. */ if (dump_output_immediately) return; /* * Use _statusline() set to output on the bottom line. - FM */ LYStatusLine = (LYlines - 1); _statusline(text); LYStatusLine = -1; } PRIVATE void option_user_message ARGS2( CONST char *, message, char *, argument) { /* * Make sure we have a pointer to a string. */ if (message == NULL || argument == NULL) return; /* * Don't print statusline messages if dumping to stdout. */ if (dump_output_immediately) return; /* * Use _user_message() set to output on the bottom line. */ LYStatusLine = (LYlines - 1); _user_message(message, argument); LYStatusLine = -1; } PUBLIC void options NOARGS { #ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS int itmp; #endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */ int response, ch; /* * If the user changes the display we need memory to put it in. */ char display_option[256]; #ifndef VMS static char putenv_command[142]; #endif /* !VMS */ char *choices[MAXCHOICES]; int CurrentCharSet = current_char_set; int CurrentShowColor = LYShowColor; int CurrentAssumeCharSet = UCLYhndl_for_unspec; BOOLEAN CurrentRawMode = LYRawMode; BOOLEAN AddValueAccepted = FALSE; BOOL use_assume_charset, old_use_assume_charset; #ifdef DIRED_SUPPORT #ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS if (LYlines < 24) { HTAlert(OPTION_SCREEN_NEEDS_24); return; } #else if (LYlines < 23) { HTAlert(OPTION_SCREEN_NEEDS_23); return; } #endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */ #else #ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS if (LYlines < 23) { HTAlert( "Screen height must be at least 23 lines for the Options menu!"); return; } #else if (LYlines < 22) { HTAlert(OPTION_SCREEN_NEEDS_22); return; } #endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */ #endif /* DIRED_SUPPORT */ term_options = FALSE; signal(SIGINT, terminate_options); if (no_option_save) { if (LYShowColor == SHOW_COLOR_NEVER) { LYShowColor = SHOW_COLOR_OFF; } else if (LYShowColor == SHOW_COLOR_ALWAYS) { LYShowColor = SHOW_COLOR_ON; } #if defined(USE_SLANG) || defined(COLOR_CURSES) } else { if (LYChosenShowColor == SHOW_COLOR_UNKNOWN) { switch (LYrcShowColor) { case SHOW_COLOR_NEVER: LYChosenShowColor = (LYShowColor >= SHOW_COLOR_ON) ? SHOW_COLOR_ON : SHOW_COLOR_NEVER; break; case SHOW_COLOR_ALWAYS: #if defined(COLOR_CURSES) if (!has_colors()) LYChosenShowColor = SHOW_COLOR_ALWAYS; else #endif LYChosenShowColor = (LYShowColor >= SHOW_COLOR_ON) ? SHOW_COLOR_ALWAYS : SHOW_COLOR_OFF; break; default: LYChosenShowColor = (LYShowColor >= SHOW_COLOR_ON) ? SHOW_COLOR_ON : SHOW_COLOR_OFF; } } #endif /* USE_SLANG || COLOR_CURSES */ } old_use_assume_charset = use_assume_charset = (user_mode == ADVANCED_MODE); draw_options: old_use_assume_charset = use_assume_charset; /* * NOTE that printw() should be avoided for strings that * might have non-ASCII or multibyte/CJK characters. - FM */ response = 0; #if defined(FANCY_CURSES) || defined (USE_SLANG) if (enable_scrollback) clear(); else erase(); #else clear(); #endif /* FANCY_CURSES || USE_SLANG */ move(0, 5); lynx_start_h1_color (); addstr(" Options Menu ("); addstr(LYNX_NAME); addstr(" Version "); addstr(LYNX_VERSION); addch(')'); lynx_stop_h1_color (); move(L_EDITOR, 5); addstr("E)ditor : "); addstr((editor && *editor) ? editor : "NONE"); move(L_DISPLAY, 5); addstr("D)ISPLAY variable : "); addstr((display && *display) ? display : "NONE"); move(L_HOME, 5); addstr("mu(L)ti-bookmarks: "); addstr((LYMultiBookmarks ? (LYMBMAdvanced ? "ADVANCED" : "STANDARD") : "OFF ")); move(L_HOME, B_BOOK); if (LYMultiBookmarks) { addstr("review/edit B)ookmarks files"); } else { addstr("B)ookmark file: "); addstr((bookmark_page && *bookmark_page) ? bookmark_page : "NONE"); } move(L_FTPSTYPE, 5); addstr("F)TP sort criteria : "); addstr((HTfileSortMethod == FILE_BY_NAME ? "By Filename" : (HTfileSortMethod == FILE_BY_SIZE ? "By Size " : (HTfileSortMethod == FILE_BY_TYPE ? "By Type " : "By Date ")))); move(L_MAIL_ADDRESS, 5); addstr("P)ersonal mail address : "); addstr((personal_mail_address && *personal_mail_address) ? personal_mail_address : "NONE"); move(L_SSEARCH, 5); addstr("S)earching type : "); addstr(case_sensitive ? "CASE SENSITIVE " : "CASE INSENSITIVE"); move(L_Charset, 5); addstr("display (C)haracter set : "); addstr((char *)LYchar_set_names[current_char_set]); move(L_LANGUAGE, 5); addstr("preferred document lan(G)uage: "); addstr((language && *language) ? language : "NONE"); move(L_PREF_CHARSET, 5); addstr("preferred document c(H)arset : "); addstr((pref_charset && *pref_charset) ? pref_charset : "NONE"); if (use_assume_charset) { move(L_ASSUME_CHARSET, 5); addstr("^A)ssume charset if unknown : "); if (UCAssume_MIMEcharset) addstr(UCAssume_MIMEcharset); else addstr((UCLYhndl_for_unspec >= 0) ? (char *)LYCharSet_UC[UCLYhndl_for_unspec].MIMEname : "NONE"); } move(L_Rawmode, 5); addstr("Raw 8-bit or CJK m(O)de : "); addstr(LYRawMode ? "ON " : "OFF"); #if defined(USE_SLANG) || defined(COLOR_CURSES) move(L_Color, B_COLOR); addstr("show color (&) : "); if (no_option_save) { addstr((LYShowColor == SHOW_COLOR_OFF ? "OFF" : "ON ")); } else { switch (LYChosenShowColor) { case SHOW_COLOR_NEVER: addstr("NEVER "); break; case SHOW_COLOR_OFF: addstr("OFF"); break; case SHOW_COLOR_ON: addstr("ON "); break; case SHOW_COLOR_ALWAYS: #if defined(COLOR_CURSES) if (!has_colors()) addstr("Always try"); else #endif addstr("ALWAYS "); } } #endif /* USE_SLANG || COLOR_CURSES */ move(L_Bool_A, B_VIKEYS); addstr("V)I keys: "); addstr(vi_keys ? "ON " : "OFF"); move(L_Bool_A, B_EMACSKEYS); addstr("e(M)acs keys: "); addstr(emacs_keys ? "ON " : "OFF"); move(L_Bool_A, B_SHOW_DOTFILES); addstr("sho(W) dot files: "); addstr((!no_dotfiles && show_dotfiles) ? "ON " : "OFF"); move(L_Bool_B, B_SELECT_POPUPS); addstr("popups for selec(T) fields : "); addstr(LYSelectPopups ? "ON " : "OFF"); move(L_Bool_B, B_SHOW_CURSOR); addstr("show cursor (@) : "); addstr(LYShowCursor ? "ON " : "OFF"); move(L_Keypad, 5); addstr("K)eypad mode : "); addstr((keypad_mode == NUMBERS_AS_ARROWS) ? "Numbers act as arrows " : ((keypad_mode == LINKS_ARE_NUMBERED) ? "Links are numbered " : "Links and form fields are numbered")); move(L_Lineed, 5); addstr("li(N)e edit style : "); addstr(LYLineeditNames[current_lineedit]); #ifdef DIRED_SUPPORT move(L_Dired, 5); addstr("l(I)st directory style : "); addstr((dir_list_style == FILES_FIRST) ? "Files first " : ((dir_list_style == MIXED_STYLE) ? "Mixed style " : "Directories first")); #endif /* DIRED_SUPPORT */ move(L_User_Mode, 5); addstr("U)ser mode : "); addstr( (user_mode == NOVICE_MODE) ? "Novice " : ((user_mode == INTERMEDIATE_MODE) ? "Intermediate" : "Advanced ")); move(L_User_Agent, 5); addstr("user (A)gent : "); addstr((LYUserAgent && *LYUserAgent) ? LYUserAgent : "NONE"); #ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS move(L_Exec, 5); addstr("local e(X)ecution links : "); #ifndef NEVER_ALLOW_REMOTE_EXEC addstr( local_exec ? "ALWAYS ON " : (local_exec_on_local_files ? "FOR LOCAL FILES ONLY" : "ALWAYS OFF ")); #else addstr(local_exec_on_local_files ? "FOR LOCAL FILES ONLY" : "ALWAYS OFF "); #endif /* !NEVER_ALLOW_REMOTE_EXEC */ #endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */ move(LYlines-3, 2); addstr(SELECT_SEGMENT); start_bold(); addstr(CAP_LETT_SEGMENT); stop_bold(); addstr(OF_OPT_LINE_SEGMENT); if (!no_option_save) { addstr(" '"); start_bold(); addstr(">"); stop_bold(); addstr("'"); addstr(TO_SAVE_SEGMENT); } addstr(OR_SEGMENT); addstr("'"); start_bold(); addstr("r"); stop_bold(); addstr("'"); addstr(TO_RETURN_SEGMENT); while (TOUPPER(response) != 'R' && !LYisNonAlnumKeyname(response, LYK_PREV_DOC) && response != '>' && !term_options && response != 7 && response != 3) { if (AddValueAccepted == TRUE) { option_statusline(VALUE_ACCEPTED); AddValueAccepted = FALSE; } move((LYlines - 2), 0); lynx_start_prompt_color (); addstr(COMMAND_PROMPT); lynx_stop_prompt_color (); refresh(); response = LYgetch(); if (term_options || response == 7 || response == 3) response = 'R'; if (LYisNonAlnumKeyname(response, LYK_REFRESH)) { lynx_force_repaint(); goto draw_options; } switch (response) { case 'e': /* Change the editor. */ case 'E': if (no_editor) { option_statusline(EDIT_DISABLED); } else if (system_editor ) { option_statusline(EDITOR_LOCKED); } else { if (editor && *editor) strcpy(display_option, editor); else { /* clear the NONE */ move(L_EDITOR, COL_OPTION_VALUES); addstr(" "); *display_option = '\0'; } option_statusline(ACCEPT_DATA); move(L_EDITOR, COL_OPTION_VALUES); start_bold(); ch = LYgetstr(display_option, VISIBLE, sizeof(display_option), NORECALL); stop_bold(); move(L_EDITOR, COL_OPTION_VALUES); if (term_options || ch == -1) { addstr((editor && *editor) ? editor : "NONE"); } else if (*display_option == '\0') { FREE(editor); addstr("NONE"); } else { StrAllocCopy(editor, display_option); addstr(display_option); } clrtoeol(); if (ch == -1) { option_statusline(CANCELLED); sleep(InfoSecs); option_statusline(""); } else { option_statusline(VALUE_ACCEPTED); } } response = ' '; break; case 'd': /* Change the display. */ case 'D': if (display && *display) { strcpy(display_option, display); } else { /* clear the NONE */ move(L_DISPLAY, COL_OPTION_VALUES); addstr(" "); *display_option = '\0'; } option_statusline(ACCEPT_DATA); move(L_DISPLAY, COL_OPTION_VALUES); start_bold(); ch = LYgetstr(display_option, VISIBLE, sizeof(display_option), NORECALL); stop_bold(); move(L_DISPLAY, COL_OPTION_VALUES); if ((term_options || ch == -1) || (display != NULL && #ifdef VMS !strcasecomp(display, display_option))) #else !strcmp(display, display_option))) #endif /* VMS */ { /* * Cancelled, or a non-NULL display string * wasn't changed. - FM */ addstr((display && *display) ? display : "NONE"); clrtoeol(); if (ch == -1) { option_statusline(CANCELLED); sleep(InfoSecs); option_statusline(""); } else { option_statusline(VALUE_ACCEPTED); } response = ' '; break; } else if (*display_option == '\0') { if ((display == NULL) || (display != NULL && *display == '\0')) { /* * NULL or zero-length display string * wasn't changed. - FM */ addstr("NONE"); clrtoeol(); option_statusline(VALUE_ACCEPTED); response = ' '; break; } } /* * Set the new DISPLAY variable. - FM */ #ifdef VMS { int i; for (i = 0; display_option[i]; i++) display_option[i] = TOUPPER(display_option[i]); Define_VMSLogical(DISPLAY, display_option); } #else sprintf(putenv_command, "DISPLAY=%s", display_option); putenv(putenv_command); #endif /* VMS */ if ((display = getenv(DISPLAY)) != NULL && *display == '\0') { display = NULL; } addstr(display ? display : "NONE"); clrtoeol(); if ((display == NULL && *display_option == '\0') || (display != NULL && !strcmp(display, display_option))) { if (display == NULL && LYisConfiguredForX == TRUE) { option_statusline(VALUE_ACCEPTED_WARNING_X); } else if (display != NULL && LYisConfiguredForX == FALSE) { option_statusline(VALUE_ACCEPTED_WARNING_NONX); } else { option_statusline(VALUE_ACCEPTED); } } else { if (*display_option) { option_statusline(FAILED_TO_SET_DISPLAY); } else { option_statusline(FAILED_CLEAR_SET_DISPLAY); } } response = ' '; break; case 'l': /* Change multibookmarks option. */ case 'L': if (LYMBMBlocked) { option_statusline(MULTIBOOKMARKS_DISALLOWED); response = ' '; break; } choices[0] = NULL; StrAllocCopy(choices[0], "OFF "); choices[1] = NULL; StrAllocCopy(choices[1], "STANDARD"); choices[2] = NULL; StrAllocCopy(choices[2], "ADVANCED"); choices[3] = NULL; if (!LYSelectPopups) { LYMultiBookmarks = boolean_choice((LYMultiBookmarks * (1 + LYMBMAdvanced)), L_HOME, C_MULTI, choices); } else { LYMultiBookmarks = popup_choice((LYMultiBookmarks * (1 + LYMBMAdvanced)), L_HOME, (C_MULTI - 1), choices, 3, FALSE); } if (LYMultiBookmarks == 2) { LYMultiBookmarks = TRUE; LYMBMAdvanced = TRUE; } else { LYMBMAdvanced = FALSE; } #if defined(VMS) || defined(USE_SLANG) if (LYSelectPopups) { move(L_HOME, C_MULTI); clrtoeol(); addstr(choices[(LYMultiBookmarks * (1 + LYMBMAdvanced))]); } #endif /* VMS || USE_SLANG */ FREE(choices[0]); FREE(choices[1]); FREE(choices[2]); #if !defined(VMS) && !defined(USE_SLANG) if (!LYSelectPopups) #endif /* !VMS && !USE_SLANG */ { move(L_HOME, B_BOOK); clrtoeol(); if (LYMultiBookmarks) { addstr("review/edit B)ookmarks files"); } else { addstr("B)ookmark file: "); addstr((bookmark_page && *bookmark_page) ? bookmark_page : "NONE"); } } response = ' '; if (LYSelectPopups) { #if !defined(VMS) || defined(USE_SLANG) if (term_options) { term_options = FALSE; } else { AddValueAccepted = TRUE; } goto draw_options; #else term_options = FALSE; #endif /* !VMS || USE_SLANG */ } break; case 'b': /* Change the bookmark page location. */ case 'B': /* * Anonymous users should not be allowed to * change the bookmark page. */ if (!no_bookmark) { if (LYMultiBookmarks) { edit_bookmarks(); signal(SIGINT, terminate_options); goto draw_options; } if (bookmark_page && *bookmark_page) { strcpy(display_option, bookmark_page); } else { /* clear the NONE */ move(L_HOME, C_DEFAULT); clrtoeol(); *display_option = '\0'; } option_statusline(ACCEPT_DATA); move(L_HOME, C_DEFAULT); start_bold(); ch = LYgetstr(display_option, VISIBLE, sizeof(display_option), NORECALL); stop_bold(); move(L_HOME, C_DEFAULT); if (term_options || ch == -1 || *display_option == '\0') { addstr((bookmark_page && *bookmark_page) ? bookmark_page : "NONE"); } else if (!LYPathOffHomeOK(display_option, sizeof(display_option))) { addstr((bookmark_page && *bookmark_page) ? bookmark_page : "NONE"); clrtoeol(); option_statusline(USE_PATH_OFF_HOME); response = ' '; break; } else { StrAllocCopy(bookmark_page, display_option); StrAllocCopy(MBM_A_subbookmark[0], bookmark_page); addstr(bookmark_page); } clrtoeol(); if (ch == -1) { option_statusline(CANCELLED); sleep(InfoSecs); option_statusline(""); } else { option_statusline(VALUE_ACCEPTED); } } else { /* anonymous */ option_statusline(BOOKMARK_CHANGE_DISALLOWED); } response = ' '; break; case 'f': /* Change ftp directory sorting. */ case 'F': /* (also local for non-DIRED) */ /* * Copy strings into choice array. */ choices[0] = NULL; StrAllocCopy(choices[0], "By Filename"); choices[1] = NULL; StrAllocCopy(choices[1], "By Type "); choices[2] = NULL; StrAllocCopy(choices[2], "By Size "); choices[3] = NULL; StrAllocCopy(choices[3], "By Date "); choices[4] = NULL; if (!LYSelectPopups) { HTfileSortMethod = boolean_choice(HTfileSortMethod, L_FTPSTYPE, -1, choices); } else { HTfileSortMethod = popup_choice(HTfileSortMethod, L_FTPSTYPE, -1, choices, 4, FALSE); #if defined(VMS) || defined(USE_SLANG) move(L_FTPSTYPE, COL_OPTION_VALUES); clrtoeol(); addstr(choices[HTfileSortMethod]); #endif /* VMS || USE_SLANG */ } FREE(choices[0]); FREE(choices[1]); FREE(choices[2]); FREE(choices[3]); response = ' '; if (LYSelectPopups) { #if !defined(VMS) || defined(USE_SLANG) if (term_options) { term_options = FALSE; } else { AddValueAccepted = TRUE; } goto draw_options; #else term_options = FALSE; #endif /* !VMS || USE_SLANG */ } break; case 'p': /* Change personal mail address for From headers. */ case 'P': if (personal_mail_address && *personal_mail_address) { strcpy(display_option, personal_mail_address); } else { /* clear the NONE */ move(L_MAIL_ADDRESS, COL_OPTION_VALUES); addstr(" "); *display_option = '\0'; } option_statusline(ACCEPT_DATA); move(L_MAIL_ADDRESS, COL_OPTION_VALUES); start_bold(); ch = LYgetstr(display_option, VISIBLE, sizeof(display_option), NORECALL); stop_bold(); move(L_MAIL_ADDRESS, COL_OPTION_VALUES); if (term_options || ch == -1) { addstr((personal_mail_address && *personal_mail_address) ? personal_mail_address : "NONE"); } else if (*display_option == '\0') { FREE(personal_mail_address); addstr("NONE"); } else { StrAllocCopy(personal_mail_address, display_option); addstr(display_option); } clrtoeol(); if (ch == -1) { option_statusline(CANCELLED); sleep(InfoSecs); option_statusline(""); } else { option_statusline(VALUE_ACCEPTED); } response = ' '; break; case 's': /* Change case sentitivity for searches. */ case 'S': /* * Copy strings into choice array. */ choices[0] = NULL; StrAllocCopy(choices[0], "CASE INSENSITIVE"); choices[1] = NULL; StrAllocCopy(choices[1], "CASE SENSITIVE "); choices[2] = NULL; case_sensitive = boolean_choice(case_sensitive, L_SSEARCH, -1, choices); FREE(choices[0]); FREE(choices[1]); response = ' '; break; case '\001': /* Change assume_charset setting. */ if (use_assume_charset) { int i, curval; char ** assume_list; assume_list = (char **)calloc(LYNumCharsets + 1, sizeof(char *)); if (!assume_list) { outofmem(__FILE__, "options"); } for (i = 0; i < LYNumCharsets; i++) { assume_list[i] = (char *)LYCharSet_UC[i].MIMEname; } curval = UCLYhndl_for_unspec; if (curval == current_char_set && UCAssume_MIMEcharset) { curval = UCGetLYhndl_byMIME(UCAssume_MIMEcharset); } if (curval < 0) curval = LYRawMode ? current_char_set : 0; if (!LYSelectPopups) { UCLYhndl_for_unspec = boolean_choice(curval, L_ASSUME_CHARSET, -1, assume_list); } else { UCLYhndl_for_unspec = popup_choice(curval, L_ASSUME_CHARSET, -1, assume_list, 0, FALSE); #if defined(VMS) || defined(USE_SLANG) move(L_ASSUME_CHARSET, COL_OPTION_VALUES); clrtoeol(); if (UCLYhndl_for_unspec >= 0) addstr((char *) LYCharSet_UC[UCLYhndl_for_unspec].MIMEname); #endif /* VMS || USE_SLANG */ } /* * Set the raw 8-bit or CJK mode defaults and * character set if changed. - FM */ if (CurrentAssumeCharSet != UCLYhndl_for_unspec || UCLYhndl_for_unspec != curval) { if (UCLYhndl_for_unspec != CurrentAssumeCharSet) { StrAllocCopy(UCAssume_MIMEcharset, LYCharSet_UC[UCLYhndl_for_unspec].MIMEname); } LYRawMode = (UCLYhndl_for_unspec == current_char_set); HTMLSetUseDefaultRawMode(current_char_set, LYRawMode); HTMLUseCharacterSet(current_char_set); CurrentAssumeCharSet = UCLYhndl_for_unspec; CurrentRawMode = LYRawMode; #if !defined(VMS) && !defined(USE_SLANG) if (!LYSelectPopups) #endif /* !VMS && !USE_SLANG */ { move(L_Rawmode, COL_OPTION_VALUES); clrtoeol(); addstr(LYRawMode ? "ON " : "OFF"); } } FREE(assume_list); response = ' '; if (LYSelectPopups) { #if !defined(VMS) || defined(USE_SLANG) if (term_options) { term_options = FALSE; } else { AddValueAccepted = TRUE; } goto draw_options; #else term_options = FALSE; #endif /* !VMS || USE_SLANG */ } } else { option_statusline(NEED_ADVANCED_USER_MODE); AddValueAccepted = FALSE; } break; case 'c': /* Change charset setting. */ case 'C': if (!LYSelectPopups) { current_char_set = boolean_choice(current_char_set, L_Charset, -1, (char **)LYchar_set_names); } else { current_char_set = popup_choice(current_char_set, L_Charset, -1, (char **)LYchar_set_names, 0, FALSE); #if defined(VMS) || defined(USE_SLANG) move(L_Charset, COL_OPTION_VALUES); clrtoeol(); addstr((char *)LYchar_set_names[current_char_set]); #endif /* VMS || USE_SLANG */ } /* * Set the raw 8-bit or CJK mode defaults and * character set if changed. - FM */ if (CurrentCharSet != current_char_set) { HTMLSetRawModeDefault(current_char_set); LYUseDefaultRawMode = TRUE; HTMLUseCharacterSet(current_char_set); CurrentCharSet = current_char_set; CurrentRawMode = LYRawMode; #if !defined(VMS) && !defined(USE_SLANG) if (!LYSelectPopups) #endif /* !VMS && !USE_SLANG */ { move(L_Rawmode, COL_OPTION_VALUES); clrtoeol(); addstr(LYRawMode ? "ON " : "OFF"); } } response = ' '; if (LYSelectPopups) { #if !defined(VMS) || defined(USE_SLANG) if (term_options) { term_options = FALSE; } else { AddValueAccepted = TRUE; } goto draw_options; #else term_options = FALSE; #endif /* !VMS || USE_SLANG */ } break; case 'o': /* Change raw mode setting. */ case 'O': /* * Copy strings into choice array. */ choices[0] = NULL; StrAllocCopy(choices[0], "OFF"); choices[1] = NULL; StrAllocCopy(choices[1], "ON "); choices[2] = NULL; LYRawMode = boolean_choice(LYRawMode, L_Rawmode, -1, choices); /* * Set the LYUseDefaultRawMode value and character * handling if LYRawMode was changed. - FM */ if (CurrentRawMode != LYRawMode) { HTMLSetUseDefaultRawMode(current_char_set, LYRawMode); HTMLSetCharacterHandling(current_char_set); CurrentRawMode = LYRawMode; } FREE(choices[0]); FREE(choices[1]); response = ' '; break; case 'g': /* Change language preference. */ case 'G': if (language && *language) { strcpy(display_option, language); } else { /* clear the NONE */ move(L_LANGUAGE, COL_OPTION_VALUES); addstr(" "); *display_option = '\0'; } option_statusline(ACCEPT_DATA); move(L_LANGUAGE, COL_OPTION_VALUES); start_bold(); ch = LYgetstr(display_option, VISIBLE, sizeof(display_option), NORECALL); stop_bold(); move(L_LANGUAGE, COL_OPTION_VALUES); if (term_options || ch == -1) { addstr((language && *language) ? language : "NONE"); } else if (*display_option == '\0') { FREE(language); addstr("NONE"); } else { StrAllocCopy(language, display_option); addstr(display_option); } clrtoeol(); if (ch == -1) { option_statusline(CANCELLED); sleep(InfoSecs); option_statusline(""); } else { option_statusline(VALUE_ACCEPTED); } response = ' '; break; case 'h': /* Change charset preference. */ case 'H': if (pref_charset && *pref_charset) { strcpy(display_option, pref_charset); } else { /* clear the NONE */ move(L_PREF_CHARSET, COL_OPTION_VALUES); addstr(" "); *display_option = '\0'; } option_statusline(ACCEPT_DATA); move(L_PREF_CHARSET, COL_OPTION_VALUES); start_bold(); ch = LYgetstr(display_option, VISIBLE, sizeof(display_option), NORECALL); stop_bold(); move(L_PREF_CHARSET, COL_OPTION_VALUES); if (term_options || ch == -1) { addstr((pref_charset && *pref_charset) ? pref_charset : "NONE"); } else if (*display_option == '\0') { FREE(pref_charset); addstr("NONE"); } else { StrAllocCopy(pref_charset, display_option); addstr(display_option); } clrtoeol(); if (ch == -1) { option_statusline(CANCELLED); sleep(InfoSecs); option_statusline(""); } else { option_statusline(VALUE_ACCEPTED); } response = ' '; break; case 'v': /* Change VI keys setting. */ case 'V': /* * Copy strings into choice array. */ choices[0] = NULL; StrAllocCopy(choices[0], "OFF"); choices[1] = NULL; StrAllocCopy(choices[1], "ON "); choices[2] = NULL; vi_keys = boolean_choice(vi_keys, L_Bool_A, C_VIKEYS, choices); if (vi_keys) { set_vi_keys(); } else { reset_vi_keys(); } FREE(choices[0]); FREE(choices[1]); response = ' '; break; case 'M': /* Change emacs keys setting. */ case 'm': /* * Copy strings into choice array. */ choices[0] = NULL; StrAllocCopy(choices[0], "OFF"); choices[1] = NULL; StrAllocCopy(choices[1], "ON "); choices[2] = NULL; emacs_keys = boolean_choice(emacs_keys, L_Bool_A, C_EMACSKEYS, choices); if (emacs_keys) { set_emacs_keys(); } else { reset_emacs_keys(); } FREE(choices[0]); FREE(choices[1]); response = ' '; break; case 'W': /* Change show dotfiles setting. */ case 'w': if (no_dotfiles) { option_statusline(DOTFILE_ACCESS_DISABLED); } else { /* * Copy strings into choice array. */ choices[0] = NULL; StrAllocCopy(choices[0], "OFF"); choices[1] = NULL; StrAllocCopy(choices[1], "ON "); choices[2] = NULL; show_dotfiles = boolean_choice(show_dotfiles, L_Bool_A, C_SHOW_DOTFILES, choices); FREE(choices[0]); FREE(choices[1]); } response = ' '; break; case 't': /* Change select popups setting. */ case 'T': /* * Copy strings into choice array. */ choices[0] = NULL; StrAllocCopy(choices[0], "OFF"); choices[1] = NULL; StrAllocCopy(choices[1], "ON "); choices[2] = NULL; LYSelectPopups = boolean_choice(LYSelectPopups, L_Bool_B, C_SELECT_POPUPS, choices); FREE(choices[0]); FREE(choices[1]); response = ' '; break; #if defined(USE_SLANG) || defined(COLOR_CURSES) case '&': /* Change show color setting. */ if (no_option_save) { #if defined(COLOR_CURSES) if (!has_colors()) { char * terminal = getenv("TERM"); if (terminal) option_user_message( COLOR_TOGGLE_DISABLED_FOR_TERM, terminal); else option_statusline(COLOR_TOGGLE_DISABLED); sleep(AlertSecs); } #endif /* * Copy strings into choice array. */ choices[0] = NULL; StrAllocCopy(choices[0], "OFF"); choices[1] = NULL; StrAllocCopy(choices[1], "ON "); choices[2] = NULL; LYShowColor = boolean_choice((LYShowColor - 1), L_Color, C_COLOR, choices); if (LYShowColor == 0) { LYShowColor = SHOW_COLOR_OFF; } else { LYShowColor = SHOW_COLOR_ON; } } else { /* !no_option_save */ BOOLEAN again = FALSE; int chosen; /* * Copy strings into choice array. */ choices[0] = NULL; StrAllocCopy(choices[0], "NEVER "); choices[1] = NULL; StrAllocCopy(choices[1], "OFF "); choices[2] = NULL; StrAllocCopy(choices[2], "ON "); choices[3] = NULL; #if defined(COLOR_CURSES) if (!has_colors()) StrAllocCopy(choices[3], "Always try"); else #endif StrAllocCopy(choices[3], "ALWAYS "); choices[4] = NULL; do { if (!LYSelectPopups) { chosen = boolean_choice(LYChosenShowColor, L_Color, C_COLOR, choices); } else { chosen = popup_choice(LYChosenShowColor, L_Color, C_COLOR, choices, 4, FALSE); } #if defined(COLOR_CURSES) again = (chosen == 2 && !has_colors()); if (again) { char * terminal = getenv("TERM"); if (terminal) option_user_message( COLOR_TOGGLE_DISABLED_FOR_TERM, terminal); else option_statusline(COLOR_TOGGLE_DISABLED); sleep(AlertSecs); } #endif } while (again); LYChosenShowColor = chosen; #if defined(VMS) if (LYSelectPopups) { move(L_Color, C_COLOR); clrtoeol(); addstr(choices[LYChosenShowColor]); } #endif /* VMS */ #if defined(COLOR_CURSES) if (has_colors()) #endif LYShowColor = chosen; FREE(choices[2]); FREE(choices[3]); } FREE(choices[0]); FREE(choices[1]); if (CurrentShowColor != LYShowColor) { lynx_force_repaint(); } CurrentShowColor = LYShowColor; #ifdef USE_SLANG SLtt_Use_Ansi_Colors = (LYShowColor > 1 ? 1 : 0); #endif response = ' '; if (LYSelectPopups && !no_option_save) { #if !defined(VMS) || defined(USE_SLANG) if (term_options) { term_options = FALSE; } else { AddValueAccepted = TRUE; } goto draw_options; #else term_options = FALSE; #endif /* !VMS || USE_SLANG */ } break; #endif /* USE_SLANG or COLOR_CURSES */ case '@': /* Change show cursor setting. */ /* * Copy strings into choice array. */ choices[0] = NULL; StrAllocCopy(choices[0], "OFF"); choices[1] = NULL; StrAllocCopy(choices[1], "ON "); choices[2] = NULL; LYShowCursor = boolean_choice(LYShowCursor, L_Bool_B, C_SHOW_CURSOR, choices); FREE(choices[0]); FREE(choices[1]); response = ' '; break; case 'k': /* Change keypad mode. */ case 'K': /* * Copy strings into choice array. */ choices[0] = NULL; StrAllocCopy(choices[0], "Numbers act as arrows "); choices[1] = NULL; StrAllocCopy(choices[1], "Links are numbered "); choices[2] = NULL; StrAllocCopy(choices[2], "Links and form fields are numbered"); choices[3] = NULL; if (!LYSelectPopups) { keypad_mode = boolean_choice(keypad_mode, L_Keypad, -1, choices); } else { keypad_mode = popup_choice(keypad_mode, L_Keypad, -1, choices, 3, FALSE); #if defined(VMS) || defined(USE_SLANG) move(L_Keypad, COL_OPTION_VALUES); clrtoeol(); addstr(choices[keypad_mode]); #endif /* VMS || USE_SLANG */ } if (keypad_mode == NUMBERS_AS_ARROWS) { set_numbers_as_arrows(); } else { reset_numbers_as_arrows(); } FREE(choices[0]); FREE(choices[1]); FREE(choices[2]); response = ' '; if (LYSelectPopups) { #if !defined(VMS) || defined(USE_SLANG) if (term_options) { term_options = FALSE; } else { AddValueAccepted = TRUE; } goto draw_options; #else term_options = FALSE; #endif /* !VMS || USE_SLANG */ } break; case 'n': /* Change line editor key bindings. */ case 'N': if (!LYSelectPopups) { current_lineedit = boolean_choice(current_lineedit, L_Lineed, -1, LYLineeditNames); } else { current_lineedit = popup_choice(current_lineedit, L_Lineed, -1, LYLineeditNames, 0, FALSE); #if defined(VMS) || defined(USE_SLANG) move(L_Lineed, COL_OPTION_VALUES); clrtoeol(); addstr(LYLineeditNames[current_lineedit]); #endif /* VMS || USE_SLANG */ } response = ' '; if (LYSelectPopups) { #if !defined(VMS) || defined(USE_SLANG) if (term_options) { term_options = FALSE; } else { AddValueAccepted = TRUE; } goto draw_options; #else term_options = FALSE; #endif /* !VMS || USE_SLANG */ } break; #ifdef DIRED_SUPPORT case 'i': /* Change local directory sorting. */ case 'I': /* * Copy strings into choice array. */ choices[0] = NULL; StrAllocCopy(choices[0], "Directories first"); choices[1] = NULL; StrAllocCopy(choices[1], "Files first "); choices[2] = NULL; StrAllocCopy(choices[2], "Mixed style "); choices[3] = NULL; if (!LYSelectPopups) { dir_list_style = boolean_choice(dir_list_style, L_Dired, -1, choices); } else { dir_list_style = popup_choice(dir_list_style, L_Dired, -1, choices, 3, FALSE); #if defined(VMS) || defined(USE_SLANG) move(L_Dired, COL_OPTION_VALUES); clrtoeol(); addstr(choices[dir_list_style]); #endif /* VMS || USE_SLANG */ } FREE(choices[0]); FREE(choices[1]); FREE(choices[2]); response = ' '; if (LYSelectPopups) { #if !defined(VMS) || defined(USE_SLANG) if (term_options) { term_options = FALSE; } else { AddValueAccepted = TRUE; } goto draw_options; #else term_options = FALSE; #endif /* !VMS || USE_SLANG */ } break; #endif /* DIRED_SUPPORT */ case 'u': /* Change user mode. */ case 'U': /* * Copy strings into choice array. */ choices[0] = NULL; StrAllocCopy(choices[0], "Novice "); choices[1] = NULL; StrAllocCopy(choices[1], "Intermediate"); choices[2] = NULL; StrAllocCopy(choices[2], "Advanced "); choices[3] = NULL; if (!LYSelectPopups) { user_mode = boolean_choice(user_mode, L_User_Mode, -1, choices); use_assume_charset = (user_mode >= 2); } else { user_mode = popup_choice(user_mode, L_User_Mode, -1, choices, 3, FALSE); use_assume_charset = (user_mode >= 2); #if defined(VMS) || defined(USE_SLANG) if (use_assume_charset == old_use_assume_charset) { move(L_User_Mode, COL_OPTION_VALUES); clrtoeol(); addstr(choices[user_mode]); } #endif /* VMS || USE_SLANG */ } FREE(choices[0]); FREE(choices[1]); FREE(choices[2]); if (user_mode == NOVICE_MODE) { display_lines = (LYlines - 4); } else { display_lines = LYlines-2; } response = ' '; if (LYSelectPopups) { #if !defined(VMS) || defined(USE_SLANG) if (term_options) { term_options = FALSE; } else { AddValueAccepted = TRUE; } goto draw_options; #else term_options = FALSE; if (use_assume_charset != old_use_assume_charset) goto draw_options; #endif /* !VMS || USE_SLANG */ } break; case 'a': /* Change user agent string. */ case 'A': if (!no_useragent) { if (LYUserAgent && *LYUserAgent) { strcpy(display_option, LYUserAgent); } else { /* clear the NONE */ move(L_HOME, COL_OPTION_VALUES); addstr(" "); *display_option = '\0'; } option_statusline(ACCEPT_DATA_OR_DEFAULT); move(L_User_Agent, COL_OPTION_VALUES); start_bold(); ch = LYgetstr(display_option, VISIBLE, sizeof(display_option), NORECALL); stop_bold(); move(L_User_Agent, COL_OPTION_VALUES); if (term_options || ch == -1) { addstr((LYUserAgent && *LYUserAgent) ? LYUserAgent : "NONE"); } else if (*display_option == '\0') { StrAllocCopy(LYUserAgent, LYUserAgentDefault); addstr((LYUserAgent && *LYUserAgent) ? LYUserAgent : "NONE"); } else { StrAllocCopy(LYUserAgent, display_option); addstr(display_option); } clrtoeol(); if (ch == -1) { option_statusline(CANCELLED); sleep(InfoSecs); option_statusline(""); } else if (LYUserAgent && *LYUserAgent && !strstr(LYUserAgent, "Lynx") && !strstr(LYUserAgent, "lynx")) { option_statusline(UA_COPYRIGHT_WARNING); } else { option_statusline(VALUE_ACCEPTED); } } else { /* disallowed */ option_statusline(UA_COPYRIGHT_WARNING); } response = ' '; break; #ifdef ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS case 'x': /* Change local exec restriction. */ case 'X': if (exec_frozen && !LYSelectPopups) { option_statusline(CHANGE_OF_SETTING_DISALLOWED); response = ' '; break; } #ifndef NEVER_ALLOW_REMOTE_EXEC if (local_exec) { itmp = 2; } else #endif /* !NEVER_ALLOW_REMOTE_EXEC */ { if (local_exec_on_local_files) { itmp= 1; } else { itmp = 0; } } /* * Copy strings into choice array. */ choices[0] = NULL; StrAllocCopy(choices[0], "ALWAYS OFF "); choices[1] = NULL; StrAllocCopy(choices[1], "FOR LOCAL FILES ONLY"); choices[2] = NULL; #ifndef NEVER_ALLOW_REMOTE_EXEC StrAllocCopy(choices[2], "ALWAYS ON "); choices[3] = NULL; #endif /* !NEVER_ALLOW_REMOTE_EXEC */ if (!LYSelectPopups) { itmp = boolean_choice(itmp, L_Exec, -1, choices); } else { itmp = popup_choice(itmp, L_Exec, -1, choices, 0, (exec_frozen ? TRUE : FALSE)); #if defined(VMS) || defined(USE_SLANG) move(L_Exec, COL_OPTION_VALUES); clrtoeol(); addstr(choices[itmp]); #endif /* VMS || USE_SLANG */ } FREE(choices[0]); FREE(choices[1]); #ifndef NEVER_ALLOW_REMOTE_EXEC FREE(choices[2]); #endif /* !NEVER_ALLOW_REMOTE_EXEC */ if (!exec_frozen) { switch (itmp) { case 0: local_exec = FALSE; local_exec_on_local_files = FALSE; break; case 1: local_exec = FALSE; local_exec_on_local_files = TRUE; break; #ifndef NEVER_ALLOW_REMOTE_EXEC case 2: local_exec = TRUE; local_exec_on_local_files = FALSE; break; #endif /* !NEVER_ALLOW_REMOTE_EXEC */ } /* end switch */ } response = ' '; if (LYSelectPopups) { #if !defined(VMS) || defined(USE_SLANG) if (exec_frozen || term_options) { term_options = FALSE; } else { AddValueAccepted = TRUE; } goto draw_options; #else term_options = FALSE; #endif /* !VMS || USE_SLANG */ } break; #endif /* ALLOW_USERS_TO_CHANGE_EXEC_WITHIN_OPTIONS */ case '>': /* Save current options to RC file. */ if (!no_option_save) { option_statusline(SAVING_OPTIONS); if (save_rc()) { LYrcShowColor = LYChosenShowColor; option_statusline(OPTIONS_SAVED); } else { HTAlert(OPTIONS_NOT_SAVED); } } else { option_statusline(R_TO_RETURN_TO_LYNX); /* * Change response so that we don't exit * the options menu. */ response = ' '; } break; case 'r': /* Return to document (quit options menu). */ case 'R': break; default: if (!no_option_save) { option_statusline(SAVE_OR_R_TO_RETURN_TO_LYNX); } else { option_statusline(R_TO_RETURN_TO_LYNX); } } /* end switch */ } /* end while */ term_options = FALSE; signal(SIGINT, cleanup_sig); } /* * Take a boolean status,prompt the user for a new status, * and return it. */ PRIVATE int boolean_choice ARGS4( int, cur_choice, int, line, int, column, char **, choices) { int response = 0; int cmd = 0; int number = 0; int col = (column >= 0 ? column : COL_OPTION_VALUES); int orig_choice = cur_choice; #ifdef VMS extern BOOLEAN HadVMSInterrupt; /* Flag from cleanup_sig() AST */ #endif /* VMS */ /* * Get the number of choices and then make * number zero-based. */ for (number = 0; choices[number] != NULL; number++) ; /* empty loop body */ number--; /* * Update the statusline. */ option_statusline(ANY_KEY_CHANGE_RET_ACCEPT); /* * Highlight the current choice. */ move(line, col); start_reverse(); addstr(choices[cur_choice]); if (LYShowCursor) move(line, (col - 1)); refresh(); /* * Get the keyboard entry, and leave the * cursor at the choice, to indicate that * it can be changed, until the user accepts * the current choice. */ term_options = FALSE; while (1) { move(line, col); if (term_options == FALSE) { response = LYgetch(); } if (term_options || response == 7 || response == 3) { /* * Control-C or Control-G. */ response = '\n'; term_options = TRUE; cur_choice = orig_choice; } #ifdef VMS if (HadVMSInterrupt) { HadVMSInterrupt = FALSE; response = '\n'; term_options = TRUE; cur_choice = orig_choice; } #endif /* VMS */ if ((response != '\n' && response != '\r') && (cmd = keymap[response+1]) != LYK_ACTIVATE) { switch (cmd) { case LYK_HOME: cur_choice = 0; break; case LYK_END: cur_choice = number; break; case LYK_REFRESH: lynx_force_repaint(); refresh(); break; case LYK_QUIT: case LYK_ABORT: case LYK_PREV_DOC: cur_choice = orig_choice; term_options = TRUE; break; case LYK_PREV_PAGE: case LYK_UP_HALF: case LYK_UP_TWO: case LYK_PREV_LINK: case LYK_UP_LINK: case LYK_LEFT_LINK: if (cur_choice == 0) cur_choice = number; /* go back to end */ else cur_choice--; break; case LYK_1: case LYK_2: case LYK_3: case LYK_4: case LYK_5: case LYK_6: case LYK_7: case LYK_8: case LYK_9: if((cmd - LYK_1 + 1) <= number) { cur_choice = cmd -LYK_1 + 1; break; } /* else fall through! */ default: if (cur_choice == number) cur_choice = 0; /* go over the top and around */ else cur_choice++; } /* end of switch */ addstr(choices[cur_choice]); if (LYShowCursor) move(line, (col - 1)); refresh(); } else { /* * Unhighlight choice. */ move(line, col); stop_reverse(); addstr(choices[cur_choice]); if (term_options) { term_options = FALSE; option_statusline(CANCELLED); sleep(InfoSecs); option_statusline(""); } else { option_statusline(VALUE_ACCEPTED); } return(cur_choice); } } } PRIVATE void terminate_options ARGS1( int, sig) { term_options = TRUE; /* * Reassert the AST. */ signal(SIGINT, terminate_options); #ifdef VMS /* * Refresh the screen to get rid of the "interrupt" message. */ if (!dump_output_immediately) { lynx_force_repaint(); refresh(); } #endif /* VMS */ } /* * Multi-Bookmark On-Line editing support. - FMG & FM */ PUBLIC void edit_bookmarks NOARGS { int response = 0, def_response = 0, ch; int MBM_current = 1; #define MULTI_OFFSET 8 int a; /* misc counter */ char MBM_tmp_line[256]; /* buffer for LYgetstr */ char ehead_buffer[265]; /* * We need (MBM_V_MAXFILES + MULTI_OFFSET) lines to display * the whole list at once. Otherwise break it up into two * segments. We know it won't be less than that because * 'o'ptions needs 23-24 at LEAST. */ term_options = FALSE; signal(SIGINT, terminate_options); draw_bookmark_list: /* * Display menu of bookmarks. NOTE that we avoid printw()'s * to increase the chances that any non-ASCII or multibyte/CJK * characters will be handled properly. - FM */ #if defined(FANCY_CURSES) || defined (USE_SLANG) if (enable_scrollback) clear(); else erase(); #else clear(); #endif /* FANCY_CURSES || USE_SLANG */ move(0, 5); lynx_start_h1_color (); if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) { sprintf(ehead_buffer, MULTIBOOKMARKS_EHEAD_MASK, MBM_current); addstr(ehead_buffer); } else { addstr(MULTIBOOKMARKS_EHEAD); } lynx_stop_h1_color (); if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) { for (a = ((MBM_V_MAXFILES/2 + 1) * (MBM_current - 1)); a <= ((float)MBM_V_MAXFILES/2 * MBM_current); a++) { move((3 + a) - ((MBM_V_MAXFILES/2 + 1)*(MBM_current - 1)), 5); addch((unsigned char)(a + 'A')); addstr(" : "); if (MBM_A_subdescript[a]) addstr(MBM_A_subdescript[a]); move((3 + a) - ((MBM_V_MAXFILES/2 + 1)*(MBM_current - 1)), 35); addstr("| "); if (MBM_A_subbookmark[a]) { addstr(MBM_A_subbookmark[a]); } } } else { for (a = 0; a <= MBM_V_MAXFILES; a++) { move(3 + a, 5); addch((unsigned char)(a + 'A')); addstr(" : "); if (MBM_A_subdescript[a]) addstr(MBM_A_subdescript[a]); move(3 + a, 35); addstr("| "); if (MBM_A_subbookmark[a]) { addstr(MBM_A_subbookmark[a]); } } } /* * Only needed when we have 2 screens. */ if (LYlines < MBM_V_MAXFILES + MULTI_OFFSET) { move((LYlines - 4), 0); addstr("'"); start_bold(); addstr("["); stop_bold(); addstr("' "); addstr(PREVIOUS); addstr(", '"); start_bold(); addstr("]"); stop_bold(); addstr("' "); addstr(NEXT_SCREEN); } move((LYlines - 3), 0); if (!no_option_save) { addstr("'"); start_bold(); addstr(">"); stop_bold(); addstr("'"); addstr(TO_SAVE_SEGMENT); } addstr(OR_SEGMENT); addstr("'"); start_bold(); addstr("^G"); stop_bold(); addstr("'"); addstr(TO_RETURN_SEGMENT); while (!term_options && !LYisNonAlnumKeyname(response, LYK_PREV_DOC) && response != 7 && response != 3 && response != '>') { move((LYlines - 2), 0); lynx_start_prompt_color (); addstr(MULTIBOOKMARKS_LETTER); lynx_stop_prompt_color (); refresh(); response = (def_response ? def_response : LYgetch()); def_response = 0; /* * Check for a cancel. */ if (term_options || response == 7 || response == 3 || LYisNonAlnumKeyname(response, LYK_PREV_DOC)) continue; /* * Check for a save. */ if (response == '>') { if (!no_option_save) { option_statusline(SAVING_OPTIONS); if (save_rc()) option_statusline(OPTIONS_SAVED); else HTAlert(OPTIONS_NOT_SAVED); } else { option_statusline(R_TO_RETURN_TO_LYNX); /* * Change response so that we don't exit * the options menu. */ response = ' '; } continue; } /* * Check for a refresh. */ if (LYisNonAlnumKeyname(response, LYK_REFRESH)) { lynx_force_repaint(); continue; } /* * Move between the screens - if we can't show it all at once. */ if ((response == ']' || LYisNonAlnumKeyname(response, LYK_NEXT_PAGE)) && LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) { MBM_current++; if (MBM_current >= 3) MBM_current = 1; goto draw_bookmark_list; } if ((response == '[' || LYisNonAlnumKeyname(response, LYK_PREV_PAGE)) && LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) { MBM_current--; if (MBM_current <= 0) MBM_current = 2; goto draw_bookmark_list; } /* * Instead of using 26 case statements, we set up * a scan through the letters and edit the lines * that way. */ for (a = 0; a <= MBM_V_MAXFILES; a++) { if ((TOUPPER(response) - 'A') == a) { if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) { if (MBM_current == 1 && a > (MBM_V_MAXFILES/2)) { MBM_current = 2; def_response = response; goto draw_bookmark_list; } if (MBM_current == 2 && a < (MBM_V_MAXFILES/2)) { MBM_current = 1; def_response = response; goto draw_bookmark_list; } } option_statusline(ACCEPT_DATA); if (a > 0) { start_bold(); if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) move( (3 + a) - ((MBM_V_MAXFILES/2 + 1)*(MBM_current - 1)), 9); else move((3 + a), 9); strcpy(MBM_tmp_line, (!MBM_A_subdescript[a] ? "" : MBM_A_subdescript[a])); ch = LYgetstr(MBM_tmp_line, VISIBLE, sizeof(MBM_tmp_line), NORECALL); stop_bold(); if (strlen(MBM_tmp_line) < 1) { FREE(MBM_A_subdescript[a]); } else { StrAllocCopy(MBM_A_subdescript[a], MBM_tmp_line); } if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) move( (3 + a) - ((MBM_V_MAXFILES/2 + 1)*(MBM_current - 1)), 5); else move((3 + a), 5); addch((unsigned char)(a + 'A')); addstr(" : "); if (MBM_A_subdescript[a]) addstr(MBM_A_subdescript[a]); clrtoeol(); refresh(); } if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) move((3 + a) - ((MBM_V_MAXFILES/2 + 1)*(MBM_current - 1)), 35); else move((3 + a), 35); addstr("| "); start_bold(); strcpy(MBM_tmp_line, (!MBM_A_subbookmark[a] ? "" : MBM_A_subbookmark[a])); ch = LYgetstr(MBM_tmp_line, VISIBLE, sizeof(MBM_tmp_line), NORECALL); stop_bold(); if (*MBM_tmp_line == '\0') { if (a == 0) StrAllocCopy(MBM_A_subbookmark[a], bookmark_page); else FREE(MBM_A_subbookmark[a]); } else if (!LYPathOffHomeOK(MBM_tmp_line, sizeof(MBM_tmp_line))) { LYMBM_statusline(USE_PATH_OFF_HOME); sleep(AlertSecs); } else { StrAllocCopy(MBM_A_subbookmark[a], MBM_tmp_line); if (a == 0) { StrAllocCopy(bookmark_page, MBM_A_subbookmark[a]); } } if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) move((3 + a) - ((MBM_V_MAXFILES/2 + 1)*(MBM_current-1)), 35); else move((3 + a), 35); addstr("| "); if (MBM_A_subbookmark[a]) addstr(MBM_A_subbookmark[a]); clrtoeol(); move(LYlines-1, 0); clrtoeol(); break; } } /* end for */ } /* end while */ term_options = FALSE; signal(SIGINT, cleanup_sig); } /* ** This function prompts for a choice or page number. ** If a 'g' or 'p' suffix is included, that will be ** loaded into c. Otherwise, c is zeroed. - FM */ PRIVATE int get_popup_choice_number ARGS1( int *, c) { char temp[120]; /* * Load the c argument into the prompt buffer. */ temp[0] = *c; temp[1] = '\0'; option_statusline(OPTION_CHOICE_NUMBER); /* * Get the number, possibly with a suffix, from the user. */ if (LYgetstr(temp, VISIBLE, sizeof(temp), NORECALL) < 0 || *temp == 0 || term_options) { option_statusline(CANCELLED); sleep(InfoSecs); *c = '\0'; term_options = FALSE; return(0); } /* * If we had a 'g' or 'p' suffix, load it into c. * Otherwise, zero c. Then return the number. */ if (strchr(temp, 'g') != NULL || strchr(temp, 'G') != NULL) { *c = 'g'; } else if (strchr(temp, 'p') != NULL || strchr(temp, 'P') != NULL) { *c = 'p'; } else { *c = '\0'; } return(atoi(temp)); } /* * This function offers the choices for values of an * option via a popup window which functions like * that for selection of options in a form. - FM */ PRIVATE int popup_choice ARGS6( int, cur_choice, int, line, int, column, char **, choices, int, i_length, int, disabled) { int ly = line; int lx = (column >= 0 ? column : (COL_OPTION_VALUES - 1)); int c = 0, cmd = 0, i = 0, j = 0; int orig_choice = cur_choice; #ifndef USE_SLANG WINDOW * form_window; #endif /* !USE_SLANG */ int num_choices = 0, top, bottom, length = -1, width = 0; char ** Cptr = choices; int window_offset = 0; int DisplayLines = (LYlines - 2); char Cnum[64]; int Lnum; int npages; #ifdef VMS extern BOOLEAN HadVMSInterrupt; /* Flag from cleanup_sig() AST */ #endif /* VMS */ static char prev_target[512]; /* Search string buffer */ static char prev_target_buffer[512]; /* Next search buffer */ static BOOL first = TRUE; char *cp; int ch = 0, recall; int QueryTotal; int QueryNum; BOOLEAN FirstRecall = TRUE; BOOLEAN ReDraw = FALSE; int number; char buffer[512]; /* * Initialize the search string buffer. - FM */ if (first) { *prev_target_buffer = '\0'; first = FALSE; } *prev_target = '\0'; QueryTotal = (search_queries ? HTList_count(search_queries) : 0); recall = ((QueryTotal >= 1) ? RECALL : NORECALL); QueryNum = QueryTotal; /* * Count the number of choices to be displayed, where * num_choices ranges from 0 to n, and set width to the * longest choice string length. Also set Lnum to the * length for the highest choice number, then decrement * num_choices so as to be zero-based. The window width * will be based on the sum of width and Lnum. - FM */ for (num_choices = 0; Cptr[num_choices] != NULL; num_choices++) { if (strlen(Cptr[num_choices]) > width) { width = strlen(Cptr[num_choices]); } } sprintf(Cnum, "%d: ", num_choices); Lnum = strlen(Cnum); num_choices--; /* * Let's assume for the sake of sanity that ly is the number * corresponding to the line the option is on. * Let's also assume that cur_choice is the number of the * choice that should be initially selected, with 0 being * the first choice. * So what we have, is the top equal to the current screen line * subtracting the cur_choice + 1 (the one must be for the top * line we will draw in a box). If the top goes under 0, then * consider it 0. */ top = ly - (cur_choice + 1); if (top < 0) top = 0; /* * Check and see if we need to put the i_length parameter up to * the number of real choices. */ if (i_length < 1) { i_length = num_choices; } else { /* * Otherwise, it is really one number too high. */ i_length--; } /* * The bottom is the value of the top plus the number of choices * to view plus 3 (one for the top line, one for the bottom line, * and one to offset the 0 counted in the num_choices). */ bottom = top + i_length + 3; /* * Hmm... If the bottom goes beyond the number of lines available, */ if (bottom > DisplayLines) { /* * Position the window at the top if we have more * choices than will fit in the window. */ if ((i_length + 3) > DisplayLines) { top = 0; bottom = (top + (i_length + 3)); if (bottom > DisplayLines) bottom = (DisplayLines + 1); } else { /* * Try to position the window so that the selected choice will * appear where the choice box currently is positioned. * It could end up too high, at this point, but we'll move it * down latter, if that has happened. */ top = (DisplayLines + 1) - (i_length + 3); bottom = (DisplayLines + 1); } } /* * This is really fun, when the length is 4, it means 0 to 4, or 5. */ length = (bottom - top) - 2; /* * Move the window down if it's too high. */ if (bottom < ly + 2) { bottom = ly + 2; if (bottom > DisplayLines + 1) bottom = DisplayLines + 1; top = bottom - length - 2; } /* * Set up the overall window, including the boxing characters ('*'), * if it all fits. Otherwise, set up the widest window possible. - FM */ #ifdef USE_SLANG SLsmg_fill_region(top, lx - 1, bottom - top, (Lnum + width + 4), ' '); #else if (!(form_window = newwin(bottom - top, (Lnum + width + 4), top, (lx - 1))) && !(form_window = newwin(bottom - top, 0, top, 0))) { option_statusline(POPUP_FAILED); return(orig_choice); } scrollok(form_window, TRUE); #ifdef PDCURSES keypad(form_window, TRUE); #endif /* PDCURSES */ #ifdef NCURSES LYsubwindow(form_window); #endif #if defined(HAVE_GETBKGD) /* not defined in ncurses 1.8.7 */ wbkgd(form_window, getbkgd(stdscr)); wbkgdset(form_window, getbkgd(stdscr)); #endif #endif /* USE_SLANG */ /* * Clear the command line and write * the popup statusline. - FM */ move((LYlines - 2), 0); clrtoeol(); if (disabled) { option_statusline(CHOICE_LIST_UNM_MSG); } else { option_statusline(CHOICE_LIST_MESSAGE); } /* * Set up the window_offset for choices. * cur_choice ranges from 0...n * length ranges from 0...m */ if (cur_choice >= length) { window_offset = cur_choice - length + 1; } /* * Compute the number of popup window pages. - FM */ npages = ((num_choices + 1) > length) ? (((num_choices + 1) + (length - 1))/(length)) : 1; /* * OH! I LOVE GOTOs! hack hack hack */ redraw: Cptr = choices; /* * Display the boxed choices. */ for (i = 0; i <= num_choices; i++) { if (i >= window_offset && i - window_offset < length) { sprintf(Cnum, "%s%d: ", ((num_choices > 8 && i < 9) ? " " : ""), (i + 1)); #ifdef USE_SLANG SLsmg_gotorc(top + ((i + 1) - window_offset), (lx - 1 + 2)); addstr(Cnum); SLsmg_write_nstring(Cptr[i], width); #else wmove(form_window, ((i + 1) - window_offset), 2); wclrtoeol(form_window); waddstr(form_window, Cnum); waddstr(form_window, Cptr[i]); #endif /* USE_SLANG */ } } #ifdef USE_SLANG SLsmg_draw_box(top, (lx - 1), (bottom - top), (Lnum + width + 4)); #else #ifdef VMS VMSbox(form_window, (bottom - top), (Lnum + width + 4)); #else LYbox(form_window, FALSE); #endif /* VMS */ wrefresh(form_window); #endif /* USE_SLANG */ Cptr = NULL; /* * Loop on user input. */ while (cmd != LYK_ACTIVATE) { /* * Unreverse cur choice. */ if (Cptr != NULL) { sprintf(Cnum, "%s%d: ", ((num_choices > 8 && i < 9) ? " " : ""), (i + 1)); #ifdef USE_SLANG SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 2)); addstr(Cnum); SLsmg_write_nstring(Cptr[i], width); #else wmove(form_window, ((i + 1) - window_offset), 2); waddstr(form_window, Cnum); waddstr(form_window, Cptr[i]); #endif /* USE_SLANG */ } Cptr = choices; i = cur_choice; sprintf(Cnum, "%s%d: ", ((num_choices > 8 && i < 9) ? " " : ""), (i + 1)); #ifdef USE_SLANG SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 2)); addstr(Cnum); SLsmg_set_color(2); SLsmg_write_nstring(Cptr[i], width); SLsmg_set_color(0); /* * If LYShowCursor is ON, move the cursor to the left * of the current choice, so that blind users, who are * most likely to have LYShowCursor ON, will have it's * string spoken or passed to the braille interface as * each choice is made current. Otherwise, move it to * the bottom, right column of the screen, to "hide" * the cursor as for the main document, and let sighted * users rely on the current choice's highlighting or * color without the distraction of a blinking cursor * in the window. - FM */ if (LYShowCursor) SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 1)); else SLsmg_gotorc((LYlines - 1), (LYcols - 1)); SLsmg_refresh(); #else wmove(form_window, ((i + 1) - window_offset), 2); waddstr(form_window, Cnum); wstart_reverse(form_window); waddstr(form_window, Cptr[i]); wstop_reverse(form_window); /* * If LYShowCursor is ON, move the cursor to the left * of the current choice, so that blind users, who are * most likely to have LYShowCursor ON, will have it's * string spoken or passed to the braille interface as * each choice is made current. Otherwise, leave it to * the right of the current choice, since we can't move * it out of the window, and let sighted users rely on * the highlighting of the current choice without the * distraction of a blinking cursor preceding it. - FM */ if (LYShowCursor) wmove(form_window, ((i + 1) - window_offset), 1); wrefresh(form_window); #endif /* USE_SLANG */ term_options = FALSE; c = LYgetch(); if (term_options || c == 3 || c == 7) { /* * Control-C or Control-G */ cmd = LYK_QUIT; } else { cmd = keymap[c+1]; } #ifdef VMS if (HadVMSInterrupt) { HadVMSInterrupt = FALSE; cmd = LYK_QUIT; } #endif /* VMS */ switch(cmd) { case LYK_F_LINK_NUM: c = '\0'; case LYK_1: case LYK_2: case LYK_3: case LYK_4: case LYK_5: case LYK_6: case LYK_7: case LYK_8: case LYK_9: /* * Get a number from the user, possibly with * a 'g' or 'p' suffix (which will be loaded * into c). - FM & LE */ number = get_popup_choice_number((int *)&c); /* * Check for a 'p' suffix. - FM */ if (c == 'p') { /* * Treat 1 or less as the first page. - FM */ if (number <= 1) { if (window_offset == 0) { option_statusline(ALREADY_AT_CHOICE_BEGIN); sleep(MessageSecs); if (disabled) { option_statusline(CHOICE_LIST_UNM_MSG); } else { option_statusline(CHOICE_LIST_MESSAGE); } break; } window_offset = 0; cur_choice = 0; if (disabled) { option_statusline(CHOICE_LIST_UNM_MSG); } else { option_statusline(CHOICE_LIST_MESSAGE); } goto redraw; } /* * Treat a number equal to or greater than the * number of pages as the last page. - FM */ if (number >= npages) { if (window_offset >= ((num_choices - length) + 1)) { option_statusline(ALREADY_AT_CHOICE_END); sleep(MessageSecs); if (disabled) { option_statusline(CHOICE_LIST_UNM_MSG); } else { option_statusline(CHOICE_LIST_MESSAGE); } break; } window_offset = ((npages - 1) * length); if (window_offset > (num_choices - length)) { window_offset = (num_choices - length + 1); } if (cur_choice < window_offset) cur_choice = window_offset; if (disabled) { option_statusline(CHOICE_LIST_UNM_MSG); } else { option_statusline(CHOICE_LIST_MESSAGE); } goto redraw; } /* * We want an intermediate page. - FM */ if (((number - 1) * length) == window_offset) { sprintf(buffer, ALREADY_AT_CHOICE_PAGE, number); option_statusline(buffer); sleep(MessageSecs); if (disabled) { option_statusline(CHOICE_LIST_UNM_MSG); } else { option_statusline(CHOICE_LIST_MESSAGE); } break; } cur_choice = window_offset = ((number - 1) * length); if (disabled) { option_statusline(CHOICE_LIST_UNM_MSG); } else { option_statusline(CHOICE_LIST_MESSAGE); } goto redraw; } /* * Check for a positive number, which signifies * that a choice should be sought. - FM */ if (number > 0) { /* * Decrement the number so as to correspond * with our cur_choice values. - FM */ number--; /* * If the number is in range and had no legal * suffix, select the indicated choice. - FM */ if (number <= num_choices && c == '\0') { cur_choice = number; cmd = LYK_ACTIVATE; break; } /* * Verify that we had a 'g' suffix, * and act on the number. - FM */ if (c == 'g') { if (cur_choice == number) { /* * The choice already is current. - FM */ sprintf(buffer, CHOICE_ALREADY_CURRENT, (number + 1)); option_statusline(buffer); sleep(MessageSecs); if (disabled) { option_statusline(CHOICE_LIST_UNM_MSG); } else { option_statusline(CHOICE_LIST_MESSAGE); } break; } if (number <= num_choices) { /* * The number is in range and had a 'g' * suffix, so make it the current choice, * scrolling if needed. - FM */ j = (number - cur_choice); cur_choice = number; if ((j > 0) && (cur_choice - window_offset) >= length) { window_offset += j; if (window_offset > (num_choices - length + 1)) window_offset = (num_choices - length + 1); } else if ((cur_choice - window_offset) < 0) { window_offset -= abs(j); if (window_offset < 0) window_offset = 0; } if (disabled) { option_statusline(CHOICE_LIST_UNM_MSG); } else { option_statusline(CHOICE_LIST_MESSAGE); } goto redraw; } /* * Not in range. - FM */ option_statusline(BAD_CHOICE_NUM_ENTERED); sleep(MessageSecs); } } /* * Restore the popup statusline. - FM */ if (disabled) { option_statusline(CHOICE_LIST_UNM_MSG); } else { option_statusline(CHOICE_LIST_MESSAGE); } break; case LYK_PREV_LINK: case LYK_UP_LINK: if (cur_choice > 0) cur_choice--; /* * Scroll the window up if necessary. */ if ((cur_choice - window_offset) < 0) { window_offset--; goto redraw; } break; case LYK_NEXT_LINK: case LYK_DOWN_LINK: if (cur_choice < num_choices) cur_choice++; /* * Scroll the window down if necessary */ if ((cur_choice - window_offset) >= length) { window_offset++; goto redraw; } break; case LYK_NEXT_PAGE: /* * Okay, are we on the last page of the choices list? * If not then, */ if (window_offset != (num_choices - length + 1)) { /* * Modify the current choice to not be a * coordinate in the list, but a coordinate * on the item selected in the window. */ cur_choice -= window_offset; /* * Page down the proper length for the list. * If simply to far, back up. */ window_offset += length; if (window_offset > (num_choices - length)) { window_offset = (num_choices - length + 1); } /* * Readjust the current choice to be a choice * list coordinate rather than window. * Redraw this thing. */ cur_choice += window_offset; goto redraw; } else if (cur_choice < num_choices) { /* * Already on last page of the choice list so * just redraw it with the last item selected. */ cur_choice = num_choices; } break; case LYK_PREV_PAGE: /* * Are we on the first page of the choice list? * If not then, */ if (window_offset != 0) { /* * Modify the current choice to not be a choice * list coordinate, but a window coordinate. */ cur_choice -= window_offset; /* * Page up the proper length. * If too far, back up. */ window_offset -= length; if (window_offset < 0) { window_offset = 0; } /* * Readjust the current choice. */ cur_choice += window_offset; goto redraw; } else if (cur_choice > 0) { /* * Already on the first page so just * back up to the first item. */ cur_choice = 0; } break; case LYK_HOME: cur_choice = 0; if (window_offset > 0) { window_offset = 0; goto redraw; } break; case LYK_END: cur_choice = num_choices; if (window_offset != (num_choices - length + 1)) { window_offset = (num_choices - length + 1); goto redraw; } break; case LYK_DOWN_TWO: cur_choice += 2; if (cur_choice > num_choices) cur_choice = num_choices; /* * Scroll the window down if necessary. */ if ((cur_choice - window_offset) >= length) { window_offset += 2; if (window_offset > (num_choices - length + 1)) window_offset = (num_choices - length + 1); goto redraw; } break; case LYK_UP_TWO: cur_choice -= 2; if (cur_choice < 0) cur_choice = 0; /* * Scroll the window up if necessary. */ if ((cur_choice - window_offset) < 0) { window_offset -= 2; if (window_offset < 0) window_offset = 0; goto redraw; } break; case LYK_DOWN_HALF: cur_choice += (length/2); if (cur_choice > num_choices) cur_choice = num_choices; /* * Scroll the window down if necessary. */ if ((cur_choice - window_offset) >= length) { window_offset += (length/2); if (window_offset > (num_choices - length + 1)) window_offset = (num_choices - length + 1); goto redraw; } break; case LYK_UP_HALF: cur_choice -= (length/2); if (cur_choice < 0) cur_choice = 0; /* * Scroll the window up if necessary. */ if ((cur_choice - window_offset) < 0) { window_offset -= (length/2); if (window_offset < 0) window_offset = 0; goto redraw; } break; case LYK_REFRESH: lynx_force_repaint(); refresh(); break; case LYK_NEXT: if (recall && *prev_target_buffer == '\0') { /* * We got a 'n'ext command with no prior query * specified within the popup window. See if * one was entered when the popup was retracted, * and if so, assume that's what's wanted. Note * that it will become the default within popups, * unless another is entered within a popup. If * the within popup default is to be changed at * that point, use WHEREIS ('/') and enter it, * or the up- or down-arrow keys to seek any of * the previously entered queries, regardless of * whether they were entered within or outside * of a popup window. - FM */ if ((cp = (char *)HTList_objectAt(search_queries, 0)) != NULL) { strcpy(prev_target_buffer, cp); QueryNum = 0; FirstRecall = FALSE; } } strcpy(prev_target, prev_target_buffer); case LYK_WHEREIS: if (*prev_target == '\0' ) { option_statusline(ENTER_WHEREIS_QUERY); if ((ch = LYgetstr(prev_target, VISIBLE, sizeof(prev_target_buffer), recall)) < 0) { /* * User cancelled the search via ^G. - FM */ option_statusline(CANCELLED); sleep(InfoSecs); goto restore_popup_statusline; } } check_recall: if (*prev_target == '\0' && !(recall && (ch == UPARROW || ch == DNARROW))) { /* * No entry. Simply break. - FM */ option_statusline(CANCELLED); sleep(InfoSecs); goto restore_popup_statusline; } if (recall && ch == UPARROW) { if (FirstRecall) { /* * Use the current string or * last query in the list. - FM */ FirstRecall = FALSE; if (*prev_target_buffer) { for (QueryNum = (QueryTotal - 1); QueryNum > 0; QueryNum--) { if ((cp = (char *)HTList_objectAt( search_queries, QueryNum)) != NULL && !strcmp(prev_target_buffer, cp)) { break; } } } else { QueryNum = 0; } } else { /* * Go back to the previous query in the list. - FM */ QueryNum++; } if (QueryNum >= QueryTotal) /* * Roll around to the last query in the list. - FM */ QueryNum = 0; if ((cp = (char *)HTList_objectAt(search_queries, QueryNum)) != NULL) { strcpy(prev_target, cp); if (*prev_target_buffer && !strcmp(prev_target_buffer, prev_target)) { option_statusline(EDIT_CURRENT_QUERY); } else if ((*prev_target_buffer && QueryTotal == 2) || (!(*prev_target_buffer) && QueryTotal == 1)) { option_statusline(EDIT_THE_PREV_QUERY); } else { option_statusline(EDIT_A_PREV_QUERY); } if ((ch = LYgetstr(prev_target, VISIBLE, sizeof(prev_target_buffer), recall)) < 0) { /* * User cancelled the search via ^G. - FM */ option_statusline(CANCELLED); sleep(InfoSecs); goto restore_popup_statusline; } goto check_recall; } } else if (recall && ch == DNARROW) { if (FirstRecall) { /* * Use the current string or * first query in the list. - FM */ FirstRecall = FALSE; if (*prev_target_buffer) { for (QueryNum = 0; QueryNum < (QueryTotal - 1); QueryNum++) { if ((cp = (char *)HTList_objectAt( search_queries, QueryNum)) != NULL && !strcmp(prev_target_buffer, cp)) { break; } } } else { QueryNum = (QueryTotal - 1); } } else { /* * Advance to the next query in the list. - FM */ QueryNum--; } if (QueryNum < 0) /* * Roll around to the first query in the list. - FM */ QueryNum = (QueryTotal - 1); if ((cp = (char *)HTList_objectAt(search_queries, QueryNum)) != NULL) { strcpy(prev_target, cp); if (*prev_target_buffer && !strcmp(prev_target_buffer, prev_target)) { option_statusline(EDIT_CURRENT_QUERY); } else if ((*prev_target_buffer && QueryTotal == 2) || (!(*prev_target_buffer) && QueryTotal == 1)) { option_statusline(EDIT_THE_PREV_QUERY); } else { option_statusline(EDIT_A_PREV_QUERY); } if ((ch = LYgetstr(prev_target, VISIBLE, sizeof(prev_target_buffer), recall)) < 0) { /* * User cancelled the search via ^G. - FM */ option_statusline(CANCELLED); sleep(InfoSecs); goto restore_popup_statusline; } goto check_recall; } } /* * Replace the search string buffer with the new target. - FM */ strcpy(prev_target_buffer, prev_target); HTAddSearchQuery(prev_target_buffer); /* * Start search at the next choice. - FM */ for (j = 1; Cptr[i+j] != NULL; j++) { sprintf(buffer, "%s%d: %s", ((num_choices > 8 && (j + i) < 9) ? " " : ""), (i + j + 1), Cptr[i+j]); if (case_sensitive) { if (strstr(buffer, prev_target_buffer) != NULL) break; } else { if (LYstrstr(buffer, prev_target_buffer) != NULL) break; } } if (Cptr[i+j] != NULL) { /* * We have a hit, so make that choice the current. - FM */ cur_choice += j; /* * Scroll the window down if necessary. */ if ((cur_choice - window_offset) >= length) { window_offset += j; if (window_offset > (num_choices - length + 1)) window_offset = (num_choices - length + 1); ReDraw = TRUE; } goto restore_popup_statusline; } /* * If we started at the beginning, it can't be present. - FM */ if (cur_choice == 0) { option_user_message(STRING_NOT_FOUND, prev_target_buffer); sleep(MessageSecs); goto restore_popup_statusline; } /* * Search from the beginning to the current choice. - FM */ for (j = 0; j < cur_choice; j++) { sprintf(buffer, "%s%d: %s", ((num_choices > 8 && j < 9) ? " " : ""), (j + 1), Cptr[j]); if (case_sensitive) { if (strstr(buffer, prev_target_buffer) != NULL) break; } else { if (LYstrstr(buffer, prev_target_buffer) != NULL) break; } } if (j < cur_choice) { /* * We have a hit, so make that choice the current. - FM */ j = (cur_choice - j); cur_choice -= j; /* * Scroll the window up if necessary. */ if ((cur_choice - window_offset) < 0) { window_offset -= j; if (window_offset < 0) window_offset = 0; ReDraw = TRUE; } goto restore_popup_statusline; } /* * Didn't find it in the preceding choices either. - FM */ option_user_message(STRING_NOT_FOUND, prev_target_buffer); sleep(MessageSecs); restore_popup_statusline: /* * Restore the popup statusline and * reset the search variables. - FM */ if (disabled) option_statusline(CHOICE_LIST_UNM_MSG); else option_statusline(CHOICE_LIST_MESSAGE); *prev_target = '\0'; QueryTotal = (search_queries ? HTList_count(search_queries) : 0); recall = ((QueryTotal >= 1) ? RECALL : NORECALL); QueryNum = QueryTotal; if (ReDraw == TRUE) { ReDraw = FALSE; goto redraw; } break; case LYK_QUIT: case LYK_ABORT: case LYK_PREV_DOC: cur_choice = orig_choice; term_options = TRUE; option_statusline(CANCELLED); sleep(MessageSecs); cmd = LYK_ACTIVATE; /* to exit */ break; } } #ifndef USE_SLANG delwin(form_window); #ifdef NCURSES LYsubwindow(0); #endif #endif /* !USE_SLANG */ if (disabled || term_options) { option_statusline(""); return(orig_choice); } else { option_statusline(VALUE_ACCEPTED); return(cur_choice); } }