1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-11-04 08:17:17 -05:00

Merge branch 'elinks-0.12' into elinks-0.13

Conflicts:
	src/bfu/dialog.c
	src/bfu/hotkey.c
	src/bfu/inpfield.c
	src/dialogs/options.c
	src/document/renderer.c
	src/intl/gettext/libintl.h
	src/protocol/http/codes.c
	src/session/task.c
	src/terminal/event.c
	src/terminal/terminal.h
	src/viewer/text/form.c
	src/viewer/text/link.c

And a semantic conflict in src/terminal/terminal.c.
This commit is contained in:
Kalle Olavi Niemitalo 2009-01-01 18:47:43 +00:00 committed by Kalle Olavi Niemitalo
commit 687f19dbde
30 changed files with 215 additions and 116 deletions

9
NEWS
View File

@ -75,10 +75,16 @@ ELinks 0.12pre2.GIT now:
To be released as 0.12pre3, 0.12rc1, or even 0.12.0. This branch also To be released as 0.12pre3, 0.12rc1, or even 0.12.0. This branch also
includes the changes listed under ``ELinks 0.11.5.GIT'' below. includes the changes listed under ``ELinks 0.11.5.GIT'' below.
* critical: Fix assertion failure if IMG/@usemap refers to a different
file.
* Preserve newlines in hidden input fields, and submit them as CRLF. * Preserve newlines in hidden input fields, and submit them as CRLF.
Previously, they could turn into spaces or disappear entirely. Previously, they could turn into spaces or disappear entirely.
* Perl scripts can use modules that dynamically load C libraries, like * Perl scripts can use modules that dynamically load C libraries, like
XML::LibXML::SAX does. XML::LibXML::SAX does.
* bug 885: Convert xterm titles to ISO-8859-1 by default, but add an
option to disable this. When removing control characters from a
title, note the charset. Don't truncate titles to the width of the
terminal.
* enhancement: Updated ISO 8859-7, ISO 8859-16, KOI8-R, and MacRoman. * enhancement: Updated ISO 8859-7, ISO 8859-16, KOI8-R, and MacRoman.
ELinks 0.12pre2: ELinks 0.12pre2:
@ -301,11 +307,14 @@ ELinks 0.11.5.GIT now:
To be released as 0.11.6. To be released as 0.11.6.
* critical: fix double-free crash if EOF immediately follows </MAP>
* critical bug 1053: fix crash if a download finishes after ELinks has * critical bug 1053: fix crash if a download finishes after ELinks has
closed the terminal from which the download was started closed the terminal from which the download was started
* major bug 1004: ignore locales when comparing HTML element names and * major bug 1004: ignore locales when comparing HTML element names and
similar strings, so e.g. ``title'' matches ``TITLE'' even in the similar strings, so e.g. ``title'' matches ``TITLE'' even in the
Turkish locale Turkish locale
* minor: clicking a link with the mouse activates that link, rather
than the one selected with move-cursor-* actions
ELinks 0.11.5: ELinks 0.11.5:
-------------- --------------

View File

@ -323,7 +323,7 @@ select_button_by_key(struct dialog_data *dlg_data)
#ifdef CONFIG_UTF8 #ifdef CONFIG_UTF8
key = unicode_fold_label_case(get_kbd_key(ev)); key = unicode_fold_label_case(get_kbd_key(ev));
codepage = get_opt_codepage_tree(dlg_data->win->term->spec, "charset", NULL); codepage = get_terminal_codepage(dlg_data->win->term);
#else #else
key = toupper(get_kbd_key(ev)); key = toupper(get_kbd_key(ev));
#endif #endif

View File

