1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-21 00:25:37 +00:00

Added configure option --enable-utf-8

For enabling better UTF-8 support by Witek and Scrool.
This commit is contained in:
Pavol Babincak 2006-02-03 00:27:01 +01:00 committed by Jonas Fonseca
parent 3ffa7cac91
commit f9d67aeb73
24 changed files with 591 additions and 48 deletions

View File

@ -155,6 +155,7 @@ CONFIG_SPIDERMONKEY = @CONFIG_SPIDERMONKEY@
CONFIG_SSL = @CONFIG_SSL@
CONFIG_SYSMOUSE = @CONFIG_SYSMOUSE@
CONFIG_URI_REWRITE = @CONFIG_URI_REWRITE@
CONFIG_UTF_8 = @CONFIG_UTF_8@
CONFIG_XBEL_BOOKMARKS = @CONFIG_XBEL_BOOKMARKS@
CONFIG_XMLTO = @CONFIG_XMLTO@

View File

@ -1257,6 +1257,10 @@ EL_ARG_ENABLE(CONFIG_OWN_LIBC, own-libc, [Own libc stubs],
EL_ARG_ENABLE(CONFIG_SMALL, small, [Small binary],
[ --enable-small reduce binary size as far as possible (but see the bottom of doc/small.txt!)])
EL_ARG_ENABLE(CONFIG_UTF_8, utf-8, [UTF-8],
[ --enable-utf-8 enable UTF-8 support])
AC_ARG_ENABLE(weehoofooboomookerchoo,
[
Also check out the features.conf file for more information about features!

View File

@ -167,6 +167,7 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
attr = get_opt_bool("ui.dialogs.underline_button_shortcuts")
? SCREEN_ATTR_UNDERLINE : 0;
#ifdef CONFIG_UTF_8
if (term->utf8) {
unsigned char *text2 = text;
unsigned char *end = text
@ -192,6 +193,7 @@ display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
}
len = x1 - !!hk_state;
} else
#endif /* CONFIG_UTF_8 */
if (hk_pos >= 0) {
int right = widget_data->widget->info.button.truetextlen - hk_pos - 1;

View File

@ -97,18 +97,25 @@ redraw_dialog(struct dialog_data *dlg_data, int layout)
title_color = get_bfu_color(term, "dialog.title");
if (title_color && box.width > 2) {
unsigned char *title = dlg_data->dlg->title;
#ifdef CONFIG_UTF_8
unsigned char *t2 = title;
int titlelen = strlen(title);
int len = term->utf8 ? strlen_utf8(&t2) : titlelen;
#if 1
len = int_min(box.width - 2, len);
#endif
int x = (box.width - len) / 2 + box.x;
#else
int titlelen = int_min(box.width - 2, strlen(title));
int x = (box.width - titlelen) / 2 + box.x;
#endif /* CONFIG_UTF_8 */
int y = box.y - 1;
draw_text(term, x - 1, y, " ", 1, 0, title_color);
draw_text(term, x, y, title, titlelen, 0, title_color);
#ifdef CONFIG_UTF_8
draw_text(term, x + len, y, " ", 1, 0, title_color);
#else
draw_text(term, x + titlelen, y, " ", 1, 0, title_color);
#endif /* CONFIG_UTF_8 */
}
}

View File

@ -266,8 +266,11 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data,
struct terminal *term = dlg_data->win->term;
struct color_pair *color;
int sel = is_selected_widget(dlg_data, widget_data);
#ifdef CONFIG_UTF_8
int len = 0, left = 0;
#endif /* CONFIG_UTF_8 */
#ifdef CONFIG_UTF_8
if (term->utf8) {
unsigned char *t = widget_data->cdata;
unsigned char *t2 = t;
@ -284,7 +287,9 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data,
}
t[p] = tmp;
widget_data->info.field.vpos = (int)(t2 - t);
} else {
} else
#endif /* CONFIG_UTF_8 */
{
int_bounds(&widget_data->info.field.vpos,
widget_data->info.field.cpos - widget_data->box.width + 1,
widget_data->info.field.cpos);
@ -298,26 +303,34 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data,
color = get_bfu_color(term, "dialog.field-text");
if (color) {
unsigned char *text = widget_data->cdata + widget_data->info.field.vpos;
#ifdef CONFIG_UTF_8
unsigned char *text2 = text;
int x, l, len, w;
#endif /* CONFIG_UTF_8 */
int len, w;
len = (term->utf8) ? strlen_utf8(&text2) : strlen(text);
#ifdef CONFIG_UTF_8
if (term->utf8)
len = strlen_utf8(&text2);
else
#endif /* CONFIG_UTF_8 */
len = strlen(text);
w = int_min(len, widget_data->box.width);
if (!hide) {
#ifdef CONFIG_UTF_8
int x;
if (term->utf8) {
int l;
for (l = 0, x = 0; x < w; x++)
l += utf8charlen(text+l);
w = l;
}
#endif /* CONFIG_UTF_8 */
draw_text(term, widget_data->box.x, widget_data->box.y,
text, w, 0, color);
} else {
struct box box;
if (term->utf8) len = strlen_utf8(&text);
w = int_min(len, widget_data->box.width);
copy_box(&box, &widget_data->box);
box.width = w;
@ -328,12 +341,13 @@ display_field_do(struct dialog_data *dlg_data, struct widget_data *widget_data,
if (sel) {
int x;
if (term->utf8) {
#ifdef CONFIG_UTF_8
if (term->utf8)
x = widget_data->box.x + len - left;
} else {
else
#endif /* CONFIG_UTF_8 */
x = widget_data->box.x + widget_data->info.field.cpos - widget_data->info.field.vpos;
}
set_cursor(term, x, widget_data->box.y, 0);
set_window_ptr(dlg_data->win, widget_data->box.x, widget_data->box.y);
}
@ -473,6 +487,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
case ACT_EDIT_RIGHT:
if (widget_data->info.field.cpos < strlen(widget_data->cdata)) {
#ifdef CONFIG_UTF_8
if (term->utf8) {
unsigned char *next = widget_data->cdata + widget_data->info.field.cpos;
unsigned char *end = strchr(next, '\0');
@ -480,13 +495,17 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
utf_8_to_unicode(&next, end);
widget_data->info.field.cpos = (int)(next - widget_data->cdata);
} else
#endif /* CONFIG_UTF_8 */
{
widget_data->info.field.cpos++;
}
}
goto display_field;
case ACT_EDIT_LEFT:
if (widget_data->info.field.cpos > 0)
widget_data->info.field.cpos--;
#ifdef CONFIG_UTF_8
if (widget_data->info.field.cpos && term->utf8) {
unsigned char *t = widget_data->cdata;
unsigned char *t2 = t;
@ -499,6 +518,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
widget_data->info.field.cpos = (int)(t2 - t);
}
#endif /* CONFIG_UTF_8 */
goto display_field;
case ACT_EDIT_HOME:
@ -510,6 +530,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
goto display_field;
case ACT_EDIT_BACKSPACE:
#ifdef CONFIG_UTF_8
if (widget_data->info.field.cpos && term->utf8) {
unsigned char *t = widget_data->cdata;
unsigned char *t2 = t;
@ -523,6 +544,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
widget_data->info.field.cpos = (int)(t2 - t);
goto display_field;
}
#endif /* CONFIG_UTF_8 */
if (widget_data->info.field.cpos) {
memmove(widget_data->cdata + widget_data->info.field.cpos - 1,
widget_data->cdata + widget_data->info.field.cpos,
@ -537,6 +559,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
if (widget_data->info.field.cpos >= cdata_len) goto display_field;
#ifdef CONFIG_UTF_8
if (term->utf8) {
unsigned char *next = widget_data->cdata + widget_data->info.field.cpos;
unsigned char *dest = next;
@ -546,6 +569,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
memmove(dest, next, strlen(next) + 1);
goto display_field;
}
#endif /* CONFIG_UTF_8 */
memmove(widget_data->cdata + widget_data->info.field.cpos,
widget_data->cdata + widget_data->info.field.cpos + 1,
cdata_len - widget_data->info.field.cpos + 1);
@ -627,6 +651,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
memmove(text + 1, text, textlen + 1);
*text = get_kbd_key(ev);
#ifdef CONFIG_UTF_8
if (term->utf8) {
static unsigned char buf[7];
unsigned char *t = buf;
@ -641,6 +666,7 @@ kbd_field(struct dialog_data *dlg_data, struct widget_data *widget_data)
return EVENT_PROCESSED;
else i = 0;
}
#endif /* CONFIG_UTF_8 */
goto display_field;
}
}

View File

@ -346,7 +346,6 @@ draw_menu_left_text_hk(struct terminal *term, unsigned char *text,
struct color_pair *hk_color_sel = get_bfu_color(term, "menu.hotkey.selected");
enum screen_char_attr hk_attr = get_opt_bool("ui.dialogs.underline_hotkeys")
? SCREEN_ATTR_UNDERLINE : 0;
unsigned char *text2, *end;
unsigned char c;
int xbase = x + L_TEXT_SPACE;
int w = width - (L_TEXT_SPACE + R_TEXT_SPACE);
@ -368,7 +367,10 @@ draw_menu_left_text_hk(struct terminal *term, unsigned char *text,
hk_color_sel = tmp;
}
#ifdef CONFIG_UTF_8
if (term->utf8) goto utf8;
#endif /* CONFIG_UTF_8 */
for (x = 0; x - !!hk_state < w && (c = text[x]); x++) {
if (!hk_state && x == hotkey_pos - 1) {
hk_state = 1;
@ -381,13 +383,15 @@ draw_menu_left_text_hk(struct terminal *term, unsigned char *text,
(double_hk ? hk_color_sel : hk_color));
#else
draw_char(term, xbase + x - 1, y, c, hk_attr, hk_color);
#endif
#endif /* CONFIG_DEBUG */
hk_state = 2;
} else {
draw_char(term, xbase + x - !!hk_state, y, c, 0, color);
}
}
return;
#ifdef CONFIG_UTF_8
unsigned char *text2, *end;
utf8:
end = strchr(text, '\0');
text2 = text;
@ -405,14 +409,14 @@ utf8:
(double_hk ? hk_color_sel : hk_color));
#else
draw_char(term, xbase + x - 1, y, data, hk_attr, hk_color);
#endif
#endif /* CONFIG_DEBUG */
hk_state = 2;
} else {
draw_char(term, xbase + x - !!hk_state, y, data, 0, color);
}
}
#endif /* CONFIG_UTF_8 */
}
static inline void

View File

@ -59,6 +59,9 @@ charset_list(struct terminal *term, void *xxx, void *ses_)
unsigned char *name = get_cp_name(i);
if (!name) break;
#ifndef CONFIG_UTF_8
if (is_cp_special(i)) continue;
#endif /* CONFIG_UTF_8 */
add_to_menu(&mi, name, NULL, ACT_MAIN_NONE,
display_codepage, get_cp_mime_name(i), 0);

View File

@ -250,8 +250,10 @@ render_dom_line(struct dom_renderer *renderer, struct screen_char *template,
struct document *document = renderer->document;
struct conv_table *convert = renderer->convert_table;
enum convert_string_mode mode = renderer->convert_mode;
#ifdef CONFIG_UTF_8
int utf8 = document->options.utf8;
unsigned char *end, *text;
#endif /* CONFIG_UTF_8 */
int x;
@ -268,7 +270,9 @@ render_dom_line(struct dom_renderer *renderer, struct screen_char *template,
add_search_node(renderer, length);
#ifdef CONFIG_UTF_8
if (utf8) goto utf_8;
#endif /* CONFIG_UTF_8 */
for (x = 0; x < length; x++, renderer->canvas_x++) {
unsigned char data = string[x];
@ -297,6 +301,7 @@ render_dom_line(struct dom_renderer *renderer, struct screen_char *template,
copy_screen_chars(POS(renderer), template, 1);
}
#ifdef CONFIG_UTF_8
goto end;
utf_8:
end = string + length;
@ -333,6 +338,7 @@ utf_8:
copy_screen_chars(POS(renderer), template, 1);
}
end:
#endif /* CONFIG_UTF_8 */
mem_free(string);
}
@ -1028,7 +1034,9 @@ render_dom_document(struct cache_entry *cached, struct document *document,
init_dom_renderer(&renderer, document, buffer, convert_table);
document->bgcolor = document->options.default_bg;
#ifdef CONFIG_UTF_8
document->options.utf8 = is_cp_special(document->options.cp);
#endif /* CONFIG_UTF_8 */
if (document->options.plain)
parser_type = SGML_PARSER_STREAM;

View File

@ -403,6 +403,7 @@ get_format_screen_char(struct html_context *html_context,
return &schar_cache;
}
#ifdef CONFIG_UTF_8
/* First possibly do the format change and then find out what coordinates
* to use since sub- or superscript might change them */
static inline int
@ -492,6 +493,48 @@ set_hline(struct html_context *html_context, unsigned char *chars, int charslen,
}
return len;
}
#else
/* First possibly do the format change and then find out what coordinates
* to use since sub- or superscript might change them */
static inline void
set_hline(struct html_context *html_context, unsigned char *chars, int charslen,
enum link_state link_state)
{
struct part *part = html_context->part;
struct screen_char *schar = get_format_screen_char(html_context,
link_state);
int x = part->cx;
int y = part->cy;
assert(part);
if_assert_failed return;
if (realloc_spaces(part, x + charslen))
return;
if (part->document) {
if (realloc_line(html_context, part->document,
Y(y), X(x) + charslen - 1))
return;
for (; charslen > 0; charslen--, x++, chars++) {
if (*chars == NBSP_CHAR) {
schar->data = ' ';
part->spaces[x] = html_context->options->wrap_nbsp;
} else {
part->spaces[x] = (*chars == ' ');
schar->data = *chars;
}
copy_screen_chars(&POS(x, y), schar, 1);
}
} else {
for (; charslen > 0; charslen--, x++, chars++) {
part->spaces[x] = (*chars == ' ');
}
}
}
#endif /* CONFIG_UTF_8 */
static void
move_links(struct html_context *html_context, int xf, int yf, int xt, int yt)
@ -1218,9 +1261,15 @@ done_link_state_info(void)
sizeof(renderer_context.link_state_info));
}
#ifdef CONFIG_UTF_8
static inline void
process_link(struct html_context *html_context, enum link_state link_state,
unsigned char *chars, int charslen, int utf8_len)
#else
static inline void
process_link(struct html_context *html_context, enum link_state link_state,
unsigned char *chars, int charslen)
#endif /* CONFIG_UTF_8 */
{
struct part *part = html_context->part;
struct link *link;
@ -1272,7 +1321,9 @@ process_link(struct html_context *html_context, enum link_state link_state,
if (x_offset) {
charslen -= x_offset;
chars += x_offset;
#ifdef CONFIG_UTF_8
utf8_len -= x_offset;
#endif /* CONFIG_UTF_8 */
}
link = new_link(html_context, chars, charslen);
@ -1287,14 +1338,24 @@ process_link(struct html_context *html_context, enum link_state link_state,
}
/* Add new canvas positions to the link. */
if (realloc_points(link, link->npoints + utf8_len)) {
#ifdef CONFIG_UTF_8
if (realloc_points(link, link->npoints + utf8_len))
#else
if (realloc_points(link, link->npoints + charslen))
#endif /* CONFIG_UTF_8 */
{
struct point *point = &link->points[link->npoints];
int x = X(part->cx) + x_offset;
int y = Y(part->cy);
#ifdef CONFIG_UTF_8
link->npoints += utf8_len;
for (; utf8_len > 0; utf8_len--, point++, x++) {
for (; utf8_len > 0; utf8_len--, point++, x++)
#else
for (; charslen > 0; charslen--, point++, x++)
#endif /* CONFIG_UTF_8 */
{
point->x = x;
point->y = y;
}
@ -1346,7 +1407,9 @@ put_chars(struct html_context *html_context, unsigned char *chars, int charslen)
enum link_state link_state;
int update_after_subscript = renderer_context.subscript;
struct part *part;
#ifdef CONFIG_UTF_8
int utf8_len;
#endif /* CONFIG_UTF_8 */
assert(html_context);
if_assert_failed return;
@ -1405,7 +1468,11 @@ put_chars(struct html_context *html_context, unsigned char *chars, int charslen)
else if (html_context->options->links_numbering)
put_link_number(html_context);
}
utf8_len = set_hline(html_context, chars, charslen, link_state);
#ifdef CONFIG_UTF_8
utf8_len =
#endif /* CONFIG_UTF_8 */
set_hline(html_context, chars, charslen, link_state);
if (link_state != LINK_STATE_NONE) {
#define is_drawing_subs_or_sups() \
@ -1425,15 +1492,29 @@ put_chars(struct html_context *html_context, unsigned char *chars, int charslen)
}
#undef is_drawing_subs_or_sups
#ifdef CONFIG_UTF_8
process_link(html_context, link_state, chars, charslen,
utf8_len);
#else
process_link(html_context, link_state, chars, charslen);
#endif /* CONFIG_UTF_8 */
}
#ifdef CONFIG_UTF_8
if (renderer_context.nowrap
&& part->cx + utf8_len > overlap(par_format))
return;
part->cx += utf8_len;
#else
if (renderer_context.nowrap
&& part->cx + charslen > overlap(par_format))
return;
part->cx += charslen;
#endif /* CONFIG_UTF_8 */
renderer_context.nobreak = 0;
if (!(html_context->options->wrap || html_is_preformatted())) {
@ -1449,7 +1530,11 @@ put_chars(struct html_context *html_context, unsigned char *chars, int charslen)
}
assert(charslen > 0);
#ifdef CONFIG_UTF_8
part->xa += utf8_len;
#else
part->xa += charslen;
#endif /* CONFIG_UTF_8 */
int_lower_bound(&part->max_width, part->xa
+ par_format.leftmargin + par_format.rightmargin
- (chars[charslen - 1] == ' '
@ -2013,7 +2098,9 @@ render_html_document(struct cache_entry *cached, struct document *document,
&document->cp,
&document->cp_status,
document->options.hard_assume);
#ifdef CONFIG_UTF_8
html_context->options->utf8 = is_cp_special(document->options.cp);
#endif /* CONFIG_UTF_8 */
if (title.length) {
document->title = convert_string(renderer_context.convert_table,

View File

@ -71,7 +71,9 @@ struct document_options {
unsigned int plain:1;
unsigned int wrap:1;
#ifdef CONFIG_UTF_8
unsigned int utf8:1;
#endif /* CONFIG_UTF_8 */
/* XXX: Everything past this comment is specialy handled by compare_opt() */
unsigned char *framename;

View File

@ -234,10 +234,12 @@ add_document_line(struct plain_renderer *renderer,
struct screen_char *template = &renderer->template;
struct screen_char saved_renderer_template = *template;
struct screen_char *pos, *startpos;
#ifdef CONFIG_UTF_8
unsigned char *end, *text;
int utf8 = document->options.utf8;
#endif /* CONFIG_UTF_8 */
int lineno = renderer->lineno;
int expanded = 0;
int utf8 = document->options.utf8;
int width = line_width;
int line_pos;
@ -278,7 +280,9 @@ add_document_line(struct plain_renderer *renderer,
assert(expanded >= 0);
#ifdef CONFIG_UTF_8
if (utf8) goto utf_8;
#endif /* CONFIG_UTF_8 */
startpos = pos = realloc_line(document, width + expanded, lineno);
if (!pos) {
mem_free(line);
@ -404,6 +408,7 @@ add_document_line(struct plain_renderer *renderer,
*template = saved_renderer_template;
}
}
#ifdef CONFIG_UTF_8
goto end;
utf_8:
end = line + width;
@ -537,6 +542,7 @@ utf_8:
}
}
end:
#endif /* CONFIG_UTF_8 */
mem_free(line);
realloc_line(document, pos - startpos, lineno);
@ -694,7 +700,9 @@ render_plain_document(struct cache_entry *cached, struct document *document,
document->bgcolor = document->options.default_bg;
document->width = 0;
#ifdef CONFIG_UTF_8
document->options.utf8 = is_cp_special(document->options.cp);
#endif /* CONFIG_UTF_8 */
/* Setup the style */
init_template(&renderer.template, &document->options);

View File

@ -143,8 +143,10 @@ u2cp_(unicode_val_T u, int to, int no_nbsp_hack)
to &= ~SYSTEM_CHARSET_FLAG;
#ifdef CONFIG_UTF_8
if (codepages[to].table == table_utf_8)
return encode_utf_8(u);
#endif /* CONFIG_UTF_8 */
/* To mark non breaking spaces, we use a special char NBSP_CHAR. */
if (u == 0xa0) return no_nbsp_hack ? " " : NBSP_CHAR_STRING;
@ -168,25 +170,15 @@ u2cp_(unicode_val_T u, int to, int no_nbsp_hack)
return no_str;
}
/* Number of bytes utf8 character indexed by first byte. Illegal bytes are
* equal ones and handled different. */
static char utf8char_len_tab[256] =
{
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,
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,
};
static unsigned char utf_buffer[7];
#ifdef CONFIG_UTF_8
inline unsigned char *
encode_utf_8(unicode_val_T u)
#else
static unsigned char *
encode_utf_8(unicode_val_T u)
#endif /* CONFIG_UTF_8 */
{
memset(utf_buffer, 0, 7);
@ -220,6 +212,21 @@ encode_utf_8(unicode_val_T u)
return utf_buffer;
}
#ifdef CONFIG_UTF_8
/* Number of bytes utf8 character indexed by first byte. Illegal bytes are
* equal ones and handled different. */
static char utf8char_len_tab[256] =
{
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,
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,
};
inline int utf8charlen(const unsigned char *p)
{
int len;
@ -297,6 +304,7 @@ utf_8_to_unicode(unsigned char **string, unsigned char *end)
*string = str + length;
return u > 0xffff ? '*' : u;
}
#endif /* CONFIG_UTF_8 */
/* This slow and ugly code is used by the terminal utf_8_io */
unsigned char *
@ -533,10 +541,12 @@ get_entity_string(const unsigned char *str, const int strlen, int encoding)
if (strlen <= 0) return NULL;
#ifdef CONFIG_UTF_8
/* TODO: caching UTF-8 */
encoding &= ~SYSTEM_CHARSET_FLAG;
if (codepages[encoding].table == table_utf_8)
goto skip;
#endif /* CONFIG_UTF_8 */
if (first_time) {
memset(&nb_entity_cache, 0, ENTITY_CACHE_MAXLEN * sizeof(unsigned int));
@ -591,7 +601,9 @@ get_entity_string(const unsigned char *str, const int strlen, int encoding)
fprintf(stderr, "miss\n");
#endif
}
#ifdef CONFIG_UTF_8
skip:
#endif /* CONFIG_UTF_8 */
if (*str == '#') { /* Numeric entity. */
int l = (int) strlen;
unsigned char *st = (unsigned char *) str;
@ -643,9 +655,11 @@ skip:
if (element) result = u2cp(element->c, encoding);
}
#ifdef CONFIG_UTF_8
if (codepages[encoding].table == table_utf_8) {
return result;
}
#endif /* CONFIG_UTF_8 */
end:
/* Take care of potential buffer overflow. */
if (strlen < sizeof(entity_cache[slen][0].str)) {

View File

@ -53,10 +53,12 @@ unsigned char *get_cp_name(int);
unsigned char *get_cp_mime_name(int);
int is_cp_special(int);
void free_conv_table(void);
#ifdef CONFIG_UTF_8
inline unsigned char *encode_utf_8(unicode_val_T);
inline int utf8charlen(const unsigned char *);
inline int strlen_utf8(unsigned char **);
inline unicode_val_T utf_8_to_unicode(unsigned char **, unsigned char *);
#endif /* CONFIG_UTF_8 */
unsigned char *cp2utf_8(int, int);

View File

@ -103,7 +103,11 @@ draw_char_color(struct terminal *term, int x, int y, struct color_pair *color)
}
void
#ifdef CONFIG_UTF_8
draw_char_data(struct terminal *term, int x, int y, uint16_t data)
#else
draw_char_data(struct terminal *term, int x, int y, unsigned char data)
#endif /* CONFIG_UTF_8 */
{
struct screen_char *screen_char = get_char(term, x, y);
@ -199,10 +203,17 @@ draw_border(struct terminal *term, struct box *box,
set_screen_dirty(term->screen, borderbox.y, borderbox.y + borderbox.height);
}
#ifdef CONFIG_UTF_8
void
draw_char(struct terminal *term, int x, int y,
uint16_t data, enum screen_char_attr attr,
struct color_pair *color)
#else
void
draw_char(struct terminal *term, int x, int y,
unsigned char data, enum screen_char_attr attr,
struct color_pair *color)
#endif /* CONFIG_UTF_8 */
{
struct screen_char *screen_char = get_char(term, x, y);
@ -278,6 +289,7 @@ draw_shadow(struct terminal *term, struct box *box,
draw_box(term, &dbox, ' ', 0, color);
}
#ifdef CONFIG_UTF_8
static void
draw_text_utf8(struct terminal *term, int x, int y,
unsigned char *text, int length,
@ -312,6 +324,7 @@ draw_text_utf8(struct terminal *term, int x, int y,
set_screen_dirty(term->screen, y, y);
}
#endif /* CONFIG_UTF_8 */
void
draw_text(struct terminal *term, int x, int y,
@ -324,10 +337,12 @@ draw_text(struct terminal *term, int x, int y,
assert(text && length >= 0);
if_assert_failed return;
#ifdef CONFIG_UTF_8
if (term->utf8) {
draw_text_utf8(term, x, y, text, length, attr, color);
return;
}
#endif /* CONFIG_UTF_8 */
if (length <= 0) return;
pos = get_char(term, x, y);

View File

@ -19,7 +19,11 @@ enum screen_char_attr {
/* One position in the terminal screen's image. */
struct screen_char {
/* Contains either character value or frame data. */
#ifdef CONFIG_UTF_8
uint16_t data;
#else
unsigned char data;
#endif /* CONFIG_UTF_8 */
/* Attributes are screen_char_attr bits. */
unsigned char attr;
@ -202,7 +206,11 @@ void draw_char_color(struct terminal *term, int x, int y,
struct color_pair *color);
/* Sets the data of a screen position. */
#ifdef CONFIG_UTF_8
void draw_char_data(struct terminal *term, int x, int y, uint16_t data);
#else
void draw_char_data(struct terminal *term, int x, int y, unsigned char data);
#endif /* CONFIG_UTF_8 */
/* Sets the data to @border and of a screen position. */
void draw_border_char(struct terminal *term, int x, int y,
@ -213,9 +221,15 @@ void draw_border_cross(struct terminal *, int x, int y,
enum border_cross_direction, struct color_pair *color);
/* Draws a char. */
#ifdef CONFIG_UTF_8
void draw_char(struct terminal *term, int x, int y,
uint16_t data, enum screen_char_attr attr,
struct color_pair *color);
#else
void draw_char(struct terminal *term, int x, int y,
unsigned char data, enum screen_char_attr attr,
struct color_pair *color);
#endif /* CONFIG_UTF_8 */
/* Draws area defined by @box using the same colors and attributes. */
void draw_box(struct terminal *term, struct box *box,

View File

@ -245,6 +245,9 @@ handle_interlink_event(struct terminal *term, struct term_event *ev)
case EVENT_KBD:
{
#ifndef CONFIG_UTF_8
int utf8_io = -1;
#endif /* CONFIG_UTF_8 */
int key = get_kbd_key(ev);
reset_timer();
@ -259,7 +262,13 @@ handle_interlink_event(struct terminal *term, struct term_event *ev)
}
if (interlink->utf_8.len) {
if ((key & 0xC0) == 0x80 && term->utf8) {
#ifdef CONFIG_UTF_8
if ((key & 0xC0) == 0x80 && term->utf8)
#else
utf8_io = get_opt_bool_tree(term->spec, "utf_8_io");
if ((key & 0xC0) == 0x80 && utf8_io)
#endif /* CONFIG_UTF_8 */
{
interlink->utf_8.ucs <<= 6;
interlink->utf_8.ucs |= key & 0x3F;
if (! --interlink->utf_8.len) {
@ -277,14 +286,19 @@ handle_interlink_event(struct terminal *term, struct term_event *ev)
}
}
if (key < 0x80 || key > 0xFF || !term->utf8) {
#ifdef CONFIG_UTF_8
if (key < 0x80 || key > 0xFF || !term->utf8)
#else
if (key < 0x80 || key > 0xFF
|| (utf8_io == -1
? !get_opt_bool_tree(term->spec, "utf_8_io")
: !utf8_io))
#endif /* CONFIG_UTF_8 */
{
term_send_event(term, ev);
break;
}
else if ((key & 0xC0) == 0xC0 && (key & 0xFE) != 0xFE) {
} else if ((key & 0xC0) == 0xC0 && (key & 0xFE) != 0xFE) {
unsigned int mask, cov = 0x80;
int len = 0;

View File

@ -30,7 +30,7 @@
unsigned char frame_dumb[48] = " ||||++||++++++--|-+||++--|-+----++++++++ ";
static unsigned char frame_vt100[48] = "aaaxuuukkuxkjjjkmvwtqnttmlvwtqnvvwwmmllnnjla ";
#if 0
#ifndef CONFIG_UTF_8
/* For UTF8 I/O */
static unsigned char frame_vt100_u[48] = {
177, 177, 177, 179, 180, 180, 180, 191,
@ -40,7 +40,7 @@ static unsigned char frame_vt100_u[48] = {
193, 194, 194, 192, 192, 218, 218, 197,
197, 217, 218, 177, 32, 32, 32, 32
};
#endif
#endif /* CONFIG_UTF_8 */
static unsigned char frame_freebsd[48] = {
130, 138, 128, 153, 150, 150, 150, 140,
@ -80,10 +80,12 @@ static struct string m11_hack_frame_seqs[] = {
/* begin border: */ TERM_STRING("\033[11m"),
};
#ifdef CONFIG_UTF_8
static struct string utf8_linux_frame_seqs[] = {
/* end border: */ TERM_STRING("\033[10m\033%G"),
/* begin border: */ TERM_STRING("\033%@\033[11m"),
};
#endif /* CONFIG_UTF_8 */
static struct string vt100_frame_seqs[] = {
/* end border: */ TERM_STRING("\x0f"),
@ -106,6 +108,13 @@ struct screen_driver {
* uniquely identify the screen_driver. */
enum term_mode_type type;
#ifndef CONFIG_UTF_8
/* Charsets when doing UTF8 I/O. */
/* [0] is the common charset and [1] is the frame charset.
* Test wether to use UTF8 I/O using the use_utf8_io() macro. */
int charsets[2];
#endif /* CONFIG_UTF_8 */
/* The frame translation table. May be NULL. */
unsigned char *frame;
@ -121,8 +130,10 @@ struct screen_driver {
/* These are directly derived from the terminal options. */
unsigned int transparent:1;
#ifdef CONFIG_UTF_8
/* UTF-8 I/O */
unsigned int utf8:1;
#endif /* CONFIG_UTF_8 */
/* The terminal._template_ name. */
unsigned char name[1]; /* XXX: Keep last! */
@ -131,56 +142,81 @@ struct screen_driver {
static struct screen_driver dumb_screen_driver = {
NULL_LIST_HEAD,
/* type: */ TERM_DUMB,
#ifndef CONFIG_UTF_8
/* charsets: */ { -1, -1 }, /* No UTF8 I/O */
#endif /* CONFIG_UTF_8 */
/* frame: */ frame_dumb,
/* frame_seqs: */ NULL,
/* underline: */ underline_seqs,
/* color_mode: */ COLOR_MODE_16,
/* transparent: */ 1,
#ifdef CONFIG_UTF_8
/* utf-8: */ 0,
#endif /* CONFIG_UTF_8 */
};
static struct screen_driver vt100_screen_driver = {
NULL_LIST_HEAD,
/* type: */ TERM_VT100,
#ifndef CONFIG_UTF_8
/* charsets: */ { -1, -1 }, /* No UTF8 I/O */
#endif /* CONFIG_UTF_8 */
/* frame: */ frame_vt100,
/* frame_seqs: */ vt100_frame_seqs,
/* underline: */ underline_seqs,
/* color_mode: */ COLOR_MODE_16,
/* transparent: */ 1,
#ifdef CONFIG_UTF_8
/* utf-8: */ 0,
#endif /* CONFIG_UTF_8 */
};
static struct screen_driver linux_screen_driver = {
NULL_LIST_HEAD,
/* type: */ TERM_LINUX,
#ifndef CONFIG_UTF_8
/* charsets: */ { -1, -1 }, /* No UTF8 I/O */
#endif /* CONFIG_UTF_8 */
/* frame: */ NULL, /* No restrict_852 */
/* frame_seqs: */ NULL, /* No m11_hack */
/* underline: */ underline_seqs,
/* color_mode: */ COLOR_MODE_16,
/* transparent: */ 1,
#ifdef CONFIG_UTF_8
/* utf-8: */ 0,
#endif /* CONFIG_UTF_8 */
};
static struct screen_driver koi8_screen_driver = {
NULL_LIST_HEAD,
/* type: */ TERM_KOI8,
#ifndef CONFIG_UTF_8
/* charsets: */ { -1, -1 }, /* No UTF8 I/O */
#endif /* CONFIG_UTF_8 */
/* frame: */ frame_koi,
/* frame_seqs: */ NULL,
/* underline: */ underline_seqs,
/* color_mode: */ COLOR_MODE_16,
/* transparent: */ 1,
#ifdef CONFIG_UTF_8
/* utf-8: */ 0,
#endif /* CONFIG_UTF_8 */
};
static struct screen_driver freebsd_screen_driver = {
NULL_LIST_HEAD,
/* type: */ TERM_FREEBSD,
#ifndef CONFIG_UTF_8
/* charsets: */ { -1, -1 }, /* No UTF8 I/O */
#endif /* CONFIG_UTF_8 */
/* frame: */ frame_freebsd,
/* frame_seqs: */ NULL, /* No m11_hack */
/* underline: */ underline_seqs,
/* color_mode: */ COLOR_MODE_16,
/* transparent: */ 1,
#ifdef CONFIG_UTF_8
/* utf-8: */ 0,
#endif /* CONFIG_UTF_8 */
};
/* XXX: Keep in sync with enum term_mode_type. */
@ -192,14 +228,22 @@ static struct screen_driver *screen_drivers[] = {
/* TERM_FREEBSD: */ &freebsd_screen_driver,
};
#ifdef CONFIG_UTF_8
#define use_utf8_io(driver) ((driver)->utf8)
#else
#define use_utf8_io(driver) ((driver)->charsets[0] != -1)
#endif /* CONFIG_UTF_8 */
static INIT_LIST_HEAD(active_screen_drivers);
static void
update_screen_driver(struct screen_driver *driver, struct option *term_spec)
{
#ifdef CONFIG_UTF_8
driver->utf8 = get_opt_bool_tree(term_spec, "utf_8_io");
#else
int utf8_io = get_opt_bool_tree(term_spec, "utf_8_io");
#endif /* CONFIG_UTF_8 */
driver->color_mode = get_opt_int_tree(term_spec, "colors");
driver->transparent = get_opt_bool_tree(term_spec, "transparency");
@ -210,6 +254,7 @@ update_screen_driver(struct screen_driver *driver, struct option *term_spec)
driver->underline = NULL;
}
#ifdef CONFIG_UTF_8
if (driver->type == TERM_LINUX) {
if (get_opt_bool_tree(term_spec, "restrict_852"))
driver->frame = frame_restrict;
@ -227,6 +272,46 @@ update_screen_driver(struct screen_driver *driver, struct option *term_spec)
} else if (driver->type == TERM_VT100) {
driver->frame = frame_vt100;
}
#else
if (utf8_io) {
driver->charsets[0] = get_opt_codepage_tree(term_spec, "charset");
if (driver->type == TERM_LINUX) {
if (get_opt_bool_tree(term_spec, "restrict_852"))
driver->frame = frame_restrict;
driver->charsets[1] = get_cp_index("cp437");
} else if (driver->type == TERM_FREEBSD) {
driver->charsets[1] = get_cp_index("cp437");
} else if (driver->type == TERM_VT100) {
driver->frame = frame_vt100_u;
driver->charsets[1] = get_cp_index("cp437");
} else if (driver->type == TERM_KOI8) {
driver->charsets[1] = get_cp_index("koi8-r");
} else {
driver->charsets[1] = driver->charsets[0];
}
} else {
driver->charsets[0] = -1;
if (driver->type == TERM_LINUX) {
if (get_opt_bool_tree(term_spec, "restrict_852"))
driver->frame = frame_restrict;
if (get_opt_bool_tree(term_spec, "m11_hack"))
driver->frame_seqs = m11_hack_frame_seqs;
} else if (driver->type == TERM_FREEBSD) {
if (get_opt_bool_tree(term_spec, "m11_hack"))
driver->frame_seqs = m11_hack_frame_seqs;
} else if (driver->type == TERM_VT100) {
driver->frame = frame_vt100;
}
}
#endif /* CONFIG_UTF_8 */
}
static int
@ -265,7 +350,9 @@ add_screen_driver(enum term_mode_type type, struct terminal *term, int env_len)
term->spec->change_hook = screen_driver_change_hook;
#ifdef CONFIG_UTF_8
term->utf8 = use_utf8_io(driver);
#endif /* CONFIG_UTF_8 */
return driver;
}
@ -285,7 +372,9 @@ get_screen_driver(struct terminal *term)
/* Some simple probably useless MRU ;) */
move_to_top_of_list(active_screen_drivers, driver);
#ifdef CONFIG_UTF_8
term->utf8 = use_utf8_io(driver);
#endif /* CONFIG_UTF_8 */
return driver;
}
@ -351,10 +440,15 @@ struct screen_state {
#define compare_bg_color(a, b) (TERM_COLOR_BACKGROUND(a) == TERM_COLOR_BACKGROUND(b))
#define compare_fg_color(a, b) (TERM_COLOR_FOREGROUND(a) == TERM_COLOR_FOREGROUND(b))
#ifdef CONFIG_UTF_8
static inline void
add_char_data(struct string *screen, struct screen_driver *driver,
unicode_val_T data, unsigned char border)
#else
static inline void
add_char_data(struct string *screen, struct screen_driver *driver,
unsigned char data, unsigned char border)
#endif /* CONFIG_UTF_8 */
{
if (!isscreensafe(data)) {
add_char_to_string(screen, ' ');
@ -365,11 +459,17 @@ add_char_data(struct string *screen, struct screen_driver *driver,
data = driver->frame[data - 176];
if (use_utf8_io(driver)) {
#ifdef CONFIG_UTF_8
if (border)
add_char_to_string(screen, (unsigned char)data);
else
if (data != UCS_NO_CHAR)
add_to_string(screen, encode_utf_8(data));
#else
int charset = driver->charsets[!!border];
add_to_string(screen, cp2utf_8(charset, data));
#endif /* CONFIG_UTF_8 */
return;
}

View File

@ -110,8 +110,10 @@ struct terminal {
* work and even maintaining these structures ;-). */
unsigned int master:1;
#ifdef CONFIG_UTF_8
/* Indicates whether UTF-8 I/O is used */
unsigned int utf8:1;
#endif /* CONFIG_UTF_8 */
/* The current tab number. */
int current_tab;

View File

@ -323,8 +323,10 @@ add_document_to_string(struct string *string, struct document *document)
assert(string && document);
if_assert_failed return NULL;
#ifdef CONFIG_UTF_8
if (is_cp_special(document->options.cp))
goto utf_8;
#endif /* CONFIG_UTF_8 */
for (y = 0; y < document->height; y++) {
int white = 0;
@ -358,6 +360,7 @@ add_document_to_string(struct string *string, struct document *document)
add_char_to_string(string, '\n');
}
#ifdef CONFIG_UTF_8
goto end;
utf_8:
for (y = 0; y < document->height; y++) {
@ -395,6 +398,7 @@ utf_8:
add_char_to_string(string, '\n');
}
end:
#endif /* CONFIG_UTF_8 */
return string;
}
@ -422,8 +426,10 @@ dump_to_file(struct document *document, int fd)
if (!buf) return -1;
#ifdef CONFIG_UTF_8
if (is_cp_special(document->options.cp))
goto utf_8;
#endif /* CONFIG_UTF_8 */
for (y = 0; y < document->height; y++) {
int white = 0;
@ -461,6 +467,7 @@ dump_to_file(struct document *document, int fd)
if (write_char('\n', fd, buf, &bptr))
goto fail;
}
#ifdef CONFIG_UTF_8
goto ref;
utf_8:
for (y = 0; y < document->height; y++) {
@ -508,13 +515,16 @@ utf_8:
if (write_char('\n', fd, buf, &bptr))
goto fail;
}
#endif /* CONFIG_UTF_8 */
if (hard_write(fd, buf, bptr) != bptr) {
fail:
mem_free(buf);
return -1;
}
#ifdef CONFIG_UTF_8
ref:
#endif /* CONFIG_UTF_8 */
if (document->nlinks && get_opt_bool("document.dump.references")) {
int x;
unsigned char *header = "\nReferences\n\n Visible links\n";

View File

@ -158,21 +158,27 @@ init_form_state(struct form_control *fc, struct form_state *fs)
mem_free_set(&fs->value, NULL);
switch (fc->type) {
#ifdef CONFIG_UTF_8
unsigned char *text;
#endif /* CONFIG_UTF_8 */
case FC_TEXT:
case FC_PASSWORD:
case FC_TEXTAREA:
fs->value = stracpy(fc->default_value);
fs->state = strlen(fc->default_value);
#ifdef CONFIG_UTF_8
text = fs->value;
fs->utf8_pos = strlen_utf8(&text);
#endif /* CONFIG_UTF_8 */
fs->vpos = 0;
break;
case FC_FILE:
fs->value = stracpy("");
fs->state = 0;
#ifdef CONFIG_UTF_8
fs->utf8_pos = 0;
#endif /* CONFIG_UTF_8 */
fs->vpos = 0;
break;
case FC_SELECT:
@ -335,14 +341,18 @@ draw_form_entry(struct terminal *term, struct document_view *doc_view,
dy = box->y - vs->y;
switch (fc->type) {
unsigned char *s;
#ifdef CONFIG_UTF_8
unsigned char *text, *end;
#endif /* CONFIG_UTF_8 */
int len;
int i, x, y;
case FC_TEXT:
case FC_PASSWORD:
case FC_FILE:
#ifdef CONFIG_UTF_8
if (term->utf8) goto utf_8;
#endif /* CONFIG_UTF_8 */
int_bounds(&fs->vpos, fs->state - fc->size + 1, fs->state);
if (!link->npoints) break;
@ -367,6 +377,7 @@ draw_form_entry(struct terminal *term, struct document_view *doc_view,
draw_char_data(term, x, y, data);
}
break;
#ifdef CONFIG_UTF_8
utf_8:
text = fs->value;
end = strchr(text, '\0');
@ -397,6 +408,7 @@ utf_8:
draw_char_data(term, x, y, data);
}
break;
#endif /* CONFIG_UTF_8 */
case FC_TEXTAREA:
draw_textarea(term, fs, doc_view, link);
break;
@ -415,7 +427,9 @@ utf_8:
else
/* XXX: when can this happen? --pasky */
s = "";
#ifdef CONFIG_UTF_8
if (term->utf8) goto utf_8_select;
#endif /* CONFIG_UTF_8 */
len = s ? strlen(s) : 0;
for (i = 0; i < link->npoints; i++) {
x = link->points[i].x + dx;
@ -424,6 +438,7 @@ utf_8:
draw_char_data(term, x, y, i < len ? s[i] : '_');
}
break;
#ifdef CONFIG_UTF_8
utf_8_select:
text = s;
end = strchr(s, '\0');
@ -436,6 +451,7 @@ utf_8_select:
? utf_8_to_unicode(&s, end) : '_');
}
break;
#endif /* CONFIG_UTF_8 */
case FC_SUBMIT:
case FC_IMAGE:
case FC_RESET:
@ -1245,7 +1261,9 @@ field_op(struct session *ses, struct document_view *doc_view,
unsigned char *text;
int length;
enum frame_event_status status = FRAME_EVENT_REFRESH;
#ifdef CONFIG_UTF_8
int utf8 = ses->tab->term->utf8;
#endif /* CONFIG_UTF_8 */
assert(ses && doc_view && link && ev);
if_assert_failed return FRAME_EVENT_OK;
@ -1265,6 +1283,7 @@ field_op(struct session *ses, struct document_view *doc_view,
switch (action_id) {
case ACT_EDIT_LEFT:
#ifdef CONFIG_UTF_8
if (utf8) {
unsigned char *text = fs->value;
unsigned char *end = fs->value + fs->state - 1;
@ -1274,9 +1293,11 @@ field_op(struct session *ses, struct document_view *doc_view,
fs->state = (int)(text - fs->value);
if (old != fs->state) fs->utf8_pos--;
} else
#endif /* CONFIG_UTF_8 */
fs->state = int_max(fs->state - 1, 0);
break;
case ACT_EDIT_RIGHT:
#ifdef CONFIG_UTF_8
if (utf8) {
unsigned char *text = fs->value + fs->state;
unsigned char *end = strchr(text, '\0');
@ -1286,58 +1307,91 @@ field_op(struct session *ses, struct document_view *doc_view,
fs->state = (int)(text - fs->value);
if (old != fs->state) fs->utf8_pos++;
} else
#endif /* CONFIG_UTF_8 */
fs->state = int_min(fs->state + 1, strlen(fs->value));
break;
case ACT_EDIT_HOME:
if (fc->type == FC_TEXTAREA) {
#ifdef CONFIG_UTF_8
status = textarea_op_home(fs, fc, utf8);
#else
status = textarea_op_home(fs, fc);
#endif /* CONFIG_UTF_8 */
} else {
fs->state = 0;
#ifdef CONFIG_UTF_8
fs->utf8_pos = 0;
#endif /* CONFIG_UTF_8 */
}
break;
case ACT_EDIT_UP:
if (fc->type != FC_TEXTAREA)
status = FRAME_EVENT_IGNORED;
else
#ifdef CONFIG_UTF_8
status = textarea_op_up(fs, fc, utf8);
#else
status = textarea_op_up(fs, fc);
#endif /* CONFIG_UTF_8 */
break;
case ACT_EDIT_DOWN:
if (fc->type != FC_TEXTAREA)
status = FRAME_EVENT_IGNORED;
else
#ifdef CONFIG_UTF_8
status = textarea_op_down(fs, fc, utf8);
#else
status = textarea_op_down(fs, fc);
#endif /* CONFIG_UTF_8 */
break;
case ACT_EDIT_END:
if (fc->type == FC_TEXTAREA) {
#ifdef CONFIG_UTF_8
status = textarea_op_end(fs, fc, utf8);
#else
status = textarea_op_end(fs, fc);
#endif /* CONFIG_UTF_8 */
} else {
fs->state = strlen(fs->value);
#ifdef CONFIG_UTF_8
if (utf8) {
unsigned char *text = fs->value;
fs->utf8_pos = strlen_utf8(&text);
}
#endif /* CONFIG_UTF_8 */
}
break;
case ACT_EDIT_BEGINNING_OF_BUFFER:
if (fc->type == FC_TEXTAREA) {
#ifdef CONFIG_UTF_8
status = textarea_op_bob(fs, fc, utf8);
#else
status = textarea_op_bob(fs, fc);
#endif /* CONFIG_UTF_8 */
} else {
fs->state = 0;
#ifdef CONFIG_UTF_8
fs->utf8_pos = 0;
#endif /* CONFIG_UTF_8 */
}
break;
case ACT_EDIT_END_OF_BUFFER:
if (fc->type == FC_TEXTAREA) {
#ifdef CONFIG_UTF_8
status = textarea_op_eob(fs, fc, utf8);
#else
status = textarea_op_eob(fs, fc);
#endif /* CONFIG_UTF_8 */
} else {
fs->state = strlen(fs->value);
#ifdef CONFIG_UTF_8
if (utf8) {
unsigned char *text = fs->value;
fs->utf8_pos = strlen_utf8(&text);
}
#endif /* CONFIG_UTF_8 */
}
break;
case ACT_EDIT_OPEN_EXTERNAL:
@ -1355,7 +1409,9 @@ field_op(struct session *ses, struct document_view *doc_view,
if (!form_field_is_readonly(fc))
fs->value[0] = 0;
fs->state = 0;
#ifdef CONFIG_UTF_8
fs->utf8_pos = 0;
#endif /* CONFIG_UTF_8 */
break;
case ACT_EDIT_PASTE_CLIPBOARD:
if (form_field_is_readonly(fc)) break;
@ -1371,19 +1427,24 @@ field_op(struct session *ses, struct document_view *doc_view,
fs->value = v;
memmove(v, text, length + 1);
fs->state = strlen(fs->value);
#ifdef CONFIG_UTF_8
if (utf8 && fc->type != FC_TEXTAREA) {
unsigned char *text = fs->value;
fs->utf8_pos = strlen_utf8(&text);
}
#endif /* CONFIG_UTF_8 */
}
}
mem_free(text);
break;
case ACT_EDIT_ENTER:
if (fc->type == FC_TEXTAREA) {
#ifdef CONFIG_UTF_8
status = textarea_op_enter(fs, fc, utf8);
#else
status = textarea_op_enter(fs, fc);
#endif /* CONFIG_UTF_8 */
break;
}
@ -1408,6 +1469,7 @@ field_op(struct session *ses, struct document_view *doc_view,
status = FRAME_EVENT_OK;
break;
}
#ifdef CONFIG_UTF_8
if (utf8) {
int i;
unsigned char *text = fs->value;
@ -1421,6 +1483,7 @@ field_op(struct session *ses, struct document_view *doc_view,
fs->utf8_pos--;
break;
}
#endif /* CONFIG_UTF_8 */
length = strlen(fs->value + fs->state) + 1;
text = fs->value + fs->state;
@ -1438,6 +1501,7 @@ field_op(struct session *ses, struct document_view *doc_view,
status = FRAME_EVENT_OK;
break;
}
#ifdef CONFIG_UTF_8
if (utf8) {
unsigned char *end = fs->value + length;
unsigned char *text = fs->value + fs->state;
@ -1450,6 +1514,7 @@ field_op(struct session *ses, struct document_view *doc_view,
}
break;
}
#endif /* CONFIG_UTF_8 */
text = fs->value + fs->state;
memmove(text, text + 1, length - fs->state);
@ -1479,11 +1544,13 @@ field_op(struct session *ses, struct document_view *doc_view,
memmove(text, fs->value + fs->state, length);
fs->state = (int) (text - fs->value);
#ifdef CONFIG_UTF_8
if (utf8 && fc->type != FC_TEXTAREA) {
unsigned char *text = fs->value;
fs->utf8_pos = strlen_utf8(&text);
}
#endif /* CONFIG_UTF_8 */
break;
case ACT_EDIT_KILL_TO_EOL:
if (form_field_is_readonly(fc)) {
@ -1537,10 +1604,16 @@ field_op(struct session *ses, struct document_view *doc_view,
}
if (form_field_is_readonly(fc)
|| strlen(fs->value) >= fc->maxlength) {
|| strlen(fs->value) >= fc->maxlength
#ifndef CONFIG_UTF_8
|| !insert_in_string(&fs->value, fs->state, "?", 1)
#endif /* CONFIG_UTF_8 */
)
{
status = FRAME_EVENT_OK;
break;
}
#ifdef CONFIG_UTF_8
if (utf8) {
static unsigned char buf[7];
static int i = 0;
@ -1572,6 +1645,9 @@ field_op(struct session *ses, struct document_view *doc_view,
return FRAME_EVENT_OK;
fs->value[fs->state++] = get_kbd_key(ev);
}
#else
fs->value[fs->state++] = get_kbd_key(ev);
#endif /* CONFIG_UTF_8 */
break;
}

View File

@ -39,7 +39,9 @@ struct form_state {
unsigned char *value;
int state;
#ifdef CONFIG_UTF_8
int utf8_pos;
#endif /* CONFIG_UTF_8 */
int vpos;
int vypos;

View File

@ -112,7 +112,9 @@ get_link_cursor_offset(struct document_view *doc_view, struct link *link)
{
struct form_control *fc;
struct form_state *fs;
#ifdef CONFIG_UTF_8
int utf8 = doc_view->document->options.utf8;
#endif /* CONFIG_UTF_8 */
switch (link->type) {
case LINK_CHECKBOX:
@ -124,15 +126,21 @@ get_link_cursor_offset(struct document_view *doc_view, struct link *link)
case LINK_FIELD:
fc = get_link_form_control(link);
fs = find_form_state(doc_view, fc);
#ifdef CONFIG_UTF_8
if (utf8) {
return fs ? fs->utf8_pos - fs->vpos : 0;
} else
#endif /* CONFIG_UTF_8 */
return fs ? fs->state - fs->vpos : 0;
case LINK_AREA:
fc = get_link_form_control(link);
fs = find_form_state(doc_view, fc);
#ifdef CONFIG_UTF_8
return fs ? area_cursor(fc, fs, utf8) : 0;
#else
return fs ? area_cursor(fc, fs) : 0;
#endif /* CONFIG_UTF_8 */
case LINK_HYPERTEXT:
case LINK_MAP:

View File

@ -47,6 +47,7 @@ struct line_info {
#define realloc_line_info(info, size) \
mem_align_alloc(info, size, (size) + 3, 0xFF)
#ifdef CONFIG_UTF_8
/* Allocates a line_info table describing the layout of the textarea buffer.
*
* @width is max width and the offset at which text will be wrapped
@ -117,6 +118,7 @@ format_textutf8(unsigned char *text, int width, enum form_wrap wrap, int format)
return line;
}
#endif /* CONFIG_UTF_8 */
/* Allocates a line_info table describing the layout of the textarea buffer.
*
@ -209,7 +211,11 @@ get_textarea_line_number(struct line_info *line, int cursor_position)
/* Fixes up the vpos and vypos members of the form_state. Returns the
* logical position in the textarea view. */
int
#ifdef CONFIG_UTF_8
area_cursor(struct form_control *fc, struct form_state *fs, int utf8)
#else
area_cursor(struct form_control *fc, struct form_state *fs)
#endif /* CONFIG_UTF_8 */
{
struct line_info *line;
int x, y;
@ -217,9 +223,11 @@ area_cursor(struct form_control *fc, struct form_state *fs, int utf8)
assert(fc && fs);
if_assert_failed return 0;
#ifdef CONFIG_UTF_8
if (utf8)
line = format_textutf8(fs->value, fc->cols, fc->wrap, 0);
else
#endif /* CONFIG_UTF_8 */
line = format_text(fs->value, fc->cols, fc->wrap, 0);
if (!line) return 0;
@ -228,7 +236,7 @@ area_cursor(struct form_control *fc, struct form_state *fs, int utf8)
mem_free(line);
return 0;
}
#ifdef CONFIG_UTF_8
if (utf8) {
unsigned char *text = fs->value + line[y].start;
unsigned char tmp = fs->value[fs->state];
@ -237,6 +245,7 @@ area_cursor(struct form_control *fc, struct form_state *fs, int utf8)
x = strlen_utf8(&text);
fs->value[fs->state] = tmp;
} else
#endif /* CONFIG_UTF_8 */
x = fs->state - line[y].start;
mem_free(line);
@ -252,6 +261,7 @@ area_cursor(struct form_control *fc, struct form_state *fs, int utf8)
return y * fc->cols + x;
}
#ifdef CONFIG_UTF_8
static void
draw_textarea_utf8(struct terminal *term, struct form_state *fs,
struct document_view *doc_view, struct link *link)
@ -329,7 +339,7 @@ draw_textarea_utf8(struct terminal *term, struct form_state *fs,
mem_free(linex);
}
#endif /* CONFIG_UTF_8 */
void
draw_textarea(struct terminal *term, struct form_state *fs,
@ -345,10 +355,12 @@ draw_textarea(struct terminal *term, struct form_state *fs,
assert(term && doc_view && doc_view->document && doc_view->vs && link);
if_assert_failed return;
#ifdef CONFIG_UTF_8
if (term->utf8) {
draw_textarea_utf8(term, fs, doc_view, link);
return;
}
#endif /* CONFIG_UTF_8 */
fc = get_link_form_control(link);
assertm(fc, "link %d has no form control", (int) (link - doc_view->document->links));
if_assert_failed return;
@ -358,7 +370,11 @@ draw_textarea(struct terminal *term, struct form_state *fs,
vy = doc_view->vs->y;
if (!link->npoints) return;
#ifdef CONFIG_UTF_8
area_cursor(fc, fs, 0);
#else
area_cursor(fc, fs);
#endif /* CONFIG_UTF_8 */
linex = format_text(fs->value, fc->cols, fc->wrap, 0);
if (!linex) return;
line = linex;
@ -615,8 +631,13 @@ menu_textarea_edit(struct terminal *term, void *xxx, void *ses_)
}
static enum frame_event_status
#ifdef CONFIG_UTF_8
textarea_op(struct form_state *fs, struct form_control *fc, int utf8,
int (*do_op)(struct form_state *, struct line_info *, int, int))
#else
textarea_op(struct form_state *fs, struct form_control *fc,
int (*do_op)(struct form_state *, struct line_info *, int))
#endif /* CONFIG_UTF_8 */
{
struct line_info *line;
int current, state;
@ -624,15 +645,22 @@ textarea_op(struct form_state *fs, struct form_control *fc, int utf8,
assert(fs && fs->value && fc);
if_assert_failed return FRAME_EVENT_OK;
#ifdef CONFIG_UTF_8
if (utf8)
line = format_textutf8(fs->value, fc->cols, fc->wrap, 0);
else
#endif /* CONFIG_UTF_8 */
line = format_text(fs->value, fc->cols, fc->wrap, 0);
if (!line) return FRAME_EVENT_OK;
current = get_textarea_line_number(line, fs->state);
state = fs->state;
if (do_op(fs, line, current, utf8)) {
#ifdef CONFIG_UTF_8
if (do_op(fs, line, current, utf8))
#else
if (do_op(fs, line, current))
#endif /* CONFIG_UTF_8 */
{
mem_free(line);
return FRAME_EVENT_IGNORED;
}
@ -641,6 +669,7 @@ textarea_op(struct form_state *fs, struct form_control *fc, int utf8,
return fs->state == state ? FRAME_EVENT_OK : FRAME_EVENT_REFRESH;
}
#ifdef CONFIG_UTF_8
static int
x_pos(struct form_state *fs, struct line_info *line, int current)
{
@ -668,26 +697,37 @@ new_pos(struct form_state *fs, struct line_info *line, int current, int len)
}
fs->state = (int)(text - fs->value);
}
#endif /* CONFIG_UTF_8 */
static int
#ifdef CONFIG_UTF_8
do_op_home(struct form_state *fs, struct line_info *line, int current, int utf8)
#else
do_op_home(struct form_state *fs, struct line_info *line, int current)
#endif /* CONFIG_UTF_8 */
{
if (current != -1) fs->state = line[current].start;
return 0;
}
static int
#ifdef CONFIG_UTF_8
do_op_up(struct form_state *fs, struct line_info *line, int current, int utf8)
#else
do_op_up(struct form_state *fs, struct line_info *line, int current)
#endif /* CONFIG_UTF_8 */
{
if (current == -1) return 0;
if (!current) return 1;
#ifdef CONFIG_UTF_8
if (utf8) {
int len = x_pos(fs, line, current);
new_pos(fs, line, current - 1, len);
return 0;
}
#endif /* CONFIG_UTF_8 */
fs->state -= line[current].start - line[current-1].start;
int_upper_bound(&fs->state, line[current-1].end);
@ -695,24 +735,35 @@ do_op_up(struct form_state *fs, struct line_info *line, int current, int utf8)
}
static int
#ifdef CONFIG_UTF_8
do_op_down(struct form_state *fs, struct line_info *line, int current, int utf8)
#else
do_op_down(struct form_state *fs, struct line_info *line, int current)
#endif /* CONFIG_UTF_8 */
{
if (current == -1) return 0;
if (line[current+1].start == -1) return 1;
#ifdef CONFIG_UTF_8
if (utf8) {
int len = x_pos(fs, line, current);
new_pos(fs, line, current + 1, len);
return 0;
}
#endif /* CONFIG_UTF_8 */
fs->state += line[current+1].start - line[current].start;
int_upper_bound(&fs->state, line[current+1].end);
return 0;
}
static int
#ifdef CONFIG_UTF_8
do_op_end(struct form_state *fs, struct line_info *line, int current, int utf8)
#else
do_op_end(struct form_state *fs, struct line_info *line, int current)
#endif /* CONFIG_UTF_8 */
{
if (current == -1) {
fs->state = strlen(fs->value);
@ -727,7 +778,11 @@ do_op_end(struct form_state *fs, struct line_info *line, int current, int utf8)
}
static int
#ifdef CONFIG_UTF_8
do_op_bob(struct form_state *fs, struct line_info *line, int current, int utf8)
#else
do_op_bob(struct form_state *fs, struct line_info *line, int current)
#endif /* CONFIG_UTF_8 */
{
if (current == -1) return 0;
@ -737,7 +792,11 @@ do_op_bob(struct form_state *fs, struct line_info *line, int current, int utf8)
}
static int
#ifdef CONFIG_UTF_8
do_op_eob(struct form_state *fs, struct line_info *line, int current, int utf8)
#else
do_op_eob(struct form_state *fs, struct line_info *line, int current)
#endif /* CONFIG_UTF_8 */
{
if (current == -1) {
fs->state = strlen(fs->value);
@ -753,50 +812,102 @@ do_op_eob(struct form_state *fs, struct line_info *line, int current, int utf8)
return 0;
}
#ifdef CONFIG_UTF_8
enum frame_event_status
textarea_op_home(struct form_state *fs, struct form_control *fc, int utf8)
{
return textarea_op(fs, fc, utf8, do_op_home);
}
#else
enum frame_event_status
textarea_op_home(struct form_state *fs, struct form_control *fc)
{
return textarea_op(fs, fc, do_op_home);
}
#endif /* CONFIG_UTF_8 */
#ifdef CONFIG_UTF_8
enum frame_event_status
textarea_op_up(struct form_state *fs, struct form_control *fc, int utf8)
{
return textarea_op(fs, fc, utf8, do_op_up);
}
#else
enum frame_event_status
textarea_op_up(struct form_state *fs, struct form_control *fc)
{
return textarea_op(fs, fc, do_op_up);
}
#endif /* CONFIG_UTF_8 */
#ifdef CONFIG_UTF_8
enum frame_event_status
textarea_op_down(struct form_state *fs, struct form_control *fc, int utf8)
{
return textarea_op(fs, fc, utf8, do_op_down);
}
#else
enum frame_event_status
textarea_op_down(struct form_state *fs, struct form_control *fc)
{
return textarea_op(fs, fc, do_op_down);
}
#endif /* CONFIG_UTF_8 */
#ifdef CONFIG_UTF_8
enum frame_event_status
textarea_op_end(struct form_state *fs, struct form_control *fc, int utf8)
{
return textarea_op(fs, fc, utf8, do_op_end);
}
#else
enum frame_event_status
textarea_op_end(struct form_state *fs, struct form_control *fc)
{
return textarea_op(fs, fc, do_op_end);
}
#endif /* CONFIG_UTF_8 */
/* Set the form state so the cursor is on the first line of the buffer.
* Preserve the column if possible. */
#ifdef CONFIG_UTF_8
enum frame_event_status
textarea_op_bob(struct form_state *fs, struct form_control *fc, int utf8)
{
return textarea_op(fs, fc, utf8, do_op_bob);
}
#else
enum frame_event_status
textarea_op_bob(struct form_state *fs, struct form_control *fc)
{
return textarea_op(fs, fc, do_op_bob);
}
#endif /* CONFIG_UTF_8 */
/* Set the form state so the cursor is on the last line of the buffer. Preserve
* the column if possible. This is done by getting current and last line and
* then shifting the state by the delta of both lines start position bounding
* the whole thing to the end of the last line. */
#ifdef CONFIG_UTF_8
enum frame_event_status
textarea_op_eob(struct form_state *fs, struct form_control *fc, int utf8)
{
return textarea_op(fs, fc, utf8, do_op_eob);
}
#else
enum frame_event_status
textarea_op_eob(struct form_state *fs, struct form_control *fc)
{
return textarea_op(fs, fc, do_op_eob);
}
#endif /* CONFIG_UTF_8 */
enum frame_event_status
#ifdef CONFIG_UTF_8
textarea_op_enter(struct form_state *fs, struct form_control *fc, int utf8)
#else
textarea_op_enter(struct form_state *fs, struct form_control *fc)
#endif /* CONFIG_UTF_8 */
{
assert(fs && fs->value && fc);
if_assert_failed return FRAME_EVENT_OK;
@ -817,7 +928,9 @@ set_textarea(struct document_view *doc_view, int direction)
struct form_control *fc;
struct form_state *fs;
struct link *link;
#ifdef CONFIG_UTF_8
int utf8 = doc_view->document->options.utf8;
#endif /* CONFIG_UTF_8 */
assert(doc_view && doc_view->vs && doc_view->document);
assert(direction == 1 || direction == -1);
@ -838,8 +951,15 @@ set_textarea(struct document_view *doc_view, int direction)
/* Depending on which way we entered the textarea move cursor so that
* it is available at end or start. */
#ifdef CONFIG_UTF_8
if (direction == 1)
textarea_op_eob(fs, fc, utf8);
else
textarea_op_bob(fs, fc, utf8);
#else
if (direction == 1)
textarea_op_eob(fs, fc);
else
textarea_op_bob(fs, fc);
#endif /* CONFIG_UTF_8 */
}

View File

@ -13,7 +13,11 @@ struct link;
struct session;
struct terminal;
#ifdef CONFIG_UTF_8
int area_cursor(struct form_control *fc, struct form_state *fs, int utf8);
#else
int area_cursor(struct form_control *fc, struct form_state *fs);
#endif /* CONFIG_UTF_8 */
void draw_textarea(struct terminal *term, struct form_state *fs, struct document_view *doc_view, struct link *link);
unsigned char *encode_textarea(struct submitted_value *sv);
@ -21,6 +25,7 @@ extern int textarea_editor;
void textarea_edit(int, struct terminal *, struct form_state *, struct document_view *, struct link *);
void menu_textarea_edit(struct terminal *term, void *xxx, void *ses_);
#ifdef CONFIG_UTF_8
enum frame_event_status textarea_op_home(struct form_state *fs, struct form_control *fc, int utf8);
enum frame_event_status textarea_op_up(struct form_state *fs, struct form_control *fc, int utf8);
enum frame_event_status textarea_op_down(struct form_state *fs, struct form_control *fc, int utf8);
@ -28,6 +33,15 @@ enum frame_event_status textarea_op_end(struct form_state *fs, struct form_contr
enum frame_event_status textarea_op_bob(struct form_state *fs, struct form_control *fc, int utf8);
enum frame_event_status textarea_op_eob(struct form_state *fs, struct form_control *fc, int utf8);
enum frame_event_status textarea_op_enter(struct form_state *fs, struct form_control *fc, int utf8);
#else
enum frame_event_status textarea_op_home(struct form_state *fs, struct form_control *fc);
enum frame_event_status textarea_op_up(struct form_state *fs, struct form_control *fc);
enum frame_event_status textarea_op_down(struct form_state *fs, struct form_control *fc);
enum frame_event_status textarea_op_end(struct form_state *fs, struct form_control *fc);
enum frame_event_status textarea_op_bob(struct form_state *fs, struct form_control *fc);
enum frame_event_status textarea_op_eob(struct form_state *fs, struct form_control *fc);
enum frame_event_status textarea_op_enter(struct form_state *fs, struct form_control *fc);
#endif /* CONFIG_UTF_8 */
void set_textarea(struct document_view *doc_view, int direction);