diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/GridText.c | 2 | ||||
-rw-r--r-- | src/HTFWriter.c | 4 | ||||
-rw-r--r-- | src/HTML.c | 16 | ||||
-rw-r--r-- | src/LYCurses.c | 281 | ||||
-rw-r--r-- | src/LYCurses.h | 33 | ||||
-rw-r--r-- | src/LYExtern.c | 4 | ||||
-rw-r--r-- | src/LYForms.c | 170 | ||||
-rw-r--r-- | src/LYGlobalDefs.h | 4 | ||||
-rw-r--r-- | src/LYHash.h | 3 | ||||
-rw-r--r-- | src/LYKeymap.c | 547 | ||||
-rw-r--r-- | src/LYKeymap.h | 20 | ||||
-rw-r--r-- | src/LYMail.c | 9 | ||||
-rw-r--r-- | src/LYMain.c | 40 | ||||
-rw-r--r-- | src/LYMainLoop.c | 58 | ||||
-rw-r--r-- | src/LYOptions.c | 157 | ||||
-rw-r--r-- | src/LYStrings.c | 427 | ||||
-rw-r--r-- | src/LYStrings.h | 10 | ||||
-rw-r--r-- | src/LYStyle.c | 143 | ||||
-rw-r--r-- | src/LYStyle.h | 4 | ||||
-rw-r--r-- | src/LYUtils.c | 10 |
20 files changed, 1217 insertions, 725 deletions
diff --git a/src/GridText.c b/src/GridText.c index 3c148609..5786b5cb 100644 --- a/src/GridText.c +++ b/src/GridText.c @@ -4432,7 +4432,7 @@ PUBLIC void _internal_HTC ARGS3(HText *,text, int,style, int,dir) if (line->numstyles > 0 && dir == 0 && line->styles[line->numstyles].direction && line->styles[line->numstyles].style == style && - line->styles[line->numstyles].horizpos + (int) line->styles[line->numstyles].horizpos == (int)line->size - ctrl_chars_on_this_line) { /* * If this is an OFF change directly preceded by an diff --git a/src/HTFWriter.c b/src/HTFWriter.c index 6ea0dea1..653c2a9f 100644 --- a/src/HTFWriter.c +++ b/src/HTFWriter.c @@ -740,7 +740,7 @@ PUBLIC HTStream* HTSaveToFile ARGS3( return(NULL); } - if (((cp=strchr(pres->rep->name, ';')) != NULL) && + if (((cp = strchr(pres->rep->name, ';')) != NULL) && strstr((cp+1), "charset") != NULL) { _user_message(MSG_DOWNLOAD_OR_CANCEL, pres->rep->name); } else if (*(pres->rep->name) != '\0') { @@ -749,7 +749,7 @@ PUBLIC HTStream* HTSaveToFile ARGS3( _statusline(CANNOT_DISPLAY_FILE_D_OR_C); } - while(c != 'D') { + while (c != 'D' && c != 'C') { c = LYgetch_single(); #ifdef VMS /* diff --git a/src/HTML.c b/src/HTML.c index c0fcf621..f346f2de 100644 --- a/src/HTML.c +++ b/src/HTML.c @@ -3204,7 +3204,7 @@ PRIVATE int HTML_start_element ARGS6( #else /*Close an HREF-less NAMED-ed now if force_empty_hrefless_a was requested - VH*/ - if (href == NULL && force_empty_hrefless_a) { + if (href == NULL && force_empty_hrefless_a) { SET_SKIP_STACK(HTML_A); HTML_end_element(me, HTML_A, include); } @@ -5181,7 +5181,11 @@ PRIVATE int HTML_start_element ARGS6( /* text+file don't go in here */ if ((UseALTasVALUE == TRUE) || (present && present[HTML_INPUT_VALUE] && - value[HTML_INPUT_VALUE] && *value[HTML_INPUT_VALUE])) { + value[HTML_INPUT_VALUE] && + (*value[HTML_INPUT_VALUE] || + (I.type && (!strcasecomp(I.type, "checkbox") || + !strcasecomp(I.type, "radio")))))) { + /* * Convert any HTML entities or decimal escaping. - FM */ @@ -6731,11 +6735,11 @@ PRIVATE int HTML_end_element ARGS3( */ me->inA = FALSE; #ifdef MARK_HIDDEN_LINKS - if (hidden_link_marker && *hidden_link_marker && - HText_isAnchorBlank(me->text, me->CurrentANum) ) { - HText_appendText(me->text,hidden_link_marker); + if (hidden_link_marker && *hidden_link_marker && + HText_isAnchorBlank(me->text, me->CurrentANum) ) { + HText_appendText(me->text,hidden_link_marker); } -#endif +#endif UPDATE_STYLE; if (me->inBoldA == TRUE && me->inBoldH == FALSE) HText_appendCharacter(me->text, LY_BOLD_END_CHAR); diff --git a/src/LYCurses.c b/src/LYCurses.c index d25d10c3..6991981d 100644 --- a/src/LYCurses.c +++ b/src/LYCurses.c @@ -198,48 +198,44 @@ PRIVATE void sl_suspend ARGS1( #endif /* SIGSTOP */ return; } +#endif /* USE_SLANG */ -#else /* Not slang: */ - -#ifdef VMS /* -** This function boxes windows with graphic characters for -** VMS curses. Pass it the window, it's height, and it's -** width. - FM +** This function boxes windows for (n)curses. */ -PUBLIC void VMSbox ARGS3( +PUBLIC void LYbox ARGS2( WINDOW *, win, - int, height, - int, width) + BOOLEAN, formfield GCC_UNUSED) { +#ifdef USE_SLANG + SLsmg_draw_box(win->top_y, win->left_x, win->height, win->width + 4); +#else +#ifdef VMS + /* + * This should work for VAX-C and DEC-C, since they both have the same + * win._max_y and win._max_x members -TD + * + * (originally VMSbox by FM) + */ int i; wmove(win, 0, 0); waddstr(win, "\033)0\016l"); - for (i = 1; i < width; i++) + for (i = 1; i < win->_max_x; i++) waddch(win, 'q'); waddch(win, 'k'); - for (i = 1; i < height-1; i++) { + for (i = 1; i < win->_max_y-1; i++) { wmove(win, i, 0); waddch(win, 'x'); - wmove(win, i, width-1); + wmove(win, i, win->_max_x-1); waddch(win, 'x'); } wmove(win, i, 0); waddch(win, 'm'); - for (i = 1; i < width; i++) + for (i = 1; i < win->_max_x; i++) waddch(win, 'q'); waddstr(win, "j\017"); -} -#else -/* -** This function boxes windows for non-VMS (n)curses. -** Pass it the window. - FM -*/ -PUBLIC void LYbox ARGS2( - WINDOW *, win, - BOOLEAN, formfield GCC_UNUSED) -{ +#else /* !VMS */ /* * If the terminal is in UTF-8 mode, it probably cannot understand * box drawing characters as (n)curses handles them. (This may also @@ -276,9 +272,10 @@ PUBLIC void LYbox ARGS2( if (formfield) wcurses_css(win, "frame", ABS_OFF); #endif -} #endif /* VMS */ + wrefresh(win); #endif /* USE_SLANG */ +} #if defined(USE_COLOR_STYLE) /* Ok, explanation of the USE_COLOR_STYLE styles. The basic styles (ie non @@ -336,109 +333,108 @@ PUBLIC void curses_w_style ARGS3( { #if OMIT_SCN_KEEPING # define SPECIAL_STYLE /*(CSHASHSIZE+1) */ 88888 - /* if TRACEs are not compiled in, this macro is redundant - we neend't valid - 'ds' to stack off. */ +/* if TRACEs are not compiled in, this macro is redundant - we needn't valid +'ds' to stack off. */ #endif - int YP,XP; + int YP,XP; #if !OMIT_SCN_KEEPING - bucket* ds= (style == NOSTYLE ? &nostyle_bucket : &hashStyles[style]); + bucket* ds= (style == NOSTYLE ? &nostyle_bucket : &hashStyles[style]); #else - bucket* ds= (style == NOSTYLE ? &nostyle_bucket : - (style== SPECIAL_STYLE ? &special_bucket :&hashStyles[style]) ); + bucket* ds= (style == NOSTYLE ? &nostyle_bucket : + (style== SPECIAL_STYLE ? &special_bucket :&hashStyles[style]) ); #endif - if (!ds->name) - { - CTRACE((tfp, "CSS.CS:Style %d not configured\n",style)); + if (!ds->name) { + CTRACE((tfp, "CSS.CS:Style %d not configured\n",style)); #if !OMIT_SCN_KEEPING - return; + return; #endif - } + } - CTRACE((tfp, "CSS.CS:<%s%s> (%d)\n",(dir?"":"/"),ds->name,ds->code)); + CTRACE((tfp, "CSS.CS:<%s%s> (%d)\n",(dir?"":"/"),ds->name,ds->code)); - getyx (win, YP, XP); + getyx (win, YP, XP); - if (style == s_normal && dir) - { - wattrset(win,A_NORMAL); - if (win==stdscr) cached_styles[YP][XP]=s_normal; - return; - } + if (style == s_normal && dir) { + wattrset(win,A_NORMAL); + if (win==stdscr) cached_styles[YP][XP]=s_normal; + return; + } - switch (dir) - { - /* ABS_OFF is the same as STACK_OFF for the moment */ - case STACK_OFF: - if (last_colorattr_ptr) { - int last_attr = last_styles[--last_colorattr_ptr]; - LYAttrset(win,last_attr,last_attr); - } - else - LYAttrset(win,A_NORMAL,-1); - return; - - case STACK_ON: /* remember the current attributes */ - if (last_colorattr_ptr > 127) { - CTRACE((tfp,"........... %s (0x%x) %s\r\n", - "attribute cache FULL, dropping last", - last_styles[last_colorattr_ptr], - "in LynxChangeStyle(curses_w_style)")); - last_colorattr_ptr--; - } - last_styles[last_colorattr_ptr++] = getattrs(stdscr); - /* don't cache style changes for active links */ + switch (dir) + { + /* ABS_OFF is the same as STACK_OFF for the moment */ + case STACK_OFF: + if (last_colorattr_ptr) { + int last_attr = last_styles[--last_colorattr_ptr]; + LYAttrset(win,last_attr,last_attr); + } + else + LYAttrset(win,A_NORMAL,-1); + break; + + case STACK_ON: /* remember the current attributes */ + if (last_colorattr_ptr > 127) { + CTRACE((tfp,"........... %s (0x%x) %s\r\n", + "attribute cache FULL, dropping last", + last_styles[last_colorattr_ptr], + "in LynxChangeStyle(curses_w_style)")); + last_colorattr_ptr--; + } + last_styles[last_colorattr_ptr++] = getattrs(stdscr); + /* don't cache style changes for active links */ #if OMIT_SCN_KEEPING - /* since we don't compute the hcode to stack off in HTML.c, we - * don't know whether this style is configured. So, we - * shouldn't simply return on stacking on on unconfigured - * styles, we should push curr attrs on stack. -HV - */ - if (!ds->name) return; + /* since we don't compute the hcode to stack off in HTML.c, we + * don't know whether this style is configured. So, we + * shouldn't simply return on stacking on unconfigured + * styles, we should push curr attrs on stack. -HV + */ + if (!ds->name) break; #endif - if (style != s_alink) - { - CTRACE((tfp, "CACHED: <%s> @(%d,%d)\n", ds->name, YP, XP)); - if (win==stdscr) cached_styles[YP][XP]=style; - } - LYAttrset(win, ds->color, ds->mono); - return; - - case ABS_ON: /* change without remembering the previous style */ - /* don't cache style changes for active links */ - if (style != s_alink) - { - CTRACE((tfp, "CACHED: <%s> @(%d,%d)\n", ds->name, YP, XP)); - if (win==stdscr) cached_styles[YP][XP]=style; - } - LYAttrset(win, ds->color, ds->mono); - return; + if (style != s_alink) { + CTRACE((tfp, "CACHED: <%s> @(%d,%d)\n", ds->name, YP, XP)); + if (win == stdscr) cached_styles[YP][XP] = style; } + LYAttrset(win, ds->color, ds->mono); + break; + + case ABS_ON: /* change without remembering the previous style */ + /* don't cache style changes for active links */ + if (style != s_alink) { + CTRACE((tfp, "CACHED: <%s> @(%d,%d)\n", ds->name, YP, XP)); + if (win == stdscr) cached_styles[YP][XP] = style; + } + LYAttrset(win, ds->color, ds->mono); + break; + } } /* * wrapper function to set on-screen styles - RP */ -PUBLIC void wcurses_css ARGS3(WINDOW *,win,char*,name,int,dir) -{ - int try_again=1; - while (try_again) - { - int tmpHash=hash_code(name); - CTRACE((tfp, "CSSTRIM:trying to set [%s] style - ", name)); - if (tmpHash==NOSTYLE) { - char *class=strrchr(name, '.'); - CTRACE((tfp, "undefined, trimming at %p\n", class)); - if (class) *class='\0'; - else try_again=0; - } else { - CTRACE((tfp, "ok (%d)\n", hash_code(name))); - curses_w_style(win, hash_code(name), dir); - try_again=0; - } +PUBLIC void wcurses_css ARGS3( + WINDOW *, win, + char*, name, + int, dir) +{ + int try_again = 1; + + while (try_again) { + int tmpHash = hash_code(name); + CTRACE((tfp, "CSSTRIM:trying to set [%s] style - ", name)); + if (tmpHash == NOSTYLE) { + char *class = strrchr(name, '.'); + CTRACE((tfp, "undefined, trimming at %p\n", class)); + if (class) *class = '\0'; + else try_again = 0; + } else { + CTRACE((tfp, "ok (%d)\n", hash_code(name))); + curses_w_style(win, hash_code(name), dir); + try_again = 0; } + } } PUBLIC void curses_css ARGS2(char *,name,int,dir) @@ -1322,6 +1318,52 @@ PUBLIC void LYsubAttr ARGS1( #endif /* FANCY_CURSES */ #endif /* VMS */ +/* Use this rather than the 'wprintw()' function to write a blank-padded + * string to the given window, since someone's asserted that printw doesn't + * handle 8-bit characters unlike addstr (though more info would be useful). + * + * We're blank-filling so that with SVr4 curses, it'll show the background + * color to a uniform width in the popup-menu. + */ +#ifndef USE_SLANG +PUBLIC void LYpaddstr ARGS3( + WINDOW *, the_window, + int, width, + CONST char *, the_string) +{ + width -= strlen(the_string); + waddstr(the_window, the_string); + while (width-- > 0) + waddstr(the_window, " "); +} +#endif + +PUBLIC WINDOW *LYstartPopup ARGS4( + int, top_y, + int, left_x, + int, height, + int, width) +{ + WINDOW *form_window = 0; +#ifdef USE_SLANG + static WINDOW fake_window; + SLsmg_fill_region(top_y, left_x - 1, height, width + 4, ' '); + form_window = &fake_window; + form_window->top_y = top_y; + form_window->left_x = left_x; + form_window->height = height; + form_window->width = width; +#else + if (!(form_window = newwin(height, width + 4, top_y, left_x - 1)) && + !(form_window = newwin(height, 0, top_y, 0))) { + HTAlert(POPUP_FAILED); + } else { + LYsubwindow(form_window); + } +#endif /* USE_SLANG */ + return form_window; +} + PUBLIC void LYstartTargetEmphasis NOARGS { #ifdef USE_COLOR_STYLE @@ -2040,3 +2082,32 @@ PUBLIC void lynx_stop_all_colors NOARGS stop_reverse (); stop_bold (); } + +/* + * If LYShowCursor is ON, move the cursor to the left of the current option, so + * that blind users, who are most likely to have LYShowCursor ON, will have + * it's string spoken or passed to the braille interface as each option is made + * current. Otherwise, move it to the bottom, right column of the screen, to + * "hide" the cursor as for the main document, and let sighted users rely on + * the current option's highlighting or color without the distraction of a + * blinking cursor in the window. - FM + */ +PUBLIC void LYstowCursor ARGS3( + WINDOW *, win, + int, row, + int, col) +{ +#ifdef USE_SLANG + if (LYShowCursor) + SLsmg_gotorc(win->top_y + row, win->left_x + col); + else + LYHideCursor(); + SLsmg_refresh(); +#else + if (LYShowCursor) + wmove(win, row, col); + else + LYHideCursor(); + wrefresh(win); +#endif /* USE_SLANG */ +} diff --git a/src/LYCurses.h b/src/LYCurses.h index 21934a56..f7be0924 100644 --- a/src/LYCurses.h +++ b/src/LYCurses.h @@ -47,7 +47,15 @@ #ifdef USE_SLANG #include <slang.h> -#define WINDOW void + +#undef WINDOW +typedef struct { + int top_y; + int left_x; + int height; + int width; +} WINDOW; + #define waddstr(w,s) addstr(s) #ifndef ACS_UARROW @@ -158,10 +166,6 @@ # endif /* VMS && __GNUC__ */ #endif /* HAVE_CONFIG_H */ -#if defined(NCURSES) || defined(PDCURSES) -extern void LYsubwindow PARAMS((WINDOW * param)); -#endif /* NCURSES */ - /* * PDCurses' mouse code does nothing in the DJGPP configuration. */ @@ -176,12 +180,17 @@ extern void LYsubwindow PARAMS((WINDOW * param)); #define USE_MOUSE 1 #endif -#ifdef VMS -extern void VMSbox PARAMS((WINDOW *win, int height, int width)); +#endif /* USE_SLANG */ + +#ifdef USE_SLANG +#define LYstopPopup() /* nothing */ #else +extern void LYsubwindow PARAMS((WINDOW * param)); +#define LYstopPopup() LYsubwindow(0) +#endif /* NCURSES */ + extern void LYbox PARAMS((WINDOW *win, BOOLEAN formfield)); -#endif /* VMS */ -#endif /* USE_SLANG */ +extern WINDOW *LYstartPopup PARAMS((int top_y, int left_x, int height, int width)); /* * Useful macros not in PDCurses or very old ncurses headers. @@ -247,6 +256,7 @@ extern void LYstartTargetEmphasis NOPARAMS; extern void LYstopTargetEmphasis NOPARAMS; extern void LYtouchline PARAMS((int row)); extern void LYwaddnstr PARAMS((WINDOW *w, CONST char *s, size_t len)); +extern void LYpaddstr PARAMS((WINDOW *w, int width, CONST char *s)); #define LYaddstr(s) LYwaddnstr(stdscr, s, strlen(s)) #define LYaddnstr(s,len) LYwaddnstr(stdscr, s, len) @@ -310,9 +320,6 @@ extern unsigned int Lynx_Color_Flags; /* * Map some curses functions to slang functions. */ -#ifndef WINDOW -#define WINDOW void -#endif #define stdscr NULL #ifdef SLANG_MBCS_HACK extern int PHYSICAL_SLtt_Screen_Cols; @@ -552,4 +559,6 @@ extern void lynx_stop_all_colors NOPARAMS; #define LYHideCursor() move((LYlines - 1), (LYcols - 2)) #endif +extern void LYstowCursor PARAMS((WINDOW * win, int row, int col)); + #endif /* LYCURSES_H */ diff --git a/src/LYExtern.c b/src/LYExtern.c index 338cc42b..8cecb422 100644 --- a/src/LYExtern.c +++ b/src/LYExtern.c @@ -191,8 +191,8 @@ BOOL run_external ARGS2( #ifdef WIN_EX /* 1998/01/26 (Mon) 09:16:13 */ if (c == NULL) { - HTInfoMsg("Not external command exists"); - return; + HTInfoMsg("External command is null"); + return 0; } #endif diff --git a/src/LYForms.c b/src/LYForms.c index 11eb5125..f4b57b78 100644 --- a/src/LYForms.c +++ b/src/LYForms.c @@ -92,11 +92,11 @@ PUBLIC int change_form_link_ex ARGS8( dummy = popup_options(form->num_value, form->select_list, form_link->ly, form_link->lx, form->size, form->size_l, form->disabled); -#if defined(FANCY_CURSES) || defined(USE_SLANG) +#if CTRL_W_HACK != DO_NOTHING if (!enable_scrollback) c = CTRL_W_HACK; /* CTRL-W refresh without clearok */ else -#endif /* FANCY_CURSES || USE_SLANG */ +#endif c = 12; /* CTRL-L for repaint */ break; } @@ -123,11 +123,11 @@ PUBLIC int change_form_link_ex ARGS8( */ form->value_cs = opt_ptr->value_cs; } -#if defined(FANCY_CURSES) || defined(USE_SLANG) +#if CTRL_W_HACK != DO_NOTHING if (!enable_scrollback) c = CTRL_W_HACK; /* CTRL-W refresh without clearok */ else -#endif /* FANCY_CURSES || USE_SLANG */ +#endif c = 12; /* CTRL-L for repaint */ break; @@ -445,14 +445,13 @@ again: ch = LYgetch_input(); #ifdef SUPPORT_MULTIBYTE_EDIT -#ifdef WIN_EX - if (!refresh_mb && (EditBinding(ch) != LYE_CHAR)) - goto again; -#else - if (!refresh_mb && - (EditBinding(ch) != LYE_CHAR) && (EditBinding(ch) != LYE_AIX)) - goto again; + if (!refresh_mb + && (EditBinding(ch) != LYE_CHAR) +#ifndef WIN_EX + && (EditBinding(ch) != LYE_AIX) #endif + ) + goto again; #endif /* SUPPORT_MULTIBYTE_EDIT */ #ifdef VMS if (HadVMSInterrupt) { @@ -854,26 +853,29 @@ PRIVATE int get_popup_option_number ARGS2( return num; } -/* Use this rather than the 'wprintw()' function to write a blank-padded - * string to the given window, since someone's asserted that printw doesn't - * handle 8-bit characters unlike addstr (though more info would be useful). - * - * We're blank-filling so that with SVr4 curses, it'll show the background - * color to a uniform width in the popup-menu. - */ -#ifndef USE_SLANG -PRIVATE void paddstr ARGS3( - WINDOW *, the_window, +PRIVATE void draw_option ARGS5( + WINDOW *, win, + int, entry, int, width, - char *, the_string) + BOOL, reversed, + OptionType *, opt_ptr) { - width -= strlen(the_string); - waddstr(the_window, the_string); - while (width-- > 0) - waddstr(the_window, " "); +#ifdef USE_SLANG + if (reversed) + SLsmg_gotorc((win->top_y + entry), win->left_x + 2); + SLsmg_gotorc(win->top_y + entry, win->left_x + 2); + SLsmg_write_nstring(opt_ptr->name, win->width); + if (reversed) + SLsmg_set_color(0); +#else + wmove(win, entry, 2); + if (reversed) + wstart_reverse(win); + LYpaddstr(win, width, opt_ptr->name); + if (reversed) + wstop_reverse(win); +#endif /* USE_SLANG */ } -#endif - PRIVATE int popup_options ARGS7( int, cur_selection, @@ -891,9 +893,7 @@ PRIVATE int popup_options ARGS7( */ int c = 0, cmd = 0, i = 0, j = 0, rel = 0; int orig_selection = cur_selection; -#ifndef USE_SLANG WINDOW * form_window; -#endif /* !USE_SLANG */ int num_options = 0, top, bottom, length = -1; OptionType * opt_ptr = list; int window_offset = 0; @@ -1017,30 +1017,12 @@ PRIVATE int popup_options ARGS7( * Set up the overall window, including the boxing characters ('*'), * if it all fits. Otherwise, set up the widest window possible. - FM */ -#ifdef USE_SLANG - if (width + 4 > SLtt_Screen_Cols) { + if (width + 4 > LYcols) { lx = 1; width = LYcols - 5; /* avoids a crash? - kw */ } - SLsmg_fill_region(top, lx - 1, bottom - top, width + 4, ' '); -#else - if (!(form_window = newwin(bottom - top, width + 4, top, lx - 1)) && - !(form_window = newwin(bottom - top, 0, top, 0))) { - HTAlert(POPUP_FAILED); + if ((form_window = LYstartPopup(top, lx, bottom - top, width)) == 0) return(orig_selection); - } - scrollok(form_window, TRUE); -#ifdef PDCURSES - keypad(form_window, TRUE); -#endif /* PDCURSES */ -#if defined(NCURSES) || defined(PDCURSES) - LYsubwindow(form_window); -#endif -#if defined(HAVE_GETBKGD) /* not defined in ncurses 1.8.7 */ - wbkgd(form_window, getbkgd(stdscr)); - wbkgdset(form_window, getbkgd(stdscr)); -#endif -#endif /* USE_SLANG */ /* * Set up the window_offset for options. @@ -1071,107 +1053,40 @@ redraw: */ for (i = 0; i <= num_options; i++, opt_ptr = opt_ptr->next) { if (i >= window_offset && i - window_offset < length) { -#ifdef USE_SLANG - SLsmg_gotorc(top + ((i + 1) - window_offset), (lx - 1 + 2)); - SLsmg_write_nstring(opt_ptr->name, width); -#else - wmove(form_window, ((i + 1) - window_offset), 2); - paddstr(form_window, width, opt_ptr->name); -#endif /* USE_SLANG */ + draw_option(form_window, ((i + 1) - window_offset), width, FALSE, opt_ptr); } } -#ifdef USE_SLANG - SLsmg_draw_box(top, (lx - 1), (bottom - top), (width + 4)); -#else -#ifdef VMS - VMSbox(form_window, (bottom - top), (width + 4)); -#else LYbox(form_window, TRUE); -#endif /* VMS */ - wrefresh(form_window); -#endif /* USE_SLANG */ opt_ptr = NULL; /* * Loop on user input. */ while (cmd != LYK_ACTIVATE) { + int row = ((i + 1) - window_offset); /* * Unreverse cur selection. */ if (opt_ptr != NULL) { -#ifdef USE_SLANG - SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 2)); - SLsmg_write_nstring(opt_ptr->name, width); -#else - wmove(form_window, ((i + 1) - window_offset), 2); - paddstr(form_window, width, opt_ptr->name); -#endif /* USE_SLANG */ + draw_option(form_window, row, width, FALSE, opt_ptr); } opt_ptr = list; for (i = 0; i < cur_selection; i++, opt_ptr = opt_ptr->next) ; /* null body */ + row = ((i + 1) - window_offset); -#ifdef USE_SLANG - SLsmg_set_color(2); - SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 2)); - SLsmg_write_nstring(opt_ptr->name, width); - SLsmg_set_color(0); - /* - * If LYShowCursor is ON, move the cursor to the left - * of the current option, so that blind users, who are - * most likely to have LYShowCursor ON, will have it's - * string spoken or passed to the braille interface as - * each option is made current. Otherwise, move it to - * the bottom, right column of the screen, to "hide" - * the cursor as for the main document, and let sighted - * users rely on the current option's highlighting or - * color without the distraction of a blinking cursor - * in the window. - FM - */ - if (LYShowCursor) - SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 1)); - else - SLsmg_gotorc((LYlines - 1), (LYcols - 1)); - SLsmg_refresh(); -#else - wmove(form_window, ((i + 1) - window_offset), 2); -#if defined(WIN_EX) /* FIX */ - wattron(form_window, A_REVERSE); -#else - wstart_reverse(form_window); -#endif - paddstr(form_window, width, opt_ptr->name); -#if defined(WIN_EX) /* FIX */ - wattroff(form_window, A_REVERSE); -#else - wstop_reverse(form_window); -#endif - /* - * If LYShowCursor is ON, move the cursor to the left - * of the current option, so that blind users, who are - * most likely to have LYShowCursor ON, will have it's - * string spoken or passed to the braille interface as - * each option is made current. Otherwise, leave it to - * the right of the current option, since we can't move - * it out of the window, and let sighted users rely on - * the highlighting of the current option without the - * distraction of a blinking cursor preceding it. - FM - */ - if (LYShowCursor) - wmove(form_window, ((i + 1) - window_offset), 1); - wrefresh(form_window); -#endif /* USE_SLANG */ + draw_option(form_window, row, width, TRUE, opt_ptr); + LYstowCursor(form_window, row, 1); c = LYgetch_choice(); if (c == 7) { /* Control-C or Control-G */ cmd = LYK_QUIT; #ifndef USE_SLANG } else if (c == MOUSE_KEY) { - if ((cmd = fancy_mouse(form_window, i + 1 - window_offset, &cur_selection)) < 0) + if ((cmd = fancy_mouse(form_window, row, &cur_selection)) < 0) goto redraw; if (cmd == LYK_ACTIVATE) break; @@ -1852,12 +1767,7 @@ restore_popup_statusline: break; } } -#ifndef USE_SLANG - delwin(form_window); -#if defined(NCURSES) || defined(PDCURSES) - LYsubwindow(0); -#endif -#endif /* !USE_SLANG */ + LYstopPopup(); return(disabled ? orig_selection : cur_selection); } diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h index faa41a86..3def0c78 100644 --- a/src/LYGlobalDefs.h +++ b/src/LYGlobalDefs.h @@ -215,7 +215,7 @@ extern int display_lines; /* number of lines in the display */ extern int dump_output_width; extern int keypad_mode; /* NUMBERS_AS_ARROWS or LINKS_ARE_NUMBERED */ extern int lynx_temp_subspace; -extern int more; /* is there more document to display? */ +extern BOOLEAN more; /* is there more document to display? */ extern int user_mode; /* novice or advanced */ extern int www_search_result; @@ -405,7 +405,7 @@ extern BOOLEAN no_externals; /* don't allow the use of externals */ extern BOOLEAN LYNoISMAPifUSEMAP; /* Omit ISMAP link if MAP present? */ extern int LYHiddenLinks; -extern BOOL Old_DTD; +extern BOOLEAN Old_DTD; #define MBM_V_MAXFILES 25 /* Max number of sub-bookmark files */ /* diff --git a/src/LYHash.h b/src/LYHash.h index 383261f1..8fc83b8f 100644 --- a/src/LYHash.h +++ b/src/LYHash.h @@ -31,14 +31,13 @@ extern int hash_code PARAMS((char* string)); extern bucket special_bucket;/*it's used when OMIT_SCN_KEEPING is 1 in HTML.c and LYCurses.c. */ extern bucket nostyle_bucket;/*initialized properly - to be used in CTRACE when - NOSTYLE is passed as 'style' to curses_w_style */ + NOSTYLE is passed as 'style' to curses_w_style */ extern int hash_code_lowercase_on_fly PARAMS((char* string)); extern int hash_code_aggregate_char PARAMS((char c,int hash)); extern int hash_code_aggregate_lower_str PARAMS((char* c,int hash_was)); extern int s_alink, s_a, s_status, - s_label, s_value, s_high, s_normal, s_alert, s_title, #ifdef USE_SCROLLBAR s_sb_bar, s_sb_bg, s_sb_aa, s_sb_naa, diff --git a/src/LYKeymap.c b/src/LYKeymap.c index 11c6156e..a94749b2 100644 --- a/src/LYKeymap.c +++ b/src/LYKeymap.c @@ -114,7 +114,7 @@ LYK_F_LINK_NUM, LYK_1, LYK_2, LYK_3, LYK_4, LYK_5, LYK_6, LYK_7, /* 4 */ /* 5 */ /* 6 */ /* 7 */ -LYK_8, LYK_9, 0, LYK_TRACE_LOG, +LYK_8, LYK_9, LYK_COMMAND, LYK_TRACE_LOG, /* 8 */ /* 9 */ /* : */ /* ; */ LYK_UP_LINK, LYK_INFO, LYK_DOWN_LINK, LYK_HELP, @@ -625,129 +625,335 @@ LYK_TAG_LINK, LYK_UPLOAD, 0, 0, }; #endif /* DIRED_SUPPORT && OK_OVERRIDE */ -struct rmap { - CONST char *name; - CONST char *doc; -}; - +#define DATA(code, name, doc) { code, name, doc } /* The order of this array must match the LYKeymapCode enum in LYKeymap.h */ -PRIVATE struct rmap revmap[] = { -{ "UNMAPPED", NULL }, -{ "1", NULL }, -{ "2", NULL }, -{ "3", NULL }, -{ "4", NULL }, -{ "5", NULL }, -{ "6", NULL }, -{ "7", NULL }, -{ "8", NULL }, -{ "9", NULL }, -{ "SOURCE", "toggle source/presentation for current document" }, -{ "RELOAD", "reload the current document" }, -{ "PIPE", "pipe the current document to an external command" }, -{ "QUIT", "quit the browser" }, -{ "ABORT", "quit the browser unconditionally" }, -{ "NEXT_PAGE", "view the next page of the document" }, -{ "PREV_PAGE", "view the previous page of the document" }, -{ "UP_TWO", "go back two lines in the document" }, -{ "DOWN_TWO", "go forward two lines in the document" }, -{ "UP_HALF", "go back half a page in the document" }, -{ "DOWN_HALF", "go forward half a page in the document" }, -{ "REFRESH", "refresh the screen to clear garbled text" }, -{ "HOME", "go to the beginning of the current document" }, -{ "END", "go to the end of the current document" }, -{ "FIRST_LINK", "make the first link on the line current" }, -{ "LAST_LINK", "make the last link on the line current" }, -{ "PREV_LINK", "make the previous link current" }, -{ "NEXT_LINK", "make the next link current" }, -{ "LPOS_PREV_LINK", "make previous link current, same column for input" }, -{ "LPOS_NEXT_LINK", "make next link current, same column for input" }, -{ "FASTBACKW_LINK", "previous link or text area, only stops on links" }, -{ "FASTFORW_LINK", "next link or text area, only stops on links" }, -{ "UP_LINK", "move up the page to a previous link" }, -{ "DOWN_LINK", "move down the page to another link" }, -{ "RIGHT_LINK", "move right to another link" }, -{ "LEFT_LINK", "move left to a previous link" }, -{ "HISTORY", "display stack of currently-suspended documents" }, -{ "PREV_DOC", "go back to the previous document" }, -{ "ACTIVATE", "go to the document given by the current link" }, -{ "MOUSE_SUBMIT", "follow current link, submit" }, /* not mapped */ -{ "GOTO", "go to a document given as a URL" }, -{ "ECGOTO", "edit the current document's URL and go to it" }, -{ "HELP", "display help on using the browser" }, -{ "DWIMHELP", "display help page that may depend on context" }, -{ "INDEX", "display an index of potentially useful documents" }, -{ "NOCACHE", "force submission of form or link with no-cache" }, -{ "INTERRUPT", "interrupt network connection or transmission" }, -{ "MAIN_MENU", "return to the first screen (home page)" }, -{ "OPTIONS", "display and change option settings" }, -{ "INDEX_SEARCH", "allow searching of an index" }, -{ "WHEREIS", "search within the current document" }, -{ "NEXT", "search for the next occurence" }, -{ "COMMENT", "send a comment to the author of the current document" }, -{ "EDIT", "edit the current document or a form's textarea" }, -{ "INFO", "display information on the current document and link" }, -{ "PRINT", "display choices for printing the current document" }, -{ "ADD_BOOKMARK", "add to your personal bookmark list" }, -{ "DEL_BOOKMARK", "delete from your personal bookmark list" }, -{ "VIEW_BOOKMARK", "view your personal bookmark list" }, -{ "VLINKS", "list links visited during the current Lynx session" }, -{ "SHELL", "escape from the browser to the system" }, -{ "DOWNLOAD", "download the current link to your computer" }, -{ "TRACE_TOGGLE", "toggle tracing of browser operations" }, -{ "TRACE_LOG", "view trace log if started in the current session" }, -{ "IMAGE_TOGGLE", "toggle handling of all images as links" }, -{ "INLINE_TOGGLE", "toggle pseudo-ALTs for inlines with no ALT string" }, -{ "HEAD", "send a HEAD request for the current document or link" }, -{ "DO_NOTHING", NULL }, -{ "TOGGLE_HELP", "show other commands in the novice help menu" }, -{ "JUMP", "go directly to a target document or action" }, -{ "KEYMAP", "display the current key map" }, -{ "LIST", "list the references (links) in the current document" }, -{ "TOOLBAR", "go to Toolbar or Banner in the current document" }, -{ "HISTORICAL", "toggle historical vs. valid/minimal comment parsing" }, -{ "MINIMAL", "toggle minimal vs. valid comment parsing" }, -{ "SOFT_DQUOTES", "toggle valid vs. soft double-quote parsing" }, -{ "RAW_TOGGLE", "toggle raw 8-bit translations or CJK mode ON or OFF" }, -{ "COOKIE_JAR", "examine the Cookie Jar" }, -{ "F_LINK_NUM", "invoke the 'Follow link (or page) number:' prompt" }, -{ "CLEAR_AUTH", "clear all authorization info for this session" }, -{ "SWITCH_DTD", "switch between two ways of parsing HTML" }, -{ "ELGOTO", "edit the current link's URL or ACTION and go to it" }, -{ "CHANGE_LINK", "force reset of the current link on the page" }, -{ "DWIMEDIT", "use external editor for context-dependent purpose" }, -{ "EDITTEXTAREA", "use an external editor to edit a form's textarea" }, -{ "GROWTEXTAREA", "add 5 new blank lines to the bottom of a textarea" }, -{ "INSERTFILE", "insert file into a textarea (just above cursorline)" }, +PRIVATE Kcmd revmap[] = { + DATA( + LYK_UNKNOWN, "UNMAPPED", + NULL ), + DATA( + LYK_COMMAND, "COMMAND", + "prompt for, execute a command" ), + DATA( + LYK_1, "1", + NULL ), + DATA( + LYK_2, "2", + NULL ), + DATA( + LYK_3, "3", + NULL ), + DATA( + LYK_4, "4", + NULL ), + DATA( + LYK_5, "5", + NULL ), + DATA( + LYK_6, "6", + NULL ), + DATA( + LYK_7, "7", + NULL ), + DATA( + LYK_8, "8", + NULL ), + DATA( + LYK_9, "9", + NULL ), + DATA( + LYK_SOURCE, "SOURCE", + "toggle source/presentation for current document" ), + DATA( + LYK_RELOAD, "RELOAD", + "reload the current document" ), + DATA( + LYK_PIPE, "PIPE", + "pipe the current document to an external command" ), + DATA( + LYK_QUIT, "QUIT", + "quit the browser" ), + DATA( + LYK_ABORT, "ABORT", + "quit the browser unconditionally" ), + DATA( + LYK_NEXT_PAGE, "NEXT_PAGE", + "view the next page of the document" ), + DATA( + LYK_PREV_PAGE, "PREV_PAGE", + "view the previous page of the document" ), + DATA( + LYK_UP_TWO, "UP_TWO", + "go back two lines in the document" ), + DATA( + LYK_DOWN_TWO, "DOWN_TWO", + "go forward two lines in the document" ), + DATA( + LYK_UP_HALF, "UP_HALF", + "go back half a page in the document" ), + DATA( + LYK_DOWN_HALF, "DOWN_HALF", + "go forward half a page in the document" ), + DATA( + LYK_REFRESH, "REFRESH", + "refresh the screen to clear garbled text" ), + DATA( + LYK_HOME, "HOME", + "go to the beginning of the current document" ), + DATA( + LYK_END, "END", + "go to the end of the current document" ), + DATA( + LYK_FIRST_LINK, "FIRST_LINK", + "make the first link on the line current" ), + DATA( + LYK_LAST_LINK, "LAST_LINK", + "make the last link on the line current" ), + DATA( + LYK_PREV_LINK, "PREV_LINK", + "make the previous link current" ), + DATA( + LYK_NEXT_LINK, "NEXT_LINK", + "make the next link current" ), + DATA( + LYK_LPOS_PREV_LINK, "LPOS_PREV_LINK", + "make previous link current, same column for input" ), + DATA( + LYK_LPOS_NEXT_LINK, "LPOS_NEXT_LINK", + "make next link current, same column for input" ), + DATA( + LYK_FASTBACKW_LINK, "FASTBACKW_LINK", + "previous link or text area, only stops on links" ), + DATA( + LYK_FASTFORW_LINK, "FASTFORW_LINK", + "next link or text area, only stops on links" ), + DATA( + LYK_UP_LINK, "UP_LINK", + "move up the page to a previous link" ), + DATA( + LYK_DOWN_LINK, "DOWN_LINK", + "move down the page to another link" ), + DATA( + LYK_RIGHT_LINK, "RIGHT_LINK", + "move right to another link" ), + DATA( + LYK_LEFT_LINK, "LEFT_LINK", + "move left to a previous link" ), + DATA( + LYK_HISTORY, "HISTORY", + "display stack of currently-suspended documents" ), + DATA( + LYK_PREV_DOC, "PREV_DOC", + "go back to the previous document" ), + DATA( + LYK_ACTIVATE, "ACTIVATE", + "go to the document given by the current link" ), + DATA( + LYK_SUBMIT, "MOUSE_SUBMIT", + "DO NOT MAP: follow current link, submit" ), + DATA( + LYK_GOTO, "GOTO", + "go to a document given as a URL" ), + DATA( + LYK_ECGOTO, "ECGOTO", + "edit the current document's URL and go to it" ), + DATA( + LYK_HELP, "HELP", + "display help on using the browser" ), + DATA( + LYK_DWIMHELP, "DWIMHELP", + "display help page that may depend on context" ), + DATA( + LYK_INDEX, "INDEX", + "display an index of potentially useful documents" ), + DATA( + LYK_NOCACHE, "NOCACHE", + "force submission of form or link with no-cache" ), + DATA( + LYK_INTERRUPT, "INTERRUPT", + "interrupt network connection or transmission" ), + DATA( + LYK_MAIN_MENU, "MAIN_MENU", + "return to the first screen (home page)" ), + DATA( + LYK_OPTIONS, "OPTIONS", + "display and change option settings" ), + DATA( + LYK_INDEX_SEARCH, "INDEX_SEARCH", + "allow searching of an index" ), + DATA( + LYK_WHEREIS, "WHEREIS", + "search within the current document" ), + DATA( + LYK_NEXT, "NEXT", + "search for the next occurence" ), + DATA( + LYK_COMMENT, "COMMENT", + "send a comment to the author of the current document" ), + DATA( + LYK_EDIT, "EDIT", + "edit the current document or a form's textarea" ), + DATA( + LYK_INFO, "INFO", + "display information on the current document and link" ), + DATA( + LYK_PRINT, "PRINT", + "display choices for printing the current document" ), + DATA( + LYK_ADD_BOOKMARK, "ADD_BOOKMARK", + "add to your personal bookmark list" ), + DATA( + LYK_DEL_BOOKMARK, "DEL_BOOKMARK", + "delete from your personal bookmark list" ), + DATA( + LYK_VIEW_BOOKMARK, "VIEW_BOOKMARK", + "view your personal bookmark list" ), + DATA( + LYK_VLINKS, "VLINKS", + "list links visited during the current Lynx session" ), + DATA( + LYK_SHELL, "SHELL", + "escape from the browser to the system" ), + DATA( + LYK_DOWNLOAD, "DOWNLOAD", + "download the current link to your computer" ), + DATA( + LYK_TRACE_TOGGLE, "TRACE_TOGGLE", + "toggle tracing of browser operations" ), + DATA( + LYK_TRACE_LOG, "TRACE_LOG", + "view trace log if started in the current session" ), + DATA( + LYK_IMAGE_TOGGLE, "IMAGE_TOGGLE", + "toggle handling of all images as links" ), + DATA( + LYK_INLINE_TOGGLE, "INLINE_TOGGLE", + "toggle pseudo-ALTs for inlines with no ALT string" ), + DATA( + LYK_HEAD, "HEAD", + "send a HEAD request for the current document or link" ), + DATA( + LYK_DO_NOTHING, "DO_NOTHING", + NULL ), + DATA( + LYK_TOGGLE_HELP, "TOGGLE_HELP", + "show other commands in the novice help menu" ), + DATA( + LYK_JUMP, "JUMP", + "go directly to a target document or action" ), + DATA( + LYK_KEYMAP, "KEYMAP", + "display the current key map" ), + DATA( + LYK_LIST, "LIST", + "list the references (links) in the current document" ), + DATA( + LYK_TOOLBAR, "TOOLBAR", + "go to Toolbar or Banner in the current document" ), + DATA( + LYK_HISTORICAL, "HISTORICAL", + "toggle historical vs. valid/minimal comment parsing" ), + DATA( + LYK_MINIMAL, "MINIMAL", + "toggle minimal vs. valid comment parsing" ), + DATA( + LYK_SOFT_DQUOTES, "SOFT_DQUOTES", + "toggle valid vs. soft double-quote parsing" ), + DATA( + LYK_RAW_TOGGLE, "RAW_TOGGLE", + "toggle raw 8-bit translations or CJK mode ON or OFF" ), + DATA( + LYK_COOKIE_JAR, "COOKIE_JAR", + "examine the Cookie Jar" ), + DATA( + LYK_F_LINK_NUM, "F_LINK_NUM", + "invoke the 'Follow link (or page) number:' prompt" ), + DATA( + LYK_CLEAR_AUTH, "CLEAR_AUTH", + "clear all authorization info for this session" ), + DATA( + LYK_SWITCH_DTD, "SWITCH_DTD", + "switch between two ways of parsing HTML" ), + DATA( + LYK_ELGOTO, "ELGOTO", + "edit the current link's URL or ACTION and go to it" ), + DATA( + LYK_CHANGE_LINK, "CHANGE_LINK", + "force reset of the current link on the page" ), + DATA( + LYK_DWIMEDIT, "DWIMEDIT", + "use external editor for context-dependent purpose" ), + DATA( + LYK_EDIT_TEXTAREA, "EDITTEXTAREA", + "use an external editor to edit a form's textarea" ), + DATA( + LYK_GROW_TEXTAREA, "GROWTEXTAREA", + "add 5 new blank lines to the bottom of a textarea" ), + DATA( + LYK_INSERT_FILE, "INSERTFILE", + "insert file into a textarea (just above cursorline)" ), #ifdef EXP_ADDRLIST_PAGE -{ "ADDRLIST", "like LIST command, but always shows the links' URLs" }, + DATA( + LYK_ADDRLIST, "ADDRLIST", + "like LIST command, but always shows the links' URLs" ), #endif #ifdef USE_EXTERNALS -{ "EXTERN", "run external program with url" }, + DATA( + LYK_EXTERN, "EXTERN", + "run external program with url" ), #endif #ifdef VMS -{ "DIRED_MENU", "invoke File/Directory Manager, if available" }, + DATA( + LYK_DIRED_MENU, "DIRED_MENU", + "invoke File/Directory Manager, if available" ), #else #ifdef DIRED_SUPPORT -{ "DIRED_MENU", "display a full menu of file operations" }, -{ "CREATE", "create a new file or directory" }, -{ "REMOVE", "remove a file or directory" }, -{ "MODIFY", "modify the name or location of a file or directory" }, -{ "TAG_LINK", "tag a file or directory for later action" }, -{ "UPLOAD", "upload from your computer to the current directory" }, -{ "INSTALL", "install file or tagged files into a system area" }, + DATA( + LYK_DIRED_MENU, "DIRED_MENU", + "display a full menu of file operations" ), + DATA( + LYK_CREATE, "CREATE", + "create a new file or directory" ), + DATA( + LYK_REMOVE, "REMOVE", + "remove a file or directory" ), + DATA( + LYK_MODIFY, "MODIFY", + "modify the name or location of a file or directory" ), + DATA( + LYK_TAG_LINK, "TAG_LINK", + "tag a file or directory for later action" ), + DATA( + LYK_UPLOAD, "UPLOAD", + "upload from your computer to the current directory" ), + DATA( + LYK_INSTALL, "INSTALL", + "install file or tagged files into a system area" ), #endif /* DIRED_SUPPORT */ -#ifdef SH_EX /* 1999/01/01 (Fri) 01:18:12 */ -{ "CHANGE_CENTER", "toggle center alignment in HTML TABLE" }, -{ "TO_CLIPBOARD", "link's URL to Clip Board" }, -{ "CHANGE_KCODE", "Change Kanji code" }, +#ifdef SH_EX /* 1999/01/01 (Fri) 01:18:12 */ + DATA( + LYK_CHG_CENTER, "CHANGE_CENTER", + "toggle center alignment in HTML TABLE" ), + DATA( + LYK_TO_CLIPBOARD, "TO_CLIPBOARD", + "link's URL to Clip Board" ), +#endif +#ifdef KANJI_CODE_OVERRIDE + DATA( + LYK_CHG_KCODE, "CHANGE_KCODE", + "Change Kanji code" ), #endif #endif /* VMS */ #ifdef SUPPORT_CHDIR - { "CHDIR", "change current directory" }, + DATA( + LYK_CHDIR, "CHDIR", + "change current directory" ), #endif -{ NULL, "" } + DATA( + LYK_UNKNOWN, NULL, + "" ) }; +#undef DATA PRIVATE CONST struct { int key; @@ -837,6 +1043,78 @@ PRIVATE struct emap ekmap[] = { #endif }; +/* + * Build a list of Lynx's commands, for use in the tab-completion in LYgetstr. + */ +PUBLIC HTList *LYcommandList NOARGS +{ + static HTList *myList = NULL; + + if (myList == NULL) { + unsigned j; + myList = HTList_new(); + for (j = 0; revmap[j].name != 0; j++) { + if (revmap[j].doc != 0) + HTList_addObject(myList, revmap[j].name); + } + } + return myList; +} + +/* + * Find the given keycode. + */ +PUBLIC Kcmd * LYKeycodeToKcmd ARGS1( + LYKeymapCode, code) +{ + unsigned j; + Kcmd *result = 0; + + if (code > LYK_UNKNOWN) { + for (j = 0; revmap[j].name != 0; j++) { + if (revmap[j].code == code) { + result = revmap + j; + break; + } + } + } + return result; +} + +/* + * Find the given command-name, accepting an abbreviation if it is unique. + */ +PUBLIC Kcmd * LYStringToKcmd ARGS1( + CONST char *, name) +{ + unsigned need = strlen(name); + unsigned j; + BOOL exact = FALSE; + Kcmd *result = 0; + Kcmd *maybe = 0; + + if (name != 0 && *name != 0) { + for (j = 0; revmap[j].name != 0; j++) { + if (!strcasecomp(revmap[j].name, name)) { + result = revmap + j; + break; + } else if (!exact + && !strncasecomp(revmap[j].name, name, need)) { + if (maybe == 0) { + maybe = revmap + j; + } else { + if (revmap[j].name[need] != 0 + && maybe->name[need] != 0) { + maybe = 0; + exact = TRUE; + } + } + } + } + } + return (result != 0) ? result : maybe; +} + PUBLIC char *LYKeycodeToString ARGS2 ( int, c, BOOLEAN, upper8) @@ -952,19 +1230,19 @@ PRIVATE char * format_binding ARGS2( LYKeymap_t *, table, int, i) { - unsigned the_key = table[i]; + LYKeymap_t the_key = table[i]; char *buf = 0; char *formatted; + Kcmd *rmap = LYKeycodeToKcmd(the_key); - if (the_key != 0 - && the_key < TABLESIZE(revmap) - && revmap[the_key].name != 0 - && revmap[the_key].doc != 0 + if (rmap != 0 + && rmap->name != 0 + && rmap->doc != 0 && (formatted = pretty_html(i-1)) != 0) { HTSprintf0(&buf, "%-*s %-13s %s\n", PRETTY_LEN, formatted, - revmap[the_key].name, - revmap[the_key].doc); + rmap->name, + rmap->doc); return buf; } return 0; @@ -1016,23 +1294,14 @@ PRIVATE void print_binding ARGS3( /* * Return lynxactioncode whose name is the string func. - * func must be present in the revmap table. * returns -1 if not found. - kw */ PUBLIC int lacname_to_lac ARGS1( CONST char *, func) { - int i; - struct rmap *mp; + Kcmd *mp = LYStringToKcmd(func); - if (func == NULL || *func == '\0') - return (-1); - for (i = 0, mp = revmap; (*mp).name != NULL; mp++, i++) { - if (strcmp((*mp).name, func) == 0) { - return i; - } - } - return (-1); + return (mp != 0) ? mp->code : -1; } /* @@ -1136,8 +1405,8 @@ PRIVATE int LYLoadKeymap ARGS4 ( * Don't show CHANGE_LINK if mouse not enabled. */ if ((i >= 0200 || i <= ' ' || !isalpha(i-1)) && - strcmp(revmap[keymap[i]].name, "PIPE") && - (LYUseMouse || strcmp(revmap[keymap[i]].name, "CHANGE_LINK"))) { + (keymap[i] != LYK_PIPE) && + (LYUseMouse || (keymap[i] != LYK_CHANGE_LINK))) { print_binding(target, i, FALSE); } } @@ -1163,7 +1432,6 @@ GLOBALDEF PUBLIC HTProtocol LYLynxKeymap = {"LYNXKEYMAP", LYLoadKeymap, 0}; * for Dired mode, otherwise in the general keymap[] table. * If DIRED_SUPPORT or OK_OVERRIDE is not defined, don't do anything * when for_dired is requested. - * func must be present in the revmap table. * returns lynxkeycode value != 0 if the mapping was made, 0 if not. */ PUBLIC int remap ARGS3( @@ -1171,8 +1439,7 @@ PUBLIC int remap ARGS3( char *, func, BOOLEAN, for_dired) { - int i; - struct rmap *mp; + Kcmd *mp; int c; #if !defined(DIRED_SUPPORT) || !defined(OK_OVERRIDE) @@ -1197,16 +1464,14 @@ PUBLIC int remap ARGS3( } if (c + 1 >= KEYMAP_SIZE) return 0; - for (i = 0, mp = revmap; (*mp).name != NULL; mp++, i++) { - if (strcmp((*mp).name, func) == 0) { + if ((mp = LYStringToKcmd(func)) != 0) { #if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE) - if (for_dired) - key_override[c+1] = (char) i; - else + if (for_dired) + key_override[c+1] = mp->code; + else #endif - keymap[c+1] = (char) i; - return (c ? c : LAC_TO_LKC0(i)); /* don't return 0, successful */ - } + keymap[c+1] = mp->code; + return (c ? c : LAC_TO_LKC0(mp->code)); /* don't return 0, successful */ } return 0; } diff --git a/src/LYKeymap.h b/src/LYKeymap.h index c4f47672..b53e657f 100644 --- a/src/LYKeymap.h +++ b/src/LYKeymap.h @@ -1,11 +1,11 @@ #ifndef LYKEYMAP_H #define LYKEYMAP_H -#ifndef HTUTILS_H #include <HTUtils.h> -#endif +#include <HTList.h> extern BOOLEAN LYisNonAlnumKeyname PARAMS((int ch, int KeyName)); +extern HTList *LYcommandList NOPARAMS; extern char *LYKeycodeToString PARAMS((int c, BOOLEAN upper8)); extern char *fmt_keys PARAMS((int lkc_first, int lkc_second)); extern char *key_for_func PARAMS((int func)); @@ -111,10 +111,13 @@ extern LYKeymap_t key_override[]; /* Variables for holding and passing around lynxactioncodes are * generally of type int, the types LYKeymap_t and LYKeymapCodes * are currently only used for the definitions. That could change. - kw + * + * The values in this enum are indexed against the command names in the + * 'revmap[]' array in LYKeymap.c */ -/* The order of this enum must match the 'revmap[]' array in LYKeymap.c */ typedef enum { LYK_UNKNOWN=0 + , LYK_COMMAND , LYK_1 , LYK_2 , LYK_3 @@ -243,5 +246,16 @@ typedef enum { #endif } LYKeymapCode; +/* + * Symbol table for internal commands. + */ +typedef struct { + LYKeymapCode code; + CONST char *name; + CONST char *doc; +} Kcmd; + +extern Kcmd * LYKeycodeToKcmd PARAMS((LYKeymapCode code)); +extern Kcmd * LYStringToKcmd PARAMS((CONST char * name)); #endif /* LYKEYMAP_H */ diff --git a/src/LYMail.c b/src/LYMail.c index 7dd55aef..4a8d7d63 100644 --- a/src/LYMail.c +++ b/src/LYMail.c @@ -54,16 +54,15 @@ PRIVATE char *blat_cmd( #ifdef USE_ALT_BLAT_MAILER - HTSprintf0(&b_cmd, "%s %s -t %s -s \"%s\" %s %s %s %s %s", + HTSprintf0(&b_cmd, "%s %s -t \"%s\" -s \"%s\" %s%s%s%s", mail_cmd, filename, address, subject, system_mail_flags, - ccaddr? "-c" : "", + ccaddr? " -c \"" : "", ccaddr? ccaddr : "", - mail_addr? (mail_addr[0]? "-f" : "") : "", - mail_addr? (mail_addr[0]? mail_addr : "") : ""); + ccaddr? "\"" : ""); #else /* !USE_ALT_BLAT_MAILER */ @@ -1682,7 +1681,7 @@ PUBLIC void reply_by_mail ARGS4( if (HTConfirm(is_preparsed ? INC_PREPARSED_MSG_PROMPT : INC_ORIG_MSG_PROMPT) == YES) { - print_wwwfile_to_fd(fd, !is_preparsed); + print_wwwfile_to_fd(fd, (BOOLEAN)!is_preparsed); } } LYCloseTempFP(fd); /* Close the tmpfile. */ diff --git a/src/LYMain.c b/src/LYMain.c index 31179bf2..0f082263 100644 --- a/src/LYMain.c +++ b/src/LYMain.c @@ -38,6 +38,8 @@ #ifdef __DJGPP__ #include <dos.h> #include <dpmi.h> +#include <io.h> +#include <sys/stat.h> #endif /* __DJGPP__ */ #ifdef __EMX__ @@ -382,7 +384,7 @@ PUBLIC linkstruct links[MAXLINKS]; PUBLIC histstruct history[MAXHIST]; PUBLIC int nlinks = 0; /* number of links in memory */ PUBLIC int nhist = 0; /* number of history entries */ -PUBLIC int more = FALSE; /* is there more text to display? */ +PUBLIC BOOLEAN more = FALSE; /* is there more text to display? */ PUBLIC int InfoSecs; /* Seconds to sleep() for Information messages */ PUBLIC int MessageSecs; /* Seconds to sleep() for important Messages */ PUBLIC int AlertSecs; /* Seconds to sleep() for HTAlert() messages */ @@ -420,9 +422,9 @@ PUBLIC char *LYCookieSStrictCheckDomains = NULL; /* check strictly */ PUBLIC char *LYCookieSLooseCheckDomains = NULL; /* check loosely */ PUBLIC char *LYCookieSQueryCheckDomains = NULL; /* check w/a query */ #ifdef EXP_PERSISTENT_COOKIES -BOOLEAN persistent_cookies = FALSE; /* disabled by default! */ -PUBLIC char *LYCookieFile = NULL; /* cookie read file */ -PUBLIC char *LYCookieSaveFile = NULL; /* cookie save file */ +BOOLEAN persistent_cookies = FALSE; /* disabled by default! */ +PUBLIC char *LYCookieFile = NULL; /* cookie read file */ +PUBLIC char *LYCookieSaveFile = NULL; /* cookie save file */ #endif /* EXP_PERSISTENT_COOKIES */ PUBLIC char *XLoadImageCommand = NULL; /* Default image viewer for X */ PUBLIC BOOLEAN LYNoISMAPifUSEMAP = FALSE; /* Omit ISMAP link if MAP present? */ @@ -438,7 +440,7 @@ PUBLIC BOOLEAN LYSeekFragAREAinCur = TRUE; PUBLIC BOOLEAN LYStripDotDotURLs = TRUE; /* Try to fix ../ in some URLs? */ PUBLIC BOOLEAN LYForceSSLCookiesSecure = FALSE; PUBLIC BOOLEAN LYNoCc = FALSE; -PUBLIC BOOLEAN LYPreparsedSource = FALSE; /* Show source as preparsed? */ +PUBLIC BOOLEAN LYPreparsedSource = FALSE; /* Show source as preparsed? */ PUBLIC BOOLEAN LYPrependBaseToSource = TRUE; PUBLIC BOOLEAN LYPrependCharsetToSource = TRUE; PUBLIC BOOLEAN LYQuitDefaultYes = QUIT_DEFAULT_YES; @@ -662,6 +664,7 @@ PRIVATE void free_lynx_globals NOARGS FREE(links[i].lname); } nlinks = 0; + HTList_delete(LYcommandList()); return; } @@ -1492,7 +1495,7 @@ PUBLIC int main ARGS2( #ifdef USE_PRETTYSRC if ( (!Old_DTD) != TRUE ) /* skip if they are already initialized -HV */ #endif - HTSwitchDTD(!Old_DTD); + HTSwitchDTD((BOOLEAN)!Old_DTD); /* * Set up the proper character set with the desired @@ -1657,20 +1660,14 @@ PUBLIC int main ARGS2( * Check the -popup command line toggle. - FM */ if (LYUseDefSelPop == FALSE) { - if (LYSelectPopups == TRUE) - LYSelectPopups = FALSE; - else - LYSelectPopups = TRUE; + LYSelectPopups = !LYSelectPopups; } /* * Check the -show_cursor command line toggle. - FM */ if (LYUseDefShoCur == FALSE) { - if (LYShowCursor == TRUE) - LYShowCursor = FALSE; - else - LYShowCursor = TRUE; + LYShowCursor = !LYShowCursor; } /* @@ -1715,16 +1712,19 @@ PUBLIC int main ARGS2( #if defined (__DJGPP__) if (watt_debug) - dbug_init(); + dbug_init(); sock_init(); __system_flags = - __system_emulate_chdir | /* handle `cd' internally */ - __system_handle_null_commands | /* ignore cmds with no effect */ - __system_allow_long_cmds | /* handle commands > 126 chars */ - __system_use_shell | /* use $SHELL if set */ - __system_allow_multiple_cmds | /* allow `cmd1; cmd2; ...' */ + __system_emulate_chdir | /* handle `cd' internally */ + __system_handle_null_commands | /* ignore cmds with no effect */ + __system_allow_long_cmds | /* handle commands > 126 chars */ + __system_use_shell | /* use $SHELL if set */ + __system_allow_multiple_cmds | /* allow `cmd1; cmd2; ...' */ __system_redirect; /* redirect internally */ + + /* This speeds up stat() tremendously */ + _djstat_flags |= _STAT_INODE | _STAT_EXEC_MAGIC |_STAT_DIRSIZE; #endif /* __DJGPP__ */ /* trap interrupts */ diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c index b7eaf53a..916d649a 100644 --- a/src/LYMainLoop.c +++ b/src/LYMainLoop.c @@ -1151,7 +1151,7 @@ gettext("Enctype multipart/form-data not yet supported! Cannot submit.")); links[curdoc.link].form->name, links[curdoc.link].form->value, FALSE, - (real_cmd==LYK_SUBMIT || + (BOOLEAN)(real_cmd==LYK_SUBMIT || real_cmd==LYK_NOCACHE || real_cmd==LYK_DOWNLOAD || real_cmd==LYK_HEAD)); @@ -1660,6 +1660,30 @@ PRIVATE void handle_LYK_CLEAR_AUTH ARGS2( } } +PRIVATE int handle_LYK_COMMAND ARGS1( + char *, user_input_buffer) +{ + int ch; + Kcmd *mp; + char *src, *tmp; + + *user_input_buffer = 0; + _statusline(": "); + if (LYgetstr(user_input_buffer, VISIBLE, MAX_LINE, RECALL_CMD) >= 0) { + src = LYSkipBlanks(user_input_buffer); + tmp = LYSkipNonBlanks(src); + *tmp = 0; + ch = ((mp = LYStringToKcmd(src)) != 0) ? mp->code : 0; + CTRACE((tfp, "LYK_COMMAND(%s.%s) = %d\n", src, tmp, ch)); + if (ch == 0) { + return *src ? -1 : 0; + } + /* FIXME: reuse the rest of the buffer for parameters */ + return ch; + } + return 0; +} + PRIVATE void handle_LYK_COMMENT ARGS4( BOOLEAN *, refresh_screen, char **, owner_address_p, @@ -4422,7 +4446,7 @@ PRIVATE void handle_LYK_SWITCH_DTD NOARGS } /* end if no bypass */ #endif Old_DTD = !Old_DTD; - HTSwitchDTD(!Old_DTD); + HTSwitchDTD((BOOLEAN) !Old_DTD); HTUserMsg(Old_DTD ? USING_DTD_0 : USING_DTD_1); #ifdef SOURCE_CACHE if (canreparse) { @@ -5094,18 +5118,10 @@ PUBLIC void handle_LYK_CHDIR NOARGS if (!no_dired_support && (lynx_edit_mode || (LYIsUIPage(curdoc.address, UIP_DIRED_MENU)))) { char buf2[LY_MAXPATH]; - char* tmp; char* addr = NULL; - strcpy(buf2, p); Current_Dir(buf2); - tmp = wwwName(buf2); - - StrAllocCopy(addr, "file://localhost"); - StrAllocCat(addr, tmp); - if (tmp != buf2) - /*since wwwName is nop on unix and allocates something on VMS and DOS*/ - FREE(tmp); + LYLocalFileToURL(&addr, buf2); newdoc.address = addr; newdoc.isHEAD = FALSE; @@ -6748,6 +6764,9 @@ new_cmd: /* follow_col = -1; switch(cmd) { + case -1: + HTUserMsg(COMMAND_UNKNOWN); + break; case 0: /* unmapped character */ default: if (curdoc.link >= 0 && curdoc.link < nlinks && @@ -6763,10 +6782,11 @@ new_cmd: /* } else #endif show_main_statusline(links[curdoc.link], FOR_INPUT); - } else if (more) + } else if (more) { HTInfoMsg(MOREHELP); - else + } else { HTInfoMsg(HELP); + } show_help = TRUE; if (TRACE) { @@ -6776,6 +6796,10 @@ new_cmd: /* } break; + case LYK_COMMAND: + cmd = handle_LYK_COMMAND(user_input_buffer); + goto new_cmd; + case LYK_INTERRUPT: /* * No network transmission to interrupt - 'til we multithread. @@ -7543,14 +7567,6 @@ PRIVATE void show_main_statusline ARGS2( _statusline(HELP); } -#if 0 /* messages now produced in show_formlink_statusline - kw */ -#ifdef INACTIVE_INPUT_STYLE_VH - if (textinput_redrawn) { - _statusline(gettext("Inactive text input, activate to edit (e.g., press ENTER)")); - } -#endif -#endif - /* turn off cursor since now it's probably on statusline -HV */ /* But not if LYShowCursor is on. -show_cursor may be used as a * workaround to avoid putting the cursor in the last position, for diff --git a/src/LYOptions.c b/src/LYOptions.c index b126cd0f..9beb653f 100644 --- a/src/LYOptions.c +++ b/src/LYOptions.c @@ -2164,6 +2164,37 @@ PRIVATE int get_popup_choice_number ARGS1( " " : ""), \ (choice + 1), value) +PRIVATE void draw_option ARGS7( + WINDOW *, win, + int, entry, + int, width, + BOOLEAN, reverse, + int, num_choices, + int, number, + CONST char *, value) +{ + char Cnum[64]; + + FormatChoiceNum(Cnum, number, ""); +#ifdef USE_SLANG + SLsmg_gotorc(win->top_y + entry, (win->left_x + 2)); + addstr(Cnum); + if (reverse) + SLsmg_set_color(2); + LYaddnstr(value, width); + if (reverse) + SLsmg_set_color(0); +#else + wmove(win, entry, 2); + waddstr(win, Cnum); + if (reverse) + wstart_reverse(win); + LYpaddstr(win, width, value); + if (reverse) + wstop_reverse(win); +#endif /* USE_SLANG */ +} + /* * This function offers the choices for values of an * option via a popup window which functions like @@ -2185,9 +2216,7 @@ PUBLIC int popup_choice ARGS7( int lx = (column >= 0 ? column : (COL_OPTION_VALUES - 1)); int c = 0, cmd = 0, i = 0, j = 0; int orig_choice = cur_choice; -#ifndef USE_SLANG WINDOW * form_window; -#endif /* !USE_SLANG */ int num_choices = 0, top, bottom, length = -1; unsigned width = 0; CONST char ** Cptr = choices; @@ -2329,27 +2358,8 @@ PUBLIC int popup_choice ARGS7( * Set up the overall window, including the boxing characters ('*'), * if it all fits. Otherwise, set up the widest window possible. - FM */ -#ifdef USE_SLANG - SLsmg_fill_region(top, lx - 1, bottom - top, (Lnum + width + 4), ' '); -#else - if (!(form_window = newwin(bottom - top, (Lnum + width + 4), - top, (lx - 1))) && - !(form_window = newwin(bottom - top, 0, top, 0))) { - HTAlert(POPUP_FAILED); + if ((form_window = LYstartPopup(top, lx, bottom - top, Lnum + width)) == 0) return(orig_choice); - } - scrollok(form_window, TRUE); -#ifdef PDCURSES - keypad(form_window, TRUE); -#endif /* PDCURSES */ -#if defined(NCURSES) || defined(PDCURSES) - LYsubwindow(form_window); -#endif -#if defined(HAVE_GETBKGD)/* not defined in ncurses 1.8.7 */ - wbkgd(form_window, getbkgd(stdscr)); - wbkgdset(form_window, getbkgd(stdscr)); -#endif -#endif /* USE_SLANG */ /* * Clear the command line and write @@ -2395,105 +2405,32 @@ redraw: */ for (i = 0; i <= num_choices; i++) { if (i >= window_offset && i - window_offset < length) { - FormatChoiceNum(Cnum, i, ""); -#ifdef USE_SLANG - SLsmg_gotorc(top + ((i + 1) - window_offset), (lx - 1 + 2)); - addstr(Cnum); - LYaddnstr(Cptr[i], width); -#else - wmove(form_window, ((i + 1) - window_offset), 2); - wclrtoeol(form_window); - waddstr(form_window, Cnum); - LYwaddstr(form_window, Cptr[i]); -#endif /* USE_SLANG */ + draw_option (form_window, ((i + 1) - window_offset), width, FALSE, + num_choices, i, Cptr[i]); } } -#ifdef USE_SLANG - SLsmg_draw_box(top, (lx - 1), (bottom - top), (Lnum + width + 4)); -#else -#ifdef VMS - VMSbox(form_window, (bottom - top), (Lnum + width + 4)); -#else LYbox(form_window, FALSE); -#endif /* VMS */ - wrefresh(form_window); -#endif /* USE_SLANG */ Cptr = NULL; /* * Loop on user input. */ while (cmd != LYK_ACTIVATE) { + int row = ((i + 1) - window_offset); + /* * Unreverse cur choice. */ if (Cptr != NULL) { - FormatChoiceNum(Cnum, i, ""); -#ifdef USE_SLANG - SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 2)); - addstr(Cnum); - LYaddnstr(Cptr[i], width); -#else - wmove(form_window, ((i + 1) - window_offset), 2); - waddstr(form_window, Cnum); - LYwaddstr(form_window, Cptr[i]); -#endif /* USE_SLANG */ + draw_option (form_window, row, width, FALSE, + num_choices, i, Cptr[i]); } Cptr = choices; i = cur_choice; - FormatChoiceNum(Cnum, i, ""); -#ifdef USE_SLANG - SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 2)); - addstr(Cnum); - SLsmg_set_color(2); - LYaddnstr(Cptr[i], width); - SLsmg_set_color(0); - /* - * If LYShowCursor is ON, move the cursor to the left - * of the current choice, so that blind users, who are - * most likely to have LYShowCursor ON, will have it's - * string spoken or passed to the braille interface as - * each choice is made current. Otherwise, move it to - * the bottom, right column of the screen, to "hide" - * the cursor as for the main document, and let sighted - * users rely on the current choice's highlighting or - * color without the distraction of a blinking cursor - * in the window. - FM - */ - if (LYShowCursor) - SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 1)); - else - SLsmg_gotorc((LYlines - 1), (LYcols - 1)); - SLsmg_refresh(); -#else - wmove(form_window, ((i + 1) - window_offset), 2); - waddstr(form_window, Cnum); -#if defined(WIN_EX) /* 1997/10/18 (Sat) 00:10:51 */ - wattron(form_window, A_REVERSE); -#else - wstart_reverse(form_window); -#endif - LYwaddstr(form_window, Cptr[i]); -#if defined(WIN_EX) /* 1997/10/18 (Sat) 00:10:58 */ - wattroff(form_window, A_REVERSE); -#else - wstop_reverse(form_window); -#endif - /* - * If LYShowCursor is ON, move the cursor to the left - * of the current choice, so that blind users, who are - * most likely to have LYShowCursor ON, will have it's - * string spoken or passed to the braille interface as - * each choice is made current. Otherwise, leave it to - * the right of the current choice, since we can't move - * it out of the window, and let sighted users rely on - * the highlighting of the current choice without the - * distraction of a blinking cursor preceding it. - FM - */ - if (LYShowCursor) - wmove(form_window, ((i + 1) - window_offset), 1); - wrefresh(form_window); -#endif /* USE_SLANG */ + row = ((i + 1) - window_offset); + draw_option (form_window, row, width, TRUE, + num_choices, i, Cptr[i]); + LYstowCursor(form_window, row, 1); term_options = FALSE; c = LYgetch_choice(); @@ -2501,7 +2438,7 @@ redraw: cmd = LYK_QUIT; #ifndef USE_SLANG } else if (c == MOUSE_KEY) { - if ((cmd = fancy_mouse(form_window, i + 1 - window_offset, &cur_choice)) < 0) + if ((cmd = fancy_mouse(form_window, row, &cur_choice)) < 0) goto redraw; if (cmd == LYK_ACTIVATE) break; @@ -3122,13 +3059,7 @@ restore_popup_statusline: } } FREE(popup_status_msg); -#ifndef USE_SLANG - touchwin(stdscr); - delwin(form_window); -#if defined(NCURSES) || defined(PDCURSES) - LYsubwindow(0); -#endif -#endif /* !USE_SLANG */ + LYstopPopup(); if (disabled || term_options) { _statusline(""); diff --git a/src/LYStrings.c b/src/LYStrings.c index 723345d7..b8ed9f48 100644 --- a/src/LYStrings.c +++ b/src/LYStrings.c @@ -14,6 +14,7 @@ #include <HTAlert.h> #include <HTString.h> #include <LYCharUtils.h> +#include <HTList.h> #include <HTParse.h> #ifdef USE_MOUSE #include <LYMainLoop.h> @@ -46,13 +47,7 @@ extern BOOL HTPassHighCtrlRaw; /*Allowing the user to press tab when entering URL to get the closest match in the closet*/ #define LYClosetSize 100 -static char* LYCloset[LYClosetSize]; /* Closet with LYClosetSize shelves */ -static int LYClosetTop = 0; /*Points to the next empty shelf */ - -PRIVATE char *LYFindInCloset PARAMS(( - char* base)); -PRIVATE void LYAddToCloset PARAMS(( - char* str)); +static HTList *URL_edit_history; /* If you want to add mouse support for some new platform, it's fairly ** simple to do. Once you've determined the X and Y coordinates of @@ -259,6 +254,60 @@ PUBLIC int fancy_mouse ARGS3( return cmd; } +/* + * Remove the oldest item in the closet + */ +PRIVATE void LYRemoveFromCloset NOARGS +{ + char *data = HTList_removeFirstObject(URL_edit_history); + + if (data != 0) + FREE(data); +} + +PUBLIC void LYOpenCloset NOARGS +{ + URL_edit_history = HTList_new(); +} + +PUBLIC void LYCloseCloset NOARGS +{ + while (!HTList_isEmpty(URL_edit_history) ) { + LYRemoveFromCloset(); + } + HTList_delete(URL_edit_history); /* should already be empty */ +} + +/* + * Strategy: We begin at the top and search downwards. We return the first + * match, i.e., the newest since we search from the top. This should be made + * more intelligent, but works for now. + */ +PRIVATE char * LYFindInCloset ARGS1(char*, base) +{ + HTList *list = URL_edit_history; + char *data; + unsigned len = strlen(base); + + while (!HTList_isEmpty(list)) { + data = HTList_nextObject(list); + if (!strncmp(base, data, len)) + return(data); + } + + return(0); +} + +PRIVATE void LYAddToCloset ARGS1(char*, str) +{ + char *data = NULL; + + StrAllocCopy(data, str); + HTList_addObject(URL_edit_history, data); + while (HTList_count(URL_edit_history) > LYClosetSize) + LYRemoveFromCloset(); +} + PRIVATE int XYdist ARGS5( int, x1, @@ -645,7 +694,6 @@ PUBLIC int LYmbcsstrlen ARGS3( #endif /* HAVE_KEYPAD */ #endif /* !defined(GetChar) */ -#if defined(NCURSES) || defined(PDCURSES) /* * Workaround a bug in ncurses order-of-refresh by setting a pointer to * the topmost window that should be displayed. @@ -653,14 +701,24 @@ PUBLIC int LYmbcsstrlen ARGS3( * 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 !defined(WIN_EX) - if ((my_subwindow = param) != 0) + if ((my_subwindow = param) != 0) { +#if defined(NCURSES) || defined(PDCURSES) keypad(param, TRUE); +#if defined(HAVE_GETBKGD) /* not defined in ncurses 1.8.7 */ + wbkgd(my_subwindow, getbkgd(stdscr)); + wbkgdset(my_subwindow, getbkgd(stdscr)); +#endif #endif + scrollok(my_subwindow, TRUE); + } else { + touchwin(stdscr); + delwin(my_subwindow); + } } #endif @@ -3218,20 +3276,291 @@ PUBLIC void LYRefreshEdit ARGS1( refresh(); } +PRIVATE void reinsertEdit ARGS2( + EditFieldData *, edit, + char *, result) +{ + if (result != 0) { + LYEdit1(edit, '\0', LYE_ERASE, FALSE); + while (*result != '\0') { + LYLineEdit(edit, (int)(*result), FALSE); + result++; + } + } +} + +PRIVATE HTList *whichRecall ARGS1( + RecallType, recall) +{ + switch (recall) { + case RECALL_CMD: + return LYcommandList(); + default: + return URL_edit_history; + } +} + +PRIVATE int caselessCmpList ARGS2( + CONST void *, a, + CONST void *, b) +{ + return strcasecomp(*(CONST char *CONST *)a, *(CONST char *CONST *)b); +} + +PRIVATE int normalCmpList ARGS2( + CONST void *, a, + CONST void *, b) +{ + return strcmp(*(CONST char *CONST *)a, *(CONST char *CONST *)b); +} + +PRIVATE char **sortedList ARGS2( + HTList *, list, + BOOL, ignorecase) +{ + unsigned count = HTList_count(list); + unsigned n = 0; + char **result = calloc(count + 1, sizeof(char *)); + + if (result == 0) + outofmem(__FILE__, "sortedList"); + + while (!HTList_isEmpty(list)) + result[n++] = HTList_nextObject(list); + if (count > 1) { + qsort((char *)result, count, sizeof(*result), + ignorecase ? caselessCmpList : normalCmpList); + } + + return result; +} + +PRIVATE int lengthOfList ARGS1( + char **, list) +{ + int result = 0; + + while (*list++ != 0) + result++; + return result; +} + +PRIVATE int widestInList ARGS1( + char **, list) +{ + int result = 0; + int check; + + while (*list != 0) { + check = strlen(*list++); + if (check > result) + result = check; + } + return result; +} + +PRIVATE void draw_option ARGS5( + WINDOW *, win, + int, entry, + int, width, + BOOL, reversed, + char *, value) +{ +#ifdef USE_SLANG + if (reversed) + SLsmg_gotorc((win->top_y + entry), win->left_x + 2); + SLsmg_gotorc(win->top_y + entry, win->left_x + 2); + SLsmg_write_nstring(value, win->width); + if (reversed) + SLsmg_set_color(0); +#else + wmove(win, entry, 2); + if (reversed) + wstart_reverse(win); + LYpaddstr(win, width, value); + if (reversed) + wstop_reverse(win); +#endif /* USE_SLANG */ +} + +PRIVATE int LYgetMenuKeycode ARGS3( + WINDOW *, win, + int, row, + int *, cur_selectionp) +{ + int cmd; + int c = LYgetch_choice(); + + if (c == 7) { /* Control-C or Control-G */ + cmd = LYK_QUIT; +#ifndef USE_SLANG + } else if (c == MOUSE_KEY) { + cmd = fancy_mouse(win, row, cur_selectionp); +#endif + } else { + cmd = LKC_TO_LAC(keymap,c); + } +#ifdef VMS + if (HadVMSInterrupt) { + HadVMSInterrupt = FALSE; + cmd = LYK_QUIT; + } +#endif /* VMS */ + return cmd; +} + +PRIVATE void completeFromPopup ARGS2( + EditFieldData *, edit, + char **, data) +{ + WINDOW *win; + int top; + int lx = 2; + int width = widestInList(data); + int num_options = lengthOfList(data); + int height = num_options + 2; + int i, row, length; + int cmd = LYK_UNKNOWN; + int window_offset = 0; + int cur_selection = 0; + int old_selection = -1; + int old_y, old_x; + +#ifdef USE_SLANG + old_y = SLsmg_get_row(); + old_x = SLsmg_get_column(); +#else + getyx(stdscr, old_y, old_x); +#endif + + if (height > LYlines - 2) + height = LYlines - 2; + length = height - 2; + top = LYlines - height - 1; + + while (cur_selection < num_options + && strcasecomp(data[cur_selection], edit->buffer) < 0) + cur_selection++; + if (cur_selection + 1 - window_offset >= length) { + window_offset = cur_selection + 1 - length; + } + + /* construct a popup window */ + if ((win = LYstartPopup(top, lx, height, width)) != 0) { + /* handle events in the popup window */ +redraw: + LYbox(win, FALSE); + for (i = 0; i < num_options; i++) { + row = ((i + 1) - window_offset); + if (row >= 1 && row <= length) + draw_option(win, row, width, FALSE, data[i]); + } + old_selection = -1; + + while (cmd != LYK_ACTIVATE) { + + if (old_selection >= 0 + && old_selection != cur_selection) { + row = ((old_selection + 1) - window_offset); + draw_option(win, row, width, FALSE, data[old_selection]); + } + old_selection = cur_selection; + + row = ((cur_selection + 1) - window_offset); + draw_option(win, row, width, TRUE, data[cur_selection]); + LYstowCursor(win, row, 1); + cmd = LYgetMenuKeycode(win, row, &cur_selection); + + /* FIXME: this whole switch statement should be integrated with + * the redundant logic in LYForms.c and LYOptions.c (there's no + * point in having multiple copies of code that scroll through + * a popup menu). + */ + switch (cmd) { + case -1: + goto redraw; + + case LYK_HOME: + cur_selection = 0; + if (window_offset > 0) { + window_offset = 0; + goto redraw; + } + break; + + case LYK_END: + cur_selection = num_options - 1; + if (window_offset != (num_options - length)) { + window_offset = (num_options - length); + goto redraw; + } + break; + + case LYK_PREV_LINK: + case LYK_LPOS_PREV_LINK: + case LYK_FASTBACKW_LINK: + case LYK_UP_LINK: + if (cur_selection > 0) + cur_selection--; + + /* + * Scroll the window up if necessary. + */ + if ((cur_selection - window_offset) < 0) { + window_offset--; + goto redraw; + } + break; + + case LYK_NEXT_LINK: + case LYK_LPOS_NEXT_LINK: + case LYK_FASTFORW_LINK: + case LYK_DOWN_LINK: + if (cur_selection < num_options - 1) + cur_selection++; + /* + * Scroll the window down if necessary + */ + if ((cur_selection - window_offset) >= length) { + window_offset++; + goto redraw; + } + break; + + case LYK_QUIT: + case LYK_ABORT: + case LYK_PREV_DOC: + cur_selection = -1; + cmd = LYK_ACTIVATE; /* to exit */ + break; + } + } + LYstopPopup(); + } + if (cur_selection >= 0) + reinsertEdit(edit, data[cur_selection]); + +#ifdef USE_SLANG + SLsmg_gotorc(old_y, old_x); +#else + wmove(stdscr, old_y, old_x); +#endif +} + #define CurModif MyEdit.current_modifiers PUBLIC int LYgetstr ARGS4( char *, inputline, int, hidden, size_t, bufsize, - int, recall) + RecallType, recall) { int x, y, MaxStringSize; int ch; - int xlec; + int xlec = -2; + int last_xlec = -1; int last_xlkc = -1; EditFieldData MyEdit; - char *res; #ifdef SUPPORT_MULTIBYTE_EDIT BOOL refresh_mb = TRUE; #endif /* SUPPORT_MULTIBYTE_EDIT */ @@ -3278,7 +3607,7 @@ again: ch = 7; } - if (recall && (ch == UPARROW || ch == DNARROW)) { + if (recall != NORECALL && (ch == UPARROW || ch == DNARROW)) { LYstrncpy(inputline, MyEdit.buffer, (int)bufsize); LYAddToCloset(MyEdit.buffer); return(ch); @@ -3294,6 +3623,7 @@ again: if (LKC_TO_LAC(keymap,ch) == LYK_REFRESH) goto again; #endif + last_xlec = xlec; xlec = EditBinding(ch); if ((xlec & LYE_DF) && !(xlec & LYE_FORM_LAC)) { last_xlkc = ch; @@ -3315,18 +3645,15 @@ again: CurModif |= LKC_MOD2; break; case LYE_TAB: - ch = '\t'; - /* This used to fall through to the next case before - tab completion was introduced */ - res = LYFindInCloset(MyEdit.buffer); - if (res != 0) { - LYEdit1(&MyEdit, '\0', LYE_ERASE, FALSE); - while (*res != '\0') { - LYLineEdit(&MyEdit, (int)(*res), FALSE); - res++; + if (xlec == last_xlec) { + HTList *list = whichRecall(recall); + if (!HTList_isEmpty(list)) { + char **data = sortedList(list, recall == RECALL_CMD); + completeFromPopup(&MyEdit, data); + FREE(data); } } else { - ch = '\0'; + reinsertEdit(&MyEdit, LYFindInCloset(MyEdit.buffer)); } break; @@ -3554,58 +3881,6 @@ PUBLIC char * LYno_attr_char_case_strstr ARGS2( return(NULL); } -PUBLIC void LYOpenCloset NOARGS -{ - /* We initialize the list-looka-like, i.e., the Closet */ - int i = 0; - while(i < LYClosetSize){ - LYCloset[i] = NULL; - i = i + 1; - } - LYClosetTop = 0; -} - -PUBLIC void LYCloseCloset NOARGS -{ - int i = 0; - - /* Clean up the list-looka-like, i.e., the Closet */ - while (i < LYClosetSize){ - FREE(LYCloset[i]); - i = i + 1; - } -} - -/* - * Strategy: We begin at the top and search downwards. We return the first - * match, i.e., the newest since we search from the top. This should be made - * more intelligent, but works for now. - */ -PRIVATE char * LYFindInCloset ARGS1(char*, base) -{ - int shelf; - unsigned len = strlen(base); - - shelf = (LYClosetTop - 1 + LYClosetSize) % LYClosetSize; - - while (LYCloset[shelf] != NULL){ - if (!strncmp(base, LYCloset[shelf], len)) { - return(LYCloset[shelf]); - } - shelf = (shelf - 1 + LYClosetSize) % LYClosetSize; - } - return(0); -} - -PRIVATE void LYAddToCloset ARGS1(char*, str) -{ - LYCloset[LYClosetTop] = NULL; - StrAllocCopy(LYCloset[LYClosetTop], str); - - LYClosetTop = (LYClosetTop + 1) % LYClosetSize; - FREE(LYCloset[LYClosetTop]); -} - /* * LYno_attr_char_strstr will find the first occurrence of the * string pointed to by tarptr in the string pointed to by chptr. diff --git a/src/LYStrings.h b/src/LYStrings.h index 32aeed8c..1d2f9131 100644 --- a/src/LYStrings.h +++ b/src/LYStrings.h @@ -3,6 +3,12 @@ #include <LYCurses.h> +typedef enum { + NORECALL = 0 + , RECALL + , RECALL_CMD +} RecallType; + /* UPPER8(ch1,ch2) is an extension of (TOUPPER(ch1) - TOUPPER(ch2)) */ extern int UPPER8 PARAMS(( int ch1, @@ -26,7 +32,7 @@ extern int LYgetstr PARAMS(( char * inputline, int hidden, size_t bufsize, - int recall)); + RecallType recall)); extern char *LYstrsep PARAMS(( char ** stringp, CONST char * delim)); @@ -156,8 +162,6 @@ extern void base64_encode PARAMS((char * dest, char * src, int len)); #define VISIBLE 0 #define HIDDEN 1 -#define NORECALL 0 -#define RECALL 1 #ifdef EXP_ALT_BINDINGS /* Enable code implementing additional, mostly emacs-like, line-editing diff --git a/src/LYStyle.c b/src/LYStyle.c index 517e1832..42c98a67 100644 --- a/src/LYStyle.c +++ b/src/LYStyle.c @@ -1,6 +1,6 @@ /* character level styles for Lynx * (c) 1996 Rob Partington -- donated to the Lyncei (if they want it :-) - * @Id: LYStyle.c 1.36 Fri, 23 Jun 2000 08:15:08 -0700 dickey @ + * @Id: LYStyle.c 1.37 Sun, 16 Jul 2000 20:16:13 -0700 dickey @ */ #include <HTUtils.h> #include <HTML.h> @@ -25,9 +25,11 @@ #ifdef USE_COLOR_STYLE +PRIVATE void style_initialiseHashTable NOPARAMS; + /* stack of attributes during page rendering */ PUBLIC int last_styles[128]; -PUBLIC int last_colorattr_ptr=0; +PUBLIC int last_colorattr_ptr = 0; PUBLIC bucket hashStyles[CSHASHSIZE]; PUBLIC bucket special_bucket = @@ -63,7 +65,6 @@ static char *Mono_Strings[7] = /* Remember the hash codes for common elements */ PUBLIC int s_alink = NOSTYLE, s_a = NOSTYLE, s_status = NOSTYLE, - s_label = NOSTYLE, s_value = NOSTYLE, s_high = NOSTYLE, s_normal = NOSTYLE, s_alert = NOSTYLE, s_title = NOSTYLE, #ifdef USE_SCROLLBAR s_sb_bar = NOSTYLE, s_sb_bg = NOSTYLE, @@ -80,7 +81,10 @@ PRIVATE unsigned char our_pairs[2][MAX_COLOR][MAX_COLOR]; PRIVATE void parse_attributes ARGS5(char*,mono,char*,fg,char*,bg,int,style,char*,element) { int i; - int mA = 0, fA = default_fg, bA = default_bg, cA = A_NORMAL; + int mA = 0; + short fA = default_fg; + short bA = default_bg; + int cA = A_NORMAL; int newstyle = hash_code(element); CTRACE((tfp, "CSS(PA):style d=%d / h=%d, e=%s\n", style, newstyle,element)); @@ -329,43 +333,54 @@ PRIVATE void free_colorstylestuff NOARGS */ PRIVATE void initialise_default_stylesheet NOARGS { + static CONST char *table[] = { + "a:bold:green", + "alert:bold:yellow:red", + "alink:reverse:yellow:black", + "label:normal:magenta", + "status:reverse:yellow:blue", + "title:normal:magenta", + "whereis:reverse+underline:magenta:cyan" + }; + unsigned n; + char temp[80]; + for (n = 0; n < TABLESIZE(table); n++) { + parse_style(strcpy(temp, table[n])); + } } /* Set all the buckets in the hash table to be empty */ -PUBLIC void style_initialiseHashTable NOARGS +PRIVATE void style_initialiseHashTable NOARGS { - int i; - static int firsttime = 1; + int i; + static int firsttime = 1; - for (i = 0; i <CSHASHSIZE; i++) - { - if (firsttime) - hashStyles[i].name = NULL; - else - FREE(hashStyles[i].name); - hashStyles[i].color = -1; - hashStyles[i].cattr = -1; - hashStyles[i].mono = -1; - } - if (firsttime) { - firsttime = 0; + for (i = 0; i <CSHASHSIZE; i++) + { + if (firsttime) + hashStyles[i].name = NULL; + else + FREE(hashStyles[i].name); + hashStyles[i].color = 0; + hashStyles[i].cattr = 0; + hashStyles[i].mono = 0; + } + if (firsttime) { + firsttime = 0; #ifdef LY_FIND_LEAKS - atexit(free_colorstylestuff); + atexit(free_colorstylestuff); #endif - } - s_high = hash_code("high"); - s_alink = hash_code("alink"); - s_value = hash_code("value"); - s_label = hash_code("label"); - s_a = hash_code("a"); - s_status = hash_code("status"); - s_alert = hash_code("alert"); - s_title = hash_code("title"); + } + s_alink = hash_code("alink"); + s_a = hash_code("a"); + s_status = hash_code("status"); + s_alert = hash_code("alert"); + s_title = hash_code("title"); #ifdef USE_SCROLLBAR - s_sb_bar = hash_code("scroll.bar"); - s_sb_bg = hash_code("scroll.back"); - s_sb_aa = hash_code("scroll.arrow"); - s_sb_naa = hash_code("scroll.noarrow"); + s_sb_bar = hash_code("scroll.bar"); + s_sb_bg = hash_code("scroll.back"); + s_sb_aa = hash_code("scroll.arrow"); + s_sb_naa = hash_code("scroll.noarrow"); #endif } @@ -377,33 +392,35 @@ HTList *lss_styles = NULL; PUBLIC void parse_userstyles NOARGS { - char *name; - HTList *cur = lss_styles; - colorPairs = 0; - style_initialiseHashTable(); + char *name; + HTList *cur = lss_styles; - /* set our styles to be the same as vanilla-curses-lynx */ - initialise_default_stylesheet(); + colorPairs = 0; + style_initialiseHashTable(); - while ((name = HTList_nextObject(cur)) != NULL) - { - CTRACE((tfp, "LSS:%s\n", name ? name : "!?! empty !?!")); - if (name != NULL) - parse_style(name); + /* set our styles to be the same as vanilla-curses-lynx */ + if (HTList_isEmpty(cur)) { + initialise_default_stylesheet(); + } else { + while ((name = HTList_nextObject(cur)) != NULL) { + CTRACE((tfp, "LSS:%s\n", name ? name : "!?! empty !?!")); + if (name != NULL) + parse_style(name); } + } } /* Add a STYLE: option line to our list */ -PUBLIC void HStyle_addStyle ARGS1(char*,buffer) +PRIVATE void HStyle_addStyle ARGS1(char*,buffer) { - char *name = NULL; - StrAllocCopy(name, buffer); - if (lss_styles == NULL) - lss_styles = HTList_new(); - strtolower(name); - CTRACE((tfp, "READCSS:%s\n", name ? name : "!?! empty !?!")); - HTList_addObject (lss_styles, name); + char *name = NULL; + StrAllocCopy(name, buffer); + if (lss_styles == NULL) + lss_styles = HTList_new(); + strtolower(name); + CTRACE((tfp, "READCSS:%s\n", name ? name : "!?! empty !?!")); + HTList_addObject (lss_styles, name); } PUBLIC void style_deleteStyleList NOARGS @@ -415,18 +432,6 @@ PUBLIC void style_deleteStyleList NOARGS lss_styles = NULL; } -char* default_stylesheet[] = { - "a:bold", "em:bold", "strong:bold", "b:bold", "i:bold", - "alink:reverse", "status:reverse", NULL -}; - -PUBLIC void style_defaultStyleSheet NOARGS -{ - int i; - for (i = 0; default_stylesheet[i]; i++) - HStyle_addStyle(default_stylesheet[i]); -} - PRIVATE int style_readFromFileREC ARGS2(char*, file, int, toplevel) { FILE *fh; @@ -440,13 +445,13 @@ PRIVATE int style_readFromFileREC ARGS2(char*, file, int, toplevel) if (!fh) { /* this should probably be an alert or something */ - CTRACE((tfp, "CSS:Can't open style file '%s', using defaults\n", file)); + CTRACE((tfp, "CSS:Can't open style file %s, using defaults\n", file)); return -1; } if (toplevel) { - style_initialiseHashTable(); - style_deleteStyleList(); + style_initialiseHashTable(); + style_deleteStyleList(); } while (LYSafeGets(&buffer, fh) != NULL) @@ -459,10 +464,6 @@ PRIVATE int style_readFromFileREC ARGS2(char*, file, int, toplevel) else if (buffer[0] != '#' && (len = strlen(buffer)) > 0) HStyle_addStyle(buffer); } - /* the default styles are added after the user styles in order - ** that they come before them <grin> RP - */ - /* style_defaultStyleSheet(); */ fclose (fh); if (toplevel && LYCursesON) diff --git a/src/LYStyle.h b/src/LYStyle.h index 6df504cf..253ec986 100644 --- a/src/LYStyle.h +++ b/src/LYStyle.h @@ -16,12 +16,8 @@ extern HTCharStyle displayStyles[DSTYLE_ELEMENTS]; extern int lynx_has_color; /* Set all the buckets in the hash table to be empty */ -extern void style_initialiseHashTable NOPARAMS; - extern void parse_userstyles NOPARAMS; -extern void HStyle_addStyle PARAMS((char* buffer)); - extern void style_deleteStyleList NOPARAMS; extern void style_defaultStyleSheet NOPARAMS; diff --git a/src/LYUtils.c b/src/LYUtils.c index 5a298057..896ff407 100644 --- a/src/LYUtils.c +++ b/src/LYUtils.c @@ -4385,7 +4385,7 @@ PUBLIC void LYConvertToURL ARGS2( #endif /* DOSPATH */ *AllocatedString = NULL; /* so StrAllocCopy doesn't free it */ - StrAllocCopy(*AllocatedString,"file://localhost"); + StrAllocCopy(*AllocatedString, "file://localhost"); if (*old_string != '/') { char *fragment = NULL; @@ -4551,7 +4551,7 @@ have_VMS_URL: chk = GetFullPathNameA(old_string, MAX_PATH + 1, fullpath, &filepart); if (chk != 0) { - StrAllocCopy(temp, HTDOS_wwwName(fullpath)); + StrAllocCopy(temp, wwwName(fullpath)); StrAllocCat(*AllocatedString, temp); FREE(temp); CTRACE((tfp, "Converted '%s' to '%s'\n", @@ -4607,11 +4607,7 @@ have_VMS_URL: */ #if defined (DOSPATH) || defined (__EMX__) || defined (WIN_EX) if (old_string[1] != ':' && old_string[1] != '|') { -#ifdef DOSPATH - StrAllocCopy(temp, HTDOS_wwwName(curdir)); -#else StrAllocCopy(temp, wwwName(curdir)); -#endif LYAddHtmlSep(&temp); LYstrncpy(curdir, temp, (sizeof(curdir) - 1)); StrAllocCat(temp, old_string); @@ -7184,6 +7180,8 @@ PUBLIC void LYLocalFileToURL ARGS2( if (!LYIsHtmlSep(*leaf)) LYAddHtmlSep(target); StrAllocCat(*target, leaf); + if (leaf != source) + FREE(leaf); } #ifdef NOTDEFINED |