@ -127,7 +127,7 @@ check_hotkeys_common(struct menu *menu, term_event_char_T hotkey, struct termina
{ {
#ifdef CONFIG_UTF8 #ifdef CONFIG_UTF8
unicode_val_T key = unicode_fold_label_case(hotkey); unicode_val_T key = unicode_fold_label_case(hotkey);
int codepage = get_opt_codepage_tree(term->spec, "charset", NULL); int codepage = get_terminal_codepage(term);
#else #else
unsigned char key = toupper(hotkey); unsigned char key = toupper(hotkey);
#endif #endif

View File

@ -692,9 +692,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
/* get_kbd_key(ev) is UCS-4, and @text /* get_kbd_key(ev) is UCS-4, and @text
* is in the terminal's charset. */ * is in the terminal's charset. */
ins = u2cp_no_nbsp(get_kbd_key(ev), ins = u2cp_no_nbsp(get_kbd_key(ev),
get_opt_codepage_tree(term->spec, get_terminal_codepage(term));
"charset",
NULL));
inslen = strlen(ins); inslen = strlen(ins);
#endif /* CONFIG_UTF8 */ #endif /* CONFIG_UTF8 */

View File

@ -847,6 +847,19 @@ static struct option_info config_options_info[] = {
"3 is KOI-8\n" "3 is KOI-8\n"
"4 is FreeBSD")), "4 is FreeBSD")),
INIT_OPT_BOOL("terminal._template_", N_("Always encode xterm title in ISO-8859-1"),
"latin1_title", 0, 1,
N_("When updating the window title of xterm or a similar "
"terminal emulator, encode the title in ISO-8859-1 (Latin-1), "
"rather than in the charset used for other text in the window. "
"Cyrillic and other characters get replaced with Latin ones. "
"Xterm requires this unless you explicitly enable UTF-8 "
"titles in it.\n"
"\n"
"If this option does not take effect immediately, try switching "
"to a different page so that ELinks notices it needs to update "
"the title.")),
INIT_OPT_BOOL("terminal._template_", N_("Switch fonts for line drawing"), INIT_OPT_BOOL("terminal._template_", N_("Switch fonts for line drawing"),
"m11_hack", 0, 0, "m11_hack", 0, 0,
N_("Switch fonts when drawing lines, enabling both local characters\n" N_("Switch fonts when drawing lines, enabling both local characters\n"

View File

@ -50,7 +50,7 @@ charset_list(struct terminal *term, void *xxx, void *ses_)
int i, items; int i, items;
int sel = 0; int sel = 0;
const unsigned char *const sel_mime = get_cp_mime_name( const unsigned char *const sel_mime = get_cp_mime_name(
get_opt_codepage_tree(term->spec, "charset", NULL)); get_terminal_codepage(term));
struct menu_item *mi = new_menu(FREE_LIST); struct menu_item *mi = new_menu(FREE_LIST);
if (!mi) return; if (!mi) return;

View File

@ -493,12 +493,12 @@ display_window_title(struct session *ses, struct terminal *term)
if (!title) return; if (!title) return;
titlelen = strlen(title); titlelen = strlen(title);
if (last_ses != ses if ((last_ses != ses
|| !status->last_title || !status->last_title
|| strlen(status->last_title) != titlelen || strlen(status->last_title) != titlelen
|| memcmp(status->last_title, title, titlelen)) { || memcmp(status->last_title, title, titlelen))
&& set_terminal_title(term, title) >= 0) {
mem_free_set(&status->last_title, title); mem_free_set(&status->last_title, title);
set_terminal_title(term, title);
last_ses = ses; last_ses = ses;
} else { } else {
mem_free(title); mem_free(title);

View File

@ -619,6 +619,9 @@ look_for_tag(unsigned char **pos, unsigned char *eof,
return 0; return 0;
} }
/** @return -1 if EOF is hit without the closing tag; 0 if the closing
* tag is found (in which case this also adds *@a menu to *@a ml); or
* 1 if this should be called again. */
static int static int
look_for_link(unsigned char **pos, unsigned char *eof, struct menu_item **menu, look_for_link(unsigned char **pos, unsigned char *eof, struct menu_item **menu,
struct memory_list **ml, struct uri *href_base, struct memory_list **ml, struct uri *href_base,
@ -636,7 +639,7 @@ look_for_link(unsigned char **pos, unsigned char *eof, struct menu_item **menu,
(*pos)++; (*pos)++;
} }
if (*pos >= eof) return 0; if (*pos >= eof) return -1;
if (*pos + 2 <= eof && ((*pos)[1] == '!' || (*pos)[1] == '?')) { if (*pos + 2 <= eof && ((*pos)[1] == '!' || (*pos)[1] == '?')) {
*pos = skip_comment(*pos, eof); *pos = skip_comment(*pos, eof);
@ -651,7 +654,7 @@ look_for_link(unsigned char **pos, unsigned char *eof, struct menu_item **menu,
if (!c_strlcasecmp(name, namelen, "A", 1)) { if (!c_strlcasecmp(name, namelen, "A", 1)) {
while (look_for_tag(pos, eof, name, namelen, &label)); while (look_for_tag(pos, eof, name, namelen, &label));
if (*pos >= eof) return 0; if (*pos >= eof) return -1;
} else if (!c_strlcasecmp(name, namelen, "AREA", 4)) { } else if (!c_strlcasecmp(name, namelen, "AREA", 4)) {
/* FIXME (bug 784): options->cp is the terminal charset; /* FIXME (bug 784): options->cp is the terminal charset;
@ -769,6 +772,7 @@ get_image_map(unsigned char *head, unsigned char *pos, unsigned char *eof,
{ {
struct conv_table *ct; struct conv_table *ct;
struct string hd; struct string hd;
int look_result;
if (!init_string(&hd)) return -1; if (!init_string(&hd)) return -1;
@ -789,10 +793,13 @@ get_image_map(unsigned char *head, unsigned char *pos, unsigned char *eof,
*ml = NULL; *ml = NULL;
while (look_for_link(&pos, eof, menu, ml, uri, target_base, ct, options)) do {
; /* This call can modify both *ml and *menu. */
look_result = look_for_link(&pos, eof, menu, ml, uri,
target_base, ct, options);
} while (look_result > 0);
if (pos >= eof) { if (look_result < 0) {
freeml(*ml); freeml(*ml);
mem_free(*menu); mem_free(*menu);
return -1; return -1;

View File

@ -457,8 +457,7 @@ render_document_frames(struct session *ses, int no_cache)
if (!get_opt_bool_tree(ses->tab->term->spec, "underline", NULL)) if (!get_opt_bool_tree(ses->tab->term->spec, "underline", NULL))
doc_opts.color_flags |= COLOR_ENHANCE_UNDERLINE; doc_opts.color_flags |= COLOR_ENHANCE_UNDERLINE;
doc_opts.cp = get_opt_codepage_tree(ses->tab->term->spec, "charset", doc_opts.cp = get_terminal_codepage(ses->tab->term);
NULL);
doc_opts.no_cache = no_cache & 1; doc_opts.no_cache = no_cache & 1;
doc_opts.gradual_rerendering = !!(no_cache & 2); doc_opts.gradual_rerendering = !!(no_cache & 2);

View File

@ -255,7 +255,6 @@ encode_utf8(unicode_val_T u)
return utf_buffer; return utf_buffer;
} }
#ifdef CONFIG_UTF8
/* Number of bytes utf8 character indexed by first byte. Illegal bytes are /* Number of bytes utf8 character indexed by first byte. Illegal bytes are
* equal ones and handled different. */ * equal ones and handled different. */
static const char utf8char_len_tab[256] = { static const char utf8char_len_tab[256] = {
@ -269,6 +268,7 @@ static const char utf8char_len_tab[256] = {
3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4, 5,5,5,5,6,6,1,1, 3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4, 5,5,5,5,6,6,1,1,
}; };
#ifdef CONFIG_UTF8
inline int utf8charlen(const unsigned char *p) inline int utf8charlen(const unsigned char *p)
{ {
return p ? utf8char_len_tab[*p] : 0; return p ? utf8char_len_tab[*p] : 0;
@ -631,6 +631,7 @@ unicode_fold_label_case(unicode_val_T c)
return c; return c;
#endif /* !(__STDC_ISO_10646__ && HAVE_WCTYPE_H) */ #endif /* !(__STDC_ISO_10646__ && HAVE_WCTYPE_H) */
} }
#endif /* CONFIG_UTF8 */
inline unicode_val_T inline unicode_val_T
utf8_to_unicode(unsigned char **string, const unsigned char *end) utf8_to_unicode(unsigned char **string, const unsigned char *end)
@ -715,7 +716,6 @@ invalid_utf8:
*string = str + length; *string = str + length;
return u; return u;
} }
#endif /* CONFIG_UTF8 */
/* The common part of cp2u and cp2utf_8. */ /* The common part of cp2u and cp2utf_8. */
static unicode_val_T static unicode_val_T
@ -754,9 +754,8 @@ cp2utf8(int from, int c)
return encode_utf8(cp2u_shared(&codepages[from], c)); return encode_utf8(cp2u_shared(&codepages[from], c));
} }
#ifdef CONFIG_UTF8
unicode_val_T unicode_val_T
cp_to_unicode(int codepage, unsigned char **string, unsigned char *end) cp_to_unicode(int codepage, unsigned char **string, const unsigned char *end)
{ {
unicode_val_T ret; unicode_val_T ret;
@ -770,7 +769,6 @@ cp_to_unicode(int codepage, unsigned char **string, unsigned char *end)
++*string; ++*string;
return ret; return ret;
} }
#endif /* CONFIG_UTF8 */
#ifdef CONFIG_COMBINE #ifdef CONFIG_COMBINE

View File

@ -154,9 +154,9 @@ unsigned char *utf8_step_backward(unsigned char *, unsigned char *,
inline int unicode_to_cell(unicode_val_T); inline int unicode_to_cell(unicode_val_T);
unicode_val_T unicode_fold_label_case(unicode_val_T); unicode_val_T unicode_fold_label_case(unicode_val_T);
inline int strlen_utf8(unsigned char **); inline int strlen_utf8(unsigned char **);
inline unicode_val_T utf8_to_unicode(unsigned char **, const unsigned char *);
unicode_val_T cp_to_unicode(int, unsigned char **, unsigned char *);
#endif /* CONFIG_UTF8 */ #endif /* CONFIG_UTF8 */
inline unicode_val_T utf8_to_unicode(unsigned char **, const unsigned char *);
unicode_val_T cp_to_unicode(int, unsigned char **, const unsigned char *);
#ifdef CONFIG_COMBINE #ifdef CONFIG_COMBINE
extern unicode_val_T last_combined; extern unicode_val_T last_combined;

View File

@ -61,7 +61,7 @@ extern int current_charset;
static inline void static inline void
intl_set_charset(struct terminal *term) intl_set_charset(struct terminal *term)
{ {
int new_charset = get_opt_codepage_tree(term->spec, "charset", NULL); int new_charset = get_terminal_codepage(term);
/* Prevent useless switching. */ /* Prevent useless switching. */
if (current_charset != new_charset) { if (current_charset != new_charset) {

View File

@ -303,7 +303,7 @@ get_window_title(void)
} }
void void
set_window_title(unsigned char *title) set_window_title(unsigned char *title, int codepage)
{ {
#ifndef DEBUG_OS2 #ifndef DEBUG_OS2
static PTIB tib; static PTIB tib;

View File

@ -407,73 +407,71 @@ set_clipboard_text(unsigned char *data)
/* Set xterm-like term window's title. */ /* Set xterm-like term window's title. */
void void
set_window_title(unsigned char *title) set_window_title(unsigned char *title, int codepage)
{ {
unsigned char *s; struct string filtered;
int xsize, ysize;
int j = 0;
#ifndef HAVE_SYS_CYGWIN_H #ifndef HAVE_SYS_CYGWIN_H
/* Check if we're in a xterm-like terminal. */ /* Check if we're in a xterm-like terminal. */
if (!is_xterm() && !is_gnuscreen()) return; if (!is_xterm() && !is_gnuscreen()) return;
#endif #endif
/* Retrieve terminal dimensions. */ if (!init_string(&filtered)) return;
get_terminal_size(0, &xsize, &ysize);
/* Check if terminal width is reasonnable. */ /* Copy title to filtered if different from NULL */
if (xsize < 1 || xsize > 1024) return;
/* Allocate space for title + 3 ending points + null char. */
s = mem_alloc(xsize + 3 + 1);
if (!s) return;
/* Copy title to s if different from NULL */
if (title) { if (title) {
int i; unsigned char *scan = title;
unsigned char *end = title + strlen(title);
/* We limit title length to terminal width and ignore control /* Remove control characters, so that they cannot
* chars if any. Note that in most cases window decoration * interfere with the command we send to the terminal.
* reduces printable width, so it's just a precaution. */ * However, do not attempt to limit the title length
* to terminal width, because the title is usually
* drawn in a different font anyway. */
/* Note that this is the right place where to do it, since /* Note that this is the right place where to do it, since
* potential alternative set_window_title() routines might * potential alternative set_window_title() routines might
* want to take different precautions. */ * want to take different precautions. */
for (i = 0; title[i] && i < xsize; i++) { for (;;) {
/* 0x80 .. 0x9f are ISO-8859-* control characters. unsigned char *charbegin = scan;
* In some other encodings they could be used for unicode_val_T unicode
* legitimate characters, though (ie. in Kamenicky). = cp_to_unicode(codepage, &scan, end);
* We should therefore maybe check for these only int charlen = scan - charbegin;
* if the terminal is running in an ISO- encoding. */
if (iscntrl(title[i]) || (title[i] & 0x7f) < 0x20 if (unicode == UCS_NO_CHAR)
|| title[i] == 0x7f) break;
/* This need not recognize all Unicode control
* characters. Only those that can make the
* terminal misparse the command. */
if (unicode < 0x20
|| (unicode >= 0x7F && unicode < 0xA0))
continue; continue;
s[j++] = title[i]; /* xterm entirely rejects 1024-byte or longer
* titles. */
if (filtered.length + charlen >= 1024 - 3) {
add_to_string(&filtered, "...");
break;
} }
/* If title is truncated, add "..." */ add_bytes_to_string(&filtered, charbegin, charlen);
if (i == xsize) {
s[j++] = '.';
s[j++] = '.';
s[j++] = '.';
} }
} }
s[j] = '\0';
/* Send terminal escape sequence + title string */ /* Send terminal escape sequence + title string */
printf("\033]0;%s\a", s); printf("\033]0;%s\a", filtered.source);
#if 0 #if 0
/* Miciah don't like this so it is disabled because it changes the /* Miciah don't like this so it is disabled because it changes the
* default window name. --jonas */ * default window name. --jonas */
/* Set the GNU screen window name */ /* Set the GNU screen window name */
if (is_gnuscreen()) if (is_gnuscreen())
printf("\033k%s\033\134", s); printf("\033k%s\033\134", filtered.source);
#endif #endif
fflush(stdout); fflush(stdout);
mem_free(s); done_string(&filtered);
} }
#ifdef HAVE_X11 #ifdef HAVE_X11

View File

@ -38,7 +38,7 @@ void resume_mouse(void *);
int start_thread(void (*)(void *, int), void *, int); int start_thread(void (*)(void *, int), void *, int);
unsigned char *get_clipboard_text(void); unsigned char *get_clipboard_text(void);
void set_clipboard_text(unsigned char *); void set_clipboard_text(unsigned char *);
void set_window_title(unsigned char *); void set_window_title(unsigned char *, int codepage);
unsigned char *get_window_title(void); unsigned char *get_window_title(void);
void block_stdin(void); void block_stdin(void);
void unblock_stdin(void); void unblock_stdin(void);

View File

@ -171,8 +171,7 @@ show_http_error_document(struct session *ses, void *data)
if (str) { if (str) {
/* The codepage that _("foo", term) used when it was /* The codepage that _("foo", term) used when it was
* called by get_http_error_document. */ * called by get_http_error_document. */
const int gettext_codepage const int gettext_codepage = get_terminal_codepage(term);
= get_opt_codepage_tree(term->spec, "charset", NULL);
if (cached) delete_entry_content(cache); if (cached) delete_entry_content(cache);

View File

@ -518,17 +518,23 @@ maybe_pre_format_html(struct cache_entry *cached, struct session *ses)
* were 0, it could then be freed, and the * were 0, it could then be freed, and the
* cached->preformatted assignment at the end of this function * cached->preformatted assignment at the end of this function
* would crash. Normally, the document has a reference to the * would crash. Normally, the document has a reference to the
* cache entry, and that suffices. If the following assertion * cache entry, and that suffices. However, if the cache
* ever fails, object_lock(cached) and object_unlock(cached) * entry was loaded to satisfy e.g. USEMAP="imgmap.html#map",
* must be added to this function. */ * then cached->object.refcount == 0 here, and must be
assert(cached->object.refcount > 0); * incremented.
if_assert_failed return; *
* cached->object.refcount == 0 is safe while the cache entry
* is being loaded, because garbage_collection() calls
* is_entry_used(), which checks whether any connection is
* using the cache entry. But loading has ended before this
* point. */
object_lock(cached);
fragment = get_cache_fragment(cached); fragment = get_cache_fragment(cached);
if (!fragment) return; if (!fragment) goto unlock_and_return;
/* We cannot do anything if the data are fragmented. */ /* We cannot do anything if the data are fragmented. */
if (!list_is_singleton(cached->frag)) return; if (!list_is_singleton(cached->frag)) goto unlock_and_return;
set_event_id(pre_format_html_event, "pre-format-html"); set_event_id(pre_format_html_event, "pre-format-html");
trigger_event(pre_format_html_event, ses, cached); trigger_event(pre_format_html_event, ses, cached);
@ -536,6 +542,9 @@ maybe_pre_format_html(struct cache_entry *cached, struct session *ses)
/* XXX: Keep this after the trigger_event, because hooks might call /* XXX: Keep this after the trigger_event, because hooks might call
* normalize_cache_entry()! */ * normalize_cache_entry()! */
cached->preformatted = 1; cached->preformatted = 1;
unlock_and_return:
object_unlock(cached);
} }
#endif #endif

View File

@ -388,7 +388,7 @@ ses_imgmap(struct session *ses)
&menu, &ml, ses->loading_uri, &menu, &ml, ses->loading_uri,
&doc_view->document->options, &doc_view->document->options,
ses->task.target.frame, ses->task.target.frame,
get_opt_codepage_tree(ses->tab->term->spec, "charset", NULL), get_terminal_codepage(ses->tab->term),
get_opt_codepage("document.codepage.assume", ses), get_opt_codepage("document.codepage.assume", ses),
get_opt_bool("document.codepage.force_assumed", ses))) get_opt_bool("document.codepage.force_assumed", ses)))
return; return;

View File

@ -149,8 +149,7 @@ term_send_ucs(struct terminal *term, unicode_val_T u,
const unsigned char *recoded; const unsigned char *recoded;
set_kbd_term_event(&ev, KBD_UNDEF, modifier); set_kbd_term_event(&ev, KBD_UNDEF, modifier);
recoded = u2cp_no_nbsp(u, get_opt_codepage_tree(term->spec, "charset", recoded = u2cp_no_nbsp(u, get_terminal_codepage(term));
NULL));
if (!recoded) recoded = "*"; if (!recoded) recoded = "*";
while (*recoded) { while (*recoded) {
ev.info.keyboard.key = *recoded; ev.info.keyboard.key = *recoded;
@ -186,8 +185,7 @@ check_terminal_name(struct terminal *term, struct terminal_info *info)
/* Probably not best place for set this. But now we finally have /* Probably not best place for set this. But now we finally have
* term->spec and term->utf8 should be set before decode session info. * term->spec and term->utf8 should be set before decode session info.
* --Scrool */ * --Scrool */
term->utf8_cp = is_cp_utf8(get_opt_codepage_tree(term->spec, term->utf8_cp = is_cp_utf8(get_terminal_codepage(term));
"charset", NULL));
/* Force UTF-8 I/O if the UTF-8 charset is selected. Various /* Force UTF-8 I/O if the UTF-8 charset is selected. Various
* places assume that the terminal's charset is unibyte if * places assume that the terminal's charset is unibyte if
* UTF-8 I/O is disabled. (bug 827) */ * UTF-8 I/O is disabled. (bug 827) */

View File

@ -101,6 +101,7 @@ struct itrm {
unsigned char *orig_title; /**< For restoring window title */ unsigned char *orig_title; /**< For restoring window title */
int verase; /**< Byte to map to KBD_BS, or -1 */ int verase; /**< Byte to map to KBD_BS, or -1 */
int title_codepage; /**< Codepage of terminal title */
unsigned int blocked:1; /**< Whether it was blocked */ unsigned int blocked:1; /**< Whether it was blocked */
unsigned int altscreen:1; /**< Whether to use alternate screen */ unsigned int altscreen:1; /**< Whether to use alternate screen */
unsigned int touched_title:1; /**< Whether the term title was changed */ unsigned int touched_title:1; /**< Whether the term title was changed */

View File

@ -331,6 +331,11 @@ handle_trm(int std_in, int std_out, int sock_in, int sock_out, int ctl_in,
itrm->timer = TIMER_ID_UNDEF; itrm->timer = TIMER_ID_UNDEF;
itrm->remote = !!remote; itrm->remote = !!remote;
/* If the master does not tell which charset it's using in
* this terminal, assume it's some ISO 8859. Because that's
* what older versions of ELinks did. */
itrm->title_codepage = get_cp_index("ISO-8859-1");
/* FIXME: Combination altscreen + xwin does not work as it should, /* FIXME: Combination altscreen + xwin does not work as it should,
* mouse clicks are reportedly partially ignored. */ * mouse clicks are reportedly partially ignored. */
if (info.system_env & (ENV_SCREEN | ENV_XWIN)) if (info.system_env & (ENV_SCREEN | ENV_XWIN))
@ -424,7 +429,7 @@ free_itrm(struct itrm *itrm)
if (!itrm->remote) { if (!itrm->remote) {
if (itrm->orig_title && *itrm->orig_title) { if (itrm->orig_title && *itrm->orig_title) {
set_window_title(itrm->orig_title); set_window_title(itrm->orig_title, itrm->title_codepage);
} else if (itrm->touched_title) { } else if (itrm->touched_title) {
/* Set the window title to the value of $TERM if X11 /* Set the window title to the value of $TERM if X11
@ -434,7 +439,8 @@ free_itrm(struct itrm *itrm)
get_terminal_name(title); get_terminal_name(title);
if (*title) if (*title)
set_window_title(title); set_window_title(title,
get_cp_index("US-ASCII"));
} }
@ -507,7 +513,12 @@ dispatch_special(unsigned char *text)
ditrm->orig_title = get_window_title(); ditrm->orig_title = get_window_title();
ditrm->touched_title = 1; ditrm->touched_title = 1;
} }
set_window_title(text + 1); /* TODO: Is it really possible to get here with
* ditrm == NULL, and which charset would then
* be most appropriate? */
set_window_title(text + 1,
ditrm ? ditrm->title_codepage
: get_cp_index("US-ASCII"));
break; break;
case TERM_FN_RESIZE: case TERM_FN_RESIZE:
if (ditrm && ditrm->remote) if (ditrm && ditrm->remote)
@ -515,6 +526,18 @@ dispatch_special(unsigned char *text)
resize_terminal_from_str(text + 1); resize_terminal_from_str(text + 1);
break; break;
case TERM_FN_TITLE_CODEPAGE:
if (ditrm) {
int cp = get_cp_index(text + 1);
/* If the master sends the name of an
* unrecognized charset, assume only
* that it's ASCII compatible. */
if (cp == -1)
cp = get_cp_index("US-ASCII");
ditrm->title_codepage = cp;
}
break;
} }
} }

View File

@ -118,6 +118,24 @@ init_term(int fdin, int fdout)
return term; return term;
} }
/** Get the codepage of a terminal. The UTF-8 I/O option does not
* affect this.
*
* @todo Perhaps cache the value in struct terminal?
*
* @bug Bug 1064: If the charset has been set as "System", this should
* apply the locale environment variables of the slave ELinks process,
* not those of the master ELinks process that parsed the configuration
* file. That is why the parameter points to struct terminal and not
* merely to its option tree (term->spec).
*
* @see get_translation_table(), get_cp_mime_name() */
int
get_terminal_codepage(const struct terminal *term)
{
return get_opt_codepage_tree(term->spec, "charset", NULL);
}
void void
redraw_all_terminals(void) redraw_all_terminals(void)
{ {
@ -371,12 +389,44 @@ do_terminal_function(struct terminal *term, unsigned char code,
fmem_free(x_data); fmem_free(x_data);
} }
void /** @return negative on error; zero or positive on success. */
int
set_terminal_title(struct terminal *term, unsigned char *title) set_terminal_title(struct terminal *term, unsigned char *title)
{ {
if (term->title && !strcmp(title, term->title)) return; int from_cp;
int to_cp;
unsigned char *converted = NULL;
if (term->title && !strcmp(title, term->title)) return 0;
/* In which codepage was the title parameter given? */
from_cp = get_terminal_codepage(term);
/* In which codepage does the terminal want the title? */
if (get_opt_bool_tree(term->spec, "latin1_title", NULL))
to_cp = get_cp_index("ISO-8859-1");
else if (get_opt_bool_tree(term->spec, "utf_8_io", NULL))
to_cp = get_cp_index("UTF-8");
else
to_cp = from_cp;
if (from_cp != to_cp) {
struct conv_table *convert_table;
convert_table = get_translation_table(from_cp, to_cp);
if (!convert_table) return -1;
converted = convert_string(convert_table, title, strlen(title),
to_cp, CSM_NONE, NULL, NULL, NULL);
if (!converted) return -1;
}
mem_free_set(&term->title, stracpy(title)); mem_free_set(&term->title, stracpy(title));
do_terminal_function(term, TERM_FN_TITLE, title); do_terminal_function(term, TERM_FN_TITLE_CODEPAGE,
get_cp_mime_name(to_cp));
do_terminal_function(term, TERM_FN_TITLE,
converted ? converted : title);
mem_free_if(converted);
return 0;
} }
static int terminal_pipe[2]; static int terminal_pipe[2];

View File

@ -179,6 +179,7 @@ void redraw_terminal(struct terminal *term);
void redraw_terminal_cls(struct terminal *term); void redraw_terminal_cls(struct terminal *term);
void cls_redraw_all_terminals(void); void cls_redraw_all_terminals(void);
struct terminal *get_default_terminal(void); struct terminal *get_default_terminal(void);
int get_terminal_codepage(const struct terminal *);
void redraw_all_terminals(void); void redraw_all_terminals(void);
void destroy_all_terminals(void); void destroy_all_terminals(void);
@ -191,12 +192,14 @@ void close_handle(void *);
void assert_terminal_ptr_not_dangling(const struct terminal *); void assert_terminal_ptr_not_dangling(const struct terminal *);
#endif #endif
/** Operations that can be requested with do_terminal_function(). /** Operations that can be requested with do_terminal_function() in
* the master and then executed with dispatch_special() in a slave.
* The interlink protocol passes these values as one byte in a * The interlink protocol passes these values as one byte in a
* null-terminated string, so zero cannot be used. */ * null-terminated string, so zero cannot be used. */
enum { enum {
TERM_FN_TITLE = 1, TERM_FN_TITLE = 1,
TERM_FN_RESIZE = 2 TERM_FN_RESIZE = 2,
TERM_FN_TITLE_CODEPAGE = 3
}; };
/** How to execute a program in a terminal. These values are used in /** How to execute a program in a terminal. These values are used in
@ -217,7 +220,7 @@ enum term_exec {
void exec_on_terminal(struct terminal *, unsigned char *, unsigned char *, enum term_exec); void exec_on_terminal(struct terminal *, unsigned char *, unsigned char *, enum term_exec);
void exec_shell(struct terminal *term); void exec_shell(struct terminal *term);
void set_terminal_title(struct terminal *, unsigned char *); int set_terminal_title(struct terminal *, unsigned char *);
void do_terminal_function(struct terminal *, unsigned char, unsigned char *); void do_terminal_function(struct terminal *, unsigned char, unsigned char *);
int check_terminal_pipes(void); int check_terminal_pipes(void);

View File

@ -313,21 +313,11 @@ add_cp_html_to_string(struct string *string, int src_codepage,
const unsigned char *const end = src + len; const unsigned char *const end = src + len;
unicode_val_T unicode; unicode_val_T unicode;
while (src != end) { for (;;) {
if (is_cp_utf8(src_codepage)) { unicode = cp_to_unicode(src_codepage,
#ifdef CONFIG_UTF8 (unsigned char **) &src, end);
unicode = utf8_to_unicode((unsigned char **) &src,
end);
if (unicode == UCS_NO_CHAR) if (unicode == UCS_NO_CHAR)
break; break;
#else /* !CONFIG_UTF8 */
/* Cannot parse UTF-8 without CONFIG_UTF8.
* Pretend the input is ISO-8859-1 instead. */
unicode = *src++;
#endif /* !CONFIG_UTF8 */
} else {
unicode = cp2u(src_codepage, *src++);
}
if (unicode < 0x20 || unicode >= 0x7F if (unicode < 0x20 || unicode >= 0x7F
|| unicode == '<' || unicode == '>' || unicode == '&' || unicode == '<' || unicode == '>' || unicode == '&'

View File

@ -177,7 +177,7 @@ init_form_state(struct document_view *doc_view,
doc_cp = doc_view->document->cp; doc_cp = doc_view->document->cp;
term = doc_view->session->tab->term; term = doc_view->session->tab->term;
viewer_cp = get_opt_codepage_tree(term->spec, "charset", NULL); viewer_cp = get_terminal_codepage(term);
mem_free_set(&fs->value, NULL); mem_free_set(&fs->value, NULL);
@ -1235,7 +1235,7 @@ get_form_uri(struct session *ses, struct document_view *doc_view,
get_successful_controls(doc_view, fc, &submit); get_successful_controls(doc_view, fc, &submit);
cp_from = get_opt_codepage_tree(ses->tab->term->spec, "charset", NULL); cp_from = get_terminal_codepage(ses->tab->term);
cp_to = doc_view->document->cp; cp_to = doc_view->document->cp;
switch (form->method) { switch (form->method) {
case FORM_METHOD_GET: case FORM_METHOD_GET:
@ -1868,9 +1868,7 @@ field_op(struct session *ses, struct document_view *doc_view,
#ifdef CONFIG_UTF8 #ifdef CONFIG_UTF8
/* fs->value is in the charset of the terminal. */ /* fs->value is in the charset of the terminal. */
ctext = u2cp_no_nbsp(get_kbd_key(ev), ctext = u2cp_no_nbsp(get_kbd_key(ev),
get_opt_codepage_tree(ses->tab->term->spec, get_terminal_codepage(ses->tab->term));
"charset",
NULL));
length = strlen(ctext); length = strlen(ctext);
if (strlen(fs->value) + length > fc->maxlength if (strlen(fs->value) + length > fc->maxlength

View File

@ -1214,8 +1214,7 @@ try_document_key(struct session *ses, struct document_view *doc_view,
#ifdef CONFIG_UTF8 #ifdef CONFIG_UTF8
key = get_kbd_key(ev); key = get_kbd_key(ev);
#else /* !CONFIG_UTF8 */ #else /* !CONFIG_UTF8 */
key = cp2u(get_opt_codepage_tree(ses->tab->term->spec, key = cp2u(get_terminal_codepage(ses->tab->term),
"charset", NULL),
get_kbd_key(ev)); get_kbd_key(ev));
#endif /* !CONFIG_UTF8 */ #endif /* !CONFIG_UTF8 */
/* If @key now is 0 (which is used in link.accesskey if there /* If @key now is 0 (which is used in link.accesskey if there

View File

@ -1169,6 +1169,7 @@ frame_ev_mouse(struct session *ses, struct document_view *doc_view, struct term_
enum frame_event_status status = FRAME_EVENT_REFRESH; enum frame_event_status status = FRAME_EVENT_REFRESH;
doc_view->vs->current_link = link - doc_view->document->links; doc_view->vs->current_link = link - doc_view->document->links;
ses->navigate_mode = NAVIGATE_LINKWISE;
if (!link_is_textinput(link)) { if (!link_is_textinput(link)) {

BIN
test/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,11 +1,11 @@
<html> <html>
<body> <body>
<IMG SRC="image.gif" ALT="ImageMap" USEMAP="#map"> <IMG SRC="image.png" ALT="ImageMap" USEMAP="#map">
<map name="map"> <map name="map">
<AREA SHAPE="rect" HREF="align.html" alt="1"> <AREA SHAPE="poly" COORDS="24,26, 30,30, 22,40, 15,35, 24,26" HREF="href_tests.html" alt="1">
<AREA SHAPE="rect" HREF="color.html" alt="2"> <AREA SHAPE="poly" COORDS="21,21, 38,10, 34,19, 39,29, 21,21" HREF="color.html" alt="2">
<AREA SHAPE="rect" HREF="underline.html" alt="3"> <AREA SHAPE="rect" COORDS="12,1, 30,18" HREF="underline.html" alt="3">
<AREA SHAPE="rect" HREF="poocs.net.html" name="91" alt="4"> <AREA SHAPE="circle" COORDS="9.5,22, 9" HREF="nbsp.html" name="91" alt="4">
</map> </map>
</body> </body>
</html> </html>

6
test/imgmap2.html Normal file
View File

@ -0,0 +1,6 @@
<TITLE>Crashes in client-side image maps</TITLE>
<P><IMG src="image.png" usemap="imgmap.html#map" alt="ImageMap"> in another file</P>
<P><IMG src="image.png" usemap="#at_eof" alt="ImageMap"> at the very end of this file</P>
<MAP name="at_eof">
<AREA shape="rect" coords="12,1, 30,18" href="http://elinks.cz/" alt="see this?">
<!-- no newline at the end of this line --></MAP>