From 1fb37740bfa0a5855477b574756465f800d11881 Mon Sep 17 00:00:00 2001 From: Jindrich Novy Date: Thu, 23 Oct 2008 13:24:00 +0000 Subject: [PATCH] - allow switching of trailing spaces/tab highlighting with crtl-v, patch from Jan Engelhardt (#464738) - update the UTF-8 patch accordingly --- mc-cedit-configurable-highlight.patch | 363 ++ mc-utf8.patch | 7769 ++++++++++++------------- mc.spec | 9 +- 3 files changed, 4243 insertions(+), 3898 deletions(-) create mode 100644 mc-cedit-configurable-highlight.patch diff --git a/mc-cedit-configurable-highlight.patch b/mc-cedit-configurable-highlight.patch new file mode 100644 index 0000000..99c8160 --- /dev/null +++ b/mc-cedit-configurable-highlight.patch @@ -0,0 +1,363 @@ + +Move syntax highlighting options into their own menu, and make TAB and +Whitespace highlighting selectable. + +Signed-off-by: Jan Engelhardt + +--- + edit/edit.c | 6 ++ + edit/edit.h | 7 ++ + edit/editcmddef.h | 1 + edit/editdraw.c | 4 + + edit/editkeys.c | 1 + edit/editmenu.c | 6 ++ + edit/editoptions.c | 141 ++++++++++++++++++++++++++++++++++++++++------------- + src/setup.c | 1 + 8 files changed, 133 insertions(+), 34 deletions(-) + +Index: mc/edit/edit.c +=================================================================== +--- mc.orig/edit/edit.c ++++ mc/edit/edit.c +@@ -2487,6 +2487,12 @@ edit_execute_cmd (WEdit *edit, int comma + edit->force |= REDRAW_PAGE; + break; + ++ case CK_Toggle_Syntax2: ++ ++option_highlighting; ++ option_highlighting %= 4; ++ edit->force |= REDRAW_PAGE; ++ break; ++ + case CK_Find: + edit_search_cmd (edit, 0); + break; +Index: mc/edit/edit.h +=================================================================== +--- mc.orig/edit/edit.h ++++ mc/edit/edit.h +@@ -228,6 +228,7 @@ int line_is_blank (WEdit *edit, long lin + int edit_indent_width (WEdit *edit, long p); + void edit_insert_indent (WEdit *edit, int indent); + void edit_options_dialog (void); ++void edit_syntax_opt_dialog(void); + void edit_syntax_dialog (void); + void edit_mail_dialog (WEdit *edit); + void format_paragraph (WEdit *edit, int force); +@@ -279,10 +280,16 @@ typedef enum { + EDIT_DO_BACKUP + } edit_save_mode_t; + ++enum { ++ HL_WHITESPACE = 1 << 0, ++ HL_TABS = 1 << 1, ++}; ++ + extern int option_save_mode; + extern int option_save_position; + extern int option_max_undo; + extern int option_syntax_highlighting; ++extern unsigned int option_highlighting; + extern int option_auto_syntax; + extern char *option_syntax_type; + extern int editor_option_check_nl_at_eof; +Index: mc/edit/editcmddef.h +=================================================================== +--- mc.orig/edit/editcmddef.h ++++ mc/edit/editcmddef.h +@@ -109,6 +109,7 @@ + #define CK_Maximize 458 + + #define CK_Toggle_Syntax 480 ++#define CK_Toggle_Syntax2 481 + + /* macro */ + #define CK_Begin_Record_Macro 501 +Index: mc/edit/editdraw.c +=================================================================== +--- mc.orig/edit/editdraw.c ++++ mc/edit/editdraw.c +@@ -273,7 +273,9 @@ print_to_widget (WEdit *edit, long row, + } + } + +-int visible_tabs = 1, visible_tws = 1; ++unsigned int option_highlighting = HL_TABS | HL_WHITESPACE; ++#define visible_tabs (option_highlighting & HL_TABS) ++#define visible_tws (option_highlighting & HL_WHITESPACE) + + /* b is a pointer to the beginning of the line */ + static void +Index: mc/edit/editkeys.c +=================================================================== +--- mc.orig/edit/editkeys.c ++++ mc/edit/editkeys.c +@@ -114,6 +114,7 @@ static const edit_key_map_type common_ke + { XCTRL ('l'), CK_Refresh }, + { XCTRL ('o'), CK_Shell }, + { XCTRL ('s'), CK_Toggle_Syntax }, ++ { XCTRL ('v'), CK_Toggle_Syntax2 }, + { XCTRL ('u'), CK_Undo }, + { XCTRL ('t'), CK_Select_Codepage }, + { XCTRL ('q'), CK_Insert_Literal }, +Index: mc/edit/editmenu.c +=================================================================== +--- mc.orig/edit/editmenu.c ++++ mc/edit/editmenu.c +@@ -283,6 +283,11 @@ menu_options (void) + edit_options_dialog (); + } + ++static void menu_syntax_options(void) ++{ ++ edit_syntax_opt_dialog(); ++} ++ + static void + menu_syntax (void) + { +@@ -410,6 +415,7 @@ static menu_entry CmdMenuEmacs[] = + static menu_entry OptMenu[] = + { + {' ', N_("&General... "), 'G', menu_options}, ++ {' ', N_("Highlight options... "), ' ', menu_syntax_options}, + {' ', N_("&Save mode..."), 'S', menu_save_mode_cmd}, + {' ', N_("Learn &Keys..."), 'K', learn_keys}, + {' ', N_("Syntax &Highlighting..."), 'H', menu_syntax}, +Index: mc/edit/editoptions.c +=================================================================== +--- mc.orig/edit/editoptions.c ++++ mc/edit/editoptions.c +@@ -43,9 +43,6 @@ + #include "../src/dialog.h" /* B_CANCEL */ + #include "../src/wtools.h" /* QuickDialog */ + +-#define OPT_DLG_H 17 +-#define OPT_DLG_W 72 +- + #ifndef USE_INTERNAL_EDIT + #define USE_INTERNAL_EDIT 1 + #endif +@@ -65,12 +62,98 @@ i18n_translate_array (const char *array[ + } + } + ++#define OPT_DLG_H 12 ++#define OPT_DLG_W 40 ++void edit_syntax_opt_dialog(void) ++{ ++ int f_syntax_hl = option_syntax_highlighting; ++ int f_tab_hl = option_highlighting & HL_TABS; ++ int f_ws_hl = option_highlighting & HL_WHITESPACE; ++ ++ int old_syntax_hl = f_syntax_hl; ++ ++ QuickWidget quick_widgets[] = { ++ { ++ .widget_type = quick_button, ++ .relative_x = 6, ++ .x_divisions = 10, ++ .relative_y = OPT_DLG_H - 3, ++ .y_divisions = OPT_DLG_H, ++ .text = N_("&Cancel"), ++ .value = B_CANCEL, ++ }, ++ { ++ .widget_type = quick_button, ++ .relative_x = 2, ++ .x_divisions = 10, ++ .relative_y = OPT_DLG_H - 3, ++ .y_divisions = OPT_DLG_H, ++ .text = N_("&OK"), ++ .value = B_ENTER, ++ }, ++ { ++ .widget_type = quick_checkbox, ++ .relative_x = 6, ++ .x_divisions = OPT_DLG_W, ++ .relative_y = 6, ++ .y_divisions = OPT_DLG_H, ++ .text = N_("Whitespace highlighting"), ++ .result = &f_ws_hl, ++ }, ++ { ++ .widget_type = quick_checkbox, ++ .relative_x = 6, ++ .x_divisions = OPT_DLG_W, ++ .relative_y = 5, ++ .y_divisions = OPT_DLG_H, ++ .text = N_("Tab highlighting"), ++ .result = &f_tab_hl, ++ }, ++ { ++ .widget_type = quick_checkbox, ++ .relative_x = 6, ++ .x_divisions = OPT_DLG_W, ++ .relative_y = 4, ++ .y_divisions = OPT_DLG_H, ++ .text = N_("Syntax highlighting"), ++ .result = &f_syntax_hl, ++ }, ++ NULL_QuickWidget, ++ }; ++ QuickDialog quick_options = { ++ .xlen = OPT_DLG_W, ++ .ylen = OPT_DLG_H, ++ .xpos = -1, ++ .ypos = 0, ++ .title = N_(" Syntax options "), ++ .help = "", ++ .widgets = quick_widgets, ++ }; ++ ++ if (quick_dialog(&quick_options) == B_CANCEL) ++ return; ++ ++ if (old_syntax_hl != f_syntax_hl) ++ /* Load or unload syntax rules if the option has changed */ ++ edit_load_syntax(wedit, NULL, option_syntax_type); ++ ++ option_syntax_highlighting = f_syntax_hl; ++ option_highlighting = 0; ++ if (f_tab_hl) ++ option_highlighting |= HL_TABS; ++ if (f_ws_hl) ++ option_highlighting |= HL_WHITESPACE; ++} ++#undef OPT_DLG_H ++#undef OPT_DLG_W ++ ++#define OPT_DLG_H 17 ++#define OPT_DLG_W 72 + void + edit_options_dialog (void) + { + char wrap_length[32], tab_spacing[32], *p, *q; + int wrap_mode = 0; +- int old_syntax_hl; + int tedit_key_emulation = edit_key_emulation; + int toption_fill_tabs_with_spaces = option_fill_tabs_with_spaces; + int toption_save_position = option_save_position; +@@ -102,37 +185,34 @@ edit_options_dialog (void) + OPT_DLG_H, "", OPT_DLG_W / 2 - 4 - 24, 0, 0, 0, + "edit-tab-spacing"}, + /* 6 */ +- {quick_checkbox, OPT_DLG_W / 2 + 1, OPT_DLG_W, OPT_DLG_H - 8, +- OPT_DLG_H, N_("Synta&x highlighting"), 8, 0, 0, 0, NULL}, +- /* 7 */ + {quick_checkbox, OPT_DLG_W / 2 + 1, OPT_DLG_W, OPT_DLG_H - 9, + OPT_DLG_H, N_("Save file &position"), 0, 0, 0, 0, NULL}, +- /* 8 */ ++ /* 7 */ + {quick_checkbox, OPT_DLG_W / 2 + 1, OPT_DLG_W, OPT_DLG_H - 10, + OPT_DLG_H, N_("Confir&m before saving"), 6, 0, 0, 0, NULL}, +- /* 9 */ ++ /* 8 */ + {quick_checkbox, OPT_DLG_W / 2 + 1, OPT_DLG_W, OPT_DLG_H - 11, + OPT_DLG_H, N_("Fill tabs with &spaces"), 0, 0, 0, 0, NULL}, +- /* 10 */ ++ /* 9 */ + {quick_checkbox, OPT_DLG_W / 2 + 1, OPT_DLG_W, OPT_DLG_H - 12, + OPT_DLG_H, N_("&Return does autoindent"), 0, 0, 0, 0, NULL}, +- /* 11 */ ++ /* 10 */ + {quick_checkbox, OPT_DLG_W / 2 + 1, OPT_DLG_W, OPT_DLG_H - 13, + OPT_DLG_H, N_("&Backspace through tabs"), 0, 0, 0, 0, NULL}, +- /* 12 */ ++ /* 11 */ + {quick_checkbox, OPT_DLG_W / 2 + 1, OPT_DLG_W, OPT_DLG_H - 14, + OPT_DLG_H, N_("&Fake half tabs"), 0, 0, 0, 0, NULL}, +- /* 13 */ ++ /* 12 */ + {quick_radio, 5, OPT_DLG_W, OPT_DLG_H - 7, OPT_DLG_H, "", 3, 0, 0, + const_cast(char **, wrap_str), "wrapm"}, +- /* 14 */ ++ /* 13 */ + {quick_label, 4, OPT_DLG_W, OPT_DLG_H - 8, OPT_DLG_H, + N_("Wrap mode"), 0, 0, + 0, 0, NULL}, +- /* 15 */ ++ /* 14 */ + {quick_radio, 5, OPT_DLG_W, OPT_DLG_H - 13, OPT_DLG_H, "", 3, 0, 0, + const_cast(char **, key_emu_str), "keyemu"}, +- /* 16 */ ++ /* 15 */ + {quick_label, 4, OPT_DLG_W, OPT_DLG_H - 14, OPT_DLG_H, + N_("Key emulation"), 0, 0, 0, 0, NULL}, + NULL_QuickWidget +@@ -156,13 +236,12 @@ edit_options_dialog (void) + quick_widgets[3].str_result = &p; + quick_widgets[5].text = tab_spacing; + quick_widgets[5].str_result = &q; +- quick_widgets[6].result = &tedit_syntax_highlighting; +- quick_widgets[7].result = &toption_save_position; +- quick_widgets[8].result = &tedit_confirm_save; +- quick_widgets[9].result = &toption_fill_tabs_with_spaces; +- quick_widgets[10].result = &toption_return_does_auto_indent; +- quick_widgets[11].result = &toption_backspace_through_tabs; +- quick_widgets[12].result = &toption_fake_half_tabs; ++ quick_widgets[6].result = &toption_save_position; ++ quick_widgets[7].result = &tedit_confirm_save; ++ quick_widgets[8].result = &toption_fill_tabs_with_spaces; ++ quick_widgets[9].result = &toption_return_does_auto_indent; ++ quick_widgets[10].result = &toption_backspace_through_tabs; ++ quick_widgets[11].result = &toption_fake_half_tabs; + + if (option_auto_para_formatting) + wrap_mode = 1; +@@ -171,19 +250,17 @@ edit_options_dialog (void) + else + wrap_mode = 0; + +- quick_widgets[13].result = &wrap_mode; +- quick_widgets[13].value = wrap_mode; ++ quick_widgets[12].result = &wrap_mode; ++ quick_widgets[12].value = wrap_mode; + +- quick_widgets[15].result = &tedit_key_emulation; +- quick_widgets[15].value = tedit_key_emulation; ++ quick_widgets[14].result = &tedit_key_emulation; ++ quick_widgets[14].value = tedit_key_emulation; + + Quick_options.widgets = quick_widgets; + + if (quick_dialog (&Quick_options) == B_CANCEL) + return; + +- old_syntax_hl = option_syntax_highlighting; +- + if (p) { + option_word_wrap_line_length = atoi (p); + g_free (p); +@@ -195,7 +272,6 @@ edit_options_dialog (void) + g_free (q); + } + +- option_syntax_highlighting = tedit_syntax_highlighting; + edit_confirm_save = tedit_confirm_save; + option_save_position = toption_save_position; + option_fill_tabs_with_spaces = toption_fill_tabs_with_spaces; +@@ -220,9 +296,8 @@ edit_options_dialog (void) + edit_reload_menu (); + } + +- /* Load or unload syntax rules if the option has changed */ +- if (option_syntax_highlighting != old_syntax_hl) +- edit_load_syntax (wedit, NULL, option_syntax_type); + /* Load usermap if it's needed */ + edit_load_user_map (wedit); + } ++#undef DLG_OPT_W ++#undef DLG_OPT_H +Index: mc/src/setup.c +=================================================================== +--- mc.orig/src/setup.c ++++ mc/src/setup.c +@@ -216,6 +216,7 @@ static const struct { + { "editor_option_typewriter_wrap", &option_typewriter_wrap }, + { "editor_edit_confirm_save", &edit_confirm_save }, + { "editor_syntax_highlighting", &option_syntax_highlighting }, ++ { "editor_highlight", &option_highlighting }, + #endif /* USE_INTERNAL_EDIT */ + + { "nice_rotating_dash", &nice_rotating_dash }, diff --git a/mc-utf8.patch b/mc-utf8.patch index bbb30a7..a77f77a 100644 --- a/mc-utf8.patch +++ b/mc-utf8.patch @@ -1,3806 +1,32 @@ -diff -up mc-4.6.2-pre1/src/filegui.c.utf8 mc-4.6.2-pre1/src/filegui.c ---- mc-4.6.2-pre1/src/filegui.c.utf8 2007-08-23 15:16:39.000000000 +0200 -+++ mc-4.6.2-pre1/src/filegui.c 2008-02-25 14:56:22.000000000 +0100 -@@ -65,6 +65,7 @@ - #include "filegui.h" - #include "key.h" /* get_event */ - #include "util.h" /* strip_password() */ -+#include "tty.h" - - /* }}} */ - -@@ -563,8 +564,8 @@ init_replace (FileOpContext *ctx, enum O - * longest of "Overwrite..." labels - * (assume "Target date..." are short enough) - */ -- l1 = max (strlen (rd_widgets[6].text), -- strlen (rd_widgets[11].text)); -+ l1 = max (mbstrlen (rd_widgets[6].text), -+ mbstrlen (rd_widgets[11].text)); - - /* longest of button rows */ - i = sizeof (rd_widgets) / sizeof (rd_widgets[0]); -@@ -575,7 +576,7 @@ init_replace (FileOpContext *ctx, enum O - l2 = max (l2, l); - l = 0; - } -- l += strlen (rd_widgets[i].text) + 4; -+ l += mbstrlen (rd_widgets[i].text) + 4; - } - } - l2 = max (l2, l); /* last row */ -@@ -593,12 +594,12 @@ init_replace (FileOpContext *ctx, enum O - l = l1; - } - rd_widgets[i].xpos = l; -- l += strlen (rd_widgets[i].text) + 4; -+ l += mbstrlen (rd_widgets[i].text) + 4; - } - } - /* Abort button is centered */ - rd_widgets[1].xpos = -- (rd_xlen - strlen (rd_widgets[1].text) - 3) / 2; -+ (rd_xlen - mbstrlen (rd_widgets[1].text) - 3) / 2; - } - #endif /* ENABLE_NLS */ - -@@ -617,7 +618,7 @@ init_replace (FileOpContext *ctx, enum O - - ADD_RD_LABEL (ui, 0, - name_trunc (ui->replace_filename, -- rd_trunc - strlen (rd_widgets[0].text)), 0); -+ rd_trunc - mbstrlen (rd_widgets[0].text)), 0); - ADD_RD_BUTTON (1); - - ADD_RD_BUTTON (2); -@@ -804,36 +805,36 @@ fmd_init_i18n (int force) - if (fmd_widgets[i].text[0] != '\0') - fmd_widgets[i].text = _(fmd_widgets[i].text); - -- len = strlen (fmd_widgets[FMCB11].text) -- + strlen (fmd_widgets[FMCB21].text) + 15; -+ len = mbstrlen (fmd_widgets[FMCB11].text) -+ + mbstrlen (fmd_widgets[FMCB21].text) + 15; - fmd_xlen = max (fmd_xlen, len); - -- len = strlen (fmd_widgets[FMCB12].text) -- + strlen (fmd_widgets[FMCB22].text) + 15; -+ len = mbstrlen (fmd_widgets[FMCB12].text) -+ + mbstrlen (fmd_widgets[FMCB22].text) + 15; - fmd_xlen = max (fmd_xlen, len); - -- len = strlen (fmd_widgets[FMBRGT].text) -- + strlen (fmd_widgets[FMBLFT].text) + 11; -+ len = mbstrlen (fmd_widgets[FMBRGT].text) -+ + mbstrlen (fmd_widgets[FMBLFT].text) + 11; - - #ifdef FMBMID -- len += strlen (fmd_widgets[FMBMID].text) + 6; -+ len += mbstrlen (fmd_widgets[FMBMID].text) + 6; - #endif - - fmd_xlen = max (fmd_xlen, len + 4); - - len = (fmd_xlen - (len + 6)) / 2; - i = fmd_widgets[FMBLFT].relative_x = len + 3; -- i += strlen (fmd_widgets[FMBLFT].text) + 8; -+ i += mbstrlen (fmd_widgets[FMBLFT].text) + 8; - - #ifdef FMBMID - fmd_widgets[FMBMID].relative_x = i; -- i += strlen (fmd_widgets[FMBMID].text) + 6; -+ i += mbstrlen (fmd_widgets[FMBMID].text) + 6; - #endif - - fmd_widgets[FMBRGT].relative_x = i; - - #define chkbox_xpos(i) \ -- fmd_widgets [i].relative_x = fmd_xlen - strlen (fmd_widgets [i].text) - 6 -+ fmd_widgets [i].relative_x = fmd_xlen - mbstrlen (fmd_widgets [i].text) - 6 - - chkbox_xpos (FMCB0); - chkbox_xpos (FMCB21); -@@ -855,7 +856,7 @@ fmd_init_i18n (int force) - - char * - file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text, -- const char *def_text, int only_one, int *do_background) -+ const char *def_text_orig, int only_one, int *do_background) - { - int source_easy_patterns = easy_patterns; - char *source_mask, *orig_mask, *dest_dir, *tmpdest; -@@ -864,12 +865,20 @@ file_mask_dialog (FileOpContext *ctx, Fi - struct stat buf; - int val; - QuickDialog Quick_input; -- -+ char *def_text; - g_return_val_if_fail (ctx != NULL, NULL); -+ -+ def_text = g_strdup(def_text_orig); -+ - #if 0 - message (1, __FUNCTION__, "text = `%s' \n def_text = `%s'", text, - def_text); - #endif -+ -+#ifdef UTF8 -+ fix_utf8(def_text); -+#endif -+ - fmd_init_i18n (FALSE); - - /* Set up the result pointers */ -@@ -928,6 +937,7 @@ file_mask_dialog (FileOpContext *ctx, Fi - orig_mask = source_mask; - if (!dest_dir || !*dest_dir) { - g_free (source_mask); -+ g_free(def_text); - return dest_dir; - } - if (source_easy_patterns) { -@@ -981,5 +991,6 @@ file_mask_dialog (FileOpContext *ctx, Fi - } - if (val == B_USER) - *do_background = 1; -+ g_free(def_text); - return dest_dir; - } -diff -up mc-4.6.2-pre1/src/tty.h.utf8 mc-4.6.2-pre1/src/tty.h ---- mc-4.6.2-pre1/src/tty.h.utf8 2006-05-15 15:26:18.000000000 +0200 -+++ mc-4.6.2-pre1/src/tty.h 2008-02-25 14:56:22.000000000 +0100 -@@ -8,6 +8,8 @@ - of ifdefs in the other files small. - */ - -+#include /* gboolean is used here */ -+ - #ifdef HAVE_SLANG - # include "myslang.h" - #endif -diff -up mc-4.6.2-pre1/src/widget.c.utf8 mc-4.6.2-pre1/src/widget.c ---- mc-4.6.2-pre1/src/widget.c.utf8 2006-05-29 13:58:43.000000000 +0200 -+++ mc-4.6.2-pre1/src/widget.c 2008-02-25 14:56:22.000000000 +0100 -@@ -36,6 +36,9 @@ - - #include "global.h" - #include "tty.h" -+#ifdef UTF8 -+#include -+#endif /* UTF8 */ - #include "color.h" - #include "mouse.h" - #include "dialog.h" -@@ -182,6 +185,11 @@ button_callback (Widget *w, widget_msg_t - if (b->hotpos >= 0) { - widget_selectcolor (w, b->selected, TRUE); - widget_move (w, 0, b->hotpos + off); -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) -+ SLsmg_write_nwchars (&b->hotwc, 1); -+ else -+#endif - addch ((unsigned char) b->text[b->hotpos]); - } - return MSG_HANDLED; -@@ -215,7 +223,7 @@ button_event (Gpm_Event *event, void *da - static int - button_len (const char *text, unsigned int flags) - { -- int ret = strlen (text); -+ int ret = mbstrlen (text); - switch (flags){ - case DEFPUSH_BUTTON: - ret += 6; -@@ -238,14 +246,36 @@ button_len (const char *text, unsigned i - * the button text is g_malloc()ed, we can safely change and shorten it. - */ - static void --button_scan_hotkey (WButton *b) -+scan_hotkey (char *text, int *hotposp, int *hotkeyp, wchar_t *hotwcp) - { -- char *cp = strchr (b->text, '&'); -+ char *cp = strchr (text, '&'); - - if (cp != NULL && cp[1] != '\0') { -- g_strlcpy (cp, cp + 1, strlen (cp)); -- b->hotkey = tolower ((unsigned char) *cp); -- b->hotpos = cp - b->text; -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) { -+ mbstate_t s; -+ int len; -+ -+ *cp = '\0'; -+ memset (&s, 0, sizeof (s)); -+ len = mbrtowc (hotwcp, cp + 1, MB_CUR_MAX, &s); -+ if (len > 0) { -+ *hotposp = mbstrlen (text); -+ if (*hotposp < 0) { -+ *hotposp = -1; -+ } else { -+ /* FIXME */ -+ *hotkeyp = tolower (*hotwcp); -+ } -+ } -+ } else -+#endif -+ { -+ *hotkeyp = tolower (cp[1]); -+ *hotposp = cp - text; -+ } -+ -+ memmove (cp, cp + 1, strlen (cp + 1) + 1); - } - } - -@@ -266,8 +296,9 @@ button_new (int y, int x, int action, in - widget_want_hotkey (b->widget, 1); - b->hotkey = 0; - b->hotpos = -1; -+ b->hotwc = L'\0'; - -- button_scan_hotkey(b); -+ scan_hotkey(b->text, &b->hotpos, &b->hotkey, &b->hotwc); - return b; - } - -@@ -280,14 +311,13 @@ button_get_text (WButton *b) - void - button_set_text (WButton *b, const char *text) - { -- g_free (b->text); -+ g_free (b->text); - b->text = g_strdup (text); - b->widget.cols = button_len (text, b->flags); -- button_scan_hotkey(b); -+ scan_hotkey(b->text, &b->hotpos, &b->hotkey, &b->hotwc); - dlg_redraw (b->widget.parent); - } - -- - /* Radio button widget */ - static int radio_event (Gpm_Event *event, void *); - -@@ -362,14 +392,35 @@ radio_callback (Widget *w, widget_msg_t - widget_move (&r->widget, i, 0); - - tty_printf ("(%c) ", (r->sel == i) ? '*' : ' '); -- for (cp = r->texts[i]; *cp; cp++) { -- if (*cp == '&') { -- widget_selectcolor (w, focused, TRUE); -+ cp = strchr (r->texts[i], '&'); -+ if (cp != NULL) { -+#ifdef UTF8 -+ mbstate_t s; -+ wchar_t wc; -+ int len; -+#endif -+ tty_printf ("%.*s", (int) ((char *) cp - r->texts[i]), -+ r->texts[i]); -+ widget_selectcolor (w, focused, TRUE); -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) { -+ memset (&s, 0, sizeof (s)); -+ len = mbrtowc (&wc, cp + 1, MB_CUR_MAX, &s); -+ ++cp; -+ if (len > 0) { -+ tty_printf ("%.*s", len, cp); -+ cp += len; -+ } -+ } else -+#endif -+ { - addch (*++cp); -- widget_selectcolor (w, focused, FALSE); -- } else -- addch (*cp); -- } -+ ++cp; -+ } -+ widget_selectcolor (w, focused, FALSE); -+ } else -+ cp = r->texts[i]; -+ addstr ((char *) cp); - } - return MSG_HANDLED; - -@@ -408,7 +459,7 @@ radio_new (int y, int x, int count, cons - /* Compute the longest string */ - max = 0; - for (i = 0; i < count; i++){ -- m = strlen (texts [i]); -+ m = mbstrlen (texts [i]); - if (m > max) - max = m; - } -@@ -468,6 +519,11 @@ check_callback (Widget *w, widget_msg_t - if (c->hotpos >= 0) { - widget_selectcolor (w, msg == WIDGET_FOCUS, TRUE); - widget_move (&c->widget, 0, +c->hotpos + 4); -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) -+ SLsmg_write_nwchars (&c->hotwc, 1); -+ else -+#endif - addch ((unsigned char) c->text[c->hotpos]); - } - return MSG_HANDLED; -@@ -505,35 +561,20 @@ WCheck * - check_new (int y, int x, int state, const char *text) - { - WCheck *c = g_new (WCheck, 1); -- const char *s; -- char *t; -- -- init_widget (&c->widget, y, x, 1, strlen (text), -+ -+ init_widget (&c->widget, y, x, 1, mbstrlen (text), - check_callback, check_event); - c->state = state ? C_BOOL : 0; - c->text = g_strdup (text); - c->hotkey = 0; - c->hotpos = -1; -+ c->hotwc = L'\0'; - widget_want_hotkey (c->widget, 1); - -- /* Scan for the hotkey */ -- for (s = text, t = c->text; *s; s++, t++){ -- if (*s != '&'){ -- *t = *s; -- continue; -- } -- s++; -- if (*s){ -- c->hotkey = tolower ((unsigned char) *s); -- c->hotpos = t - c->text; -- } -- *t = *s; -- } -- *t = 0; -+ scan_hotkey (c->text, &c->hotpos, &c->hotkey, &c->hotwc); - return c; - } - -- - /* Label widget */ - - static cb_ret_t -@@ -572,7 +613,7 @@ label_callback (Widget *w, widget_msg_t - } - widget_move (&l->widget, y, 0); - tty_printf ("%s", p); -- xlen = l->widget.cols - strlen (p); -+ xlen = l->widget.cols - mbstrlen (p); - if (xlen > 0) - tty_printf ("%*s", xlen, " "); - if (!q) -@@ -606,7 +647,7 @@ label_set_text (WLabel *label, const cha - if (text){ - label->text = g_strdup (text); - if (label->auto_adjust_cols) { -- newcols = strlen (text); -+ newcols = mbstrlen (text); - if (newcols > label->widget.cols) - label->widget.cols = newcols; - } -@@ -630,7 +671,7 @@ label_new (int y, int x, const char *tex - if (!text || strchr(text, '\n')) - width = 1; - else -- width = strlen (text); -+ width = mbstrlen (text); - - l = g_new (WLabel, 1); - init_widget (&l->widget, y, x, 1, width, label_callback, NULL); -@@ -778,13 +819,69 @@ static void draw_history_button (WInput - /* Pointer to killed data */ - static char *kill_buffer = 0; - -+#ifdef UTF8 -+static int -+charpos(WInput *in, int idx) -+{ -+ int i, pos, l, len; -+ mbstate_t mbs; -+ memset (&mbs, 0, sizeof (mbs)); -+ i = 0; -+ pos = 0; -+ len = strlen(in->buffer); -+ -+ while (in->buffer[pos]) { -+ if (i == idx) -+ return pos; -+ l = mbrlen(in->buffer + pos, len - pos, &mbs); -+ if (l <= 0) -+ return pos; -+ pos+=l; -+ i++; -+ }; -+ return pos; -+} -+ -+static int -+charcolumn(WInput *in, int idx) -+{ -+ int i, pos, l, width, len; -+ mbstate_t mbs; -+ memset (&mbs, 0, sizeof (mbs)); -+ i = 0; -+ pos = 0; width = 0; -+ len = strlen(in->buffer); -+ -+ while (in->buffer[pos]) { -+ wchar_t wc; -+ if (i == idx) -+ return width; -+ l = mbrtowc(&wc, in->buffer + pos, len - pos, &mbs); -+ if (l <= 0) -+ return width; -+ pos += l; width += wcwidth(wc); -+ i++; -+ }; -+ return width; -+} -+#else -+#define charpos(in, idx) (idx) -+#define charcolumn(in, idx) (idx) -+#endif /* UTF8 */ -+ - void - update_input (WInput *in, int clear_first) - { - int has_history = 0; - int i, j; -- unsigned char c; -- int buf_len = strlen (in->buffer); -+ int buf_len = mbstrlen (in->buffer); -+#ifndef UTF8 -+ unsigned char c; -+#else /* UTF8 */ -+ wchar_t c; -+ mbstate_t mbs; -+ memset (&mbs, 0, sizeof (mbs)); -+#endif /* UTF8 */ - - if (should_show_history_button (in)) - has_history = HISTORY_BUTTON_WIDTH; -@@ -794,7 +891,7 @@ update_input (WInput *in, int clear_firs - - /* Make the point visible */ - if ((in->point < in->first_shown) || -- (in->point >= in->first_shown+in->field_len - has_history)){ -+ (charcolumn(in, in->point) >= charcolumn(in, in->first_shown) + in->field_len - has_history)){ - in->first_shown = in->point - (in->field_len / 3); - if (in->first_shown < 0) - in->first_shown = 0; -@@ -814,14 +911,29 @@ update_input (WInput *in, int clear_firs - addch (' '); - widget_move (&in->widget, 0, 0); - -+#ifndef UTF8 - for (i = 0, j = in->first_shown; i < in->field_len - has_history && in->buffer [j]; i++){ - c = in->buffer [j++]; - c = is_printable (c) ? c : '.'; -- if (in->is_password) -+#else /* UTF8 */ -+ for (i = 0, j = in->first_shown; (i < in->field_len - has_history) && (j < buf_len); i++,j++){ -+ char * chp = in->buffer + charpos(in,j); -+ size_t res = mbrtowc(&c, chp, strlen(chp), &mbs); -+ c = (res && iswprint (c)) ? 0 : '.'; -+#endif /* UTF8 */ -+ if (in->is_password) - c = '*'; -+#ifndef UTF8 - addch (c); -+#else /* UTF8 */ -+ if (c) { -+ addch (c); -+ } -+ else -+ SLsmg_write_nchars (chp, res); -+#endif /* UTF8 */ - } -- widget_move (&in->widget, 0, in->point - in->first_shown); -+ widget_move (&in->widget, 0, charcolumn(in, in->point) - charcolumn(in, in->first_shown)); - - if (clear_first) - in->first = 0; -@@ -974,7 +1086,7 @@ char * - show_hist (GList *history, int widget_x, int widget_y) - { - GList *hi, *z; -- size_t maxlen = strlen (i18n_htitle ()), i, count = 0; -+ size_t maxlen = mbstrlen (i18n_htitle ()), i, count = 0; - int x, y, w, h; - char *q, *r = 0; - Dlg_head *query_dlg; -@@ -987,7 +1099,7 @@ show_hist (GList *history, int widget_x, - z = g_list_first (history); - hi = z; - while (hi) { -- if ((i = strlen ((char *) hi->data)) > maxlen) -+ if ((i = mbstrlen ((char *) hi->data)) > maxlen) - maxlen = i; - count++; - hi = g_list_next (hi); -@@ -1157,35 +1269,83 @@ new_input (WInput *in) - in->need_push = 1; - in->buffer [0] = 0; - in->point = 0; -+ in->charpoint = 0; - in->mark = 0; - free_completions (in); - update_input (in, 0); - } - -+static void -+move_buffer_backward (WInput *in, int point) -+{ -+ int i, pos, len; -+ int str_len = mbstrlen (in->buffer); -+ if (point >= str_len) return; -+ -+ pos = charpos(in,point); -+ len = charpos(in,point + 1) - pos; -+ -+ for (i = pos; in->buffer [i + len - 1]; i++) -+ in->buffer [i] = in->buffer [i + len]; -+} -+ - static cb_ret_t - insert_char (WInput *in, int c_code) - { - size_t i; -+#ifdef UTF8 -+ mbstate_t mbs; -+ int res; -+ -+ memset (&mbs, 0, sizeof (mbs)); -+#else -+ in->charpoint = 0; -+#endif /* UTF8 */ - - if (c_code == -1) - return MSG_NOT_HANDLED; - -+#ifdef UTF8 -+ if (in->charpoint >= MB_CUR_MAX) return 1; -+ -+ in->charbuf[in->charpoint++] = c_code; -+ -+ res = mbrlen((char *)in->charbuf, in->charpoint, &mbs); -+ if (res < 0) { -+ if (res != -2) in->charpoint = 0; /* broken multibyte char, skip */ -+ return 1; -+ } -+ -+#endif /* UTF8 */ - in->need_push = 1; -- if (strlen (in->buffer)+1 == (size_t) in->current_max_len){ -+ if (strlen (in->buffer) + 1 + in->charpoint >= (size_t) in->current_max_len){ - /* Expand the buffer */ -- char *narea = g_realloc (in->buffer, in->current_max_len + in->field_len); -+ char *narea = g_realloc (in->buffer, in->current_max_len + in->field_len + in->charpoint); - if (narea){ - in->buffer = narea; -- in->current_max_len += in->field_len; -+ in->current_max_len += in->field_len + in->charpoint; - } - } -+#ifndef UTF8 - if (strlen (in->buffer)+1 < (size_t) in->current_max_len){ - size_t l = strlen (&in->buffer [in->point]); - for (i = l+1; i > 0; i--) - in->buffer [in->point+i] = in->buffer [in->point+i-1]; - in->buffer [in->point] = c_code; -+#else /* UTF8 */ -+ if (strlen (in->buffer) + in->charpoint < in->current_max_len){ -+ size_t ins_point = charpos(in,in->point); /* bytes from begin */ -+ /* move chars */ -+ size_t rest_bytes = strlen (in->buffer + ins_point); -+ -+ for (i = rest_bytes + 1; i > 0; i--) -+ in->buffer [ins_point + i + in->charpoint - 1] = in->buffer [ins_point + i - 1]; -+ -+ memcpy(in->buffer + ins_point, in->charbuf, in->charpoint); -+#endif /* UTF8 */ - in->point++; - } -+ in->charpoint = 0; - return MSG_HANDLED; - } - -@@ -1193,12 +1353,14 @@ static void - beginning_of_line (WInput *in) - { - in->point = 0; -+ in->charpoint = 0; - } - - static void - end_of_line (WInput *in) - { -- in->point = strlen (in->buffer); -+ in->point = mbstrlen (in->buffer); -+ in->charpoint = 0; - } - - static void -@@ -1206,18 +1368,21 @@ backward_char (WInput *in) - { - if (in->point) - in->point--; -+ in->charpoint = 0; - } - - static void - forward_char (WInput *in) - { -- if (in->buffer [in->point]) -+ if (in->buffer [charpos(in,in->point)]) - in->point++; -+ in->charpoint = 0; - } - - static void - forward_word (WInput * in) - { -+#ifndef UTF8 - char *p = in->buffer + in->point; - - while (*p -@@ -1227,11 +1392,39 @@ forward_word (WInput * in) - while (*p && isalnum ((unsigned char) *p)) - p++; - in->point = p - in->buffer; -+#else /* UTF8 */ -+ mbstate_t mbs; -+ int len = mbstrlen (in->buffer); -+ memset (&mbs, 0, sizeof (mbs)); -+ -+ while (in->point < len) { -+ wchar_t c; -+ char *p = in->buffer + charpos(in,in->point); -+ size_t res = mbrtowc(&c, p, strlen(p), &mbs); -+ if (res <= 0 || !(iswspace (c) || iswpunct (c))) -+ break; -+ in->point++; -+ } -+ -+ memset (&mbs, 0, sizeof (mbs)); -+ -+ while (in->point < len) { -+ wchar_t c; -+ char *p = in->buffer + charpos(in,in->point); -+ size_t res = mbrtowc(&c, p, strlen(p), &mbs); -+ if (res <= 0 || !iswalnum (c)) -+ break; -+ in->point++; -+ } -+ -+ in->charpoint = 0; -+#endif /* UTF8 */ - } - - static void - backward_word (WInput *in) - { -+#ifndef UTF8 - char *p = in->buffer + in->point; - - while (p - 1 > in->buffer - 1 && (isspace ((unsigned char) *(p - 1)) -@@ -1241,6 +1434,32 @@ backward_word (WInput *in) - while (p - 1 > in->buffer - 1 && isalnum ((unsigned char) *(p - 1))) - p--; - in->point = p - in->buffer; -+#else /* UTF8 */ -+ mbstate_t mbs; -+ -+ memset (&mbs, 0, sizeof (mbs)); -+ while (in->point > 0) { -+ wchar_t c; -+ char *p = in->buffer + charpos(in,in->point); -+ size_t res = mbrtowc(&c, p, strlen(p), &mbs); -+ if (*p && (res <= 0 || !(iswspace (c) || iswpunct (c)))) -+ break; -+ in->point--; -+ } -+ -+ memset (&mbs, 0, sizeof (mbs)); -+ -+ while (in->point > 0) { -+ wchar_t c; -+ char *p = in->buffer + charpos(in,in->point); -+ size_t res = mbrtowc(&c, p, strlen(p), &mbs); -+ if (*p && (res <= 0 || !iswalnum (c))) -+ break; -+ in->point--; -+ } -+ -+ in->charpoint = 0; -+#endif /* UTF8 */ - } - - static void -@@ -1273,8 +1492,9 @@ backward_delete (WInput *in) - - if (!in->point) - return; -- for (i = in->point; in->buffer [i-1]; i++) -- in->buffer [i-1] = in->buffer [i]; -+ -+ move_buffer_backward(in, in->point - 1); -+ in->charpoint = 0; - in->need_push = 1; - in->point--; - } -@@ -1282,10 +1502,8 @@ backward_delete (WInput *in) - static void - delete_char (WInput *in) - { -- int i; -- -- for (i = in->point; in->buffer [i]; i++) -- in->buffer [i] = in->buffer [i+1]; -+ move_buffer_backward(in, in->point); -+ in->charpoint = 0; - in->need_push = 1; - } - -@@ -1300,6 +1518,9 @@ copy_region (WInput *in, int x_first, in - - g_free (kill_buffer); - -+ first=charpos(in,first); -+ last=charpos(in,last); -+ - kill_buffer = g_strndup(in->buffer+first,last-first); - } - -@@ -1308,11 +1529,13 @@ delete_region (WInput *in, int x_first, - { - int first = min (x_first, x_last); - int last = max (x_first, x_last); -- size_t len = strlen (&in->buffer [last]) + 1; -+ size_t len; - - in->point = first; - in->mark = first; -- memmove (&in->buffer [first], &in->buffer [last], len); -+ len = strlen (&in->buffer [charpos(in,last)]) + 1; -+ memmove (&in->buffer [charpos(in,first)], &in->buffer [charpos(in,last)], len); -+ in->charpoint = 0; - in->need_push = 1; - } - -@@ -1329,6 +1552,8 @@ kill_word (WInput *in) - copy_region (in, old_point, new_point); - delete_region (in, old_point, new_point); - in->need_push = 1; -+ in->charpoint = 0; -+ in->charpoint = 0; - } - - static void -@@ -1372,16 +1597,20 @@ yank (WInput *in) - - if (!kill_buffer) - return; -+ in->charpoint = 0; - for (p = kill_buffer; *p; p++) - insert_char (in, *p); -+ in->charpoint = 0; - } - - static void - kill_line (WInput *in) - { -+ int chp = charpos(in,in->point); - g_free (kill_buffer); -- kill_buffer = g_strdup (&in->buffer [in->point]); -- in->buffer [in->point] = 0; -+ kill_buffer = g_strdup (&in->buffer [chp]); -+ in->buffer [chp] = 0; -+ in->charpoint = 0; - } - - void -@@ -1391,9 +1620,10 @@ assign_text (WInput *in, const char *tex - g_free (in->buffer); - in->buffer = g_strdup (text); /* was in->buffer->text */ - in->current_max_len = strlen (in->buffer) + 1; -- in->point = strlen (in->buffer); -+ in->point = mbstrlen (in->buffer); - in->mark = 0; - in->need_push = 1; -+ in->charpoint = 0; - } - - static void -@@ -1520,6 +1750,7 @@ port_region_marked_for_delete (WInput *i - *in->buffer = 0; - in->point = 0; - in->first = 0; -+ in->charpoint = 0; - } - - cb_ret_t -@@ -1548,7 +1779,11 @@ handle_char (WInput *in, int c_code) - } - } - if (!input_map [i].fn){ -+#ifndef UTF8 - if (c_code > 255 || !is_printable (c_code)) -+#else /* UTF8 */ -+ if (c_code > 255) -+#endif /* UTF8 */ - return MSG_NOT_HANDLED; - if (in->first){ - port_region_marked_for_delete (in); -@@ -1581,6 +1816,9 @@ input_set_point (WInput *in, int pos) - if (pos != in->point) - free_completions (in); - in->point = pos; -+#ifdef UTF8 -+ in->charpoint = 0; -+#endif /* UTF8 */ - update_input (in, 1); - } - -@@ -1621,7 +1859,7 @@ input_callback (Widget *w, widget_msg_t - return MSG_HANDLED; - - case WIDGET_CURSOR: -- widget_move (&in->widget, 0, in->point - in->first_shown); -+ widget_move (&in->widget, 0, charcolumn(in, in->point) - charcolumn(in, in->first_shown)); - return MSG_HANDLED; - - case WIDGET_DESTROY: -@@ -1645,7 +1883,7 @@ input_event (Gpm_Event * event, void *da - && should_show_history_button (in)) { - do_show_hist (in); - } else { -- in->point = strlen (in->buffer); -+ in->point = mbstrlen (in->buffer); - if (event->x - in->first_shown - 1 < in->point) - in->point = event->x - in->first_shown - 1; - if (in->point < 0) -@@ -1702,7 +1940,8 @@ input_new (int y, int x, int color, int - in->is_password = 0; - - strcpy (in->buffer, def_text); -- in->point = strlen (in->buffer); -+ in->point = mbstrlen (in->buffer); -+ in->charpoint = 0; - return in; - } - -diff -up mc-4.6.2-pre1/src/widget.h.utf8 mc-4.6.2-pre1/src/widget.h ---- mc-4.6.2-pre1/src/widget.h.utf8 2006-02-28 17:15:21.000000000 +0100 -+++ mc-4.6.2-pre1/src/widget.h 2008-02-25 14:56:22.000000000 +0100 -@@ -22,6 +22,7 @@ typedef struct WButton { - char *text; /* text of button */ - int hotkey; /* hot KEY */ - int hotpos; /* offset hot KEY char in text */ -+ wchar_t hotwc; - bcback callback; /* Callback function */ - } WButton; - -@@ -42,6 +43,7 @@ typedef struct WCheck { - char *text; /* text of check button */ - int hotkey; /* hot KEY */ - int hotpos; /* offset hot KEY char in text */ -+ wchar_t hotwc; - } WCheck; - - typedef struct WGauge { -@@ -57,16 +59,20 @@ char *show_hist (GList *history, int wid - - typedef struct { - Widget widget; -- int point; /* cursor position in the input line */ -- int mark; /* The mark position */ -- int first_shown; /* Index of the first shown character */ -- int current_max_len; /* Maximum length of input line */ -- int field_len; /* Length of the editing field */ -+ int point; /* cursor position in the input line (mb chars) */ -+ int mark; /* The mark position (mb chars) */ -+ int first_shown; /* Index of the first shown character (mb chars) */ -+ int current_max_len; /* Maximum length of input line (bytes) */ -+ int field_len; /* Length of the editing field (mb chars) */ - int color; /* color used */ - int first; /* Is first keystroke? */ - int disable_update; /* Do we want to skip updates? */ - int is_password; /* Is this a password input line? */ - char *buffer; /* pointer to editing buffer */ -+#ifdef UTF8 -+ char charbuf[MB_LEN_MAX]; -+#endif /* UTF8 */ -+ int charpoint; - GList *history; /* The history */ - int need_push; /* need to push the current Input on hist? */ - char **completions; /* Possible completions array */ -diff -up mc-4.6.2-pre1/src/menu.c.utf8 mc-4.6.2-pre1/src/menu.c ---- mc-4.6.2-pre1/src/menu.c.utf8 2005-09-05 04:12:09.000000000 +0200 -+++ mc-4.6.2-pre1/src/menu.c 2008-02-25 14:56:22.000000000 +0100 -@@ -22,6 +22,7 @@ - #include - - #include -+#include - - #include "global.h" - #include "tty.h" -@@ -53,35 +54,95 @@ create_menu (const char *name, menu_entr - { - Menu *menu; - const char *cp; -+ int wlen = 0; -+ mbstate_t s; - - menu = (Menu *) g_malloc (sizeof (*menu)); - menu->count = count; - menu->max_entry_len = 20; - menu->entries = entries; -+ menu->name = g_strdup (name); -+ menu_scan_hotkey (menu); -+#ifdef UTF8 -+ menu->wentries = NULL; -+ menu->wname = NULL; -+ if (SLsmg_Is_Unicode) { -+ const char *str = menu->name; -+ memset (&s, 0, sizeof (s)); -+ wlen = mbsrtowcs (NULL, &str, -1, &s); -+ if (wlen > 0) -+ ++wlen; -+ else { -+ wlen = 0; -+ memset (&s, 0, sizeof (s)); -+ } -+ } -+#endif - - if (entries != (menu_entry*) NULL) { - register menu_entry* mp; - for (mp = entries; count--; mp++) { - if (mp->text[0] != '\0') { -+ int len; - #ifdef ENABLE_NLS - mp->text = _(mp->text); - #endif /* ENABLE_NLS */ - cp = strchr (mp->text,'&'); -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) { -+ len = mbstrlen(mp->text) + 1; -+ wlen += len; -+ menu->max_entry_len = max (len - 1, menu->max_entry_len); -+ } else -+#endif -+ len = strlen (mp->text); - - if (cp != NULL && *(cp+1) != '\0') { - mp->hot_key = tolower ((unsigned char) *(cp+1)); -- menu->max_entry_len = max ((int) (strlen (mp->text) - 1), -- menu->max_entry_len); -+ menu->max_entry_len = max (len - 1, menu->max_entry_len); - } else { -- menu->max_entry_len = max ((int) strlen (mp->text), -- menu->max_entry_len); -+ menu->max_entry_len = max (len, menu->max_entry_len); - } - } - } - } - -- menu->name = g_strdup (name); -- menu_scan_hotkey(menu); -+#ifdef UTF8 -+ if (wlen) { -+ wchar_t *wp; -+ const char *str; -+ int len; -+ -+ menu->wentries = (wchar_t **) -+ g_malloc (sizeof (wchar_t *) * menu->count -+ + wlen * sizeof (wchar_t)); -+ wp = (wchar_t *) (menu->wentries + menu->count); -+ str = menu->name; -+ len = mbsrtowcs (wp, &str, wlen, &s); -+ if (len > 0) { -+ menu->wname = wp; -+ wlen -= len + 1; -+ wp += len + 1; -+ } else -+ memset (&s, 0, sizeof (s)); -+ if (menu->entries != NULL) -+ for (count = 0; count < menu->count; ++count) -+ if (menu->entries[count].text[0] != '\0') { -+ str = menu->entries[count].text; -+ menu->wentries[count] = wp; -+ len = mbsrtowcs (wp, &str, wlen, &s); -+ if (len > 0) { -+ wlen -= len + 1; -+ wp += len + 1; -+ } else { -+ memset (&s, 0, sizeof (s)); -+ *wp++ = L'\0'; -+ --wlen; -+ } -+ } -+ } -+#endif -+ - menu->start_x = 0; - menu->help_node = g_strdup (help_node); - return menu; -@@ -112,8 +173,26 @@ static void menubar_paint_idx (WMenu *me - const char *text; - - addch((unsigned char)menu->entries [idx].first_letter); -- for (text = menu->entries [idx].text; *text; text++) -- { -+#ifdef UTF8 -+ if (menu->wentries) { -+ wchar_t *wtext, *wp; -+ -+ for (wtext = wp = menu->wentries [idx]; *wtext; wtext++) { -+ if (*wtext == L'&') { -+ if (wtext > wp) -+ SLsmg_write_nwchars (wp, wtext - wp); -+ attrset (color == MENU_SELECTED_COLOR ? -+ MENU_HOTSEL_COLOR : MENU_HOT_COLOR); -+ SLsmg_write_nwchars (++wtext, 1); -+ attrset (color); -+ wp = wtext + 1; -+ } -+ } -+ if (wtext > wp) -+ SLsmg_write_nwchars (wp, wtext - wp); -+ } else -+#endif -+ for (text = menu->entries [idx].text; *text; text++) { - if (*text != '&') - addch(*text); - else { -@@ -122,7 +201,7 @@ static void menubar_paint_idx (WMenu *me - addch(*(++text)); - attrset(color); - } -- } -+ } - } - widget_move (&menubar->widget, y, x + 1); - } -@@ -168,6 +247,12 @@ static void menubar_draw (WMenu *menubar - if (menubar->active) - attrset(i == menubar->selected?MENU_SELECTED_COLOR:SELECTED_COLOR); - widget_move (&menubar->widget, 0, menubar->menu [i]->start_x); -+#ifdef UTF8 -+ if (menubar->menu [i]->wname) -+ SLsmg_write_nwchars (menubar->menu [i]->wname, -+ wcslen (menubar->menu [i]->wname)); -+ else -+#endif - tty_printf ("%s", menubar->menu [i]->name); - } - -@@ -493,7 +578,13 @@ menubar_arrange(WMenu* menubar) - - for (i = 0; i < items; i++) - { -- int len = strlen(menubar->menu[i]->name); -+ int len; -+#ifdef UTF8 -+ if (menubar->menu[i]->wname) -+ len = wcslen (menubar->menu[i]->wname); -+ else -+#endif -+ len = strlen(menubar->menu[i]->name); - menubar->menu[i]->start_x = start_x; - start_x += len + gap; - } -@@ -506,7 +597,13 @@ menubar_arrange(WMenu* menubar) - for (i = 0; i < items; i++) - { - /* preserve length here, to be used below */ -- gap -= (menubar->menu[i]->start_x = strlen(menubar->menu[i]->name)); -+#ifdef UTF8 -+ if (menubar->menu[i]->wname) -+ menubar->menu[i]->start_x = wcslen (menubar->menu[i]->wname); -+ else -+#endif -+ menubar->menu[i]->start_x = strlen (menubar->menu[i]->name); -+ gap -= menubar->menu[i]->start_x; - } - - gap /= (items - 1); -@@ -530,6 +627,9 @@ menubar_arrange(WMenu* menubar) - void - destroy_menu (Menu *menu) - { -+#ifdef UTF8 -+ g_free (menu->wentries); -+#endif - g_free (menu->name); - g_free (menu->help_node); - g_free (menu); -diff -up mc-4.6.2-pre1/src/wtools.c.utf8 mc-4.6.2-pre1/src/wtools.c ---- mc-4.6.2-pre1/src/wtools.c.utf8 2006-09-14 11:12:49.000000000 +0200 -+++ mc-4.6.2-pre1/src/wtools.c 2008-02-25 14:56:22.000000000 +0100 -@@ -49,11 +49,11 @@ create_listbox_window (int cols, int lin - /* Adjust sizes */ - lines = (lines > LINES - 6) ? LINES - 6 : lines; - -- if (title && (cols < (len = strlen (title) + 2))) -+ if (title && (cols < (len = mbstrlen (title) + 2))) - cols = len; - - /* no &, but 4 spaces around button for brackets and such */ -- if (cols < (len = strlen (cancel_string) + 3)) -+ if (cols < (len = mbstrlen (cancel_string) + 3)) - cols = len; - - cols = cols > COLS - 6 ? COLS - 6 : cols; -@@ -124,7 +124,7 @@ query_dialog (const char *header, const - va_start (ap, count); - for (i = 0; i < count; i++) { - char *cp = va_arg (ap, char *); -- win_len += strlen (cp) + 6; -+ win_len += mbstrlen (cp) + 6; - if (strchr (cp, '&') != NULL) - win_len--; - } -@@ -133,7 +133,7 @@ query_dialog (const char *header, const - - /* count coordinates */ - msglen (text, &lines, &cols); -- cols = 6 + max (win_len, max ((int) strlen (header), cols)); -+ cols = 6 + max (win_len, max ((int) mbstrlen (header), cols)); - lines += 4 + (count > 0 ? 2 : 0); - xpos = COLS / 2 - cols / 2; - ypos = LINES / 3 - (lines - 3) / 2; -@@ -148,7 +148,7 @@ query_dialog (const char *header, const - va_start (ap, count); - for (i = 0; i < count; i++) { - cur_name = va_arg (ap, char *); -- xpos = strlen (cur_name) + 6; -+ xpos = mbstrlen (cur_name) + 6; - if (strchr (cur_name, '&') != NULL) - xpos--; - -@@ -463,7 +463,7 @@ fg_input_dialog_help (const char *header - quick_widgets[2].histname = histname; - - msglen (text, &lines, &cols); -- len = max ((int) strlen (header), cols) + 4; -+ len = max ((int) mbstrlen (header), cols) + 4; - len = max (len, 64); - - /* The special value of def_text is used to identify password boxes -@@ -485,7 +485,7 @@ fg_input_dialog_help (const char *header - quick_widgets[1].text = _(quick_widgets[1].text); - quick_widgets[0].relative_x = len / 2 + 4; - quick_widgets[1].relative_x = -- len / 2 - (strlen (quick_widgets[1].text) + 9); -+ len / 2 - (mbstrlen (quick_widgets[1].text) + 9); - quick_widgets[0].x_divisions = quick_widgets[1].x_divisions = len; - #endif /* ENABLE_NLS */ - -diff -up mc-4.6.2-pre1/src/learn.c.utf8 mc-4.6.2-pre1/src/learn.c ---- mc-4.6.2-pre1/src/learn.c.utf8 2005-05-27 05:35:15.000000000 +0200 -+++ mc-4.6.2-pre1/src/learn.c 2008-02-25 14:56:22.000000000 +0100 -@@ -237,7 +237,7 @@ init_learn (void) - learn_but[0].x = 78 / 2 + 4; - - learn_but[1].text = _(learn_but[1].text); -- learn_but[1].x = 78 / 2 - (strlen (learn_but[1].text) + 9); -+ learn_but[1].x = 78 / 2 - (mbstrlen (learn_but[1].text) + 9); - - learn_title = _(learn_title); - i18n_flag = 1; -diff -up mc-4.6.2-pre1/src/slint.c.utf8 mc-4.6.2-pre1/src/slint.c ---- mc-4.6.2-pre1/src/slint.c.utf8 2005-09-05 04:14:29.000000000 +0200 -+++ mc-4.6.2-pre1/src/slint.c 2008-02-25 14:56:22.000000000 +0100 -@@ -141,7 +141,9 @@ void - slang_init (void) - { - SLtt_get_terminfo (); -- -+#if SLANG_VERSION >= 20000 -+ SLutf8_enable (-1); -+#endif - /* - * If the terminal in not in terminfo but begins with a well-known - * string such as "linux" or "xterm" S-Lang will go on, but the -diff -up mc-4.6.2-pre1/src/option.c.utf8 mc-4.6.2-pre1/src/option.c ---- mc-4.6.2-pre1/src/option.c.utf8 2006-02-28 17:15:21.000000000 +0100 -+++ mc-4.6.2-pre1/src/option.c 2008-02-25 14:56:22.000000000 +0100 -@@ -123,12 +123,12 @@ init_configure (void) - title2 = _(" Pause after run... "); - title3 = _(" Other options "); - -- first_width = strlen (title1) + 1; -- second_width = strlen (title3) + 1; -+ first_width = mbstrlen (title1) + 1; -+ second_width = mbstrlen (title3) + 1; - - for (i = 0; check_options[i].text; i++) { - check_options[i].text = _(check_options[i].text); -- l1 = strlen (check_options[i].text) + 7; -+ l1 = mbstrlen (check_options[i].text) + 7; - if (i >= OTHER_OPTIONS) { - if (l1 > first_width) - first_width = l1; -@@ -141,23 +141,23 @@ init_configure (void) - i = PAUSE_OPTIONS; - while (i--) { - pause_options[i] = _(pause_options[i]); -- l1 = strlen (pause_options[i]) + 7; -+ l1 = mbstrlen (pause_options[i]) + 7; - if (l1 > first_width) - first_width = l1; - } - -- l1 = strlen (title2) + 1; -+ l1 = mbstrlen (title2) + 1; - if (l1 > first_width) - first_width = l1; - -- l1 = 11 + strlen (ok_button) -- + strlen (save_button) -- + strlen (cancel_button); -+ l1 = 11 + mbstrlen (ok_button) -+ + mbstrlen (save_button) -+ + mbstrlen (cancel_button); - - i = (first_width + second_width - l1) / 4; - b1 = 5 + i; -- b2 = b1 + strlen (ok_button) + i + 6; -- b3 = b2 + strlen (save_button) + i + 4; -+ b2 = b1 + mbstrlen (ok_button) + i + 6; -+ b3 = b2 + mbstrlen (save_button) + i + 4; - - i18n_config_flag = 1; - } -diff -up mc-4.6.2-pre1/src/menu.h.utf8 mc-4.6.2-pre1/src/menu.h ---- mc-4.6.2-pre1/src/menu.h.utf8 2004-12-03 20:17:47.000000000 +0100 -+++ mc-4.6.2-pre1/src/menu.h 2008-02-25 14:56:22.000000000 +0100 -@@ -21,6 +21,8 @@ typedef struct Menu { - menu_entry *entries; - int start_x; /* position relative to menubar start */ - char *help_node; -+ wchar_t **wentries; -+ wchar_t *wname; - } Menu; - - extern int menubar_visible; -diff -up mc-4.6.2-pre1/src/file.c.utf8 mc-4.6.2-pre1/src/file.c ---- mc-4.6.2-pre1/src/file.c.utf8 2007-02-22 15:29:11.000000000 +0100 -+++ mc-4.6.2-pre1/src/file.c 2008-02-25 14:56:22.000000000 +0100 -@@ -161,15 +161,20 @@ static const char * - do_transform_source (FileOpContext *ctx, const char *source) - { - size_t j, k, l, len; -- const char *fnsource = x_basename (source); -+ char *fnsource = g_strdup (x_basename (source)); - int next_reg; - enum CaseConvs case_conv = NO_CONV; - static char fntarget[MC_MAXPATHLEN]; - -+#ifdef UTF8 -+ fix_utf8(fnsource); -+#endif -+ - len = strlen (fnsource); - j = re_match (&ctx->rx, fnsource, len, 0, &ctx->regs); - if (j != len) { - transform_error = FILE_SKIP; -+ g_free (fnsource); - return NULL; - } - for (next_reg = 1, j = 0, k = 0; j < strlen (ctx->dest_mask); j++) { -@@ -213,6 +218,7 @@ do_transform_source (FileOpContext *ctx, - || ctx->regs.start[next_reg] < 0) { - message (1, MSG_ERROR, _(" Invalid target mask ")); - transform_error = FILE_ABORT; -+ g_free(fnsource); - return NULL; - } - for (l = (size_t) ctx->regs.start[next_reg]; -@@ -227,6 +233,7 @@ do_transform_source (FileOpContext *ctx, - } - } - fntarget[k] = 0; -+ g_free(fnsource); - return fntarget; - } - -@@ -1688,13 +1695,13 @@ panel_operate_generate_prompt (const WPa - *dp = '\0'; - - if (single_source) { -- i = fmd_xlen - strlen (format_string) - 4; -+ i = fmd_xlen - mbstrlen (format_string) - 4; - g_snprintf (cmd_buf, sizeof (cmd_buf), format_string, - name_trunc (single_source, i)); - } else { - g_snprintf (cmd_buf, sizeof (cmd_buf), format_string, - panel->marked); -- i = strlen (cmd_buf) + 6 - fmd_xlen; -+ i = mbstrlen (cmd_buf) + 6 - fmd_xlen; - if (i > 0) { - fmd_xlen += i; - fmd_init_i18n (TRUE); /* to recalculate positions of child widgets */ -diff -up mc-4.6.2-pre1/src/main.c.utf8 mc-4.6.2-pre1/src/main.c ---- mc-4.6.2-pre1/src/main.c.utf8 2006-09-22 17:14:58.000000000 +0200 -+++ mc-4.6.2-pre1/src/main.c 2008-02-25 14:56:22.000000000 +0100 -@@ -704,7 +704,7 @@ load_prompt (int fd, void *unused) - int prompt_len; - - tmp_prompt = strip_ctrl_codes (subshell_prompt); -- prompt_len = strlen (tmp_prompt); -+ prompt_len = mbstrlen (tmp_prompt); - - /* Check for prompts too big */ - if (COLS > 8 && prompt_len > COLS - 8) { -@@ -1610,7 +1610,11 @@ update_xterm_title_path (void) - if (xterm_flag && xterm_title) { - p = s = g_strdup (strip_home_and_password (current_panel->cwd)); - do { -+#ifndef UTF8 - if (!is_printable ((unsigned char) *s)) -+#else /* UTF8 */ -+ if (*(unsigned char *)s < ' ') -+#endif /* UTF8 */ - *s = '?'; - } while (*++s); - fprintf (stdout, "\33]0;mc - %s\7", p); -diff -up mc-4.6.2-pre1/src/find.c.utf8 mc-4.6.2-pre1/src/find.c ---- mc-4.6.2-pre1/src/find.c.utf8 2006-02-04 12:03:35.000000000 +0100 -+++ mc-4.6.2-pre1/src/find.c 2008-02-25 14:56:22.000000000 +0100 -@@ -217,7 +217,7 @@ find_parameters (char **start_dir, char - int l1, maxlen = 0; - - while (i--) { -- l1 = strlen (labs[i] = _(labs[i])); -+ l1 = mbstrlen (labs[i] = _(labs[i])); - if (l1 > maxlen) - maxlen = l1; - } -@@ -226,7 +226,7 @@ find_parameters (char **start_dir, char - FIND_X = i; - - for (i = sizeof (buts) / sizeof (buts[0]), l1 = 0; i--;) { -- l1 += strlen (buts[i] = _(buts[i])); -+ l1 += mbstrlen (buts[i] = _(buts[i])); - } - l1 += 21; - if (l1 > FIND_X) -@@ -235,8 +235,8 @@ find_parameters (char **start_dir, char - ilen = FIND_X - 7 - maxlen; /* for the case of very long buttons :) */ - istart = FIND_X - 3 - ilen; - -- b1 = b0 + strlen (buts[0]) + 7; -- b2 = FIND_X - (strlen (buts[2]) + 6); -+ b1 = b0 + mbstrlen (buts[0]) + 7; -+ b2 = FIND_X - (mbstrlen (buts[2]) + 6); - - i18n_flag = 1; - case_label = _(case_label); -@@ -863,7 +863,7 @@ setup_gui (void) - if (!i18n_flag) { - register int i = sizeof (fbuts) / sizeof (fbuts[0]); - while (i--) -- fbuts[i].len = strlen (fbuts[i].text = _(fbuts[i].text)) + 3; -+ fbuts[i].len = mbstrlen (fbuts[i].text = _(fbuts[i].text)) + 3; - fbuts[2].len += 2; /* DEFPUSH_BUTTON */ - i18n_flag = 1; - } -@@ -1028,7 +1028,7 @@ find_file (char *start_dir, char *patter - - if (!next_free) /* first turn i.e clean old list */ - panel_clean_dir (current_panel); -- list->list[next_free].fnamelen = strlen (name); -+ list->list[next_free].fnamelen = mbstrlen (name); - list->list[next_free].fname = name; - list->list[next_free].f.marked = 0; - list->list[next_free].f.link_to_dir = link_to_dir; -diff -up mc-4.6.2-pre1/src/view.c.utf8 mc-4.6.2-pre1/src/view.c ---- mc-4.6.2-pre1/src/view.c.utf8 2006-12-30 14:16:54.000000000 +0100 -+++ mc-4.6.2-pre1/src/view.c 2008-02-25 14:56:22.000000000 +0100 -@@ -43,6 +43,10 @@ - #include - #include - -+#ifdef UTF8 -+#include -+#endif /* UTF8 */ -+ - #include "global.h" - #include "tty.h" - #include "cmd.h" /* For view_other_cmd */ -@@ -1642,7 +1646,7 @@ view_display_status (WView *view) - hline (' ', width); - - file_label = _("File: %s"); -- file_label_width = strlen (file_label) - 2; -+ file_label_width = mbstrlen (file_label) - 2; - file_name = view->filename ? view->filename - : view->command ? view->command - : ""; -@@ -1910,6 +1914,12 @@ view_display_text (WView * view) - offset_type from; - int c; - struct hexedit_change_node *curr = view->change_list; -+#ifdef UTF8 -+ mbstate_t mbs; -+ char mbbuf[MB_LEN_MAX]; -+ int mblen; -+ wchar_t wc; -+#endif /* UTF8 */ - - view_display_clean (view); - view_display_ruler (view); -@@ -1922,8 +1932,37 @@ view_display_text (WView * view) - - tty_setcolor (NORMAL_COLOR); - for (row = 0, col = 0; row < height && (c = get_byte (view, from)) != -1; from++) { -- -+#ifndef UTF8 - if (view->text_nroff_mode && c == '\b') { -+#else /* UTF8 */ -+ mblen = 1; -+ mbbuf[0] = convert_to_display_c (c); -+ -+ while (mblen < MB_LEN_MAX) { -+ int res; -+ memset (&mbs, 0, sizeof (mbs)); -+ res = mbrtowc (&wc, mbbuf, mblen, &mbs); -+ if (res <= 0 && res != -2) { -+ wc = '.'; -+ mblen = 1; -+ break; -+ } -+ if (res == mblen) -+ break; -+ -+ mbbuf[mblen] = convert_to_display_c (get_byte (view, from + mblen)); -+ mblen++; -+ } -+ -+ if (mblen == MB_LEN_MAX) { -+ wc = '.'; -+ mblen = 1; -+ } -+ -+ from += mblen - 1; -+ -+ if (view->text_nroff_mode && wc == '\b') { -+#endif /* UTF8 */ - int c_prev; - int c_next; - -@@ -1988,10 +2027,17 @@ view_display_text (WView * view) - if (col >= view->dpy_text_column - && col - view->dpy_text_column < width) { - widget_move (view, top + row, left + (col - view->dpy_text_column)); -+#ifndef UTF8 - c = convert_to_display_c (c); - if (!is_printable (c)) - c = '.'; - tty_print_char (c); -+#else -+ wc = convert_to_display_c (wc); -+ if (!iswprint (wc)) -+ wc = '.'; -+ tty_print_char (wc); -+#endif - } - col++; - tty_setcolor (NORMAL_COLOR); -diff -up mc-4.6.2-pre1/src/dialog.c.utf8 mc-4.6.2-pre1/src/dialog.c ---- mc-4.6.2-pre1/src/dialog.c.utf8 2005-09-05 05:20:27.000000000 +0200 -+++ mc-4.6.2-pre1/src/dialog.c 2008-02-25 14:56:22.000000000 +0100 -@@ -166,7 +166,7 @@ common_dialog_repaint (struct Dlg_head * - - if (h->title) { - attrset (DLG_HOT_NORMALC (h)); -- dlg_move (h, space, (h->cols - strlen (h->title)) / 2); -+ dlg_move (h, space, (h->cols - mbstrlen (h->title)) / 2); - addstr (h->title); - } - } -diff -up mc-4.6.2-pre1/src/util.h.utf8 mc-4.6.2-pre1/src/util.h ---- mc-4.6.2-pre1/src/util.h.utf8 2006-02-03 18:04:17.000000000 +0100 -+++ mc-4.6.2-pre1/src/util.h 2008-02-25 14:56:22.000000000 +0100 -@@ -103,6 +103,13 @@ void init_uid_gid_cache (void); - char *get_group (int); - char *get_owner (int); - -+void fix_utf8(char *str); -+size_t mbstrlen (const char *); -+wchar_t *mbstr_to_wchar (const char *); -+char *wchar_to_mbstr (const wchar_t *); -+char *utf8_to_local(char *str); -+ -+ - #define MAX_I18NTIMELENGTH 14 - #define MIN_I18NTIMELENGTH 10 - #define STD_I18NTIMELENGTH 12 -diff -up mc-4.6.2-pre1/src/boxes.c.utf8 mc-4.6.2-pre1/src/boxes.c ---- mc-4.6.2-pre1/src/boxes.c.utf8 2006-02-28 17:15:21.000000000 +0100 -+++ mc-4.6.2-pre1/src/boxes.c 2008-02-25 14:56:22.000000000 +0100 -@@ -153,23 +153,23 @@ display_init (int radio_sel, char *init_ - display_title = _(display_title); - for (i = 0; i < LIST_TYPES; i++) { - displays[i] = _(displays[i]); -- if ((l = strlen (displays[i])) > maxlen) -+ if ((l = mbstrlen (displays[i])) > maxlen) - maxlen = l; - } - -- i = strlen (ok_button) + 5; -- l = strlen (cancel_button) + 3; -+ i = mbstrlen (ok_button) + 5; -+ l = mbstrlen (cancel_button) + 3; - l = max (i, l); - - i = maxlen + l + 16; - if (i > DISPLAY_X) - DISPLAY_X = i; - -- i = strlen (user_mini_status) + 13; -+ i = mbstrlen (user_mini_status) + 13; - if (i > DISPLAY_X) - DISPLAY_X = i; - -- i = strlen (display_title) + 10; -+ i = mbstrlen (display_title) + 10; - if (i > DISPLAY_X) - DISPLAY_X = i; - -@@ -288,20 +288,20 @@ sort_box (sortfn *sort_fn, int *reverse, - int maxlen = 0; - for (i = SORT_TYPES - 1; i >= 0; i--) { - sort_orders_names[i] = _(sort_orders[i].sort_name); -- r = strlen (sort_orders_names[i]); -+ r = mbstrlen (sort_orders_names[i]); - if (r > maxlen) - maxlen = r; - } - - check_pos = maxlen + 9; - -- r = strlen (reverse_label) + 4; -- i = strlen (case_label) + 4; -+ r = mbstrlen (reverse_label) + 4; -+ i = mbstrlen (case_label) + 4; - if (i > r) - r = i; - -- l = strlen (ok_button) + 6; -- i = strlen (cancel_button) + 4; -+ l = mbstrlen (ok_button) + 6; -+ i = mbstrlen (cancel_button) + 4; - if (i > l) - l = i; - -@@ -310,7 +310,7 @@ sort_box (sortfn *sort_fn, int *reverse, - if (i > SORT_X) - SORT_X = i; - -- i = strlen (sort_title) + 6; -+ i = mbstrlen (sort_title) + 6; - if (i > SORT_X) - SORT_X = i; - -@@ -408,7 +408,7 @@ confirm_box (void) - while (i--) - { - conf_widgets [i].text = _(conf_widgets [i].text); -- l1 = strlen (conf_widgets [i].text) + 3; -+ l1 = mbstrlen (conf_widgets [i].text) + 3; - if (l1 > maxlen) - maxlen = l1; - } -@@ -423,8 +423,8 @@ confirm_box (void) - * And this for the case when buttons with some space to the right - * do not fit within 2/6 - */ -- l1 = strlen (conf_widgets [0].text) + 3; -- i = strlen (conf_widgets [1].text) + 5; -+ l1 = mbstrlen (conf_widgets [0].text) + 3; -+ i = mbstrlen (conf_widgets [1].text) + 5; - if (i > l1) - l1 = i; - -@@ -497,11 +497,11 @@ display_bits_box (void) - { - display_widgets [i].text = _(display_widgets[i].text); - display_bits_str [i] = _(display_bits_str [i]); -- l1 = strlen (display_bits_str [i]); -+ l1 = mbstrlen (display_bits_str [i]); - if (l1 > maxlen) - maxlen = l1; - } -- l1 = strlen (display_widgets [2].text); -+ l1 = mbstrlen (display_widgets [2].text); - if (l1 > maxlen) - maxlen = l1; - -@@ -509,8 +509,8 @@ display_bits_box (void) - display_bits.xlen = (maxlen + 5) * 6 / 4; - - /* See above confirm_box */ -- l1 = strlen (display_widgets [0].text) + 3; -- i = strlen (display_widgets [1].text) + 5; -+ l1 = mbstrlen (display_widgets [0].text) + 3; -+ i = mbstrlen (display_widgets [1].text) + 5; - if (i > l1) - l1 = i; - -@@ -605,7 +605,7 @@ init_disp_bits_box (void) - - cpname = _("&Select"); - add_widget (dbits_dlg, -- button_new (4, DISPX - 8 - strlen (cpname), B_USER, -+ button_new (4, DISPX - 8 - mbstrlen (cpname), B_USER, - NORMAL_BUTTON, cpname, sel_charset_button)); - - return dbits_dlg; -@@ -816,7 +816,7 @@ cd_dialog (void) - quick_widgets [1].y_divisions = - quick_widgets [0].y_divisions = Quick_input.ylen = 5; - -- len = strlen (quick_widgets [1].text); -+ len = mbstrlen (quick_widgets [1].text); - - quick_widgets [0].relative_x = - quick_widgets [1].relative_x + len + 1; -@@ -975,7 +975,7 @@ jobs_cmd (void) - { - job_buttons [i].name = _(job_buttons [i].name); - -- len = strlen (job_buttons [i].name) + 4; -+ len = mbstrlen (job_buttons [i].name) + 4; - JOBS_X = max (JOBS_X, startx + len + 3); - - job_buttons [i].xpos = startx; -@@ -984,7 +984,7 @@ jobs_cmd (void) - - /* Last button - Ok a.k.a. Cancel :) */ - job_buttons [n_buttons - 1].xpos = -- JOBS_X - strlen (job_buttons [n_buttons - 1].name) - 7; -+ JOBS_X - mbstrlen (job_buttons [n_buttons - 1].name) - 7; - - i18n_flag = 1; - } -@@ -1042,7 +1042,7 @@ vfs_smb_get_authinfo (const char *host, - - while (i--) - { -- l1 = strlen (labs [i] = _(labs [i])); -+ l1 = mbstrlen (labs [i] = _(labs [i])); - if (l1 > maxlen) - maxlen = l1; - } -@@ -1052,7 +1052,7 @@ vfs_smb_get_authinfo (const char *host, - - for (i = sizeof(buts)/sizeof(buts[0]), l1 = 0; i--; ) - { -- l1 += strlen (buts [i] = _(buts [i])); -+ l1 += mbstrlen (buts [i] = _(buts [i])); - } - l1 += 15; - if (l1 > dialog_x) -@@ -1061,7 +1061,7 @@ vfs_smb_get_authinfo (const char *host, - ilen = dialog_x - 7 - maxlen; /* for the case of very long buttons :) */ - istart = dialog_x - 3 - ilen; - -- b2 = dialog_x - (strlen(buts[1]) + 6); -+ b2 = dialog_x - (mbstrlen(buts[1]) + 6); - - i18n_flag = 1; - } -diff -up mc-4.6.2-pre1/src/help.c.utf8 mc-4.6.2-pre1/src/help.c ---- mc-4.6.2-pre1/src/help.c.utf8 2007-01-20 12:40:45.000000000 +0100 -+++ mc-4.6.2-pre1/src/help.c 2008-02-25 14:56:22.000000000 +0100 -@@ -447,10 +447,28 @@ static void help_show (Dlg_head *h, cons - #ifndef HAVE_SLANG - addch (acs_map [c]); - #else -+#if defined(UTF8) && SLANG_VERSION < 20000 -+ SLsmg_draw_object (h->y + line + 2, h->x + col + 2, acs_map [c]); -+#else - SLsmg_draw_object (h->y + line + 2, h->x + col + 2, c); -+#endif /* UTF8 */ - #endif -+ } else { -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) { -+ int len; -+ mbstate_t mbs; -+ wchar_t wc; -+ memset (&mbs, 0, sizeof (mbs)); -+ len = mbrtowc(&wc, p, MB_CUR_MAX, &mbs); -+ if (len <= 0) len = 1; /* skip broken multibyte chars */ -+ -+ SLsmg_write_nwchars(&wc, 1); -+ p += len - 1; - } else -+#endif - addch (c); -+ } - col++; - break; - } -@@ -803,6 +821,12 @@ interactive_display (const char *filenam - message (1, MSG_ERROR, _(" Cannot open file %s \n %s "), filename ? filename : hlpfile, - unix_error_string (errno)); - } -+ else -+ { -+ char *conv = utf8_to_local(data); -+ g_free(data); -+ data = conv; -+ } - - if (!filename) - g_free (hlpfile); -diff -up mc-4.6.2-pre1/src/achown.c.utf8 mc-4.6.2-pre1/src/achown.c ---- mc-4.6.2-pre1/src/achown.c.utf8 2005-09-05 03:36:58.000000000 +0200 -+++ mc-4.6.2-pre1/src/achown.c 2008-02-25 14:56:22.000000000 +0100 -@@ -584,6 +584,12 @@ init_chown_advanced (void) - b_att[2] = button_new (XTRACT (6)); - b_user = button_new (XTRACT (5)); - b_group = button_new (XTRACT (4)); -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) { -+ b_user->text = g_realloc (b_user->text, MB_CUR_MAX * 15 + 1); -+ b_group->text = g_realloc (b_group->text, MB_CUR_MAX * 15 + 1); -+ } -+#endif - - add_widget (ch_dlg, b_group); - add_widget (ch_dlg, b_user); -diff -up mc-4.6.2-pre1/src/tty.c.utf8 mc-4.6.2-pre1/src/tty.c ---- mc-4.6.2-pre1/src/tty.c.utf8 2006-05-23 09:38:59.000000000 +0200 -+++ mc-4.6.2-pre1/src/tty.c 2008-02-25 14:56:22.000000000 +0100 -@@ -134,10 +134,12 @@ tty_print_char(int c) - * defined or not. Congratulations! At least, they left the API call - * for SLsmg_write_nchars as it has always been. - */ -- char ch; -- -- ch = c; -- SLsmg_write_nchars(&ch, 1); -+ -+ /* The above comment is a nonsense, SLsmg_write_char(c) works pretty -+ * good for me. So please don't mess with Red Hat people. -+ * Jindrich Novy (jnovy@redhat.com) -+ */ -+ SLsmg_write_char(c); - #else - addch(c); - #endif -diff -up mc-4.6.2-pre1/src/util.c.utf8 mc-4.6.2-pre1/src/util.c ---- mc-4.6.2-pre1/src/util.c.utf8 2005-11-03 03:18:38.000000000 +0100 -+++ mc-4.6.2-pre1/src/util.c 2008-02-25 14:56:22.000000000 +0100 -@@ -33,7 +33,11 @@ - #include - #include - #include -+#include -+#include -+#include - -+#include "tty.h" - #include "global.h" - #include "profile.h" - #include "main.h" /* mc_home */ -@@ -45,9 +49,39 @@ - #include "charsets.h" - #endif - -+#ifdef UTF8 -+#include -+#endif -+ - static const char app_text [] = "Midnight-Commander"; - int easy_patterns = 1; - -+#if SLANG_VERSION >= 20000 -+void SLsmg_write_nwchars(wchar_t *s, size_t n) -+{ -+ if (SLsmg_is_utf8_mode()) { /* slang can handle it directly */ -+ while(n-- && *s) -+ SLsmg_write_char(*s++); -+ } -+ else { /* convert wchars back to 8bit encoding */ -+ mbstate_t mbs; -+ memset (&mbs, 0, sizeof (mbs)); -+ while (n-- && *s) { -+ char buf[MB_LEN_MAX + 1]; /* should use 1 char, but to be sure */ -+ if (*s < 0x80) { -+ SLsmg_write_char(*s++); /* ASCII */ -+ } -+ else { -+ if (wcrtomb(buf, *s++, &mbs) == 1) -+ SLsmg_write_char((wchar_t)(buf[0])); -+ else -+ SLsmg_write_char('?'); /* should not happen */ -+ } -+ } -+ } -+} -+#endif -+ - extern void str_replace(char *s, char from, char to) - { - for (; *s != '\0'; s++) { -@@ -78,9 +112,106 @@ is_8bit_printable (unsigned char c) - return (c > 31 && c != 127 && c != 155); - } - -+size_t -+mbstrlen (const char *str) -+{ -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) { -+ size_t width = 0; -+ -+ for (; *str; str++) { -+ wchar_t c; -+ size_t len; -+ -+ len = mbrtowc (&c, str, MB_CUR_MAX, NULL); -+ -+ if (len == (size_t)(-1) || len == (size_t)(-2)) break; -+ -+ if (len > 0) { -+ int wcsize = wcwidth(c); -+ width += wcsize > 0 ? wcsize : 0; -+ str += len-1; -+ } -+ } -+ -+ return width; -+ } else -+#endif -+ return strlen (str); -+} -+ -+#ifdef UTF8 -+ -+void -+fix_utf8(char *str) -+{ -+ mbstate_t mbs; -+ -+ char *p = str; -+ -+ while (*p) { -+ int len; -+ memset (&mbs, 0, sizeof (mbs)); -+ len = mbrlen(p, MB_CUR_MAX, &mbs); -+ if (len == -1) { -+ *p = '?'; -+ p++; -+ } else if (len > 0) { -+ p += len; -+ } else { -+ p++; -+ } -+ } -+} -+#endif -+ -+ -+ -+#ifdef UTF8 -+wchar_t * -+mbstr_to_wchar (const char *str) -+{ -+ int len = mbstrlen(str); -+ wchar_t *buf = g_malloc((len+1) * sizeof(wchar_t)); -+ mbstate_t mbs; -+ memset (&mbs, 0, sizeof (mbs)); -+ mbsrtowcs (buf, &str, len, &mbs); -+ buf[len] = 0; -+ return buf; -+} -+ -+char * -+wchar_to_mbstr (const wchar_t *wstr) -+{ -+ mbstate_t mbs; -+ const wchar_t *wstr2; -+ char * string; -+ int len; -+ -+ memset (&mbs, 0, sizeof (mbs)); -+ wstr2 = wstr; -+ len = wcsrtombs(NULL, &wstr2, 0, &mbs); -+ if (len <= 0) -+ return NULL; -+ -+ string = g_malloc(len + 1); -+ -+ wstr2 = wstr; -+ wcsrtombs(string, &wstr2, len, &mbs); -+ string[len] = 0; -+ return string; -+} -+#endif -+ -+ -+ - int - is_printable (int c) - { -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) -+ return iswprint (c); -+#endif - c &= 0xff; - - #ifdef HAVE_CHARSET -@@ -98,7 +229,7 @@ is_printable (int c) - #endif /* !HAVE_CHARSET */ - } - --/* Calculates the message dimensions (lines and columns) */ -+/* Calculates the message dimension in columns and lines. */ - void - msglen (const char *text, int *lines, int *columns) - { -@@ -111,8 +242,21 @@ msglen (const char *text, int *lines, in - nlines++; - colindex = 0; - } else { -+#ifndef UTF8 - colindex++; - if (colindex > ncolumns) -+#else /* UTF8 */ -+ size_t len; -+ wchar_t c; -+ -+ len = mbrtowc (&c, text, MB_CUR_MAX, NULL); -+ if (len > 0 && len != (size_t)(-1) && len != (size_t)(-2)) { -+ int wcsize = wcwidth(c); -+ colindex += wcsize > 0 ? wcsize-1 : -1; -+ text += len-1; -+ } -+ if (++colindex > ncolumns) -+#endif /* UTF8 */ - ncolumns = colindex; - } - } -@@ -206,7 +350,24 @@ name_quote (const char *s, int quote_per - *d++ = '\\'; - break; - } -+#ifndef UTF8 - *d = *s; -+#else /* UTF8 */ -+ { -+ mbstate_t mbs; -+ int len; -+ memset (&mbs, 0, sizeof (mbs)); -+ len = mbrlen(s, MB_CUR_MAX, &mbs); -+ if (len > 0) { -+ while (len-- > 1) -+ *d++ = *s++; -+ *d = *s; -+ } else { -+ *d = '?'; -+ } -+ -+ } -+#endif /* UTF8 */ - } - *d = '\0'; - return ret; -@@ -228,25 +389,90 @@ const char * - name_trunc (const char *txt, int trunc_len) - { - static char x[MC_MAXPATHLEN + MC_MAXPATHLEN]; -- int txt_len; -+ int txt_len, first, skip; - char *p; -+ const char *str; - - if ((size_t) trunc_len > sizeof (x) - 1) { - trunc_len = sizeof (x) - 1; - } -- txt_len = strlen (txt); -- if (txt_len <= trunc_len) { -- strcpy (x, txt); -- } else { -- int y = (trunc_len / 2) + (trunc_len % 2); -- strncpy (x, txt, y); -- strncpy (x + y, txt + txt_len - (trunc_len / 2), trunc_len / 2); -- x[y] = '~'; -- } -- x[trunc_len] = 0; -- for (p = x; *p; p++) -- if (!is_printable (*p)) -- *p = '?'; -+ txt_len = mbstrlen (txt); -+ first = 0; -+ skip = 0; -+ if (txt_len > trunc_len) { -+ first = trunc_len / 2; -+ skip = txt_len - trunc_len + 1; -+ } -+ -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) { -+ mbstate_t s; -+ int mbmax; -+ -+ str = txt; -+ memset (&s, 0, sizeof (s)); -+ mbmax = MB_CUR_MAX; -+ p = x; -+ while (p < x + sizeof (x) - 1 && trunc_len) { -+ wchar_t wc; -+ int len; -+ -+ len = mbrtowc (&wc, str, mbmax, &s); -+ if (!len) -+ break; -+ if (len < 0) { -+ memset (&s, 0, sizeof (s)); -+ *p = '?'; -+ len = 1; -+ str++; -+ } else if (!is_printable (wc)) { -+ *p = '?'; -+ str += len; -+ len = 1; -+ } else if (p >= x + sizeof (x) - len) -+ break; -+ else { -+ memcpy (p, str, len); -+ str += len; -+ } -+ if (first) { -+ --trunc_len; -+ --first; -+ p += len; -+ if (!first && p < x + sizeof (x) - 1 && trunc_len) { -+ *p++ = '~'; -+ --trunc_len; -+ } -+ } else if (skip) -+ --skip; -+ else { -+ --trunc_len; -+ p += len; -+ } -+ } -+ } else -+#endif -+ { -+ str = txt; -+ p = x; -+ while (p < x + sizeof (x) - 1) { -+ if (*str == '\0') -+ break; -+ else if (!is_printable (*str)) -+ *p++ = '?'; -+ else -+ *p++ = *str; -+ ++str; -+ if (first) { -+ --first; -+ if (!first) { -+ *p++ = '~'; -+ str += skip; -+ } -+ } -+ } -+ } -+ *p = '\0'; - return x; - } - -@@ -678,11 +904,61 @@ load_file (const char *filename) - } - - char * -+utf8_to_local(char *str) -+{ -+ iconv_t cd; -+ size_t buflen = strlen(str); -+ char *output; -+ int retry = 1; -+ -+ cd = iconv_open (nl_langinfo(CODESET), "UTF-8"); -+ if (cd == (iconv_t) -1) { -+ return g_strdup(str); -+ } -+ -+ output = g_malloc(buflen + 1); -+ -+ while (retry) -+ { -+ char *wrptr = output; -+ char *inptr = str; -+ size_t insize = buflen; -+ size_t avail = buflen; -+ size_t nconv; -+ -+ nconv = iconv (cd, &inptr, &insize, &wrptr, &avail); -+ if (nconv == (size_t) -1) -+ { -+ if (errno == E2BIG) -+ { -+ buflen *= 2; -+ g_free(output); -+ output = g_malloc(buflen + 1); -+ } -+ else -+ { -+ g_free(output); -+ return g_strdup(str); -+ } -+ } -+ else { -+ retry = 0; -+ *wrptr = 0; -+ } -+ } -+ -+ iconv_close (cd); -+ -+ return output; -+} -+ -+char * - load_mc_home_file (const char *filename, char **allocated_filename) - { - char *hintfile_base, *hintfile; - char *lang; - char *data; -+ char *conv_data; - - hintfile_base = concat_dir_and_file (mc_home, filename); - lang = guess_message_value (); -@@ -715,7 +991,10 @@ load_mc_home_file (const char *filename, - else - g_free (hintfile); - -- return data; -+ conv_data = utf8_to_local(data); -+ g_free(data); -+ -+ return conv_data; - } - - /* Check strftime() results. Some systems (i.e. Solaris) have different -@@ -724,12 +1003,14 @@ size_t - i18n_checktimelength (void) - { - size_t length, a, b; -- char buf [MAX_I18NTIMELENGTH + 1]; -+ char buf [4 * MAX_I18NTIMELENGTH + 1]; - time_t testtime = time (NULL); - -- a = strftime (buf, sizeof(buf)-1, _("%b %e %H:%M"), localtime(&testtime)); -- b = strftime (buf, sizeof(buf)-1, _("%b %e %Y"), localtime(&testtime)); -- -+ strftime (buf, sizeof(buf)-1, _("%b %e %H:%M"), localtime(&testtime)); -+ a = mbstrlen (buf); -+ strftime (buf, sizeof(buf)-1, _("%b %e %Y"), localtime(&testtime)); -+ b = mbstrlen (buf); -+ - length = max (a, b); - - /* Don't handle big differences. Use standard value (email bug, please) */ -@@ -742,15 +1023,12 @@ i18n_checktimelength (void) - const char * - file_date (time_t when) - { -- static char timebuf [MAX_I18NTIMELENGTH + 1]; -+ static char timebuf [4 * MAX_I18NTIMELENGTH + 1]; - time_t current_time = time ((time_t) 0); -- static size_t i18n_timelength = 0; - static const char *fmtyear, *fmttime; - const char *fmt; - -- if (i18n_timelength == 0){ -- i18n_timelength = i18n_checktimelength() + 1; -- -+ if (fmtyear == NULL) { - /* strftime() format string for old dates */ - fmtyear = _("%b %e %Y"); - /* strftime() format string for recent dates */ -@@ -770,7 +1048,7 @@ file_date (time_t when) - else - fmt = fmttime; - -- strftime (timebuf, i18n_timelength, fmt, localtime(&when)); -+ strftime (timebuf, sizeof (timebuf) - 1, fmt, localtime(&when)); - return timebuf; - } - -@@ -900,10 +1178,27 @@ strip_ctrl_codes (char *s) - r++; - continue; - } -- -+#ifndef UTF8 - if (is_printable(*r)) - *w++ = *r; - ++r; -+#else /* UTF8 */ -+ { -+ mbstate_t mbs; -+ int len; -+ memset (&mbs, 0, sizeof (mbs)); -+ len = mbrlen(r, MB_CUR_MAX, &mbs); -+ -+ if (len > 0 && (unsigned char)*r >= ' ') -+ while (len--) -+ *w++ = *r++; -+ else { -+ if (len == -1) -+ *w++ = '?'; -+ r++; -+ } -+ } -+#endif /* UTF8 */ - } - *w = 0; - return s; -diff -up mc-4.6.2-pre1/src/screen.c.utf8 mc-4.6.2-pre1/src/screen.c ---- mc-4.6.2-pre1/src/screen.c.utf8 2007-08-24 14:22:29.000000000 +0200 -+++ mc-4.6.2-pre1/src/screen.c 2008-02-25 14:56:22.000000000 +0100 -@@ -171,21 +171,56 @@ add_permission_string (char *dest, int w - static const char * - string_file_name (file_entry *fe, int len) - { -- static char buffer [MC_MAXPATHLEN + 1]; - size_t i; - -- for (i = 0; i < sizeof(buffer) - 1; i++) { -- char c; -+#ifdef UTF8 -+ static char buffer [BUF_SMALL * 4]; -+ mbstate_t s; -+ int mbmax = MB_CUR_MAX; -+ const char *str = fe->fname; - -- c = fe->fname[i]; -+ memset (&s, 0, sizeof (s)); -+#else -+ static char buffer [BUF_SMALL]; -+#endif - -- if (!c) -- break; -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) -+ for (i = 0; i < sizeof (buffer) - 1; i++) { -+ wchar_t wc; -+ int len; - -- if (!is_printable(c)) -- c = '?'; -+ len = mbrtowc (&wc, str, mbmax, &s); -+ if (!len) -+ break; -+ if (len < 0) { -+ memset (&s, 0, sizeof (s)); -+ buffer[i] = '?'; -+ str++; -+ continue; -+ } -+ if (!is_printable (wc)) { -+ buffer[i] = '?'; -+ str++; -+ continue; -+ } -+ if (i >= sizeof (buffer) - len) -+ break; -+ memcpy (buffer + i, str, len); -+ i += len - 1; -+ str += len; -+ } else -+#endif -+ for (i = 0; i < sizeof(buffer) - 1; i++) { -+ char c; -+ -+ c = fe->fname[i]; - -- buffer[i] = c; -+ if (!c) break; -+ -+ if (!is_printable(c)) c = '?'; -+ -+ buffer[i] = c; - } - - buffer[i] = 0; -@@ -450,42 +485,6 @@ static struct { - { "dot", 1, 0, J_RIGHT, " ", 0, string_dot, NULL }, - }; - --static char * --to_buffer (char *dest, int just_mode, int len, const char *txt) --{ -- int txtlen = strlen (txt); -- int still, over; -- -- /* Fill buffer with spaces */ -- memset (dest, ' ', len); -- -- still = (over=(txtlen > len)) ? (txtlen - len) : (len - txtlen); -- -- switch (HIDE_FIT(just_mode)){ -- case J_LEFT: -- still = 0; -- break; -- case J_CENTER: -- still /= 2; -- break; -- case J_RIGHT: -- default: -- break; -- } -- -- if (over){ -- if (IS_FIT(just_mode)) -- strcpy (dest, name_trunc(txt, len)); -- else -- strncpy (dest, txt+still, len); -- } else -- strncpy (dest+still, txt, txtlen); -- -- dest[len] = '\0'; -- -- return (dest + len); --} -- - static int - file_compute_color (int attr, file_entry *fe) - { -@@ -539,14 +538,18 @@ file_compute_color (int attr, file_entry - - /* Formats the file number file_index of panel in the buffer dest */ - static void --format_file (char *dest, int limit, WPanel *panel, int file_index, int width, int attr, int isstatus) -+format_file (WPanel *panel, int file_index, int width, int attr, int isstatus) - { - int color, length, empty_line; - const char *txt; -- char *old_pos; -- char *cdest = dest; - format_e *format, *home; - file_entry *fe; -+#ifdef UTF8 -+ char buffer[BUF_MEDIUM * sizeof (wchar_t)]; -+#else -+ char buffer[BUF_MEDIUM]; -+#endif -+ int txtwidth = 0; - - length = 0; - empty_line = (file_index >= panel->count); -@@ -564,34 +567,137 @@ format_file (char *dest, int limit, WPan - break; - - if (format->string_fn){ -- int len; -+ int len, still, over, perm, txtlen, wide; - - if (empty_line) - txt = " "; - else - txt = (*format->string_fn)(fe, format->field_len); - -- old_pos = cdest; -- - len = format->field_len; - if (len + length > width) - len = width - length; -- if (len + (cdest - dest) > limit) -- len = limit - (cdest - dest); -+ if (len >= BUF_MEDIUM) -+ len = BUF_MEDIUM - 1; - if (len <= 0) - break; -- cdest = to_buffer (cdest, format->just_mode, len, txt); -- length += len; - -- attrset (color); -+ perm = 0; -+ if (permission_mode) { -+ if (!strcmp(format->id, "perm")) -+ perm = 1; -+ else if (!strcmp(format->id, "mode")) -+ perm = 2; -+ } - -- if (permission_mode && !strcmp(format->id, "perm")) -- add_permission_string (old_pos, format->field_len, fe, attr, color, 0); -- else if (permission_mode && !strcmp(format->id, "mode")) -- add_permission_string (old_pos, format->field_len, fe, attr, color, 1); -- else -- addstr (old_pos); -+ wide = 0; -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode && !empty_line && !perm) { -+ mbstate_t s; -+ const char *str = txt; -+ -+ memset (&s, 0, sizeof (s)); -+ txtlen = mbsrtowcs ((wchar_t *) buffer, &str, -+ sizeof (buffer) / sizeof (wchar_t), &s); -+ if (txtlen < 0) { -+ txt = " "; -+ txtlen = 1; -+ } else { -+ wide = 1; -+ txtwidth = wcswidth((wchar_t*)buffer, txtlen); -+ } -+ } else -+#endif -+ { -+ txtlen = mbstrlen (txt); -+ txtwidth = txtlen; -+ } -+ -+ over = txtwidth > len; -+ still = over ? txtlen - len : len - txtlen; -+ -+ switch (HIDE_FIT(format->just_mode)) { -+ case J_LEFT: -+ still = 0; -+ break; -+ case J_CENTER: -+ still /= 2; -+ break; -+ case J_RIGHT: -+ default: -+ break; -+ } -+ -+ attrset (color); -+ -+ if (wide) { -+#ifdef UTF8 -+ if (over) { -+ if (IS_FIT (format->just_mode)) { -+ int n1 = 0; -+ int width1 = 0; -+ int n2 = 0; -+ int width2 = 0; -+ int len1 = len / 2; -+ int len2; -+ -+ while (1) { -+ int w = wcwidth(((wchar_t *) buffer)[n1]); -+ if (width1 + w <= len1) { -+ width1 += w; -+ n1++; -+ } -+ else -+ break; -+ } -+ len2 = len - width1 - 1; -+ -+ while (1) { -+ int w = wcwidth(((wchar_t *) buffer)[txtlen - n2 - 1]); -+ if (width2 + w <= len2) { -+ width2 += w; -+ n2++; -+ } -+ else -+ break; -+ } -+ -+ -+ SLsmg_write_nwchars ((wchar_t *) buffer, n1); -+ SLsmg_write_nwchars (L"~", 1); -+ printw ("%*s", len - width1 - width2 - 1, ""); -+ SLsmg_write_nwchars (((wchar_t *) buffer) -+ + txtlen - n2, n2); -+ } else -+ SLsmg_write_nwchars ((wchar_t *) buffer, len); -+ } else { -+ printw ("%*s", still, ""); -+ SLsmg_write_nwchars ((wchar_t *) buffer, txtlen); -+ printw ("%*s", len - txtwidth - still, ""); -+ } -+#endif -+ } else { -+ if (over) { -+ if (IS_FIT (format->just_mode)) -+ strcpy (buffer, name_trunc(txt, len)); -+ else -+ memcpy (buffer, txt + still, len); -+ } else { -+ memset (buffer, ' ', still); -+ memcpy (buffer + still, txt, txtlen); -+ memset (buffer + still + txtlen, ' ', -+ len - txtlen - still); -+ } -+ buffer[len] = '\0'; - -+ if (perm) -+ add_permission_string (buffer, format->field_len, fe, -+ attr, color, perm - 1); -+ else -+ addstr (buffer); -+ } -+ -+ length += len; - } else { - if (attr == SELECTED || attr == MARKED_SELECTED) - attrset (SELECTED_COLOR); -@@ -614,7 +720,6 @@ repaint_file (WPanel *panel, int file_in - { - int second_column = 0; - int width, offset; -- char buffer [BUF_MEDIUM]; - - offset = 0; - if (!isstatus && panel->split){ -@@ -643,7 +748,7 @@ repaint_file (WPanel *panel, int file_in - widget_move (&panel->widget, file_index - panel->top_file + 2, 1); - } - -- format_file (buffer, sizeof(buffer), panel, file_index, width, attr, isstatus); -+ format_file (panel, file_index, width, attr, isstatus); - - if (!isstatus && panel->split){ - if (second_column) -@@ -692,7 +797,7 @@ display_mini_info (WPanel *panel) - ngettext("%s in %d file", "%s in %d files", panel->marked), - b_bytes, panel->marked); - -- if ((int) strlen (buffer) > cols-2){ -+ if ((int) mbstrlen (buffer) > cols-2){ - buffer [cols] = 0; - p += 2; - } else -@@ -1104,6 +1209,12 @@ paint_frame (WPanel *panel) - int side, width; - - const char *txt; -+#ifdef UTF8 -+ char buffer[30 * sizeof (wchar_t)]; -+ mbstate_t s; -+ -+ memset (&s, 0, sizeof (s)); -+#endif - if (!panel->split) - adjust_top_file (panel); - -@@ -1128,16 +1239,38 @@ paint_frame (WPanel *panel) - if (format->string_fn){ - txt = format->title; - -- header_len = strlen (txt); -+ attrset (MARKED_COLOR); -+ width -= format->field_len; -+#ifdef UTF8 -+ if (SLsmg_Is_Unicode) { -+ const char *str = txt; -+ header_len = mbsrtowcs ((wchar_t *) buffer, &str, -+ sizeof (buffer) / sizeof (wchar_t), -+ &s); -+ if (header_len < 0) { -+ memset (&s, 0, sizeof (s)); -+ printw ("%*s", format->field_len, ""); -+ continue; -+ } -+ if (header_len > format->field_len) -+ header_len = format->field_len; -+ spaces = (format->field_len - header_len) / 2; -+ extra = (format->field_len - header_len) % 2; -+ printw ("%*s", spaces, ""); -+ SLsmg_write_nwchars ((wchar_t *) buffer, header_len); -+ printw ("%*s", spaces + extra, ""); -+ continue; -+ } -+#endif -+ -+ header_len = mbstrlen (txt); - if (header_len > format->field_len) - header_len = format->field_len; - -- attrset (MARKED_COLOR); - spaces = (format->field_len - header_len) / 2; - extra = (format->field_len - header_len) % 2; - tty_printf ("%*s%.*s%*s", spaces, "", - header_len, txt, spaces+extra, ""); -- width -= 2 * spaces + extra + header_len; - } else { - attrset (NORMAL_COLOR); - one_vline (); -@@ -1894,11 +2027,24 @@ do_search (WPanel *panel, int c_code) - int i; - int wrapped = 0; - int found; -+ int prevpos, pos; -+ int j; -+ mbstate_t mbs; - - l = strlen (panel->search_buffer); - if (c_code == KEY_BACKSPACE) { -- if (l) -- panel->search_buffer[--l] = '\0'; -+ if (l) { -+ prevpos = pos = 0; -+ memset (&mbs, 0, sizeof (mbs)); -+ while (pos < l) { -+ prevpos = pos; -+ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs); -+ if (j <= 0) break; -+ pos += j; -+ } -+ --l; -+ panel->search_buffer[prevpos] = 0; -+ } - } else { - if (c_code && l < sizeof (panel->search_buffer)) { - panel->search_buffer[l] = c_code; -@@ -1907,6 +2053,14 @@ do_search (WPanel *panel, int c_code) - } - } - -+ prevpos = pos = 0; -+ memset (&mbs, 0, sizeof (mbs)); -+ while (pos < l) { -+ prevpos = pos; -+ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs); -+ if (j <= 0) break; -+ pos += j; -+ } - found = 0; - for (i = panel->selected; !wrapped || i != panel->selected; i++) { - if (i >= panel->count) { -@@ -1917,9 +2071,9 @@ do_search (WPanel *panel, int c_code) - } - if (panel-> - case_sensitive -- ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, l) -+ ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, pos) - == 0) : (g_strncasecmp (panel->dir.list[i].fname, -- panel->search_buffer, l) == 0)) { -+ panel->search_buffer, pos) == 0)) { - unselect_item (panel); - panel->selected = i; - select_item (panel); -@@ -1928,7 +2082,7 @@ do_search (WPanel *panel, int c_code) - } - } - if (!found) -- panel->search_buffer[--l] = 0; -+ panel->search_buffer[prevpos] = 0; - - paint_panel (panel); - } -diff -up mc-4.6.2-pre1/src/layout.c.utf8 mc-4.6.2-pre1/src/layout.c ---- mc-4.6.2-pre1/src/layout.c.utf8 2006-11-08 14:37:25.000000000 +0100 -+++ mc-4.6.2-pre1/src/layout.c 2008-02-25 14:56:22.000000000 +0100 -@@ -366,36 +366,36 @@ init_layout (void) - - while (i--) { - s_split_direction[i] = _(s_split_direction[i]); -- l1 = strlen (s_split_direction[i]) + 7; -+ l1 = mbstrlen (s_split_direction[i]) + 7; - if (l1 > first_width) - first_width = l1; - } - - for (i = 0; i <= 8; i++) { - check_options[i].text = _(check_options[i].text); -- l1 = strlen (check_options[i].text) + 7; -+ l1 = mbstrlen (check_options[i].text) + 7; - if (l1 > first_width) - first_width = l1; - } - -- l1 = strlen (title1) + 1; -+ l1 = mbstrlen (title1) + 1; - if (l1 > first_width) - first_width = l1; - -- l1 = strlen (title2) + 1; -+ l1 = mbstrlen (title2) + 1; - if (l1 > first_width) - first_width = l1; - - -- second_width = strlen (title3) + 1; -+ second_width = mbstrlen (title3) + 1; - for (i = 0; i < 6; i++) { - check_options[i].text = _(check_options[i].text); -- l1 = strlen (check_options[i].text) + 7; -+ l1 = mbstrlen (check_options[i].text) + 7; - if (l1 > second_width) - second_width = l1; - } - if (console_flag) { -- l1 = strlen (output_lines_label) + 13; -+ l1 = mbstrlen (output_lines_label) + 13; - if (l1 > second_width) - second_width = l1; - } -@@ -409,14 +409,14 @@ init_layout (void) - * - * Now the last thing to do - properly space buttons... - */ -- l1 = 11 + strlen (ok_button) /* 14 - all brackets and inner space */ -- +strlen (save_button) /* notice: it is 3 char less because */ -- +strlen (cancel_button); /* of '&' char in button text */ -+ l1 = 11 + mbstrlen (ok_button) /* 14 - all brackets and inner space */ -+ +mbstrlen (save_button) /* notice: it is 3 char less because */ -+ +mbstrlen (cancel_button); /* of '&' char in button text */ - - i = (first_width + second_width - l1) / 4; - b1 = 5 + i; -- b2 = b1 + strlen (ok_button) + i + 6; -- b3 = b2 + strlen (save_button) + i + 4; -+ b2 = b1 + mbstrlen (ok_button) + i + 6; -+ b3 = b2 + mbstrlen (save_button) + i + 4; - - i18n_layt_flag = 1; - } -@@ -684,7 +684,7 @@ setup_panels (void) - panel_do_cols (0); - panel_do_cols (1); - -- promptl = strlen (prompt); -+ promptl = mbstrlen (prompt); - - widget_set_size (&the_menubar->widget, 0, 0, 1, COLS); - -diff -up mc-4.6.2-pre1/src/hotlist.c.utf8 mc-4.6.2-pre1/src/hotlist.c ---- mc-4.6.2-pre1/src/hotlist.c.utf8 2006-08-08 14:17:14.000000000 +0200 -+++ mc-4.6.2-pre1/src/hotlist.c 2008-02-25 14:56:22.000000000 +0100 -@@ -563,7 +563,7 @@ init_i18n_stuff(int list_type, int cols) - - row = hotlist_but [i].y; - ++count [row]; -- len [row] += strlen (hotlist_but [i].text) + 5; -+ len [row] += mbstrlen (hotlist_but [i].text) + 5; - if (hotlist_but [i].flags == DEFPUSH_BUTTON) - len [row] += 2; - } -@@ -588,12 +588,12 @@ init_i18n_stuff(int list_type, int cols) - /* not first int the row */ - if (!strcmp (hotlist_but [i].text, cancel_but)) - hotlist_but [i].x = -- cols - strlen (hotlist_but [i].text) - 13; -+ cols - mbstrlen (hotlist_but [i].text) - 13; - else - hotlist_but [i].x = cur_x [row]; - } - -- cur_x [row] += strlen (hotlist_but [i].text) + 2 -+ cur_x [row] += mbstrlen (hotlist_but [i].text) + 2 - + (hotlist_but [i].flags == DEFPUSH_BUTTON ? 5 : 3); - } - } -@@ -834,7 +834,7 @@ static void add_widgets_i18n(QuickWidget - for (i = 0; i < 3; i++) - { - qw [i].text = _(qw [i].text); -- l[i] = strlen (qw [i].text) + 3; -+ l[i] = mbstrlen (qw [i].text) + 3; - } - space = (len - 4 - l[0] - l[1] - l[2]) / 4; - -@@ -883,7 +883,7 @@ add_new_entry_input (const char *header, - - msglen(text1, &lines1, &cols1); - msglen(text2, &lines2, &cols2); -- len = max ((int) strlen (header), cols1); -+ len = max ((int) mbstrlen (header), cols1); - len = max (len, cols2) + 4; - len = max (len, 64); - -@@ -979,7 +979,7 @@ add_new_group_input (const char *header, - #endif /* ENABLE_NLS */ - - msglen (label, &lines, &cols); -- len = max ((int) strlen (header), cols) + 4; -+ len = max ((int) mbstrlen (header), cols) + 4; - len = max (len, 64); - - #ifdef ENABLE_NLS -@@ -1035,7 +1035,7 @@ void add2hotlist_cmd (void) - { - char *prompt, *label; - const char *cp = _("Label for \"%s\":"); -- int l = strlen (cp); -+ int l = mbstrlen (cp); - char *label_string = g_strdup (current_panel->cwd); - - strip_password (label_string, 1); -diff -up mc-4.6.2-pre1/src/myslang.h.utf8 mc-4.6.2-pre1/src/myslang.h ---- mc-4.6.2-pre1/src/myslang.h.utf8 2005-09-05 05:22:04.000000000 +0200 -+++ mc-4.6.2-pre1/src/myslang.h 2008-02-25 14:56:22.000000000 +0100 -@@ -11,6 +11,16 @@ - #endif /* HAVE_SLANG_SLANG_H */ - #endif - -+#if SLANG_VERSION >= 20000 -+#define UTF8 1 -+#define SLsmg_Is_Unicode SLsmg_is_utf8_mode() -+void SLsmg_write_nwchars(wchar_t *s, size_t n); -+#endif -+ -+#ifdef UTF8 -+# include -+#endif -+ - enum { - KEY_BACKSPACE = 400, - KEY_END, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, -diff -up mc-4.6.2-pre1/src/panelize.c.utf8 mc-4.6.2-pre1/src/panelize.c ---- mc-4.6.2-pre1/src/panelize.c.utf8 2005-05-27 05:35:15.000000000 +0200 -+++ mc-4.6.2-pre1/src/panelize.c 2008-02-25 14:56:22.000000000 +0100 -@@ -127,7 +127,7 @@ init_panelize (void) - i = sizeof (panelize_but) / sizeof (panelize_but[0]); - while (i--) { - panelize_but[i].text = _(panelize_but[i].text); -- maxlen += strlen (panelize_but[i].text) + 5; -+ maxlen += mbstrlen (panelize_but[i].text) + 5; - } - maxlen += 10; - -@@ -136,11 +136,11 @@ init_panelize (void) - panelize_cols = max (panelize_cols, maxlen); - - panelize_but[2].x = -- panelize_but[3].x + strlen (panelize_but[3].text) + 7; -+ panelize_but[3].x + mbstrlen (panelize_but[3].text) + 7; - panelize_but[1].x = -- panelize_but[2].x + strlen (panelize_but[2].text) + 5; -+ panelize_but[2].x + mbstrlen (panelize_but[2].text) + 5; - panelize_but[0].x = -- panelize_cols - strlen (panelize_but[0].text) - 8 - BX; -+ panelize_cols - mbstrlen (panelize_but[0].text) - 8 - BX; - - #endif /* ENABLE_NLS */ - -diff -up mc-4.6.2-pre1/edit/wordproc.c.utf8 mc-4.6.2-pre1/edit/wordproc.c ---- mc-4.6.2-pre1/edit/wordproc.c.utf8 2006-06-16 22:01:29.000000000 +0200 -+++ mc-4.6.2-pre1/edit/wordproc.c 2008-02-25 14:56:22.000000000 +0100 -@@ -40,7 +40,12 @@ - - #define tab_width option_tab_spacing - -+#ifndef UTF8 - #define NO_FORMAT_CHARS_START "-+*\\,.;:&>" -+#else /* UTF8 */ -+#define NO_FORMAT_CHARS_START L"-+*\\,.;:&>" -+#endif /* UTF8 */ -+ - #define FONT_MEAN_WIDTH 1 - - static long -@@ -57,14 +62,21 @@ line_start (WEdit *edit, long line) - p = edit_move_forward (edit, p, line - l, 0); - - p = edit_bol (edit, p); -+ -+#ifndef UTF8 - while (strchr ("\t ", edit_get_byte (edit, p))) -+#else /* UTF8 */ -+ while (wcschr (L"\t ", edit_get_byte (edit, p))) -+#endif /* UTF8 */ -+ - p++; - return p; - } - - static int bad_line_start (WEdit * edit, long p) - { -- int c; -+ mc_wint_t c; -+ - c = edit_get_byte (edit, p); - if (c == '.') { /* `...' is acceptable */ - if (edit_get_byte (edit, p + 1) == '.') -@@ -78,7 +90,13 @@ static int bad_line_start (WEdit * edit, - return 0; /* `---' is acceptable */ - return 1; - } -+ -+#ifndef UTF8 - if (strchr (NO_FORMAT_CHARS_START, c)) -+#else /* UTF8 */ -+ if (wcschr (NO_FORMAT_CHARS_START, c)) -+#endif /* UTF8 */ -+ - return 1; - return 0; - } -@@ -131,33 +149,37 @@ end_paragraph (WEdit *edit, int force) - i - edit->curs_line, 0)); - } - --static unsigned char * -+static mc_wchar_t * - get_paragraph (WEdit *edit, long p, long q, int indent, int *size) - { -- unsigned char *s, *t; -+ mc_wchar_t *s, *t; - #if 0 -- t = g_malloc ((q - p) + 2 * (q - p) / option_word_wrap_line_length + -- 10); -+ t = g_malloc (((q - p) + 2 * (q - p) / option_word_wrap_line_length + -+ 10) * sizeof(mc_wchar_t)); - #else -- t = g_malloc (2 * (q - p) + 100); -+ t = g_malloc ((2 * (q - p) + 100) * sizeof(mc_wchar_t)); - #endif - if (!t) - return 0; - for (s = t; p < q; p++, s++) { - if (indent) - if (edit_get_byte (edit, p - 1) == '\n') -+#ifndef UTF8 - while (strchr ("\t ", edit_get_byte (edit, p))) -+#else /* UTF8 */ -+ while (wcschr (L"\t ", edit_get_byte (edit, p))) -+#endif /* UTF8 */ - p++; - *s = edit_get_byte (edit, p); - } -- *size = (unsigned long) s - (unsigned long) t; -+ *size = s - t; - t[*size] = '\n'; - return t; - } - --static void strip_newlines (unsigned char *t, int size) -+static void strip_newlines (mc_wchar_t *t, int size) - { -- unsigned char *p = t; -+ mc_wchar_t *p = t; - while (size--) { - *p = *p == '\n' ? ' ' : *p; - p++; -@@ -174,7 +196,7 @@ static inline int next_tab_pos (int x) - { - return x += tab_width - x % tab_width; - } --static int line_pixel_length (unsigned char *t, long b, int l) -+static int line_pixel_length (mc_wchar_t *t, long b, int l) - { - int x = 0, c, xn = 0; - for (;;) { -@@ -198,7 +220,7 @@ static int line_pixel_length (unsigned c - } - - static int --next_word_start (unsigned char *t, int q, int size) -+next_word_start (mc_wchar_t *t, int q, int size) - { - int i; - int saw_ws = 0; -@@ -222,7 +244,7 @@ next_word_start (unsigned char *t, int q - - /* find the start of a word */ - static int --word_start (unsigned char *t, int q, int size) -+word_start (mc_wchar_t *t, int q, int size) - { - int i = q; - if (t[q] == ' ' || t[q] == '\t') -@@ -241,7 +263,7 @@ word_start (unsigned char *t, int q, int - } - - /* replaces ' ' with '\n' to properly format a paragraph */ --static void format_this (unsigned char *t, int size, int indent) -+static void format_this (mc_wchar_t *t, int size, int indent) - { - int q = 0, ww; - strip_newlines (t, size); -@@ -269,7 +291,7 @@ static void format_this (unsigned char * - } - } - --static void replace_at (WEdit * edit, long q, int c) -+static void replace_at (WEdit * edit, long q, mc_wint_t c) - { - edit_cursor_move (edit, q - edit->curs1); - edit_delete (edit); -@@ -278,18 +300,27 @@ static void replace_at (WEdit * edit, lo - - /* replaces a block of text */ - static void --put_paragraph (WEdit * edit, unsigned char *t, long p, int indent, int size) -+put_paragraph (WEdit * edit, mc_wchar_t *t, long p, int indent, int size) - { - long cursor; -- int i, c = 0; -+ int i; -+ mc_wchar_t c = 0; - cursor = edit->curs1; - if (indent) -+#ifndef UTF8 - while (strchr ("\t ", edit_get_byte (edit, p))) -+#else /* UTF8 */ -+ while (wcschr (L"\t ", edit_get_byte (edit, p))) -+#endif /* UTF8 */ - p++; - for (i = 0; i < size; i++, p++) { - if (i && indent) { - if (t[i - 1] == '\n' && c == '\n') { -+#ifndef UTF8 - while (strchr ("\t ", edit_get_byte (edit, p))) -+#else /* UTF8 */ -+ while (wcschr (L"\t ", edit_get_byte (edit, p))) -+#endif /* UTF8 */ - p++; - } else if (t[i - 1] == '\n') { - long curs; -@@ -301,7 +332,11 @@ put_paragraph (WEdit * edit, unsigned ch - p = edit->curs1; - } else if (c == '\n') { - edit_cursor_move (edit, p - edit->curs1); -+#ifndef UTF8 - while (strchr ("\t ", edit_get_byte (edit, p))) { -+#else /* UTF8 */ -+ while (wcschr (L"\t ", edit_get_byte (edit, p))) { -+#endif /* UTF8 */ - edit_delete (edit); - if (cursor > edit->curs1) - cursor--; -@@ -334,7 +369,7 @@ format_paragraph (WEdit *edit, int force - { - long p, q; - int size; -- unsigned char *t; -+ mc_wchar_t *t; - int indent = 0; - if (option_word_wrap_line_length < 2) - return; -@@ -344,17 +379,25 @@ format_paragraph (WEdit *edit, int force - q = end_paragraph (edit, force); - indent = test_indent (edit, p, q); - t = get_paragraph (edit, p, q, indent, &size); -- if (!t) -+ if (!t) - return; - if (!force) { - int i; -+#ifndef UTF8 - if (strchr (NO_FORMAT_CHARS_START, *t)) { -+#else /* UTF8 */ -+ if (wcschr (NO_FORMAT_CHARS_START, *t)) { -+#endif /* UTF8 */ - g_free (t); - return; - } - for (i = 0; i < size - 1; i++) { - if (t[i] == '\n') { -+#ifndef UTF8 - if (strchr (NO_FORMAT_CHARS_START "\t ", t[i + 1])) { -+#else /* UTF8 */ -+ if (wcschr (NO_FORMAT_CHARS_START "\t", t[i + 1])) { -+#endif /* UTF8 */ - g_free (t); - return; - } -diff -up mc-4.6.2-pre1/edit/edit.c.utf8 mc-4.6.2-pre1/edit/edit.c ---- mc-4.6.2-pre1/edit/edit.c.utf8 2007-01-04 16:37:23.000000000 +0100 -+++ mc-4.6.2-pre1/edit/edit.c 2008-02-25 14:56:22.000000000 +0100 -@@ -102,7 +102,11 @@ char *option_backup_ext = NULL; - - static void user_menu (WEdit *edit); - -+#ifndef UTF8 - int edit_get_byte (WEdit * edit, long byte_index) -+#else -+mc_wchar_t edit_get_byte (WEdit * edit, long byte_index) -+#endif - { - unsigned long p; - if (byte_index >= (edit->curs1 + edit->curs2) || byte_index < 0) -@@ -131,7 +135,7 @@ edit_init_buffers (WEdit *edit) - - edit->curs1 = 0; - edit->curs2 = 0; -- edit->buffers2[0] = g_malloc (EDIT_BUF_SIZE); -+ edit->buffers2[0] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); - } - - /* -@@ -156,7 +160,7 @@ edit_load_file_fast (WEdit *edit, const - } - - if (!edit->buffers2[buf2]) -- edit->buffers2[buf2] = g_malloc (EDIT_BUF_SIZE); -+ edit->buffers2[buf2] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); - - mc_read (file, - (char *) edit->buffers2[buf2] + EDIT_BUF_SIZE - -@@ -166,7 +170,7 @@ edit_load_file_fast (WEdit *edit, const - for (buf = buf2 - 1; buf >= 0; buf--) { - /* edit->buffers2[0] is already allocated */ - if (!edit->buffers2[buf]) -- edit->buffers2[buf] = g_malloc (EDIT_BUF_SIZE); -+ edit->buffers2[buf] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); - mc_read (file, (char *) edit->buffers2[buf], EDIT_BUF_SIZE); - } - -@@ -239,9 +243,44 @@ edit_insert_stream (WEdit * edit, FILE * - { - int c; - long i = 0; -- while ((c = fgetc (f)) >= 0) { -+#ifndef UTF8 -+ while ((c = fgetc (f)) != EOF) { - edit_insert (edit, c); - i++; -+#else /* UTF8 */ -+ unsigned char buf[MB_LEN_MAX]; -+ int charpos = 0; -+ mbstate_t mbs; -+ -+ while ((c = fgetc (f)) != EOF) { -+ mc_wchar_t wc; -+ int size; -+ int j; -+ -+ buf[charpos++] = c; -+ -+ memset (&mbs, 0, sizeof (mbs)); -+ size = mbrtowc(&wc, (char *)buf, charpos, &mbs); -+ -+ if (size == -2) -+ continue; /* incomplete */ -+ -+ else if (size >= 0) { -+ edit_insert (edit, wc); -+ i++; -+ charpos = 0; -+ continue; -+ } -+ else { -+ -+ /* invalid */ -+#ifdef __STDC_ISO_10646__ -+ for (j=0; jlast_byte; i++) - if (fputc (edit_get_byte (edit, i), f) < 0) - break; -+#else /* UTF8 */ -+ for (i = 0; i < edit->last_byte; i++) { -+ mc_wchar_t wc = edit_get_byte (edit, i); -+ int res; -+ char tmpbuf[MB_LEN_MAX]; -+ mbstate_t mbs; -+ -+ memset (&mbs, 0, sizeof (mbs)); -+ -+#ifdef __STDC_ISO_10646__ -+ if (wc >= BINARY_CHAR_OFFSET && wc < (BINARY_CHAR_OFFSET + 256)) { -+ res = 1; -+ tmpbuf[0] = (char) (wc - BINARY_CHAR_OFFSET); -+ } else -+#endif -+ res = wcrtomb(tmpbuf, wc, &mbs); -+ if (res > 0) { -+ if (fwrite(tmpbuf, res, 1, f) != 1) -+ break; -+ } -+ } -+#endif /* UTF8 */ - return i; - } - -@@ -290,12 +352,46 @@ edit_insert_file (WEdit *edit, const cha - int i, file, blocklen; - long current = edit->curs1; - unsigned char *buf; -+#ifdef UTF8 -+ mbstate_t mbs; -+ int bufstart = 0; -+ -+ memset (&mbs, 0, sizeof (mbs)); -+#endif /* UTF8 */ - if ((file = mc_open (filename, O_RDONLY | O_BINARY)) == -1) - return 0; - buf = g_malloc (TEMP_BUF_LEN); -+#ifndef UTF8 - while ((blocklen = mc_read (file, (char *) buf, TEMP_BUF_LEN)) > 0) { - for (i = 0; i < blocklen; i++) - edit_insert (edit, buf[i]); -+#else /* UTF8 */ -+ while ((blocklen = mc_read (file, (char *) buf + bufstart, TEMP_BUF_LEN - bufstart)) > 0) { -+ blocklen += bufstart; -+ bufstart = 0; -+ for (i = 0; i < blocklen; ) { -+ mc_wchar_t wc; -+ int j; -+ int size = mbrtowc(&wc, (char *)buf + i, blocklen - i, &mbs); -+ if (size == -2) { /*incomplete char*/ -+ bufstart = blocklen - i; -+ memcpy(buf, buf+i, bufstart); -+ i = blocklen; -+ memset (&mbs, 0, sizeof (mbs)); -+ } -+ else if (size <= 0) { -+#ifdef __STDC_ISO_10646__ -+ edit_insert (edit, BINARY_CHAR_OFFSET + (mc_wchar_t)buf[i]); -+#endif -+ memset (&mbs, 0, sizeof (mbs)); -+ i++; /* skip broken char */ -+ } -+ else { -+ edit_insert (edit, wc); -+ i+=size; -+ } -+ } -+#endif /* UTF8 */ - } - edit_cursor_move (edit, current - edit->curs1); - g_free (buf); -@@ -385,7 +481,11 @@ cleanup: - static int - edit_load_file (WEdit *edit) - { -+#ifndef UTF8 - int fast_load = 1; -+#else /* UTF8 */ -+ int fast_load = 0; /* can't be used with multibyte characters */ -+#endif /* UTF8 */ - - /* Cannot do fast load if a filter is used */ - if (edit_find_filter (edit->filename) >= 0) -@@ -451,6 +551,7 @@ edit_load_position (WEdit *edit) - edit->prev_col = column; - edit_move_to_prev_col (edit, edit_bol (edit, edit->curs1)); - edit_move_display (edit, line - (edit->num_widget_lines / 2)); -+ edit->charpoint = 0; - } - - /* Save cursor position in the file */ -@@ -534,7 +635,7 @@ edit_init (WEdit *edit, int lines, int c - edit_set_filename (edit, filename); - edit->stack_size = START_STACK_SIZE; - edit->stack_size_mask = START_STACK_SIZE - 1; -- edit->undo_stack = g_malloc ((edit->stack_size + 10) * sizeof (long)); -+ edit->undo_stack = g_malloc ((edit->stack_size + 10) * sizeof (struct action)); - if (edit_load_file (edit)) { - /* edit_load_file already gives an error message */ - if (to_free) -@@ -689,14 +790,23 @@ void edit_push_action (WEdit * edit, lon - { - unsigned long sp = edit->stack_pointer; - unsigned long spm1; -- long *t; -+ -+ struct action *t; -+ mc_wchar_t ch = 0; -+ -+ if (c == CHAR_INSERT || c == CHAR_INSERT_AHEAD) { -+ va_list ap; -+ va_start (ap, c); -+ ch = va_arg (ap, mc_wint_t); -+ va_end (ap); -+ } - - /* first enlarge the stack if necessary */ - if (sp > edit->stack_size - 10) { /* say */ - if (option_max_undo < 256) - option_max_undo = 256; - if (edit->stack_size < (unsigned long) option_max_undo) { -- t = g_realloc (edit->undo_stack, (edit->stack_size * 2 + 10) * sizeof (long)); -+ t = g_realloc (edit->undo_stack, (edit->stack_size * 2 + 10) * sizeof (struct action)); - if (t) { - edit->undo_stack = t; - edit->stack_size <<= 1; -@@ -711,7 +821,7 @@ void edit_push_action (WEdit * edit, lon - #ifdef FAST_MOVE_CURSOR - if (c == CURS_LEFT_LOTS || c == CURS_RIGHT_LOTS) { - va_list ap; -- edit->undo_stack[sp] = c == CURS_LEFT_LOTS ? CURS_LEFT : CURS_RIGHT; -+ edit->undo_stack[sp].flags = c == CURS_LEFT_LOTS ? CURS_LEFT : CURS_RIGHT; - edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask; - va_start (ap, c); - c = -(va_arg (ap, int)); -@@ -722,12 +832,14 @@ void edit_push_action (WEdit * edit, lon - && spm1 != edit->stack_bottom - && ((sp - 2) & edit->stack_size_mask) != edit->stack_bottom) { - int d; -- if (edit->undo_stack[spm1] < 0) { -- d = edit->undo_stack[(sp - 2) & edit->stack_size_mask]; -- if (d == c) { -- if (edit->undo_stack[spm1] > -1000000000) { -+ mc_wchar_t d_ch; -+ if (edit->undo_stack[spm1].flags < 0) { -+ d = edit->undo_stack[(sp - 2) & edit->stack_size_mask].flags; -+ d_ch = edit->undo_stack[(sp - 2) & edit->stack_size_mask].ch; -+ if (d == c && d_ch == ch) { -+ if (edit->undo_stack[spm1].flags > -1000000000) { - if (c < KEY_PRESS) /* --> no need to push multiple do-nothings */ -- edit->undo_stack[spm1]--; -+ edit->undo_stack[spm1].flags--; - return; - } - } -@@ -735,19 +847,20 @@ void edit_push_action (WEdit * edit, lon - #ifndef NO_STACK_CURSMOVE_ANIHILATION - else if ((c == CURS_LEFT && d == CURS_RIGHT) - || (c == CURS_RIGHT && d == CURS_LEFT)) { /* a left then a right anihilate each other */ -- if (edit->undo_stack[spm1] == -2) -+ if (edit->undo_stack[spm1].flags == -2) - edit->stack_pointer = spm1; - else -- edit->undo_stack[spm1]++; -+ edit->undo_stack[spm1].flags++; - return; - } - #endif - } else { -- d = edit->undo_stack[spm1]; -- if (d == c) { -+ d = edit->undo_stack[spm1].flags; -+ d_ch = edit->undo_stack[spm1].ch; -+ if (d == c && d_ch == ch) { - if (c >= KEY_PRESS) - return; /* --> no need to push multiple do-nothings */ -- edit->undo_stack[sp] = -2; -+ edit->undo_stack[sp].flags = -2; - goto check_bottom; - } - #ifndef NO_STACK_CURSMOVE_ANIHILATION -@@ -759,7 +872,9 @@ void edit_push_action (WEdit * edit, lon - #endif - } - } -- edit->undo_stack[sp] = c; -+ edit->undo_stack[sp].flags = c; -+ edit->undo_stack[sp].ch = ch; -+ - check_bottom: - - edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask; -@@ -772,10 +887,10 @@ void edit_push_action (WEdit * edit, lon - (((unsigned long) c + 1) & edit->stack_size_mask) == edit->stack_bottom) - do { - edit->stack_bottom = (edit->stack_bottom + 1) & edit->stack_size_mask; -- } while (edit->undo_stack[edit->stack_bottom] < KEY_PRESS && edit->stack_bottom != edit->stack_pointer); -+ } while (edit->undo_stack[edit->stack_bottom].flags < KEY_PRESS && edit->stack_bottom != edit->stack_pointer); - - /*If a single key produced enough pushes to wrap all the way round then we would notice that the [stack_bottom] does not contain KEY_PRESS. The stack is then initialised: */ -- if (edit->stack_pointer != edit->stack_bottom && edit->undo_stack[edit->stack_bottom] < KEY_PRESS) -+ if (edit->stack_pointer != edit->stack_bottom && edit->undo_stack[edit->stack_bottom].flags < KEY_PRESS) - edit->stack_bottom = edit->stack_pointer = 0; - } - -@@ -784,30 +899,30 @@ void edit_push_action (WEdit * edit, lon - then the file should be as it was when he loaded up. Then set edit->modified to 0. - */ - static long --pop_action (WEdit * edit) -+pop_action (WEdit * edit, struct action *c) - { -- long c; - unsigned long sp = edit->stack_pointer; - if (sp == edit->stack_bottom) { -- return STACK_BOTTOM; -+ c->flags = STACK_BOTTOM; -+ return c->flags; - } - sp = (sp - 1) & edit->stack_size_mask; -- if ((c = edit->undo_stack[sp]) >= 0) { --/* edit->undo_stack[sp] = '@'; */ -+ *c = edit->undo_stack[sp]; -+ if (edit->undo_stack[sp].flags >= 0) { - edit->stack_pointer = (edit->stack_pointer - 1) & edit->stack_size_mask; -- return c; -+ return c->flags; - } - if (sp == edit->stack_bottom) { - return STACK_BOTTOM; - } -- c = edit->undo_stack[(sp - 1) & edit->stack_size_mask]; -- if (edit->undo_stack[sp] == -2) { --/* edit->undo_stack[sp] = '@'; */ -+ *c = edit->undo_stack[(sp - 1) & edit->stack_size_mask]; -+ -+ if (edit->undo_stack[sp].flags == -2) { - edit->stack_pointer = sp; - } else -- edit->undo_stack[sp]++; -+ edit->undo_stack[sp].flags++; - -- return c; -+ return c->flags; - } - - /* is called whenever a modification is made by one of the four routines below */ -@@ -828,7 +943,7 @@ static inline void edit_modification (WE - */ - - void --edit_insert (WEdit *edit, int c) -+edit_insert (WEdit *edit, mc_wchar_t c) - { - /* check if file has grown to large */ - if (edit->last_byte >= SIZE_LIMIT) -@@ -866,12 +981,11 @@ edit_insert (WEdit *edit, int c) - /* add a new buffer if we've reached the end of the last one */ - if (!(edit->curs1 & M_EDIT_BUF_SIZE)) - edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = -- g_malloc (EDIT_BUF_SIZE); -+ g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); - - /* perform the insertion */ -- edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE][edit-> -- curs1 & M_EDIT_BUF_SIZE] -- = (unsigned char) c; -+ edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] -+ [edit->curs1 & M_EDIT_BUF_SIZE] = c; - - /* update file length */ - edit->last_byte++; -@@ -882,7 +996,7 @@ edit_insert (WEdit *edit, int c) - - - /* same as edit_insert and move left */ --void edit_insert_ahead (WEdit * edit, int c) -+void edit_insert_ahead (WEdit * edit, mc_wchar_t c) - { - if (edit->last_byte >= SIZE_LIMIT) - return; -@@ -905,7 +1019,7 @@ void edit_insert_ahead (WEdit * edit, in - edit->last_get_rule += (edit->last_get_rule >= edit->curs1); - - if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE)) -- edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE); -+ edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); - edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1] = c; - - edit->last_byte++; -@@ -915,7 +1029,7 @@ void edit_insert_ahead (WEdit * edit, in - - int edit_delete (WEdit * edit) - { -- int p; -+ mc_wint_t p; - if (!edit->curs2) - return 0; - -@@ -939,7 +1053,7 @@ int edit_delete (WEdit * edit) - edit->total_lines--; - edit->force |= REDRAW_AFTER_CURSOR; - } -- edit_push_action (edit, p + 256); -+ edit_push_action (edit, CHAR_INSERT_AHEAD, p); - if (edit->curs1 < edit->start_display) { - edit->start_display--; - if (p == '\n') -@@ -953,7 +1067,7 @@ int edit_delete (WEdit * edit) - static int - edit_backspace (WEdit * edit) - { -- int p; -+ mc_wint_t p; - if (!edit->curs1) - return 0; - -@@ -977,7 +1091,7 @@ edit_backspace (WEdit * edit) - edit->total_lines--; - edit->force |= REDRAW_AFTER_CURSOR; - } -- edit_push_action (edit, p); -+ edit_push_action (edit, CHAR_INSERT, p); - - if (edit->curs1 < edit->start_display) { - edit->start_display--; -@@ -990,10 +1104,18 @@ edit_backspace (WEdit * edit) - - #ifdef FAST_MOVE_CURSOR - --static void memqcpy (WEdit * edit, unsigned char *dest, unsigned char *src, int n) -+static void memqcpy (WEdit * edit, mc_wchar_t *dest, mc_wchar_t *src, int n) - { - unsigned long next; -+#ifndef UTF8 - while ((next = (unsigned long) memccpy (dest, src, '\n', n))) { -+#else /* UTF8 */ -+ while (n) { -+ next = 0; -+ while (next < n && src[next]!='\n') next++; -+ if (next < n) next++; -+ wmemcpy (dest, src, next) -+#endif /* UTF8 */ - edit->curs_line--; - next -= (unsigned long) dest; - n -= next; -@@ -1006,7 +1128,7 @@ int - edit_move_backward_lots (WEdit *edit, long increment) - { - int r, s, t; -- unsigned char *p; -+ mc_wchar_t *p; - - if (increment > edit->curs1) - increment = edit->curs1; -@@ -1046,7 +1168,7 @@ edit_move_backward_lots (WEdit *edit, lo - edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p; - else - edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = -- g_malloc (EDIT_BUF_SIZE); -+ g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); - } else { - g_free (p); - } -@@ -1084,7 +1206,7 @@ edit_move_backward_lots (WEdit *edit, lo - edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p; - else - edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = -- g_malloc (EDIT_BUF_SIZE); -+ g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); - } else { - g_free (p); - } -@@ -1116,7 +1238,7 @@ int edit_cursor_move (WEdit * edit, long - - c = edit_get_byte (edit, edit->curs1 - 1); - if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE)) -- edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE); -+ edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); - edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1] = c; - edit->curs2++; - c = edit->buffers1[(edit->curs1 - 1) >> S_EDIT_BUF_SIZE][(edit->curs1 - 1) & M_EDIT_BUF_SIZE]; -@@ -1141,7 +1263,7 @@ int edit_cursor_move (WEdit * edit, long - - c = edit_get_byte (edit, edit->curs1); - if (!(edit->curs1 & M_EDIT_BUF_SIZE)) -- edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE); -+ edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); - edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE][edit->curs1 & M_EDIT_BUF_SIZE] = c; - edit->curs1++; - c = edit->buffers2[(edit->curs2 - 1) >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - ((edit->curs2 - 1) & M_EDIT_BUF_SIZE) - 1]; -@@ -1248,7 +1370,7 @@ long edit_move_forward3 (WEdit * edit, l - q = edit->last_byte + 2; - - for (col = 0, p = current; p < q; p++) { -- int c; -+ mc_wchar_t c; - if (cols != -10) { - if (col == cols) - return p; -@@ -1266,7 +1388,7 @@ long edit_move_forward3 (WEdit * edit, l - } else if (c < 32 || c == 127) - col += 2; /* Caret notation for control characters */ - else -- col++; -+ col += wcwidth(c); - } - return col; - } -@@ -1399,12 +1521,16 @@ static int - is_blank (WEdit *edit, long offset) - { - long s, f; -- int c; -+ mc_wchar_t c; - s = edit_bol (edit, offset); - f = edit_eol (edit, offset) - 1; - while (s <= f) { - c = edit_get_byte (edit, s++); -+#ifndef UTF8 - if (!isspace (c)) -+#else -+ if (!iswspace (c)) -+#endif /* UTF8 */ - return 0; - } - return 1; -@@ -1659,6 +1785,7 @@ my_type_of (int c) - return 2; - return 0x80000000UL; - } -+#ifndef UTF8 - if (isupper (c)) - c = 'A'; - else if (islower (c)) -@@ -1669,6 +1796,18 @@ my_type_of (int c) - c = '0'; - else if (isspace (c)) - c = ' '; -+#else -+ if (iswupper (c)) -+ c = 'A'; -+ else if (iswlower (c)) -+ c = 'a'; -+ else if (iswalpha (c)) -+ c = 'a'; -+ else if (iswdigit (c)) -+ c = '0'; -+ else if (iswspace (c)) -+ c = ' '; -+#endif /* UTF8 */ - q = strchr (option_chars_move_whole_word, c); - if (!q) - return 0xFFFFFFFFUL; -@@ -1693,10 +1832,18 @@ edit_left_word_move (WEdit *edit, int s) - c2 = edit_get_byte (edit, edit->curs1); - if (!(my_type_of (c1) & my_type_of (c2))) - break; -+#ifndef UTF8 - if (isspace (c1) && !isspace (c2)) -+#else -+ if (iswspace (c1) && !iswspace (c2)) -+#endif /* UTF8 */ - break; - if (s) -+#ifndef UTF8 - if (!isspace (c1) && isspace (c2)) -+#else -+ if (!iswspace (c1) && iswspace (c2)) -+#endif /* UTF8 */ - break; - } - } -@@ -1719,10 +1866,18 @@ edit_right_word_move (WEdit *edit, int s - c2 = edit_get_byte (edit, edit->curs1); - if (!(my_type_of (c1) & my_type_of (c2))) - break; -+#ifndef UTF8 - if (isspace (c1) && !isspace (c2)) -+#else -+ if (iswspace (c1) && !iswspace (c2)) -+#endif /* UTF8 */ - break; - if (s) -+#ifndef UTF8 - if (!isspace (c1) && isspace (c2)) -+#else -+ if (!iswspace (c1) && iswspace (c2)) -+#endif /* UTF8 */ - break; - } - } -@@ -1742,7 +1897,11 @@ static void edit_right_delete_word (WEdi - break; - c1 = edit_delete (edit); - c2 = edit_get_byte (edit, edit->curs1); -+#ifndef UTF8 - if ((isspace (c1) == 0) != (isspace (c2) == 0)) -+#else -+ if ((iswspace (c1) == 0) != (iswspace (c2) == 0)) -+#endif /* UTF8 */ - break; - if (!(my_type_of (c1) & my_type_of (c2))) - break; -@@ -1757,7 +1916,11 @@ static void edit_left_delete_word (WEdit - break; - c1 = edit_backspace (edit); - c2 = edit_get_byte (edit, edit->curs1 - 1); -+#ifndef UTF8 - if ((isspace (c1) == 0) != (isspace (c2) == 0)) -+#else -+ if ((iswspace (c1) == 0) != (iswspace (c2) == 0)) -+#endif /* UTF8 */ - break; - if (!(my_type_of (c1) & my_type_of (c2))) - break; -@@ -1771,13 +1934,13 @@ static void edit_left_delete_word (WEdit - static void - edit_do_undo (WEdit * edit) - { -- long ac; -+ struct action ac; - long count = 0; - - edit->stack_disable = 1; /* don't record undo's onto undo stack! */ - -- while ((ac = pop_action (edit)) < KEY_PRESS) { -- switch ((int) ac) { -+ while (pop_action (edit, &ac) < KEY_PRESS) { -+ switch ((int) ac.flags) { - case STACK_BOTTOM: - goto done_undo; - case CURS_RIGHT: -@@ -1798,31 +1961,33 @@ edit_do_undo (WEdit * edit) - case COLUMN_OFF: - column_highlighting = 0; - break; -+ case CHAR_INSERT: -+ edit_insert (edit, ac.ch); -+ break; -+ case CHAR_INSERT_AHEAD: -+ edit_insert_ahead (edit, ac.ch); -+ break; - } -- if (ac >= 256 && ac < 512) -- edit_insert_ahead (edit, ac - 256); -- if (ac >= 0 && ac < 256) -- edit_insert (edit, ac); - -- if (ac >= MARK_1 - 2 && ac < MARK_2 - 2) { -- edit->mark1 = ac - MARK_1; -+ if (ac.flags >= MARK_1 - 2 && ac.flags < MARK_2 - 2) { -+ edit->mark1 = ac.flags - MARK_1; - edit->column1 = edit_move_forward3 (edit, edit_bol (edit, edit->mark1), 0, edit->mark1); -- } else if (ac >= MARK_2 - 2 && ac < KEY_PRESS) { -- edit->mark2 = ac - MARK_2; -+ } else if (ac.flags >= MARK_2 - 2 && ac.flags < KEY_PRESS) { -+ edit->mark2 = ac.flags - MARK_2; - edit->column2 = edit_move_forward3 (edit, edit_bol (edit, edit->mark2), 0, edit->mark2); - } - if (count++) - edit->force |= REDRAW_PAGE; /* more than one pop usually means something big */ - } - -- if (edit->start_display > ac - KEY_PRESS) { -- edit->start_line -= edit_count_lines (edit, ac - KEY_PRESS, edit->start_display); -+ if (edit->start_display > ac.flags - KEY_PRESS) { -+ edit->start_line -= edit_count_lines (edit, ac.flags - KEY_PRESS, edit->start_display); - edit->force |= REDRAW_PAGE; -- } else if (edit->start_display < ac - KEY_PRESS) { -- edit->start_line += edit_count_lines (edit, edit->start_display, ac - KEY_PRESS); -+ } else if (edit->start_display < ac.flags - KEY_PRESS) { -+ edit->start_line += edit_count_lines (edit, edit->start_display, ac.flags - KEY_PRESS); - edit->force |= REDRAW_PAGE; - } -- edit->start_display = ac - KEY_PRESS; /* see push and pop above */ -+ edit->start_display = ac.flags - KEY_PRESS; /* see push and pop above */ - edit_update_curs_row (edit); - - done_undo:; -@@ -2102,7 +2267,7 @@ static void edit_goto_matching_bracket ( - * passed as -1. Commands are executed, and char_for_insertion is - * inserted at the cursor. - */ --void edit_execute_key_command (WEdit *edit, int command, int char_for_insertion) -+void edit_execute_key_command (WEdit *edit, int command, mc_wint_t char_for_insertion) - { - if (command == CK_Begin_Record_Macro) { - edit->macro_i = 0; -@@ -2137,7 +2302,7 @@ static const char * const shell_cmd[] = - all of them. It also does not check for the Undo command. - */ - void --edit_execute_cmd (WEdit *edit, int command, int char_for_insertion) -+edit_execute_cmd (WEdit *edit, int command, mc_wint_t char_for_insertion) - { - edit->force |= REDRAW_LINE; - -@@ -2170,7 +2335,7 @@ edit_execute_cmd (WEdit *edit, int comma - } - - /* An ordinary key press */ -- if (char_for_insertion >= 0) { -+ if (char_for_insertion != (mc_wint_t) -1) { - if (edit->overwrite) { - if (edit_get_byte (edit, edit->curs1) != '\n') - edit_delete (edit); +diff -up mc-4.6.2-pre1/acinclude.m4.utf8 mc-4.6.2-pre1/acinclude.m4 +--- mc-4.6.2-pre1/acinclude.m4.utf8 2006-09-07 17:59:51.000000000 +0200 ++++ mc-4.6.2-pre1/acinclude.m4 2008-10-23 14:00:12.000000000 +0200 +@@ -399,14 +399,14 @@ AC_DEFUN([MC_WITH_SLANG], [ + fi + + dnl Unless external S-Lang was requested, reject S-Lang with UTF-8 hacks +- if test x$with_screen = xslang; then +- : +- m4_if([$1], strict, , +- [AC_CHECK_LIB([slang], [SLsmg_write_nwchars], +- [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \ +-it's not fully supported yet]) +- with_screen=mcslang])]) +- fi ++dnl if test x$with_screen = xslang; then ++dnl : ++dnl m4_if([$1], strict, , ++dnl [AC_CHECK_LIB([slang], [SLsmg_write_nwchars], ++dnl [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \ ++dnl it's not fully supported yet]) ++dnl with_screen=mcslang])]) ++dnl fi + + if test x$with_screen = xslang; then + AC_DEFINE(HAVE_SYSTEM_SLANG, 1, diff -up mc-4.6.2-pre1/edit/editcmd.c.utf8 mc-4.6.2-pre1/edit/editcmd.c --- mc-4.6.2-pre1/edit/editcmd.c.utf8 2007-05-02 13:22:01.000000000 +0200 -+++ mc-4.6.2-pre1/edit/editcmd.c 2008-02-25 14:56:22.000000000 +0100 ++++ mc-4.6.2-pre1/edit/editcmd.c 2008-10-23 14:00:12.000000000 +0200 @@ -61,7 +61,7 @@ #define edit_get_save_file(f,h) input_expand_dialog (h, _(" Enter file name: "), f) @@ -4885,9 +1111,713 @@ diff -up mc-4.6.2-pre1/edit/editcmd.c.utf8 mc-4.6.2-pre1/edit/editcmd.c if (num_compl > 0) { /* insert completed word if there is only one match */ +diff -up mc-4.6.2-pre1/edit/edit.c.utf8 mc-4.6.2-pre1/edit/edit.c +--- mc-4.6.2-pre1/edit/edit.c.utf8 2007-01-04 16:37:23.000000000 +0100 ++++ mc-4.6.2-pre1/edit/edit.c 2008-10-23 14:00:12.000000000 +0200 +@@ -102,7 +102,11 @@ char *option_backup_ext = NULL; + + static void user_menu (WEdit *edit); + ++#ifndef UTF8 + int edit_get_byte (WEdit * edit, long byte_index) ++#else ++mc_wchar_t edit_get_byte (WEdit * edit, long byte_index) ++#endif + { + unsigned long p; + if (byte_index >= (edit->curs1 + edit->curs2) || byte_index < 0) +@@ -131,7 +135,7 @@ edit_init_buffers (WEdit *edit) + + edit->curs1 = 0; + edit->curs2 = 0; +- edit->buffers2[0] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers2[0] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + } + + /* +@@ -156,7 +160,7 @@ edit_load_file_fast (WEdit *edit, const + } + + if (!edit->buffers2[buf2]) +- edit->buffers2[buf2] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers2[buf2] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + + mc_read (file, + (char *) edit->buffers2[buf2] + EDIT_BUF_SIZE - +@@ -166,7 +170,7 @@ edit_load_file_fast (WEdit *edit, const + for (buf = buf2 - 1; buf >= 0; buf--) { + /* edit->buffers2[0] is already allocated */ + if (!edit->buffers2[buf]) +- edit->buffers2[buf] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers2[buf] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + mc_read (file, (char *) edit->buffers2[buf], EDIT_BUF_SIZE); + } + +@@ -239,9 +243,44 @@ edit_insert_stream (WEdit * edit, FILE * + { + int c; + long i = 0; +- while ((c = fgetc (f)) >= 0) { ++#ifndef UTF8 ++ while ((c = fgetc (f)) != EOF) { + edit_insert (edit, c); + i++; ++#else /* UTF8 */ ++ unsigned char buf[MB_LEN_MAX]; ++ int charpos = 0; ++ mbstate_t mbs; ++ ++ while ((c = fgetc (f)) != EOF) { ++ mc_wchar_t wc; ++ int size; ++ int j; ++ ++ buf[charpos++] = c; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ size = mbrtowc(&wc, (char *)buf, charpos, &mbs); ++ ++ if (size == -2) ++ continue; /* incomplete */ ++ ++ else if (size >= 0) { ++ edit_insert (edit, wc); ++ i++; ++ charpos = 0; ++ continue; ++ } ++ else { ++ ++ /* invalid */ ++#ifdef __STDC_ISO_10646__ ++ for (j=0; jlast_byte; i++) + if (fputc (edit_get_byte (edit, i), f) < 0) + break; ++#else /* UTF8 */ ++ for (i = 0; i < edit->last_byte; i++) { ++ mc_wchar_t wc = edit_get_byte (edit, i); ++ int res; ++ char tmpbuf[MB_LEN_MAX]; ++ mbstate_t mbs; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ ++#ifdef __STDC_ISO_10646__ ++ if (wc >= BINARY_CHAR_OFFSET && wc < (BINARY_CHAR_OFFSET + 256)) { ++ res = 1; ++ tmpbuf[0] = (char) (wc - BINARY_CHAR_OFFSET); ++ } else ++#endif ++ res = wcrtomb(tmpbuf, wc, &mbs); ++ if (res > 0) { ++ if (fwrite(tmpbuf, res, 1, f) != 1) ++ break; ++ } ++ } ++#endif /* UTF8 */ + return i; + } + +@@ -290,12 +352,46 @@ edit_insert_file (WEdit *edit, const cha + int i, file, blocklen; + long current = edit->curs1; + unsigned char *buf; ++#ifdef UTF8 ++ mbstate_t mbs; ++ int bufstart = 0; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++#endif /* UTF8 */ + if ((file = mc_open (filename, O_RDONLY | O_BINARY)) == -1) + return 0; + buf = g_malloc (TEMP_BUF_LEN); ++#ifndef UTF8 + while ((blocklen = mc_read (file, (char *) buf, TEMP_BUF_LEN)) > 0) { + for (i = 0; i < blocklen; i++) + edit_insert (edit, buf[i]); ++#else /* UTF8 */ ++ while ((blocklen = mc_read (file, (char *) buf + bufstart, TEMP_BUF_LEN - bufstart)) > 0) { ++ blocklen += bufstart; ++ bufstart = 0; ++ for (i = 0; i < blocklen; ) { ++ mc_wchar_t wc; ++ int j; ++ int size = mbrtowc(&wc, (char *)buf + i, blocklen - i, &mbs); ++ if (size == -2) { /*incomplete char*/ ++ bufstart = blocklen - i; ++ memcpy(buf, buf+i, bufstart); ++ i = blocklen; ++ memset (&mbs, 0, sizeof (mbs)); ++ } ++ else if (size <= 0) { ++#ifdef __STDC_ISO_10646__ ++ edit_insert (edit, BINARY_CHAR_OFFSET + (mc_wchar_t)buf[i]); ++#endif ++ memset (&mbs, 0, sizeof (mbs)); ++ i++; /* skip broken char */ ++ } ++ else { ++ edit_insert (edit, wc); ++ i+=size; ++ } ++ } ++#endif /* UTF8 */ + } + edit_cursor_move (edit, current - edit->curs1); + g_free (buf); +@@ -385,7 +481,11 @@ cleanup: + static int + edit_load_file (WEdit *edit) + { ++#ifndef UTF8 + int fast_load = 1; ++#else /* UTF8 */ ++ int fast_load = 0; /* can't be used with multibyte characters */ ++#endif /* UTF8 */ + + /* Cannot do fast load if a filter is used */ + if (edit_find_filter (edit->filename) >= 0) +@@ -451,6 +551,7 @@ edit_load_position (WEdit *edit) + edit->prev_col = column; + edit_move_to_prev_col (edit, edit_bol (edit, edit->curs1)); + edit_move_display (edit, line - (edit->num_widget_lines / 2)); ++ edit->charpoint = 0; + } + + /* Save cursor position in the file */ +@@ -534,7 +635,7 @@ edit_init (WEdit *edit, int lines, int c + edit_set_filename (edit, filename); + edit->stack_size = START_STACK_SIZE; + edit->stack_size_mask = START_STACK_SIZE - 1; +- edit->undo_stack = g_malloc ((edit->stack_size + 10) * sizeof (long)); ++ edit->undo_stack = g_malloc ((edit->stack_size + 10) * sizeof (struct action)); + if (edit_load_file (edit)) { + /* edit_load_file already gives an error message */ + if (to_free) +@@ -689,14 +790,23 @@ void edit_push_action (WEdit * edit, lon + { + unsigned long sp = edit->stack_pointer; + unsigned long spm1; +- long *t; ++ ++ struct action *t; ++ mc_wchar_t ch = 0; ++ ++ if (c == CHAR_INSERT || c == CHAR_INSERT_AHEAD) { ++ va_list ap; ++ va_start (ap, c); ++ ch = va_arg (ap, mc_wint_t); ++ va_end (ap); ++ } + + /* first enlarge the stack if necessary */ + if (sp > edit->stack_size - 10) { /* say */ + if (option_max_undo < 256) + option_max_undo = 256; + if (edit->stack_size < (unsigned long) option_max_undo) { +- t = g_realloc (edit->undo_stack, (edit->stack_size * 2 + 10) * sizeof (long)); ++ t = g_realloc (edit->undo_stack, (edit->stack_size * 2 + 10) * sizeof (struct action)); + if (t) { + edit->undo_stack = t; + edit->stack_size <<= 1; +@@ -711,7 +821,7 @@ void edit_push_action (WEdit * edit, lon + #ifdef FAST_MOVE_CURSOR + if (c == CURS_LEFT_LOTS || c == CURS_RIGHT_LOTS) { + va_list ap; +- edit->undo_stack[sp] = c == CURS_LEFT_LOTS ? CURS_LEFT : CURS_RIGHT; ++ edit->undo_stack[sp].flags = c == CURS_LEFT_LOTS ? CURS_LEFT : CURS_RIGHT; + edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask; + va_start (ap, c); + c = -(va_arg (ap, int)); +@@ -722,12 +832,14 @@ void edit_push_action (WEdit * edit, lon + && spm1 != edit->stack_bottom + && ((sp - 2) & edit->stack_size_mask) != edit->stack_bottom) { + int d; +- if (edit->undo_stack[spm1] < 0) { +- d = edit->undo_stack[(sp - 2) & edit->stack_size_mask]; +- if (d == c) { +- if (edit->undo_stack[spm1] > -1000000000) { ++ mc_wchar_t d_ch; ++ if (edit->undo_stack[spm1].flags < 0) { ++ d = edit->undo_stack[(sp - 2) & edit->stack_size_mask].flags; ++ d_ch = edit->undo_stack[(sp - 2) & edit->stack_size_mask].ch; ++ if (d == c && d_ch == ch) { ++ if (edit->undo_stack[spm1].flags > -1000000000) { + if (c < KEY_PRESS) /* --> no need to push multiple do-nothings */ +- edit->undo_stack[spm1]--; ++ edit->undo_stack[spm1].flags--; + return; + } + } +@@ -735,19 +847,20 @@ void edit_push_action (WEdit * edit, lon + #ifndef NO_STACK_CURSMOVE_ANIHILATION + else if ((c == CURS_LEFT && d == CURS_RIGHT) + || (c == CURS_RIGHT && d == CURS_LEFT)) { /* a left then a right anihilate each other */ +- if (edit->undo_stack[spm1] == -2) ++ if (edit->undo_stack[spm1].flags == -2) + edit->stack_pointer = spm1; + else +- edit->undo_stack[spm1]++; ++ edit->undo_stack[spm1].flags++; + return; + } + #endif + } else { +- d = edit->undo_stack[spm1]; +- if (d == c) { ++ d = edit->undo_stack[spm1].flags; ++ d_ch = edit->undo_stack[spm1].ch; ++ if (d == c && d_ch == ch) { + if (c >= KEY_PRESS) + return; /* --> no need to push multiple do-nothings */ +- edit->undo_stack[sp] = -2; ++ edit->undo_stack[sp].flags = -2; + goto check_bottom; + } + #ifndef NO_STACK_CURSMOVE_ANIHILATION +@@ -759,7 +872,9 @@ void edit_push_action (WEdit * edit, lon + #endif + } + } +- edit->undo_stack[sp] = c; ++ edit->undo_stack[sp].flags = c; ++ edit->undo_stack[sp].ch = ch; ++ + check_bottom: + + edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask; +@@ -772,10 +887,10 @@ void edit_push_action (WEdit * edit, lon + (((unsigned long) c + 1) & edit->stack_size_mask) == edit->stack_bottom) + do { + edit->stack_bottom = (edit->stack_bottom + 1) & edit->stack_size_mask; +- } while (edit->undo_stack[edit->stack_bottom] < KEY_PRESS && edit->stack_bottom != edit->stack_pointer); ++ } while (edit->undo_stack[edit->stack_bottom].flags < KEY_PRESS && edit->stack_bottom != edit->stack_pointer); + + /*If a single key produced enough pushes to wrap all the way round then we would notice that the [stack_bottom] does not contain KEY_PRESS. The stack is then initialised: */ +- if (edit->stack_pointer != edit->stack_bottom && edit->undo_stack[edit->stack_bottom] < KEY_PRESS) ++ if (edit->stack_pointer != edit->stack_bottom && edit->undo_stack[edit->stack_bottom].flags < KEY_PRESS) + edit->stack_bottom = edit->stack_pointer = 0; + } + +@@ -784,30 +899,30 @@ void edit_push_action (WEdit * edit, lon + then the file should be as it was when he loaded up. Then set edit->modified to 0. + */ + static long +-pop_action (WEdit * edit) ++pop_action (WEdit * edit, struct action *c) + { +- long c; + unsigned long sp = edit->stack_pointer; + if (sp == edit->stack_bottom) { +- return STACK_BOTTOM; ++ c->flags = STACK_BOTTOM; ++ return c->flags; + } + sp = (sp - 1) & edit->stack_size_mask; +- if ((c = edit->undo_stack[sp]) >= 0) { +-/* edit->undo_stack[sp] = '@'; */ ++ *c = edit->undo_stack[sp]; ++ if (edit->undo_stack[sp].flags >= 0) { + edit->stack_pointer = (edit->stack_pointer - 1) & edit->stack_size_mask; +- return c; ++ return c->flags; + } + if (sp == edit->stack_bottom) { + return STACK_BOTTOM; + } +- c = edit->undo_stack[(sp - 1) & edit->stack_size_mask]; +- if (edit->undo_stack[sp] == -2) { +-/* edit->undo_stack[sp] = '@'; */ ++ *c = edit->undo_stack[(sp - 1) & edit->stack_size_mask]; ++ ++ if (edit->undo_stack[sp].flags == -2) { + edit->stack_pointer = sp; + } else +- edit->undo_stack[sp]++; ++ edit->undo_stack[sp].flags++; + +- return c; ++ return c->flags; + } + + /* is called whenever a modification is made by one of the four routines below */ +@@ -828,7 +943,7 @@ static inline void edit_modification (WE + */ + + void +-edit_insert (WEdit *edit, int c) ++edit_insert (WEdit *edit, mc_wchar_t c) + { + /* check if file has grown to large */ + if (edit->last_byte >= SIZE_LIMIT) +@@ -866,12 +981,11 @@ edit_insert (WEdit *edit, int c) + /* add a new buffer if we've reached the end of the last one */ + if (!(edit->curs1 & M_EDIT_BUF_SIZE)) + edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = +- g_malloc (EDIT_BUF_SIZE); ++ g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + + /* perform the insertion */ +- edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE][edit-> +- curs1 & M_EDIT_BUF_SIZE] +- = (unsigned char) c; ++ edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] ++ [edit->curs1 & M_EDIT_BUF_SIZE] = c; + + /* update file length */ + edit->last_byte++; +@@ -882,7 +996,7 @@ edit_insert (WEdit *edit, int c) + + + /* same as edit_insert and move left */ +-void edit_insert_ahead (WEdit * edit, int c) ++void edit_insert_ahead (WEdit * edit, mc_wchar_t c) + { + if (edit->last_byte >= SIZE_LIMIT) + return; +@@ -905,7 +1019,7 @@ void edit_insert_ahead (WEdit * edit, in + edit->last_get_rule += (edit->last_get_rule >= edit->curs1); + + if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE)) +- edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1] = c; + + edit->last_byte++; +@@ -915,7 +1029,7 @@ void edit_insert_ahead (WEdit * edit, in + + int edit_delete (WEdit * edit) + { +- int p; ++ mc_wint_t p; + if (!edit->curs2) + return 0; + +@@ -939,7 +1053,7 @@ int edit_delete (WEdit * edit) + edit->total_lines--; + edit->force |= REDRAW_AFTER_CURSOR; + } +- edit_push_action (edit, p + 256); ++ edit_push_action (edit, CHAR_INSERT_AHEAD, p); + if (edit->curs1 < edit->start_display) { + edit->start_display--; + if (p == '\n') +@@ -953,7 +1067,7 @@ int edit_delete (WEdit * edit) + static int + edit_backspace (WEdit * edit) + { +- int p; ++ mc_wint_t p; + if (!edit->curs1) + return 0; + +@@ -977,7 +1091,7 @@ edit_backspace (WEdit * edit) + edit->total_lines--; + edit->force |= REDRAW_AFTER_CURSOR; + } +- edit_push_action (edit, p); ++ edit_push_action (edit, CHAR_INSERT, p); + + if (edit->curs1 < edit->start_display) { + edit->start_display--; +@@ -990,10 +1104,18 @@ edit_backspace (WEdit * edit) + + #ifdef FAST_MOVE_CURSOR + +-static void memqcpy (WEdit * edit, unsigned char *dest, unsigned char *src, int n) ++static void memqcpy (WEdit * edit, mc_wchar_t *dest, mc_wchar_t *src, int n) + { + unsigned long next; ++#ifndef UTF8 + while ((next = (unsigned long) memccpy (dest, src, '\n', n))) { ++#else /* UTF8 */ ++ while (n) { ++ next = 0; ++ while (next < n && src[next]!='\n') next++; ++ if (next < n) next++; ++ wmemcpy (dest, src, next) ++#endif /* UTF8 */ + edit->curs_line--; + next -= (unsigned long) dest; + n -= next; +@@ -1006,7 +1128,7 @@ int + edit_move_backward_lots (WEdit *edit, long increment) + { + int r, s, t; +- unsigned char *p; ++ mc_wchar_t *p; + + if (increment > edit->curs1) + increment = edit->curs1; +@@ -1046,7 +1168,7 @@ edit_move_backward_lots (WEdit *edit, lo + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p; + else + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = +- g_malloc (EDIT_BUF_SIZE); ++ g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + } else { + g_free (p); + } +@@ -1084,7 +1206,7 @@ edit_move_backward_lots (WEdit *edit, lo + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p; + else + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = +- g_malloc (EDIT_BUF_SIZE); ++ g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + } else { + g_free (p); + } +@@ -1116,7 +1238,7 @@ int edit_cursor_move (WEdit * edit, long + + c = edit_get_byte (edit, edit->curs1 - 1); + if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE)) +- edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1] = c; + edit->curs2++; + c = edit->buffers1[(edit->curs1 - 1) >> S_EDIT_BUF_SIZE][(edit->curs1 - 1) & M_EDIT_BUF_SIZE]; +@@ -1141,7 +1263,7 @@ int edit_cursor_move (WEdit * edit, long + + c = edit_get_byte (edit, edit->curs1); + if (!(edit->curs1 & M_EDIT_BUF_SIZE)) +- edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE); ++ edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t)); + edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE][edit->curs1 & M_EDIT_BUF_SIZE] = c; + edit->curs1++; + c = edit->buffers2[(edit->curs2 - 1) >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - ((edit->curs2 - 1) & M_EDIT_BUF_SIZE) - 1]; +@@ -1248,7 +1370,7 @@ long edit_move_forward3 (WEdit * edit, l + q = edit->last_byte + 2; + + for (col = 0, p = current; p < q; p++) { +- int c; ++ mc_wchar_t c; + if (cols != -10) { + if (col == cols) + return p; +@@ -1266,7 +1388,7 @@ long edit_move_forward3 (WEdit * edit, l + } else if (c < 32 || c == 127) + col += 2; /* Caret notation for control characters */ + else +- col++; ++ col += wcwidth(c); + } + return col; + } +@@ -1399,12 +1521,16 @@ static int + is_blank (WEdit *edit, long offset) + { + long s, f; +- int c; ++ mc_wchar_t c; + s = edit_bol (edit, offset); + f = edit_eol (edit, offset) - 1; + while (s <= f) { + c = edit_get_byte (edit, s++); ++#ifndef UTF8 + if (!isspace (c)) ++#else ++ if (!iswspace (c)) ++#endif /* UTF8 */ + return 0; + } + return 1; +@@ -1659,6 +1785,7 @@ my_type_of (int c) + return 2; + return 0x80000000UL; + } ++#ifndef UTF8 + if (isupper (c)) + c = 'A'; + else if (islower (c)) +@@ -1669,6 +1796,18 @@ my_type_of (int c) + c = '0'; + else if (isspace (c)) + c = ' '; ++#else ++ if (iswupper (c)) ++ c = 'A'; ++ else if (iswlower (c)) ++ c = 'a'; ++ else if (iswalpha (c)) ++ c = 'a'; ++ else if (iswdigit (c)) ++ c = '0'; ++ else if (iswspace (c)) ++ c = ' '; ++#endif /* UTF8 */ + q = strchr (option_chars_move_whole_word, c); + if (!q) + return 0xFFFFFFFFUL; +@@ -1693,10 +1832,18 @@ edit_left_word_move (WEdit *edit, int s) + c2 = edit_get_byte (edit, edit->curs1); + if (!(my_type_of (c1) & my_type_of (c2))) + break; ++#ifndef UTF8 + if (isspace (c1) && !isspace (c2)) ++#else ++ if (iswspace (c1) && !iswspace (c2)) ++#endif /* UTF8 */ + break; + if (s) ++#ifndef UTF8 + if (!isspace (c1) && isspace (c2)) ++#else ++ if (!iswspace (c1) && iswspace (c2)) ++#endif /* UTF8 */ + break; + } + } +@@ -1719,10 +1866,18 @@ edit_right_word_move (WEdit *edit, int s + c2 = edit_get_byte (edit, edit->curs1); + if (!(my_type_of (c1) & my_type_of (c2))) + break; ++#ifndef UTF8 + if (isspace (c1) && !isspace (c2)) ++#else ++ if (iswspace (c1) && !iswspace (c2)) ++#endif /* UTF8 */ + break; + if (s) ++#ifndef UTF8 + if (!isspace (c1) && isspace (c2)) ++#else ++ if (!iswspace (c1) && iswspace (c2)) ++#endif /* UTF8 */ + break; + } + } +@@ -1742,7 +1897,11 @@ static void edit_right_delete_word (WEdi + break; + c1 = edit_delete (edit); + c2 = edit_get_byte (edit, edit->curs1); ++#ifndef UTF8 + if ((isspace (c1) == 0) != (isspace (c2) == 0)) ++#else ++ if ((iswspace (c1) == 0) != (iswspace (c2) == 0)) ++#endif /* UTF8 */ + break; + if (!(my_type_of (c1) & my_type_of (c2))) + break; +@@ -1757,7 +1916,11 @@ static void edit_left_delete_word (WEdit + break; + c1 = edit_backspace (edit); + c2 = edit_get_byte (edit, edit->curs1 - 1); ++#ifndef UTF8 + if ((isspace (c1) == 0) != (isspace (c2) == 0)) ++#else ++ if ((iswspace (c1) == 0) != (iswspace (c2) == 0)) ++#endif /* UTF8 */ + break; + if (!(my_type_of (c1) & my_type_of (c2))) + break; +@@ -1771,13 +1934,13 @@ static void edit_left_delete_word (WEdit + static void + edit_do_undo (WEdit * edit) + { +- long ac; ++ struct action ac; + long count = 0; + + edit->stack_disable = 1; /* don't record undo's onto undo stack! */ + +- while ((ac = pop_action (edit)) < KEY_PRESS) { +- switch ((int) ac) { ++ while (pop_action (edit, &ac) < KEY_PRESS) { ++ switch ((int) ac.flags) { + case STACK_BOTTOM: + goto done_undo; + case CURS_RIGHT: +@@ -1798,31 +1961,33 @@ edit_do_undo (WEdit * edit) + case COLUMN_OFF: + column_highlighting = 0; + break; ++ case CHAR_INSERT: ++ edit_insert (edit, ac.ch); ++ break; ++ case CHAR_INSERT_AHEAD: ++ edit_insert_ahead (edit, ac.ch); ++ break; + } +- if (ac >= 256 && ac < 512) +- edit_insert_ahead (edit, ac - 256); +- if (ac >= 0 && ac < 256) +- edit_insert (edit, ac); + +- if (ac >= MARK_1 - 2 && ac < MARK_2 - 2) { +- edit->mark1 = ac - MARK_1; ++ if (ac.flags >= MARK_1 - 2 && ac.flags < MARK_2 - 2) { ++ edit->mark1 = ac.flags - MARK_1; + edit->column1 = edit_move_forward3 (edit, edit_bol (edit, edit->mark1), 0, edit->mark1); +- } else if (ac >= MARK_2 - 2 && ac < KEY_PRESS) { +- edit->mark2 = ac - MARK_2; ++ } else if (ac.flags >= MARK_2 - 2 && ac.flags < KEY_PRESS) { ++ edit->mark2 = ac.flags - MARK_2; + edit->column2 = edit_move_forward3 (edit, edit_bol (edit, edit->mark2), 0, edit->mark2); + } + if (count++) + edit->force |= REDRAW_PAGE; /* more than one pop usually means something big */ + } + +- if (edit->start_display > ac - KEY_PRESS) { +- edit->start_line -= edit_count_lines (edit, ac - KEY_PRESS, edit->start_display); ++ if (edit->start_display > ac.flags - KEY_PRESS) { ++ edit->start_line -= edit_count_lines (edit, ac.flags - KEY_PRESS, edit->start_display); + edit->force |= REDRAW_PAGE; +- } else if (edit->start_display < ac - KEY_PRESS) { +- edit->start_line += edit_count_lines (edit, edit->start_display, ac - KEY_PRESS); ++ } else if (edit->start_display < ac.flags - KEY_PRESS) { ++ edit->start_line += edit_count_lines (edit, edit->start_display, ac.flags - KEY_PRESS); + edit->force |= REDRAW_PAGE; + } +- edit->start_display = ac - KEY_PRESS; /* see push and pop above */ ++ edit->start_display = ac.flags - KEY_PRESS; /* see push and pop above */ + edit_update_curs_row (edit); + + done_undo:; +@@ -2102,7 +2267,7 @@ static void edit_goto_matching_bracket ( + * passed as -1. Commands are executed, and char_for_insertion is + * inserted at the cursor. + */ +-void edit_execute_key_command (WEdit *edit, int command, int char_for_insertion) ++void edit_execute_key_command (WEdit *edit, int command, mc_wint_t char_for_insertion) + { + if (command == CK_Begin_Record_Macro) { + edit->macro_i = 0; +@@ -2137,7 +2302,7 @@ static const char * const shell_cmd[] = + all of them. It also does not check for the Undo command. + */ + void +-edit_execute_cmd (WEdit *edit, int command, int char_for_insertion) ++edit_execute_cmd (WEdit *edit, int command, mc_wint_t char_for_insertion) + { + edit->force |= REDRAW_LINE; + +@@ -2170,7 +2335,7 @@ edit_execute_cmd (WEdit *edit, int comma + } + + /* An ordinary key press */ +- if (char_for_insertion >= 0) { ++ if (char_for_insertion != (mc_wint_t) -1) { + if (edit->overwrite) { + if (edit_get_byte (edit, edit->curs1) != '\n') + edit_delete (edit); diff -up mc-4.6.2-pre1/edit/editdraw.c.utf8 mc-4.6.2-pre1/edit/editdraw.c --- mc-4.6.2-pre1/edit/editdraw.c.utf8 2007-08-27 14:06:03.000000000 +0200 -+++ mc-4.6.2-pre1/edit/editdraw.c 2008-02-25 15:35:11.000000000 +0100 ++++ mc-4.6.2-pre1/edit/editdraw.c 2008-10-23 14:00:45.000000000 +0200 @@ -70,11 +70,16 @@ static void status_string (WEdit * edit, * as decimal and as hex. */ @@ -4980,7 +1910,7 @@ diff -up mc-4.6.2-pre1/edit/editdraw.c.utf8 mc-4.6.2-pre1/edit/editdraw.c int color; int i; -@@ -307,62 +320,88 @@ edit_draw_this_line (WEdit *edit, long b +@@ -307,62 +320,89 @@ edit_draw_this_line (WEdit *edit, long b } while (col <= end_col - edit->start_col) { @@ -5078,6 +2008,7 @@ diff -up mc-4.6.2-pre1/edit/editdraw.c.utf8 mc-4.6.2-pre1/edit/editdraw.c - while (--i) - *(p++) = c; + p->ch |= ' '; ++ p->style = ' '; + c = p->style & ~MOD_CURSOR; + p++; + while (--i) { @@ -5095,7 +2026,7 @@ diff -up mc-4.6.2-pre1/edit/editdraw.c.utf8 mc-4.6.2-pre1/edit/editdraw.c col++; break; } -@@ -372,22 +411,47 @@ edit_draw_this_line (WEdit *edit, long b +@@ -372,22 +412,47 @@ edit_draw_this_line (WEdit *edit, long b /* Caret notation for control characters */ if (c < 32) { @@ -5150,7 +2081,7 @@ diff -up mc-4.6.2-pre1/edit/editdraw.c.utf8 mc-4.6.2-pre1/edit/editdraw.c } col++; break; -@@ -398,7 +462,7 @@ edit_draw_this_line (WEdit *edit, long b +@@ -398,7 +463,7 @@ edit_draw_this_line (WEdit *edit, long b } else { start_col_real = start_col = 0; } @@ -5159,64 +2090,9 @@ diff -up mc-4.6.2-pre1/edit/editdraw.c.utf8 mc-4.6.2-pre1/edit/editdraw.c print_to_widget (edit, row, start_col, start_col_real, end_col, line); } -diff -up mc-4.6.2-pre1/edit/editwidget.c.utf8 mc-4.6.2-pre1/edit/editwidget.c ---- mc-4.6.2-pre1/edit/editwidget.c.utf8 2006-12-10 23:07:28.000000000 +0100 -+++ mc-4.6.2-pre1/edit/editwidget.c 2008-02-25 14:56:22.000000000 +0100 -@@ -331,7 +331,8 @@ edit_callback (Widget *w, widget_msg_t m - - case WIDGET_KEY: - { -- int cmd, ch; -+ int cmd; -+ mc_wint_t ch; - - /* The user may override the access-keys for the menu bar. */ - if (edit_translate_key (e, parm, &cmd, &ch)) { -diff -up mc-4.6.2-pre1/edit/edit-widget.h.utf8 mc-4.6.2-pre1/edit/edit-widget.h ---- mc-4.6.2-pre1/edit/edit-widget.h.utf8 2007-02-03 02:03:53.000000000 +0100 -+++ mc-4.6.2-pre1/edit/edit-widget.h 2008-02-25 14:56:22.000000000 +0100 -@@ -30,6 +30,11 @@ typedef struct edit_key_map_type { - long command; - } edit_key_map_type; - -+struct action { -+ mc_wchar_t ch; -+ long flags; -+}; -+ - struct WEdit { - Widget widget; - -@@ -42,8 +47,17 @@ struct WEdit { - /* dynamic buffers and cursor position for editor: */ - long curs1; /* position of the cursor from the beginning of the file. */ - long curs2; /* position from the end of the file */ -+#ifndef UTF8 - unsigned char *buffers1[MAXBUFF + 1]; /* all data up to curs1 */ - unsigned char *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */ -+#else /* UTF8 */ -+ mc_wchar_t *buffers1[MAXBUFF + 1]; /* all data up to curs1 */ -+ mc_wchar_t *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */ -+ -+ unsigned char charbuf[MB_LEN_MAX]; -+ int charpoint; -+#endif /* UTF8 */ -+ - - /* search variables */ - long search_start; /* First character to start searching from */ -@@ -87,7 +101,7 @@ struct WEdit { - - /* undo stack and pointers */ - unsigned long stack_pointer; -- long *undo_stack; -+ struct action *undo_stack; - unsigned long stack_size; - unsigned long stack_size_mask; - unsigned long stack_bottom; diff -up mc-4.6.2-pre1/edit/edit.h.utf8 mc-4.6.2-pre1/edit/edit.h --- mc-4.6.2-pre1/edit/edit.h.utf8 2006-12-10 23:07:28.000000000 +0100 -+++ mc-4.6.2-pre1/edit/edit.h 2008-02-25 14:56:22.000000000 +0100 ++++ mc-4.6.2-pre1/edit/edit.h 2008-10-23 14:00:12.000000000 +0200 @@ -25,6 +25,27 @@ #include @@ -5311,7 +2187,7 @@ diff -up mc-4.6.2-pre1/edit/edit.h.utf8 mc-4.6.2-pre1/edit/edit.h diff -up mc-4.6.2-pre1/edit/editkeys.c.utf8 mc-4.6.2-pre1/edit/editkeys.c --- mc-4.6.2-pre1/edit/editkeys.c.utf8 2006-02-01 18:07:11.000000000 +0100 -+++ mc-4.6.2-pre1/edit/editkeys.c 2008-02-25 14:56:22.000000000 +0100 ++++ mc-4.6.2-pre1/edit/editkeys.c 2008-10-23 14:00:12.000000000 +0200 @@ -182,10 +182,10 @@ static const edit_key_map_type common_ke * 'command' is one of the editor commands from editcmddef.h. */ @@ -5366,40 +2242,2318 @@ diff -up mc-4.6.2-pre1/edit/editkeys.c.utf8 mc-4.6.2-pre1/edit/editkeys.c /* unchanged, key has no function here */ return 0; } -diff -up mc-4.6.2-pre1/acinclude.m4.utf8 mc-4.6.2-pre1/acinclude.m4 ---- mc-4.6.2-pre1/acinclude.m4.utf8 2006-09-07 17:59:51.000000000 +0200 -+++ mc-4.6.2-pre1/acinclude.m4 2008-02-25 14:56:22.000000000 +0100 -@@ -399,14 +399,14 @@ AC_DEFUN([MC_WITH_SLANG], [ - fi +diff -up mc-4.6.2-pre1/edit/editwidget.c.utf8 mc-4.6.2-pre1/edit/editwidget.c +--- mc-4.6.2-pre1/edit/editwidget.c.utf8 2006-12-10 23:07:28.000000000 +0100 ++++ mc-4.6.2-pre1/edit/editwidget.c 2008-10-23 14:00:12.000000000 +0200 +@@ -331,7 +331,8 @@ edit_callback (Widget *w, widget_msg_t m - dnl Unless external S-Lang was requested, reject S-Lang with UTF-8 hacks -- if test x$with_screen = xslang; then -- : -- m4_if([$1], strict, , -- [AC_CHECK_LIB([slang], [SLsmg_write_nwchars], -- [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \ --it's not fully supported yet]) -- with_screen=mcslang])]) -- fi -+dnl if test x$with_screen = xslang; then -+dnl : -+dnl m4_if([$1], strict, , -+dnl [AC_CHECK_LIB([slang], [SLsmg_write_nwchars], -+dnl [AC_MSG_WARN([Rejecting S-Lang with UTF-8 support, \ -+dnl it's not fully supported yet]) -+dnl with_screen=mcslang])]) -+dnl fi + case WIDGET_KEY: + { +- int cmd, ch; ++ int cmd; ++ mc_wint_t ch; - if test x$with_screen = xslang; then - AC_DEFINE(HAVE_SYSTEM_SLANG, 1, -diff -Nrbu mc-4.6.1a/src/view.c mc-4.6.1a-OK/src/view.c ---- mc-4.6.2-pre1/src/view.c 2006-05-05 19:01:49.000000000 +0400 -+++ mc-4.6.2-pre1/src/view.c 2006-05-05 18:39:24.000000000 +0400 -@@ -2006,16 +2006,19 @@ + /* The user may override the access-keys for the menu bar. */ + if (edit_translate_key (e, parm, &cmd, &ch)) { +diff -up mc-4.6.2-pre1/edit/edit-widget.h.utf8 mc-4.6.2-pre1/edit/edit-widget.h +--- mc-4.6.2-pre1/edit/edit-widget.h.utf8 2007-02-03 02:03:53.000000000 +0100 ++++ mc-4.6.2-pre1/edit/edit-widget.h 2008-10-23 14:00:12.000000000 +0200 +@@ -30,6 +30,11 @@ typedef struct edit_key_map_type { + long command; + } edit_key_map_type; + ++struct action { ++ mc_wchar_t ch; ++ long flags; ++}; ++ + struct WEdit { + Widget widget; + +@@ -42,8 +47,17 @@ struct WEdit { + /* dynamic buffers and cursor position for editor: */ + long curs1; /* position of the cursor from the beginning of the file. */ + long curs2; /* position from the end of the file */ ++#ifndef UTF8 + unsigned char *buffers1[MAXBUFF + 1]; /* all data up to curs1 */ + unsigned char *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */ ++#else /* UTF8 */ ++ mc_wchar_t *buffers1[MAXBUFF + 1]; /* all data up to curs1 */ ++ mc_wchar_t *buffers2[MAXBUFF + 1]; /* all data from end of file down to curs2 */ ++ ++ unsigned char charbuf[MB_LEN_MAX]; ++ int charpoint; ++#endif /* UTF8 */ ++ + + /* search variables */ + long search_start; /* First character to start searching from */ +@@ -87,7 +101,7 @@ struct WEdit { + + /* undo stack and pointers */ + unsigned long stack_pointer; +- long *undo_stack; ++ struct action *undo_stack; + unsigned long stack_size; + unsigned long stack_size_mask; + unsigned long stack_bottom; +diff -up mc-4.6.2-pre1/edit/wordproc.c.utf8 mc-4.6.2-pre1/edit/wordproc.c +--- mc-4.6.2-pre1/edit/wordproc.c.utf8 2006-06-16 22:01:29.000000000 +0200 ++++ mc-4.6.2-pre1/edit/wordproc.c 2008-10-23 14:00:12.000000000 +0200 +@@ -40,7 +40,12 @@ + + #define tab_width option_tab_spacing + ++#ifndef UTF8 + #define NO_FORMAT_CHARS_START "-+*\\,.;:&>" ++#else /* UTF8 */ ++#define NO_FORMAT_CHARS_START L"-+*\\,.;:&>" ++#endif /* UTF8 */ ++ + #define FONT_MEAN_WIDTH 1 + + static long +@@ -57,14 +62,21 @@ line_start (WEdit *edit, long line) + p = edit_move_forward (edit, p, line - l, 0); + + p = edit_bol (edit, p); ++ ++#ifndef UTF8 + while (strchr ("\t ", edit_get_byte (edit, p))) ++#else /* UTF8 */ ++ while (wcschr (L"\t ", edit_get_byte (edit, p))) ++#endif /* UTF8 */ ++ + p++; + return p; + } + + static int bad_line_start (WEdit * edit, long p) + { +- int c; ++ mc_wint_t c; ++ + c = edit_get_byte (edit, p); + if (c == '.') { /* `...' is acceptable */ + if (edit_get_byte (edit, p + 1) == '.') +@@ -78,7 +90,13 @@ static int bad_line_start (WEdit * edit, + return 0; /* `---' is acceptable */ + return 1; + } ++ ++#ifndef UTF8 + if (strchr (NO_FORMAT_CHARS_START, c)) ++#else /* UTF8 */ ++ if (wcschr (NO_FORMAT_CHARS_START, c)) ++#endif /* UTF8 */ ++ + return 1; + return 0; + } +@@ -131,33 +149,37 @@ end_paragraph (WEdit *edit, int force) + i - edit->curs_line, 0)); + } + +-static unsigned char * ++static mc_wchar_t * + get_paragraph (WEdit *edit, long p, long q, int indent, int *size) + { +- unsigned char *s, *t; ++ mc_wchar_t *s, *t; + #if 0 +- t = g_malloc ((q - p) + 2 * (q - p) / option_word_wrap_line_length + +- 10); ++ t = g_malloc (((q - p) + 2 * (q - p) / option_word_wrap_line_length + ++ 10) * sizeof(mc_wchar_t)); + #else +- t = g_malloc (2 * (q - p) + 100); ++ t = g_malloc ((2 * (q - p) + 100) * sizeof(mc_wchar_t)); + #endif + if (!t) + return 0; + for (s = t; p < q; p++, s++) { + if (indent) + if (edit_get_byte (edit, p - 1) == '\n') ++#ifndef UTF8 + while (strchr ("\t ", edit_get_byte (edit, p))) ++#else /* UTF8 */ ++ while (wcschr (L"\t ", edit_get_byte (edit, p))) ++#endif /* UTF8 */ + p++; + *s = edit_get_byte (edit, p); + } +- *size = (unsigned long) s - (unsigned long) t; ++ *size = s - t; + t[*size] = '\n'; + return t; + } + +-static void strip_newlines (unsigned char *t, int size) ++static void strip_newlines (mc_wchar_t *t, int size) + { +- unsigned char *p = t; ++ mc_wchar_t *p = t; + while (size--) { + *p = *p == '\n' ? ' ' : *p; + p++; +@@ -174,7 +196,7 @@ static inline int next_tab_pos (int x) + { + return x += tab_width - x % tab_width; + } +-static int line_pixel_length (unsigned char *t, long b, int l) ++static int line_pixel_length (mc_wchar_t *t, long b, int l) + { + int x = 0, c, xn = 0; + for (;;) { +@@ -198,7 +220,7 @@ static int line_pixel_length (unsigned c + } + + static int +-next_word_start (unsigned char *t, int q, int size) ++next_word_start (mc_wchar_t *t, int q, int size) + { + int i; + int saw_ws = 0; +@@ -222,7 +244,7 @@ next_word_start (unsigned char *t, int q + + /* find the start of a word */ + static int +-word_start (unsigned char *t, int q, int size) ++word_start (mc_wchar_t *t, int q, int size) + { + int i = q; + if (t[q] == ' ' || t[q] == '\t') +@@ -241,7 +263,7 @@ word_start (unsigned char *t, int q, int + } + + /* replaces ' ' with '\n' to properly format a paragraph */ +-static void format_this (unsigned char *t, int size, int indent) ++static void format_this (mc_wchar_t *t, int size, int indent) + { + int q = 0, ww; + strip_newlines (t, size); +@@ -269,7 +291,7 @@ static void format_this (unsigned char * + } + } + +-static void replace_at (WEdit * edit, long q, int c) ++static void replace_at (WEdit * edit, long q, mc_wint_t c) + { + edit_cursor_move (edit, q - edit->curs1); + edit_delete (edit); +@@ -278,18 +300,27 @@ static void replace_at (WEdit * edit, lo + + /* replaces a block of text */ + static void +-put_paragraph (WEdit * edit, unsigned char *t, long p, int indent, int size) ++put_paragraph (WEdit * edit, mc_wchar_t *t, long p, int indent, int size) + { + long cursor; +- int i, c = 0; ++ int i; ++ mc_wchar_t c = 0; + cursor = edit->curs1; + if (indent) ++#ifndef UTF8 + while (strchr ("\t ", edit_get_byte (edit, p))) ++#else /* UTF8 */ ++ while (wcschr (L"\t ", edit_get_byte (edit, p))) ++#endif /* UTF8 */ + p++; + for (i = 0; i < size; i++, p++) { + if (i && indent) { + if (t[i - 1] == '\n' && c == '\n') { ++#ifndef UTF8 + while (strchr ("\t ", edit_get_byte (edit, p))) ++#else /* UTF8 */ ++ while (wcschr (L"\t ", edit_get_byte (edit, p))) ++#endif /* UTF8 */ + p++; + } else if (t[i - 1] == '\n') { + long curs; +@@ -301,7 +332,11 @@ put_paragraph (WEdit * edit, unsigned ch + p = edit->curs1; + } else if (c == '\n') { + edit_cursor_move (edit, p - edit->curs1); ++#ifndef UTF8 + while (strchr ("\t ", edit_get_byte (edit, p))) { ++#else /* UTF8 */ ++ while (wcschr (L"\t ", edit_get_byte (edit, p))) { ++#endif /* UTF8 */ + edit_delete (edit); + if (cursor > edit->curs1) + cursor--; +@@ -334,7 +369,7 @@ format_paragraph (WEdit *edit, int force + { + long p, q; + int size; +- unsigned char *t; ++ mc_wchar_t *t; + int indent = 0; + if (option_word_wrap_line_length < 2) + return; +@@ -344,17 +379,25 @@ format_paragraph (WEdit *edit, int force + q = end_paragraph (edit, force); + indent = test_indent (edit, p, q); + t = get_paragraph (edit, p, q, indent, &size); +- if (!t) ++ if (!t) + return; + if (!force) { + int i; ++#ifndef UTF8 + if (strchr (NO_FORMAT_CHARS_START, *t)) { ++#else /* UTF8 */ ++ if (wcschr (NO_FORMAT_CHARS_START, *t)) { ++#endif /* UTF8 */ + g_free (t); + return; + } + for (i = 0; i < size - 1; i++) { + if (t[i] == '\n') { ++#ifndef UTF8 + if (strchr (NO_FORMAT_CHARS_START "\t ", t[i + 1])) { ++#else /* UTF8 */ ++ if (wcschr (NO_FORMAT_CHARS_START "\t", t[i + 1])) { ++#endif /* UTF8 */ + g_free (t); + return; + } +diff -up mc-4.6.2-pre1/src/achown.c.utf8 mc-4.6.2-pre1/src/achown.c +--- mc-4.6.2-pre1/src/achown.c.utf8 2005-09-05 03:36:58.000000000 +0200 ++++ mc-4.6.2-pre1/src/achown.c 2008-10-23 14:00:12.000000000 +0200 +@@ -584,6 +584,12 @@ init_chown_advanced (void) + b_att[2] = button_new (XTRACT (6)); + b_user = button_new (XTRACT (5)); + b_group = button_new (XTRACT (4)); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ b_user->text = g_realloc (b_user->text, MB_CUR_MAX * 15 + 1); ++ b_group->text = g_realloc (b_group->text, MB_CUR_MAX * 15 + 1); ++ } ++#endif + + add_widget (ch_dlg, b_group); + add_widget (ch_dlg, b_user); +diff -up mc-4.6.2-pre1/src/boxes.c.utf8 mc-4.6.2-pre1/src/boxes.c +--- mc-4.6.2-pre1/src/boxes.c.utf8 2006-02-28 17:15:21.000000000 +0100 ++++ mc-4.6.2-pre1/src/boxes.c 2008-10-23 14:00:12.000000000 +0200 +@@ -153,23 +153,23 @@ display_init (int radio_sel, char *init_ + display_title = _(display_title); + for (i = 0; i < LIST_TYPES; i++) { + displays[i] = _(displays[i]); +- if ((l = strlen (displays[i])) > maxlen) ++ if ((l = mbstrlen (displays[i])) > maxlen) + maxlen = l; + } + +- i = strlen (ok_button) + 5; +- l = strlen (cancel_button) + 3; ++ i = mbstrlen (ok_button) + 5; ++ l = mbstrlen (cancel_button) + 3; + l = max (i, l); + + i = maxlen + l + 16; + if (i > DISPLAY_X) + DISPLAY_X = i; + +- i = strlen (user_mini_status) + 13; ++ i = mbstrlen (user_mini_status) + 13; + if (i > DISPLAY_X) + DISPLAY_X = i; + +- i = strlen (display_title) + 10; ++ i = mbstrlen (display_title) + 10; + if (i > DISPLAY_X) + DISPLAY_X = i; + +@@ -288,20 +288,20 @@ sort_box (sortfn *sort_fn, int *reverse, + int maxlen = 0; + for (i = SORT_TYPES - 1; i >= 0; i--) { + sort_orders_names[i] = _(sort_orders[i].sort_name); +- r = strlen (sort_orders_names[i]); ++ r = mbstrlen (sort_orders_names[i]); + if (r > maxlen) + maxlen = r; + } + + check_pos = maxlen + 9; + +- r = strlen (reverse_label) + 4; +- i = strlen (case_label) + 4; ++ r = mbstrlen (reverse_label) + 4; ++ i = mbstrlen (case_label) + 4; + if (i > r) + r = i; + +- l = strlen (ok_button) + 6; +- i = strlen (cancel_button) + 4; ++ l = mbstrlen (ok_button) + 6; ++ i = mbstrlen (cancel_button) + 4; + if (i > l) + l = i; + +@@ -310,7 +310,7 @@ sort_box (sortfn *sort_fn, int *reverse, + if (i > SORT_X) + SORT_X = i; + +- i = strlen (sort_title) + 6; ++ i = mbstrlen (sort_title) + 6; + if (i > SORT_X) + SORT_X = i; + +@@ -408,7 +408,7 @@ confirm_box (void) + while (i--) + { + conf_widgets [i].text = _(conf_widgets [i].text); +- l1 = strlen (conf_widgets [i].text) + 3; ++ l1 = mbstrlen (conf_widgets [i].text) + 3; + if (l1 > maxlen) + maxlen = l1; + } +@@ -423,8 +423,8 @@ confirm_box (void) + * And this for the case when buttons with some space to the right + * do not fit within 2/6 + */ +- l1 = strlen (conf_widgets [0].text) + 3; +- i = strlen (conf_widgets [1].text) + 5; ++ l1 = mbstrlen (conf_widgets [0].text) + 3; ++ i = mbstrlen (conf_widgets [1].text) + 5; + if (i > l1) + l1 = i; + +@@ -497,11 +497,11 @@ display_bits_box (void) + { + display_widgets [i].text = _(display_widgets[i].text); + display_bits_str [i] = _(display_bits_str [i]); +- l1 = strlen (display_bits_str [i]); ++ l1 = mbstrlen (display_bits_str [i]); + if (l1 > maxlen) + maxlen = l1; + } +- l1 = strlen (display_widgets [2].text); ++ l1 = mbstrlen (display_widgets [2].text); + if (l1 > maxlen) + maxlen = l1; + +@@ -509,8 +509,8 @@ display_bits_box (void) + display_bits.xlen = (maxlen + 5) * 6 / 4; + + /* See above confirm_box */ +- l1 = strlen (display_widgets [0].text) + 3; +- i = strlen (display_widgets [1].text) + 5; ++ l1 = mbstrlen (display_widgets [0].text) + 3; ++ i = mbstrlen (display_widgets [1].text) + 5; + if (i > l1) + l1 = i; + +@@ -605,7 +605,7 @@ init_disp_bits_box (void) + + cpname = _("&Select"); + add_widget (dbits_dlg, +- button_new (4, DISPX - 8 - strlen (cpname), B_USER, ++ button_new (4, DISPX - 8 - mbstrlen (cpname), B_USER, + NORMAL_BUTTON, cpname, sel_charset_button)); + + return dbits_dlg; +@@ -816,7 +816,7 @@ cd_dialog (void) + quick_widgets [1].y_divisions = + quick_widgets [0].y_divisions = Quick_input.ylen = 5; + +- len = strlen (quick_widgets [1].text); ++ len = mbstrlen (quick_widgets [1].text); + + quick_widgets [0].relative_x = + quick_widgets [1].relative_x + len + 1; +@@ -975,7 +975,7 @@ jobs_cmd (void) + { + job_buttons [i].name = _(job_buttons [i].name); + +- len = strlen (job_buttons [i].name) + 4; ++ len = mbstrlen (job_buttons [i].name) + 4; + JOBS_X = max (JOBS_X, startx + len + 3); + + job_buttons [i].xpos = startx; +@@ -984,7 +984,7 @@ jobs_cmd (void) + + /* Last button - Ok a.k.a. Cancel :) */ + job_buttons [n_buttons - 1].xpos = +- JOBS_X - strlen (job_buttons [n_buttons - 1].name) - 7; ++ JOBS_X - mbstrlen (job_buttons [n_buttons - 1].name) - 7; + + i18n_flag = 1; + } +@@ -1042,7 +1042,7 @@ vfs_smb_get_authinfo (const char *host, + + while (i--) + { +- l1 = strlen (labs [i] = _(labs [i])); ++ l1 = mbstrlen (labs [i] = _(labs [i])); + if (l1 > maxlen) + maxlen = l1; + } +@@ -1052,7 +1052,7 @@ vfs_smb_get_authinfo (const char *host, + + for (i = sizeof(buts)/sizeof(buts[0]), l1 = 0; i--; ) + { +- l1 += strlen (buts [i] = _(buts [i])); ++ l1 += mbstrlen (buts [i] = _(buts [i])); + } + l1 += 15; + if (l1 > dialog_x) +@@ -1061,7 +1061,7 @@ vfs_smb_get_authinfo (const char *host, + ilen = dialog_x - 7 - maxlen; /* for the case of very long buttons :) */ + istart = dialog_x - 3 - ilen; + +- b2 = dialog_x - (strlen(buts[1]) + 6); ++ b2 = dialog_x - (mbstrlen(buts[1]) + 6); + + i18n_flag = 1; + } +diff -up mc-4.6.2-pre1/src/dialog.c.utf8 mc-4.6.2-pre1/src/dialog.c +--- mc-4.6.2-pre1/src/dialog.c.utf8 2005-09-05 05:20:27.000000000 +0200 ++++ mc-4.6.2-pre1/src/dialog.c 2008-10-23 14:00:12.000000000 +0200 +@@ -166,7 +166,7 @@ common_dialog_repaint (struct Dlg_head * + + if (h->title) { + attrset (DLG_HOT_NORMALC (h)); +- dlg_move (h, space, (h->cols - strlen (h->title)) / 2); ++ dlg_move (h, space, (h->cols - mbstrlen (h->title)) / 2); + addstr (h->title); + } + } +diff -up mc-4.6.2-pre1/src/file.c.utf8 mc-4.6.2-pre1/src/file.c +--- mc-4.6.2-pre1/src/file.c.utf8 2007-02-22 15:29:11.000000000 +0100 ++++ mc-4.6.2-pre1/src/file.c 2008-10-23 14:00:12.000000000 +0200 +@@ -161,15 +161,20 @@ static const char * + do_transform_source (FileOpContext *ctx, const char *source) + { + size_t j, k, l, len; +- const char *fnsource = x_basename (source); ++ char *fnsource = g_strdup (x_basename (source)); + int next_reg; + enum CaseConvs case_conv = NO_CONV; + static char fntarget[MC_MAXPATHLEN]; + ++#ifdef UTF8 ++ fix_utf8(fnsource); ++#endif ++ + len = strlen (fnsource); + j = re_match (&ctx->rx, fnsource, len, 0, &ctx->regs); + if (j != len) { + transform_error = FILE_SKIP; ++ g_free (fnsource); + return NULL; + } + for (next_reg = 1, j = 0, k = 0; j < strlen (ctx->dest_mask); j++) { +@@ -213,6 +218,7 @@ do_transform_source (FileOpContext *ctx, + || ctx->regs.start[next_reg] < 0) { + message (1, MSG_ERROR, _(" Invalid target mask ")); + transform_error = FILE_ABORT; ++ g_free(fnsource); + return NULL; + } + for (l = (size_t) ctx->regs.start[next_reg]; +@@ -227,6 +233,7 @@ do_transform_source (FileOpContext *ctx, + } + } + fntarget[k] = 0; ++ g_free(fnsource); + return fntarget; + } + +@@ -1688,13 +1695,13 @@ panel_operate_generate_prompt (const WPa + *dp = '\0'; + + if (single_source) { +- i = fmd_xlen - strlen (format_string) - 4; ++ i = fmd_xlen - mbstrlen (format_string) - 4; + g_snprintf (cmd_buf, sizeof (cmd_buf), format_string, + name_trunc (single_source, i)); + } else { + g_snprintf (cmd_buf, sizeof (cmd_buf), format_string, + panel->marked); +- i = strlen (cmd_buf) + 6 - fmd_xlen; ++ i = mbstrlen (cmd_buf) + 6 - fmd_xlen; + if (i > 0) { + fmd_xlen += i; + fmd_init_i18n (TRUE); /* to recalculate positions of child widgets */ +diff -up mc-4.6.2-pre1/src/filegui.c.utf8 mc-4.6.2-pre1/src/filegui.c +--- mc-4.6.2-pre1/src/filegui.c.utf8 2007-08-23 15:16:39.000000000 +0200 ++++ mc-4.6.2-pre1/src/filegui.c 2008-10-23 14:00:12.000000000 +0200 +@@ -65,6 +65,7 @@ + #include "filegui.h" + #include "key.h" /* get_event */ + #include "util.h" /* strip_password() */ ++#include "tty.h" + + /* }}} */ + +@@ -563,8 +564,8 @@ init_replace (FileOpContext *ctx, enum O + * longest of "Overwrite..." labels + * (assume "Target date..." are short enough) + */ +- l1 = max (strlen (rd_widgets[6].text), +- strlen (rd_widgets[11].text)); ++ l1 = max (mbstrlen (rd_widgets[6].text), ++ mbstrlen (rd_widgets[11].text)); + + /* longest of button rows */ + i = sizeof (rd_widgets) / sizeof (rd_widgets[0]); +@@ -575,7 +576,7 @@ init_replace (FileOpContext *ctx, enum O + l2 = max (l2, l); + l = 0; + } +- l += strlen (rd_widgets[i].text) + 4; ++ l += mbstrlen (rd_widgets[i].text) + 4; + } + } + l2 = max (l2, l); /* last row */ +@@ -593,12 +594,12 @@ init_replace (FileOpContext *ctx, enum O + l = l1; + } + rd_widgets[i].xpos = l; +- l += strlen (rd_widgets[i].text) + 4; ++ l += mbstrlen (rd_widgets[i].text) + 4; + } + } + /* Abort button is centered */ + rd_widgets[1].xpos = +- (rd_xlen - strlen (rd_widgets[1].text) - 3) / 2; ++ (rd_xlen - mbstrlen (rd_widgets[1].text) - 3) / 2; + } + #endif /* ENABLE_NLS */ + +@@ -617,7 +618,7 @@ init_replace (FileOpContext *ctx, enum O + + ADD_RD_LABEL (ui, 0, + name_trunc (ui->replace_filename, +- rd_trunc - strlen (rd_widgets[0].text)), 0); ++ rd_trunc - mbstrlen (rd_widgets[0].text)), 0); + ADD_RD_BUTTON (1); + + ADD_RD_BUTTON (2); +@@ -804,36 +805,36 @@ fmd_init_i18n (int force) + if (fmd_widgets[i].text[0] != '\0') + fmd_widgets[i].text = _(fmd_widgets[i].text); + +- len = strlen (fmd_widgets[FMCB11].text) +- + strlen (fmd_widgets[FMCB21].text) + 15; ++ len = mbstrlen (fmd_widgets[FMCB11].text) ++ + mbstrlen (fmd_widgets[FMCB21].text) + 15; + fmd_xlen = max (fmd_xlen, len); + +- len = strlen (fmd_widgets[FMCB12].text) +- + strlen (fmd_widgets[FMCB22].text) + 15; ++ len = mbstrlen (fmd_widgets[FMCB12].text) ++ + mbstrlen (fmd_widgets[FMCB22].text) + 15; + fmd_xlen = max (fmd_xlen, len); + +- len = strlen (fmd_widgets[FMBRGT].text) +- + strlen (fmd_widgets[FMBLFT].text) + 11; ++ len = mbstrlen (fmd_widgets[FMBRGT].text) ++ + mbstrlen (fmd_widgets[FMBLFT].text) + 11; + + #ifdef FMBMID +- len += strlen (fmd_widgets[FMBMID].text) + 6; ++ len += mbstrlen (fmd_widgets[FMBMID].text) + 6; + #endif + + fmd_xlen = max (fmd_xlen, len + 4); + + len = (fmd_xlen - (len + 6)) / 2; + i = fmd_widgets[FMBLFT].relative_x = len + 3; +- i += strlen (fmd_widgets[FMBLFT].text) + 8; ++ i += mbstrlen (fmd_widgets[FMBLFT].text) + 8; + + #ifdef FMBMID + fmd_widgets[FMBMID].relative_x = i; +- i += strlen (fmd_widgets[FMBMID].text) + 6; ++ i += mbstrlen (fmd_widgets[FMBMID].text) + 6; + #endif + + fmd_widgets[FMBRGT].relative_x = i; + + #define chkbox_xpos(i) \ +- fmd_widgets [i].relative_x = fmd_xlen - strlen (fmd_widgets [i].text) - 6 ++ fmd_widgets [i].relative_x = fmd_xlen - mbstrlen (fmd_widgets [i].text) - 6 + + chkbox_xpos (FMCB0); + chkbox_xpos (FMCB21); +@@ -855,7 +856,7 @@ fmd_init_i18n (int force) + + char * + file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text, +- const char *def_text, int only_one, int *do_background) ++ const char *def_text_orig, int only_one, int *do_background) + { + int source_easy_patterns = easy_patterns; + char *source_mask, *orig_mask, *dest_dir, *tmpdest; +@@ -864,12 +865,20 @@ file_mask_dialog (FileOpContext *ctx, Fi + struct stat buf; + int val; + QuickDialog Quick_input; +- ++ char *def_text; + g_return_val_if_fail (ctx != NULL, NULL); ++ ++ def_text = g_strdup(def_text_orig); ++ + #if 0 + message (1, __FUNCTION__, "text = `%s' \n def_text = `%s'", text, + def_text); + #endif ++ ++#ifdef UTF8 ++ fix_utf8(def_text); ++#endif ++ + fmd_init_i18n (FALSE); + + /* Set up the result pointers */ +@@ -928,6 +937,7 @@ file_mask_dialog (FileOpContext *ctx, Fi + orig_mask = source_mask; + if (!dest_dir || !*dest_dir) { + g_free (source_mask); ++ g_free(def_text); + return dest_dir; + } + if (source_easy_patterns) { +@@ -981,5 +991,6 @@ file_mask_dialog (FileOpContext *ctx, Fi + } + if (val == B_USER) + *do_background = 1; ++ g_free(def_text); + return dest_dir; + } +diff -up mc-4.6.2-pre1/src/find.c.utf8 mc-4.6.2-pre1/src/find.c +--- mc-4.6.2-pre1/src/find.c.utf8 2006-02-04 12:03:35.000000000 +0100 ++++ mc-4.6.2-pre1/src/find.c 2008-10-23 14:00:12.000000000 +0200 +@@ -217,7 +217,7 @@ find_parameters (char **start_dir, char + int l1, maxlen = 0; + + while (i--) { +- l1 = strlen (labs[i] = _(labs[i])); ++ l1 = mbstrlen (labs[i] = _(labs[i])); + if (l1 > maxlen) + maxlen = l1; + } +@@ -226,7 +226,7 @@ find_parameters (char **start_dir, char + FIND_X = i; + + for (i = sizeof (buts) / sizeof (buts[0]), l1 = 0; i--;) { +- l1 += strlen (buts[i] = _(buts[i])); ++ l1 += mbstrlen (buts[i] = _(buts[i])); + } + l1 += 21; + if (l1 > FIND_X) +@@ -235,8 +235,8 @@ find_parameters (char **start_dir, char + ilen = FIND_X - 7 - maxlen; /* for the case of very long buttons :) */ + istart = FIND_X - 3 - ilen; + +- b1 = b0 + strlen (buts[0]) + 7; +- b2 = FIND_X - (strlen (buts[2]) + 6); ++ b1 = b0 + mbstrlen (buts[0]) + 7; ++ b2 = FIND_X - (mbstrlen (buts[2]) + 6); + + i18n_flag = 1; + case_label = _(case_label); +@@ -863,7 +863,7 @@ setup_gui (void) + if (!i18n_flag) { + register int i = sizeof (fbuts) / sizeof (fbuts[0]); + while (i--) +- fbuts[i].len = strlen (fbuts[i].text = _(fbuts[i].text)) + 3; ++ fbuts[i].len = mbstrlen (fbuts[i].text = _(fbuts[i].text)) + 3; + fbuts[2].len += 2; /* DEFPUSH_BUTTON */ + i18n_flag = 1; + } +@@ -1028,7 +1028,7 @@ find_file (char *start_dir, char *patter + + if (!next_free) /* first turn i.e clean old list */ + panel_clean_dir (current_panel); +- list->list[next_free].fnamelen = strlen (name); ++ list->list[next_free].fnamelen = mbstrlen (name); + list->list[next_free].fname = name; + list->list[next_free].f.marked = 0; + list->list[next_free].f.link_to_dir = link_to_dir; +diff -up mc-4.6.2-pre1/src/help.c.utf8 mc-4.6.2-pre1/src/help.c +--- mc-4.6.2-pre1/src/help.c.utf8 2007-01-20 12:40:45.000000000 +0100 ++++ mc-4.6.2-pre1/src/help.c 2008-10-23 14:00:12.000000000 +0200 +@@ -447,10 +447,28 @@ static void help_show (Dlg_head *h, cons + #ifndef HAVE_SLANG + addch (acs_map [c]); + #else ++#if defined(UTF8) && SLANG_VERSION < 20000 ++ SLsmg_draw_object (h->y + line + 2, h->x + col + 2, acs_map [c]); ++#else + SLsmg_draw_object (h->y + line + 2, h->x + col + 2, c); ++#endif /* UTF8 */ + #endif ++ } else { ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ int len; ++ mbstate_t mbs; ++ wchar_t wc; ++ memset (&mbs, 0, sizeof (mbs)); ++ len = mbrtowc(&wc, p, MB_CUR_MAX, &mbs); ++ if (len <= 0) len = 1; /* skip broken multibyte chars */ ++ ++ SLsmg_write_nwchars(&wc, 1); ++ p += len - 1; + } else ++#endif + addch (c); ++ } + col++; + break; + } +@@ -803,6 +821,12 @@ interactive_display (const char *filenam + message (1, MSG_ERROR, _(" Cannot open file %s \n %s "), filename ? filename : hlpfile, + unix_error_string (errno)); + } ++ else ++ { ++ char *conv = utf8_to_local(data); ++ g_free(data); ++ data = conv; ++ } + + if (!filename) + g_free (hlpfile); +diff -up mc-4.6.2-pre1/src/hotlist.c.utf8 mc-4.6.2-pre1/src/hotlist.c +--- mc-4.6.2-pre1/src/hotlist.c.utf8 2006-08-08 14:17:14.000000000 +0200 ++++ mc-4.6.2-pre1/src/hotlist.c 2008-10-23 14:00:12.000000000 +0200 +@@ -563,7 +563,7 @@ init_i18n_stuff(int list_type, int cols) + + row = hotlist_but [i].y; + ++count [row]; +- len [row] += strlen (hotlist_but [i].text) + 5; ++ len [row] += mbstrlen (hotlist_but [i].text) + 5; + if (hotlist_but [i].flags == DEFPUSH_BUTTON) + len [row] += 2; + } +@@ -588,12 +588,12 @@ init_i18n_stuff(int list_type, int cols) + /* not first int the row */ + if (!strcmp (hotlist_but [i].text, cancel_but)) + hotlist_but [i].x = +- cols - strlen (hotlist_but [i].text) - 13; ++ cols - mbstrlen (hotlist_but [i].text) - 13; + else + hotlist_but [i].x = cur_x [row]; + } + +- cur_x [row] += strlen (hotlist_but [i].text) + 2 ++ cur_x [row] += mbstrlen (hotlist_but [i].text) + 2 + + (hotlist_but [i].flags == DEFPUSH_BUTTON ? 5 : 3); + } + } +@@ -834,7 +834,7 @@ static void add_widgets_i18n(QuickWidget + for (i = 0; i < 3; i++) + { + qw [i].text = _(qw [i].text); +- l[i] = strlen (qw [i].text) + 3; ++ l[i] = mbstrlen (qw [i].text) + 3; + } + space = (len - 4 - l[0] - l[1] - l[2]) / 4; + +@@ -883,7 +883,7 @@ add_new_entry_input (const char *header, + + msglen(text1, &lines1, &cols1); + msglen(text2, &lines2, &cols2); +- len = max ((int) strlen (header), cols1); ++ len = max ((int) mbstrlen (header), cols1); + len = max (len, cols2) + 4; + len = max (len, 64); + +@@ -979,7 +979,7 @@ add_new_group_input (const char *header, + #endif /* ENABLE_NLS */ + + msglen (label, &lines, &cols); +- len = max ((int) strlen (header), cols) + 4; ++ len = max ((int) mbstrlen (header), cols) + 4; + len = max (len, 64); + + #ifdef ENABLE_NLS +@@ -1035,7 +1035,7 @@ void add2hotlist_cmd (void) + { + char *prompt, *label; + const char *cp = _("Label for \"%s\":"); +- int l = strlen (cp); ++ int l = mbstrlen (cp); + char *label_string = g_strdup (current_panel->cwd); + + strip_password (label_string, 1); +diff -up mc-4.6.2-pre1/src/layout.c.utf8 mc-4.6.2-pre1/src/layout.c +--- mc-4.6.2-pre1/src/layout.c.utf8 2006-11-08 14:37:25.000000000 +0100 ++++ mc-4.6.2-pre1/src/layout.c 2008-10-23 14:00:12.000000000 +0200 +@@ -366,36 +366,36 @@ init_layout (void) + + while (i--) { + s_split_direction[i] = _(s_split_direction[i]); +- l1 = strlen (s_split_direction[i]) + 7; ++ l1 = mbstrlen (s_split_direction[i]) + 7; + if (l1 > first_width) + first_width = l1; + } + + for (i = 0; i <= 8; i++) { + check_options[i].text = _(check_options[i].text); +- l1 = strlen (check_options[i].text) + 7; ++ l1 = mbstrlen (check_options[i].text) + 7; + if (l1 > first_width) + first_width = l1; + } + +- l1 = strlen (title1) + 1; ++ l1 = mbstrlen (title1) + 1; + if (l1 > first_width) + first_width = l1; + +- l1 = strlen (title2) + 1; ++ l1 = mbstrlen (title2) + 1; + if (l1 > first_width) + first_width = l1; + + +- second_width = strlen (title3) + 1; ++ second_width = mbstrlen (title3) + 1; + for (i = 0; i < 6; i++) { + check_options[i].text = _(check_options[i].text); +- l1 = strlen (check_options[i].text) + 7; ++ l1 = mbstrlen (check_options[i].text) + 7; + if (l1 > second_width) + second_width = l1; + } + if (console_flag) { +- l1 = strlen (output_lines_label) + 13; ++ l1 = mbstrlen (output_lines_label) + 13; + if (l1 > second_width) + second_width = l1; + } +@@ -409,14 +409,14 @@ init_layout (void) + * + * Now the last thing to do - properly space buttons... + */ +- l1 = 11 + strlen (ok_button) /* 14 - all brackets and inner space */ +- +strlen (save_button) /* notice: it is 3 char less because */ +- +strlen (cancel_button); /* of '&' char in button text */ ++ l1 = 11 + mbstrlen (ok_button) /* 14 - all brackets and inner space */ ++ +mbstrlen (save_button) /* notice: it is 3 char less because */ ++ +mbstrlen (cancel_button); /* of '&' char in button text */ + + i = (first_width + second_width - l1) / 4; + b1 = 5 + i; +- b2 = b1 + strlen (ok_button) + i + 6; +- b3 = b2 + strlen (save_button) + i + 4; ++ b2 = b1 + mbstrlen (ok_button) + i + 6; ++ b3 = b2 + mbstrlen (save_button) + i + 4; + + i18n_layt_flag = 1; + } +@@ -684,7 +684,7 @@ setup_panels (void) + panel_do_cols (0); + panel_do_cols (1); + +- promptl = strlen (prompt); ++ promptl = mbstrlen (prompt); + + widget_set_size (&the_menubar->widget, 0, 0, 1, COLS); + +diff -up mc-4.6.2-pre1/src/learn.c.utf8 mc-4.6.2-pre1/src/learn.c +--- mc-4.6.2-pre1/src/learn.c.utf8 2005-05-27 05:35:15.000000000 +0200 ++++ mc-4.6.2-pre1/src/learn.c 2008-10-23 14:00:12.000000000 +0200 +@@ -237,7 +237,7 @@ init_learn (void) + learn_but[0].x = 78 / 2 + 4; + + learn_but[1].text = _(learn_but[1].text); +- learn_but[1].x = 78 / 2 - (strlen (learn_but[1].text) + 9); ++ learn_but[1].x = 78 / 2 - (mbstrlen (learn_but[1].text) + 9); + + learn_title = _(learn_title); + i18n_flag = 1; +diff -up mc-4.6.2-pre1/src/main.c.utf8 mc-4.6.2-pre1/src/main.c +--- mc-4.6.2-pre1/src/main.c.utf8 2006-09-22 17:14:58.000000000 +0200 ++++ mc-4.6.2-pre1/src/main.c 2008-10-23 14:00:12.000000000 +0200 +@@ -704,7 +704,7 @@ load_prompt (int fd, void *unused) + int prompt_len; + + tmp_prompt = strip_ctrl_codes (subshell_prompt); +- prompt_len = strlen (tmp_prompt); ++ prompt_len = mbstrlen (tmp_prompt); + + /* Check for prompts too big */ + if (COLS > 8 && prompt_len > COLS - 8) { +@@ -1610,7 +1610,11 @@ update_xterm_title_path (void) + if (xterm_flag && xterm_title) { + p = s = g_strdup (strip_home_and_password (current_panel->cwd)); + do { ++#ifndef UTF8 + if (!is_printable ((unsigned char) *s)) ++#else /* UTF8 */ ++ if (*(unsigned char *)s < ' ') ++#endif /* UTF8 */ + *s = '?'; + } while (*++s); + fprintf (stdout, "\33]0;mc - %s\7", p); +diff -up mc-4.6.2-pre1/src/menu.c.utf8 mc-4.6.2-pre1/src/menu.c +--- mc-4.6.2-pre1/src/menu.c.utf8 2005-09-05 04:12:09.000000000 +0200 ++++ mc-4.6.2-pre1/src/menu.c 2008-10-23 14:00:12.000000000 +0200 +@@ -22,6 +22,7 @@ + #include + + #include ++#include + + #include "global.h" + #include "tty.h" +@@ -53,35 +54,95 @@ create_menu (const char *name, menu_entr + { + Menu *menu; + const char *cp; ++ int wlen = 0; ++ mbstate_t s; + + menu = (Menu *) g_malloc (sizeof (*menu)); + menu->count = count; + menu->max_entry_len = 20; + menu->entries = entries; ++ menu->name = g_strdup (name); ++ menu_scan_hotkey (menu); ++#ifdef UTF8 ++ menu->wentries = NULL; ++ menu->wname = NULL; ++ if (SLsmg_Is_Unicode) { ++ const char *str = menu->name; ++ memset (&s, 0, sizeof (s)); ++ wlen = mbsrtowcs (NULL, &str, -1, &s); ++ if (wlen > 0) ++ ++wlen; ++ else { ++ wlen = 0; ++ memset (&s, 0, sizeof (s)); ++ } ++ } ++#endif + + if (entries != (menu_entry*) NULL) { + register menu_entry* mp; + for (mp = entries; count--; mp++) { + if (mp->text[0] != '\0') { ++ int len; + #ifdef ENABLE_NLS + mp->text = _(mp->text); + #endif /* ENABLE_NLS */ + cp = strchr (mp->text,'&'); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ len = mbstrlen(mp->text) + 1; ++ wlen += len; ++ menu->max_entry_len = max (len - 1, menu->max_entry_len); ++ } else ++#endif ++ len = strlen (mp->text); + + if (cp != NULL && *(cp+1) != '\0') { + mp->hot_key = tolower ((unsigned char) *(cp+1)); +- menu->max_entry_len = max ((int) (strlen (mp->text) - 1), +- menu->max_entry_len); ++ menu->max_entry_len = max (len - 1, menu->max_entry_len); + } else { +- menu->max_entry_len = max ((int) strlen (mp->text), +- menu->max_entry_len); ++ menu->max_entry_len = max (len, menu->max_entry_len); + } + } + } + } + +- menu->name = g_strdup (name); +- menu_scan_hotkey(menu); ++#ifdef UTF8 ++ if (wlen) { ++ wchar_t *wp; ++ const char *str; ++ int len; ++ ++ menu->wentries = (wchar_t **) ++ g_malloc (sizeof (wchar_t *) * menu->count ++ + wlen * sizeof (wchar_t)); ++ wp = (wchar_t *) (menu->wentries + menu->count); ++ str = menu->name; ++ len = mbsrtowcs (wp, &str, wlen, &s); ++ if (len > 0) { ++ menu->wname = wp; ++ wlen -= len + 1; ++ wp += len + 1; ++ } else ++ memset (&s, 0, sizeof (s)); ++ if (menu->entries != NULL) ++ for (count = 0; count < menu->count; ++count) ++ if (menu->entries[count].text[0] != '\0') { ++ str = menu->entries[count].text; ++ menu->wentries[count] = wp; ++ len = mbsrtowcs (wp, &str, wlen, &s); ++ if (len > 0) { ++ wlen -= len + 1; ++ wp += len + 1; ++ } else { ++ memset (&s, 0, sizeof (s)); ++ *wp++ = L'\0'; ++ --wlen; ++ } ++ } ++ } ++#endif ++ + menu->start_x = 0; + menu->help_node = g_strdup (help_node); + return menu; +@@ -112,8 +173,26 @@ static void menubar_paint_idx (WMenu *me + const char *text; + + addch((unsigned char)menu->entries [idx].first_letter); +- for (text = menu->entries [idx].text; *text; text++) +- { ++#ifdef UTF8 ++ if (menu->wentries) { ++ wchar_t *wtext, *wp; ++ ++ for (wtext = wp = menu->wentries [idx]; *wtext; wtext++) { ++ if (*wtext == L'&') { ++ if (wtext > wp) ++ SLsmg_write_nwchars (wp, wtext - wp); ++ attrset (color == MENU_SELECTED_COLOR ? ++ MENU_HOTSEL_COLOR : MENU_HOT_COLOR); ++ SLsmg_write_nwchars (++wtext, 1); ++ attrset (color); ++ wp = wtext + 1; ++ } ++ } ++ if (wtext > wp) ++ SLsmg_write_nwchars (wp, wtext - wp); ++ } else ++#endif ++ for (text = menu->entries [idx].text; *text; text++) { + if (*text != '&') + addch(*text); + else { +@@ -122,7 +201,7 @@ static void menubar_paint_idx (WMenu *me + addch(*(++text)); + attrset(color); + } +- } ++ } + } + widget_move (&menubar->widget, y, x + 1); + } +@@ -168,6 +247,12 @@ static void menubar_draw (WMenu *menubar + if (menubar->active) + attrset(i == menubar->selected?MENU_SELECTED_COLOR:SELECTED_COLOR); + widget_move (&menubar->widget, 0, menubar->menu [i]->start_x); ++#ifdef UTF8 ++ if (menubar->menu [i]->wname) ++ SLsmg_write_nwchars (menubar->menu [i]->wname, ++ wcslen (menubar->menu [i]->wname)); ++ else ++#endif + tty_printf ("%s", menubar->menu [i]->name); + } + +@@ -493,7 +578,13 @@ menubar_arrange(WMenu* menubar) + + for (i = 0; i < items; i++) + { +- int len = strlen(menubar->menu[i]->name); ++ int len; ++#ifdef UTF8 ++ if (menubar->menu[i]->wname) ++ len = wcslen (menubar->menu[i]->wname); ++ else ++#endif ++ len = strlen(menubar->menu[i]->name); + menubar->menu[i]->start_x = start_x; + start_x += len + gap; + } +@@ -506,7 +597,13 @@ menubar_arrange(WMenu* menubar) + for (i = 0; i < items; i++) + { + /* preserve length here, to be used below */ +- gap -= (menubar->menu[i]->start_x = strlen(menubar->menu[i]->name)); ++#ifdef UTF8 ++ if (menubar->menu[i]->wname) ++ menubar->menu[i]->start_x = wcslen (menubar->menu[i]->wname); ++ else ++#endif ++ menubar->menu[i]->start_x = strlen (menubar->menu[i]->name); ++ gap -= menubar->menu[i]->start_x; + } + + gap /= (items - 1); +@@ -530,6 +627,9 @@ menubar_arrange(WMenu* menubar) + void + destroy_menu (Menu *menu) + { ++#ifdef UTF8 ++ g_free (menu->wentries); ++#endif + g_free (menu->name); + g_free (menu->help_node); + g_free (menu); +diff -up mc-4.6.2-pre1/src/menu.h.utf8 mc-4.6.2-pre1/src/menu.h +--- mc-4.6.2-pre1/src/menu.h.utf8 2004-12-03 20:17:47.000000000 +0100 ++++ mc-4.6.2-pre1/src/menu.h 2008-10-23 14:00:12.000000000 +0200 +@@ -21,6 +21,8 @@ typedef struct Menu { + menu_entry *entries; + int start_x; /* position relative to menubar start */ + char *help_node; ++ wchar_t **wentries; ++ wchar_t *wname; + } Menu; + + extern int menubar_visible; +diff -up mc-4.6.2-pre1/src/myslang.h.utf8 mc-4.6.2-pre1/src/myslang.h +--- mc-4.6.2-pre1/src/myslang.h.utf8 2005-09-05 05:22:04.000000000 +0200 ++++ mc-4.6.2-pre1/src/myslang.h 2008-10-23 14:00:12.000000000 +0200 +@@ -11,6 +11,16 @@ + #endif /* HAVE_SLANG_SLANG_H */ + #endif + ++#if SLANG_VERSION >= 20000 ++#define UTF8 1 ++#define SLsmg_Is_Unicode SLsmg_is_utf8_mode() ++void SLsmg_write_nwchars(wchar_t *s, size_t n); ++#endif ++ ++#ifdef UTF8 ++# include ++#endif ++ + enum { + KEY_BACKSPACE = 400, + KEY_END, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, +diff -up mc-4.6.2-pre1/src/option.c.utf8 mc-4.6.2-pre1/src/option.c +--- mc-4.6.2-pre1/src/option.c.utf8 2006-02-28 17:15:21.000000000 +0100 ++++ mc-4.6.2-pre1/src/option.c 2008-10-23 14:00:12.000000000 +0200 +@@ -123,12 +123,12 @@ init_configure (void) + title2 = _(" Pause after run... "); + title3 = _(" Other options "); + +- first_width = strlen (title1) + 1; +- second_width = strlen (title3) + 1; ++ first_width = mbstrlen (title1) + 1; ++ second_width = mbstrlen (title3) + 1; + + for (i = 0; check_options[i].text; i++) { + check_options[i].text = _(check_options[i].text); +- l1 = strlen (check_options[i].text) + 7; ++ l1 = mbstrlen (check_options[i].text) + 7; + if (i >= OTHER_OPTIONS) { + if (l1 > first_width) + first_width = l1; +@@ -141,23 +141,23 @@ init_configure (void) + i = PAUSE_OPTIONS; + while (i--) { + pause_options[i] = _(pause_options[i]); +- l1 = strlen (pause_options[i]) + 7; ++ l1 = mbstrlen (pause_options[i]) + 7; + if (l1 > first_width) + first_width = l1; + } + +- l1 = strlen (title2) + 1; ++ l1 = mbstrlen (title2) + 1; + if (l1 > first_width) + first_width = l1; + +- l1 = 11 + strlen (ok_button) +- + strlen (save_button) +- + strlen (cancel_button); ++ l1 = 11 + mbstrlen (ok_button) ++ + mbstrlen (save_button) ++ + mbstrlen (cancel_button); + + i = (first_width + second_width - l1) / 4; + b1 = 5 + i; +- b2 = b1 + strlen (ok_button) + i + 6; +- b3 = b2 + strlen (save_button) + i + 4; ++ b2 = b1 + mbstrlen (ok_button) + i + 6; ++ b3 = b2 + mbstrlen (save_button) + i + 4; + + i18n_config_flag = 1; + } +diff -up mc-4.6.2-pre1/src/panelize.c.utf8 mc-4.6.2-pre1/src/panelize.c +--- mc-4.6.2-pre1/src/panelize.c.utf8 2005-05-27 05:35:15.000000000 +0200 ++++ mc-4.6.2-pre1/src/panelize.c 2008-10-23 14:00:12.000000000 +0200 +@@ -127,7 +127,7 @@ init_panelize (void) + i = sizeof (panelize_but) / sizeof (panelize_but[0]); + while (i--) { + panelize_but[i].text = _(panelize_but[i].text); +- maxlen += strlen (panelize_but[i].text) + 5; ++ maxlen += mbstrlen (panelize_but[i].text) + 5; + } + maxlen += 10; + +@@ -136,11 +136,11 @@ init_panelize (void) + panelize_cols = max (panelize_cols, maxlen); + + panelize_but[2].x = +- panelize_but[3].x + strlen (panelize_but[3].text) + 7; ++ panelize_but[3].x + mbstrlen (panelize_but[3].text) + 7; + panelize_but[1].x = +- panelize_but[2].x + strlen (panelize_but[2].text) + 5; ++ panelize_but[2].x + mbstrlen (panelize_but[2].text) + 5; + panelize_but[0].x = +- panelize_cols - strlen (panelize_but[0].text) - 8 - BX; ++ panelize_cols - mbstrlen (panelize_but[0].text) - 8 - BX; + + #endif /* ENABLE_NLS */ + +diff -up mc-4.6.2-pre1/src/screen.c.utf8 mc-4.6.2-pre1/src/screen.c +--- mc-4.6.2-pre1/src/screen.c.utf8 2007-08-24 14:22:29.000000000 +0200 ++++ mc-4.6.2-pre1/src/screen.c 2008-10-23 14:00:12.000000000 +0200 +@@ -171,21 +171,56 @@ add_permission_string (char *dest, int w + static const char * + string_file_name (file_entry *fe, int len) + { +- static char buffer [MC_MAXPATHLEN + 1]; + size_t i; + +- for (i = 0; i < sizeof(buffer) - 1; i++) { +- char c; ++#ifdef UTF8 ++ static char buffer [BUF_SMALL * 4]; ++ mbstate_t s; ++ int mbmax = MB_CUR_MAX; ++ const char *str = fe->fname; + +- c = fe->fname[i]; ++ memset (&s, 0, sizeof (s)); ++#else ++ static char buffer [BUF_SMALL]; ++#endif + +- if (!c) +- break; ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) ++ for (i = 0; i < sizeof (buffer) - 1; i++) { ++ wchar_t wc; ++ int len; + +- if (!is_printable(c)) +- c = '?'; ++ len = mbrtowc (&wc, str, mbmax, &s); ++ if (!len) ++ break; ++ if (len < 0) { ++ memset (&s, 0, sizeof (s)); ++ buffer[i] = '?'; ++ str++; ++ continue; ++ } ++ if (!is_printable (wc)) { ++ buffer[i] = '?'; ++ str++; ++ continue; ++ } ++ if (i >= sizeof (buffer) - len) ++ break; ++ memcpy (buffer + i, str, len); ++ i += len - 1; ++ str += len; ++ } else ++#endif ++ for (i = 0; i < sizeof(buffer) - 1; i++) { ++ char c; ++ ++ c = fe->fname[i]; + +- buffer[i] = c; ++ if (!c) break; ++ ++ if (!is_printable(c)) c = '?'; ++ ++ buffer[i] = c; + } + + buffer[i] = 0; +@@ -450,42 +485,6 @@ static struct { + { "dot", 1, 0, J_RIGHT, " ", 0, string_dot, NULL }, + }; + +-static char * +-to_buffer (char *dest, int just_mode, int len, const char *txt) +-{ +- int txtlen = strlen (txt); +- int still, over; +- +- /* Fill buffer with spaces */ +- memset (dest, ' ', len); +- +- still = (over=(txtlen > len)) ? (txtlen - len) : (len - txtlen); +- +- switch (HIDE_FIT(just_mode)){ +- case J_LEFT: +- still = 0; +- break; +- case J_CENTER: +- still /= 2; +- break; +- case J_RIGHT: +- default: +- break; +- } +- +- if (over){ +- if (IS_FIT(just_mode)) +- strcpy (dest, name_trunc(txt, len)); +- else +- strncpy (dest, txt+still, len); +- } else +- strncpy (dest+still, txt, txtlen); +- +- dest[len] = '\0'; +- +- return (dest + len); +-} +- + static int + file_compute_color (int attr, file_entry *fe) + { +@@ -539,14 +538,18 @@ file_compute_color (int attr, file_entry + + /* Formats the file number file_index of panel in the buffer dest */ + static void +-format_file (char *dest, int limit, WPanel *panel, int file_index, int width, int attr, int isstatus) ++format_file (WPanel *panel, int file_index, int width, int attr, int isstatus) + { + int color, length, empty_line; + const char *txt; +- char *old_pos; +- char *cdest = dest; + format_e *format, *home; + file_entry *fe; ++#ifdef UTF8 ++ char buffer[BUF_MEDIUM * sizeof (wchar_t)]; ++#else ++ char buffer[BUF_MEDIUM]; ++#endif ++ int txtwidth = 0; + + length = 0; + empty_line = (file_index >= panel->count); +@@ -564,34 +567,137 @@ format_file (char *dest, int limit, WPan + break; + + if (format->string_fn){ +- int len; ++ int len, still, over, perm, txtlen, wide; + + if (empty_line) + txt = " "; + else + txt = (*format->string_fn)(fe, format->field_len); + +- old_pos = cdest; +- + len = format->field_len; + if (len + length > width) + len = width - length; +- if (len + (cdest - dest) > limit) +- len = limit - (cdest - dest); ++ if (len >= BUF_MEDIUM) ++ len = BUF_MEDIUM - 1; + if (len <= 0) + break; +- cdest = to_buffer (cdest, format->just_mode, len, txt); +- length += len; + +- attrset (color); ++ perm = 0; ++ if (permission_mode) { ++ if (!strcmp(format->id, "perm")) ++ perm = 1; ++ else if (!strcmp(format->id, "mode")) ++ perm = 2; ++ } + +- if (permission_mode && !strcmp(format->id, "perm")) +- add_permission_string (old_pos, format->field_len, fe, attr, color, 0); +- else if (permission_mode && !strcmp(format->id, "mode")) +- add_permission_string (old_pos, format->field_len, fe, attr, color, 1); +- else +- addstr (old_pos); ++ wide = 0; ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode && !empty_line && !perm) { ++ mbstate_t s; ++ const char *str = txt; ++ ++ memset (&s, 0, sizeof (s)); ++ txtlen = mbsrtowcs ((wchar_t *) buffer, &str, ++ sizeof (buffer) / sizeof (wchar_t), &s); ++ if (txtlen < 0) { ++ txt = " "; ++ txtlen = 1; ++ } else { ++ wide = 1; ++ txtwidth = wcswidth((wchar_t*)buffer, txtlen); ++ } ++ } else ++#endif ++ { ++ txtlen = mbstrlen (txt); ++ txtwidth = txtlen; ++ } ++ ++ over = txtwidth > len; ++ still = over ? txtlen - len : len - txtlen; ++ ++ switch (HIDE_FIT(format->just_mode)) { ++ case J_LEFT: ++ still = 0; ++ break; ++ case J_CENTER: ++ still /= 2; ++ break; ++ case J_RIGHT: ++ default: ++ break; ++ } ++ ++ attrset (color); ++ ++ if (wide) { ++#ifdef UTF8 ++ if (over) { ++ if (IS_FIT (format->just_mode)) { ++ int n1 = 0; ++ int width1 = 0; ++ int n2 = 0; ++ int width2 = 0; ++ int len1 = len / 2; ++ int len2; ++ ++ while (1) { ++ int w = wcwidth(((wchar_t *) buffer)[n1]); ++ if (width1 + w <= len1) { ++ width1 += w; ++ n1++; ++ } ++ else ++ break; ++ } ++ len2 = len - width1 - 1; ++ ++ while (1) { ++ int w = wcwidth(((wchar_t *) buffer)[txtlen - n2 - 1]); ++ if (width2 + w <= len2) { ++ width2 += w; ++ n2++; ++ } ++ else ++ break; ++ } ++ ++ ++ SLsmg_write_nwchars ((wchar_t *) buffer, n1); ++ SLsmg_write_nwchars (L"~", 1); ++ printw ("%*s", len - width1 - width2 - 1, ""); ++ SLsmg_write_nwchars (((wchar_t *) buffer) ++ + txtlen - n2, n2); ++ } else ++ SLsmg_write_nwchars ((wchar_t *) buffer, len); ++ } else { ++ printw ("%*s", still, ""); ++ SLsmg_write_nwchars ((wchar_t *) buffer, txtlen); ++ printw ("%*s", len - txtwidth - still, ""); ++ } ++#endif ++ } else { ++ if (over) { ++ if (IS_FIT (format->just_mode)) ++ strcpy (buffer, name_trunc(txt, len)); ++ else ++ memcpy (buffer, txt + still, len); ++ } else { ++ memset (buffer, ' ', still); ++ memcpy (buffer + still, txt, txtlen); ++ memset (buffer + still + txtlen, ' ', ++ len - txtlen - still); ++ } ++ buffer[len] = '\0'; + ++ if (perm) ++ add_permission_string (buffer, format->field_len, fe, ++ attr, color, perm - 1); ++ else ++ addstr (buffer); ++ } ++ ++ length += len; + } else { + if (attr == SELECTED || attr == MARKED_SELECTED) + attrset (SELECTED_COLOR); +@@ -614,7 +720,6 @@ repaint_file (WPanel *panel, int file_in + { + int second_column = 0; + int width, offset; +- char buffer [BUF_MEDIUM]; + + offset = 0; + if (!isstatus && panel->split){ +@@ -643,7 +748,7 @@ repaint_file (WPanel *panel, int file_in + widget_move (&panel->widget, file_index - panel->top_file + 2, 1); + } + +- format_file (buffer, sizeof(buffer), panel, file_index, width, attr, isstatus); ++ format_file (panel, file_index, width, attr, isstatus); + + if (!isstatus && panel->split){ + if (second_column) +@@ -692,7 +797,7 @@ display_mini_info (WPanel *panel) + ngettext("%s in %d file", "%s in %d files", panel->marked), + b_bytes, panel->marked); + +- if ((int) strlen (buffer) > cols-2){ ++ if ((int) mbstrlen (buffer) > cols-2){ + buffer [cols] = 0; + p += 2; + } else +@@ -1104,6 +1209,12 @@ paint_frame (WPanel *panel) + int side, width; + + const char *txt; ++#ifdef UTF8 ++ char buffer[30 * sizeof (wchar_t)]; ++ mbstate_t s; ++ ++ memset (&s, 0, sizeof (s)); ++#endif + if (!panel->split) + adjust_top_file (panel); + +@@ -1128,16 +1239,38 @@ paint_frame (WPanel *panel) + if (format->string_fn){ + txt = format->title; + +- header_len = strlen (txt); ++ attrset (MARKED_COLOR); ++ width -= format->field_len; ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ const char *str = txt; ++ header_len = mbsrtowcs ((wchar_t *) buffer, &str, ++ sizeof (buffer) / sizeof (wchar_t), ++ &s); ++ if (header_len < 0) { ++ memset (&s, 0, sizeof (s)); ++ printw ("%*s", format->field_len, ""); ++ continue; ++ } ++ if (header_len > format->field_len) ++ header_len = format->field_len; ++ spaces = (format->field_len - header_len) / 2; ++ extra = (format->field_len - header_len) % 2; ++ printw ("%*s", spaces, ""); ++ SLsmg_write_nwchars ((wchar_t *) buffer, header_len); ++ printw ("%*s", spaces + extra, ""); ++ continue; ++ } ++#endif ++ ++ header_len = mbstrlen (txt); + if (header_len > format->field_len) + header_len = format->field_len; + +- attrset (MARKED_COLOR); + spaces = (format->field_len - header_len) / 2; + extra = (format->field_len - header_len) % 2; + tty_printf ("%*s%.*s%*s", spaces, "", + header_len, txt, spaces+extra, ""); +- width -= 2 * spaces + extra + header_len; + } else { + attrset (NORMAL_COLOR); + one_vline (); +@@ -1894,11 +2027,24 @@ do_search (WPanel *panel, int c_code) + int i; + int wrapped = 0; + int found; ++ int prevpos, pos; ++ int j; ++ mbstate_t mbs; + + l = strlen (panel->search_buffer); + if (c_code == KEY_BACKSPACE) { +- if (l) +- panel->search_buffer[--l] = '\0'; ++ if (l) { ++ prevpos = pos = 0; ++ memset (&mbs, 0, sizeof (mbs)); ++ while (pos < l) { ++ prevpos = pos; ++ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs); ++ if (j <= 0) break; ++ pos += j; ++ } ++ --l; ++ panel->search_buffer[prevpos] = 0; ++ } + } else { + if (c_code && l < sizeof (panel->search_buffer)) { + panel->search_buffer[l] = c_code; +@@ -1907,6 +2053,14 @@ do_search (WPanel *panel, int c_code) + } + } + ++ prevpos = pos = 0; ++ memset (&mbs, 0, sizeof (mbs)); ++ while (pos < l) { ++ prevpos = pos; ++ j = mbrlen (panel->search_buffer + pos, l - pos, &mbs); ++ if (j <= 0) break; ++ pos += j; ++ } + found = 0; + for (i = panel->selected; !wrapped || i != panel->selected; i++) { + if (i >= panel->count) { +@@ -1917,9 +2071,9 @@ do_search (WPanel *panel, int c_code) + } + if (panel-> + case_sensitive +- ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, l) ++ ? (strncmp (panel->dir.list[i].fname, panel->search_buffer, pos) + == 0) : (g_strncasecmp (panel->dir.list[i].fname, +- panel->search_buffer, l) == 0)) { ++ panel->search_buffer, pos) == 0)) { + unselect_item (panel); + panel->selected = i; + select_item (panel); +@@ -1928,7 +2082,7 @@ do_search (WPanel *panel, int c_code) + } + } + if (!found) +- panel->search_buffer[--l] = 0; ++ panel->search_buffer[prevpos] = 0; + + paint_panel (panel); + } +diff -up mc-4.6.2-pre1/src/slint.c.utf8 mc-4.6.2-pre1/src/slint.c +--- mc-4.6.2-pre1/src/slint.c.utf8 2005-09-05 04:14:29.000000000 +0200 ++++ mc-4.6.2-pre1/src/slint.c 2008-10-23 14:00:12.000000000 +0200 +@@ -141,7 +141,9 @@ void + slang_init (void) + { + SLtt_get_terminfo (); +- ++#if SLANG_VERSION >= 20000 ++ SLutf8_enable (-1); ++#endif + /* + * If the terminal in not in terminfo but begins with a well-known + * string such as "linux" or "xterm" S-Lang will go on, but the +diff -up mc-4.6.2-pre1/src/tty.c.utf8 mc-4.6.2-pre1/src/tty.c +--- mc-4.6.2-pre1/src/tty.c.utf8 2006-05-23 09:38:59.000000000 +0200 ++++ mc-4.6.2-pre1/src/tty.c 2008-10-23 14:00:12.000000000 +0200 +@@ -134,10 +134,12 @@ tty_print_char(int c) + * defined or not. Congratulations! At least, they left the API call + * for SLsmg_write_nchars as it has always been. + */ +- char ch; +- +- ch = c; +- SLsmg_write_nchars(&ch, 1); ++ ++ /* The above comment is a nonsense, SLsmg_write_char(c) works pretty ++ * good for me. So please don't mess with Red Hat people. ++ * Jindrich Novy (jnovy@redhat.com) ++ */ ++ SLsmg_write_char(c); + #else + addch(c); + #endif +diff -up mc-4.6.2-pre1/src/tty.h.utf8 mc-4.6.2-pre1/src/tty.h +--- mc-4.6.2-pre1/src/tty.h.utf8 2006-05-15 15:26:18.000000000 +0200 ++++ mc-4.6.2-pre1/src/tty.h 2008-10-23 14:00:12.000000000 +0200 +@@ -8,6 +8,8 @@ + of ifdefs in the other files small. + */ + ++#include /* gboolean is used here */ ++ + #ifdef HAVE_SLANG + # include "myslang.h" + #endif +diff -up mc-4.6.2-pre1/src/util.c.utf8 mc-4.6.2-pre1/src/util.c +--- mc-4.6.2-pre1/src/util.c.utf8 2005-11-03 03:18:38.000000000 +0100 ++++ mc-4.6.2-pre1/src/util.c 2008-10-23 14:00:12.000000000 +0200 +@@ -33,7 +33,11 @@ + #include + #include + #include ++#include ++#include ++#include + ++#include "tty.h" + #include "global.h" + #include "profile.h" + #include "main.h" /* mc_home */ +@@ -45,9 +49,39 @@ + #include "charsets.h" + #endif + ++#ifdef UTF8 ++#include ++#endif ++ + static const char app_text [] = "Midnight-Commander"; + int easy_patterns = 1; + ++#if SLANG_VERSION >= 20000 ++void SLsmg_write_nwchars(wchar_t *s, size_t n) ++{ ++ if (SLsmg_is_utf8_mode()) { /* slang can handle it directly */ ++ while(n-- && *s) ++ SLsmg_write_char(*s++); ++ } ++ else { /* convert wchars back to 8bit encoding */ ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++ while (n-- && *s) { ++ char buf[MB_LEN_MAX + 1]; /* should use 1 char, but to be sure */ ++ if (*s < 0x80) { ++ SLsmg_write_char(*s++); /* ASCII */ ++ } ++ else { ++ if (wcrtomb(buf, *s++, &mbs) == 1) ++ SLsmg_write_char((wchar_t)(buf[0])); ++ else ++ SLsmg_write_char('?'); /* should not happen */ ++ } ++ } ++ } ++} ++#endif ++ + extern void str_replace(char *s, char from, char to) + { + for (; *s != '\0'; s++) { +@@ -78,9 +112,106 @@ is_8bit_printable (unsigned char c) + return (c > 31 && c != 127 && c != 155); + } + ++size_t ++mbstrlen (const char *str) ++{ ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ size_t width = 0; ++ ++ for (; *str; str++) { ++ wchar_t c; ++ size_t len; ++ ++ len = mbrtowc (&c, str, MB_CUR_MAX, NULL); ++ ++ if (len == (size_t)(-1) || len == (size_t)(-2)) break; ++ ++ if (len > 0) { ++ int wcsize = wcwidth(c); ++ width += wcsize > 0 ? wcsize : 0; ++ str += len-1; ++ } ++ } ++ ++ return width; ++ } else ++#endif ++ return strlen (str); ++} ++ ++#ifdef UTF8 ++ ++void ++fix_utf8(char *str) ++{ ++ mbstate_t mbs; ++ ++ char *p = str; ++ ++ while (*p) { ++ int len; ++ memset (&mbs, 0, sizeof (mbs)); ++ len = mbrlen(p, MB_CUR_MAX, &mbs); ++ if (len == -1) { ++ *p = '?'; ++ p++; ++ } else if (len > 0) { ++ p += len; ++ } else { ++ p++; ++ } ++ } ++} ++#endif ++ ++ ++ ++#ifdef UTF8 ++wchar_t * ++mbstr_to_wchar (const char *str) ++{ ++ int len = mbstrlen(str); ++ wchar_t *buf = g_malloc((len+1) * sizeof(wchar_t)); ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++ mbsrtowcs (buf, &str, len, &mbs); ++ buf[len] = 0; ++ return buf; ++} ++ ++char * ++wchar_to_mbstr (const wchar_t *wstr) ++{ ++ mbstate_t mbs; ++ const wchar_t *wstr2; ++ char * string; ++ int len; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ wstr2 = wstr; ++ len = wcsrtombs(NULL, &wstr2, 0, &mbs); ++ if (len <= 0) ++ return NULL; ++ ++ string = g_malloc(len + 1); ++ ++ wstr2 = wstr; ++ wcsrtombs(string, &wstr2, len, &mbs); ++ string[len] = 0; ++ return string; ++} ++#endif ++ ++ ++ + int + is_printable (int c) + { ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) ++ return iswprint (c); ++#endif + c &= 0xff; + + #ifdef HAVE_CHARSET +@@ -98,7 +229,7 @@ is_printable (int c) + #endif /* !HAVE_CHARSET */ + } + +-/* Calculates the message dimensions (lines and columns) */ ++/* Calculates the message dimension in columns and lines. */ + void + msglen (const char *text, int *lines, int *columns) + { +@@ -111,8 +242,21 @@ msglen (const char *text, int *lines, in + nlines++; + colindex = 0; + } else { ++#ifndef UTF8 + colindex++; + if (colindex > ncolumns) ++#else /* UTF8 */ ++ size_t len; ++ wchar_t c; ++ ++ len = mbrtowc (&c, text, MB_CUR_MAX, NULL); ++ if (len > 0 && len != (size_t)(-1) && len != (size_t)(-2)) { ++ int wcsize = wcwidth(c); ++ colindex += wcsize > 0 ? wcsize-1 : -1; ++ text += len-1; ++ } ++ if (++colindex > ncolumns) ++#endif /* UTF8 */ + ncolumns = colindex; + } + } +@@ -206,7 +350,24 @@ name_quote (const char *s, int quote_per + *d++ = '\\'; + break; + } ++#ifndef UTF8 + *d = *s; ++#else /* UTF8 */ ++ { ++ mbstate_t mbs; ++ int len; ++ memset (&mbs, 0, sizeof (mbs)); ++ len = mbrlen(s, MB_CUR_MAX, &mbs); ++ if (len > 0) { ++ while (len-- > 1) ++ *d++ = *s++; ++ *d = *s; ++ } else { ++ *d = '?'; ++ } ++ ++ } ++#endif /* UTF8 */ + } + *d = '\0'; + return ret; +@@ -228,25 +389,90 @@ const char * + name_trunc (const char *txt, int trunc_len) + { + static char x[MC_MAXPATHLEN + MC_MAXPATHLEN]; +- int txt_len; ++ int txt_len, first, skip; + char *p; ++ const char *str; + + if ((size_t) trunc_len > sizeof (x) - 1) { + trunc_len = sizeof (x) - 1; + } +- txt_len = strlen (txt); +- if (txt_len <= trunc_len) { +- strcpy (x, txt); +- } else { +- int y = (trunc_len / 2) + (trunc_len % 2); +- strncpy (x, txt, y); +- strncpy (x + y, txt + txt_len - (trunc_len / 2), trunc_len / 2); +- x[y] = '~'; +- } +- x[trunc_len] = 0; +- for (p = x; *p; p++) +- if (!is_printable (*p)) +- *p = '?'; ++ txt_len = mbstrlen (txt); ++ first = 0; ++ skip = 0; ++ if (txt_len > trunc_len) { ++ first = trunc_len / 2; ++ skip = txt_len - trunc_len + 1; ++ } ++ ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ mbstate_t s; ++ int mbmax; ++ ++ str = txt; ++ memset (&s, 0, sizeof (s)); ++ mbmax = MB_CUR_MAX; ++ p = x; ++ while (p < x + sizeof (x) - 1 && trunc_len) { ++ wchar_t wc; ++ int len; ++ ++ len = mbrtowc (&wc, str, mbmax, &s); ++ if (!len) ++ break; ++ if (len < 0) { ++ memset (&s, 0, sizeof (s)); ++ *p = '?'; ++ len = 1; ++ str++; ++ } else if (!is_printable (wc)) { ++ *p = '?'; ++ str += len; ++ len = 1; ++ } else if (p >= x + sizeof (x) - len) ++ break; ++ else { ++ memcpy (p, str, len); ++ str += len; ++ } ++ if (first) { ++ --trunc_len; ++ --first; ++ p += len; ++ if (!first && p < x + sizeof (x) - 1 && trunc_len) { ++ *p++ = '~'; ++ --trunc_len; ++ } ++ } else if (skip) ++ --skip; ++ else { ++ --trunc_len; ++ p += len; ++ } ++ } ++ } else ++#endif ++ { ++ str = txt; ++ p = x; ++ while (p < x + sizeof (x) - 1) { ++ if (*str == '\0') ++ break; ++ else if (!is_printable (*str)) ++ *p++ = '?'; ++ else ++ *p++ = *str; ++ ++str; ++ if (first) { ++ --first; ++ if (!first) { ++ *p++ = '~'; ++ str += skip; ++ } ++ } ++ } ++ } ++ *p = '\0'; + return x; + } + +@@ -678,11 +904,61 @@ load_file (const char *filename) + } + + char * ++utf8_to_local(char *str) ++{ ++ iconv_t cd; ++ size_t buflen = strlen(str); ++ char *output; ++ int retry = 1; ++ ++ cd = iconv_open (nl_langinfo(CODESET), "UTF-8"); ++ if (cd == (iconv_t) -1) { ++ return g_strdup(str); ++ } ++ ++ output = g_malloc(buflen + 1); ++ ++ while (retry) ++ { ++ char *wrptr = output; ++ char *inptr = str; ++ size_t insize = buflen; ++ size_t avail = buflen; ++ size_t nconv; ++ ++ nconv = iconv (cd, &inptr, &insize, &wrptr, &avail); ++ if (nconv == (size_t) -1) ++ { ++ if (errno == E2BIG) ++ { ++ buflen *= 2; ++ g_free(output); ++ output = g_malloc(buflen + 1); ++ } ++ else ++ { ++ g_free(output); ++ return g_strdup(str); ++ } ++ } ++ else { ++ retry = 0; ++ *wrptr = 0; ++ } ++ } ++ ++ iconv_close (cd); ++ ++ return output; ++} ++ ++char * + load_mc_home_file (const char *filename, char **allocated_filename) + { + char *hintfile_base, *hintfile; + char *lang; + char *data; ++ char *conv_data; + + hintfile_base = concat_dir_and_file (mc_home, filename); + lang = guess_message_value (); +@@ -715,7 +991,10 @@ load_mc_home_file (const char *filename, + else + g_free (hintfile); + +- return data; ++ conv_data = utf8_to_local(data); ++ g_free(data); ++ ++ return conv_data; + } + + /* Check strftime() results. Some systems (i.e. Solaris) have different +@@ -724,12 +1003,14 @@ size_t + i18n_checktimelength (void) + { + size_t length, a, b; +- char buf [MAX_I18NTIMELENGTH + 1]; ++ char buf [4 * MAX_I18NTIMELENGTH + 1]; + time_t testtime = time (NULL); + +- a = strftime (buf, sizeof(buf)-1, _("%b %e %H:%M"), localtime(&testtime)); +- b = strftime (buf, sizeof(buf)-1, _("%b %e %Y"), localtime(&testtime)); +- ++ strftime (buf, sizeof(buf)-1, _("%b %e %H:%M"), localtime(&testtime)); ++ a = mbstrlen (buf); ++ strftime (buf, sizeof(buf)-1, _("%b %e %Y"), localtime(&testtime)); ++ b = mbstrlen (buf); ++ + length = max (a, b); + + /* Don't handle big differences. Use standard value (email bug, please) */ +@@ -742,15 +1023,12 @@ i18n_checktimelength (void) + const char * + file_date (time_t when) + { +- static char timebuf [MAX_I18NTIMELENGTH + 1]; ++ static char timebuf [4 * MAX_I18NTIMELENGTH + 1]; + time_t current_time = time ((time_t) 0); +- static size_t i18n_timelength = 0; + static const char *fmtyear, *fmttime; + const char *fmt; + +- if (i18n_timelength == 0){ +- i18n_timelength = i18n_checktimelength() + 1; +- ++ if (fmtyear == NULL) { + /* strftime() format string for old dates */ + fmtyear = _("%b %e %Y"); + /* strftime() format string for recent dates */ +@@ -770,7 +1048,7 @@ file_date (time_t when) + else + fmt = fmttime; + +- strftime (timebuf, i18n_timelength, fmt, localtime(&when)); ++ strftime (timebuf, sizeof (timebuf) - 1, fmt, localtime(&when)); + return timebuf; + } + +@@ -900,10 +1178,27 @@ strip_ctrl_codes (char *s) + r++; + continue; + } +- ++#ifndef UTF8 + if (is_printable(*r)) + *w++ = *r; + ++r; ++#else /* UTF8 */ ++ { ++ mbstate_t mbs; ++ int len; ++ memset (&mbs, 0, sizeof (mbs)); ++ len = mbrlen(r, MB_CUR_MAX, &mbs); ++ ++ if (len > 0 && (unsigned char)*r >= ' ') ++ while (len--) ++ *w++ = *r++; ++ else { ++ if (len == -1) ++ *w++ = '?'; ++ r++; ++ } ++ } ++#endif /* UTF8 */ + } + *w = 0; + return s; +diff -up mc-4.6.2-pre1/src/util.h.utf8 mc-4.6.2-pre1/src/util.h +--- mc-4.6.2-pre1/src/util.h.utf8 2006-02-03 18:04:17.000000000 +0100 ++++ mc-4.6.2-pre1/src/util.h 2008-10-23 14:00:12.000000000 +0200 +@@ -103,6 +103,13 @@ void init_uid_gid_cache (void); + char *get_group (int); + char *get_owner (int); + ++void fix_utf8(char *str); ++size_t mbstrlen (const char *); ++wchar_t *mbstr_to_wchar (const char *); ++char *wchar_to_mbstr (const wchar_t *); ++char *utf8_to_local(char *str); ++ ++ + #define MAX_I18NTIMELENGTH 14 + #define MIN_I18NTIMELENGTH 10 + #define STD_I18NTIMELENGTH 12 +diff -up mc-4.6.2-pre1/src/view.c.utf8 mc-4.6.2-pre1/src/view.c +--- mc-4.6.2-pre1/src/view.c.utf8 2006-12-30 14:16:54.000000000 +0100 ++++ mc-4.6.2-pre1/src/view.c 2008-10-23 14:00:12.000000000 +0200 +@@ -43,6 +43,10 @@ + #include + #include + ++#ifdef UTF8 ++#include ++#endif /* UTF8 */ ++ + #include "global.h" + #include "tty.h" + #include "cmd.h" /* For view_other_cmd */ +@@ -1642,7 +1646,7 @@ view_display_status (WView *view) + hline (' ', width); + + file_label = _("File: %s"); +- file_label_width = strlen (file_label) - 2; ++ file_label_width = mbstrlen (file_label) - 2; + file_name = view->filename ? view->filename + : view->command ? view->command + : ""; +@@ -1910,6 +1914,12 @@ view_display_text (WView * view) + offset_type from; + int c; + struct hexedit_change_node *curr = view->change_list; ++#ifdef UTF8 ++ mbstate_t mbs; ++ char mbbuf[MB_LEN_MAX]; ++ int mblen; ++ wchar_t wc; ++#endif /* UTF8 */ + + view_display_clean (view); + view_display_ruler (view); +@@ -1922,8 +1932,37 @@ view_display_text (WView * view) + + tty_setcolor (NORMAL_COLOR); + for (row = 0, col = 0; row < height && (c = get_byte (view, from)) != -1; from++) { +- ++#ifndef UTF8 + if (view->text_nroff_mode && c == '\b') { ++#else /* UTF8 */ ++ mblen = 1; ++ mbbuf[0] = convert_to_display_c (c); ++ ++ while (mblen < MB_LEN_MAX) { ++ int res; ++ memset (&mbs, 0, sizeof (mbs)); ++ res = mbrtowc (&wc, mbbuf, mblen, &mbs); ++ if (res <= 0 && res != -2) { ++ wc = '.'; ++ mblen = 1; ++ break; ++ } ++ if (res == mblen) ++ break; ++ ++ mbbuf[mblen] = convert_to_display_c (get_byte (view, from + mblen)); ++ mblen++; ++ } ++ ++ if (mblen == MB_LEN_MAX) { ++ wc = '.'; ++ mblen = 1; ++ } ++ ++ from += mblen - 1; ++ ++ if (view->text_nroff_mode && wc == '\b') { ++#endif /* UTF8 */ + int c_prev; + int c_next; + +@@ -1988,10 +2027,20 @@ view_display_text (WView * view) if (col >= view->dpy_text_column && col - view->dpy_text_column < width) { widget_move (view, top + row, left + (col - view->dpy_text_column)); --#ifndef UTF8 +#ifdef UTF8 + if (SLsmg_is_utf8_mode ()) { + if (!iswprint (wc)) @@ -5411,13 +4565,834 @@ diff -Nrbu mc-4.6.1a/src/view.c mc-4.6.1a-OK/src/view.c if (!is_printable (c)) c = '.'; tty_print_char (c); --#else -- wc = convert_to_display_c (wc); -- if (!iswprint (wc)) -- wc = '.'; -- tty_print_char (wc); +#ifdef UTF8 + } - #endif ++#endif } col++; + tty_setcolor (NORMAL_COLOR); +diff -up mc-4.6.2-pre1/src/widget.c.utf8 mc-4.6.2-pre1/src/widget.c +--- mc-4.6.2-pre1/src/widget.c.utf8 2006-05-29 13:58:43.000000000 +0200 ++++ mc-4.6.2-pre1/src/widget.c 2008-10-23 14:00:12.000000000 +0200 +@@ -36,6 +36,9 @@ + + #include "global.h" + #include "tty.h" ++#ifdef UTF8 ++#include ++#endif /* UTF8 */ + #include "color.h" + #include "mouse.h" + #include "dialog.h" +@@ -182,6 +185,11 @@ button_callback (Widget *w, widget_msg_t + if (b->hotpos >= 0) { + widget_selectcolor (w, b->selected, TRUE); + widget_move (w, 0, b->hotpos + off); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) ++ SLsmg_write_nwchars (&b->hotwc, 1); ++ else ++#endif + addch ((unsigned char) b->text[b->hotpos]); + } + return MSG_HANDLED; +@@ -215,7 +223,7 @@ button_event (Gpm_Event *event, void *da + static int + button_len (const char *text, unsigned int flags) + { +- int ret = strlen (text); ++ int ret = mbstrlen (text); + switch (flags){ + case DEFPUSH_BUTTON: + ret += 6; +@@ -238,14 +246,36 @@ button_len (const char *text, unsigned i + * the button text is g_malloc()ed, we can safely change and shorten it. + */ + static void +-button_scan_hotkey (WButton *b) ++scan_hotkey (char *text, int *hotposp, int *hotkeyp, wchar_t *hotwcp) + { +- char *cp = strchr (b->text, '&'); ++ char *cp = strchr (text, '&'); + + if (cp != NULL && cp[1] != '\0') { +- g_strlcpy (cp, cp + 1, strlen (cp)); +- b->hotkey = tolower ((unsigned char) *cp); +- b->hotpos = cp - b->text; ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ mbstate_t s; ++ int len; ++ ++ *cp = '\0'; ++ memset (&s, 0, sizeof (s)); ++ len = mbrtowc (hotwcp, cp + 1, MB_CUR_MAX, &s); ++ if (len > 0) { ++ *hotposp = mbstrlen (text); ++ if (*hotposp < 0) { ++ *hotposp = -1; ++ } else { ++ /* FIXME */ ++ *hotkeyp = tolower (*hotwcp); ++ } ++ } ++ } else ++#endif ++ { ++ *hotkeyp = tolower (cp[1]); ++ *hotposp = cp - text; ++ } ++ ++ memmove (cp, cp + 1, strlen (cp + 1) + 1); + } + } + +@@ -266,8 +296,9 @@ button_new (int y, int x, int action, in + widget_want_hotkey (b->widget, 1); + b->hotkey = 0; + b->hotpos = -1; ++ b->hotwc = L'\0'; + +- button_scan_hotkey(b); ++ scan_hotkey(b->text, &b->hotpos, &b->hotkey, &b->hotwc); + return b; + } + +@@ -280,14 +311,13 @@ button_get_text (WButton *b) + void + button_set_text (WButton *b, const char *text) + { +- g_free (b->text); ++ g_free (b->text); + b->text = g_strdup (text); + b->widget.cols = button_len (text, b->flags); +- button_scan_hotkey(b); ++ scan_hotkey(b->text, &b->hotpos, &b->hotkey, &b->hotwc); + dlg_redraw (b->widget.parent); + } + +- + /* Radio button widget */ + static int radio_event (Gpm_Event *event, void *); + +@@ -362,14 +392,35 @@ radio_callback (Widget *w, widget_msg_t + widget_move (&r->widget, i, 0); + + tty_printf ("(%c) ", (r->sel == i) ? '*' : ' '); +- for (cp = r->texts[i]; *cp; cp++) { +- if (*cp == '&') { +- widget_selectcolor (w, focused, TRUE); ++ cp = strchr (r->texts[i], '&'); ++ if (cp != NULL) { ++#ifdef UTF8 ++ mbstate_t s; ++ wchar_t wc; ++ int len; ++#endif ++ tty_printf ("%.*s", (int) ((char *) cp - r->texts[i]), ++ r->texts[i]); ++ widget_selectcolor (w, focused, TRUE); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) { ++ memset (&s, 0, sizeof (s)); ++ len = mbrtowc (&wc, cp + 1, MB_CUR_MAX, &s); ++ ++cp; ++ if (len > 0) { ++ tty_printf ("%.*s", len, cp); ++ cp += len; ++ } ++ } else ++#endif ++ { + addch (*++cp); +- widget_selectcolor (w, focused, FALSE); +- } else +- addch (*cp); +- } ++ ++cp; ++ } ++ widget_selectcolor (w, focused, FALSE); ++ } else ++ cp = r->texts[i]; ++ addstr ((char *) cp); + } + return MSG_HANDLED; + +@@ -408,7 +459,7 @@ radio_new (int y, int x, int count, cons + /* Compute the longest string */ + max = 0; + for (i = 0; i < count; i++){ +- m = strlen (texts [i]); ++ m = mbstrlen (texts [i]); + if (m > max) + max = m; + } +@@ -468,6 +519,11 @@ check_callback (Widget *w, widget_msg_t + if (c->hotpos >= 0) { + widget_selectcolor (w, msg == WIDGET_FOCUS, TRUE); + widget_move (&c->widget, 0, +c->hotpos + 4); ++#ifdef UTF8 ++ if (SLsmg_Is_Unicode) ++ SLsmg_write_nwchars (&c->hotwc, 1); ++ else ++#endif + addch ((unsigned char) c->text[c->hotpos]); + } + return MSG_HANDLED; +@@ -505,35 +561,20 @@ WCheck * + check_new (int y, int x, int state, const char *text) + { + WCheck *c = g_new (WCheck, 1); +- const char *s; +- char *t; +- +- init_widget (&c->widget, y, x, 1, strlen (text), ++ ++ init_widget (&c->widget, y, x, 1, mbstrlen (text), + check_callback, check_event); + c->state = state ? C_BOOL : 0; + c->text = g_strdup (text); + c->hotkey = 0; + c->hotpos = -1; ++ c->hotwc = L'\0'; + widget_want_hotkey (c->widget, 1); + +- /* Scan for the hotkey */ +- for (s = text, t = c->text; *s; s++, t++){ +- if (*s != '&'){ +- *t = *s; +- continue; +- } +- s++; +- if (*s){ +- c->hotkey = tolower ((unsigned char) *s); +- c->hotpos = t - c->text; +- } +- *t = *s; +- } +- *t = 0; ++ scan_hotkey (c->text, &c->hotpos, &c->hotkey, &c->hotwc); + return c; + } + +- + /* Label widget */ + + static cb_ret_t +@@ -572,7 +613,7 @@ label_callback (Widget *w, widget_msg_t + } + widget_move (&l->widget, y, 0); + tty_printf ("%s", p); +- xlen = l->widget.cols - strlen (p); ++ xlen = l->widget.cols - mbstrlen (p); + if (xlen > 0) + tty_printf ("%*s", xlen, " "); + if (!q) +@@ -606,7 +647,7 @@ label_set_text (WLabel *label, const cha + if (text){ + label->text = g_strdup (text); + if (label->auto_adjust_cols) { +- newcols = strlen (text); ++ newcols = mbstrlen (text); + if (newcols > label->widget.cols) + label->widget.cols = newcols; + } +@@ -630,7 +671,7 @@ label_new (int y, int x, const char *tex + if (!text || strchr(text, '\n')) + width = 1; + else +- width = strlen (text); ++ width = mbstrlen (text); + + l = g_new (WLabel, 1); + init_widget (&l->widget, y, x, 1, width, label_callback, NULL); +@@ -778,13 +819,69 @@ static void draw_history_button (WInput + /* Pointer to killed data */ + static char *kill_buffer = 0; + ++#ifdef UTF8 ++static int ++charpos(WInput *in, int idx) ++{ ++ int i, pos, l, len; ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++ i = 0; ++ pos = 0; ++ len = strlen(in->buffer); ++ ++ while (in->buffer[pos]) { ++ if (i == idx) ++ return pos; ++ l = mbrlen(in->buffer + pos, len - pos, &mbs); ++ if (l <= 0) ++ return pos; ++ pos+=l; ++ i++; ++ }; ++ return pos; ++} ++ ++static int ++charcolumn(WInput *in, int idx) ++{ ++ int i, pos, l, width, len; ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++ i = 0; ++ pos = 0; width = 0; ++ len = strlen(in->buffer); ++ ++ while (in->buffer[pos]) { ++ wchar_t wc; ++ if (i == idx) ++ return width; ++ l = mbrtowc(&wc, in->buffer + pos, len - pos, &mbs); ++ if (l <= 0) ++ return width; ++ pos += l; width += wcwidth(wc); ++ i++; ++ }; ++ return width; ++} ++#else ++#define charpos(in, idx) (idx) ++#define charcolumn(in, idx) (idx) ++#endif /* UTF8 */ ++ + void + update_input (WInput *in, int clear_first) + { + int has_history = 0; + int i, j; +- unsigned char c; +- int buf_len = strlen (in->buffer); ++ int buf_len = mbstrlen (in->buffer); ++#ifndef UTF8 ++ unsigned char c; ++#else /* UTF8 */ ++ wchar_t c; ++ mbstate_t mbs; ++ memset (&mbs, 0, sizeof (mbs)); ++#endif /* UTF8 */ + + if (should_show_history_button (in)) + has_history = HISTORY_BUTTON_WIDTH; +@@ -794,7 +891,7 @@ update_input (WInput *in, int clear_firs + + /* Make the point visible */ + if ((in->point < in->first_shown) || +- (in->point >= in->first_shown+in->field_len - has_history)){ ++ (charcolumn(in, in->point) >= charcolumn(in, in->first_shown) + in->field_len - has_history)){ + in->first_shown = in->point - (in->field_len / 3); + if (in->first_shown < 0) + in->first_shown = 0; +@@ -814,14 +911,29 @@ update_input (WInput *in, int clear_firs + addch (' '); + widget_move (&in->widget, 0, 0); + ++#ifndef UTF8 + for (i = 0, j = in->first_shown; i < in->field_len - has_history && in->buffer [j]; i++){ + c = in->buffer [j++]; + c = is_printable (c) ? c : '.'; +- if (in->is_password) ++#else /* UTF8 */ ++ for (i = 0, j = in->first_shown; (i < in->field_len - has_history) && (j < buf_len); i++,j++){ ++ char * chp = in->buffer + charpos(in,j); ++ size_t res = mbrtowc(&c, chp, strlen(chp), &mbs); ++ c = (res && iswprint (c)) ? 0 : '.'; ++#endif /* UTF8 */ ++ if (in->is_password) + c = '*'; ++#ifndef UTF8 + addch (c); ++#else /* UTF8 */ ++ if (c) { ++ addch (c); ++ } ++ else ++ SLsmg_write_nchars (chp, res); ++#endif /* UTF8 */ + } +- widget_move (&in->widget, 0, in->point - in->first_shown); ++ widget_move (&in->widget, 0, charcolumn(in, in->point) - charcolumn(in, in->first_shown)); + + if (clear_first) + in->first = 0; +@@ -974,7 +1086,7 @@ char * + show_hist (GList *history, int widget_x, int widget_y) + { + GList *hi, *z; +- size_t maxlen = strlen (i18n_htitle ()), i, count = 0; ++ size_t maxlen = mbstrlen (i18n_htitle ()), i, count = 0; + int x, y, w, h; + char *q, *r = 0; + Dlg_head *query_dlg; +@@ -987,7 +1099,7 @@ show_hist (GList *history, int widget_x, + z = g_list_first (history); + hi = z; + while (hi) { +- if ((i = strlen ((char *) hi->data)) > maxlen) ++ if ((i = mbstrlen ((char *) hi->data)) > maxlen) + maxlen = i; + count++; + hi = g_list_next (hi); +@@ -1157,35 +1269,83 @@ new_input (WInput *in) + in->need_push = 1; + in->buffer [0] = 0; + in->point = 0; ++ in->charpoint = 0; + in->mark = 0; + free_completions (in); + update_input (in, 0); + } + ++static void ++move_buffer_backward (WInput *in, int point) ++{ ++ int i, pos, len; ++ int str_len = mbstrlen (in->buffer); ++ if (point >= str_len) return; ++ ++ pos = charpos(in,point); ++ len = charpos(in,point + 1) - pos; ++ ++ for (i = pos; in->buffer [i + len - 1]; i++) ++ in->buffer [i] = in->buffer [i + len]; ++} ++ + static cb_ret_t + insert_char (WInput *in, int c_code) + { + size_t i; ++#ifdef UTF8 ++ mbstate_t mbs; ++ int res; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++#else ++ in->charpoint = 0; ++#endif /* UTF8 */ + + if (c_code == -1) + return MSG_NOT_HANDLED; + ++#ifdef UTF8 ++ if (in->charpoint >= MB_CUR_MAX) return 1; ++ ++ in->charbuf[in->charpoint++] = c_code; ++ ++ res = mbrlen((char *)in->charbuf, in->charpoint, &mbs); ++ if (res < 0) { ++ if (res != -2) in->charpoint = 0; /* broken multibyte char, skip */ ++ return 1; ++ } ++ ++#endif /* UTF8 */ + in->need_push = 1; +- if (strlen (in->buffer)+1 == (size_t) in->current_max_len){ ++ if (strlen (in->buffer) + 1 + in->charpoint >= (size_t) in->current_max_len){ + /* Expand the buffer */ +- char *narea = g_realloc (in->buffer, in->current_max_len + in->field_len); ++ char *narea = g_realloc (in->buffer, in->current_max_len + in->field_len + in->charpoint); + if (narea){ + in->buffer = narea; +- in->current_max_len += in->field_len; ++ in->current_max_len += in->field_len + in->charpoint; + } + } ++#ifndef UTF8 + if (strlen (in->buffer)+1 < (size_t) in->current_max_len){ + size_t l = strlen (&in->buffer [in->point]); + for (i = l+1; i > 0; i--) + in->buffer [in->point+i] = in->buffer [in->point+i-1]; + in->buffer [in->point] = c_code; ++#else /* UTF8 */ ++ if (strlen (in->buffer) + in->charpoint < in->current_max_len){ ++ size_t ins_point = charpos(in,in->point); /* bytes from begin */ ++ /* move chars */ ++ size_t rest_bytes = strlen (in->buffer + ins_point); ++ ++ for (i = rest_bytes + 1; i > 0; i--) ++ in->buffer [ins_point + i + in->charpoint - 1] = in->buffer [ins_point + i - 1]; ++ ++ memcpy(in->buffer + ins_point, in->charbuf, in->charpoint); ++#endif /* UTF8 */ + in->point++; + } ++ in->charpoint = 0; + return MSG_HANDLED; + } + +@@ -1193,12 +1353,14 @@ static void + beginning_of_line (WInput *in) + { + in->point = 0; ++ in->charpoint = 0; + } + + static void + end_of_line (WInput *in) + { +- in->point = strlen (in->buffer); ++ in->point = mbstrlen (in->buffer); ++ in->charpoint = 0; + } + + static void +@@ -1206,18 +1368,21 @@ backward_char (WInput *in) + { + if (in->point) + in->point--; ++ in->charpoint = 0; + } + + static void + forward_char (WInput *in) + { +- if (in->buffer [in->point]) ++ if (in->buffer [charpos(in,in->point)]) + in->point++; ++ in->charpoint = 0; + } + + static void + forward_word (WInput * in) + { ++#ifndef UTF8 + char *p = in->buffer + in->point; + + while (*p +@@ -1227,11 +1392,39 @@ forward_word (WInput * in) + while (*p && isalnum ((unsigned char) *p)) + p++; + in->point = p - in->buffer; ++#else /* UTF8 */ ++ mbstate_t mbs; ++ int len = mbstrlen (in->buffer); ++ memset (&mbs, 0, sizeof (mbs)); ++ ++ while (in->point < len) { ++ wchar_t c; ++ char *p = in->buffer + charpos(in,in->point); ++ size_t res = mbrtowc(&c, p, strlen(p), &mbs); ++ if (res <= 0 || !(iswspace (c) || iswpunct (c))) ++ break; ++ in->point++; ++ } ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ ++ while (in->point < len) { ++ wchar_t c; ++ char *p = in->buffer + charpos(in,in->point); ++ size_t res = mbrtowc(&c, p, strlen(p), &mbs); ++ if (res <= 0 || !iswalnum (c)) ++ break; ++ in->point++; ++ } ++ ++ in->charpoint = 0; ++#endif /* UTF8 */ + } + + static void + backward_word (WInput *in) + { ++#ifndef UTF8 + char *p = in->buffer + in->point; + + while (p - 1 > in->buffer - 1 && (isspace ((unsigned char) *(p - 1)) +@@ -1241,6 +1434,32 @@ backward_word (WInput *in) + while (p - 1 > in->buffer - 1 && isalnum ((unsigned char) *(p - 1))) + p--; + in->point = p - in->buffer; ++#else /* UTF8 */ ++ mbstate_t mbs; ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ while (in->point > 0) { ++ wchar_t c; ++ char *p = in->buffer + charpos(in,in->point); ++ size_t res = mbrtowc(&c, p, strlen(p), &mbs); ++ if (*p && (res <= 0 || !(iswspace (c) || iswpunct (c)))) ++ break; ++ in->point--; ++ } ++ ++ memset (&mbs, 0, sizeof (mbs)); ++ ++ while (in->point > 0) { ++ wchar_t c; ++ char *p = in->buffer + charpos(in,in->point); ++ size_t res = mbrtowc(&c, p, strlen(p), &mbs); ++ if (*p && (res <= 0 || !iswalnum (c))) ++ break; ++ in->point--; ++ } ++ ++ in->charpoint = 0; ++#endif /* UTF8 */ + } + + static void +@@ -1273,8 +1492,9 @@ backward_delete (WInput *in) + + if (!in->point) + return; +- for (i = in->point; in->buffer [i-1]; i++) +- in->buffer [i-1] = in->buffer [i]; ++ ++ move_buffer_backward(in, in->point - 1); ++ in->charpoint = 0; + in->need_push = 1; + in->point--; + } +@@ -1282,10 +1502,8 @@ backward_delete (WInput *in) + static void + delete_char (WInput *in) + { +- int i; +- +- for (i = in->point; in->buffer [i]; i++) +- in->buffer [i] = in->buffer [i+1]; ++ move_buffer_backward(in, in->point); ++ in->charpoint = 0; + in->need_push = 1; + } + +@@ -1300,6 +1518,9 @@ copy_region (WInput *in, int x_first, in + + g_free (kill_buffer); + ++ first=charpos(in,first); ++ last=charpos(in,last); ++ + kill_buffer = g_strndup(in->buffer+first,last-first); + } + +@@ -1308,11 +1529,13 @@ delete_region (WInput *in, int x_first, + { + int first = min (x_first, x_last); + int last = max (x_first, x_last); +- size_t len = strlen (&in->buffer [last]) + 1; ++ size_t len; + + in->point = first; + in->mark = first; +- memmove (&in->buffer [first], &in->buffer [last], len); ++ len = strlen (&in->buffer [charpos(in,last)]) + 1; ++ memmove (&in->buffer [charpos(in,first)], &in->buffer [charpos(in,last)], len); ++ in->charpoint = 0; + in->need_push = 1; + } + +@@ -1329,6 +1552,8 @@ kill_word (WInput *in) + copy_region (in, old_point, new_point); + delete_region (in, old_point, new_point); + in->need_push = 1; ++ in->charpoint = 0; ++ in->charpoint = 0; + } + + static void +@@ -1372,16 +1597,20 @@ yank (WInput *in) + + if (!kill_buffer) + return; ++ in->charpoint = 0; + for (p = kill_buffer; *p; p++) + insert_char (in, *p); ++ in->charpoint = 0; + } + + static void + kill_line (WInput *in) + { ++ int chp = charpos(in,in->point); + g_free (kill_buffer); +- kill_buffer = g_strdup (&in->buffer [in->point]); +- in->buffer [in->point] = 0; ++ kill_buffer = g_strdup (&in->buffer [chp]); ++ in->buffer [chp] = 0; ++ in->charpoint = 0; + } + + void +@@ -1391,9 +1620,10 @@ assign_text (WInput *in, const char *tex + g_free (in->buffer); + in->buffer = g_strdup (text); /* was in->buffer->text */ + in->current_max_len = strlen (in->buffer) + 1; +- in->point = strlen (in->buffer); ++ in->point = mbstrlen (in->buffer); + in->mark = 0; + in->need_push = 1; ++ in->charpoint = 0; + } + + static void +@@ -1520,6 +1750,7 @@ port_region_marked_for_delete (WInput *i + *in->buffer = 0; + in->point = 0; + in->first = 0; ++ in->charpoint = 0; + } + + cb_ret_t +@@ -1548,7 +1779,11 @@ handle_char (WInput *in, int c_code) + } + } + if (!input_map [i].fn){ ++#ifndef UTF8 + if (c_code > 255 || !is_printable (c_code)) ++#else /* UTF8 */ ++ if (c_code > 255) ++#endif /* UTF8 */ + return MSG_NOT_HANDLED; + if (in->first){ + port_region_marked_for_delete (in); +@@ -1581,6 +1816,9 @@ input_set_point (WInput *in, int pos) + if (pos != in->point) + free_completions (in); + in->point = pos; ++#ifdef UTF8 ++ in->charpoint = 0; ++#endif /* UTF8 */ + update_input (in, 1); + } + +@@ -1621,7 +1859,7 @@ input_callback (Widget *w, widget_msg_t + return MSG_HANDLED; + + case WIDGET_CURSOR: +- widget_move (&in->widget, 0, in->point - in->first_shown); ++ widget_move (&in->widget, 0, charcolumn(in, in->point) - charcolumn(in, in->first_shown)); + return MSG_HANDLED; + + case WIDGET_DESTROY: +@@ -1645,7 +1883,7 @@ input_event (Gpm_Event * event, void *da + && should_show_history_button (in)) { + do_show_hist (in); + } else { +- in->point = strlen (in->buffer); ++ in->point = mbstrlen (in->buffer); + if (event->x - in->first_shown - 1 < in->point) + in->point = event->x - in->first_shown - 1; + if (in->point < 0) +@@ -1702,7 +1940,8 @@ input_new (int y, int x, int color, int + in->is_password = 0; + + strcpy (in->buffer, def_text); +- in->point = strlen (in->buffer); ++ in->point = mbstrlen (in->buffer); ++ in->charpoint = 0; + return in; + } + +diff -up mc-4.6.2-pre1/src/widget.h.utf8 mc-4.6.2-pre1/src/widget.h +--- mc-4.6.2-pre1/src/widget.h.utf8 2006-02-28 17:15:21.000000000 +0100 ++++ mc-4.6.2-pre1/src/widget.h 2008-10-23 14:00:12.000000000 +0200 +@@ -22,6 +22,7 @@ typedef struct WButton { + char *text; /* text of button */ + int hotkey; /* hot KEY */ + int hotpos; /* offset hot KEY char in text */ ++ wchar_t hotwc; + bcback callback; /* Callback function */ + } WButton; + +@@ -42,6 +43,7 @@ typedef struct WCheck { + char *text; /* text of check button */ + int hotkey; /* hot KEY */ + int hotpos; /* offset hot KEY char in text */ ++ wchar_t hotwc; + } WCheck; + + typedef struct WGauge { +@@ -57,16 +59,20 @@ char *show_hist (GList *history, int wid + + typedef struct { + Widget widget; +- int point; /* cursor position in the input line */ +- int mark; /* The mark position */ +- int first_shown; /* Index of the first shown character */ +- int current_max_len; /* Maximum length of input line */ +- int field_len; /* Length of the editing field */ ++ int point; /* cursor position in the input line (mb chars) */ ++ int mark; /* The mark position (mb chars) */ ++ int first_shown; /* Index of the first shown character (mb chars) */ ++ int current_max_len; /* Maximum length of input line (bytes) */ ++ int field_len; /* Length of the editing field (mb chars) */ + int color; /* color used */ + int first; /* Is first keystroke? */ + int disable_update; /* Do we want to skip updates? */ + int is_password; /* Is this a password input line? */ + char *buffer; /* pointer to editing buffer */ ++#ifdef UTF8 ++ char charbuf[MB_LEN_MAX]; ++#endif /* UTF8 */ ++ int charpoint; + GList *history; /* The history */ + int need_push; /* need to push the current Input on hist? */ + char **completions; /* Possible completions array */ +diff -up mc-4.6.2-pre1/src/wtools.c.utf8 mc-4.6.2-pre1/src/wtools.c +--- mc-4.6.2-pre1/src/wtools.c.utf8 2006-09-14 11:12:49.000000000 +0200 ++++ mc-4.6.2-pre1/src/wtools.c 2008-10-23 14:00:12.000000000 +0200 +@@ -49,11 +49,11 @@ create_listbox_window (int cols, int lin + /* Adjust sizes */ + lines = (lines > LINES - 6) ? LINES - 6 : lines; + +- if (title && (cols < (len = strlen (title) + 2))) ++ if (title && (cols < (len = mbstrlen (title) + 2))) + cols = len; + + /* no &, but 4 spaces around button for brackets and such */ +- if (cols < (len = strlen (cancel_string) + 3)) ++ if (cols < (len = mbstrlen (cancel_string) + 3)) + cols = len; + + cols = cols > COLS - 6 ? COLS - 6 : cols; +@@ -124,7 +124,7 @@ query_dialog (const char *header, const + va_start (ap, count); + for (i = 0; i < count; i++) { + char *cp = va_arg (ap, char *); +- win_len += strlen (cp) + 6; ++ win_len += mbstrlen (cp) + 6; + if (strchr (cp, '&') != NULL) + win_len--; + } +@@ -133,7 +133,7 @@ query_dialog (const char *header, const + + /* count coordinates */ + msglen (text, &lines, &cols); +- cols = 6 + max (win_len, max ((int) strlen (header), cols)); ++ cols = 6 + max (win_len, max ((int) mbstrlen (header), cols)); + lines += 4 + (count > 0 ? 2 : 0); + xpos = COLS / 2 - cols / 2; + ypos = LINES / 3 - (lines - 3) / 2; +@@ -148,7 +148,7 @@ query_dialog (const char *header, const + va_start (ap, count); + for (i = 0; i < count; i++) { + cur_name = va_arg (ap, char *); +- xpos = strlen (cur_name) + 6; ++ xpos = mbstrlen (cur_name) + 6; + if (strchr (cur_name, '&') != NULL) + xpos--; + +@@ -463,7 +463,7 @@ fg_input_dialog_help (const char *header + quick_widgets[2].histname = histname; + + msglen (text, &lines, &cols); +- len = max ((int) strlen (header), cols) + 4; ++ len = max ((int) mbstrlen (header), cols) + 4; + len = max (len, 64); + + /* The special value of def_text is used to identify password boxes +@@ -485,7 +485,7 @@ fg_input_dialog_help (const char *header + quick_widgets[1].text = _(quick_widgets[1].text); + quick_widgets[0].relative_x = len / 2 + 4; + quick_widgets[1].relative_x = +- len / 2 - (strlen (quick_widgets[1].text) + 9); ++ len / 2 - (mbstrlen (quick_widgets[1].text) + 9); + quick_widgets[0].x_divisions = quick_widgets[1].x_divisions = len; + #endif /* ENABLE_NLS */ + diff --git a/mc.spec b/mc.spec index 533542f..cd8485e 100644 --- a/mc.spec +++ b/mc.spec @@ -1,7 +1,7 @@ Summary: User-friendly text console file manager and visual shell Name: mc Version: 4.6.2 -Release: 6.pre1%{?dist} +Release: 7.pre1%{?dist} Epoch: 1 License: GPLv2 Group: System Environment/Shells @@ -34,6 +34,7 @@ Patch19: mc-hintchk.patch Patch20: mc-7zip.patch Patch21: mc-oldrpmtags.patch Patch22: mc-shellcwd.patch +Patch23: mc-cedit-configurable-highlight.patch %description Midnight Commander is a visual shell much like a file manager, only @@ -67,6 +68,7 @@ specific files. %patch20 -p1 -b .7zip %patch21 -p1 -b .oldrpmtags %patch22 -p1 -b .shellcwd +%patch23 -p1 -b .cedit-configurable-highlight # convert files in /lib to UTF-8 pushd lib @@ -204,6 +206,11 @@ rm -rf $RPM_BUILD_ROOT %dir %{_libexecdir}/mc %changelog +* Thu Oct 23 2008 Jindrich Novy 4.6.2-7.pre1 +- allow switching of trailing spaces/tab highlighting with crtl-v, + patch from Jan Engelhardt (#464738) +- update the UTF-8 patch accordingly + * Tue Sep 2 2008 Jindrich Novy 4.6.2-6.pre1 - do not change directory in panel to subshell directory when switched back from subshell (#460633)