about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>2001-10-06 22:20:25 -0400
committerThomas E. Dickey <dickey@invisible-island.net>2001-10-06 22:20:25 -0400
commitf78e27712a4f44dbdf3c1532c3d1958989bf40a5 (patch)
tree51a8f8acd39f65da307ae05a0b9276490e03bedd /src
parentfc99820d832c512631aa418520f5bc6a204e8b91 (diff)
downloadlynx-snapshots-f78e27712a4f44dbdf3c1532c3d1958989bf40a5.tar.gz
snapshot of project "lynx", label v2-8-5dev_3
Diffstat (limited to 'src')
-rw-r--r--src/GridText.c204
-rw-r--r--src/GridText.h2
-rw-r--r--src/HTML.c18
-rw-r--r--src/LYCurses.c44
-rw-r--r--src/LYCurses.h2
-rw-r--r--src/LYGetFile.c34
-rw-r--r--src/LYGlobalDefs.h13
-rw-r--r--src/LYList.c4
-rw-r--r--src/LYMain.c60
-rw-r--r--src/LYOptions.c38
-rw-r--r--src/LYReadCFG.c7
-rw-r--r--src/LYStrings.c35
-rw-r--r--src/LYUtils.c129
-rw-r--r--src/LYUtils.h1
-rw-r--r--src/LYrcFile.c21
15 files changed, 392 insertions, 220 deletions
diff --git a/src/GridText.c b/src/GridText.c
index 8b12dd33..88630322 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -145,7 +145,7 @@ PUBLIC int LYCacheSourceForAborted = SOURCE_CACHE_FOR_ABORTED_DROP;
 #endif
 
 #ifdef USE_SCROLLBAR
-PUBLIC BOOLEAN LYsb = FALSE;
+PUBLIC BOOLEAN LYShowScrollbar = FALSE;
 PUBLIC BOOLEAN LYsb_arrow = TRUE;
 PUBLIC int LYsb_begin = -1;
 PUBLIC int LYsb_end = -1;
@@ -1580,7 +1580,7 @@ PRIVATE void display_scrollbar ARGS1(
     int top_skip, bot_skip, sh, shown;
 
     LYsb_begin = LYsb_end = -1;
-    if (!LYsb || !text || h <= 2
+    if (!LYShowScrollbar || !text || h <= 2
 	|| (text->Lines + 1) <= display_lines)
 	return;
 
@@ -4014,12 +4014,32 @@ check_WrapSource:
     /*
      *  Check if we should ignore characters at the wrap point.
      */
-    if (text->IgnoreExcess &&
-	(((indent + (int)line->offset + (int)line->size) +
-	  (int)style->rightIndent - ctrl_chars_on_this_line) >= (WRAP_COLS(text)-1) ||
-	 ((indent + (int)line->offset + (int)line->size) +
-	  utfxtra_on_this_line - ctrl_chars_on_this_line) >= (LYcols_cu-1)))
-	return;
+    if (text->IgnoreExcess) {
+	int nominal = (indent + (int)(line->offset + line->size) - ctrl_chars_on_this_line);
+	int limit = (WRAP_COLS(text) - 1);
+	int number;
+
+	if (fields_are_numbered()
+	 && !number_fields_on_left
+	 && text->last_anchor != 0
+	 && (number = text->last_anchor->number) > 0) {
+	    limit -= (number > 99999
+	    		? 6
+			: (number > 9999
+			    ? 5
+			    : (number > 999
+				? 4
+				: (number > 99
+				    ? 3
+				    : (number > 9
+					? 2
+					: 1))))) + 2;
+	}
+	if ((nominal + (int)style->rightIndent) >= limit
+	 || (nominal + utfxtra_on_this_line) >= (LYcols_cu - 1)) {
+	    return;
+	}
+    }
 
     /*
      *  Check for end of line.
@@ -4769,6 +4789,33 @@ PUBLIC void HText_startStblRowGroup ARGS2(
 /*		Anchor handling
 **		---------------
 */
+PRIVATE void add_link_number ARGS3(
+    HText *,		text,
+    TextAnchor *,	a,
+    BOOL,		save_position)
+{
+    char marker[32];
+
+    /*
+     *  If we are doing link_numbering add the link number.
+     */
+    if ((a->number > 0)
+#ifdef USE_PRETTYSRC
+     && (text->source ? !psrcview_no_anchor_numbering : 1 )
+#endif
+     && links_are_numbered()) {
+	char saved_lastchar = text->LastChar;
+	int saved_linenum = text->Lines;
+	sprintf(marker,"[%d]", a->number);
+	HText_appendText(text, marker);
+	if (saved_linenum && text->Lines && saved_lastchar != ' ')
+	    text->LastChar = ']'; /* if marker not after space caused split */
+	if (save_position) {
+	    a->line_num = text->Lines;
+	    a->line_pos = text->last_line->size;
+	}
+    }
+}
 
 /*	Start an anchor field
 */
@@ -4777,8 +4824,6 @@ PUBLIC int HText_beginAnchor ARGS3(
 	BOOL,			underline,
 	HTChildAnchor *,	anc)
 {
-    char marker[32];
-
     TextAnchor * a = typecalloc(TextAnchor);
 
     if (a == NULL)
@@ -4812,25 +4857,8 @@ PUBLIC int HText_beginAnchor ARGS3(
 	a->number = 0;
     }
 
-    /*
-     *  If we are doing link_numbering add the link number.
-     */
-    if ((a->number > 0) &&
-#ifdef USE_PRETTYSRC
-	(text->source ? !psrcview_no_anchor_numbering : 1 ) &&
-#endif
-	(keypad_mode == LINKS_ARE_NUMBERED ||
-	 keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED)) {
-	char saved_lastchar = text->LastChar;
-	int saved_linenum = text->Lines;
-	sprintf(marker,"[%d]", a->number);
-	HText_appendText(text, marker);
-	if (saved_linenum && text->Lines && saved_lastchar != ' ')
-	    text->LastChar = ']'; /* if marker not after space caused split */
-	a->line_num = text->Lines;
-	a->line_pos = text->last_line->size;
-    }
-
+    if (number_links_on_left)
+	add_link_number(text, a, TRUE);
     return(a->number);
 }
 
@@ -4881,14 +4909,14 @@ PRIVATE BOOL HText_endAnchor0 ARGS3(
 	   "BUG: HText_endAnchor0: internal error: last anchor was input field!\n"));
 	return FALSE;
     }
