/* $LynxId: LYOptions.c,v 1.164 2013/10/25 01:10:17 tom Exp $ */ #include #include #include /* 'reloading' flag */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef USE_COLOR_STYLE #include #endif #include BOOLEAN term_options; #define TOP_LINK "/" #define MBM_LINK "//MBM_MENU" #define MARGIN_STR (no_margins ? "" : "  ") #define MARGIN_LEN (no_margins ? 0 : 2) static void terminate_options(int sig); #define COL_OPTION_VALUES 36 /* display column where option values start */ #if defined(USE_SLANG) || defined(COLOR_CURSES) static BOOLEAN can_do_colors = FALSE; #endif static int LYChosenShowColor = SHOW_COLOR_UNKNOWN; /* whether to show and save */ BOOLEAN LYCheckUserAgent(void) { if (non_empty(LYUserAgent)) { if (strstr(LYUserAgent, "Lynx") == 0 && strstr(LYUserAgent, "lynx") == 0 && strstr(LYUserAgent, "L_y_n_x") == 0 && strstr(LYUserAgent, "l_y_n_x") == 0) { return FALSE; } } return TRUE; } static void validate_x_display(void) { char *cp; if ((cp = LYgetXDisplay()) != NULL) { StrAllocCopy(x_display, cp); } else { FREE(x_display); } } static void summarize_x_display(char *display_option) { if ((x_display == NULL && *display_option == '\0') || (x_display != NULL && !strcmp(x_display, display_option))) { if (x_display == NULL && LYisConfiguredForX == TRUE) { _statusline(VALUE_ACCEPTED_WARNING_X); } else if (x_display != NULL && LYisConfiguredForX == FALSE) { _statusline(VALUE_ACCEPTED_WARNING_NONX); } else { _statusline(VALUE_ACCEPTED); } } else { if (*display_option) { _statusline(FAILED_TO_SET_DISPLAY); } else { _statusline(FAILED_CLEAR_SET_DISPLAY); } } } static void SetupChosenShowColor(void) { #if defined(USE_SLANG) || defined(COLOR_CURSES) can_do_colors = TRUE; #if defined(COLOR_CURSES) if (LYCursesON) /* could crash if called before initialization */ can_do_colors = (has_colors() ? TRUE : FALSE); #endif if (!no_option_save) { 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 (!can_do_colors) LYChosenShowColor = SHOW_COLOR_ALWAYS; else 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 */ } #ifndef NO_OPTION_MENU static int boolean_choice(int status, int line, int column, STRING2PTR choices); #define LYChooseBoolean(status, line, column, choices) \ (BOOLEAN) boolean_choice(status, line, column, (const char *const*)choices) #define LYChooseEnum(status, line, column, choices) \ boolean_choice(status, line, column, (const char *const*)choices) #define MAXCHOICES 10 /* * Values for the options menu. - FM * * L_foo values are the Y coordinates for the menu item. * B_foo values are the X coordinates for the item's prompt string. * C_foo values are the X coordinates for the item's value string. */ #define L_EDITOR 2 #define L_DISPLAY 3 #define L_HOME 4 #define C_MULTI 24 #define B_BOOK 34 #define C_DEFAULT 50 #define L_FTPSTYPE 5 #define L_MAIL_ADDRESS 6 #define L_SSEARCH 7 #define L_LANGUAGE 8 #define L_PREF_CHARSET 9 #define L_ASSUME_CHARSET (L_PREF_CHARSET + 1) #define L_CHARSET 10 #define L_RAWMODE 11 #define L_COLOR L_RAWMODE #define B_COLOR 44 #define C_COLOR 62 #define L_BOOL_A 12 #define B_VIKEYS 5 #define C_VIKEYS 15 #define B_EMACSKEYS 22 #define C_EMACSKEYS 36 #define B_SHOW_DOTFILES 44 #define C_SHOW_DOTFILES 62 #define L_BOOL_B 13 #define B_SELECT_POPUPS 5 #define C_SELECT_POPUPS 36 #define B_SHOW_CURSOR 44 #define C_SHOW_CURSOR 62 #define L_KEYPAD 14 #define L_LINEED 15 #define L_LAYOUT 16 #ifdef DIRED_SUPPORT #define L_DIRED 17 #define L_USER_MODE 18 #define L_USER_AGENT 19 #define L_EXEC 20 #else #define L_USER_MODE 17 #define L_USER_AGENT 18 #define L_EXEC 19 #endif /* DIRED_SUPPORT */ #define L_VERBOSE_IMAGES L_USER_MODE #define B_VERBOSE_IMAGES 50 #define C_VERBOSE_IMAGES (B_VERBOSE_IMAGES + 21) /* a kludge to add assume_charset only in ADVANCED mode... */ #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_Layout (use_assume_charset ? L_LAYOUT + 1 : L_LAYOUT) #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) #define LPAREN '(' #define RPAREN ')' static int add_it(char *text, int len) { if (len) { text[len] = '\0'; LYaddstr(text); } return 0; } /* * addlbl() is used instead of plain LYaddstr() in old-style options menu * to show hot keys in bold. */ static void addlbl(const char *text) { char actual[80]; int s, d; BOOL b = FALSE; for (s = d = 0; text[s]; s++) { actual[d++] = text[s]; if (text[s] == LPAREN) { d = add_it(actual, d - 1); lynx_start_bold(); b = TRUE; actual[d++] = text[s]; } else if (text[s] == RPAREN) { d = add_it(actual, d); lynx_stop_bold(); b = FALSE; } } add_it(actual, d); if (b) lynx_stop_bold(); } #if !defined(VMS) || defined(USE_SLANG) #define HANDLE_LYOPTIONS \ if (term_options) { \ term_options = FALSE; \ } else { \ AddValueAccepted = TRUE; \ } \ goto draw_options #else #define HANDLE_LYOPTIONS \ term_options = FALSE; \ if (use_assume_charset != old_use_assume_charset) \ goto draw_options #endif /* !VMS || USE_SLANG */ void LYoptions(void) { #define ShowBool(value) LYaddstr((value) ? "ON " : "OFF") static const char *bool_choices[] = { "OFF", "ON", NULL }; static const char *const caseless_choices[] = { "CASE INSENSITIVE", "CASE SENSITIVE", NULL }; #ifdef DIRED_SUPPORT static const char *dirList_choices[] = { "Directories first", "Files first", "Mixed style", NULL }; #endif #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)) static const char *exec_choices[] = { "ALWAYS OFF", "FOR LOCAL FILES ONLY", #ifndef NEVER_ALLOW_REMOTE_EXEC "ALWAYS ON", #endif /* !NEVER_ALLOW_REMOTE_EXEC */ NULL }; #endif static const char *fileSort_choices[] = { "By Filename", "By Type", "By Size", "By Date", NULL }; static const char *keypad_choices[] = { "Numbers act as arrows", "Links are numbered", "Links and form fields are numbered", NULL }; static const char *mbm_choices[] = { "OFF ", "STANDARD", "ADVANCED", NULL }; static const char *userMode_choices[] = { "Novice", "Intermediate", "Advanced", NULL }; #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)) int itmp; #endif /* ENABLE_OPTS_CHANGE_EXEC */ int response, ch; /* * If the user changes the display we need memory to put it in. */ bstring *my_data = NULL; char *choices[MAXCHOICES]; int CurrentCharSet = current_char_set; int CurrentAssumeCharSet = UCLYhndl_for_unspec; int CurrentShowColor = LYShowColor; BOOLEAN CurrentRawMode = LYRawMode; BOOLEAN AddValueAccepted = FALSE; BOOL use_assume_charset; #if defined(VMS) || defined(USE_SLANG) BOOL old_use_assume_charset; #endif #ifdef DIRED_SUPPORT #ifdef ENABLE_OPTS_CHANGE_EXEC if (LYlines < 24) { HTAlert(OPTION_SCREEN_NEEDS_24); return; } #else if (LYlines < 23) { HTAlert(OPTION_SCREEN_NEEDS_23); return; } #endif /* ENABLE_OPTS_CHANGE_EXEC */ #else #ifdef ENABLE_OPTS_CHANGE_EXEC if (LYlines < 23) { HTAlert(OPTION_SCREEN_NEEDS_23); return; } #else if (LYlines < 22) { HTAlert(OPTION_SCREEN_NEEDS_22); return; } #endif /* ENABLE_OPTS_CHANGE_EXEC */ #endif /* DIRED_SUPPORT */ term_options = FALSE; LYStatusLine = (LYlines - 1); /* screen is otherwise too crowded */ 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 { SetupChosenShowColor(); #endif /* USE_SLANG || COLOR_CURSES */ } use_assume_charset = (BOOLEAN) (user_mode == ADVANCED_MODE); draw_options: #if defined(VMS) || defined(USE_SLANG) old_use_assume_charset = use_assume_charset; #endif /* * NOTE that printw() should be avoided for strings that might have * non-ASCII or multibyte/CJK characters. - FM */ #if defined(FANCY_CURSES) || defined (USE_SLANG) if (enable_scrollback) { LYclear(); } else { LYerase(); } #else LYclear(); #endif /* FANCY_CURSES || USE_SLANG */ LYmove(0, 5); lynx_start_h1_color(); LYaddstr(" Options Menu ("); LYaddstr(LYNX_NAME); LYaddstr(" Version "); LYaddstr(LYNX_VERSION); LYaddch(')'); lynx_stop_h1_color(); LYmove(L_EDITOR, 5); addlbl("(E)ditor : "); LYaddstr(non_empty(editor) ? editor : "NONE"); LYmove(L_DISPLAY, 5); addlbl("(D)ISPLAY variable : "); LYaddstr(non_empty(x_display) ? x_display : "NONE"); LYmove(L_HOME, 5); addlbl("mu(L)ti-bookmarks: "); LYaddstr(mbm_choices[LYMultiBookmarks]); LYmove(L_HOME, B_BOOK); if (LYMultiBookmarks != MBM_OFF) { addlbl("review/edit (B)ookmarks files"); } else { addlbl("(B)ookmark file: "); LYaddstr(non_empty(bookmark_page) ? bookmark_page : "NONE"); } LYmove(L_FTPSTYPE, 5); addlbl("(F)TP sort criteria : "); LYaddstr((HTfileSortMethod == FILE_BY_NAME ? "By Filename" : (HTfileSortMethod == FILE_BY_SIZE ? "By Size " : (HTfileSortMethod == FILE_BY_TYPE ? "By Type " : "By Date ")))); LYmove(L_MAIL_ADDRESS, 5); addlbl("(P)ersonal mail address : "); LYaddstr(non_empty(personal_mail_address) ? personal_mail_address : "NONE"); LYmove(L_SSEARCH, 5); addlbl("(S)earching type : "); LYaddstr(LYcase_sensitive ? "CASE SENSITIVE " : "CASE INSENSITIVE"); LYmove(L_Charset, 5); addlbl("display (C)haracter set : "); LYaddstr(LYchar_set_names[current_char_set]); LYmove(L_LANGUAGE, 5); addlbl("preferred document lan(G)uage: "); LYaddstr(non_empty(language) ? language : "NONE"); LYmove(L_PREF_CHARSET, 5); addlbl("preferred document c(H)arset : "); LYaddstr(non_empty(pref_charset) ? pref_charset : "NONE"); if (use_assume_charset) { LYmove(L_ASSUME_CHARSET, 5); addlbl("(^A)ssume charset if unknown : "); if (UCAssume_MIMEcharset) LYaddstr(UCAssume_MIMEcharset); else LYaddstr((UCLYhndl_for_unspec >= 0) ? LYCharSet_UC[UCLYhndl_for_unspec].MIMEname : "NONE"); } LYmove(L_Rawmode, 5); addlbl("Raw 8-bit or CJK m(O)de : "); ShowBool(LYRawMode); #if defined(USE_SLANG) || defined(COLOR_CURSES) LYmove(L_Color, B_COLOR); addlbl("show color (&) : "); if (no_option_save) { ShowBool(LYShowColor == SHOW_COLOR_OFF); } else { switch (LYChosenShowColor) { case SHOW_COLOR_NEVER: LYaddstr("NEVER "); break; case SHOW_COLOR_OFF: LYaddstr("OFF"); break; case SHOW_COLOR_ON: LYaddstr("ON "); break; case SHOW_COLOR_ALWAYS: #if defined(COLOR_CURSES) if (!has_colors()) LYaddstr("Always try"); else #endif LYaddstr("ALWAYS "); } } #endif /* USE_SLANG || COLOR_CURSES */ LYmove(L_Bool_A, B_VIKEYS); addlbl("(V)I keys: "); ShowBool(vi_keys); LYmove(L_Bool_A, B_EMACSKEYS); addlbl("e(M)acs keys: "); ShowBool(emacs_keys); LYmove(L_Bool_A, B_SHOW_DOTFILES); addlbl("sho(W) dot files: "); ShowBool(!no_dotfiles && show_dotfiles); LYmove(L_Bool_B, B_SELECT_POPUPS); addlbl("popups for selec(T) fields : "); ShowBool(LYSelectPopups); LYmove(L_Bool_B, B_SHOW_CURSOR); addlbl("show cursor (@) : "); ShowBool(LYShowCursor); LYmove(L_Keypad, 5); addlbl("(K)eypad mode : "); LYaddstr((fields_are_numbered() && links_are_numbered()) ? "Links and form fields are numbered" : (links_are_numbered() ? "Links are numbered " : (fields_are_numbered() ? "Form fields are numbered " : "Numbers act as arrows "))); LYmove(L_Lineed, 5); addlbl("li(N)e edit style : "); LYaddstr(LYEditorNames[current_lineedit]); #ifdef EXP_KEYBOARD_LAYOUT LYmove(L_Layout, 5); addlbl("Ke(Y)board layout : "); LYaddstr(LYKbLayoutNames[current_layout]); #endif #ifdef DIRED_SUPPORT LYmove(L_Dired, 5); addlbl("l(I)st directory style : "); LYaddstr((dir_list_style == FILES_FIRST) ? "Files first " : ((dir_list_style == MIXED_STYLE) ? "Mixed style " : "Directories first")); #endif /* DIRED_SUPPORT */ LYmove(L_User_Mode, 5); addlbl("(U)ser mode : "); LYaddstr((user_mode == NOVICE_MODE) ? "Novice " : ((user_mode == INTERMEDIATE_MODE) ? "Intermediate" : "Advanced ")); addlbl(" verbose images (!) : "); ShowBool(verbose_img); LYmove(L_User_Agent, 5); addlbl("user (A)gent : "); LYaddstr(non_empty(LYUserAgent) ? LYUserAgent : "NONE"); #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)) LYmove(L_Exec, 5); addlbl("local e(X)ecution links : "); #ifndef NEVER_ALLOW_REMOTE_EXEC LYaddstr(local_exec ? "ALWAYS ON " : (local_exec_on_local_files ? "FOR LOCAL FILES ONLY" : "ALWAYS OFF ")); #else LYaddstr(local_exec_on_local_files ? "FOR LOCAL FILES ONLY" : "ALWAYS OFF "); #endif /* !NEVER_ALLOW_REMOTE_EXEC */ #endif /* ENABLE_OPTS_CHANGE_EXEC */ LYmove(LYlines - 3, 2); LYaddstr(SELECT_SEGMENT); lynx_start_bold(); LYaddstr(CAP_LETT_SEGMENT); lynx_stop_bold(); LYaddstr(OF_OPT_LINE_SEGMENT); if (!no_option_save) { LYaddstr(" '"); lynx_start_bold(); LYaddstr(">"); lynx_stop_bold(); LYaddstr("'"); LYaddstr(TO_SAVE_SEGMENT); } LYaddstr(OR_SEGMENT); LYaddstr("'"); lynx_start_bold(); LYaddstr("r"); lynx_stop_bold(); LYaddstr("'"); LYaddstr(TO_RETURN_SEGMENT); response = 0; while (response != 'R' && !LYisNonAlnumKeyname(response, LYK_PREV_DOC) && response != '>' && !term_options && !LYCharIsINTERRUPT_NO_letter(response)) { if (AddValueAccepted == TRUE) { _statusline(VALUE_ACCEPTED); AddValueAccepted = FALSE; } LYmove((LYlines - 2), 0); lynx_start_prompt_color(); LYaddstr(COMMAND_PROMPT); lynx_stop_prompt_color(); LYrefresh(); response = LYgetch_single(); if (term_options || LYCharIsINTERRUPT_NO_letter(response)) response = 'R'; if (LYisNonAlnumKeyname(response, LYK_REFRESH)) { lynx_force_repaint(); goto draw_options; } switch (response) { case 'E': /* Change the editor. */ if (no_editor) { _statusline(EDIT_DISABLED); } else if (system_editor) { _statusline(EDITOR_LOCKED); } else { if (non_empty(editor)) { BStrCopy0(my_data, editor); } else { /* clear the NONE */ LYmove(L_EDITOR, COL_OPTION_VALUES); LYaddstr(" "); BStrCopy0(my_data, ""); } _statusline(ACCEPT_DATA); LYmove(L_EDITOR, COL_OPTION_VALUES); lynx_start_bold(); ch = LYgetBString(&my_data, FALSE, 0, NORECALL); lynx_stop_bold(); LYmove(L_EDITOR, COL_OPTION_VALUES); if (term_options || ch == -1) { LYaddstr(non_empty(editor) ? editor : "NONE"); } else if (isBEmpty(my_data)) { FREE(editor); LYaddstr("NONE"); } else { StrAllocCopy(editor, my_data->str); LYaddstr(editor); } LYclrtoeol(); if (ch == -1) { HTInfoMsg(CANCELLED); HTInfoMsg(""); } else { _statusline(VALUE_ACCEPTED); } } response = ' '; break; case 'D': /* Change the display. */ if (non_empty(x_display)) { BStrCopy0(my_data, x_display); } else { /* clear the NONE */ LYmove(L_DISPLAY, COL_OPTION_VALUES); LYaddstr(" "); BStrCopy0(my_data, ""); } _statusline(ACCEPT_DATA); LYmove(L_DISPLAY, COL_OPTION_VALUES); lynx_start_bold(); ch = LYgetBString(&my_data, FALSE, 0, NORECALL); lynx_stop_bold(); LYmove(L_DISPLAY, COL_OPTION_VALUES); #ifdef VMS #define CompareEnvVars(a,b) strcasecomp(a, b) #else #define CompareEnvVars(a,b) strcmp(a, b) #endif /* VMS */ if ((term_options || ch == -1) || (x_display != NULL && !CompareEnvVars(x_display, my_data->str))) { /* * Cancelled, or a non-NULL display string wasn't changed. - * FM */ LYaddstr(non_empty(x_display) ? x_display : "NONE"); LYclrtoeol(); if (ch == -1) { HTInfoMsg(CANCELLED); HTInfoMsg(""); } else { _statusline(VALUE_ACCEPTED); } response = ' '; break; } else if (isBEmpty(my_data)) { if ((x_display == NULL) || (x_display != NULL && *x_display == '\0')) { /* * NULL or zero-length display string wasn't changed. - FM */ LYaddstr("NONE"); LYclrtoeol(); _statusline(VALUE_ACCEPTED); response = ' '; break; } } /* * Set the new DISPLAY variable. - FM */ LYsetXDisplay(my_data->str); validate_x_display(); LYaddstr(x_display ? x_display : "NONE"); LYclrtoeol(); summarize_x_display(my_data->str); response = ' '; break; case 'L': /* Change multibookmarks option. */ if (LYMBMBlocked) { _statusline(MULTIBOOKMARKS_DISALLOWED); response = ' '; break; } if (!LYSelectPopups) { LYMultiBookmarks = LYChooseEnum(LYMultiBookmarks, L_HOME, C_MULTI, mbm_choices); } else { LYMultiBookmarks = LYChoosePopup(LYMultiBookmarks, L_HOME, (C_MULTI - 1), mbm_choices, 3, FALSE, FALSE); } #if defined(VMS) || defined(USE_SLANG) if (LYSelectPopups) { LYmove(L_HOME, C_MULTI); LYclrtoeol(); LYaddstr(mbm_choices[LYMultiBookmarks]); } #endif /* VMS || USE_SLANG */ #if !defined(VMS) && !defined(USE_SLANG) if (!LYSelectPopups) #endif /* !VMS && !USE_SLANG */ { LYmove(L_HOME, B_BOOK); LYclrtoeol(); if (LYMultiBookmarks != MBM_OFF) { LYaddstr(gettext("review/edit B)ookmarks files")); } else { LYaddstr(gettext("B)ookmark file: ")); LYaddstr(non_empty(bookmark_page) ? bookmark_page : "NONE"); } } response = ' '; if (LYSelectPopups) { HANDLE_LYOPTIONS; } break; case 'B': /* Change the bookmark page location. */ /* * Anonymous users should not be allowed to change the bookmark * page. */ if (!no_bookmark) { if (LYMultiBookmarks != MBM_OFF) { edit_bookmarks(); signal(SIGINT, terminate_options); goto draw_options; } if (non_empty(bookmark_page)) { BStrCopy0(my_data, bookmark_page); } else { /* clear the NONE */ LYmove(L_HOME, C_DEFAULT); LYclrtoeol(); BStrCopy0(my_data, ""); } _statusline(ACCEPT_DATA); LYmove(L_HOME, C_DEFAULT); lynx_start_bold(); ch = LYgetBString(&my_data, FALSE, 0, NORECALL); lynx_stop_bold(); LYmove(L_HOME, C_DEFAULT); BStrAlloc(my_data, my_data->len + LY_MAXPATH); /* lengthen */ if (term_options || ch == -1 || isBEmpty(my_data)) { LYaddstr(non_empty(bookmark_page) ? bookmark_page : "NONE"); } else if (!LYPathOffHomeOK(my_data->str, (size_t) my_data->len)) { LYaddstr(non_empty(bookmark_page) ? bookmark_page : "NONE"); LYclrtoeol(); _statusline(USE_PATH_OFF_HOME); response = ' '; break; } else { StrAllocCopy(bookmark_page, my_data->str); StrAllocCopy(MBM_A_subbookmark[0], bookmark_page); LYaddstr(bookmark_page); } LYclrtoeol(); if (ch == -1) { HTInfoMsg(CANCELLED); HTInfoMsg(""); } else { _statusline(VALUE_ACCEPTED); } } else { /* anonymous */ _statusline(BOOKMARK_CHANGE_DISALLOWED); } response = ' '; break; case 'F': /* Change ftp directory sorting. */ if (!LYSelectPopups) { HTfileSortMethod = LYChooseEnum(HTfileSortMethod, L_FTPSTYPE, -1, fileSort_choices); } else { HTfileSortMethod = LYChoosePopup(HTfileSortMethod, L_FTPSTYPE, -1, fileSort_choices, 4, FALSE, FALSE); #if defined(VMS) || defined(USE_SLANG) LYmove(L_FTPSTYPE, COL_OPTION_VALUES); LYclrtoeol(); LYaddstr(fileSort_choices[HTfileSortMethod]); #endif /* VMS || USE_SLANG */ } response = ' '; if (LYSelectPopups) { HANDLE_LYOPTIONS; } break; case 'P': /* Change personal mail address for From headers. */ if (non_empty(personal_mail_address)) { BStrCopy0(my_data, personal_mail_address); } else { /* clear the NONE */ LYmove(L_MAIL_ADDRESS, COL_OPTION_VALUES); LYaddstr(" "); BStrCopy0(my_data, ""); } _statusline(ACCEPT_DATA); LYmove(L_MAIL_ADDRESS, COL_OPTION_VALUES); lynx_start_bold(); ch = LYgetBString(&my_data, FALSE, 0, NORECALL); lynx_stop_bold(); LYmove(L_MAIL_ADDRESS, COL_OPTION_VALUES); if (term_options || ch == -1) { LYaddstr((personal_mail_address && *personal_mail_address) ? personal_mail_address : "NONE"); } else if (isBEmpty(my_data)) { FREE(personal_mail_address); LYaddstr("NONE"); } else { StrAllocCopy(personal_mail_address, my_data->str); LYaddstr(personal_mail_address); } LYclrtoeol(); if (ch == -1) { HTInfoMsg(CANCELLED); HTInfoMsg(""); } else { _statusline(VALUE_ACCEPTED); } response = ' '; break; case 'S': /* Change case sensitivity for searches. */ LYcase_sensitive = LYChooseBoolean(LYcase_sensitive, L_SSEARCH, -1, caseless_choices); response = ' '; break; case '\001': /* Change assume_charset setting. */ if (use_assume_charset) { int i, curval; const char **assume_list; assume_list = typecallocn(const char *, (unsigned) (LYNumCharsets + 1)); if (!assume_list) { outofmem(__FILE__, "options"); } for (i = 0; i < LYNumCharsets; i++) { assume_list[i] = 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) { #ifndef ALL_CHARSETS_IN_O_MENU_SCREEN UCLYhndl_for_unspec = assumed_doc_charset_map[(LYChooseEnum(charset_subsets[curval].assumed_idx, L_ASSUME_CHARSET, -1, assumed_charset_choices) ? 1 : 0)]; #else UCLYhndl_for_unspec = LYChooseEnum(curval, L_ASSUME_CHARSET, -1, assume_list); #endif } else { #ifndef ALL_CHARSETS_IN_O_MENU_SCREEN UCLYhndl_for_unspec = assumed_doc_charset_map[(LYChoosePopup(charset_subsets[curval].assumed_idx, L_ASSUME_CHARSET, -1, assumed_charset_choices, 0, FALSE, FALSE) ? 1 : 0)]; #else UCLYhndl_for_unspec = LYChoosePopup(curval, L_ASSUME_CHARSET, -1, assume_list, 0, FALSE, FALSE); #endif #if defined(VMS) || defined(USE_SLANG) LYmove(L_ASSUME_CHARSET, COL_OPTION_VALUES); LYclrtoeol(); if (UCLYhndl_for_unspec >= 0) LYaddstr(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); } if (HTCJK != JAPANESE) LYRawMode = (BOOLEAN) (UCLYhndl_for_unspec == current_char_set); HTMLSetUseDefaultRawMode(current_char_set, LYRawMode); HTMLSetCharacterHandling(current_char_set); CurrentAssumeCharSet = UCLYhndl_for_unspec; CurrentRawMode = LYRawMode; #if !defined(VMS) && !defined(USE_SLANG) if (!LYSelectPopups) #endif /* !VMS && !USE_SLANG */ { LYmove(L_Rawmode, COL_OPTION_VALUES); LYclrtoeol(); ShowBool(LYRawMode); } } FREE(assume_list); response = ' '; if (LYSelectPopups) { HANDLE_LYOPTIONS; } } else { _statusline(NEED_ADVANCED_USER_MODE); AddValueAccepted = FALSE; } break; case 'C': /* Change display charset setting. */ if (!LYSelectPopups) { #ifndef ALL_CHARSETS_IN_O_MENU_SCREEN displayed_display_charset_idx = LYChooseEnum(displayed_display_charset_idx, L_Charset, -1, display_charset_choices); current_char_set = display_charset_map[displayed_display_charset_idx]; #else current_char_set = LYChooseEnum(current_char_set, L_Charset, -1, LYchar_set_names); #endif } else { #ifndef ALL_CHARSETS_IN_O_MENU_SCREEN displayed_display_charset_idx = LYChoosePopup(displayed_display_charset_idx, L_Charset, -1, display_charset_choices, 0, FALSE, FALSE); current_char_set = display_charset_map[displayed_display_charset_idx]; #else current_char_set = LYChoosePopup(current_char_set, L_Charset, -1, LYchar_set_names, 0, FALSE, FALSE); #endif #if defined(VMS) || defined(USE_SLANG) LYmove(L_Charset, COL_OPTION_VALUES); LYclrtoeol(); LYaddstr(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) { LYUseDefaultRawMode = TRUE; HTMLUseCharacterSet(current_char_set); CurrentCharSet = current_char_set; CurrentRawMode = LYRawMode; #if !defined(VMS) && !defined(USE_SLANG) if (!LYSelectPopups) #endif /* !VMS && !USE_SLANG */ { LYmove(L_Rawmode, COL_OPTION_VALUES); LYclrtoeol(); ShowBool(LYRawMode); } #ifdef CAN_SWITCH_DISPLAY_CHARSET /* Deduce whether the user wants autoswitch: */ switch_display_charsets = (current_char_set == auto_display_charset || current_char_set == auto_other_display_charset); #endif } response = ' '; if (LYSelectPopups) { HANDLE_LYOPTIONS; } break; case 'O': /* Change raw mode setting. */ LYRawMode = LYChooseBoolean(LYRawMode, L_Rawmode, -1, bool_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; } response = ' '; break; case 'G': /* Change language preference. */ if (non_empty(language)) { BStrCopy0(my_data, language); } else { /* clear the NONE */ LYmove(L_LANGUAGE, COL_OPTION_VALUES); LYaddstr(" "); BStrCopy0(my_data, ""); } _statusline(ACCEPT_DATA); LYmove(L_LANGUAGE, COL_OPTION_VALUES); lynx_start_bold(); ch = LYgetBString(&my_data, FALSE, 0, NORECALL); lynx_stop_bold(); LYmove(L_LANGUAGE, COL_OPTION_VALUES); if (term_options || ch == -1) { LYaddstr(non_empty(language) ? language : "NONE"); } else if (isBEmpty(my_data)) { FREE(language); LYaddstr("NONE"); } else { StrAllocCopy(language, my_data->str); LYaddstr(language); } LYclrtoeol(); if (ch == -1) { HTInfoMsg(CANCELLED); HTInfoMsg(""); } else { _statusline(VALUE_ACCEPTED); } response = ' '; break; case 'H': /* Change charset preference. */ if (non_empty(pref_charset)) { BStrCopy0(my_data, pref_charset); } else { /* clear the NONE */ LYmove(L_PREF_CHARSET, COL_OPTION_VALUES); LYaddstr(" "); BStrCopy0(my_data, ""); } _statusline(ACCEPT_DATA); LYmove(L_PREF_CHARSET, COL_OPTION_VALUES); lynx_start_bold(); ch = LYgetBString(&my_data, FALSE, 0, NORECALL); lynx_stop_bold(); LYmove(L_PREF_CHARSET, COL_OPTION_VALUES); if (term_options || ch == -1) { LYaddstr(non_empty(pref_charset) ? pref_charset : "NONE"); } else if (isBEmpty(my_data)) { FREE(pref_charset); LYaddstr("NONE"); } else { StrAllocCopy(pref_charset, my_data->str); LYaddstr(pref_charset); } LYclrtoeol(); if (ch == -1) { HTInfoMsg(CANCELLED); HTInfoMsg(""); } else { _statusline(VALUE_ACCEPTED); } response = ' '; break; case 'V': /* Change VI keys setting. */ vi_keys = LYChooseBoolean(vi_keys, L_Bool_A, C_VIKEYS, bool_choices); if (vi_keys) { set_vi_keys(); } else { reset_vi_keys(); } response = ' '; break; case 'M': /* Change emacs keys setting. */ emacs_keys = LYChooseBoolean(emacs_keys, L_Bool_A, C_EMACSKEYS, bool_choices); if (emacs_keys) { set_emacs_keys(); } else { reset_emacs_keys(); } response = ' '; break; case 'W': /* Change show dotfiles setting. */ if (no_dotfiles) { _statusline(DOTFILE_ACCESS_DISABLED); } else { show_dotfiles = LYChooseBoolean(show_dotfiles, L_Bool_A, C_SHOW_DOTFILES, bool_choices); } response = ' '; break; case 'T': /* Change select popups setting. */ LYSelectPopups = LYChooseBoolean(LYSelectPopups, L_Bool_B, C_SELECT_POPUPS, bool_choices); 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 = LYGetEnv("TERM"); if (terminal) HTUserMsg2(COLOR_TOGGLE_DISABLED_FOR_TERM, terminal); else HTUserMsg(COLOR_TOGGLE_DISABLED); break; } #endif LYShowColor = LYChooseEnum((LYShowColor - 1), L_Color, C_COLOR, bool_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 = LYChooseEnum(LYChosenShowColor, L_Color, C_COLOR, choices); } else { chosen = LYChoosePopup(LYChosenShowColor, L_Color, C_COLOR, choices, 4, FALSE, FALSE); } #if defined(COLOR_CURSES) again = (BOOLEAN) (chosen == SHOW_COLOR_ON && !has_colors()); if (again) { char *terminal = LYGetEnv("TERM"); if (terminal) HTUserMsg2(COLOR_TOGGLE_DISABLED_FOR_TERM, terminal); else HTUserMsg(COLOR_TOGGLE_DISABLED); } #endif } while (again); LYChosenShowColor = chosen; #if defined(VMS) if (LYSelectPopups) { LYmove(L_Color, C_COLOR); LYclrtoeol(); LYaddstr(choices[LYChosenShowColor]); } #endif /* VMS */ #if defined(COLOR_CURSES) if (has_colors()) #endif LYShowColor = chosen; FREE(choices[0]); FREE(choices[1]); FREE(choices[2]); FREE(choices[3]); } if (CurrentShowColor != LYShowColor) { lynx_force_repaint(); } CurrentShowColor = LYShowColor; #ifdef USE_SLANG SLtt_Use_Ansi_Colors = (LYShowColor > SHOW_COLOR_OFF ? TRUE : FALSE); #endif response = ' '; if (LYSelectPopups && !no_option_save) { HANDLE_LYOPTIONS; } break; #endif /* USE_SLANG or COLOR_CURSES */ case '@': /* Change show cursor setting. */ LYShowCursor = LYChooseBoolean(LYShowCursor, L_Bool_B, C_SHOW_CURSOR, bool_choices); response = ' '; break; case 'K': /* Change keypad mode. */ if (!LYSelectPopups) { keypad_mode = LYChooseEnum(keypad_mode, L_Keypad, -1, keypad_choices); } else { keypad_mode = LYChoosePopup(keypad_mode, L_Keypad, -1, keypad_choices, 3, FALSE, FALSE); #if defined(VMS) || defined(USE_SLANG) LYmove(L_Keypad, COL_OPTION_VALUES); LYclrtoeol(); LYaddstr(keypad_choices[keypad_mode]); #endif /* VMS || USE_SLANG */ } if (keypad_mode == NUMBERS_AS_ARROWS) { set_numbers_as_arrows(); } else { reset_numbers_as_arrows(); } response = ' '; if (LYSelectPopups) { HANDLE_LYOPTIONS; } break; case 'N': /* Change line editor key bindings. */ if (!LYSelectPopups) { current_lineedit = LYChooseEnum(current_lineedit, L_Lineed, -1, LYEditorNames); } else { current_lineedit = LYChoosePopup(current_lineedit, L_Lineed, -1, LYEditorNames, 0, FALSE, FALSE); #if defined(VMS) || defined(USE_SLANG) LYmove(L_Lineed, COL_OPTION_VALUES); LYclrtoeol(); LYaddstr(LYEditorNames[current_lineedit]); #endif /* VMS || USE_SLANG */ } response = ' '; if (LYSelectPopups) { HANDLE_LYOPTIONS; } break; #ifdef EXP_KEYBOARD_LAYOUT case 'Y': /* Change keyboard layout */ if (!LYSelectPopups) { current_layout = LYChooseEnum(current_layout, L_Layout, -1, LYKbLayoutNames); } else { current_layout = LYChoosePopup(current_layout, L_Layout, -1, LYKbLayoutNames, 0, FALSE, FALSE); #if defined(VMS) || defined(USE_SLANG) LYmove(L_Layout, COL_OPTION_VALUES); LYclrtoeol(); LYaddstr(LYKbLayoutNames[current_layout]); #endif /* VMS || USE_SLANG */ } response = ' '; if (LYSelectPopups) { HANDLE_LYOPTIONS; } break; #endif /* EXP_KEYBOARD_LAYOUT */ #ifdef DIRED_SUPPORT case 'I': /* Change local directory sorting. */ if (!LYSelectPopups) { dir_list_style = LYChooseEnum(dir_list_style, L_Dired, -1, dirList_choices); } else { dir_list_style = LYChoosePopup(dir_list_style, L_Dired, -1, dirList_choices, 3, FALSE, FALSE); #if defined(VMS) || defined(USE_SLANG) LYmove(L_Dired, COL_OPTION_VALUES); LYclrtoeol(); LYaddstr(dirList_choices[dir_list_style]); #endif /* VMS || USE_SLANG */ } response = ' '; if (LYSelectPopups) { HANDLE_LYOPTIONS; } break; #endif /* DIRED_SUPPORT */ case 'U': /* Change user mode. */ if (!LYSelectPopups) { user_mode = LYChooseEnum(user_mode, L_User_Mode, -1, userMode_choices); use_assume_charset = (BOOLEAN) (user_mode >= 2); } else { user_mode = LYChoosePopup(user_mode, L_User_Mode, -1, userMode_choices, 3, FALSE, FALSE); use_assume_charset = (BOOLEAN) (user_mode >= 2); #if defined(VMS) || defined(USE_SLANG) if (use_assume_charset == old_use_assume_charset) { LYmove(L_User_Mode, COL_OPTION_VALUES); LYclrtoeol(); LYaddstr(userMode_choices[user_mode]); } #endif /* VMS || USE_SLANG */ } LYSetDisplayLines(); response = ' '; if (LYSelectPopups) { HANDLE_LYOPTIONS; } break; case '!': if (!LYSelectPopups) { verbose_img = LYChooseBoolean(verbose_img, L_VERBOSE_IMAGES, C_VERBOSE_IMAGES, bool_choices); } else { verbose_img = (BOOLEAN) LYChoosePopup(verbose_img, L_VERBOSE_IMAGES, C_VERBOSE_IMAGES, bool_choices, 2, FALSE, FALSE); } response = ' '; if (LYSelectPopups) { HANDLE_LYOPTIONS; } break; case 'A': /* Change user agent string. */ if (!no_useragent) { if (non_empty(LYUserAgent)) { BStrCopy0(my_data, LYUserAgent); } else { /* clear the NONE */ LYmove(L_HOME, COL_OPTION_VALUES); LYaddstr(" "); BStrCopy0(my_data, ""); } _statusline(ACCEPT_DATA_OR_DEFAULT); LYmove(L_User_Agent, COL_OPTION_VALUES); lynx_start_bold(); ch = LYgetBString(&my_data, FALSE, 0, NORECALL); lynx_stop_bold(); LYmove(L_User_Agent, COL_OPTION_VALUES); if (term_options || ch == -1) { LYaddstr((LYUserAgent && *LYUserAgent) ? LYUserAgent : "NONE"); } else if (isBEmpty(my_data)) { StrAllocCopy(LYUserAgent, LYUserAgentDefault); LYaddstr((LYUserAgent && *LYUserAgent) ? LYUserAgent : "NONE"); } else { StrAllocCopy(LYUserAgent, my_data->str); LYaddstr(LYUserAgent); } LYclrtoeol(); if (ch == -1) { HTInfoMsg(CANCELLED); HTInfoMsg(""); } else if (!LYCheckUserAgent()) { _statusline(UA_PLEASE_USE_LYNX); } else { _statusline(VALUE_ACCEPTED); } } else { /* disallowed */ _statusline(UA_CHANGE_DISABLED); } response = ' '; break; #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)) case 'X': /* Change local exec restriction. */ if (exec_frozen && !LYSelectPopups) { _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; } } if (!LYSelectPopups) { itmp = LYChooseEnum(itmp, L_Exec, -1, exec_choices); } else { itmp = LYChoosePopup(itmp, L_Exec, -1, exec_choices, 0, (exec_frozen ? TRUE : FALSE), FALSE); #if defined(VMS) || defined(USE_SLANG) LYmove(L_Exec, COL_OPTION_VALUES); LYclrtoeol(); LYaddstr(exec_choices[itmp]); #endif /* VMS || USE_SLANG */ } 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) { HANDLE_LYOPTIONS; } break; #endif /* ENABLE_OPTS_CHANGE_EXEC */ case '>': /* Save current options to RC file. */ if (!no_option_save) { HTInfoMsg(SAVING_OPTIONS); LYrcShowColor = LYChosenShowColor; if (save_rc(NULL)) { HTInfoMsg(OPTIONS_SAVED); } else { HTAlert(OPTIONS_NOT_SAVED); } } else { HTInfoMsg(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). */ break; default: if (!no_option_save) { HTInfoMsg(SAVE_OR_R_TO_RETURN_TO_LYNX); } else { HTInfoMsg(R_TO_RETURN_TO_LYNX); } } /* end switch */ } /* end while */ term_options = FALSE; LYStatusLine = -1; /* let user_mode have some of the screen */ signal(SIGINT, cleanup_sig); BStrFree(my_data); return; } static int widest_choice(STRING2PTR choices) { int n, width = 0; for (n = 0; choices[n] != NULL; ++n) { int len = (int) strlen(choices[n]); if (width < len) width = len; } return width; } static void show_choice(const char *choice, int width) { int len = (int) strlen(choice); LYaddstr(choice); while (len++ < width) LYaddch(' '); } /* * Take a status code, prompt the user for a new status, and return it. */ static int boolean_choice(int cur_choice, int line, int column, STRING2PTR choices) { int response = 0; int cmd = 0; int number = 0; int col = (column >= 0 ? column : COL_OPTION_VALUES); int orig_choice = cur_choice; int width = widest_choice(choices); /* * 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. */ _statusline(ANY_KEY_CHANGE_RET_ACCEPT); /* * Highlight the current choice. */ LYmove(line, col); lynx_start_reverse(); show_choice(choices[cur_choice], width); if (LYShowCursor) LYmove(line, (col - 1)); LYrefresh(); /* * 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) { LYmove(line, col); if (term_options == FALSE) { response = LYgetch_single(); } if (term_options || LYCharIsINTERRUPT_NO_letter(response)) { /* * 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 = LKC_TO_LAC(keymap, response)) != LYK_ACTIVATE) { switch (cmd) { case LYK_HOME: cur_choice = 0; break; case LYK_END: cur_choice = number; break; case LYK_REFRESH: lynx_force_repaint(); LYrefresh(); 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_LPOS_PREV_LINK: case LYK_FASTBACKW_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 */ show_choice(choices[cur_choice], width); if (LYShowCursor) LYmove(line, (col - 1)); LYrefresh(); } else { /* * Unhighlight choice. */ LYmove(line, col); lynx_stop_reverse(); show_choice(choices[cur_choice], width); if (term_options) { term_options = FALSE; HTInfoMsg(CANCELLED); HTInfoMsg(""); } else { _statusline(VALUE_ACCEPTED); } return cur_choice; } } } #endif /* !NO_OPTION_MENU */ static void terminate_options(int sig GCC_UNUSED) { 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(); LYrefresh(); } #endif /* VMS */ } /* * Multi-Bookmark On-Line editing support. - FMG & FM */ void edit_bookmarks(void) { int response = 0, def_response = 0; int MBM_current = 1; #define MULTI_OFFSET 8 int a; /* misc counter */ bstring *my_data = NULL; /* * 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) { LYclear(); } else { LYerase(); } #else LYclear(); #endif /* FANCY_CURSES || USE_SLANG */ LYmove(0, 5); lynx_start_h1_color(); if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) { char *ehead_buffer = 0; HTSprintf0(&ehead_buffer, MULTIBOOKMARKS_EHEAD_MASK, MBM_current); LYaddstr(ehead_buffer); FREE(ehead_buffer); } else { LYaddstr(MULTIBOOKMARKS_EHEAD); } lynx_stop_h1_color(); if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) { for (a = ((MBM_V_MAXFILES / 2 + 1) * (MBM_current - 1)); a <= (MBM_current * MBM_V_MAXFILES / 2); a++) { LYmove((3 + a) - ((MBM_V_MAXFILES / 2 + 1) * (MBM_current - 1)), 5); LYaddch(UCH(LYindex2MBM(a))); LYaddstr(" : "); if (MBM_A_subdescript[a]) LYaddstr(MBM_A_subdescript[a]); LYmove((3 + a) - ((MBM_V_MAXFILES / 2 + 1) * (MBM_current - 1)), 35); LYaddstr("| "); if (MBM_A_subbookmark[a]) { LYaddstr(MBM_A_subbookmark[a]); } } } else { for (a = 0; a <= MBM_V_MAXFILES; a++) { LYmove(3 + a, 5); LYaddch(UCH(LYindex2MBM(a))); LYaddstr(" : "); if (MBM_A_subdescript[a]) LYaddstr(MBM_A_subdescript[a]); LYmove(3 + a, 35); LYaddstr("| "); if (MBM_A_subbookmark[a]) { LYaddstr(MBM_A_subbookmark[a]); } } } /* * Only needed when we have 2 screens. */ if (LYlines < MBM_V_MAXFILES + MULTI_OFFSET) { LYmove((LYlines - 4), 0); LYaddstr("'"); lynx_start_bold(); LYaddstr("["); lynx_stop_bold(); LYaddstr("' "); LYaddstr(PREVIOUS); LYaddstr(", '"); lynx_start_bold(); LYaddstr("]"); lynx_stop_bold(); LYaddstr("' "); LYaddstr(NEXT_SCREEN); } LYmove((LYlines - 3), 0); if (!no_option_save) { LYaddstr("'"); lynx_start_bold(); LYaddstr(">"); lynx_stop_bold(); LYaddstr("'"); LYaddstr(TO_SAVE_SEGMENT); } LYaddstr(OR_SEGMENT); LYaddstr("'"); lynx_start_bold(); LYaddstr("^G"); lynx_stop_bold(); LYaddstr("'"); LYaddstr(TO_RETURN_SEGMENT); while (!term_options && !LYisNonAlnumKeyname(response, LYK_PREV_DOC) && !LYCharIsINTERRUPT_NO_letter(response) && response != '>') { LYmove((LYlines - 2), 0); lynx_start_prompt_color(); LYaddstr(MULTIBOOKMARKS_LETTER); lynx_stop_prompt_color(); LYrefresh(); response = (def_response ? def_response : LYgetch_single()); def_response = 0; /* * Check for a cancel. */ if (term_options || LYCharIsINTERRUPT_NO_letter(response) || LYisNonAlnumKeyname(response, LYK_PREV_DOC)) continue; /* * Check for a save. */ if (response == '>') { if (!no_option_save) { HTInfoMsg(SAVING_OPTIONS); if (save_rc(NULL)) HTInfoMsg(OPTIONS_SAVED); else HTAlert(OPTIONS_NOT_SAVED); } else { HTInfoMsg(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 (LYMBM2index(response) == 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; } } _statusline(ACCEPT_DATA); if (a > 0) { lynx_start_bold(); if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) LYmove((3 + a) - ((MBM_V_MAXFILES / 2 + 1) * (MBM_current - 1)), 9); else LYmove((3 + a), 9); BStrCopy0(my_data, (!MBM_A_subdescript[a] ? "" : MBM_A_subdescript[a])); (void) LYgetBString(&my_data, FALSE, 0, NORECALL); lynx_stop_bold(); if (isBEmpty(my_data)) { FREE(MBM_A_subdescript[a]); } else { StrAllocCopy(MBM_A_subdescript[a], my_data->str); } if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) LYmove((3 + a) - ((MBM_V_MAXFILES / 2 + 1) * (MBM_current - 1)), 5); else LYmove((3 + a), 5); LYaddch(UCH(LYindex2MBM(a))); LYaddstr(" : "); if (MBM_A_subdescript[a]) LYaddstr(MBM_A_subdescript[a]); LYclrtoeol(); LYrefresh(); } if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) LYmove((3 + a) - ((MBM_V_MAXFILES / 2 + 1) * (MBM_current - 1)), 35); else LYmove((3 + a), 35); LYaddstr("| "); lynx_start_bold(); BStrCopy0(my_data, NonNull(MBM_A_subbookmark[a])); (void) LYgetBString(&my_data, FALSE, 0, NORECALL); lynx_stop_bold(); if (isBEmpty(my_data)) { if (a == 0) StrAllocCopy(MBM_A_subbookmark[a], bookmark_page); else FREE(MBM_A_subbookmark[a]); } else { BStrAlloc(my_data, my_data->len + LY_MAXPATH); if (!LYPathOffHomeOK(my_data->str, (size_t) my_data->len)) { LYMBM_statusline(USE_PATH_OFF_HOME); LYSleepAlert(); } else { StrAllocCopy(MBM_A_subbookmark[a], my_data->str); if (a == 0) { StrAllocCopy(bookmark_page, MBM_A_subbookmark[a]); } } } if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) LYmove((3 + a) - ((MBM_V_MAXFILES / 2 + 1) * (MBM_current - 1)), 35); else LYmove((3 + a), 35); LYaddstr("| "); if (MBM_A_subbookmark[a]) LYaddstr(MBM_A_subbookmark[a]); LYclrtoeol(); LYParkCursor(); break; } } /* end for */ } /* end while */ BStrFree(my_data); term_options = FALSE; signal(SIGINT, cleanup_sig); } #if defined(USE_CURSES_PADS) || !defined(NO_OPTION_MENU) || (defined(USE_MOUSE) && (defined(NCURSES) || defined(PDCURSES))) /* * 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 * * Also used for mouse popups with ncurses; this is indicated by for_mouse. */ int popup_choice(int cur_choice, int line, int column, STRING2PTR choices, int i_length, int disabled, int for_mouse) { if (column < 0) column = (COL_OPTION_VALUES - 1); term_options = FALSE; cur_choice = LYhandlePopupList(cur_choice, line, column, (STRING2PTR) choices, -1, i_length, disabled, for_mouse); switch (cur_choice) { case LYK_QUIT: case LYK_ABORT: case LYK_PREV_DOC: term_options = TRUE; if (!for_mouse) { HTUserMsg(CANCELLED); } break; } if (disabled || term_options) { _statusline(""); } else if (!for_mouse) { _statusline(VALUE_ACCEPTED); } return (cur_choice); } #endif /* !NO_OPTION_MENU */ #ifndef NO_OPTION_FORMS /* * I'm paranoid about mistyping strings. Also, this way they get combined * so we don't have to worry about the intelligence of the compiler. * We don't need to burn memory like it's cheap. We're better than that. */ #define SELECTED(flag) (flag) ? selected_string : "" #define DISABLED(flag) (flag) ? disabled_string : "" typedef struct { int value; const char *LongName; const char *HtmlName; } OptValues; typedef struct { char *tag; char *value; } PostPair; static const char selected_string[] = "selected"; static const char disabled_string[] = "disabled"; static const char on_string[] = N_("ON"); static const char off_string[] = N_("OFF"); static const char never_string[] = N_("NEVER"); static const char always_string[] = N_("ALWAYS"); static OptValues bool_values[] = { {FALSE, N_("OFF"), "OFF"}, {TRUE, N_("ON"), "ON"}, {0, 0, 0} }; static const char *secure_string = "secure"; static char *secure_value = NULL; static const char *save_options_string = "save_options"; /* * Personal Preferences */ static const char *cookies_string = RC_SET_COOKIES; static const char *cookies_ignore_all_string = N_("ignore"); static const char *cookies_up_to_user_string = N_("ask user"); static const char *cookies_accept_all_string = N_("accept all"); static const char *x_display_string = RC_DISPLAY; static const char *editor_string = RC_FILE_EDITOR; static const char *emacs_keys_string = RC_EMACS_KEYS; #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)) #define EXEC_ALWAYS 2 #define EXEC_LOCAL 1 #define EXEC_NEVER 0 static const char *exec_links_string = RC_RUN_ALL_EXECUTION_LINKS; static OptValues exec_links_values[] = { {EXEC_NEVER, N_("ALWAYS OFF"), "ALWAYS OFF"}, {EXEC_LOCAL, N_("FOR LOCAL FILES ONLY"), "FOR LOCAL FILES ONLY"}, #ifndef NEVER_ALLOW_REMOTE_EXEC {EXEC_ALWAYS, N_("ALWAYS ON"), "ALWAYS ON"}, #endif {0, 0, 0} }; #endif /* ENABLE_OPTS_CHANGE_EXEC */ #ifdef EXP_KEYBOARD_LAYOUT static const char *kblayout_string = RC_KBLAYOUT; #endif static const char *keypad_mode_string = RC_KEYPAD_MODE; static OptValues keypad_mode_values[] = { {NUMBERS_AS_ARROWS, N_("Numbers act as arrows"), "number_arrows"}, {LINKS_ARE_NUMBERED, N_("Links are numbered"), "links_numbered"}, {LINKS_AND_FIELDS_ARE_NUMBERED, N_("Links and form fields are numbered"), "links_and_forms"}, {FIELDS_ARE_NUMBERED, N_("Form fields are numbered"), "forms_numbered"}, {0, 0, 0} }; static const char *lineedit_mode_string = RC_LINEEDIT_MODE; static const char *mail_address_string = RC_PERSONAL_MAIL_ADDRESS; static const char *personal_name_string = RC_PERSONAL_MAIL_NAME; static const char *search_type_string = RC_CASE_SENSITIVE_SEARCHING; #ifndef DISABLE_FTP static const char *anonftp_password_string = RC_ANONFTP_PASSWORD; #endif static OptValues search_type_values[] = { {FALSE, N_("Case insensitive"), "case_insensitive"}, {TRUE, N_("Case sensitive"), "case_sensitive"}, {0, 0, 0} }; #if defined(USE_SLANG) || defined(COLOR_CURSES) static const char *show_color_string = RC_SHOW_COLOR; static OptValues show_color_values[] = { {SHOW_COLOR_NEVER, never_string, never_string}, {SHOW_COLOR_OFF, off_string, off_string}, {SHOW_COLOR_ON, on_string, on_string}, {SHOW_COLOR_ALWAYS, always_string, always_string}, {0, 0, 0} }; #endif #ifdef USE_COLOR_STYLE static const char *color_style_string = RC_COLOR_STYLE; static OptValues *color_style_values; static HTList *color_style_list; #endif #ifdef USE_DEFAULT_COLORS static const char *default_colors_string = RC_DEFAULT_COLORS; #endif static const char *show_cursor_string = RC_SHOW_CURSOR; static const char *underline_links_string = RC_UNDERLINE_LINKS; #ifdef USE_SCROLLBAR static const char *show_scrollbar_string = RC_SCROLLBAR; #endif static const char prompt_dft_string[] = N_("prompt normally"); static const char prompt_yes_string[] = N_("force yes-response"); static const char prompt_no_string[] = N_("force no-response"); static OptValues prompt_values[] = { {FORCE_PROMPT_DFT, prompt_dft_string, prompt_dft_string}, {FORCE_PROMPT_YES, prompt_yes_string, prompt_yes_string}, {FORCE_PROMPT_NO, prompt_no_string, prompt_no_string}, {0, 0, 0} }; static const char *cookie_prompt_string = RC_FORCE_COOKIE_PROMPT; #ifdef USE_SSL static const char *ssl_prompt_string = RC_FORCE_SSL_PROMPT; #endif static const char *user_mode_string = RC_USER_MODE; static OptValues user_mode_values[] = { {NOVICE_MODE, N_("Novice"), "Novice"}, {INTERMEDIATE_MODE, N_("Intermediate"), "Intermediate"}, {ADVANCED_MODE, N_("Advanced"), "Advanced"}, {0, 0, 0} }; static const char *vi_keys_string = RC_VI_KEYS; static const char *visited_links_string = RC_VISITED_LINKS; static OptValues visited_links_values[] = { {VISITED_LINKS_AS_FIRST_V, N_("By First Visit"), "first_visited"}, {VISITED_LINKS_AS_FIRST_V | VISITED_LINKS_REVERSE, N_("By First Visit Reversed"), "first_visited_reversed"}, {VISITED_LINKS_AS_TREE, N_("As Visit Tree"), "visit_tree"}, {VISITED_LINKS_AS_LATEST, N_("By Last Visit"), "last_visited"}, {VISITED_LINKS_AS_LATEST | VISITED_LINKS_REVERSE, N_("By Last Visit Reversed"), "last_visited_reversed"}, {0, 0, 0} }; /* * Document Layout */ static const char *DTD_recovery_string = RC_TAGSOUP; static OptValues DTD_type_values[] = { /* Old_DTD variable */ {TRUE, N_("relaxed (TagSoup mode)"), "tagsoup"}, {FALSE, N_("strict (SortaSGML mode)"), "sortasgml"}, {0, 0, 0} }; static const char *bad_html_string = RC_BAD_HTML; static OptValues bad_html_values[] = { {BAD_HTML_IGNORE, N_("Ignore"), "ignore"}, {BAD_HTML_TRACE, N_("Add to trace-file"), "trace"}, {BAD_HTML_MESSAGE, N_("Add to LYNXMESSAGES"), "message"}, {BAD_HTML_WARN, N_("Warn, point to trace-file"), "warn"}, {0, 0, 0} }; static const char *select_popups_string = RC_SELECT_POPUPS; static const char *images_string = "images"; static const char *images_ignore_all_string = N_("ignore"); static const char *images_use_label_string = N_("as labels"); static const char *images_use_links_string = N_("as links"); static const char *verbose_images_string = RC_VERBOSE_IMAGES; static OptValues verbose_images_type_values[] = { /* verbose_img variable */ {FALSE, N_("OFF"), "OFF"}, {TRUE, N_("show filename"), "ON"}, {0, 0, 0} }; /* * Bookmark Options */ static const char *mbm_string = RC_MULTI_BOOKMARK; static OptValues mbm_values[] = { {MBM_OFF, N_("OFF"), "OFF"}, {MBM_STANDARD, N_("STANDARD"), "STANDARD"}, {MBM_ADVANCED, N_("ADVANCED"), "ADVANCED"}, {0, 0, 0} }; static const char *single_bookmark_string = RC_BOOKMARK_FILE; #ifdef USE_SESSIONS static const char *auto_session_string = RC_AUTO_SESSION; static const char *single_session_string = RC_SESSION_FILE; #endif /* * Character Set Options */ static const char *assume_char_set_string = RC_ASSUME_CHARSET; static const char *display_char_set_string = RC_CHARACTER_SET; static const char *raw_mode_string = RC_RAW_MODE; #ifdef USE_LOCALE_CHARSET static const char *locale_charset_string = RC_LOCALE_CHARSET; #endif static const char *html5_charsets_string = RC_HTML5_CHARSETS; /* * File Management Options */ static const char *show_dotfiles_string = RC_SHOW_DOTFILES; static const char *no_pause_string = RC_NO_PAUSE; #ifdef DIRED_SUPPORT static const char *dired_list_string = RC_DIR_LIST_STYLE; static OptValues dired_list_values[] = { {DIRS_FIRST, N_("Directories first"), "dired_dir"}, {FILES_FIRST, N_("Files first"), "dired_files"}, {MIXED_STYLE, N_("Mixed style"), "dired_mixed"}, {0, 0, 0} }; #ifdef LONG_LIST static const char *dired_sort_string = RC_DIR_LIST_ORDER; static OptValues dired_sort_values[] = { {ORDER_BY_NAME, N_("By Name"), "dired_by_name"}, {ORDER_BY_TYPE, N_("By Type"), "dired_by_type"}, {ORDER_BY_SIZE, N_("By Size"), "dired_by_size"}, {ORDER_BY_DATE, N_("By Date"), "dired_by_date"}, {ORDER_BY_MODE, N_("By Mode"), "dired_by_mode"}, #ifndef NO_GROUPS {ORDER_BY_USER, N_("By User"), "dired_by_user"}, {ORDER_BY_GROUP, N_("By Group"), "dired_by_group"}, #endif {0, 0, 0} }; #endif /* LONG_LIST */ #endif /* DIRED_SUPPORT */ #ifndef DISABLE_FTP static const char *passive_ftp_string = RC_FTP_PASSIVE; static const char *ftp_sort_string = RC_FILE_SORTING_METHOD; static OptValues ftp_sort_values[] = { {FILE_BY_NAME, N_("By Name"), "ftp_by_name"}, {FILE_BY_TYPE, N_("By Type"), "ftp_by_type"}, {FILE_BY_SIZE, N_("By Size"), "ftp_by_size"}, {FILE_BY_DATE, N_("By Date"), "ftp_by_date"}, {0, 0, 0} }; #endif #ifdef USE_READPROGRESS static const char *show_rate_string = RC_SHOW_KB_RATE; static OptValues rate_values[] = { {rateOFF, N_("Do not show rate"), "rate_off"}, {rateBYTES, N_("Show %s/sec rate"), "rate_bytes"}, {rateKB, N_("Show %s/sec rate"), "rate_kb"}, #ifdef USE_READPROGRESS {rateEtaBYTES, N_("Show %s/sec, ETA"), "rate_eta_bytes"}, {rateEtaKB, N_("Show %s/sec, ETA"), "rate_eta_kb"}, {rateEtaBYTES2, N_("Show %s/sec (2-digits), ETA"), "rate_eta_bytes2"}, {rateEtaKB2, N_("Show %s/sec (2-digits), ETA"), "rate_eta_kb2"}, #endif #ifdef USE_PROGRESSBAR {rateBAR, N_("Show progressbar"), "rate_bar"}, #endif {0, 0, 0} }; #endif /* USE_READPROGRESS */ /* * Presentation (MIME) types used in "Accept". */ static const char *preferred_media_string = RC_PREFERRED_MEDIA_TYPES; static OptValues media_values[] = { {mediaOpt1, N_("Accept lynx's internal types"), "media_opt1"}, {mediaOpt2, N_("Also accept lynx.cfg's types"), "media_opt2"}, {mediaOpt3, N_("Also accept user's types"), "media_opt3"}, {mediaOpt4, N_("Also accept system's types"), "media_opt4"}, {mediaALL, N_("Accept all types"), "media_all"}, {0, 0, 0} }; static const char *preferred_encoding_string = RC_PREFERRED_ENCODING; static OptValues encoding_values[] = { {encodingNONE, N_("None"), "encoding_none"}, #if defined(USE_ZLIB) || defined(GZIP_PATH) {encodingGZIP, N_("gzip"), "encoding_gzip"}, {encodingDEFLATE, N_("deflate"), "encoding_deflate"}, #endif #if defined(USE_ZLIB) || defined(COMPRESS_PATH) {encodingCOMPRESS, N_("compress"), "encoding_compress"}, #endif #if defined(USE_BZLIB) || defined(BZIP2_PATH) {encodingBZIP2, N_("bzip2"), "encoding_bzip2"}, #endif {encodingALL, N_("All"), "encoding_all"}, {0, 0, 0} }; /* * Headers transferred to remote server */ static const char *preferred_doc_char_string = RC_PREFERRED_CHARSET; static const char *preferred_doc_lang_string = RC_PREFERRED_LANGUAGE; static const char *send_user_agent_string = RC_SEND_USERAGENT; static const char *user_agent_string = RC_USERAGENT; #define PutHeader(fp, Name) \ fprintf(fp, "\n%s%s\n", MARGIN_STR, LYEntifyTitle(&buffer, Name)); #define PutCheckBox(fp, Name, Value, disable) \ fprintf(fp,\ "\n",\ Name, Value ? "checked" : "", disable_all?disabled_string:disable) #define PutTextInput(fp, Name, Value, Size, disable) \ fprintf(fp,\ "\n",\ (int) Size, Name, Value, disable_all?disabled_string:disable) #define PutOption(fp, flag, html, name) \ fprintf(fp,"