+
     if (a->number) {
 	/*
 	 *  If it goes somewhere...
 	 */
 	int i, j, k, l;
 	BOOL remove_numbers_on_empty = (BOOL) (
-	    ((keypad_mode == LINKS_ARE_NUMBERED ||
-	      keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED) &&
+	    (links_are_numbered() &&
 	     (text->hiddenlinkflag != HIDDENLINKS_MERGE ||
 	      (LYNoISMAPifUSEMAP &&
 	       !(text->node_anchor && text->node_anchor->bookmark) &&
@@ -5117,7 +5145,7 @@ PRIVATE BOOL HText_endAnchor0 ARGS3(
 			for (anc = a; anc; anc = anc->next) {
 			    if (anc->line_num == a->line_num &&
 				anc->line_pos >= NumSize) {
-			    anc->line_pos -= NumSize;
+				anc->line_pos -= NumSize;
 			    }
 			}
 			start->size = j;
@@ -5246,6 +5274,8 @@ PRIVATE BOOL HText_endAnchor0 ARGS3(
 		}
 	    }
 	} else {
+    if (!number_links_on_left)
+	add_link_number(text, a, FALSE);
 	    /*
 	     *  The anchor's content is not restricted to only
 	     *  white and special characters, so we'll show it
@@ -7506,8 +7536,7 @@ PUBLIC void print_crawl_to_fd ARGS3(
      *  Add the References list if appropriate
      */
     if ((nolist == FALSE) &&
-	(keypad_mode == LINKS_ARE_NUMBERED ||
-	 keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED)) {
+	links_are_numbered()) {
 	printlist(fp,FALSE);
     }
 
@@ -8811,7 +8840,7 @@ PRIVATE char * HText_skipOptionNumPrefix ARGS1(
     /*
      *  Check if we are in the correct keypad mode.
      */
-    if (keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED) {
+    if (fields_are_numbered()) {
 	/*
 	 *  Skip the option number embedded in the option name so the
 	 *  extra chars won't mess up cgi scripts processing the value.
@@ -8869,14 +8898,16 @@ PUBLIC char * HText_setLastOptionValue ARGS7(
     unsigned char *tmp = NULL;
     int number = 0, i, j;
 
-    if (!(text && text->last_anchor &&
-	  text->last_anchor->link_type == INPUT_ANCHOR)) {
+    if (!(value
+      && text
+      && text->last_anchor
+      && text->last_anchor->link_type == INPUT_ANCHOR)) {
 	CTRACE((tfp, "HText_setLastOptionValue: invalid call!  value:%s!\n",
 		    (value ? value : "<NULL>")));
 	return NULL;
     }
 
-    CTRACE((tfp, "Entering HText_setLastOptionValue: value:%s, checked:%s\n",
+    CTRACE((tfp, "Entering HText_setLastOptionValue: value:\"%s\", checked:%s\n",
 		value, (checked ? "on" : "off")));
 
     /*
@@ -8899,7 +8930,7 @@ PUBLIC char * HText_setLastOptionValue ARGS7(
 	cp++;
     if (HTCurSelectGroupType == F_RADIO_TYPE &&
 	LYSelectPopups &&
-	keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED) {
+	fields_are_numbered()) {
 	/*
 	 *  Collapse any space between the popup option
 	 *  prefix and actual value. - FM
@@ -9100,7 +9131,7 @@ PUBLIC char * HText_setLastOptionValue ARGS7(
     }
 
     if (TRACE) {
-	CTRACE((tfp, "HText_setLastOptionValue:%s value=%s",
+	CTRACE((tfp, "HText_setLastOptionValue:%s value=\"%s\"\n",
 		(order == LAST_ORDER) ? " LAST_ORDER" : "",
 		value));
 	CTRACE((tfp,"            val_cs=%d \"%s\"",
@@ -9108,7 +9139,7 @@ PUBLIC char * HText_setLastOptionValue ARGS7(
 			(val_cs >= 0 ?
 			 LYCharSet_UC[val_cs].MIMEname : "<UNKNOWN>")));
 	if (submit_value) {
-	    CTRACE((tfp, " (submit_val_cs %d \"%s\") submit_value%s=%s\n",
+	    CTRACE((tfp, " (submit_val_cs %d \"%s\") submit_value%s=\"%s\"\n",
 		    submit_val_cs,
 		    (submit_val_cs >= 0 ?
 		     LYCharSet_UC[submit_val_cs].MIMEname : "<UNKNOWN>"),
@@ -9139,6 +9170,9 @@ PUBLIC int HText_beginInput ARGS3(
     char *IValue = NULL;
     unsigned char *tmp = NULL;
     int i, j;
+    int adjust_marker = 0;
+    int MaximumSize;
+    char marker[16];
 
     CTRACE((tfp, "GridText: Entering HText_beginInput\n"));
 
@@ -9149,7 +9183,6 @@ PUBLIC int HText_beginInput ARGS3(
     a->line_num = text->Lines;
     a->line_pos = text->last_line->size;
 
-
     /*
      *  If this is a radio button, or an OPTION we're converting
      *  to a radio button, and it's the first with this name, make
@@ -9209,7 +9242,6 @@ PUBLIC int HText_beginInput ARGS3(
 
     HTFormFields++;
 
-
     /*
      *  Set the no_cache flag if the METHOD is POST. - FM
      */
@@ -9486,37 +9518,34 @@ PUBLIC int HText_beginInput ARGS3(
 	    break;
 
 	default:
-	    if (keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED)
+	    if (fields_are_numbered())
 		a->number = ++(text->last_anchor_number);
 	    else
 		a->number = 0;
 	    break;
     }
-    if (keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED && a->number > 0) {
-	char marker[16];
+    if (fields_are_numbered() && (a->number > 0)) {
+	sprintf(marker,"[%d]", a->number);
+	if (number_fields_on_left) {
+	    BOOL had_bracket = (f->type == F_OPTION_LIST_TYPE);
 
-	if (f->type != F_OPTION_LIST_TYPE)
-	    /*
-	     *  '[' was already put out for a popup menu
-	     *  designator.  See HTML.c.
-	     */
-	    HText_appendCharacter(text, '[');
-	sprintf(marker,"%d]", a->number);
-	HText_appendText(text, marker);
-	if (f->type == F_OPTION_LIST_TYPE)
-	    /*
-	     *  Add option list designation char.
-	     */
-	    HText_appendCharacter(text, '[');
+	    HText_appendText(text, had_bracket ? (marker + 1) : marker);
+	    if (had_bracket)
+		HText_appendCharacter(text, '[');
+	} else {
+	    adjust_marker = strlen(marker);
+	}
 	a->line_num = text->Lines;
 	a->line_pos = text->last_line->size;
+    } else {
+	*marker = '\0';
     }
 
     /*
      *  Restrict SIZE to maximum allowable size.
      */
+    MaximumSize = WRAP_COLS(text) - adjust_marker;
     switch (f->type) {
-	int MaximumSize;
 
 	case F_SUBMIT_TYPE:
 	case F_IMAGE_SUBMIT_TYPE:
@@ -9532,20 +9561,19 @@ PUBLIC int HText_beginInput ARGS3(
 	     *  text entry lines can be long, and will be scrolled
 	     *  horizontally within the editing window. - FM
 	     */
-	    MaximumSize = (WRAP_COLS(text) - 1) -
-			  (int)text->style->leftIndent -
-			  (int)text->style->rightIndent;
+	    MaximumSize -= (1 +
+			  (int)text->style->leftIndent +
+			  (int)text->style->rightIndent);
 
 	    /*  If we are numbering form links, place is taken by [nn]  */
-	    if (keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED)
-		MaximumSize -= (a->number >= 10	/*Buggy if 1e6 links, sowhat?*/
-				? (a->number >= 100
-				   ? (a->number >= 1000
-				      ? (a->number >= 10000
-					 ? (a->number >= 100000
-					    ? 6 : 5) : 4) : 3) : 2) : 1) + 2;
-	    if (f->size > MaximumSize)
-		f->size = MaximumSize;
+	    if (fields_are_numbered()) {
+		if (!number_fields_on_left
+		 && f->type == F_TEXT_TYPE
+		 && MaximumSize > a->line_pos + 10)
+		    MaximumSize -= a->line_pos;
+		else
+		    MaximumSize -= strlen(marker);
+	    }
 
 	    /*
 	     *  Save value for submit/reset buttons so they
@@ -9554,7 +9582,6 @@ PUBLIC int HText_beginInput ARGS3(
 	    I->value = f->value;
 	    break;
 
-
 	default:
 	    /*
 	     *  For all other fields we limit the size element to
@@ -9562,10 +9589,11 @@ PUBLIC int HText_beginInput ARGS3(
 	     *  are types with small placeholders, and/or are a
 	     *  type which is handled via a popup window. - FM
 	     */
-	    if (f->size > WRAP_COLS(text)-10)
-		f->size = WRAP_COLS(text)-10;  /* maximum */
+	    MaximumSize -= 10;
 	    break;
     }
+    if (f->size > MaximumSize)
+	f->size = MaximumSize;
 
     /*
      *  Add this anchor to the anchor list
@@ -9618,6 +9646,26 @@ PUBLIC int HText_beginInput ARGS3(
 }
 
 /*
+ * If we're numbering fields on the right, do it.  Note that some fields may
+ * be too long for the line - we'll lose the marker in that case rather than
+ * truncate the field.
+ */
+PUBLIC void HText_endInput ARGS1(
+	HText *,		text)
+{
+    if (fields_are_numbered()
+     && !number_fields_on_left
+     && text != NULL
+     && text->last_anchor != NULL
+     && text->last_anchor->number > 0) {
+	char marker[20];
+	HText_setIgnoreExcess(text, FALSE);
+	sprintf(marker,"[%d]", text->last_anchor->number);
+	HText_appendText(text, marker);
+    }
+}
+
+/*
  *  Get a translation (properly: transcoding) quality, factoring in
  *  our ability to translate (an UCTQ_t) and a possible q parameter
  *  on the given charset string, for cs_from -> givenmime.
@@ -11720,7 +11768,7 @@ PRIVATE void insert_new_textarea_anchor ARGS2(
     l->styles = htline->styles;
 #endif
     strcpy (l->data,     htline->data);
-    if (keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED) {
+    if (fields_are_numbered()) {
 	a->number++;
 	increment_tagged_htline (l, a, &lx, &curr_tag, 1, CHOP);
     }
@@ -11791,7 +11839,7 @@ PRIVATE void update_subsequent_anchors ARGS4(
      */
     anchor = start_anchor->next;   /* begin updating with the NEXT anchor */
     while (anchor) {
-	if ((keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED) &&
+	if (fields_are_numbered() &&
 	    (anchor->number != 0))
 	    anchor->number += newlines;
 	anchor->line_num  += newlines;
@@ -11828,7 +11876,7 @@ PRIVATE void update_subsequent_anchors ARGS4(
      *   relocating an anchor to the following line, when [tag] digits
      *   expansion pushes things too far in that direction.]
      */
-    if (keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED) {
+    if (fields_are_numbered()) {
 	anchor = start_anchor->next;
 	while (htline != FirstHTLine(HTMainText)) {
 
diff --git a/src/GridText.h b/src/GridText.h
index 24be45f6..0e2956a7 100644
--- a/src/GridText.h
+++ b/src/GridText.h
@@ -207,6 +207,8 @@ extern int HText_beginInput PARAMS((
 	HText *		text,
 	BOOL		underline,
 	InputFieldData *I));
+extern void HText_endInput PARAMS((
+	HText *		text));
 extern int HText_SubmitForm PARAMS((
 	FormInfo *	submit_item,
 	document *	doc,
diff --git a/src/HTML.c b/src/HTML.c
index d27f1844..64235829 100644
--- a/src/HTML.c
+++ b/src/HTML.c
@@ -5265,6 +5265,7 @@ PRIVATE int HTML_start_element ARGS6(
 		 *  expected to follow. - FM
 		 */
 		HTML_put_string(me, "(_)");
+		HText_endInput(me->text);
 		chars = 0;
 		me->in_word = YES;
 		if (me->sp[0].tag_number != HTML_PRE &&
@@ -5280,6 +5281,7 @@ PRIVATE int HTML_start_element ARGS6(
 		 *  expected to follow. - FM
 		 */
 		HTML_put_string(me, "[_]");
+		HText_endInput(me->text);
 		chars = 0;
 		me->in_word = YES;
 		if (me->sp[0].tag_number != HTML_PRE &&
@@ -5322,8 +5324,11 @@ PRIVATE int HTML_start_element ARGS6(
 		 *  so output the rest of the underscore
 		 *  placeholders, if any more are needed. - FM
 		 */
-		for (; chars > 0; chars--)
-		    HTML_put_character(me, '_');
+		if (chars > 0) {
+		    for (; chars > 0; chars--)
+			HTML_put_character(me, '_');
+		    HText_endInput(me->text);
+		}
 	    } else {
 		if (HTCJK == JAPANESE) {
 		    kcode = HText_getKcode(me->text);
@@ -5376,6 +5381,9 @@ PRIVATE int HTML_start_element ARGS6(
 		    HText_updateSpecifiedKcode(me->text, specified_kcode);
 		}
 	    }
+	    if (chars != 0) {
+		HText_endInput(me->text);
+	    }
 	    HText_setIgnoreExcess(me->text, FALSE);
 	    FREE(ImageSrc);
 	    FREE(I_value);
@@ -5539,7 +5547,7 @@ PRIVATE int HTML_start_element ARGS6(
 	    }
 
 	    /*
-	     *	If its not a multiple option list and select popups
+	     *	If it's not a multiple option list and select popups
 	     *	are enabled, then don't use the checkbox/button method,
 	     *	and don't put anything on the screen yet.
 	     */
@@ -5655,7 +5663,6 @@ PRIVATE int HTML_start_element ARGS6(
 		me->LastOptionChecked = FALSE;
 	    me->first_option = FALSE;
 
-
 	    if (present && present[HTML_OPTION_VALUE] &&
 		value[HTML_OPTION_VALUE]) {
 		if (!I_value) {
@@ -5682,7 +5689,7 @@ PRIVATE int HTML_start_element ARGS6(
 	     */
 	    if (HTCurSelectGroupType == F_RADIO_TYPE &&
 		LYSelectPopups &&
-		keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED) {
+		fields_are_numbered()) {
 		char marker[8];
 		int opnum = HText_getOptionNum(me->text);
 
@@ -7518,6 +7525,7 @@ End_Object:
 		 */
 		if (!me->first_option) {
 		    HText_appendCharacter(me->text, ']');
+		    HText_endInput(me->text);
 		    HText_setLastChar(me->text, ']');
 		    me->in_word = YES;
 		}
diff --git a/src/LYCurses.c b/src/LYCurses.c
index 7d664bfa..2f43537b 100644
--- a/src/LYCurses.c
+++ b/src/LYCurses.c
@@ -1515,6 +1515,39 @@ PUBLIC void LYpaddstr ARGS3(
     while (width-- > 0)
 	waddstr(the_window, " ");
 }
+
+/*
+ * Workaround a bug in ncurses order-of-refresh by setting a pointer to
+ * the topmost window that should be displayed.
+ *
+ * FIXME: the associated call on 'keypad()' is not needed for Unix, but
+ * something in the OS/2 EMX port requires it.
+ */
+PRIVATE WINDOW *my_subwindow;
+
+PUBLIC void LYsubwindow ARGS1(WINDOW *, param)
+{
+    if (param != 0) {
+	my_subwindow = param;
+#if defined(NCURSES) || defined(PDCURSES)
+	keypad(my_subwindow, TRUE);
+#if defined(HAVE_GETBKGD) /* not defined in ncurses 1.8.7 */
+	wbkgd(my_subwindow, getbkgd(LYwin));
+	wbkgdset(my_subwindow, getbkgd(LYwin));
+#endif
+#endif
+	scrollok(my_subwindow, TRUE);
+    } else {
+	touchwin(LYwin);
+	delwin(my_subwindow);
+	my_subwindow = 0;
+    }
+}
+
+PUBLIC WINDOW *LYtopwindow NOARGS
+{
+    return (my_subwindow ? my_subwindow : LYwin);
+}
 #endif
 
 PUBLIC WINDOW *LYstartPopup ARGS4(
@@ -1595,7 +1628,7 @@ PUBLIC void LYstopTargetEmphasis NOARGS
 PUBLIC void LYtouchline ARGS1(
 	int,		row)
 {
-#if defined(HAVE_WREDRAWLN)
+#if defined(HAVE_WREDRAWLN) && !defined(NCURSES_VERSION)
     wredrawln(LYwin, row, 1);
 #else
 #if defined(HAVE_TOUCHLINE)
@@ -2206,6 +2239,15 @@ PUBLIC void LYrefresh NOARGS
 
 	wnoutrefresh(stdscr);
 	pnoutrefresh(LYwin, 0, LYshiftWin, 0, 0, LYlines, LYscreenWidth()-1);
+
+	/*
+	 * Keep a popup window visible.  This can happen if the user presses
+	 * '/' to do a search within a popup.
+	 */
+	if (my_subwindow != 0) {
+	    touchwin(my_subwindow);
+	    wnoutrefresh(my_subwindow);
+	}
 	doupdate();
     } else {
 	refresh();
diff --git a/src/LYCurses.h b/src/LYCurses.h
index 03ef3b36..5de3fc6b 100644
--- a/src/LYCurses.h
+++ b/src/LYCurses.h
@@ -252,8 +252,10 @@ typedef struct {
 
 #ifdef USE_SLANG
 #define LYstopPopup() /* nothing */
+#define LYtopwindow() LYwin
 #else
 extern void LYsubwindow PARAMS((WINDOW * param));
+extern WINDOW * LYtopwindow NOPARAMS;
 #define LYstopPopup() LYsubwindow(0)
 #endif /* NCURSES */
 
diff --git a/src/LYGetFile.c b/src/LYGetFile.c
index 3ea3e2b9..1c4097ea 100644
--- a/src/LYGetFile.c
+++ b/src/LYGetFile.c
@@ -716,7 +716,9 @@ Try_Redirected_URL:
 		}
 		{
 
-		    if (url_type == FTP_URL_TYPE && !ftp_ok) {
+		    if (!ftp_ok
+		     && (url_type == FTP_URL_TYPE
+		      || url_type == NCFTP_URL_TYPE)) {
 			HTUserMsg(FTP_DISABLED);
 			return(NULLFILE);
 		    }
@@ -752,6 +754,7 @@ Try_Redirected_URL:
 		    if (url_type == HTTP_URL_TYPE ||
 			url_type == HTTPS_URL_TYPE ||
 			url_type == FTP_URL_TYPE ||
+			url_type == NCFTP_URL_TYPE ||
 			url_type == CSO_URL_TYPE)
 			fix_httplike_urls(doc, url_type);
 		    WWWDoc.address = doc->address;  /* possible reload */
@@ -899,7 +902,8 @@ Try_Redirected_URL:
 				(no_goto_finger &&
 				 url_type == FINGER_URL_TYPE) ||
 				(no_goto_ftp &&
-				 url_type == FTP_URL_TYPE) ||
+				 (url_type == FTP_URL_TYPE ||
+				  url_type == NCFTP_URL_TYPE)) ||
 				(no_goto_gopher &&
 				 url_type == GOPHER_URL_TYPE) ||
 				(no_goto_http &&
@@ -1552,6 +1556,20 @@ PRIVATE int fix_httplike_urls ARGS2(
 	LYTrimHtmlSep(doc->address);
 	CTRACE((tfp, "            changed to '%s'\n", doc->address));
 	CTRACE_SLEEP(MessageSecs);
+    } else if (type == NCFTP_URL_TYPE) {
+	char *path = NULL;
+	char *first = doc->address;
+	char *second = strchr(first, ':');
+
+	CTRACE((tfp, "fix_httplike_urls: URL '%s'\n", doc->address));
+
+	*second++ = '\0';
+	HTSprintf0(&path, "ftp://%s%s", first, second);
+	FREE(doc->address);
+	doc->address = path;
+
+	CTRACE((tfp, "            changed to '%s'\n", doc->address));
+	CTRACE_SLEEP(MessageSecs);
     }
 #endif /* DISABLE_FTP */
 
@@ -1565,12 +1583,12 @@ PRIVATE int fix_httplike_urls ARGS2(
 	if (type == HTTP_URL_TYPE ||
 	    type == HTTPS_URL_TYPE) {
 	    if ((slash-2) - strchr(doc->address, ':')) {
-	    /*
-	     *  Turns out we were not looking at the right slash after all,
-	     *  there must have been more than one "://" which is valid
-	     *  at least for http URLs (later occurrences can be part of
-	     *  a query string, for example), so leave this alone, too. - kw
-	     */
+		/*
+		 *  Turns out we were not looking at the right slash after all,
+		 *  there must have been more than one "://" which is valid
+		 *  at least for http URLs (later occurrences can be part of
+		 *  a query string, for example), so leave this alone, too. - kw
+		 */
 		return(0);
 	    }
 	    if (strchr(doc->address, '?')) {
diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h
index a800b37f..764b6033 100644
--- a/src/LYGlobalDefs.h
+++ b/src/LYGlobalDefs.h
@@ -96,6 +96,15 @@ extern char *LYCgiDocumentRoot;  /* DOCUMENT_ROOT in the lynxcgi env */
 #define NUMBERS_AS_ARROWS 0
 #define LINKS_ARE_NUMBERED 1
 #define LINKS_AND_FIELDS_ARE_NUMBERED 2
+#define FIELDS_ARE_NUMBERED 3
+
+#define links_are_numbered() \
+	    (keypad_mode == LINKS_ARE_NUMBERED || \
+	     keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED)
+
+#define fields_are_numbered() \
+	    (keypad_mode == FIELDS_ARE_NUMBERED || \
+	     keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED)
 
 #define HIDDENLINKS_MERGE	0
 #define HIDDENLINKS_SEPARATE	1
@@ -185,6 +194,8 @@ extern BOOLEAN long_url_ok;
 extern BOOLEAN lynx_mode;
 extern BOOLEAN more;		/* is there more document to display? */
 extern BOOLEAN news_ok;
+extern BOOLEAN number_fields_on_left;
+extern BOOLEAN number_links_on_left;
 extern BOOLEAN recent_sizechange;
 extern BOOLEAN rlogin_ok;
 extern BOOLEAN system_editor;	  /* True if locked-down editor */
@@ -523,7 +534,7 @@ extern int setmode(int handle, int amode);
 
 #ifdef USE_SCROLLBAR
 /* GridText.c */
-extern BOOLEAN LYsb;
+extern BOOLEAN LYShowScrollbar;
 extern BOOLEAN LYsb_arrow;
 extern int LYsb_begin;
 extern int LYsb_end;
diff --git a/src/LYList.c b/src/LYList.c
index fcc1ad74..1606a3af 100644
--- a/src/LYList.c
+++ b/src/LYList.c
@@ -123,7 +123,7 @@ PUBLIC int showlist ARGS2(
 	     *	right in connection with always treating this file as
 	     *	HIDDENLINKS_MERGE in GridText.c - kw
 	     */
-	    if (keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED) {
+	    if (fields_are_numbered()) {
 		HText_FormDescNumber(cnt, (char **)&desc);
 		fprintf(fp0,
 		"<li><a id=%d href=\"#%d\">form field</a> = <em>%s</em>\n",
@@ -286,7 +286,7 @@ PUBLIC void printlist ARGS2(
 		 *  the list page match the numbering in the original document,
 		 *  but won't create a forward link to the form. - FM && LE
 		 */
-		if (keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED) {
+		if (fields_are_numbered()) {
 		    HText_FormDescNumber(cnt, (char **)&desc);
 		    fprintf(fp, "%4d. form field = %s\n", cnt, desc);
 		}
diff --git a/src/LYMain.c b/src/LYMain.c
index 689be99d..36303f4c 100644
--- a/src/LYMain.c
+++ b/src/LYMain.c
@@ -154,49 +154,54 @@ PUBLIC lynx_list_item_type *downloaders = NULL;
 PUBLIC lynx_list_item_type *externals = NULL;
 			    /* linked list of external options */
 #endif
+
 PUBLIC lynx_list_item_type *uploaders = NULL;
 PUBLIC int port_syntax = 1;
 PUBLIC int LYShowColor = SHOW_COLOR_UNKNOWN; /* to show or not */
 PUBLIC int LYrcShowColor = SHOW_COLOR_UNKNOWN; /* ... last used */
+
 #if !defined(NO_OPTION_FORMS) && !defined(NO_OPTION_MENU)
 PUBLIC BOOLEAN LYUseFormsOptions = TRUE; /* use forms-based options menu */
 #endif
+
+PUBLIC BOOLEAN LYJumpFileURL = FALSE;	 /* always FALSE the first time */
+PUBLIC BOOLEAN LYPermitURL = FALSE;
+PUBLIC BOOLEAN LYRestricted = FALSE; /* whether we have -anonymous option */
 PUBLIC BOOLEAN LYShowCursor = SHOW_CURSOR; /* to show or not to show */
-PUBLIC BOOLEAN verbose_img = VERBOSE_IMAGES;  /* show filenames or not */
 PUBLIC BOOLEAN LYUseDefShoCur = TRUE;	/* Command line -show_cursor toggle */
+PUBLIC BOOLEAN LYUserSpecifiedURL = TRUE;/* always TRUE  the first time */
+PUBLIC BOOLEAN LYValidate = FALSE;
 PUBLIC BOOLEAN LYforce_no_cache = FALSE;
-PUBLIC BOOLEAN LYoverride_no_cache = FALSE;/*override no-cache b/c history etc*/
 PUBLIC BOOLEAN LYinternal_flag = FALSE; /* override no-cache b/c internal link*/
+PUBLIC BOOLEAN LYoverride_no_cache = FALSE;/*override no-cache b/c history etc*/
 PUBLIC BOOLEAN LYresubmit_posts = ALWAYS_RESUBMIT_POSTS;
 PUBLIC BOOLEAN LYtrimInputFields = FALSE;
-PUBLIC BOOLEAN LYUserSpecifiedURL = TRUE;/* always TRUE  the first time */
-PUBLIC BOOLEAN LYJumpFileURL = FALSE;	 /* always FALSE the first time */
-PUBLIC BOOLEAN jump_buffer = JUMPBUFFER; /* TRUE if offering default shortcut */
-PUBLIC BOOLEAN goto_buffer = GOTOBUFFER; /* TRUE if offering default goto URL */
-PUBLIC BOOLEAN ftp_passive = FTP_PASSIVE; /* TRUE if doing ftp in passive mode */
-PUBLIC BOOLEAN recent_sizechange = FALSE;/* the window size changed recently? */
-PUBLIC int user_mode = NOVICE_MODE;
-PUBLIC BOOLEAN dump_output_immediately = FALSE;
-PUBLIC BOOLEAN is_www_index = FALSE;
-PUBLIC BOOLEAN lynx_mode = NORMAL_LYNX_MODE;
-PUBLIC BOOLEAN bold_headers = FALSE;
 PUBLIC BOOLEAN bold_H1 = FALSE;
+PUBLIC BOOLEAN bold_headers = FALSE;
 PUBLIC BOOLEAN bold_name_anchors = FALSE;
-PUBLIC BOOLEAN use_underscore = SUBSTITUTE_UNDERSCORES;
-PUBLIC BOOLEAN nolist = FALSE;
+PUBLIC BOOLEAN case_sensitive = CASE_SENSITIVE_ALWAYS_ON;
+PUBLIC BOOLEAN check_mail = CHECKMAIL;
+PUBLIC BOOLEAN child_lynx = FALSE;
+PUBLIC BOOLEAN dump_output_immediately = FALSE;
+PUBLIC BOOLEAN emacs_keys = EMACS_KEYS_ALWAYS_ON;
+PUBLIC BOOLEAN error_logging = MAIL_SYSTEM_ERROR_LOGGING;
+PUBLIC BOOLEAN ftp_passive = FTP_PASSIVE; /* TRUE if doing ftp in passive mode */
+PUBLIC BOOLEAN goto_buffer = GOTOBUFFER; /* TRUE if offering default goto URL */
 PUBLIC BOOLEAN historical_comments = FALSE;
+PUBLIC BOOLEAN is_www_index = FALSE;
+PUBLIC BOOLEAN jump_buffer = JUMPBUFFER; /* TRUE if offering default shortcut */
+PUBLIC BOOLEAN lynx_mode = NORMAL_LYNX_MODE;
 PUBLIC BOOLEAN minimal_comments = FALSE;
+PUBLIC BOOLEAN nolist = FALSE;
+PUBLIC BOOLEAN number_fields_on_left = TRUE;
+PUBLIC BOOLEAN number_links_on_left = TRUE;
+PUBLIC BOOLEAN recent_sizechange = FALSE;/* the window size changed recently? */
 PUBLIC BOOLEAN soft_dquotes = FALSE;
-PUBLIC BOOLEAN LYRestricted = FALSE; /* whether we have -anonymous option */
-PUBLIC BOOLEAN LYValidate = FALSE;
-PUBLIC BOOLEAN LYPermitURL = FALSE;
-PUBLIC BOOLEAN child_lynx = FALSE;
-PUBLIC BOOLEAN error_logging = MAIL_SYSTEM_ERROR_LOGGING;
-PUBLIC BOOLEAN check_mail = CHECKMAIL;
+PUBLIC BOOLEAN use_underscore = SUBSTITUTE_UNDERSCORES;
+PUBLIC BOOLEAN verbose_img = VERBOSE_IMAGES;  /* show filenames or not */
 PUBLIC BOOLEAN vi_keys = VI_KEYS_ALWAYS_ON;
-PUBLIC BOOLEAN emacs_keys = EMACS_KEYS_ALWAYS_ON;
 PUBLIC int keypad_mode = DEFAULT_KEYPAD_MODE;
-PUBLIC BOOLEAN case_sensitive = CASE_SENSITIVE_ALWAYS_ON;
+PUBLIC int user_mode = NOVICE_MODE;
 
 PUBLIC BOOLEAN telnet_ok = TRUE;
 #ifndef DISABLE_NEWS
@@ -1757,7 +1762,7 @@ PUBLIC int main ARGS2(
 	}
     }
 
-    if (keypad_mode == NUMBERS_AS_ARROWS) {
+    if (!links_are_numbered()) {
 	if (number_fields)
 	    keypad_mode = LINKS_AND_FIELDS_ARE_NUMBERED;
 	if (number_links)
@@ -2018,7 +2023,7 @@ PUBLIC int main ARGS2(
 	if (crawl && !number_links && !number_fields) {
 	    keypad_mode = NUMBERS_AS_ARROWS;
 	} else if (!nolist) {
-	    if (keypad_mode == NUMBERS_AS_ARROWS) {
+	    if (!links_are_numbered()) {
 		if (number_fields)
 		    keypad_mode = LINKS_AND_FIELDS_ARE_NUMBERED;
 		else
@@ -2035,8 +2040,7 @@ PUBLIC int main ARGS2(
 	status = mainloop();
 	if (!nolist &&
 	    !crawl &&		/* For -crawl it has already been done! */
-	    (keypad_mode == LINKS_ARE_NUMBERED ||
-	     keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED))
+	    links_are_numbered())
 	    printlist(stdout, FALSE);
 #ifdef EXP_PERSISTENT_COOKIES
 	/*
@@ -3598,7 +3602,7 @@ with the PREV_DOC command or from the History List"
    ),
 #ifdef USE_SCROLLBAR
    PARSE_SET(
-      "scrollbar",	4|TOGGLE_ARG,		LYsb,
+      "scrollbar",	4|TOGGLE_ARG,		LYShowScrollbar,
       "toggles showing scrollbar"
    ),
    PARSE_SET(
diff --git a/src/LYOptions.c b/src/LYOptions.c
index 8de61b6b..eebb3f93 100644
--- a/src/LYOptions.c
+++ b/src/LYOptions.c
@@ -509,11 +509,13 @@ draw_options:
 
     LYmove(L_Keypad, 5);
     addlbl("(K)eypad mode                : ");
-    LYaddstr((keypad_mode == NUMBERS_AS_ARROWS) ?
-				"Numbers act as arrows             " :
-	 ((keypad_mode == LINKS_ARE_NUMBERED) ?
-				"Links are numbered                " :
-				"Links and form fields are numbered"));
+    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            : ");
@@ -2146,6 +2148,9 @@ static OptValues keypad_mode_values[]	= {
 	{ LINKS_AND_FIELDS_ARE_NUMBERED,
 			      "Links and form fields are numbered",
 			      "links_and_forms" },
+	{ FIELDS_ARE_NUMBERED,
+			      "Form fields are numbered",
+			      "forms_numbered" },
 	{ 0, 0, 0 }};
 static char * lineedit_mode_string	= "lineedit_mode";
 static char * mail_address_string	= "personal_mail_address";
@@ -2154,6 +2159,7 @@ static OptValues search_type_values[] = {
 	{ FALSE,	    "Case insensitive",  "case_insensitive" },
 	{ TRUE,		    "Case sensitive",	 "case_sensitive" },
 	{ 0, 0, 0 }};
+
 #if defined(USE_SLANG) || defined(COLOR_CURSES)
 static char * show_color_string		= "show_color";
 static OptValues show_color_values[] = {
@@ -2163,7 +2169,13 @@ static OptValues show_color_values[] = {
 	{ SHOW_COLOR_ALWAYS,	always_string,	always_string },
 	{ 0, 0, 0 }};
 #endif
+
 static char * show_cursor_string	= "show_cursor";
+
+#if USE_SCROLLBAR
+static char * show_scrollbar_string	= "show_scrollbar";
+#endif
+
 static char * user_mode_string		= "user_mode";
 static OptValues user_mode_values[] = {
 	{ NOVICE_MODE,		"Novice",	"Novice" },
@@ -2679,6 +2691,14 @@ PUBLIC int postoptions ARGS1(
 	    LYShowCursor = (BOOL) code;
 	}
 
+#ifdef USE_SCROLLBAR
+	/* Show Scrollbar: ON/OFF */
+	if (!strcmp(data[i].tag, show_scrollbar_string)
+	 && GetOptValues(bool_values, data[i].value, &code)) {
+	    LYShowScrollbar = (BOOL) code;
+	}
+#endif
+
 	/* User Mode: SELECT */
 	if (!strcmp(data[i].tag, user_mode_string)
 	 && GetOptValues(user_mode_values, data[i].value, &user_mode)) {
@@ -3392,6 +3412,14 @@ PRIVATE int gen_options ARGS1(
     PutOptValues(fp0, LYShowCursor, bool_values);
     EndSelect(fp0);
 
+#ifdef USE_SCROLLBAR
+    /* Show scrollbar: ON/OFF */
+    PutLabel(fp0, gettext("Show scrollbar"), show_scrollbar_string);
+    BeginSelect(fp0, show_scrollbar_string);
+    PutOptValues(fp0, LYShowScrollbar, bool_values);
+    EndSelect(fp0);
+#endif
+
     /* Select Popups: ON/OFF */
     PutLabel(fp0, gettext("Popups for select fields"), select_popups_string);
     BeginSelect(fp0, select_popups_string);
diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c
index 7dd55482..93a6457c 100644
--- a/src/LYReadCFG.c
+++ b/src/LYReadCFG.c
@@ -1393,6 +1393,8 @@ PRIVATE Config_Type Config_Table [] =
      PARSE_Env("nntp_proxy",           0),
      PARSE_ENV("nntpserver",           0), /* actually NNTPSERVER */
 #endif
+     PARSE_SET("number_fields_on_left",number_fields_on_left),
+     PARSE_SET("number_links_on_left", number_links_on_left),
      PARSE_SET("no_dot_files",         no_dotfiles),
      PARSE_SET("no_file_referer",      no_filereferer),
 #ifndef VMS
@@ -1436,7 +1438,7 @@ PRIVATE Config_Type Config_Table [] =
      PARSE_STR("save_space",           lynx_save_space),
      PARSE_SET("scan_for_buried_news_refs", scan_for_buried_news_references),
 #ifdef USE_SCROLLBAR
-     PARSE_SET("scrollbar",            LYsb),
+     PARSE_SET("scrollbar",            LYShowScrollbar),
      PARSE_SET("scrollbar_arrow",      LYsb_arrow),
 #endif
      PARSE_SET("seek_frag_area_in_cur", LYSeekFragAREAinCur),
@@ -1708,6 +1710,7 @@ PRIVATE void do_read_cfg ARGS5(
 	/* Significant lines are of the form KEYWORD:WHATEVER */
 	if ((value = strchr (name, ':')) == 0) {
 	    /* fprintf (stderr, "Bad line-- no :\n"); */
+	    CTRACE((tfp, "LYReadCFG: missing ':' %s\n", name));
 	    continue;
 	}
 
@@ -1729,9 +1732,11 @@ PRIVATE void do_read_cfg ARGS5(
 		*cp = 0;
 	}
 
+	CTRACE2(TRACE_CFG, (tfp, "LYReadCFG %s:%s\n", name, value));
 	tbl = lookup_config(name);
 	if (tbl->name == 0) {
 	    /* lynx ignores unknown keywords */
+	    CTRACE((tfp, "LYReadCFG: ignored %s:%s\n", name, value));
 	    continue;
 	}
 #ifdef SH_EX
diff --git a/src/LYStrings.c b/src/LYStrings.c
index 9960f626..5a3df082 100644
--- a/src/LYStrings.c
+++ b/src/LYStrings.c
@@ -419,7 +419,7 @@ PRIVATE int set_clicked_link ARGS4(
 		c = LAC_TO_LKC0(LYK_PREV_PAGE);
 	}
 #ifdef USE_SCROLLBAR
-    } else if (x == LYcols - 1 && LYsb && LYsb_begin >= 0) {
+    } else if (x == LYcols - 1 && LYShowScrollbar && LYsb_begin >= 0) {
 	int h = display_lines - 2*(LYsb_arrow != 0);
 
 	mouse_link = -2;
@@ -700,7 +700,7 @@ PUBLIC int LYmbcsstrlen ARGS3(
 #endif /* USE_SLANG */
 
 #if !defined(GetChar) && defined(NCURSES)
-#define GetChar() wgetch(my_subwindow ? my_subwindow : LYwin)
+#define GetChar() wgetch(LYtopwindow())
 #endif
 
 #if !defined(GetChar) && defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
@@ -752,37 +752,6 @@ PRIVATE int myGetChar NOARGS
 #endif /* HAVE_KEYPAD */
 #endif /* !defined(GetChar) */
 
-/*
- * Workaround a bug in ncurses order-of-refresh by setting a pointer to
- * the topmost window that should be displayed.
- *
- * FIXME: the associated call on 'keypad()' is not needed for Unix, but
- * something in the OS/2 EMX port requires it.
- */
-#ifndef USE_SLANG
-PRIVATE WINDOW *my_subwindow;
-
-PUBLIC void LYsubwindow ARGS1(WINDOW *, param)
-{
-    if (param != 0) {
-	my_subwindow = param;
-#if defined(NCURSES) || defined(PDCURSES)
-	keypad(my_subwindow, TRUE);
-#if defined(HAVE_GETBKGD) /* not defined in ncurses 1.8.7 */
-	wbkgd(my_subwindow, getbkgd(LYwin));
-	wbkgdset(my_subwindow, getbkgd(LYwin));
-#endif
-#endif
-	scrollok(my_subwindow, TRUE);
-    } else {
-	touchwin(LYwin);
-	delwin(my_subwindow);
-	my_subwindow = 0;
-    }
-}
-#endif
-
-
 #if defined(USE_SLANG) && defined(USE_MOUSE)
 PRIVATE int sl_parse_mouse_event ARGS3(int *, x, int *, y, int *, button)
 {
diff --git a/src/LYUtils.c b/src/LYUtils.c
index f3bcc1e0..a743f4ad 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -2779,18 +2779,19 @@ PUBLIC int is_url ARGS1(
 {
     char *cp = filename;
     char *cp1;
+    int result = NOT_A_URL_TYPE;
 
     /*
      *	Don't crash on an empty argument.
      */
     if (cp == NULL || *cp == '\0')
-	return(0);
+	return(result);
 
     /*
      *	Can't be a URL if it lacks a colon.
      */
     if (NULL == strchr(cp, ':'))
-	return(0);
+	return(result);
 
     /*
      *	Kill beginning spaces.
@@ -2804,61 +2805,63 @@ PUBLIC int is_url ARGS1(
      *	a colon later in the string.  Also can't be
      *  a URL if it starts with a colon. - KW
      */
-    if (*cp == ':' || LYIsHtmlSep(*cp))
-	return(0);
+    if (*cp == ':' || LYIsHtmlSep(*cp)) {
+	result = NOT_A_URL_TYPE;
 
-    if (compare_type(cp, "news:", 5)) {
-	return(NEWS_URL_TYPE);
+#ifndef DISABLE_NEWS
+    } else if (compare_type(cp, "news:", 5)) {
+	result = NEWS_URL_TYPE;
 
     } else if (compare_type(cp, "nntp:", 5)) {
-	return(NNTP_URL_TYPE);
+	result = NNTP_URL_TYPE;
 
     } else if (compare_type(cp, "snews:", 6)) {
-	return(SNEWS_URL_TYPE);
+	result = SNEWS_URL_TYPE;
 
     } else if (compare_type(cp, "newspost:", 9)) {
 	/*
 	 *  Special Lynx type to handle news posts.
 	 */
-	return(NEWSPOST_URL_TYPE);
+	result = NEWSPOST_URL_TYPE;
 
     } else if (compare_type(cp, "newsreply:", 10)) {
 	/*
 	 *  Special Lynx type to handle news replies (followups).
 	 */
-	return(NEWSREPLY_URL_TYPE);
+	result = NEWSREPLY_URL_TYPE;
 
     } else if (compare_type(cp, "snewspost:", 10)) {
 	/*
 	 *  Special Lynx type to handle snews posts.
 	 */
-	return(NEWSPOST_URL_TYPE);
+	result = NEWSPOST_URL_TYPE;
 
     } else if (compare_type(cp, "snewsreply:", 11)) {
 	/*
 	 *  Special Lynx type to handle snews replies (followups).
 	 */
-	return(NEWSREPLY_URL_TYPE);
+	result = NEWSREPLY_URL_TYPE;
+#endif
 
     } else if (compare_type(cp, "mailto:", 7)) {
-	return(MAILTO_URL_TYPE);
+	result = MAILTO_URL_TYPE;
 
 #ifndef DISABLE_BIBP
     } else if (compare_type(cp, "bibp:", 5)) {
-	return(BIBP_URL_TYPE);
+	result = BIBP_URL_TYPE;
 #endif
 
     } else if (compare_type(cp, "file:", 5)) {
 	if (LYisLocalFile(cp)) {
-	    return(FILE_URL_TYPE);
+	    result = FILE_URL_TYPE;
 	} else if (LYIsHtmlSep(cp[5]) && LYIsHtmlSep(cp[6])) {
-	    return(FTP_URL_TYPE);
+	    result = FTP_URL_TYPE;
 	} else {
-	    return(0);
+	    result = NOT_A_URL_TYPE;
 	}
 
     } else if (compare_type(cp, "data:", 5)) {
-	return(DATA_URL_TYPE);
+	result = DATA_URL_TYPE;
 
     } else if (compare_type(cp, "lynxexec:", 9)) {
 	/*
@@ -2866,7 +2869,7 @@ PUBLIC int is_url ARGS1(
 	 *  of commands or scripts which require a pause to
 	 *  read the screen upon completion.
 	 */
-	return(LYNXEXEC_URL_TYPE);
+	result = LYNXEXEC_URL_TYPE;
 
     } else if (compare_type(cp, "lynxprog:", 9)) {
 	/*
@@ -2874,146 +2877,161 @@ PUBLIC int is_url ARGS1(
 	 *  of commands, scripts or programs with do not
 	 *  require a pause to read screen upon completion.
 	 */
-	return(LYNXPROG_URL_TYPE);
+	result = LYNXPROG_URL_TYPE;
 
     } else if (compare_type(cp, "lynxcgi:", 8)) {
 	/*
 	 *  Special External Lynx type to handle cgi scripts.
 	 */
-	return(LYNXCGI_URL_TYPE);
+	result = LYNXCGI_URL_TYPE;
 
     } else if (compare_type(cp, "LYNXPRINT:", 10)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
-	return(LYNXPRINT_URL_TYPE);
+	result = LYNXPRINT_URL_TYPE;
 
     } else if (compare_type(cp, "LYNXOPTIONS:", 12)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
-	return(LYNXOPTIONS_URL_TYPE);
+	result = LYNXOPTIONS_URL_TYPE;
 
     } else if (compare_type(cp, "LYNXCFG:", 8)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
-	return(LYNXCFG_URL_TYPE);
+	result = LYNXCFG_URL_TYPE;
 
     } else if (compare_type(cp, "LYNXMESSAGES:", 13)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
-	return(LYNXMESSAGES_URL_TYPE);
+	result = LYNXMESSAGES_URL_TYPE;
 
     } else if (compare_type(cp, "LYNXCOMPILEOPTS:", 16)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
-	return(LYNXCOMPILE_OPTS_URL_TYPE);
+	result = LYNXCOMPILE_OPTS_URL_TYPE;
 
     } else if (compare_type(cp, "LYNXDOWNLOAD:", 13)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
-	return(LYNXDOWNLOAD_URL_TYPE);
+	result = LYNXDOWNLOAD_URL_TYPE;
 
     } else if (compare_type(cp, "LYNXDIRED:", 10)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
-	return(LYNXDIRED_URL_TYPE);
+	result = LYNXDIRED_URL_TYPE;
 
     } else if (compare_type(cp, "LYNXHIST:", 9)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
-	return(LYNXHIST_URL_TYPE);
+	result = LYNXHIST_URL_TYPE;
 
     } else if (compare_type(cp, "LYNXKEYMAP:", 11)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
-	return(LYNXKEYMAP_URL_TYPE);
+	result = LYNXKEYMAP_URL_TYPE;
 
     } else if (compare_type(cp, "LYNXIMGMAP:", 11)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
 	(void)is_url(&cp[11]);	/* forces lower/uppercase of next part */
-	return(LYNXIMGMAP_URL_TYPE);
+	result = LYNXIMGMAP_URL_TYPE;
 
     } else if (compare_type(cp, "LYNXCOOKIE:", 11)) {
 	/*
 	 *  Special Internal Lynx type.
 	 */
-	return(LYNXCOOKIE_URL_TYPE);
+	result = LYNXCOOKIE_URL_TYPE;
 
-    } else if (strstr((cp+3), "://") == NULL) {
+    } else if (strlen(cp) >= 3
+	    && strstr((cp+3), "://") == NULL) {
 	/*
 	 *  If it doesn't contain "://", and it's not one of the
 	 *  the above, it can't be a URL with a scheme we know,
 	 *  so check if it's an unknown scheme for which proxying
 	 *  has been set up. - FM
 	 */
-	return(LYCheckForProxyURL(filename));
+	if ((cp1 = strstr(cp, ":")) != NULL
+	 && (cp1 - cp) > 1		/* exclude DOS-style device:/path */
+	 && LYisAbsPath(cp1+1)) {
+	    result = NCFTP_URL_TYPE;
+	} else {
+	    result = LYCheckForProxyURL(filename);
+	}
 
     } else if (compare_type(cp, "http:", 5)) {
-	return(HTTP_URL_TYPE);
+	result = HTTP_URL_TYPE;
 
     } else if (compare_type(cp, "https:", 6)) {
-	return(HTTPS_URL_TYPE);
+	result = HTTPS_URL_TYPE;
 
+#ifndef DISABLE_GOPHER
     } else if (compare_type(cp, "gopher:", 7)) {
-	if ((cp1 = strchr(cp+11,'/')) != NULL) {
+	if (strlen(cp) >= 11
+	 && (cp1 = strchr(cp+11,'/')) != NULL) {
 
 	    if (TOUPPER(*(cp1+1)) == 'H' || *(cp1+1) == 'w')
 		/* if this is a gopher html type */
-		return(HTML_GOPHER_URL_TYPE);
+		result = HTML_GOPHER_URL_TYPE;
 	    else if (*(cp1+1) == 'T' || *(cp1+1) == '8')
-		return(TELNET_GOPHER_URL_TYPE);
+		result = TELNET_GOPHER_URL_TYPE;
 	    else if (*(cp1+1) == '7')
-		return(INDEX_GOPHER_URL_TYPE);
+		result = INDEX_GOPHER_URL_TYPE;
 	    else
-		return(GOPHER_URL_TYPE);
+		result = GOPHER_URL_TYPE;
 	} else {
-	    return(GOPHER_URL_TYPE);
+	    result = GOPHER_URL_TYPE;
 	}
+#endif
 
+#ifndef DISABLE_FTP
     } else if (compare_type(cp, "ftp:", 4)) {
-	return(FTP_URL_TYPE);
+	result = FTP_URL_TYPE;
+#endif
 
     } else if (compare_type(cp, "wais:", 5)) {
-	return(WAIS_URL_TYPE);
+	result = WAIS_URL_TYPE;
 
     } else if (compare_type(cp, "telnet:", 7)) {
-	return(TELNET_URL_TYPE);
+	result = TELNET_URL_TYPE;
 
     } else if (compare_type(cp, "tn3270:", 7)) {
-	return(TN3270_URL_TYPE);
+	result = TN3270_URL_TYPE;
 
     } else if (compare_type(cp, "rlogin:", 7)) {
-	return(RLOGIN_URL_TYPE);
+	result = RLOGIN_URL_TYPE;
 
     } else if (compare_type(cp, "cso:", 4)) {
-	return(CSO_URL_TYPE);
+	result = CSO_URL_TYPE;
 
+#ifndef DISABLE_FINGER
     } else if (compare_type(cp, "finger:", 7)) {
-	return(FINGER_URL_TYPE);
+	result = FINGER_URL_TYPE;
+#endif
 
     } else if (compare_type(cp, "afs:", 4)) {
-	return(AFS_URL_TYPE);
+	result = AFS_URL_TYPE;
 
     } else if (compare_type(cp, "prospero:", 9)) {
-	return(PROSPERO_URL_TYPE);
+	result = PROSPERO_URL_TYPE;
 
     } else {
 	/*
 	 *  Check if it's an unknown scheme for which
 	 *  proxying has been set up. - FM
 	 */
-	return(LYCheckForProxyURL(filename));
+	result = LYCheckForProxyURL(filename);
     }
+    return result;
 }
 
 /*
@@ -3278,7 +3296,8 @@ PUBLIC BOOLEAN inlocaldomain NOARGS
 #endif /* LINUX */
 
     } else {
-	CTRACE((tfp, "Could not get ttyname or open UTMP file %s\n", UTMP_FILE));
+	CTRACE((tfp, "Could not get ttyname (returned %s) or open UTMP file %s\n",
+		      (cp != 0) ? cp : "<null>", UTMP_FILE));
     }
 
     return(FALSE);
@@ -3852,7 +3871,7 @@ PRIVATE int fmt_tempname ARGS3(
 	CONST char *,	suffix)
 {
     int code;
-#if defined(USE_MKSTEMP) && defined(HAVE_MKSTEMP)
+#if defined(HAVE_MKSTEMP)
     int fd;
     char interim[LY_MAXPATH];
     sprintf(interim, "%.*sXXXXXX", LY_MAXPATH - 8, prefix);
@@ -7360,7 +7379,7 @@ PUBLIC void LYTrimPathSep ARGS1(
 	path[len-1] = 0;
 }
 
-#ifdef DOSPATH
+#if defined(DOSPATH) && !defined(__DJGPP__)
 #define PATHSEP_STR "\\"
 #else
 #define PATHSEP_STR "/"
diff --git a/src/LYUtils.h b/src/LYUtils.h
index db0b6bbe..95c89eb2 100644
--- a/src/LYUtils.h
+++ b/src/LYUtils.h
@@ -223,6 +223,7 @@ typedef enum {
     HTTP_URL_TYPE,
     FILE_URL_TYPE,
     FTP_URL_TYPE,
+    NCFTP_URL_TYPE,
     WAIS_URL_TYPE,
     NEWS_URL_TYPE,
     NNTP_URL_TYPE,
diff --git a/src/LYrcFile.c b/src/LYrcFile.c
index 71068929..f79d8d11 100644
--- a/src/LYrcFile.c
+++ b/src/LYrcFile.c
@@ -47,9 +47,12 @@ PRIVATE Config_Enum tbl_file_sort[] = {
 };
 
 PUBLIC Config_Enum tbl_keypad_mode[] = {
+    { "FIELDS_ARE_NUMBERED", FIELDS_ARE_NUMBERED },
     { "LINKS_AND_FIELDS_ARE_NUMBERED", LINKS_AND_FIELDS_ARE_NUMBERED },
-    { "LINKS_AND_FORM_FIELDS_ARE_NUMBERED", LINKS_AND_FIELDS_ARE_NUMBERED },
     { "LINKS_ARE_NUMBERED", LINKS_ARE_NUMBERED },
+    { "LINKS_ARE_NOT_NUMBERED", NUMBERS_AS_ARROWS },
+    /* obsolete variations: */
+    { "LINKS_AND_FORM_FIELDS_ARE_NUMBERED", LINKS_AND_FIELDS_ARE_NUMBERED },
     { "NUMBERS_AS_ARROWS", NUMBERS_AS_ARROWS },
     { NULL,		DEFAULT_KEYPAD_MODE }
 };
@@ -400,6 +403,9 @@ WARNING - This is potentially dangerous.  Since you may view\n\
           you are viewing trusted source information.\n\
 ")),
 #endif
+#if USE_SCROLLBAR
+    MAYBE_SET("scrollbar",             LYShowScrollbar, MSG_ENABLE_LYNXRC),
+#endif
     PARSE_SET("select_popups",         LYSelectPopups, N_("\
 select_popups specifies whether the OPTIONs in a SELECT block which\n\
 lacks a MULTIPLE attribute are presented as a vertical list of radio\n\
@@ -530,6 +536,9 @@ PUBLIC void read_rc ARGS1(FILE *, fp)
 	if ((fp = fopen(rcfile, TXT_R)) == NULL) {
 	    return;
 	}
+	CTRACE((tfp, "read_rc opened %s\n", rcfile));
+    } else {
+	CTRACE((tfp, "read_rc used passed-in stream\n"));
     }
 
     /*
@@ -551,11 +560,15 @@ PUBLIC void read_rc ARGS1(FILE *, fp)
 	/*
 	 * Parse the "name=value" strings.
 	 */
-	if ((value = strchr(name, '=')) == 0)
+	if ((value = strchr(name, '=')) == 0) {
+	    CTRACE((tfp, "LYrcFile: missing '=' %s\n", name));
 	    continue;
+	}
 	*value++ = '\0';
 	LYTrimTrailing(name);
 	value = LYSkipBlanks(value);
+	CTRACE2(TRACE_CFG, (tfp, "LYrcFile %s:%s\n", name, value));
+
 	tbl = lookup_config(name);
 	if (tbl->name == 0) {
 	    char *special = "multi_bookmark";
@@ -563,8 +576,10 @@ PUBLIC void read_rc ARGS1(FILE *, fp)
 		tbl = lookup_config(special);
 	    }
 	    /* lynx ignores unknown keywords */
-	    if (tbl->name == 0)
+	    if (tbl->name == 0) {
+		CTRACE((tfp, "LYrcFile: ignored %s=%s\n", name, value));
 		continue;
+	    }
 	}
 
 	q = ParseUnionOf(tbl);