View | Details | Raw Unified | Return to bug 131355
Collapse All | Expand All

(-)Makefile (-12 / +17 lines)
Lines 6-16 Link Here
6
#
6
#
7
7
8
PORTNAME=	mc
8
PORTNAME=	mc
9
PORTVERSION=	4.6.1
9
PORTVERSION=	4.6.2
10
PORTREVISION=	8
11
CATEGORIES=	misc shells
10
CATEGORIES=	misc shells
12
MASTER_SITES=	${MASTER_SITE_SUNSITE}
11
MASTER_SITES=	http://www.midnight-commander.org/downloads/ \
13
MASTER_SITE_SUBDIR=	utils/file/managers/mc/
12
		${MASTER_SITE_SUNSITE}
13
MASTER_SITE_SUBDIR=	utils/file/managers/mc
14
15
PATCH_SITES=	${MASTER_SITES}
14
16
15
MAINTAINER=	fjoe@FreeBSD.org
17
MAINTAINER=	fjoe@FreeBSD.org
16
COMMENT=	Midnight Commander, a free Norton Commander Clone
18
COMMENT=	Midnight Commander, a free Norton Commander Clone
Lines 29-34 Link Here
29
.endif
31
.endif
30
USE_PERL5=	yes
32
USE_PERL5=	yes
31
GNU_CONFIGURE=	yes
33
GNU_CONFIGURE=	yes
34
USE_AUTOTOOLS=	aclocal:19 automake:19
35
ACLOCAL_ARGS=	-I m4
36
AUTOMAKE_ARGS=	-c -a
32
37
33
OPTIONS=	UTF8		"Build with UTF8 support" on \
38
OPTIONS=	UTF8		"Build with UTF8 support" on \
34
		SLANG		"Build with SLang library" on \
39
		SLANG		"Build with SLang library" on \
Lines 47-53 Link Here
47
.endif
52
.endif
48
53
49
.if defined(WITH_ICONV) || !(defined(WITHOUT_ICONV) || defined(MINIMAL))
54
.if defined(WITH_ICONV) || !(defined(WITHOUT_ICONV) || defined(MINIMAL))
50
CONFIGURE_ARGS+=--enable-charset
55
CONFIGURE_ARGS+=--enable-charset --with-libiconv-prefix=${LOCALBASE}
51
PLIST_SUB=	CHARSETS=""
56
PLIST_SUB=	CHARSETS=""
52
.else
57
.else
53
PLIST_SUB=	CHARSETS="@comment "
58
PLIST_SUB=	CHARSETS="@comment "
Lines 57-64 Link Here
57
CONFIGURE_ARGS+=--disable-nls
62
CONFIGURE_ARGS+=--disable-nls
58
PLIST_SUB+=	NLS="@comment "
63
PLIST_SUB+=	NLS="@comment "
59
.else
64
.else
65
CONFIGURE_ARGS+=--with-libintl-prefix=${LOCALBASE}
60
PLIST_SUB+=	NLS=""
66
PLIST_SUB+=	NLS=""
61
_MANLANG=	es hu it pl ru.KOI8-R sr
67
_MANLANG=	es hu it pl ru sr
62
.endif
68
.endif
63
69
64
.if !defined(WITH_X11) || defined(MINIMAL)
70
.if !defined(WITH_X11) || defined(MINIMAL)
Lines 82-90 Link Here
82
.endif
88
.endif
83
89
84
.if defined(WITH_UTF8)
90
.if defined(WITH_UTF8)
91
PATCHFILES=	${DISTNAME}-utf8.patch.gz
92
PATCH_DIST_STRIP=	-p1
85
LIB_DEPENDS+=	slang.2:${PORTSDIR}/devel/libslang2
93
LIB_DEPENDS+=	slang.2:${PORTSDIR}/devel/libslang2
86
CONFIGURE_ARGS+=--with-screen-slang
94
CONFIGURE_ARGS+=--with-screen=slang
87
CONFIGURE_ENV+=	LDFLAGS=-L${PREFIX}/lib
95
CONFIGURE_ENV+=	LDFLAGS=-L${LOCALBASE}/lib
88
.elif !defined(WITH_SLANG) && (defined(WITHOUT_SLANG) || defined(MINIMAL))
96
.elif !defined(WITH_SLANG) && (defined(WITHOUT_SLANG) || defined(MINIMAL))
89
CONFIGURE_ARGS+=--with-screen=ncurses
97
CONFIGURE_ARGS+=--with-screen=ncurses
90
.else
98
.else
Lines 110-123 Link Here
110
post-patch:
118
post-patch:
111
.if !defined(WITH_NLS) && (defined(WITHOUT_NLS) || defined(MINIMAL))
119
.if !defined(WITH_NLS) && (defined(WITHOUT_NLS) || defined(MINIMAL))
112
	@${REINPLACE_CMD} -e '/^LIBFILES_ADD +=/,/[^\\]$$/ s/^/#/'\
120
	@${REINPLACE_CMD} -e '/^LIBFILES_ADD +=/,/[^\\]$$/ s/^/#/'\
113
	    ${WRKSRC}/lib/Makefile.in
121
		${WRKSRC}/lib/Makefile.am
114
.endif
122
.endif
115
	@${REINPLACE_CMD} -e 's|/usr/bin/zip|${LOCALBASE}/bin/zip|' \
123
	@${REINPLACE_CMD} -e 's|/usr/bin/zip|${LOCALBASE}/bin/zip|' \
116
		-e 's|/usr/bin/unzip|${LOCALBASE}/bin/unzip|' \
124
		-e 's|/usr/bin/unzip|${LOCALBASE}/bin/unzip|' \
117
		${WRKSRC}/configure
125
		${WRKSRC}/configure
118
.if defined(WITH_UTF8)
119
	cat ${PATCHDIR}/mc-4.6.1-utf8-r2.patch | patch -p1 --silent -d ${WRKSRC}
120
.endif
121
126
122
post-install:
127
post-install:
123
	@${LN} -sf mc ${PREFIX}/bin/midc
128
	@${LN} -sf mc ${PREFIX}/bin/midc
(-)distinfo (-3 / +6 lines)
Lines 1-3 Link Here
1
MD5 (mc-4.6.1.tar.gz) = 18b20db6e40480a53bac2870c56fc3c4
1
MD5 (mc-4.6.2.tar.gz) = ec92966f4d0c8b50c344fe901859ae2a
2
SHA256 (mc-4.6.1.tar.gz) = 086ab03daaac28a28c0ddb9a709040b59e1322f6bfa68e39d004d9c66b119e7e
2
SHA256 (mc-4.6.2.tar.gz) = d34c913e7fff4ea61cf8640b10f9118829cc5359045a1821b6510f3c8b1be26e
3
SIZE (mc-4.6.1.tar.gz) = 3928370
3
SIZE (mc-4.6.2.tar.gz) = 3442912
4
MD5 (mc-4.6.2-utf8.patch.gz) = 9753f1d340c7e3f6f73242afcf12edd2
5
SHA256 (mc-4.6.2-utf8.patch.gz) = 8ce42552efcef32ca72bed87ca9f1438179a0ea2682f7d6b4d4975b11ec9bdf4
6
SIZE (mc-4.6.2-utf8.patch.gz) = 51164
(-)pkg-descr (-1 / +1 lines)
Lines 5-8 Link Here
5
preserving the full power of the command prompt. You will wonder how
5
preserving the full power of the command prompt. You will wonder how
6
you could ever live without it.
6
you could ever live without it.
7
7
8
WWW: http://www.ibiblio.org/mc/
8
WWW: http://www.midnight-commander.org
(-)pkg-plist (+11 lines)
Lines 36-41 Link Here
36
%%NLS%%share/locale/ta/LC_MESSAGES/mc.mo
36
%%NLS%%share/locale/ta/LC_MESSAGES/mc.mo
37
%%NLS%%share/locale/tr/LC_MESSAGES/mc.mo
37
%%NLS%%share/locale/tr/LC_MESSAGES/mc.mo
38
%%NLS%%share/locale/uk/LC_MESSAGES/mc.mo
38
%%NLS%%share/locale/uk/LC_MESSAGES/mc.mo
39
%%NLS%%share/locale/vi/LC_MESSAGES/mc.mo
39
%%NLS%%share/locale/wa/LC_MESSAGES/mc.mo
40
%%NLS%%share/locale/wa/LC_MESSAGES/mc.mo
40
%%NLS%%share/locale/zh_CN/LC_MESSAGES/mc.mo
41
%%NLS%%share/locale/zh_CN/LC_MESSAGES/mc.mo
41
%%NLS%%share/locale/zh_TW/LC_MESSAGES/mc.mo
42
%%NLS%%share/locale/zh_TW/LC_MESSAGES/mc.mo
Lines 65-70 Link Here
65
%%DATADIR%%/extfs/rpms
66
%%DATADIR%%/extfs/rpms
66
%%DATADIR%%/extfs/sfs.ini
67
%%DATADIR%%/extfs/sfs.ini
67
%%DATADIR%%/extfs/trpm
68
%%DATADIR%%/extfs/trpm
69
%%DATADIR%%/extfs/u7z
70
%%DATADIR%%/extfs/ualz
68
%%DATADIR%%/extfs/uar
71
%%DATADIR%%/extfs/uar
69
%%DATADIR%%/extfs/uarj
72
%%DATADIR%%/extfs/uarj
70
%%DATADIR%%/extfs/uha
73
%%DATADIR%%/extfs/uha
Lines 102-107 Link Here
102
%%EDITOR%%%%DATADIR%%/syntax/c.syntax
105
%%EDITOR%%%%DATADIR%%/syntax/c.syntax
103
%%EDITOR%%%%DATADIR%%/syntax/changelog.syntax
106
%%EDITOR%%%%DATADIR%%/syntax/changelog.syntax
104
%%EDITOR%%%%DATADIR%%/syntax/cs.syntax
107
%%EDITOR%%%%DATADIR%%/syntax/cs.syntax
108
%%EDITOR%%%%DATADIR%%/syntax/css.syntax
109
%%EDITOR%%%%DATADIR%%/syntax/cxx.syntax
110
%%EDITOR%%%%DATADIR%%/syntax/d.syntax
111
%%EDITOR%%%%DATADIR%%/syntax/debian-changelog.syntax
112
%%EDITOR%%%%DATADIR%%/syntax/debian-control.syntax
113
%%EDITOR%%%%DATADIR%%/syntax/debian-description.syntax
114
%%EDITOR%%%%DATADIR%%/syntax/debian-sources-list.syntax
105
%%EDITOR%%%%DATADIR%%/syntax/diff.syntax
115
%%EDITOR%%%%DATADIR%%/syntax/diff.syntax
106
%%EDITOR%%%%DATADIR%%/syntax/dos.syntax
116
%%EDITOR%%%%DATADIR%%/syntax/dos.syntax
107
%%EDITOR%%%%DATADIR%%/syntax/eiffel.syntax
117
%%EDITOR%%%%DATADIR%%/syntax/eiffel.syntax
Lines 142-144 Link Here
142
@dirrm %%DATADIR%%/extfs
152
@dirrm %%DATADIR%%/extfs
143
@dirrm %%DATADIR%%/bin
153
@dirrm %%DATADIR%%/bin
144
@dirrm %%DATADIR%%
154
@dirrm %%DATADIR%%
155
@dirrm libexec/mc
(-)files/mc-4.6.1-utf8-r2.patch (-5119 lines)
Removed Link Here
1
diff -Naur mc-4.6.1-old/edit/edit.c mc-4.6.1/edit/edit.c
2
--- mc-4.6.1-old/edit/edit.c	2005-05-27 16:19:18.000000000 +0200
3
+++ mc-4.6.1/edit/edit.c	2005-10-28 10:08:07.736247264 +0200
4
@@ -93,7 +93,7 @@
5
 
6
 #ifndef NO_INLINE_GETBYTE
7
 
8
-int edit_get_byte (WEdit * edit, long byte_index)
9
+mc_wchar_t edit_get_byte (WEdit * edit, long byte_index)
10
 {
11
     unsigned long p;
12
     if (byte_index >= (edit->curs1 + edit->curs2) || byte_index < 0)
13
@@ -125,7 +125,7 @@
14
 
15
     edit->curs1 = 0;
16
     edit->curs2 = 0;
17
-    edit->buffers2[0] = g_malloc (EDIT_BUF_SIZE);
18
+    edit->buffers2[0] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
19
 }
20
 
21
 /*
22
@@ -152,7 +152,7 @@
23
     }
24
 
25
     if (!edit->buffers2[buf2])
26
-	edit->buffers2[buf2] = g_malloc (EDIT_BUF_SIZE);
27
+	edit->buffers2[buf2] = g_malloc (EDIT_BUF_SIZE  * sizeof(mc_wchar_t));
28
 
29
     mc_read (file,
30
 	     (char *) edit->buffers2[buf2] + EDIT_BUF_SIZE -
31
@@ -162,7 +162,7 @@
32
     for (buf = buf2 - 1; buf >= 0; buf--) {
33
 	/* edit->buffers2[0] is already allocated */
34
 	if (!edit->buffers2[buf])
35
-	    edit->buffers2[buf] = g_malloc (EDIT_BUF_SIZE);
36
+	    edit->buffers2[buf] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
37
 	mc_read (file, (char *) edit->buffers2[buf], EDIT_BUF_SIZE);
38
     }
39
 
40
@@ -242,9 +242,44 @@
41
 {
42
     int c;
43
     long i = 0;
44
-    while ((c = fgetc (f)) >= 0) {
45
+#ifndef UTF8
46
+    while ((c = fgetc (f)) != EOF) {
47
 	edit_insert (edit, c);
48
 	i++;
49
+#else /* UTF8 */
50
+    unsigned char buf[MB_LEN_MAX];
51
+    int charpos = 0;
52
+    mbstate_t mbs;
53
+
54
+    while ((c = fgetc (f)) != EOF) {
55
+	mc_wchar_t wc;
56
+	int size;
57
+	int j;
58
+
59
+	buf[charpos++] = c;
60
+
61
+        memset (&mbs, 0, sizeof (mbs));
62
+	size = mbrtowc(&wc, (char *)buf, charpos, &mbs);
63
+
64
+	if (size == -2) 
65
+	    continue; /* incomplete */
66
+
67
+	else if (size >= 0) {
68
+	    edit_insert (edit, wc);
69
+	    i++;
70
+	    charpos = 0;
71
+	    continue;
72
+	}
73
+	else {
74
+
75
+		/* invalid  */
76
+#ifdef __STDC_ISO_10646__
77
+		for (j=0; j<charpos; j++)
78
+		    edit_insert (edit, BINARY_CHAR_OFFSET + (mc_wchar_t)buf[j]);
79
+#endif
80
+		charpos = 0;
81
+	}
82
+#endif /* UTF8 */
83
     }
84
     return i;
85
 }
86
@@ -252,9 +287,32 @@
87
 long edit_write_stream (WEdit * edit, FILE * f)
88
 {
89
     long i;
90
+#ifndef UTF8
91
     for (i = 0; i < edit->last_byte; i++)
92
 	if (fputc (edit_get_byte (edit, i), f) < 0)
93
 	    break;
94
+#else /* UTF8 */
95
+    for (i = 0; i < edit->last_byte; i++) {
96
+	mc_wchar_t wc = edit_get_byte (edit, i);
97
+	int res;
98
+	char tmpbuf[MB_LEN_MAX];
99
+        mbstate_t mbs;
100
+
101
+        memset (&mbs, 0, sizeof (mbs));
102
+
103
+#ifdef __STDC_ISO_10646__ 
104
+	if (wc >= BINARY_CHAR_OFFSET && wc < (BINARY_CHAR_OFFSET + 256)) {
105
+	    res = 1;
106
+	    tmpbuf[0] = (char) (wc - BINARY_CHAR_OFFSET);
107
+	} else
108
+#endif
109
+	res = wcrtomb(tmpbuf, wc, &mbs);
110
+	if (res > 0) {
111
+	    if (fwrite(tmpbuf, res, 1, f) != 1)
112
+		break;
113
+	}
114
+    }
115
+#endif /* UTF8 */
116
     return i;
117
 }
118
 
119
@@ -294,12 +352,46 @@
120
 	int i, file, blocklen;
121
 	long current = edit->curs1;
122
 	unsigned char *buf;
123
+#ifdef UTF8
124
+	mbstate_t mbs;
125
+	int bufstart = 0;
126
+
127
+	memset (&mbs, 0, sizeof (mbs));
128
+#endif /* UTF8 */
129
 	if ((file = mc_open (filename, O_RDONLY | O_BINARY)) == -1)
130
 	    return 0;
131
 	buf = g_malloc (TEMP_BUF_LEN);
132
+#ifndef UTF8
133
 	while ((blocklen = mc_read (file, (char *) buf, TEMP_BUF_LEN)) > 0) {
134
 	    for (i = 0; i < blocklen; i++)
135
 		edit_insert (edit, buf[i]);
136
+#else /* UTF8 */
137
+	while ((blocklen = mc_read (file, (char *) buf + bufstart, TEMP_BUF_LEN - bufstart)) > 0) {
138
+	    blocklen += bufstart;
139
+	    bufstart = 0;
140
+	    for (i = 0; i < blocklen; ) {
141
+		mc_wchar_t wc;
142
+		int j;
143
+	        int size = mbrtowc(&wc, (char *)buf + i, blocklen - i, &mbs);
144
+		if (size == -2) { /*incomplete char*/
145
+		    bufstart = blocklen - i;
146
+		    memcpy(buf, buf+i, bufstart);
147
+		    i = blocklen;
148
+		    memset (&mbs, 0, sizeof (mbs));
149
+		}
150
+		else if (size <= 0) {
151
+#ifdef __STDC_ISO_10646__
152
+		    edit_insert (edit, BINARY_CHAR_OFFSET + (mc_wchar_t)buf[i]);
153
+#endif
154
+		    memset (&mbs, 0, sizeof (mbs));
155
+		    i++; /* skip broken char */
156
+		}
157
+		else {
158
+		    edit_insert (edit, wc);
159
+		    i+=size;
160
+		}
161
+	    }
162
+#endif /* UTF8 */
163
 	}
164
 	edit_cursor_move (edit, current - edit->curs1);
165
 	g_free (buf);
166
@@ -393,7 +485,11 @@
167
 static int
168
 edit_load_file (WEdit *edit)
169
 {
170
+#ifndef UTF8
171
     int fast_load = 1;
172
+#else /* UTF8 */
173
+    int fast_load = 0; /* can't be used with multibyte characters */
174
+#endif /* UTF8 */
175
 
176
     /* Cannot do fast load if a filter is used */
177
     if (edit_find_filter (edit->filename) >= 0)
178
@@ -540,7 +636,7 @@
179
     edit_set_filename (edit, filename);
180
     edit->stack_size = START_STACK_SIZE;
181
     edit->stack_size_mask = START_STACK_SIZE - 1;
182
-    edit->undo_stack = g_malloc ((edit->stack_size + 10) * sizeof (long));
183
+    edit->undo_stack = g_malloc ((edit->stack_size + 10) * sizeof (struct action));
184
     if (edit_load_file (edit)) {
185
 	/* edit_load_file already gives an error message */
186
 	if (to_free)
187
@@ -565,7 +661,9 @@
188
 	edit_move_display (edit, line - 1);
189
 	edit_move_to_line (edit, line - 1);
190
     }
191
-
192
+#ifdef UTF8
193
+    edit->charpoint = 0;
194
+#endif
195
     return edit;
196
 }
197
 
198
@@ -693,13 +789,23 @@
199
 {
200
     unsigned long sp = edit->stack_pointer;
201
     unsigned long spm1;
202
-    long *t;
203
+  
204
+    struct action *t; 
205
+    mc_wchar_t ch = 0; 
206
+
207
+    if (c == CHAR_INSERT || c == CHAR_INSERT_AHEAD) { 
208
+      va_list ap; 
209
+      va_start (ap, c); 
210
+      ch = va_arg (ap, mc_wint_t); 
211
+      va_end (ap); 
212
+    } 
213
+
214
 /* first enlarge the stack if necessary */
215
     if (sp > edit->stack_size - 10) {	/* say */
216
 	if (option_max_undo < 256)
217
 	    option_max_undo = 256;
218
 	if (edit->stack_size < (unsigned long) option_max_undo) {
219
-	    t = g_realloc (edit->undo_stack, (edit->stack_size * 2 + 10) * sizeof (long));
220
+	    t = g_realloc (edit->undo_stack, (edit->stack_size * 2 + 10) * sizeof (struct action));
221
 	    if (t) {
222
 		edit->undo_stack = t;
223
 		edit->stack_size <<= 1;
224
@@ -714,7 +820,7 @@
225
 #ifdef FAST_MOVE_CURSOR
226
     if (c == CURS_LEFT_LOTS || c == CURS_RIGHT_LOTS) {
227
 	va_list ap;
228
-	edit->undo_stack[sp] = c == CURS_LEFT_LOTS ? CURS_LEFT : CURS_RIGHT;
229
+	edit->undo_stack[sp].flags = c == CURS_LEFT_LOTS ? CURS_LEFT : CURS_RIGHT;
230
 	edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask;
231
 	va_start (ap, c);
232
 	c = -(va_arg (ap, int));
233
@@ -725,12 +831,14 @@
234
 	&& spm1 != edit->stack_bottom
235
 	&& ((sp - 2) & edit->stack_size_mask) != edit->stack_bottom) {
236
 	int d;
237
-	if (edit->undo_stack[spm1] < 0) {
238
-	    d = edit->undo_stack[(sp - 2) & edit->stack_size_mask];
239
-	    if (d == c) {
240
-		if (edit->undo_stack[spm1] > -1000000000) {
241
+	mc_wchar_t d_ch;
242
+	if (edit->undo_stack[spm1].flags < 0) {
243
+	    d    = edit->undo_stack[(sp - 2) & edit->stack_size_mask].flags;
244
+	    d_ch = edit->undo_stack[(sp - 2) & edit->stack_size_mask].ch;
245
+	    if (d == c && d_ch == ch) {
246
+		if (edit->undo_stack[spm1].flags > -1000000000) {
247
 		    if (c < KEY_PRESS)	/* --> no need to push multiple do-nothings */
248
-			edit->undo_stack[spm1]--;
249
+			edit->undo_stack[spm1].flags--;
250
 		    return;
251
 		}
252
 	    }
253
@@ -738,19 +846,20 @@
254
 #ifndef NO_STACK_CURSMOVE_ANIHILATION
255
 	    else if ((c == CURS_LEFT && d == CURS_RIGHT)
256
 		     || (c == CURS_RIGHT && d == CURS_LEFT)) {	/* a left then a right anihilate each other */
257
-		if (edit->undo_stack[spm1] == -2)
258
+		if (edit->undo_stack[spm1].flags == -2)
259
 		    edit->stack_pointer = spm1;
260
 		else
261
-		    edit->undo_stack[spm1]++;
262
+		    edit->undo_stack[spm1].flags++;
263
 		return;
264
 	    }
265
 #endif
266
 	} else {
267
-	    d = edit->undo_stack[spm1];
268
-	    if (d == c) {
269
+	    d    = edit->undo_stack[spm1].flags;
270
+	    d_ch = edit->undo_stack[spm1].ch;
271
+	    if (d == c && d_ch == ch) {
272
 		if (c >= KEY_PRESS)
273
 		    return;	/* --> no need to push multiple do-nothings */
274
-		edit->undo_stack[sp] = -2;
275
+		edit->undo_stack[sp].flags = -2;
276
 		goto check_bottom;
277
 	    }
278
 #ifndef NO_STACK_CURSMOVE_ANIHILATION
279
@@ -762,7 +871,9 @@
280
 #endif
281
 	}
282
     }
283
-    edit->undo_stack[sp] = c;
284
+    edit->undo_stack[sp].flags = c;
285
+    edit->undo_stack[sp].ch = ch;
286
+
287
   check_bottom:
288
 
289
     edit->stack_pointer = (edit->stack_pointer + 1) & edit->stack_size_mask;
290
@@ -775,10 +886,10 @@
291
        (((unsigned long) c + 1) & edit->stack_size_mask) == edit->stack_bottom)
292
 	do {
293
 	    edit->stack_bottom = (edit->stack_bottom + 1) & edit->stack_size_mask;
294
-	} while (edit->undo_stack[edit->stack_bottom] < KEY_PRESS && edit->stack_bottom != edit->stack_pointer);
295
+	} while (edit->undo_stack[edit->stack_bottom].flags < KEY_PRESS && edit->stack_bottom != edit->stack_pointer);
296
 
297
 /*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: */
298
-    if (edit->stack_pointer != edit->stack_bottom && edit->undo_stack[edit->stack_bottom] < KEY_PRESS)
299
+    if (edit->stack_pointer != edit->stack_bottom && edit->undo_stack[edit->stack_bottom].flags < KEY_PRESS)
300
 	edit->stack_bottom = edit->stack_pointer = 0;
301
 }
302
 
303
@@ -787,30 +898,30 @@
304
    then the file should be as it was when he loaded up. Then set edit->modified to 0.
305
  */
306
 static long
307
-pop_action (WEdit * edit)
308
+pop_action (WEdit * edit, struct action *c)
309
 {
310
-    long c;
311
     unsigned long sp = edit->stack_pointer;
312
     if (sp == edit->stack_bottom) {
313
-	return STACK_BOTTOM;
314
+	c->flags = STACK_BOTTOM;
315
+	return c->flags;
316
     }
317
     sp = (sp - 1) & edit->stack_size_mask;
318
-    if ((c = edit->undo_stack[sp]) >= 0) {
319
-/*	edit->undo_stack[sp] = '@'; */
320
+    *c = edit->undo_stack[sp];
321
+    if (edit->undo_stack[sp].flags >= 0) {
322
 	edit->stack_pointer = (edit->stack_pointer - 1) & edit->stack_size_mask;
323
-	return c;
324
+	return c->flags;
325
     }
326
     if (sp == edit->stack_bottom) {
327
 	return STACK_BOTTOM;
328
     }
329
-    c = edit->undo_stack[(sp - 1) & edit->stack_size_mask];
330
-    if (edit->undo_stack[sp] == -2) {
331
-/*      edit->undo_stack[sp] = '@'; */
332
+    *c = edit->undo_stack[(sp - 1) & edit->stack_size_mask];
333
+
334
+    if (edit->undo_stack[sp].flags == -2) {
335
 	edit->stack_pointer = sp;
336
     } else
337
-	edit->undo_stack[sp]++;
338
+	edit->undo_stack[sp].flags++;
339
 
340
-    return c;
341
+    return c->flags;
342
 }
343
 
344
 /* is called whenever a modification is made by one of the four routines below */
345
@@ -831,7 +942,7 @@
346
  */
347
 
348
 void
349
-edit_insert (WEdit *edit, int c)
350
+edit_insert (WEdit *edit, mc_wchar_t c)
351
 {
352
     /* check if file has grown to large */
353
     if (edit->last_byte >= SIZE_LIMIT)
354
@@ -869,12 +980,11 @@
355
     /* add a new buffer if we've reached the end of the last one */
356
     if (!(edit->curs1 & M_EDIT_BUF_SIZE))
357
 	edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] =
358
-	    g_malloc (EDIT_BUF_SIZE);
359
+	    g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
360
 
361
     /* perform the insertion */
362
-    edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE][edit->
363
-						   curs1 & M_EDIT_BUF_SIZE]
364
-	= (unsigned char) c;
365
+    edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE]
366
+		    [edit->curs1 & M_EDIT_BUF_SIZE] = c;
367
 
368
     /* update file length */
369
     edit->last_byte++;
370
@@ -885,7 +995,7 @@
371
 
372
 
373
 /* same as edit_insert and move left */
374
-void edit_insert_ahead (WEdit * edit, int c)
375
+void edit_insert_ahead (WEdit * edit, mc_wchar_t c)
376
 {
377
     if (edit->last_byte >= SIZE_LIMIT)
378
 	return;
379
@@ -908,7 +1018,7 @@
380
     edit->last_get_rule += (edit->last_get_rule >= edit->curs1);
381
 
382
     if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE))
383
-	edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE);
384
+	edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
385
     edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1] = c;
386
 
387
     edit->last_byte++;
388
@@ -918,7 +1028,7 @@
389
 
390
 int edit_delete (WEdit * edit)
391
 {
392
-    int p;
393
+    mc_wint_t p;
394
     if (!edit->curs2)
395
 	return 0;
396
 
397
@@ -942,7 +1052,7 @@
398
 	edit->total_lines--;
399
 	edit->force |= REDRAW_AFTER_CURSOR;
400
     }
401
-    edit_push_action (edit, p + 256);
402
+    edit_push_action (edit, CHAR_INSERT_AHEAD, p);
403
     if (edit->curs1 < edit->start_display) {
404
 	edit->start_display--;
405
 	if (p == '\n')
406
@@ -956,7 +1066,7 @@
407
 static int
408
 edit_backspace (WEdit * edit)
409
 {
410
-    int p;
411
+    mc_wint_t p;
412
     if (!edit->curs1)
413
 	return 0;
414
 
415
@@ -980,7 +1090,7 @@
416
 	edit->total_lines--;
417
 	edit->force |= REDRAW_AFTER_CURSOR;
418
     }
419
-    edit_push_action (edit, p);
420
+    edit_push_action (edit, CHAR_INSERT, p);
421
 
422
     if (edit->curs1 < edit->start_display) {
423
 	edit->start_display--;
424
@@ -993,10 +1103,18 @@
425
 
426
 #ifdef FAST_MOVE_CURSOR
427
 
428
-static void memqcpy (WEdit * edit, unsigned char *dest, unsigned char *src, int n)
429
+static void memqcpy (WEdit * edit, mc_wchar_t *dest, mc_wchar_t *src, int n)
430
 {
431
     unsigned long next;
432
+#ifndef UTF8
433
     while ((next = (unsigned long) memccpy (dest, src, '\n', n))) {
434
+#else /* UTF8 */
435
+    while (n) {
436
+	next = 0;
437
+	while (next < n && src[next]!='\n') next++;
438
+	if (next < n) next++;
439
+        wmemcpy (dest, src, next)
440
+#endif /* UTF8 */
441
 	edit->curs_line--;
442
 	next -= (unsigned long) dest;
443
 	n -= next;
444
@@ -1009,7 +1127,7 @@
445
 edit_move_backward_lots (WEdit *edit, long increment)
446
 {
447
     int r, s, t;
448
-    unsigned char *p;
449
+    mc_wchar_t *p;
450
 
451
     if (increment > edit->curs1)
452
 	increment = edit->curs1;
453
@@ -1049,7 +1167,7 @@
454
 	    edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p;
455
 	else
456
 	    edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] =
457
-		g_malloc (EDIT_BUF_SIZE);
458
+		g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
459
     } else {
460
 	g_free (p);
461
     }
462
@@ -1087,7 +1205,7 @@
463
 		edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] = p;
464
 	    else
465
 		edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE] =
466
-		    g_malloc (EDIT_BUF_SIZE);
467
+		    g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
468
 	} else {
469
 	    g_free (p);
470
 	}
471
@@ -1119,7 +1237,7 @@
472
 
473
 	    c = edit_get_byte (edit, edit->curs1 - 1);
474
 	    if (!((edit->curs2 + 1) & M_EDIT_BUF_SIZE))
475
-		edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE);
476
+		edit->buffers2[(edit->curs2 + 1) >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
477
 	    edit->buffers2[edit->curs2 >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (edit->curs2 & M_EDIT_BUF_SIZE) - 1] = c;
478
 	    edit->curs2++;
479
 	    c = edit->buffers1[(edit->curs1 - 1) >> S_EDIT_BUF_SIZE][(edit->curs1 - 1) & M_EDIT_BUF_SIZE];
480
@@ -1144,7 +1262,7 @@
481
 
482
 	    c = edit_get_byte (edit, edit->curs1);
483
 	    if (!(edit->curs1 & M_EDIT_BUF_SIZE))
484
-		edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE);
485
+		edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE] = g_malloc (EDIT_BUF_SIZE * sizeof(mc_wchar_t));
486
 	    edit->buffers1[edit->curs1 >> S_EDIT_BUF_SIZE][edit->curs1 & M_EDIT_BUF_SIZE] = c;
487
 	    edit->curs1++;
488
 	    c = edit->buffers2[(edit->curs2 - 1) >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - ((edit->curs2 - 1) & M_EDIT_BUF_SIZE) - 1];
489
@@ -1251,7 +1369,7 @@
490
 	q = edit->last_byte + 2;
491
 
492
     for (col = 0, p = current; p < q; p++) {
493
-	int c;
494
+	mc_wchar_t c;
495
 	if (cols != -10) {
496
 	    if (col == cols)
497
 		return p;
498
@@ -1269,7 +1387,7 @@
499
 	} else if (c < 32 || c == 127)
500
 	    col += 2; /* Caret notation for control characters */
501
 	else
502
-	    col++;
503
+	    col += wcwidth(c);
504
     }
505
     return col;
506
 }
507
@@ -1402,7 +1520,7 @@
508
 is_blank (WEdit *edit, long offset)
509
 {
510
     long s, f;
511
-    int c;
512
+    mc_wchar_t c;
513
     s = edit_bol (edit, offset);
514
     f = edit_eol (edit, offset) - 1;
515
     while (s <= f) {
516
@@ -1774,13 +1892,13 @@
517
 static void
518
 edit_do_undo (WEdit * edit)
519
 {
520
-    long ac;
521
+    struct action ac;
522
     long count = 0;
523
 
524
     edit->stack_disable = 1;	/* don't record undo's onto undo stack! */
525
 
526
-    while ((ac = pop_action (edit)) < KEY_PRESS) {
527
-	switch ((int) ac) {
528
+    while (pop_action (edit, &ac) < KEY_PRESS) {
529
+	switch ((int) ac.flags) {
530
 	case STACK_BOTTOM:
531
 	    goto done_undo;
532
 	case CURS_RIGHT:
533
@@ -1801,31 +1919,33 @@
534
 	case COLUMN_OFF:
535
 	    column_highlighting = 0;
536
 	    break;
537
+	case CHAR_INSERT:
538
+	    edit_insert (edit, ac.ch);
539
+	    break;
540
+	case CHAR_INSERT_AHEAD:
541
+	    edit_insert_ahead (edit, ac.ch);
542
+	    break;
543
 	}
544
-	if (ac >= 256 && ac < 512)
545
-	    edit_insert_ahead (edit, ac - 256);
546
-	if (ac >= 0 && ac < 256)
547
-	    edit_insert (edit, ac);
548
 
549
-	if (ac >= MARK_1 - 2 && ac < MARK_2 - 2) {
550
-	    edit->mark1 = ac - MARK_1;
551
+	if (ac.flags >= MARK_1 - 2 && ac.flags < MARK_2 - 2) {
552
+	    edit->mark1 = ac.flags - MARK_1;
553
 	    edit->column1 = edit_move_forward3 (edit, edit_bol (edit, edit->mark1), 0, edit->mark1);
554
-	} else if (ac >= MARK_2 - 2 && ac < KEY_PRESS) {
555
-	    edit->mark2 = ac - MARK_2;
556
+	} else if (ac.flags >= MARK_2 - 2 && ac.flags < KEY_PRESS) {
557
+	    edit->mark2 = ac.flags - MARK_2;
558
 	    edit->column2 = edit_move_forward3 (edit, edit_bol (edit, edit->mark2), 0, edit->mark2);
559
 	}
560
 	if (count++)
561
 	    edit->force |= REDRAW_PAGE;		/* more than one pop usually means something big */
562
     }
563
 
564
-    if (edit->start_display > ac - KEY_PRESS) {
565
-	edit->start_line -= edit_count_lines (edit, ac - KEY_PRESS, edit->start_display);
566
+    if (edit->start_display > ac.flags - KEY_PRESS) {
567
+	edit->start_line -= edit_count_lines (edit, ac.flags - KEY_PRESS, edit->start_display);
568
 	edit->force |= REDRAW_PAGE;
569
-    } else if (edit->start_display < ac - KEY_PRESS) {
570
-	edit->start_line += edit_count_lines (edit, edit->start_display, ac - KEY_PRESS);
571
+    } else if (edit->start_display < ac.flags - KEY_PRESS) {
572
+	edit->start_line += edit_count_lines (edit, edit->start_display, ac.flags - KEY_PRESS);
573
 	edit->force |= REDRAW_PAGE;
574
     }
575
-    edit->start_display = ac - KEY_PRESS;	/* see push and pop above */
576
+    edit->start_display = ac.flags - KEY_PRESS;	/* see push and pop above */
577
     edit_update_curs_row (edit);
578
 
579
   done_undo:;
580
@@ -2102,7 +2222,7 @@
581
  * passed as -1.  Commands are executed, and char_for_insertion is
582
  * inserted at the cursor.
583
  */
584
-void edit_execute_key_command (WEdit *edit, int command, int char_for_insertion)
585
+void edit_execute_key_command (WEdit *edit, int command, mc_wint_t char_for_insertion)
586
 {
587
     if (command == CK_Begin_Record_Macro) {
588
 	edit->macro_i = 0;
589
@@ -2137,7 +2257,7 @@
590
    all of them. It also does not check for the Undo command.
591
  */
592
 void
593
-edit_execute_cmd (WEdit *edit, int command, int char_for_insertion)
594
+edit_execute_cmd (WEdit *edit, int command, mc_wint_t char_for_insertion)
595
 {
596
     edit->force |= REDRAW_LINE;
597
 
598
@@ -2170,7 +2290,7 @@
599
     }
600
 
601
     /* An ordinary key press */
602
-    if (char_for_insertion >= 0) {
603
+    if (char_for_insertion != (mc_wint_t) -1) {
604
 	if (edit->overwrite) {
605
 	    if (edit_get_byte (edit, edit->curs1) != '\n')
606
 		edit_delete (edit);
607
diff -Naur mc-4.6.1-old/edit/editcmd.c mc-4.6.1/edit/editcmd.c
608
--- mc-4.6.1-old/edit/editcmd.c	2005-05-27 16:19:18.000000000 +0200
609
+++ mc-4.6.1/edit/editcmd.c	2005-10-28 10:08:07.687254712 +0200
610
@@ -46,7 +46,7 @@
611
 #define edit_get_save_file(f,h) input_expand_dialog (h, _(" Enter file name: "), f)
612
 
613
 struct selection {
614
-   unsigned char * text;
615
+   mc_wchar_t *text;
616
    int len;
617
 };
618
 
619
@@ -69,12 +69,16 @@
620
 #define MAX_REPL_LEN 1024
621
 
622
 static int edit_save_cmd (WEdit *edit);
623
-static unsigned char *edit_get_block (WEdit *edit, long start,
624
+static mc_wchar_t *edit_get_block (WEdit *edit, long start,
625
 				      long finish, int *l);
626
 
627
-static inline int my_lower_case (int c)
628
+static inline mc_wchar_t my_lower_case (mc_wchar_t c)
629
 {
630
+#ifndef UTF8
631
     return tolower(c & 0xFF);
632
+#else
633
+    return towlower(c);
634
+#endif    
635
 }
636
 
637
 static const char *strcasechr (const unsigned char *s, int c)
638
@@ -108,11 +112,11 @@
639
 #endif /* !HAVE_MEMMOVE */
640
 
641
 /* #define itoa MY_itoa  <---- this line is now in edit.h */
642
-static char *
643
+static mc_wchar_t *
644
 MY_itoa (int i)
645
 {
646
-    static char t[14];
647
-    char *s = t + 13;
648
+    static mc_wchar_t t[14];
649
+    mc_wchar_t *s = t + 13;
650
     int j = i;
651
     *s-- = 0;
652
     do {
653
@@ -196,6 +200,48 @@
654
     doupdate();
655
 }
656
 
657
+#ifdef UTF8
658
+
659
+static size_t
660
+wchar_write(int fd, mc_wchar_t *buf, size_t len)
661
+{
662
+    char *tmpbuf = g_malloc(len + MB_LEN_MAX);
663
+    mbstate_t mbs;
664
+    size_t i;
665
+    size_t outlen = 0;
666
+    size_t res;
667
+
668
+    for (i = 0; i < len; i++) {
669
+	if (outlen >= len) {
670
+	    if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) {
671
+		g_free(tmpbuf);
672
+		return -1;
673
+	    }
674
+	    outlen = 0;
675
+	}
676
+	memset (&mbs, 0, sizeof (mbs));
677
+#ifdef __STDC_ISO_10646__ 
678
+	if (buf[i] >= BINARY_CHAR_OFFSET && buf[i] < (BINARY_CHAR_OFFSET + 256)) {
679
+	    res = 1;
680
+	    tmpbuf[outlen] = (char) (buf[i] - BINARY_CHAR_OFFSET);
681
+
682
+	} else
683
+#endif
684
+	res = wcrtomb(tmpbuf + outlen, buf[i], &mbs);
685
+	if (res > 0) {
686
+	    outlen += res;
687
+	}
688
+    }
689
+    if ((res = mc_write(fd, tmpbuf, outlen)) != outlen) {
690
+	g_free(tmpbuf);
691
+	return -1;
692
+    }
693
+    g_free(tmpbuf);
694
+    return len;
695
+}
696
+
697
+#endif /* UTF8 */
698
+
699
 /*  If 0 (quick save) then  a) create/truncate <filename> file,
700
 			    b) save to <filename>;
701
     if 1 (safe save) then   a) save to <tempnam>,
702
@@ -303,32 +349,48 @@
703
 	buf = 0;
704
 	filelen = edit->last_byte;
705
 	while (buf <= (edit->curs1 >> S_EDIT_BUF_SIZE) - 1) {
706
+#ifndef UTF8
707
 	    if (mc_write (fd, (char *) edit->buffers1[buf], EDIT_BUF_SIZE)
708
+#else /* UTF8 */
709
+	    if (wchar_write (fd, edit->buffers1[buf], EDIT_BUF_SIZE)
710
+#endif /* UTF8 */
711
 		!= EDIT_BUF_SIZE) {
712
 		mc_close (fd);
713
 		goto error_save;
714
 	    }
715
 	    buf++;
716
 	}
717
+#ifndef UTF8
718
 	if (mc_write
719
 	    (fd, (char *) edit->buffers1[buf],
720
+#else /* UTF8 */
721
+	if (wchar_write
722
+	    (fd, edit->buffers1[buf],
723
+#endif /* UTF8 */
724
 	     edit->curs1 & M_EDIT_BUF_SIZE) !=
725
 	    (edit->curs1 & M_EDIT_BUF_SIZE)) {
726
 	    filelen = -1;
727
 	} else if (edit->curs2) {
728
 	    edit->curs2--;
729
 	    buf = (edit->curs2 >> S_EDIT_BUF_SIZE);
730
-	    if (mc_write
731
-		(fd,
732
-		 (char *) edit->buffers2[buf] + EDIT_BUF_SIZE -
733
+#ifndef UTF8
734
+	    if (mc_write(fd, (char *) edit->buffers2[buf] + EDIT_BUF_SIZE -
735
+#else /* UTF8 */
736
+	    if (wchar_write(fd, edit->buffers2[buf] + EDIT_BUF_SIZE -
737
+#endif /* UTF8 */
738
 		 (edit->curs2 & M_EDIT_BUF_SIZE) - 1,
739
 		 1 + (edit->curs2 & M_EDIT_BUF_SIZE)) !=
740
 		1 + (edit->curs2 & M_EDIT_BUF_SIZE)) {
741
 		filelen = -1;
742
 	    } else {
743
 		while (--buf >= 0) {
744
+#ifndef UTF8
745
 		    if (mc_write
746
 			(fd, (char *) edit->buffers2[buf],
747
+#else /* UTF8 */
748
+		    if (wchar_write
749
+			(fd, edit->buffers2[buf],
750
+#endif /* UTF8 */
751
 			 EDIT_BUF_SIZE) != EDIT_BUF_SIZE) {
752
 			filelen = -1;
753
 			break;
754
@@ -643,13 +705,21 @@
755
 	if (!n || n == EOF)
756
 	    break;
757
 	n = 0;
758
+#ifndef UTF8
759
 	while (fscanf (f, "%hd %hd, ", &macro[n].command, &macro[n].ch))
760
+#else /* UTF8 */
761
+	while (fscanf (f, "%hd %lu, ", &macro[n].command, &macro[n].ch))
762
+#endif /* UTF8 */
763
 	    n++;
764
 	fscanf (f, ";\n");
765
 	if (s != k) {
766
 	    fprintf (g, ("key '%d 0': "), s);
767
 	    for (i = 0; i < n; i++)
768
+#ifndef UTF8
769
 		fprintf (g, "%hd %hd, ", macro[i].command, macro[i].ch);
770
+#else /* UTF8 */
771
+		fprintf (g, "%hd %lu, ", macro[i].command, macro[i].ch);
772
+#endif /* UTF8 */
773
 	    fprintf (g, ";\n");
774
 	}
775
     }
776
@@ -685,7 +755,11 @@
777
 	if (f) {
778
 	    fprintf (f, ("key '%d 0': "), s);
779
 	    for (i = 0; i < n; i++)
780
+#ifndef UTF8
781
 		fprintf (f, "%hd %hd, ", macro[i].command, macro[i].ch);
782
+#else /* UTF8 */
783
+		fprintf (f, "%hd %lu, ", macro[i].command, macro[i].ch);
784
+#endif /* UTF8 */
785
 	    fprintf (f, ";\n");
786
 	    fclose (f);
787
 	    if (saved_macros_loaded) {
788
@@ -734,10 +808,18 @@
789
 		saved_macro[i++] = s;
790
 	    if (!found) {
791
 		*n = 0;
792
+#ifndef UTF8
793
 		while (*n < MAX_MACRO_LENGTH && 2 == fscanf (f, "%hd %hd, ", &macro[*n].command, &macro[*n].ch))
794
+#else /* UTF8 */
795
+		while (*n < MAX_MACRO_LENGTH && 2 == fscanf (f, "%hd %lu, ", &macro[*n].command, &macro[*n].ch))
796
+#endif /* UTF8 */
797
 		    (*n)++;
798
 	    } else {
799
+#ifndef UTF8
800
 		while (2 == fscanf (f, "%hd %hd, ", &dummy.command, &dummy.ch));
801
+#else /* UTF8 */
802
+		while (2 == fscanf (f, "%hd %lu, ", &dummy.command, &dummy.ch));
803
+#endif /* UTF8 */
804
 	    }
805
 	    fscanf (f, ";\n");
806
 	    if (s == k)
807
@@ -886,7 +968,7 @@
808
 #define space_width 1
809
 
810
 static void
811
-edit_insert_column_of_text (WEdit * edit, unsigned char *data, int size, int width)
812
+edit_insert_column_of_text (WEdit * edit, mc_wchar_t *data, int size, int width)
813
 {
814
     long cursor;
815
     int i, col;
816
@@ -934,7 +1016,7 @@
817
 {
818
     long start_mark, end_mark, current = edit->curs1;
819
     int size, x;
820
-    unsigned char *copy_buf;
821
+    mc_wchar_t *copy_buf;
822
 
823
     edit_update_curs_col (edit);
824
     x = edit->curs_col;
825
@@ -979,7 +1061,7 @@
826
 {
827
     long count;
828
     long current;
829
-    unsigned char *copy_buf;
830
+    mc_wchar_t *copy_buf;
831
     long start_mark, end_mark;
832
     int deleted = 0;
833
     int x = 0;
834
@@ -1040,7 +1122,7 @@
835
 	edit_push_action (edit, COLUMN_ON);
836
 	column_highlighting = 0;
837
     } else {
838
-	copy_buf = g_malloc (end_mark - start_mark);
839
+	copy_buf = g_malloc ((end_mark - start_mark) * sizeof(mc_wchar_t));
840
 	edit_cursor_move (edit, start_mark - edit->curs1);
841
 	edit_scroll_screen_over_cursor (edit);
842
 	count = start_mark;
843
@@ -1371,7 +1453,11 @@
844
 /* This function is a modification of mc-3.2.10/src/view.c:regexp_view_search() */
845
 /* returns -3 on error in pattern, -1 on not found, found_len = 0 if either */
846
 static int
847
+#ifndef UTF8
848
 string_regexp_search (char *pattern, char *string, int len, int match_type,
849
+#else /* UTF8 */
850
+string_regexp_search (char *pattern, mc_wchar_t *wstring, int match_type,
851
+#endif /* UTF8 */
852
 		      int match_bol, int icase, int *found_len, void *d)
853
 {
854
     static regex_t r;
855
@@ -1380,6 +1466,11 @@
856
     regmatch_t *pmatch;
857
     static regmatch_t s[1];
858
 
859
+#ifdef UTF8
860
+    char *string;
861
+    int i;
862
+#endif /* UTF8 */
863
+
864
     pmatch = (regmatch_t *) d;
865
     if (!pmatch)
866
 	pmatch = s;
867
@@ -1399,13 +1490,51 @@
868
 	old_type = match_type;
869
 	old_icase = icase;
870
     }
871
+
872
+#ifdef UTF8
873
+    string = wchar_to_mbstr(wstring);
874
+    if (string == NULL)
875
+	return -1;
876
+#endif /* UTF8 */
877
+
878
     if (regexec
879
 	(&r, string, d ? NUM_REPL_ARGS : 1, pmatch,
880
 	 ((match_bol
881
 	   || match_type != match_normal) ? 0 : REG_NOTBOL)) != 0) {
882
 	*found_len = 0;
883
+
884
+#ifdef UTF8
885
+	g_free(string);
886
+#endif /* UTF8 */
887
+
888
 	return -1;
889
     }
890
+
891
+#ifdef UTF8
892
+    for (i = 0; i < (d ? NUM_REPL_ARGS : 1); i++) {
893
+	char tmp;
894
+	int new_o;
895
+
896
+	if (pmatch[i].rm_so < 0)
897
+	    continue;
898
+	tmp = string[pmatch[i].rm_so];
899
+	string[pmatch[i].rm_so] = 0;
900
+	new_o = mbstrlen(string);
901
+	string[pmatch[i].rm_so] = tmp;
902
+	pmatch[i].rm_so = new_o; 
903
+
904
+	if (pmatch[i].rm_eo < 0)
905
+	    continue;
906
+	tmp = string[pmatch[i].rm_eo];
907
+	string[pmatch[i].rm_eo] = 0;
908
+	new_o = mbstrlen(string);
909
+	string[pmatch[i].rm_eo] = tmp;
910
+	pmatch[i].rm_eo = new_o; 
911
+    }
912
+
913
+    g_free(string);
914
+#endif /* UTF8 */
915
+
916
     *found_len = pmatch[0].rm_eo - pmatch[0].rm_so;
917
     return (pmatch[0].rm_so);
918
 }
919
@@ -1413,13 +1542,29 @@
920
 /* thanks to  Liviu Daia <daia@stoilow.imar.ro>  for getting this
921
    (and the above) routines to work properly - paul */
922
 
923
+#ifndef UTF8
924
 typedef int (*edit_getbyte_fn) (WEdit *, long);
925
+#else /* UTF8 */
926
+typedef mc_wchar_t (*edit_getbyte_fn) (WEdit *, long);
927
+#endif /* UTF8 */
928
 
929
 static long
930
+#ifndef UTF8
931
 edit_find_string (long start, unsigned char *exp, int *len, long last_byte, edit_getbyte_fn get_byte, void *data, int once_only, void *d)
932
+#else /* UTF8 */
933
+edit_find_string (long start, unsigned char *exp_mb, int *len, long last_byte, edit_getbyte_fn get_byte, void *data, int once_only, void *d)
934
+#endif /* UTF8 */
935
 {
936
     long p, q = 0;
937
-    long l = strlen ((char *) exp), f = 0;
938
+    long f = 0;
939
+
940
+#ifndef UTF8
941
+    long l = strlen ((char *) exp);
942
+#else /* UTF8 */
943
+    mc_wchar_t *exp = mbstr_to_wchar((char *)exp_mb);
944
+    mc_wchar_t *exp_backup = exp;
945
+    long l = wcslen(exp);
946
+#endif /* UTF8 */
947
     int n = 0;
948
 
949
     for (p = 0; p < l; p++)	/* count conversions... */
950
@@ -1428,19 +1573,22 @@
951
 		n++;
952
 
953
     if (replace_scanf || replace_regexp) {
954
-	int c;
955
-	unsigned char *buf;
956
-	unsigned char mbuf[MAX_REPL_LEN * 2 + 3];
957
+	mc_wint_t c;
958
+	mc_wchar_t *buf;
959
+	mc_wchar_t mbuf[MAX_REPL_LEN * 2 + 3];
960
 
961
 	replace_scanf = (!replace_regexp);	/* can't have both */
962
 
963
 	buf = mbuf;
964
 
965
 	if (replace_scanf) {
966
-	    unsigned char e[MAX_REPL_LEN];
967
-	    if (n >= NUM_REPL_ARGS)
968
-		return -3;
969
-
970
+	    mc_wchar_t e[MAX_REPL_LEN];
971
+	    if (n >= NUM_REPL_ARGS) {
972
+#ifdef UTF8
973
+                g_free(exp_backup);
974
+#endif /* UTF8 */
975
+                return -3;
976
+	    }
977
 	    if (replace_case) {
978
 		for (p = start; p < last_byte && p < start + MAX_REPL_LEN; p++)
979
 		    buf[p - start] = (*get_byte) (data, p);
980
@@ -1454,20 +1602,36 @@
981
 	    }
982
 
983
 	    buf[(q = p - start)] = 0;
984
+#ifndef UTF8
985
 	    strcpy ((char *) e, (char *) exp);
986
 	    strcat ((char *) e, "%n");
987
+#else /* UTF8 */
988
+	    wcscpy (e, exp);
989
+	    wcscat (e, L"%n");
990
+#endif /* UTF8 */
991
 	    exp = e;
992
 
993
 	    while (q) {
994
 		*((int *) sargs[n]) = 0;	/* --> here was the problem - now fixed: good */
995
+#ifndef UTF8
996
 		if (n == sscanf ((char *) buf, (char *) exp, SCANF_ARGS)) {
997
+#else /* UTF8 */
998
+		if (n == swscanf (buf, exp, SCANF_ARGS)) {
999
+#endif /* UTF8 */
1000
 		    if (*((int *) sargs[n])) {
1001
 			*len = *((int *) sargs[n]);
1002
+#ifdef UTF8
1003
+			g_free(exp_backup);
1004
+#endif /* UTF8 */
1005
 			return start;
1006
 		    }
1007
 		}
1008
-		if (once_only)
1009
+		if (once_only) {
1010
+#ifdef UTF8
1011
+		    g_free(exp_backup);
1012
+#endif /* UTF8 */
1013
 		    return -2;
1014
+		}
1015
 		if (q + start < last_byte) {
1016
 		    if (replace_case) {
1017
 			buf[q] = (*get_byte) (data, q + start);
1018
@@ -1481,7 +1645,11 @@
1019
 		start++;
1020
 		buf++;		/* move the window along */
1021
 		if (buf == mbuf + MAX_REPL_LEN) {	/* the window is about to go past the end of array, so... */
1022
+#ifndef UTF8
1023
 		    memmove (mbuf, buf, strlen ((char *) buf) + 1);	/* reset it */
1024
+#else /* UTF8 */
1025
+		    wmemmove (mbuf, buf, (wcslen (buf) + 1));	/* reset it */
1026
+#endif /* UTF8 */
1027
 		    buf = mbuf;
1028
 		}
1029
 		q--;
1030
@@ -1507,10 +1675,17 @@
1031
 
1032
 		buf = mbuf;
1033
 		while (q) {
1034
+#ifndef UTF8
1035
 		    found_start = string_regexp_search ((char *) exp, (char *) buf, q, match_normal, match_bol, !replace_case, len, d);
1036
+#else /* UTF8 */
1037
+                    found_start = string_regexp_search ((char *) exp_mb, buf, match_normal, match_bol, !replace_case, len, d);
1038
+#endif /* UTF8 */
1039
 
1040
 		    if (found_start <= -2) {	/* regcomp/regexec error */
1041
 			*len = 0;
1042
+#ifdef UTF8
1043
+                        g_free (exp_backup);
1044
+#endif /* UTF8 */
1045
 			return -3;
1046
 		    }
1047
 		    else if (found_start == -1)	/* not found: try next line */
1048
@@ -1521,15 +1696,27 @@
1049
 			match_bol = 0;
1050
 			continue;
1051
 		    }
1052
-		    else	/* found */
1053
+		    else {	/* found */
1054
+#ifdef UTF8
1055
+			g_free(exp_backup);
1056
+#endif /* UTF8 */
1057
 			return (start + offset - q + found_start);
1058
+		    }
1059
 		}
1060
-		if (once_only)
1061
+		if (once_only) {
1062
+#ifdef UTF8
1063
+		    g_free(exp_backup);
1064
+#endif /* UTF8 */
1065
 		    return -2;
1066
+		}
1067
 
1068
 		if (buf[q - 1] != '\n') { /* incomplete line: try to recover */
1069
 		    buf = mbuf + MAX_REPL_LEN / 2;
1070
+#ifndef UTF8
1071
 		    q = strlen ((const char *) buf);
1072
+#else /* UTF8 */
1073
+		    q = wcslen (buf);
1074
+#endif /* UTF8 */
1075
 		    memmove (mbuf, buf, q);
1076
 		    p = start + q;
1077
 		    move_win = 1;
1078
@@ -1539,36 +1726,59 @@
1079
 	    }
1080
 	}
1081
     } else {
1082
+#ifndef UTF8
1083
  	*len = strlen ((const char *) exp);
1084
+#else /* UTF8 */
1085
+        *len = wcslen (exp);
1086
+#endif /* UTF8 */
1087
 	if (replace_case) {
1088
 	    for (p = start; p <= last_byte - l; p++) {
1089
- 		if ((*get_byte) (data, p) == (unsigned char)exp[0]) {	/* check if first char matches */
1090
+                if ((*get_byte) (data, p) == exp[0]) {  /* check if first char matches */
1091
 		    for (f = 0, q = 0; q < l && f < 1; q++)
1092
- 			if ((*get_byte) (data, q + p) != (unsigned char)exp[q])
1093
+                        if ((*get_byte) (data, q + p) != exp[q])
1094
 			    f = 1;
1095
-		    if (f == 0)
1096
+                    if (f == 0) {
1097
+#ifdef UTF8
1098
+                        g_free (exp_backup);
1099
+#endif /* UTF8 */
1100
 			return p;
1101
+		    }
1102
 		}
1103
-		if (once_only)
1104
+                if (once_only) {
1105
+#ifdef UTF8
1106
+                    g_free(exp_backup);
1107
+#endif /* UTF8 */
1108
 		    return -2;
1109
+		}
1110
 	    }
1111
 	} else {
1112
 	    for (p = 0; exp[p] != 0; p++)
1113
 		exp[p] = my_lower_case (exp[p]);
1114
 
1115
 	    for (p = start; p <= last_byte - l; p++) {
1116
-		if (my_lower_case ((*get_byte) (data, p)) == (unsigned char)exp[0]) {
1117
+                if (my_lower_case ((*get_byte) (data, p)) == exp[0]) {
1118
 		    for (f = 0, q = 0; q < l && f < 1; q++)
1119
-			if (my_lower_case ((*get_byte) (data, q + p)) != (unsigned char)exp[q])
1120
+                        if (my_lower_case ((*get_byte) (data, q + p)) != exp[q])
1121
 			    f = 1;
1122
-		    if (f == 0)
1123
+		    if (f == 0) {
1124
+#ifdef UTF8
1125
+                        g_free (exp_backup);
1126
+#endif /* UTF8 */
1127
 			return p;
1128
+		    }
1129
 		}
1130
-		if (once_only)
1131
+		if (once_only) {
1132
+#ifdef UTF8
1133
+                    g_free (exp_backup);
1134
+#endif /* UTF8 */
1135
 		    return -2;
1136
+		}
1137
 	    }
1138
 	}
1139
     }
1140
+#ifdef UTF8
1141
+    g_free (exp_backup);
1142
+#endif /* UTF8 */
1143
     return -2;
1144
 }
1145
 
1146
@@ -1582,9 +1792,14 @@
1147
 
1148
     while ((p = edit_find_string (p, exp, len, last_byte, get_byte, data, once_only, d)) >= 0) {
1149
 	if (replace_whole) {
1150
+#ifndef UTF8
1151
 /*If the bordering chars are not in option_whole_chars_search then word is whole */
1152
 	    if (!strcasechr (option_whole_chars_search, (*get_byte) (data, p - 1))
1153
 		&& !strcasechr (option_whole_chars_search, (*get_byte) (data, p + *len)))
1154
+#else /* UTF8 */
1155
+	    if (!iswalnum((*get_byte) (data, p - 1))
1156
+		&& !iswalnum((*get_byte) (data, p + *len)))
1157
+#endif /* UTF8 */
1158
 		return p;
1159
 	    if (once_only)
1160
 		return -2;
1161
@@ -1616,6 +1831,7 @@
1162
 
1163
 #define is_digit(x) ((x) >= '0' && (x) <= '9')
1164
 
1165
+#ifndef UTF8
1166
 #define snprint(v) { \
1167
 		*p1++ = *p++; \
1168
 		*p1 = '\0'; \
1169
@@ -1623,33 +1839,48 @@
1170
 		if (n >= (size_t) (e - s)) goto nospc; \
1171
 		s += n; \
1172
 	    }
1173
+#else /* UTF8 */
1174
+#define snprint(v) { \
1175
+		*p1++ = *p++; \
1176
+		*p1 = '\0'; \
1177
+		n = swprintf(s, e-s, q1,v); \
1178
+		if (n >= (size_t) (e - s)) goto nospc; \
1179
+		s += n; \
1180
+	    }
1181
+#endif /* UTF8 */
1182
 
1183
 /* this function uses the sprintf command to do a vprintf */
1184
 /* it takes pointers to arguments instead of the arguments themselves */
1185
 /* The return value is the number of bytes written excluding '\0'
1186
    if successfull, -1 if the resulting string would be too long and
1187
    -2 if the format string is errorneous.  */
1188
-static int snprintf_p (char *str, size_t size, const char *fmt,...)
1189
-    __attribute__ ((format (printf, 3, 4)));
1190
-
1191
-static int snprintf_p (char *str, size_t size, const char *fmt,...)
1192
+static int snprintf_p (mc_wchar_t *str, size_t size, const mc_wchar_t *fmt,...)
1193
 {
1194
     va_list ap;
1195
     size_t n;
1196
-    const char *q, *p;
1197
-    char *s = str, *e = str + size;
1198
-    char q1[40];
1199
-    char *p1;
1200
+    const mc_wchar_t *q, *p;
1201
+    mc_wchar_t *s = str, *e = str + size;
1202
+    mc_wchar_t q1[40];
1203
+
1204
+    mc_wchar_t *p1;
1205
     int nargs = 0;
1206
 
1207
     va_start (ap, fmt);
1208
     p = q = fmt;
1209
 
1210
+#ifndef UTF8
1211
     while ((p = strchr (p, '%'))) {
1212
+#else /* UTF8 */
1213
+    while ((p = wcschr (p, L'%'))) {
1214
+#endif /* UTF8 */
1215
 	n = p - q;
1216
 	if (n >= (size_t) (e - s))
1217
 	  goto nospc;
1218
+#ifndef UTF8
1219
 	memcpy (s, q, n);	/* copy stuff between format specifiers */
1220
+#else /* UTF8 */
1221
+	wmemcpy (s, q, n);	/* copy stuff between format specifiers */
1222
+#endif /* UTF8 */
1223
 	s += n;
1224
 	q = p;
1225
 	p1 = q1;
1226
@@ -1677,45 +1908,78 @@
1227
 	    *p1++ = *p++;
1228
 	if (*p == '*') {
1229
 	    p++;
1230
+#ifndef UTF8
1231
 	    strcpy (p1, MY_itoa (*va_arg (ap, int *)));	/* replace field width with a number */
1232
 	    p1 += strlen (p1);
1233
+#else /* UTF8 */
1234
+	    wcscpy (p1, MY_itoa (*va_arg (ap, int *)));	/* replace field width with a number */
1235
+	    p1 += wcslen (p1);
1236
+#endif /* UTF8 */
1237
 	} else {
1238
-	    while (is_digit (*p) && p1 < q1 + 20)
1239
+#ifndef UTF8
1240
+	    while (is_digit (*p)
1241
+#else /* UTF8 */
1242
+	    while (iswdigit (*p)
1243
+#endif /* UTF8 */
1244
+		    && p1 < q1 + 20)
1245
 		*p1++ = *p++;
1246
-	    if (is_digit (*p))
1247
+#ifndef UTF8
1248
+	    if (is_digit (*p)) 
1249
+#else /* UTF8 */
1250
+	    if (iswdigit (*p))
1251
+#endif /* UTF8 */
1252
 		goto err;
1253
 	}
1254
 	if (*p == '.')
1255
 	    *p1++ = *p++;
1256
 	if (*p == '*') {
1257
 	    p++;
1258
+#ifndef UTF8
1259
 	    strcpy (p1, MY_itoa (*va_arg (ap, int *)));	/* replace precision with a number */
1260
 	    p1 += strlen (p1);
1261
+#else /* UTF8 */
1262
+	    wcscpy (p1, MY_itoa (*va_arg (ap, int *)));	/* replace precision with a number */
1263
+	    p1 += wcslen (p1);
1264
+#endif /* UTF8 */
1265
 	} else {
1266
-	    while (is_digit (*p) && p1 < q1 + 32)
1267
+#ifndef UTF8
1268
+	    while (is_digit (*p)
1269
+#else /* UTF8 */
1270
+	    while (iswdigit (*p)
1271
+#endif /* UTF8 */
1272
+		&& p1 < q1 + 32)
1273
 		*p1++ = *p++;
1274
-	    if (is_digit (*p))
1275
+#ifndef UTF8
1276
+	    if (is_digit (*p)) 
1277
+#else /* UTF8 */
1278
+	    if (iswdigit (*p))
1279
+#endif /* UTF8 */
1280
 		goto err;
1281
 	}
1282
 /* flags done, now get argument */
1283
 	if (*p == 's') {
1284
+#ifndef UTF8
1285
 	    snprint (va_arg (ap, char *));
1286
+#else /* UTF8 */
1287
+	    *p1++ = 'l';
1288
+	    snprint (va_arg (ap, mc_wchar_t *));
1289
+#endif /* UTF8 */
1290
 	} else if (*p == 'h') {
1291
-	    if (strchr ("diouxX", *p))
1292
+	    if (*p < 128 && strchr ("diouxX", *p))
1293
 		snprint (*va_arg (ap, short *));
1294
 	} else if (*p == 'l') {
1295
 	    *p1++ = *p++;
1296
-	    if (strchr ("diouxX", *p))
1297
+	    if (*p < 128 && strchr ("diouxX", *p))
1298
 		snprint (*va_arg (ap, long *));
1299
-	} else if (strchr ("cdiouxX", *p)) {
1300
+	} else if (*p < 128 && strchr ("cdiouxX", *p)) {
1301
 	    snprint (*va_arg (ap, int *));
1302
 	} else if (*p == 'L') {
1303
 	    *p1++ = *p++;
1304
-	    if (strchr ("EefgG", *p))
1305
+	    if (*p < 128 && strchr ("EefgG", *p))
1306
 		snprint (*va_arg (ap, double *));	/* should be long double */
1307
-	} else if (strchr ("EefgG", *p)) {
1308
+	} else if (*p < 128 && strchr ("EefgG", *p)) {
1309
 	    snprint (*va_arg (ap, double *));
1310
-	} else if (strchr ("DOU", *p)) {
1311
+	} else if (*p < 128 && strchr ("DOU", *p)) {
1312
 	    snprint (*va_arg (ap, long *));
1313
 	} else if (*p == 'p') {
1314
 	    snprint (*va_arg (ap, void **));
1315
@@ -1724,10 +1988,17 @@
1316
 	q = p;
1317
     }
1318
     va_end (ap);
1319
+#ifndef UTF8
1320
     n = strlen (q);
1321
     if (n >= (size_t) (e - s))
1322
 	return -1;
1323
     memcpy (s, q, n + 1);
1324
+#else /* UTF8 */
1325
+    n = wcslen (q);
1326
+    if (n >= (size_t) (e - s))
1327
+	return -1;
1328
+    wmemcpy (s, q, n + 1);
1329
+#endif /* UTF8 */
1330
     return s + n - str;
1331
 nospc:
1332
     va_end (ap);
1333
@@ -1902,8 +2173,11 @@
1334
 		}
1335
 	    }
1336
 	    if (replace_yes) {	/* delete then insert new */
1337
+#ifdef UTF8
1338
+		mc_wchar_t *winput2 = mbstr_to_wchar(exp2);
1339
+#endif /* UTF8 */
1340
 		if (replace_scanf || replace_regexp) {
1341
-		    char repl_str[MAX_REPL_LEN + 2];
1342
+		    mc_wchar_t repl_str[MAX_REPL_LEN + 2];
1343
 		    int ret = 0;
1344
 
1345
 		    /* we need to fill in sargs just like with scanf */
1346
@@ -1912,17 +2186,25 @@
1347
 			for (k = 1;
1348
 			     k < NUM_REPL_ARGS && pmatch[k].rm_eo >= 0;
1349
 			     k++) {
1350
+#ifndef UTF8
1351
 			    unsigned char *t;
1352
+#else /* UTF8 */
1353
+			    mc_wchar_t *t;
1354
+#endif
1355
 
1356
 			    if (pmatch[k].rm_eo - pmatch[k].rm_so > 255) {
1357
 				ret = -1;
1358
 				break;
1359
 			    }
1360
+#ifndef UTF8
1361
 			    t = (unsigned char *) &sargs[k - 1][0];
1362
+#else /* UTF8 */
1363
+			    t = (mc_wchar_t *) &sargs[k - 1][0];
1364
+#endif /* UTF8 */
1365
 			    for (j = 0;
1366
 				 j < pmatch[k].rm_eo - pmatch[k].rm_so
1367
 				 && j < 255; j++, t++)
1368
-				*t = (unsigned char) edit_get_byte (edit,
1369
+				*t = edit_get_byte (edit,
1370
 								    edit->
1371
 								    search_start
1372
 								    -
1373
@@ -1939,13 +2221,22 @@
1374
 			    sargs[k - 1][0] = 0;
1375
 		    }
1376
 		    if (!ret)
1377
+#ifndef UTF8
1378
 			ret = snprintf_p (repl_str, MAX_REPL_LEN + 2, exp2, PRINTF_ARGS);
1379
+#else /* UTF8 */
1380
+                        ret = snprintf_p (repl_str, MAX_REPL_LEN + 2, winput2, PRINTF_ARGS);
1381
+#endif /* UTF8 */
1382
 		    if (ret >= 0) {
1383
 			times_replaced++;
1384
 			while (i--)
1385
 			    edit_delete (edit);
1386
+#ifndef UTF8
1387
 			while (repl_str[++i])
1388
 			    edit_insert (edit, repl_str[i]);
1389
+#else /* UTF8 */
1390
+                        while (winput2[++i])
1391
+                            edit_insert (edit, winput2[i]);
1392
+#endif /* UTF8 */
1393
 		    } else {
1394
 			edit_error_dialog (_(" Replace "),
1395
 					   ret == -2
1396
@@ -1957,10 +2248,18 @@
1397
 		    times_replaced++;
1398
 		    while (i--)
1399
 			edit_delete (edit);
1400
+#ifndef UTF8
1401
 		    while (exp2[++i])
1402
 			edit_insert (edit, exp2[i]);
1403
+#else /* UTF8 */
1404
+                    while (winput2[++i])
1405
+                        edit_insert (edit, winput2[i]);
1406
+#endif
1407
 		}
1408
 		edit->found_len = i;
1409
+#ifdef UTF8
1410
+                g_free (winput2);
1411
+#endif /* UTF8 */
1412
 	    }
1413
 	    /* so that we don't find the same string again */
1414
 	    if (replace_backwards) {
1415
@@ -2132,16 +2431,17 @@
1416
 #define TEMP_BUF_LEN 1024
1417
 
1418
 /* Return a null terminated length of text. Result must be g_free'd */
1419
-static unsigned char *
1420
+static mc_wchar_t *
1421
 edit_get_block (WEdit *edit, long start, long finish, int *l)
1422
 {
1423
-    unsigned char *s, *r;
1424
-    r = s = g_malloc (finish - start + 1);
1425
+    mc_wchar_t *s, *r;
1426
+    r = s = g_malloc ((finish - start + 1) * sizeof(mc_wchar_t));
1427
     if (column_highlighting) {
1428
 	*l = 0;
1429
 	/* copy from buffer, excluding chars that are out of the column 'margins' */
1430
 	while (start < finish) {
1431
-	    int c, x;
1432
+	    mc_wchar_t c;
1433
+	    int x;
1434
 	    x = edit_move_forward3 (edit, edit_bol (edit, start), 0,
1435
 				    start);
1436
 	    c = edit_get_byte (edit, start);
1437
@@ -2174,11 +2474,15 @@
1438
 	return 0;
1439
 
1440
     if (column_highlighting) {
1441
-	unsigned char *block, *p;
1442
+	mc_wchar_t *block, *p;
1443
 	int r;
1444
 	p = block = edit_get_block (edit, start, finish, &len);
1445
 	while (len) {
1446
+#ifndef UTF8
1447
 	    r = mc_write (file, p, len);
1448
+#else /* UTF8 */
1449
+	    r = wchar_write (file, p, len);
1450
+#endif /* UTF8 */
1451
 	    if (r < 0)
1452
 		break;
1453
 	    p += r;
1454
@@ -2186,15 +2490,19 @@
1455
 	}
1456
 	g_free (block);
1457
     } else {
1458
-	unsigned char *buf;
1459
+	mc_wchar_t *buf;
1460
 	int i = start, end;
1461
 	len = finish - start;
1462
-	buf = g_malloc (TEMP_BUF_LEN);
1463
+	buf = g_malloc (TEMP_BUF_LEN * sizeof(mc_wchar_t));
1464
 	while (start != finish) {
1465
 	    end = min (finish, start + TEMP_BUF_LEN);
1466
 	    for (; i < end; i++)
1467
 		buf[i - start] = edit_get_byte (edit, i);
1468
+#ifndef UTF8
1469
 	    len -= mc_write (file, (char *) buf, end - start);
1470
+#else /* UTF8 */
1471
+	    len -= wchar_write (file, buf, end - start);
1472
+#endif /* UTF8 */
1473
 	    start = end;
1474
 	}
1475
 	g_free (buf);
1476
@@ -2531,17 +2839,20 @@
1477
 
1478
 /* prints at the cursor */
1479
 /* returns the number of chars printed */
1480
+#ifndef UTF8
1481
 int edit_print_string (WEdit * e, const char *s)
1482
+#else /* UTF8 */
1483
+int edit_print_wstring (WEdit * e, mc_wchar_t *s)
1484
+#endif /* UTF8 */
1485
 {
1486
     int i = 0;
1487
     while (s[i])
1488
-	edit_execute_cmd (e, -1, (unsigned char) s[i++]);
1489
+	edit_execute_cmd (e, -1, s[i++]);
1490
     e->force |= REDRAW_COMPLETELY;
1491
     edit_update_screen (e);
1492
     return i;
1493
 }
1494
 
1495
-
1496
 static void pipe_mail (WEdit *edit, char *to, char *subject, char *cc)
1497
 {
1498
     FILE *p = 0;
1499
@@ -2635,15 +2946,20 @@
1500
 /* find first character of current word */
1501
 static int edit_find_word_start (WEdit *edit, long *word_start, int *word_len)
1502
 {
1503
-    int i, c, last;
1504
+    int i;
1505
+    mc_wint_t c, last;
1506
     
1507
 /* return if at begin of file */
1508
     if (edit->curs1 <= 0)
1509
 	return 0;
1510
 
1511
-    c = (unsigned char) edit_get_byte (edit, edit->curs1 - 1);
1512
+    c = edit_get_byte (edit, edit->curs1 - 1);
1513
 /* return if not at end or in word */
1514
+#ifndef UTF8
1515
     if (isspace (c) || !(isalnum (c) || c == '_'))
1516
+#else /* UTF8 */
1517
+    if (iswspace (c) || !(iswalnum (c) || c == '_'))
1518
+#endif /* UTF8 */
1519
 	return 0; 
1520
 
1521
 /* search start of word to be completed */
1522
@@ -2653,11 +2969,19 @@
1523
 	    return 0;
1524
 	    
1525
 	last = c;
1526
-	c = (unsigned char) edit_get_byte (edit, edit->curs1 - i);
1527
+	c = edit_get_byte (edit, edit->curs1 - i);
1528
 
1529
+#ifndef UTF8
1530
 	if (!(isalnum (c) || c == '_')) {
1531
+#else /* UTF8 */
1532
+	if (!(iswalnum (c) || c == '_')) {
1533
+#endif /* UTF8 */
1534
 /* return if word starts with digit */
1535
+#ifndef UTF8
1536
 	    if (isdigit (last))
1537
+#else /* UTF8 */
1538
+	    if (iswdigit (last))
1539
+#endif /* UTF8 */
1540
 		return 0;
1541
 
1542
 	    *word_start = edit->curs1 - (i - 1); /* start found */
1543
@@ -2690,7 +3014,7 @@
1544
 			  int *num)
1545
 {
1546
     int len, max_len = 0, i, skip;
1547
-    char *bufpos;
1548
+    mc_wchar_t *bufpos;
1549
 
1550
     /* collect max MAX_WORD_COMPLETIONS completions */
1551
     while (*num < MAX_WORD_COMPLETIONS) {
1552
@@ -2711,9 +3035,16 @@
1553
 	    buffers1[start >> S_EDIT_BUF_SIZE][start & M_EDIT_BUF_SIZE];
1554
 	skip = 0;
1555
 	for (i = 0; i < *num; i++) {
1556
+#ifndef UTF8
1557
 	    if (strncmp
1558
 		(&compl[i].text[word_len], &bufpos[word_len],
1559
-		 max (len, compl[i].len) - word_len) == 0) {
1560
+		 max (len,
1561
+#else /* UTF8 */
1562
+            if (wcsncmp
1563
+                ((wchar_t *) &compl[i].text[word_len],
1564
+                 (wchar_t *) &bufpos[word_len], max (len,
1565
+#endif /* UTF8 */
1566
+                 compl[i].len) - word_len) == 0) {
1567
 		skip = 1;
1568
 		break;		/* skip it, already added */
1569
 	    }
1570
@@ -2721,7 +3052,7 @@
1571
 	if (skip)
1572
 	    continue;
1573
 
1574
-	compl[*num].text = g_malloc (len + 1);
1575
+	compl[*num].text = g_malloc ((len + 1) * sizeof(mc_wchar_t));
1576
 	compl[*num].len = len;
1577
 	for (i = 0; i < len; i++)
1578
 	    compl[*num].text[i] = *(bufpos + i);
1579
@@ -2735,6 +3066,18 @@
1580
     return max_len;
1581
 }
1582
 
1583
+#ifdef UTF8
1584
+int edit_print_string (WEdit * e, const char *s)
1585
+{
1586
+    int i;
1587
+    mc_wchar_t *ws = mbstr_to_wchar(s);
1588
+    i = edit_print_wstring (e, ws);
1589
+    g_free(ws);
1590
+    return i;
1591
+}
1592
+
1593
+#endif /* UTF8 */
1594
+
1595
 
1596
 /* let the user select its preferred completion */
1597
 static void
1598
@@ -2747,6 +3090,10 @@
1599
     WListbox *compl_list;
1600
     int compl_dlg_h;	/* completion dialog height */
1601
     int compl_dlg_w;	/* completion dialog width */
1602
+#ifdef UTF8
1603
+    char *mbtext;
1604
+#endif /* UTF8 */
1605
+
1606
 
1607
     /* calculate the dialog metrics */
1608
     compl_dlg_h = num_compl + 2;
1609
@@ -2782,8 +3129,16 @@
1610
     add_widget (compl_dlg, compl_list);
1611
 
1612
     /* fill the listbox with the completions */
1613
+#ifndef UTF8
1614
     for (i = 0; i < num_compl; i++)
1615
 	listbox_add_item (compl_list, 0, 0, compl[i].text, NULL);
1616
+#else /* UTF8 */
1617
+    for (i = 0; i < num_compl; i++) {
1618
+        mbtext = wchar_to_mbstr(compl[i].text);
1619
+        listbox_add_item (compl_list, 0, 0, mbtext, NULL);
1620
+        g_free(mbtext);
1621
+    }
1622
+#endif /* UTF8 */
1623
 
1624
     /* pop up the dialog */
1625
     run_dlg (compl_dlg);
1626
@@ -2791,9 +3146,17 @@
1627
     /* apply the choosen completion */
1628
     if (compl_dlg->ret_value == B_ENTER) {
1629
 	listbox_get_current (compl_list, &curr, NULL);
1630
-	if (curr)
1631
+	if (curr){
1632
+#ifndef UTF8
1633
 	    for (curr += word_len; *curr; curr++)
1634
 		edit_insert (edit, *curr);
1635
+#else /* UTF8 */
1636
+	    mc_wchar_t *wc, *wccurr = mbstr_to_wchar(curr);
1637
+	    for (wc = wccurr + word_len; *wc; wc++)
1638
+		edit_insert (edit, *wc);
1639
+	    g_free(wccurr);
1640
+#endif /* UTF8 */
1641
+	}
1642
     }
1643
 
1644
     /* destroy dialog before return */
1645
@@ -2810,8 +3173,9 @@
1646
 {
1647
     int word_len = 0, i, num_compl = 0, max_len;
1648
     long word_start = 0;
1649
-    char *bufpos;
1650
-    char *match_expr;
1651
+    mc_wchar_t *bufpos;
1652
+    mc_wchar_t *match_expr;
1653
+    char *mbmatch_expr;
1654
     struct selection compl[MAX_WORD_COMPLETIONS];	/* completions */
1655
 
1656
     /* don't want to disturb another search */
1657
@@ -2828,16 +3192,32 @@
1658
     /* prepare match expression */
1659
     bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE]
1660
 	[word_start & M_EDIT_BUF_SIZE];
1661
+
1662
+    match_expr = g_malloc((word_len + 14) * sizeof(mc_wchar_t));
1663
+#ifndef UTF8
1664
     match_expr = g_strdup_printf ("%.*s[a-zA-Z_0-9]+", word_len, bufpos);
1665
+#else /* UTF8 */
1666
+    wcsncpy (match_expr, bufpos, word_len);
1667
+    match_expr[word_len] = '\0';
1668
+    wcscat (match_expr, L"[a-zA-Z_0-9]+");
1669
+#endif /* UTF8 */
1670
 
1671
     /* init search: backward, regexp, whole word, case sensitive */
1672
     edit_set_search_parameters (0, 1, 1, 1, 1);
1673
 
1674
     /* collect the possible completions              */
1675
     /* start search from curs1 down to begin of file */
1676
+#ifndef UTF8
1677
     max_len =
1678
 	edit_collect_completions (edit, word_start, word_len, match_expr,
1679
 				  (struct selection *) &compl, &num_compl);
1680
+#else /* UTF8 */
1681
+    mbmatch_expr = wchar_to_mbstr(match_expr);
1682
+    max_len =
1683
+	edit_collect_completions (edit, word_start, word_len, mbmatch_expr,
1684
+				  (struct selection *) &compl, &num_compl);
1685
+    g_free(mbmatch_expr);
1686
+#endif /* UTF8 */
1687
 
1688
     if (num_compl > 0) {
1689
 	/* insert completed word if there is only one match */
1690
diff -Naur mc-4.6.1-old/edit/editdraw.c mc-4.6.1/edit/editdraw.c
1691
--- mc-4.6.1-old/edit/editdraw.c	2005-05-27 16:19:18.000000000 +0200
1692
+++ mc-4.6.1/edit/editdraw.c	2005-10-28 10:08:07.657259272 +0200
1693
@@ -48,7 +48,7 @@
1694
 
1695
 static void status_string (WEdit * edit, char *s, int w)
1696
 {
1697
-    char byte_str[16];
1698
+    char byte_str[32];
1699
 
1700
     /*
1701
      * If we are at the end of file, print <EOF>,
1702
@@ -56,11 +56,16 @@
1703
      * as decimal and as hex.
1704
      */
1705
     if (edit->curs1 < edit->last_byte) {
1706
-	unsigned char cur_byte = edit_get_byte (edit, edit->curs1);
1707
+        mc_wchar_t cur_byte = edit_get_byte (edit, edit->curs1);
1708
+#ifndef UTF8
1709
 	g_snprintf (byte_str, sizeof (byte_str), "%c %3d 0x%02X",
1710
 		    is_printable (cur_byte) ? cur_byte : '.',
1711
-		    (int) cur_byte,
1712
-		    (unsigned) cur_byte);
1713
+#else /* UTF8 */
1714
+        g_snprintf (byte_str, sizeof(byte_str), "%lc %3d 0x%02X",
1715
+                    iswprint(cur_byte) ? cur_byte : '.',
1716
+#endif /* UTF8 */
1717
+                    (int) cur_byte,
1718
+                    (unsigned) cur_byte);
1719
     } else {
1720
 	strcpy (byte_str, "<EOF>");
1721
     }
1722
@@ -183,11 +188,16 @@
1723
 #define lowlevel_set_color(x) attrset(MY_COLOR_PAIR(color))
1724
 #endif
1725
 
1726
+struct line_s {
1727
+    mc_wchar_t ch;
1728
+    unsigned int style;
1729
+};
1730
+
1731
 static void
1732
 print_to_widget (WEdit *edit, long row, int start_col, int start_col_real,
1733
-		 long end_col, unsigned int line[])
1734
+		 long end_col, struct line_s line[])
1735
 {
1736
-    unsigned int *p;
1737
+    struct line_s *p;
1738
 
1739
     int x = start_col_real + EDIT_TEXT_HORIZONTAL_OFFSET;
1740
     int x1 = start_col + EDIT_TEXT_HORIZONTAL_OFFSET;
1741
@@ -201,9 +211,9 @@
1742
     edit_move (x1 + FONT_OFFSET_X, y + FONT_OFFSET_Y);
1743
     p = line;
1744
 
1745
-    while (*p) {
1746
+    while (p->ch) {
1747
 	int style;
1748
-	int textchar;
1749
+	mc_wchar_t textchar;
1750
 	int color;
1751
 
1752
 	if (cols_to_skip) {
1753
@@ -212,9 +222,9 @@
1754
 	    continue;
1755
 	}
1756
 
1757
-	style = *p & 0xFF00;
1758
-	textchar = *p & 0xFF;
1759
-	color = *p >> 16;
1760
+	style = p->style & 0xFF00;
1761
+	textchar = p->ch;
1762
+	color = p->style >> 16;
1763
 
1764
 	if (style & MOD_ABNORMAL) {
1765
 	    /* Non-printable - use black background */
1766
@@ -228,8 +238,11 @@
1767
 	} else {
1768
 	    lowlevel_set_color (color);
1769
 	}
1770
-
1771
+#ifdef UTF8
1772
+	SLsmg_write_char(textchar);
1773
+#else
1774
 	addch (textchar);
1775
+#endif
1776
 	p++;
1777
     }
1778
 }
1779
@@ -239,11 +252,11 @@
1780
 edit_draw_this_line (WEdit *edit, long b, long row, long start_col,
1781
 		     long end_col)
1782
 {
1783
-    static unsigned int line[MAX_LINE_LEN];
1784
-    unsigned int *p = line;
1785
+    struct line_s line[MAX_LINE_LEN];
1786
+    struct line_s *p = line;
1787
     long m1 = 0, m2 = 0, q, c1, c2;
1788
     int col, start_col_real;
1789
-    unsigned int c;
1790
+    mc_wint_t c;
1791
     int color;
1792
     int i, book_mark = -1;
1793
 
1794
@@ -265,66 +278,96 @@
1795
 
1796
 	if (row <= edit->total_lines - edit->start_line) {
1797
 	    while (col <= end_col - edit->start_col) {
1798
-		*p = 0;
1799
+		p->ch = 0;
1800
+		p->style = 0;
1801
 		if (q == edit->curs1)
1802
-		    *p |= MOD_CURSOR;
1803
+		    p->style |= MOD_CURSOR;
1804
 		if (q >= m1 && q < m2) {
1805
 		    if (column_highlighting) {
1806
 			int x;
1807
 			x = edit_move_forward3 (edit, b, 0, q);
1808
 			if (x >= c1 && x < c2)
1809
-			    *p |= MOD_MARKED;
1810
+			    p->style |= MOD_MARKED;
1811
 		    } else
1812
-			*p |= MOD_MARKED;
1813
+			p->style |= MOD_MARKED;
1814
 		}
1815
 		if (q == edit->bracket)
1816
-		    *p |= MOD_BOLD;
1817
+		    p->style |= MOD_BOLD;
1818
 		if (q >= edit->found_start
1819
 		    && q < edit->found_start + edit->found_len)
1820
-		    *p |= MOD_BOLD;
1821
+		    p->style |= MOD_BOLD;
1822
 		c = edit_get_byte (edit, q);
1823
 /* we don't use bg for mc - fg contains both */
1824
 		if (book_mark == -1) {
1825
 		    edit_get_syntax_color (edit, q, &color);
1826
-		    *p |= color << 16;
1827
+		    p->style |= color << 16;
1828
 		} else {
1829
-		    *p |= book_mark << 16;
1830
+		    p->style |= book_mark << 16;
1831
 		}
1832
 		q++;
1833
 		switch (c) {
1834
 		case '\n':
1835
 		    col = end_col - edit->start_col + 1;	/* quit */
1836
-		    *(p++) |= ' ';
1837
+		    p->ch = ' ';
1838
+		    p++;
1839
 		    break;
1840
 		case '\t':
1841
 		    i = TAB_SIZE - ((int) col % TAB_SIZE);
1842
-		    *p |= ' ';
1843
-		    c = *(p++) & ~MOD_CURSOR;
1844
+		    p->ch = ' ';
1845
+		    c = p->style & ~MOD_CURSOR;
1846
+		    p++;
1847
 		    col += i;
1848
-		    while (--i)
1849
-			*(p++) = c;
1850
+		    while (--i) {
1851
+			p->ch = ' '; p->style = c;
1852
+			p++;
1853
+		    }
1854
 		    break;
1855
 		default:
1856
 		    c = convert_to_display_c (c);
1857
 
1858
 		    /* Caret notation for control characters */
1859
 		    if (c < 32) {
1860
-			*(p++) = '^' | MOD_ABNORMAL;
1861
-			*(p++) = (c + 0x40) | MOD_ABNORMAL;
1862
+		        p->ch = '^';
1863
+			p->style = MOD_ABNORMAL;
1864
+			p++;
1865
+		        p->ch = c + 0x40;
1866
+			p->style = MOD_ABNORMAL;
1867
 			col += 2;
1868
 			break;
1869
 		    }
1870
 		    if (c == 127) {
1871
-			*(p++) = '^' | MOD_ABNORMAL;
1872
-			*(p++) = '?' | MOD_ABNORMAL;
1873
+		        p->ch = '^';
1874
+			p->style = MOD_ABNORMAL;
1875
+			p++;
1876
+		        p->ch = '?';
1877
+			p->style = MOD_ABNORMAL;
1878
+			p++;
1879
 			col += 2;
1880
 			break;
1881
 		    }
1882
 
1883
-		    if (is_printable (c)) {
1884
-			*(p++) |= c;
1885
+#ifndef UTF8
1886
+		    if (is_printable (c)
1887
+#else /* UTF8 */
1888
+		    if (iswprint (c)
1889
+#ifdef __STDC_ISO_10646__ 
1890
+			&& (c < BINARY_CHAR_OFFSET || c >= (BINARY_CHAR_OFFSET + 256))
1891
+#endif
1892
+#endif /* UTF8 */
1893
+			) {
1894
+			p->ch = c;
1895
+			p++;
1896
+			
1897
+#ifdef UTF8
1898
+			i = wcwidth(c);
1899
+			if (i > 1) {
1900
+			    col += i - 1;
1901
+			}
1902
+#endif /* UTF8 */
1903
 		    } else {
1904
-			*(p++) = '.' | MOD_ABNORMAL;
1905
+		        p->ch = '.';
1906
+			p->style = MOD_ABNORMAL;
1907
+			p++;
1908
 		    }
1909
 		    col++;
1910
 		    break;
1911
@@ -334,7 +377,7 @@
1912
     } else {
1913
 	start_col_real = start_col = 0;
1914
     }
1915
-    *p = 0;
1916
+    p->ch = 0;
1917
 
1918
     print_to_widget (edit, row, start_col, start_col_real, end_col, line);
1919
 }
1920
diff -Naur mc-4.6.1-old/edit/edit.h mc-4.6.1/edit/edit.h
1921
--- mc-4.6.1-old/edit/edit.h	2005-05-27 16:19:18.000000000 +0200
1922
+++ mc-4.6.1/edit/edit.h	2005-10-28 10:08:07.768242400 +0200
1923
@@ -39,6 +39,27 @@
1924
 
1925
 #include "../src/global.h"
1926
 
1927
+#include "src/tty.h"
1928
+
1929
+#ifdef UTF8
1930
+#include <wchar.h>
1931
+#include <wctype.h>
1932
+
1933
+#define mc_wchar_t wchar_t
1934
+#define mc_wint_t wint_t
1935
+
1936
+#else
1937
+
1938
+#define mc_wchar_t unsigned char
1939
+#define mc_wint_t int
1940
+
1941
+#endif
1942
+
1943
+
1944
+/* unicode private use area */
1945
+#define BINARY_CHAR_OFFSET 0xFFE00
1946
+
1947
+
1948
 #define N_menus 5
1949
 
1950
 #define SEARCH_DIALOG_OPTION_NO_SCANF	1
1951
@@ -99,6 +120,8 @@
1952
 #define START_STACK_SIZE 32
1953
 
1954
 /* Some codes that may be pushed onto or returned from the undo stack */
1955
+#define CHAR_INSERT 65
1956
+#define CHAR_INSERT_AHEAD 66
1957
 #define CURS_LEFT 601
1958
 #define CURS_RIGHT 602
1959
 #define DELCHAR 603
1960
@@ -118,7 +141,7 @@
1961
 
1962
 struct macro {
1963
     short command;
1964
-    short ch;
1965
+    mc_wchar_t ch;
1966
 };
1967
 
1968
 struct WEdit;
1969
@@ -132,26 +155,8 @@
1970
 void menu_save_mode_cmd (void);
1971
 int edit_raw_key_query (const char *heading, const char *query, int cancel);
1972
 int edit_file (const char *_file, int line);
1973
-int edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch);
1974
-
1975
-#ifndef NO_INLINE_GETBYTE
1976
-int edit_get_byte (WEdit * edit, long byte_index);
1977
-#else
1978
-static inline int edit_get_byte (WEdit * edit, long byte_index)
1979
-{
1980
-    unsigned long p;
1981
-    if (byte_index >= (edit->curs1 + edit->curs2) || byte_index < 0)
1982
-	return '\n';
1983
-
1984
-    if (byte_index >= edit->curs1) {
1985
-	p = edit->curs1 + edit->curs2 - byte_index - 1;
1986
-	return edit->buffers2[p >> S_EDIT_BUF_SIZE][EDIT_BUF_SIZE - (p & M_EDIT_BUF_SIZE) - 1];
1987
-    } else {
1988
-	return edit->buffers1[byte_index >> S_EDIT_BUF_SIZE][byte_index & M_EDIT_BUF_SIZE];
1989
-    }
1990
-}
1991
-#endif
1992
-
1993
+int edit_translate_key (WEdit *edit, long x_key, int *cmd, mc_wint_t *ch);
1994
+mc_wchar_t edit_get_byte (WEdit * edit, long byte_index);
1995
 int edit_count_lines (WEdit * edit, long current, int upto);
1996
 long edit_move_forward (WEdit * edit, long current, int lines, long upto);
1997
 long edit_move_forward3 (WEdit * edit, long current, int cols, long upto);
1998
@@ -176,11 +181,11 @@
1999
 void edit_delete_line (WEdit * edit);
2000
 
2001
 int edit_delete (WEdit * edit);
2002
-void edit_insert (WEdit * edit, int c);
2003
+void edit_insert (WEdit * edit, mc_wchar_t c);
2004
 int edit_cursor_move (WEdit * edit, long increment);
2005
 void edit_push_action (WEdit * edit, long c, ...);
2006
 void edit_push_key_press (WEdit * edit);
2007
-void edit_insert_ahead (WEdit * edit, int c);
2008
+void edit_insert_ahead (WEdit * edit, mc_wchar_t c);
2009
 long edit_write_stream (WEdit * edit, FILE * f);
2010
 char *edit_get_write_filter (const char *writename, const char *filename);
2011
 int edit_save_confirm_cmd (WEdit * edit);
2012
@@ -212,7 +217,7 @@
2013
 int eval_marks (WEdit * edit, long *start_mark, long *end_mark);
2014
 void edit_status (WEdit * edit);
2015
 void edit_execute_key_command (WEdit *edit, int command,
2016
-			       int char_for_insertion);
2017
+			       mc_wint_t char_for_insertion);
2018
 void edit_update_screen (WEdit * edit);
2019
 int edit_print_string (WEdit * e, const char *s);
2020
 void edit_move_to_line (WEdit * e, long line);
2021
@@ -256,7 +261,7 @@
2022
 void format_paragraph (WEdit *edit, int force);
2023
 
2024
 /* either command or char_for_insertion must be passed as -1 */
2025
-void edit_execute_cmd (WEdit *edit, int command, int char_for_insertion);
2026
+void edit_execute_cmd (WEdit *edit, int command, mc_wint_t char_for_insertion);
2027
 
2028
 #define get_sys_error(s) (s)
2029
 
2030
diff -Naur mc-4.6.1-old/edit/editkeys.c mc-4.6.1/edit/editkeys.c
2031
--- mc-4.6.1-old/edit/editkeys.c	2005-05-27 16:19:18.000000000 +0200
2032
+++ mc-4.6.1/edit/editkeys.c	2005-10-28 10:08:07.659258968 +0200
2033
@@ -162,10 +162,10 @@
2034
  * 'command' is one of the editor commands from editcmddef.h.
2035
  */
2036
 int
2037
-edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch)
2038
+edit_translate_key (WEdit *edit, long x_key, int *cmd, mc_wint_t *ch)
2039
 {
2040
     int command = CK_Insert_Char;
2041
-    int char_for_insertion = -1;
2042
+    mc_wint_t char_for_insertion = -1;
2043
     int i = 0;
2044
     static const long *key_map;
2045
 
2046
@@ -242,9 +242,30 @@
2047
     /* an ordinary insertable character */
2048
     if (x_key < 256) {
2049
 	int c = convert_from_input_c (x_key);
2050
-
2051
+#ifdef UTF8
2052
+	mbstate_t mbs;
2053
+	int res;
2054
+	mc_wchar_t wc;
2055
+    
2056
+	memset (&mbs, 0, sizeof (mbs));
2057
+
2058
+	if (edit->charpoint >= MB_CUR_MAX) edit->charpoint = 0;
2059
+
2060
+	edit->charbuf[edit->charpoint++] = c;
2061
+
2062
+	res = mbrtowc(&wc, (char *)edit->charbuf, edit->charpoint, &mbs);
2063
+	if (res < 0) {
2064
+	    if (res != -2) edit->charpoint = 0; /* broken multibyte char, skip */
2065
+    	    return 0;
2066
+        }
2067
+	edit->charpoint = 0;
2068
+
2069
+	if (iswprint (wc)) {
2070
+	    char_for_insertion = wc;
2071
+#else 
2072
 	if (is_printable (c)) {
2073
 	    char_for_insertion = c;
2074
+#endif /* UTF8 */
2075
 	    goto fin;
2076
 	}
2077
     }
2078
@@ -285,7 +306,7 @@
2079
     *cmd = command;
2080
     *ch = char_for_insertion;
2081
 
2082
-    if (command == CK_Insert_Char && char_for_insertion == -1) {
2083
+    if (command == CK_Insert_Char && char_for_insertion == (mc_wint_t)-1) {
2084
 	/* unchanged, key has no function here */
2085
 	return 0;
2086
     }
2087
diff -Naur mc-4.6.1-old/edit/editwidget.c mc-4.6.1/edit/editwidget.c
2088
--- mc-4.6.1-old/edit/editwidget.c	2005-05-27 16:19:18.000000000 +0200
2089
+++ mc-4.6.1/edit/editwidget.c	2005-10-28 10:08:07.664258208 +0200
2090
@@ -337,7 +337,8 @@
2091
 
2092
     case WIDGET_KEY:
2093
 	{
2094
-	    int cmd, ch;
2095
+	    int cmd;
2096
+	    mc_wint_t ch;
2097
 
2098
 	    /* first check alt-f, alt-e, alt-s, etc for drop menus */
2099
 	    if (edit_drop_hotkey_menu (e, parm))
2100
diff -Naur mc-4.6.1-old/edit/edit-widget.h mc-4.6.1/edit/edit-widget.h
2101
--- mc-4.6.1-old/edit/edit-widget.h	2003-10-29 09:54:47.000000000 +0100
2102
+++ mc-4.6.1/edit/edit-widget.h	2005-10-28 10:08:07.750245136 +0200
2103
@@ -24,6 +24,11 @@
2104
     unsigned char border;
2105
 };
2106
 
2107
+struct action {
2108
+    mc_wchar_t ch;
2109
+    long flags;
2110
+};
2111
+
2112
 struct WEdit {
2113
     Widget widget;
2114
 
2115
@@ -36,8 +41,17 @@
2116
     /* dynamic buffers and cursor position for editor: */
2117
     long curs1;			/* position of the cursor from the beginning of the file. */
2118
     long curs2;			/* position from the end of the file */
2119
+#ifndef UTF8
2120
     unsigned char *buffers1[MAXBUFF + 1];	/* all data up to curs1 */
2121
     unsigned char *buffers2[MAXBUFF + 1];	/* all data from end of file down to curs2 */
2122
+#else /* UTF8 */
2123
+    mc_wchar_t *buffers1[MAXBUFF + 1];        /* all data up to curs1 */
2124
+    mc_wchar_t *buffers2[MAXBUFF + 1];        /* all data from end of file down to curs2 */
2125
+
2126
+    unsigned char charbuf[MB_LEN_MAX];
2127
+    int charpoint;
2128
+#endif /* UTF8 */
2129
+
2130
 
2131
     /* search variables */
2132
     long search_start;		/* First character to start searching from */
2133
@@ -81,7 +95,7 @@
2134
 
2135
     /* undo stack and pointers */
2136
     unsigned long stack_pointer;
2137
-    long *undo_stack;
2138
+    struct action *undo_stack;
2139
     unsigned long stack_size;
2140
     unsigned long stack_size_mask;
2141
     unsigned long stack_bottom;
2142
diff -Naur mc-4.6.1-old/edit/wordproc.c mc-4.6.1/edit/wordproc.c
2143
--- mc-4.6.1-old/edit/wordproc.c	2005-05-27 16:19:18.000000000 +0200
2144
+++ mc-4.6.1/edit/wordproc.c	2005-10-28 10:08:07.668257600 +0200
2145
@@ -24,7 +24,12 @@
2146
 
2147
 #define tab_width option_tab_spacing
2148
 
2149
+#ifndef UTF8
2150
 #define NO_FORMAT_CHARS_START "-+*\\,.;:&>"
2151
+#else /* UTF8 */
2152
+#define NO_FORMAT_CHARS_START L"-+*\\,.;:&>"
2153
+#endif /* UTF8 */
2154
+
2155
 #define FONT_MEAN_WIDTH 1
2156
 
2157
 static long
2158
@@ -41,14 +46,21 @@
2159
 	p = edit_move_forward (edit, p, line - l, 0);
2160
 
2161
     p = edit_bol (edit, p);
2162
+
2163
+#ifndef UTF8
2164
     while (strchr ("\t ", edit_get_byte (edit, p)))
2165
+#else /* UTF8 */
2166
+    while (wcschr (L"\t ", edit_get_byte (edit, p)))
2167
+#endif /* UTF8 */
2168
+
2169
 	p++;
2170
     return p;
2171
 }
2172
 
2173
 static int bad_line_start (WEdit * edit, long p)
2174
 {
2175
-    int c;
2176
+    mc_wint_t c;
2177
+
2178
     c = edit_get_byte (edit, p);
2179
     if (c == '.') {		/* `...' is acceptable */
2180
 	if (edit_get_byte (edit, p + 1) == '.')
2181
@@ -62,7 +74,13 @@
2182
 		return 0;	/* `---' is acceptable */
2183
 	return 1;
2184
     }
2185
+    
2186
+#ifndef UTF8
2187
     if (strchr (NO_FORMAT_CHARS_START, c))
2188
+#else /* UTF8 */
2189
+    if (wcschr (NO_FORMAT_CHARS_START, c))
2190
+#endif /* UTF8 */
2191
+
2192
 	return 1;
2193
     return 0;
2194
 }
2195
@@ -115,33 +133,37 @@
2196
 					i - edit->curs_line, 0));
2197
 }
2198
 
2199
-static unsigned char *
2200
+static mc_wchar_t *
2201
 get_paragraph (WEdit *edit, long p, long q, int indent, int *size)
2202
 {
2203
-    unsigned char *s, *t;
2204
+    mc_wchar_t *s, *t;
2205
 #if 0
2206
-    t = g_malloc ((q - p) + 2 * (q - p) / option_word_wrap_line_length +
2207
-		  10);
2208
+    t = g_malloc (((q - p) + 2 * (q - p) / option_word_wrap_line_length +
2209
+		  10) * sizeof(mc_wchar_t));
2210
 #else
2211
-    t = g_malloc (2 * (q - p) + 100);
2212
+    t = g_malloc ((2 * (q - p) + 100) * sizeof(mc_wchar_t));
2213
 #endif
2214
     if (!t)
2215
 	return 0;
2216
     for (s = t; p < q; p++, s++) {
2217
 	if (indent)
2218
 	    if (edit_get_byte (edit, p - 1) == '\n')
2219
+#ifndef UTF8
2220
 		while (strchr ("\t ", edit_get_byte (edit, p)))
2221
+#else /* UTF8 */
2222
+		while (wcschr (L"\t ", edit_get_byte (edit, p)))
2223
+#endif /* UTF8 */
2224
 		    p++;
2225
 	*s = edit_get_byte (edit, p);
2226
     }
2227
-    *size = (unsigned long) s - (unsigned long) t;
2228
+    *size = s - t;
2229
     t[*size] = '\n';
2230
     return t;
2231
 }
2232
 
2233
-static void strip_newlines (unsigned char *t, int size)
2234
+static void strip_newlines (mc_wchar_t *t, int size)
2235
 {
2236
-    unsigned char *p = t;
2237
+    mc_wchar_t *p = t;
2238
     while (size--) {
2239
 	*p = *p == '\n' ? ' ' : *p;
2240
 	p++;
2241
@@ -158,7 +180,7 @@
2242
 {
2243
     return x += tab_width - x % tab_width;
2244
 }
2245
-static int line_pixel_length (unsigned char *t, long b, int l)
2246
+static int line_pixel_length (mc_wchar_t *t, long b, int l)
2247
 {
2248
     int x = 0, c, xn = 0;
2249
     for (;;) {
2250
@@ -182,7 +204,7 @@
2251
 }
2252
 
2253
 /* find the start of a word */
2254
-static int next_word_start (unsigned char *t, int q, int size)
2255
+static int next_word_start (mc_wchar_t *t, int q, int size)
2256
 {
2257
     int i;
2258
     for (i = q;; i++) {
2259
@@ -203,7 +225,7 @@
2260
 }
2261
 
2262
 /* find the start of a word */
2263
-static int word_start (unsigned char *t, int q, int size)
2264
+static int word_start (mc_wchar_t *t, int q, int size)
2265
 {
2266
     int i = q;
2267
     if (t[q] == ' ' || t[q] == '\t')
2268
@@ -222,7 +244,7 @@
2269
 }
2270
 
2271
 /* replaces ' ' with '\n' to properly format a paragraph */
2272
-static void format_this (unsigned char *t, int size, int indent)
2273
+static void format_this (mc_wchar_t *t, int size, int indent)
2274
 {
2275
     int q = 0, ww;
2276
     strip_newlines (t, size);
2277
@@ -250,7 +272,7 @@
2278
     }
2279
 }
2280
 
2281
-static void replace_at (WEdit * edit, long q, int c)
2282
+static void replace_at (WEdit * edit, long q, mc_wint_t c)
2283
 {
2284
     edit_cursor_move (edit, q - edit->curs1);
2285
     edit_delete (edit);
2286
@@ -258,18 +280,27 @@
2287
 }
2288
 
2289
 /* replaces a block of text */
2290
-static void put_paragraph (WEdit * edit, unsigned char *t, long p, long q, int indent, int size)
2291
+static void put_paragraph (WEdit * edit, mc_wchar_t *t, long p, long q, int indent, int size)
2292
 {
2293
     long cursor;
2294
-    int i, c = 0;
2295
+    int i;
2296
+    mc_wchar_t c = 0;
2297
     cursor = edit->curs1;
2298
     if (indent)
2299
+#ifndef UTF8
2300
 	while (strchr ("\t ", edit_get_byte (edit, p)))
2301
+#else /* UTF8 */
2302
+        while (wcschr (L"\t ", edit_get_byte (edit, p)))
2303
+#endif /* UTF8 */
2304
 	    p++;
2305
     for (i = 0; i < size; i++, p++) {
2306
 	if (i && indent) {
2307
 	    if (t[i - 1] == '\n' && c == '\n') {
2308
+#ifndef UTF8
2309
 		while (strchr ("\t ", edit_get_byte (edit, p)))
2310
+#else /* UTF8 */
2311
+                while (wcschr (L"\t ", edit_get_byte (edit, p)))
2312
+#endif /* UTF8 */
2313
 		    p++;
2314
 	    } else if (t[i - 1] == '\n') {
2315
 		long curs;
2316
@@ -281,7 +312,11 @@
2317
 		p = edit->curs1;
2318
 	    } else if (c == '\n') {
2319
 		edit_cursor_move (edit, p - edit->curs1);
2320
+#ifndef UTF8
2321
 		while (strchr ("\t ", edit_get_byte (edit, p))) {
2322
+#else /* UTF8 */
2323
+		while (wcschr (L"\t ", edit_get_byte (edit, p))) {
2324
+#endif /* UTF8 */
2325
 		    edit_delete (edit);
2326
 		    if (cursor > edit->curs1)
2327
 			cursor--;
2328
@@ -314,7 +349,7 @@
2329
 {
2330
     long p, q;
2331
     int size;
2332
-    unsigned char *t;
2333
+    mc_wchar_t *t;
2334
     int indent = 0;
2335
     if (option_word_wrap_line_length < 2)
2336
 	return;
2337
@@ -324,17 +359,25 @@
2338
     q = end_paragraph (edit, force);
2339
     indent = test_indent (edit, p, q);
2340
     t = get_paragraph (edit, p, q, indent, &size);
2341
-    if (!t)
2342
+    if (!t) 
2343
 	return;
2344
     if (!force) {
2345
 	int i;
2346
+#ifndef UTF8
2347
 	if (strchr (NO_FORMAT_CHARS_START, *t)) {
2348
+#else /* UTF8 */
2349
+	if (wcschr (NO_FORMAT_CHARS_START, *t)) {
2350
+#endif /* UTF8 */
2351
 	    g_free (t);
2352
 	    return;
2353
 	}
2354
 	for (i = 0; i < size - 1; i++) {
2355
 	    if (t[i] == '\n') {
2356
+#ifndef UTF8
2357
 		if (strchr (NO_FORMAT_CHARS_START "\t ", t[i + 1])) {
2358
+#else /* UTF8 */
2359
+		if (wcschr (NO_FORMAT_CHARS_START "\t", t[i + 1])) {
2360
+#endif /* UTF8 */
2361
 		    g_free (t);
2362
 		    return;
2363
 		}
2364
diff -Naur mc-4.6.1-old/src/achown.c mc-4.6.1/src/achown.c
2365
--- mc-4.6.1-old/src/achown.c	2005-07-23 18:52:02.000000000 +0200
2366
+++ mc-4.6.1/src/achown.c	2005-10-28 10:08:08.094192848 +0200
2367
@@ -583,6 +583,12 @@
2368
     b_att[2] = button_new (XTRACT (6));
2369
     b_user = button_new (XTRACT (5));
2370
     b_group = button_new (XTRACT (4));
2371
+#ifdef UTF8
2372
+    if (SLsmg_Is_Unicode) {
2373
+	b_user->text = g_realloc (b_user->text, MB_CUR_MAX * 15 + 1);
2374
+	b_group->text = g_realloc (b_group->text, MB_CUR_MAX * 15 + 1);
2375
+    }
2376
+#endif
2377
 
2378
     add_widget (ch_dlg, b_group);
2379
     add_widget (ch_dlg, b_user);
2380
diff -Naur mc-4.6.1-old/src/boxes.c mc-4.6.1/src/boxes.c
2381
--- mc-4.6.1-old/src/boxes.c	2005-05-27 16:19:18.000000000 +0200
2382
+++ mc-4.6.1/src/boxes.c	2005-10-28 10:08:08.079195128 +0200
2383
@@ -150,23 +150,23 @@
2384
 	display_title = _(display_title);
2385
 	for (i = 0; i < LIST_TYPES; i++) {
2386
 	    displays[i] = _(displays[i]);
2387
-	    if ((l = strlen (displays[i])) > maxlen)
2388
+	    if ((l = mbstrlen (displays[i])) > maxlen)
2389
 		maxlen = l;
2390
 	}
2391
 
2392
-	i = strlen (ok_button) + 5;
2393
-	l = strlen (cancel_button) + 3;
2394
+	i = mbstrlen (ok_button) + 5;
2395
+	l = mbstrlen (cancel_button) + 3;
2396
 	l = max (i, l);
2397
 
2398
 	i = maxlen + l + 16;
2399
 	if (i > DISPLAY_X)
2400
 	    DISPLAY_X = i;
2401
 
2402
-	i = strlen (user_mini_status) + 13;
2403
+	i = mbstrlen (user_mini_status) + 13;
2404
 	if (i > DISPLAY_X)
2405
 	    DISPLAY_X = i;
2406
 
2407
-	i = strlen (display_title) + 10;
2408
+	i = mbstrlen (display_title) + 10;
2409
 	if (i > DISPLAY_X)
2410
 	    DISPLAY_X = i;
2411
 
2412
@@ -285,20 +285,20 @@
2413
 	int maxlen = 0;
2414
 	for (i = SORT_TYPES - 1; i >= 0; i--) {
2415
 	    sort_orders_names[i] = _(sort_orders[i].sort_name);
2416
-	    r = strlen (sort_orders_names[i]);
2417
+	    r = mbstrlen (sort_orders_names[i]);
2418
 	    if (r > maxlen)
2419
 		maxlen = r;
2420
 	}
2421
 
2422
 	check_pos = maxlen + 9;
2423
 
2424
-	r = strlen (reverse_label) + 4;
2425
-	i = strlen (case_label) + 4;
2426
+	r = mbstrlen (reverse_label) + 4;
2427
+	i = mbstrlen (case_label) + 4;
2428
 	if (i > r)
2429
 	    r = i;
2430
 
2431
-	l = strlen (ok_button) + 6;
2432
-	i = strlen (cancel_button) + 4;
2433
+	l = mbstrlen (ok_button) + 6;
2434
+	i = mbstrlen (cancel_button) + 4;
2435
 	if (i > l)
2436
 	    l = i;
2437
 
2438
@@ -307,7 +307,7 @@
2439
 	if (i > SORT_X)
2440
 	    SORT_X = i;
2441
 
2442
-	i = strlen (sort_title) + 6;
2443
+	i = mbstrlen (sort_title) + 6;
2444
 	if (i > SORT_X)
2445
 	    SORT_X = i;
2446
 
2447
@@ -402,7 +402,7 @@
2448
 		while (i--)
2449
 		{
2450
 			conf_widgets [i].text = _(conf_widgets [i].text);
2451
-			l1 = strlen (conf_widgets [i].text) + 3;
2452
+			l1 = mbstrlen (conf_widgets [i].text) + 3;
2453
 			if (l1 > maxlen)
2454
 				maxlen = l1;
2455
 		}
2456
@@ -417,8 +417,8 @@
2457
 		 * And this for the case when buttons with some space to the right
2458
 		 * do not fit within 2/6
2459
 		 */
2460
-		l1 = strlen (conf_widgets [0].text) + 3;
2461
-		i = strlen (conf_widgets [1].text) + 5;
2462
+		l1 = mbstrlen (conf_widgets [0].text) + 3;
2463
+		i = mbstrlen (conf_widgets [1].text) + 5;
2464
 		if (i > l1)
2465
 			l1 = i;
2466
 
2467
@@ -489,11 +489,11 @@
2468
 		{
2469
 			display_widgets [i].text = _(display_widgets[i].text);
2470
 			display_bits_str [i] = _(display_bits_str [i]);
2471
-			l1 = strlen (display_bits_str [i]);
2472
+			l1 = mbstrlen (display_bits_str [i]);
2473
 			if (l1 > maxlen)
2474
 				maxlen = l1;
2475
 		}
2476
-		l1 = strlen (display_widgets [2].text);
2477
+		l1 = mbstrlen (display_widgets [2].text);
2478
 		if (l1 > maxlen)
2479
 			maxlen = l1;
2480
 		
2481
@@ -501,8 +501,8 @@
2482
 		display_bits.xlen = (maxlen + 5) * 6 / 4;
2483
 
2484
 		/* See above confirm_box */
2485
-		l1 = strlen (display_widgets [0].text) + 3;
2486
-		i = strlen (display_widgets [1].text) + 5;
2487
+		l1 = mbstrlen (display_widgets [0].text) + 3;
2488
+		i = mbstrlen (display_widgets [1].text) + 5;
2489
 		if (i > l1)
2490
 			l1 = i;
2491
 
2492
@@ -597,7 +597,7 @@
2493
 
2494
     cpname = _("&Select");
2495
     add_widget (dbits_dlg,
2496
-		button_new (4, DISPX - 8 - strlen (cpname), B_USER,
2497
+		button_new (4, DISPX - 8 - mbstrlen (cpname), B_USER,
2498
 			    NORMAL_BUTTON, cpname, sel_charset_button));
2499
 
2500
     return dbits_dlg;
2501
@@ -803,7 +803,7 @@
2502
     quick_widgets [1].y_divisions =
2503
 	quick_widgets [0].y_divisions = Quick_input.ylen = 5;
2504
 
2505
-    len = strlen (quick_widgets [1].text);
2506
+    len = mbstrlen (quick_widgets [1].text);
2507
 
2508
     quick_widgets [0].relative_x =
2509
 	quick_widgets [1].relative_x + len + 1;
2510
@@ -962,7 +962,7 @@
2511
 		{
2512
 			job_buttons [i].name = _(job_buttons [i].name);
2513
 
2514
-			len = strlen (job_buttons [i].name) + 4;
2515
+			len = mbstrlen (job_buttons [i].name) + 4;
2516
 			JOBS_X = max (JOBS_X, startx + len + 3);
2517
 
2518
 			job_buttons [i].xpos = startx;
2519
@@ -971,7 +971,7 @@
2520
 
2521
 		/* Last button - Ok a.k.a. Cancel :) */
2522
 		job_buttons [n_buttons - 1].xpos =
2523
-			JOBS_X - strlen (job_buttons [n_buttons - 1].name) - 7;
2524
+			JOBS_X - mbstrlen (job_buttons [n_buttons - 1].name) - 7;
2525
 
2526
 		i18n_flag = 1;
2527
 	}
2528
@@ -1029,7 +1029,7 @@
2529
         
2530
         while (i--)
2531
         {
2532
-            l1 = strlen (labs [i] = _(labs [i]));
2533
+            l1 = mbstrlen (labs [i] = _(labs [i]));
2534
             if (l1 > maxlen)
2535
                 maxlen = l1;
2536
         }
2537
@@ -1039,7 +1039,7 @@
2538
         
2539
         for (i = sizeof(buts)/sizeof(buts[0]), l1 = 0; i--; )
2540
         {
2541
-            l1 += strlen (buts [i] = _(buts [i]));
2542
+            l1 += mbstrlen (buts [i] = _(buts [i]));
2543
         }
2544
         l1 += 15;
2545
         if (l1 > dialog_x)
2546
@@ -1048,7 +1048,7 @@
2547
         ilen = dialog_x - 7 - maxlen; /* for the case of very long buttons :) */
2548
         istart = dialog_x - 3 - ilen;
2549
         
2550
-        b2 = dialog_x - (strlen(buts[1]) + 6);
2551
+        b2 = dialog_x - (mbstrlen(buts[1]) + 6);
2552
         
2553
         i18n_flag = 1;
2554
     }
2555
diff -Naur mc-4.6.1-old/src/dialog.c mc-4.6.1/src/dialog.c
2556
--- mc-4.6.1-old/src/dialog.c	2005-05-27 16:19:18.000000000 +0200
2557
+++ mc-4.6.1/src/dialog.c	2005-10-28 10:08:07.891223704 +0200
2558
@@ -162,7 +162,7 @@
2559
 
2560
     if (h->title) {
2561
 	attrset (HOT_NORMALC);
2562
-	dlg_move (h, space, (h->cols - strlen (h->title)) / 2);
2563
+	dlg_move (h, space, (h->cols - mbstrlen (h->title)) / 2);
2564
 	addstr (h->title);
2565
     }
2566
 }
2567
diff -Naur mc-4.6.1-old/src/file.c mc-4.6.1/src/file.c
2568
--- mc-4.6.1-old/src/file.c	2005-05-27 16:19:18.000000000 +0200
2569
+++ mc-4.6.1/src/file.c	2005-10-28 10:08:08.002206832 +0200
2570
@@ -165,15 +165,20 @@
2571
 do_transform_source (FileOpContext *ctx, const unsigned char *source)
2572
 {
2573
     size_t j, k, l, len;
2574
-    unsigned const char *fnsource = x_basename (source);
2575
+    unsigned const char *fnsource = g_strdup (x_basename (source));
2576
     int next_reg;
2577
     enum CaseConvs case_conv = NO_CONV;
2578
     static unsigned char fntarget[MC_MAXPATHLEN];
2579
 
2580
+#ifdef UTF8
2581
+    fix_utf8(fnsource);
2582
+#endif
2583
+
2584
     len = strlen (fnsource);
2585
     j = re_match (&ctx->rx, fnsource, len, 0, &ctx->regs);
2586
     if (j != len) {
2587
 	transform_error = FILE_SKIP;
2588
+	g_free(fnsource);
2589
 	return NULL;
2590
     }
2591
     for (next_reg = 1, j = 0, k = 0; j < strlen (ctx->dest_mask); j++) {
2592
@@ -217,6 +222,7 @@
2593
 		|| ctx->regs.start[next_reg] < 0) {
2594
 		message (1, MSG_ERROR, _(" Invalid target mask "));
2595
 		transform_error = FILE_ABORT;
2596
+		g_free(fnsource);
2597
 		return NULL;
2598
 	    }
2599
 	    for (l = (size_t) ctx->regs.start[next_reg];
2600
@@ -231,6 +237,7 @@
2601
 	}
2602
     }
2603
     fntarget[k] = 0;
2604
+    g_free(fnsource);
2605
     return fntarget;
2606
 }
2607
 
2608
diff -Naur mc-4.6.1-old/src/filegui.c mc-4.6.1/src/filegui.c
2609
--- mc-4.6.1-old/src/filegui.c	2005-05-27 16:19:18.000000000 +0200
2610
+++ mc-4.6.1/src/filegui.c	2005-10-28 10:08:08.140185856 +0200
2611
@@ -69,6 +69,7 @@
2612
 #include "filegui.h"
2613
 #include "key.h"		/* get_event */
2614
 #include "util.h"               /* strip_password() */
2615
+#include "tty.h"
2616
 
2617
 /* }}} */
2618
 
2619
@@ -564,8 +565,8 @@
2620
 	 * longest of "Overwrite..." labels 
2621
 	 * (assume "Target date..." are short enough)
2622
 	 */
2623
-	l1 = max (strlen (rd_widgets[6].text),
2624
-		  strlen (rd_widgets[11].text));
2625
+	l1 = max (mbstrlen (rd_widgets[6].text),
2626
+		  mbstrlen (rd_widgets[11].text));
2627
 
2628
 	/* longest of button rows */
2629
 	i = sizeof (rd_widgets) / sizeof (rd_widgets[0]);
2630
@@ -576,7 +577,7 @@
2631
 		    l2 = max (l2, l);
2632
 		    l = 0;
2633
 		}
2634
-		l += strlen (rd_widgets[i].text) + 4;
2635
+		l += mbstrlen (rd_widgets[i].text) + 4;
2636
 	    }
2637
 	}
2638
 	l2 = max (l2, l);	/* last row */
2639
@@ -594,12 +595,12 @@
2640
 		    l = l1;
2641
 		}
2642
 		rd_widgets[i].xpos = l;
2643
-		l += strlen (rd_widgets[i].text) + 4;
2644
+		l += mbstrlen (rd_widgets[i].text) + 4;
2645
 	    }
2646
 	}
2647
 	/* Abort button is centered */
2648
 	rd_widgets[1].xpos =
2649
-	    (rd_xlen - strlen (rd_widgets[1].text) - 3) / 2;
2650
+	    (rd_xlen - mbstrlen (rd_widgets[1].text) - 3) / 2;
2651
     }
2652
 #endif				/* ENABLE_NLS */
2653
 
2654
@@ -618,7 +619,7 @@
2655
 
2656
     ADD_RD_LABEL (ui, 0,
2657
 		  name_trunc (ui->replace_filename,
2658
-			      rd_trunc - strlen (rd_widgets[0].text)), 0);
2659
+			      rd_trunc - mbstrlen (rd_widgets[0].text)), 0);
2660
     ADD_RD_BUTTON (1);
2661
 
2662
     ADD_RD_BUTTON (2);
2663
@@ -805,36 +806,36 @@
2664
 	if (fmd_widgets[i].text[0] != '\0')
2665
 	    fmd_widgets[i].text = _(fmd_widgets[i].text);
2666
 
2667
-    len = strlen (fmd_widgets[FMCB11].text)
2668
-	+ strlen (fmd_widgets[FMCB21].text) + 15;
2669
+    len = mbstrlen (fmd_widgets[FMCB11].text)
2670
+	+ mbstrlen (fmd_widgets[FMCB21].text) + 15;
2671
     fmd_xlen = max (fmd_xlen, len);
2672
 
2673
-    len = strlen (fmd_widgets[FMCB12].text)
2674
-	+ strlen (fmd_widgets[FMCB22].text) + 15;
2675
+    len = mbstrlen (fmd_widgets[FMCB12].text)
2676
+	+ mbstrlen (fmd_widgets[FMCB22].text) + 15;
2677
     fmd_xlen = max (fmd_xlen, len);
2678
 
2679
-    len = strlen (fmd_widgets[FMBRGT].text)
2680
-	+ strlen (fmd_widgets[FMBLFT].text) + 11;
2681
+    len = mbstrlen (fmd_widgets[FMBRGT].text)
2682
+	+ mbstrlen (fmd_widgets[FMBLFT].text) + 11;
2683
 
2684
 #ifdef FMBMID
2685
-    len += strlen (fmd_widgets[FMBMID].text) + 6;
2686
+    len += mbstrlen (fmd_widgets[FMBMID].text) + 6;
2687
 #endif
2688
 
2689
     fmd_xlen = max (fmd_xlen, len + 4);
2690
 
2691
     len = (fmd_xlen - (len + 6)) / 2;
2692
     i = fmd_widgets[FMBLFT].relative_x = len + 3;
2693
-    i += strlen (fmd_widgets[FMBLFT].text) + 8;
2694
+    i += mbstrlen (fmd_widgets[FMBLFT].text) + 8;
2695
 
2696
 #ifdef FMBMID
2697
     fmd_widgets[FMBMID].relative_x = i;
2698
-    i += strlen (fmd_widgets[FMBMID].text) + 6;
2699
+    i += mbstrlen (fmd_widgets[FMBMID].text) + 6;
2700
 #endif
2701
 
2702
     fmd_widgets[FMBRGT].relative_x = i;
2703
 
2704
 #define	chkbox_xpos(i) \
2705
-	fmd_widgets [i].relative_x = fmd_xlen - strlen (fmd_widgets [i].text) - 6
2706
+	fmd_widgets [i].relative_x = fmd_xlen - mbstrlen (fmd_widgets [i].text) - 6
2707
 
2708
     chkbox_xpos (FMCB0);
2709
     chkbox_xpos (FMCB21);
2710
@@ -856,7 +857,7 @@
2711
 
2712
 char *
2713
 file_mask_dialog (FileOpContext *ctx, FileOperation operation, const char *text,
2714
-		  const char *def_text, int only_one, int *do_background)
2715
+		  const char *def_text_orig, int only_one, int *do_background)
2716
 {
2717
     int source_easy_patterns = easy_patterns;
2718
     char *source_mask, *orig_mask, *dest_dir, *tmpdest;
2719
@@ -865,12 +866,20 @@
2720
     struct stat buf;
2721
     int val;
2722
     QuickDialog Quick_input;
2723
-
2724
+    char *def_text;
2725
     g_return_val_if_fail (ctx != NULL, NULL);
2726
+
2727
+    def_text = g_strdup(def_text_orig);
2728
+
2729
 #if 0
2730
     message (1, __FUNCTION__, "text = `%s' \n def_text = `%s'", text,
2731
 		def_text);
2732
 #endif
2733
+
2734
+#ifdef UTF8
2735
+	fix_utf8(def_text);
2736
+#endif
2737
+
2738
     fmd_init_i18n (FALSE);
2739
 
2740
     /* Set up the result pointers */
2741
@@ -929,6 +938,7 @@
2742
     orig_mask = source_mask;
2743
     if (!dest_dir || !*dest_dir) {
2744
 	g_free (source_mask);
2745
+        g_free(def_text);
2746
 	return dest_dir;
2747
     }
2748
     if (source_easy_patterns) {
2749
@@ -982,5 +992,6 @@
2750
     }
2751
     if (val == B_USER)
2752
 	*do_background = 1;
2753
+    g_free(def_text);
2754
     return dest_dir;
2755
 }
2756
diff -Naur mc-4.6.1-old/src/find.c mc-4.6.1/src/find.c
2757
--- mc-4.6.1-old/src/find.c	2005-05-27 16:19:18.000000000 +0200
2758
+++ mc-4.6.1/src/find.c	2005-10-28 10:08:08.049199688 +0200
2759
@@ -205,7 +205,7 @@
2760
 	int l1, maxlen = 0;
2761
 
2762
 	while (i--) {
2763
-	    l1 = strlen (labs[i] = _(labs[i]));
2764
+	    l1 = mbstrlen (labs[i] = _(labs[i]));
2765
 	    if (l1 > maxlen)
2766
 		maxlen = l1;
2767
 	}
2768
@@ -214,7 +214,7 @@
2769
 	    FIND_X = i;
2770
 
2771
 	for (i = sizeof (buts) / sizeof (buts[0]), l1 = 0; i--;) {
2772
-	    l1 += strlen (buts[i] = _(buts[i]));
2773
+	    l1 += mbstrlen (buts[i] = _(buts[i]));
2774
 	}
2775
 	l1 += 21;
2776
 	if (l1 > FIND_X)
2777
@@ -223,8 +223,8 @@
2778
 	ilen = FIND_X - 7 - maxlen;	/* for the case of very long buttons :) */
2779
 	istart = FIND_X - 3 - ilen;
2780
 
2781
-	b1 = b0 + strlen (buts[0]) + 7;
2782
-	b2 = FIND_X - (strlen (buts[2]) + 6);
2783
+	b1 = b0 + mbstrlen (buts[0]) + 7;
2784
+	b2 = FIND_X - (mbstrlen (buts[2]) + 6);
2785
 
2786
 	i18n_flag = 1;
2787
 	case_label = _(case_label);
2788
@@ -813,7 +813,7 @@
2789
     if (!i18n_flag) {
2790
 	register int i = sizeof (fbuts) / sizeof (fbuts[0]);
2791
 	while (i--)
2792
-	    fbuts[i].len = strlen (fbuts[i].text = _(fbuts[i].text)) + 3;
2793
+	    fbuts[i].len = mbstrlen (fbuts[i].text = _(fbuts[i].text)) + 3;
2794
 	fbuts[2].len += 2;	/* DEFPUSH_BUTTON */
2795
 	i18n_flag = 1;
2796
     }
2797
diff -Naur mc-4.6.1-old/src/global.h mc-4.6.1/src/global.h
2798
--- mc-4.6.1-old/src/global.h	2004-09-25 15:46:23.000000000 +0200
2799
+++ mc-4.6.1/src/global.h	2005-10-28 10:11:08.071832088 +0200
2800
@@ -146,6 +146,13 @@
2801
 #   define N_(String) (String)
2802
 #endif /* !ENABLE_NLS */
2803
 
2804
+#include <slang.h>
2805
+#if SLANG_VERSION >= 20000
2806
+#define UTF8 1
2807
+#define SLsmg_Is_Unicode SLsmg_is_utf8_mode()
2808
+void SLsmg_write_nwchars(wchar_t *s, size_t n);
2809
+#endif
2810
+
2811
 #include "fs.h"
2812
 #include "util.h"
2813
 
2814
diff -Naur mc-4.6.1-old/src/help.c mc-4.6.1/src/help.c
2815
--- mc-4.6.1-old/src/help.c	2005-05-27 16:19:18.000000000 +0200
2816
+++ mc-4.6.1/src/help.c	2005-10-28 10:09:53.961098632 +0200
2817
@@ -445,10 +445,28 @@
2818
 #ifndef HAVE_SLANG
2819
 			addch (acs_map [c]);
2820
 #else
2821
+#if defined(UTF8) && SLANG_VERSION < 20000
2822
+			SLsmg_draw_object (h->y + line + 2, h->x + col + 2, acs_map [c]);
2823
+#else
2824
 			SLsmg_draw_object (h->y + line + 2, h->x + col + 2, c);
2825
+#endif /* UTF8 */
2826
 #endif
2827
+		} else {
2828
+#ifdef UTF8
2829
+		if (SLsmg_Is_Unicode) {
2830
+		    int len;
2831
+		    mbstate_t mbs;
2832
+                   wchar_t wc;
2833
+		    memset (&mbs, 0, sizeof (mbs));
2834
+		    len = mbrtowc(&wc, p, MB_CUR_MAX, &mbs);
2835
+		    if (len <= 0) len = 1; /* skip broken multibyte chars */
2836
+
2837
+            	    SLsmg_write_char(wc);
2838
+		    p += len - 1;
2839
 		} else
2840
+#endif
2841
 		    addch (c);
2842
+		}
2843
 		col++;
2844
 		break;
2845
 	    }
2846
@@ -771,6 +789,12 @@
2847
 	message (1, MSG_ERROR, _(" Cannot open file %s \n %s "), filename ? filename : hlpfile,
2848
 		 unix_error_string (errno));
2849
     }
2850
+    else
2851
+    {
2852
+	char *conv = utf8_to_local(data);
2853
+	g_free(data);
2854
+	data = conv;
2855
+    }
2856
 
2857
     if (!filename)
2858
 	g_free (hlpfile);
2859
diff -Naur mc-4.6.1-old/src/hotlist.c mc-4.6.1/src/hotlist.c
2860
--- mc-4.6.1-old/src/hotlist.c	2005-05-27 16:19:18.000000000 +0200
2861
+++ mc-4.6.1/src/hotlist.c	2005-10-28 10:08:07.918219600 +0200
2862
@@ -555,7 +555,7 @@
2863
 
2864
 			row = hotlist_but [i].y;
2865
 			++count [row];
2866
-			len [row] += strlen (hotlist_but [i].text) + 5;
2867
+			len [row] += mbstrlen (hotlist_but [i].text) + 5;
2868
 			if (hotlist_but [i].flags == DEFPUSH_BUTTON)
2869
 				len [row] += 2;
2870
 		}
2871
@@ -580,12 +580,12 @@
2872
 				/* not first int the row */
2873
 				if (!strcmp (hotlist_but [i].text, cancel_but))
2874
 					hotlist_but [i].x = 
2875
-						cols - strlen (hotlist_but [i].text) - 13;
2876
+						cols - mbstrlen (hotlist_but [i].text) - 13;
2877
 				else
2878
 					hotlist_but [i].x = cur_x [row];
2879
 			}
2880
 
2881
-			cur_x [row] += strlen (hotlist_but [i].text) + 2
2882
+			cur_x [row] += mbstrlen (hotlist_but [i].text) + 2
2883
 				+ (hotlist_but [i].flags == DEFPUSH_BUTTON ? 5 : 3);
2884
 		}
2885
 	}
2886
@@ -814,7 +814,7 @@
2887
 	for (i = 0; i < 3; i++)
2888
 	{
2889
 		qw [i].text = _(qw [i].text);
2890
-		l[i] = strlen (qw [i].text) + 3;
2891
+		l[i] = mbstrlen (qw [i].text) + 3;
2892
 	}
2893
 	space = (len - 4 - l[0] - l[1] - l[2]) / 4;
2894
 
2895
@@ -860,7 +860,7 @@
2896
 	static int i18n_flag = 0;
2897
 #endif /* ENABLE_NLS */
2898
 
2899
-    len = max (strlen (header), (size_t) msglen (text1, &lines1));
2900
+    len = max ((int) mbstrlen (header), (size_t) msglen (text1, &lines1));
2901
     len = max (len, (size_t) msglen (text2, &lines2)) + 4;
2902
     len = max (len, 64);
2903
 
2904
@@ -955,7 +955,7 @@
2905
 	static int i18n_flag = 0;
2906
 #endif /* ENABLE_NLS */
2907
     
2908
-    len = max (strlen (header), (size_t) msglen (label, &lines)) + 4;
2909
+    len = max ((int) mbstrlen (header), (size_t) msglen (label, &lines)) + 4;
2910
     len = max (len, 64);
2911
 
2912
 #ifdef ENABLE_NLS
2913
@@ -1011,7 +1011,7 @@
2914
 {
2915
     char *prompt, *label;
2916
     const char *cp = _("Label for \"%s\":");
2917
-    int l = strlen (cp);
2918
+    int l = mbstrlen (cp);
2919
     char *label_string = g_strdup (current_panel->cwd);
2920
 
2921
     strip_password (label_string, 1);
2922
diff -Naur mc-4.6.1-old/src/layout.c mc-4.6.1/src/layout.c
2923
--- mc-4.6.1-old/src/layout.c	2005-05-27 16:19:18.000000000 +0200
2924
+++ mc-4.6.1/src/layout.c	2005-10-28 10:08:07.947215192 +0200
2925
@@ -362,36 +362,36 @@
2926
 
2927
 	while (i--) {
2928
 	    s_split_direction[i] = _(s_split_direction[i]);
2929
-	    l1 = strlen (s_split_direction[i]) + 7;
2930
+	    l1 = mbstrlen (s_split_direction[i]) + 7;
2931
 	    if (l1 > first_width)
2932
 		first_width = l1;
2933
 	}
2934
 
2935
 	for (i = 0; i <= 8; i++) {
2936
 	    check_options[i].text = _(check_options[i].text);
2937
-	    l1 = strlen (check_options[i].text) + 7;
2938
+	    l1 = mbstrlen (check_options[i].text) + 7;
2939
 	    if (l1 > first_width)
2940
 		first_width = l1;
2941
 	}
2942
 
2943
-	l1 = strlen (title1) + 1;
2944
+	l1 = mbstrlen (title1) + 1;
2945
 	if (l1 > first_width)
2946
 	    first_width = l1;
2947
 
2948
-	l1 = strlen (title2) + 1;
2949
+	l1 = mbstrlen (title2) + 1;
2950
 	if (l1 > first_width)
2951
 	    first_width = l1;
2952
 
2953
 
2954
-	second_width = strlen (title3) + 1;
2955
+	second_width = mbstrlen (title3) + 1;
2956
 	for (i = 0; i < 6; i++) {
2957
 	    check_options[i].text = _(check_options[i].text);
2958
-	    l1 = strlen (check_options[i].text) + 7;
2959
+	    l1 = mbstrlen (check_options[i].text) + 7;
2960
 	    if (l1 > second_width)
2961
 		second_width = l1;
2962
 	}
2963
 	if (console_flag) {
2964
-	    l1 = strlen (output_lines_label) + 13;
2965
+	    l1 = mbstrlen (output_lines_label) + 13;
2966
 	    if (l1 > second_width)
2967
 		second_width = l1;
2968
 	}
2969
@@ -405,14 +405,14 @@
2970
 	 *
2971
 	 * Now the last thing to do - properly space buttons...
2972
 	 */
2973
-	l1 = 11 + strlen (ok_button)	/* 14 - all brackets and inner space */
2974
-	    +strlen (save_button)	/* notice: it is 3 char less because */
2975
-	    +strlen (cancel_button);	/* of '&' char in button text */
2976
+	l1 = 11 + mbstrlen (ok_button)	/* 14 - all brackets and inner space */
2977
+	    +mbstrlen (save_button)	/* notice: it is 3 char less because */
2978
+	    +mbstrlen (cancel_button);	/* of '&' char in button text */
2979
 
2980
 	i = (first_width + second_width - l1) / 4;
2981
 	b1 = 5 + i;
2982
-	b2 = b1 + strlen (ok_button) + i + 6;
2983
-	b3 = b2 + strlen (save_button) + i + 4;
2984
+	b2 = b1 + mbstrlen (ok_button) + i + 6;
2985
+	b3 = b2 + mbstrlen (save_button) + i + 4;
2986
 
2987
 	i18n_layt_flag = 1;
2988
     }
2989
@@ -684,7 +684,7 @@
2990
     panel_do_cols (0);
2991
     panel_do_cols (1);
2992
 
2993
-    promptl = strlen (prompt);
2994
+    promptl = mbstrlen (prompt);
2995
 
2996
     widget_set_size (&the_menubar->widget, 0, 0, 1, COLS);
2997
 
2998
diff -Naur mc-4.6.1-old/src/learn.c mc-4.6.1/src/learn.c
2999
--- mc-4.6.1-old/src/learn.c	2005-05-27 16:19:18.000000000 +0200
3000
+++ mc-4.6.1/src/learn.c	2005-10-28 10:08:07.787239512 +0200
3001
@@ -236,7 +236,7 @@
3002
 	learn_but[0].x = 78 / 2 + 4;
3003
 
3004
 	learn_but[1].text = _(learn_but[1].text);
3005
-	learn_but[1].x = 78 / 2 - (strlen (learn_but[1].text) + 9);
3006
+	learn_but[1].x = 78 / 2 - (mbstrlen (learn_but[1].text) + 9);
3007
 
3008
 	learn_title = _(learn_title);
3009
 	i18n_flag = 1;
3010
diff -Naur mc-4.6.1-old/src/main.c mc-4.6.1/src/main.c
3011
--- mc-4.6.1-old/src/main.c	2005-07-23 18:52:02.000000000 +0200
3012
+++ mc-4.6.1/src/main.c	2005-10-28 10:08:07.816235104 +0200
3013
@@ -1609,7 +1609,11 @@
3014
     if (xterm_flag && xterm_title) {
3015
 	p = s = g_strdup (strip_home_and_password (current_panel->cwd));
3016
 	do {
3017
+#ifndef UTF8
3018
 	    if (!is_printable (*s))
3019
+#else /* UTF8 */
3020
+            if (*s < ' ')
3021
+#endif /* UTF8 */
3022
 		*s = '?';
3023
 	} while (*++s);
3024
 	fprintf (stdout, "\33]0;mc - %s\7", p);
3025
diff -Naur mc-4.6.1-old/src/menu.c mc-4.6.1/src/menu.c
3026
--- mc-4.6.1-old/src/menu.c	2005-05-27 16:19:18.000000000 +0200
3027
+++ mc-4.6.1/src/menu.c	2005-10-28 10:08:08.110190416 +0200
3028
@@ -20,6 +20,8 @@
3029
 #include <stdarg.h>
3030
 #include <sys/types.h>
3031
 #include <ctype.h>
3032
+#include <wchar.h>
3033
+
3034
 #include "global.h"
3035
 #include "tty.h"
3036
 #include "menu.h"
3037
@@ -50,33 +52,96 @@
3038
 {
3039
     Menu *menu;
3040
     const char *cp;
3041
+    int wlen = 0;
3042
+    mbstate_t s;
3043
 
3044
     menu = (Menu *) g_malloc (sizeof (*menu));
3045
     menu->count = count;
3046
     menu->max_entry_len = 20;
3047
     menu->entries = entries;
3048
+    menu->name = g_strdup (name);
3049
+    menu_scan_hotkey (menu);
3050
+#ifdef UTF8
3051
+    menu->wentries = NULL;
3052
+    menu->wname = NULL;
3053
+    if (SLsmg_Is_Unicode) {
3054
+      const char *str = menu->name;
3055
+      memset (&s, 0, sizeof (s));
3056
+      wlen = mbsrtowcs (NULL, &str, -1, &s);
3057
+      if (wlen > 0)
3058
+        ++wlen;
3059
+      else {
3060
+        wlen = 0;
3061
+        memset (&s, 0, sizeof (s));
3062
+      }
3063
+    }
3064
+#endif
3065
 
3066
     if (entries != (menu_entry*) NULL) {
3067
 	register menu_entry* mp;
3068
 	for (mp = entries; count--; mp++) {
3069
 	    if (mp->text[0] != '\0') {
3070
+		int len;
3071
 #ifdef ENABLE_NLS
3072
 	        mp->text = _(mp->text);
3073
 #endif /* ENABLE_NLS */
3074
 	        cp = strchr (mp->text,'&');
3075
 
3076
+#ifdef UTF8
3077
+		if (SLsmg_Is_Unicode) {
3078
+                    len = mbstrlen(mp->text) + 1;
3079
+                    wlen += len;
3080
+                    menu->max_entry_len = max (len - 1, menu->max_entry_len);
3081
+                } else
3082
+#endif
3083
+                    len = strlen (mp->text);
3084
+
3085
 		if (cp != NULL && *(cp+1) != '\0') {
3086
 		    mp->hot_key = tolower (*(cp+1));
3087
-		    menu->max_entry_len = max ((int) (strlen (mp->text) - 1),
3088
-			menu->max_entry_len);
3089
+		    menu->max_entry_len = max (len - 1, menu->max_entry_len);
3090
 		} else {
3091
-		    menu->max_entry_len = max ((int) strlen (mp->text),
3092
-			menu->max_entry_len);
3093
+		    menu->max_entry_len = max (len, menu->max_entry_len);
3094
 		}
3095
 	    }
3096
 	}
3097
     }
3098
 
3099
+#ifdef UTF8
3100
+    if (wlen) {
3101
+      wchar_t *wp;
3102
+      const char *str;
3103
+      int len;
3104
+
3105
+      menu->wentries = (wchar_t **)
3106
+                       g_malloc (sizeof (wchar_t *) * menu->count
3107
+                                 + wlen * sizeof (wchar_t));
3108
+      wp = (wchar_t *) (menu->wentries + menu->count);
3109
+      str = menu->name;
3110
+      len = mbsrtowcs (wp, &str, wlen, &s);
3111
+      if (len > 0) {
3112
+          menu->wname = wp;
3113
+          wlen -= len + 1;
3114
+          wp += len + 1;
3115
+      } else
3116
+          memset (&s, 0, sizeof (s));
3117
+      if (menu->entries != NULL)
3118
+          for (count = 0; count < menu->count; ++count)
3119
+              if (menu->entries[count].text[0] != '\0') {
3120
+                  str = menu->entries[count].text;
3121
+                  menu->wentries[count] = wp;
3122
+                  len = mbsrtowcs (wp, &str, wlen, &s);
3123
+                  if (len > 0) {
3124
+                      wlen -= len + 1;
3125
+                      wp += len + 1;
3126
+                  } else {
3127
+                      memset (&s, 0, sizeof (s));
3128
+                      *wp++ = L'\0';
3129
+                      --wlen;
3130
+                  }
3131
+              }
3132
+    }
3133
+#endif
3134
+
3135
     menu->name = g_strdup (name);
3136
     menu_scan_hotkey(menu);
3137
     menu->start_x = 0;
3138
@@ -109,8 +174,26 @@
3139
 	const unsigned char *text;
3140
 
3141
 	addch((unsigned char)menu->entries [idx].first_letter);
3142
-	for (text = menu->entries [idx].text; *text; text++)
3143
-	{
3144
+#ifdef UTF8
3145
+	if (menu->wentries) {
3146
+	    wchar_t *wtext, *wp;
3147
+
3148
+	    for (wtext = wp = menu->wentries [idx]; *wtext; wtext++) {
3149
+		if (*wtext == L'&') {
3150
+		    if (wtext > wp)
3151
+			SLsmg_write_nwchars (wp, wtext - wp);
3152
+		    attrset (color == MENU_SELECTED_COLOR ?
3153
+			MENU_HOTSEL_COLOR : MENU_HOT_COLOR);
3154
+		    SLsmg_write_nwchars (++wtext, 1);
3155
+		    attrset (color);
3156
+		    wp = wtext + 1;
3157
+		}
3158
+	    }
3159
+	    if (wtext > wp)
3160
+		SLsmg_write_nwchars (wp, wtext - wp);
3161
+	} else
3162
+#endif
3163
+	    for (text = menu->entries [idx].text; *text; text++) {
3164
 		if (*text != '&')
3165
 		    addch(*text);
3166
 		else {
3167
@@ -119,7 +202,7 @@
3168
 		    addch(*(++text));
3169
 		    attrset(color);
3170
 		}
3171
-	}
3172
+	    }
3173
     }
3174
     widget_move (&menubar->widget, y, x + 1);
3175
 }
3176
@@ -167,7 +250,13 @@
3177
 	if (menubar->active)
3178
 	    attrset(i == menubar->selected?MENU_SELECTED_COLOR:SELECTED_COLOR);
3179
 	widget_move (&menubar->widget, 0, menubar->menu [i]->start_x);
3180
-	printw ("%s", menubar->menu [i]->name);
3181
+#ifdef UTF8
3182
+	if (menubar->menu [i]->wname)
3183
+	    SLsmg_write_nwchars (menubar->menu [i]->wname,
3184
+				 wcslen (menubar->menu [i]->wname));
3185
+	else
3186
+#endif
3187
+	    printw ("%s", menubar->menu [i]->name);
3188
     }
3189
 
3190
     if (menubar->dropped)
3191
@@ -489,7 +578,13 @@
3192
 
3193
 	for (i = 0; i < items; i++)
3194
 	{
3195
-		int len = strlen(menubar->menu[i]->name);
3196
+		int len;
3197
+#ifdef UTF8
3198
+		if (menubar->menu[i]->wname)
3199
+		    len = wcslen (menubar->menu[i]->wname);
3200
+		else
3201
+#endif		
3202
+		    len = strlen(menubar->menu[i]->name);
3203
 		menubar->menu[i]->start_x = start_x;
3204
 		start_x += len + gap;
3205
 	}
3206
@@ -502,7 +597,13 @@
3207
 	for (i = 0; i < items; i++)
3208
 	{
3209
 		/* preserve length here, to be used below */
3210
-		gap -= (menubar->menu[i]->start_x = strlen(menubar->menu[i]->name));
3211
+#ifdef UTF8
3212
+		if (menubar->menu[i]->wname)
3213
+		    menubar->menu[i]->start_x = wcslen (menubar->menu[i]->wname);
3214
+		else
3215
+#endif
3216
+		    menubar->menu[i]->start_x = strlen (menubar->menu[i]->name);
3217
+		gap -= menubar->menu[i]->start_x;
3218
 	}
3219
 
3220
 	gap /= (items - 1);
3221
@@ -526,6 +627,9 @@
3222
 void
3223
 destroy_menu (Menu *menu)
3224
 {
3225
+#ifdef UTF8
3226
+    g_free (menu->wentries);
3227
+#endif
3228
     g_free (menu->name);
3229
     g_free (menu->help_node);
3230
     g_free (menu);
3231
diff -Naur mc-4.6.1-old/src/menu.h mc-4.6.1/src/menu.h
3232
--- mc-4.6.1-old/src/menu.h	2004-09-18 16:30:59.000000000 +0200
3233
+++ mc-4.6.1/src/menu.h	2005-10-28 10:08:07.949214888 +0200
3234
@@ -21,6 +21,8 @@
3235
     menu_entry *entries;
3236
     int    start_x;		/* position relative to menubar start */
3237
     char   *help_node;
3238
+    wchar_t **wentries;
3239
+    wchar_t *wname;
3240
 } Menu;
3241
 
3242
 extern int menubar_visible;
3243
diff -Naur mc-4.6.1-old/src/myslang.h mc-4.6.1/src/myslang.h
3244
--- mc-4.6.1-old/src/myslang.h	2004-10-12 06:32:04.000000000 +0200
3245
+++ mc-4.6.1/src/myslang.h	2005-10-28 10:08:07.831232824 +0200
3246
@@ -11,6 +11,10 @@
3247
 #endif	/* HAVE_SLANG_SLANG_H */
3248
 #endif
3249
 
3250
+#ifdef UTF8
3251
+#    include <wchar.h>
3252
+#endif
3253
+
3254
 enum {
3255
     KEY_BACKSPACE = 400,
3256
     KEY_END, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT,
3257
diff -Naur mc-4.6.1-old/src/option.c mc-4.6.1/src/option.c
3258
--- mc-4.6.1-old/src/option.c	2005-05-27 16:19:18.000000000 +0200
3259
+++ mc-4.6.1/src/option.c	2005-10-28 10:08:08.121188744 +0200
3260
@@ -124,12 +124,12 @@
3261
 	title2 = _(" Pause after run... ");
3262
 	title3 = _(" Other options ");
3263
 
3264
-	first_width = strlen (title1) + 1;
3265
-	second_width = strlen (title3) + 1;
3266
+	first_width = mbstrlen (title1) + 1;
3267
+	second_width = mbstrlen (title3) + 1;
3268
 
3269
 	for (i = 0; check_options[i].text; i++) {
3270
 	    check_options[i].text = _(check_options[i].text);
3271
-	    l1 = strlen (check_options[i].text) + 7;
3272
+	    l1 = mbstrlen (check_options[i].text) + 7;
3273
 	    if (i >= OTHER_OPTIONS) {
3274
 		if (l1 > first_width)
3275
 		    first_width = l1;
3276
@@ -142,23 +142,23 @@
3277
 	i = PAUSE_OPTIONS;
3278
 	while (i--) {
3279
 	    pause_options[i] = _(pause_options[i]);
3280
-	    l1 = strlen (pause_options[i]) + 7;
3281
+	    l1 = mbstrlen (pause_options[i]) + 7;
3282
 	    if (l1 > first_width)
3283
 		first_width = l1;
3284
 	}
3285
 
3286
-	l1 = strlen (title2) + 1;
3287
+	l1 = mbstrlen (title2) + 1;
3288
 	if (l1 > first_width)
3289
 	    first_width = l1;
3290
 
3291
-	l1 = 11 + strlen (ok_button)
3292
-	    + strlen (save_button)
3293
-	    + strlen (cancel_button);
3294
+	l1 = 11 + mbstrlen (ok_button)
3295
+	    + mbstrlen (save_button)
3296
+	    + mbstrlen (cancel_button);
3297
 
3298
 	i = (first_width + second_width - l1) / 4;
3299
 	b1 = 5 + i;
3300
-	b2 = b1 + strlen (ok_button) + i + 6;
3301
-	b3 = b2 + strlen (save_button) + i + 4;
3302
+	b2 = b1 + mbstrlen (ok_button) + i + 6;
3303
+	b3 = b2 + mbstrlen (save_button) + i + 4;
3304
 
3305
 	i18n_config_flag = 1;
3306
     }
3307
diff -Naur mc-4.6.1-old/src/panelize.c mc-4.6.1/src/panelize.c
3308
--- mc-4.6.1-old/src/panelize.c	2005-05-27 16:19:18.000000000 +0200
3309
+++ mc-4.6.1/src/panelize.c	2005-10-28 10:08:07.933217320 +0200
3310
@@ -127,7 +127,7 @@
3311
 	i = sizeof (panelize_but) / sizeof (panelize_but[0]);
3312
 	while (i--) {
3313
 	    panelize_but[i].text = _(panelize_but[i].text);
3314
-	    maxlen += strlen (panelize_but[i].text) + 5;
3315
+	    maxlen += mbstrlen (panelize_but[i].text) + 5;
3316
 	}
3317
 	maxlen += 10;
3318
 
3319
@@ -136,11 +136,11 @@
3320
     panelize_cols = max (panelize_cols, maxlen);
3321
 
3322
     panelize_but[2].x =
3323
-	panelize_but[3].x + strlen (panelize_but[3].text) + 7;
3324
+	panelize_but[3].x + mbstrlen (panelize_but[3].text) + 7;
3325
     panelize_but[1].x =
3326
-	panelize_but[2].x + strlen (panelize_but[2].text) + 5;
3327
+	panelize_but[2].x + mbstrlen (panelize_but[2].text) + 5;
3328
     panelize_but[0].x =
3329
-	panelize_cols - strlen (panelize_but[0].text) - 8 - BX;
3330
+	panelize_cols - mbstrlen (panelize_but[0].text) - 8 - BX;
3331
 
3332
 #endif				/* ENABLE_NLS */
3333
 
3334
diff -Naur mc-4.6.1-old/src/screen.c mc-4.6.1/src/screen.c
3335
--- mc-4.6.1-old/src/screen.c	2005-05-27 16:19:18.000000000 +0200
3336
+++ mc-4.6.1/src/screen.c	2005-10-28 10:08:07.987209112 +0200
3337
@@ -169,22 +169,59 @@
3338
 static const char *
3339
 string_file_name (file_entry *fe, int len)
3340
 {
3341
-    static char buffer [BUF_SMALL];
3342
     size_t i;
3343
+#ifdef UTF8
3344
+    static char buffer [BUF_SMALL * 4];
3345
+    mbstate_t s;
3346
+    int mbmax = MB_CUR_MAX;
3347
+    const char *str = fe->fname;
3348
 
3349
-    for (i = 0; i < sizeof(buffer) - 1; i++) {
3350
-	char c;
3351
+    memset (&s, 0, sizeof (s));
3352
+#else
3353
+    static char buffer [BUF_SMALL];
3354
+#endif
3355
 
3356
-	c = fe->fname[i];
3357
+#ifdef UTF8
3358
+    if (SLsmg_Is_Unicode)
3359
+	for (i = 0; i < sizeof (buffer) - 1; i++) {
3360
+	    wchar_t wc;
3361
+	    int len;
3362
 
3363
-	if (!c)
3364
-	    break;
3365
+	    len = mbrtowc (&wc, str, mbmax, &s);
3366
+	    if (!len)
3367
+		break;
3368
+	    if (len < 0) {
3369
+		memset (&s, 0, sizeof (s));
3370
+		buffer[i] = '?';
3371
+		str++;
3372
+		continue;
3373
+	    }
3374
+	    if (!is_printable (wc)) {
3375
+		buffer[i] = '?';
3376
+		str++;
3377
+		continue;
3378
+	    }
3379
+	    if (i >= sizeof (buffer) - len)
3380
+		break;
3381
+	    memcpy (buffer + i, str, len);
3382
+	    i += len - 1;
3383
+	    str += len;
3384
+	}
3385
+    else
3386
+#endif
3387
+      for (i = 0; i < sizeof(buffer) - 1; i++) {
3388
+	  char c;
3389
 
3390
-	if (!is_printable(c))
3391
-	    c = '?';
3392
+	  c = fe->fname[i];
3393
 
3394
-	buffer[i] = c;
3395
-    }
3396
+	  if (!c)
3397
+	      break;
3398
+
3399
+	  if (!is_printable(c))
3400
+	      c = '?';
3401
+
3402
+	  buffer[i] = c;
3403
+      }
3404
 
3405
     buffer[i] = 0;
3406
     return buffer;
3407
@@ -425,42 +462,6 @@
3408
 { "dot",   1,  0, J_RIGHT,	" ",		0, string_dot,		   NULL },
3409
 };
3410
 
3411
-static char *
3412
-to_buffer (char *dest, int just_mode, int len, const char *txt)
3413
-{
3414
-    int txtlen = strlen (txt);
3415
-    int still, over;
3416
-
3417
-    /* Fill buffer with spaces */
3418
-    memset (dest, ' ', len);
3419
-
3420
-    still = (over=(txtlen > len)) ? (txtlen - len) : (len - txtlen);
3421
-
3422
-    switch (HIDE_FIT(just_mode)){
3423
-        case J_LEFT:
3424
-	    still = 0;
3425
-	    break;
3426
-	case J_CENTER:
3427
-	    still /= 2;
3428
-	    break;
3429
-	case J_RIGHT:
3430
-	default:
3431
-	    break;
3432
-    }
3433
-
3434
-    if (over){
3435
-	if (IS_FIT(just_mode))
3436
-	    strcpy (dest, name_trunc(txt, len));
3437
-	else
3438
-	    strncpy (dest, txt+still, len);
3439
-    } else
3440
-	strncpy (dest+still, txt, txtlen);
3441
-
3442
-    dest[len] = '\0';
3443
-
3444
-    return (dest + len);
3445
-}
3446
-
3447
 static int
3448
 file_compute_color (int attr, file_entry *fe)
3449
 {
3450
@@ -514,14 +515,18 @@
3451
 
3452
 /* Formats the file number file_index of panel in the buffer dest */
3453
 static void
3454
-format_file (char *dest, int limit, WPanel *panel, int file_index, int width, int attr, int isstatus)
3455
+format_file (WPanel *panel, int file_index, int width, int attr, int isstatus)
3456
 {
3457
     int      color, length, empty_line;
3458
     const char *txt;
3459
-    char     *old_pos;
3460
-    char     *cdest = dest;
3461
     format_e *format, *home;
3462
     file_entry *fe;
3463
+#ifdef UTF8
3464
+    char     buffer[BUF_MEDIUM * sizeof (wchar_t)];
3465
+#else
3466
+    char     buffer[BUF_MEDIUM];
3467
+#endif
3468
+    int txtwidth;
3469
 
3470
     length     = 0;
3471
     empty_line = (file_index >= panel->count);
3472
@@ -539,34 +544,137 @@
3473
 	    break;
3474
 
3475
 	if (format->string_fn){
3476
-	    int len;
3477
+	    int len, still, over, perm, txtlen, wide;
3478
 
3479
 	    if (empty_line)
3480
 		txt = " ";
3481
 	    else
3482
 		txt = (*format->string_fn)(fe, format->field_len);
3483
 
3484
-	    old_pos = cdest;
3485
-
3486
 	    len = format->field_len;
3487
 	    if (len + length > width)
3488
 		len = width - length;
3489
-	    if (len + (cdest - dest) > limit)
3490
-		len = limit - (cdest - dest);
3491
+	    if (len >= BUF_MEDIUM)
3492
+		len = BUF_MEDIUM - 1;
3493
 	    if (len <= 0)
3494
 		break;
3495
-	    cdest = to_buffer (cdest, format->just_mode, len, txt);
3496
-	    length += len;
3497
 
3498
-            attrset (color);
3499
+	    perm = 0;
3500
+            if (permission_mode) {
3501
+		if (!strcmp(format->id, "perm"))
3502
+		    perm = 1;
3503
+		else if (!strcmp(format->id, "mode"))
3504
+		    perm = 2;
3505
+	    }
3506
+
3507
+	    wide = 0;
3508
+#ifdef UTF8
3509
+	    if (SLsmg_Is_Unicode && !empty_line && !perm) {
3510
+		mbstate_t s;
3511
+		const char *str = txt;
3512
+
3513
+		memset (&s, 0, sizeof (s));
3514
+		txtlen = mbsrtowcs ((wchar_t *) buffer, &str,
3515
+				    sizeof (buffer) / sizeof (wchar_t), &s);
3516
+		if (txtlen < 0) {
3517
+		    txt = " ";
3518
+		    txtlen = 1;
3519
+		} else {
3520
+		    wide = 1;
3521
+		    txtwidth = wcswidth((wchar_t*)buffer, txtlen);
3522
+		}
3523
+	    } else
3524
+#endif
3525
+	    {
3526
+		txtlen = strlen (txt);
3527
+		txtwidth = txtlen;
3528
+	    }
3529
+
3530
+	    over = txtwidth > len;
3531
+	    still = over ? txtlen - len : len - txtlen;
3532
 
3533
-            if (permission_mode && !strcmp(format->id, "perm"))
3534
-                add_permission_string (old_pos, format->field_len, fe, attr, color, 0);
3535
-            else if (permission_mode && !strcmp(format->id, "mode"))
3536
-                add_permission_string (old_pos, format->field_len, fe, attr, color, 1);
3537
-            else
3538
-		addstr (old_pos);
3539
+	    switch (HIDE_FIT(format->just_mode)) {
3540
+	    case J_LEFT:
3541
+		still = 0;
3542
+		break;
3543
+	    case J_CENTER:
3544
+		still /= 2;
3545
+		break;
3546
+	    case J_RIGHT:
3547
+	    default:
3548
+		break;
3549
+	    }
3550
+
3551
+	    attrset (color);
3552
+
3553
+	    if (wide) {
3554
+#ifdef UTF8
3555
+		if (over) {
3556
+		    if (IS_FIT (format->just_mode)) {
3557
+			int n1 = 0;
3558
+			int width1 = 0;
3559
+			int n2 = 0;
3560
+			int width2 = 0;
3561
+			int len1 = len / 2;
3562
+			int len2;
3563
+			
3564
+			while (1) {
3565
+			    int w = wcwidth(((wchar_t *) buffer)[n1]);
3566
+			    if (width1 + w <= len1) {
3567
+				width1 += w;
3568
+				n1++;
3569
+			    }
3570
+			    else
3571
+				break;
3572
+			}
3573
+			len2 = len - width1 - 1;
3574
+
3575
+			while (1) {
3576
+			    int w = wcwidth(((wchar_t *) buffer)[txtlen - n2 - 1]);
3577
+			    if (width2 + w <= len2) {
3578
+				width2 += w;
3579
+				n2++;
3580
+			    }
3581
+			    else
3582
+				break;
3583
+			}
3584
+			
3585
+
3586
+			SLsmg_write_nwchars ((wchar_t *) buffer, n1);
3587
+			SLsmg_write_nwchars (L"~", 1);
3588
+			printw ("%*s", len - width1 - width2 - 1, "");
3589
+			SLsmg_write_nwchars (((wchar_t *) buffer)
3590
+					     + txtlen - n2, n2);
3591
+		    } else
3592
+			SLsmg_write_nwchars ((wchar_t *) buffer, len);
3593
+		} else {
3594
+		    printw ("%*s", still, "");
3595
+		    SLsmg_write_nwchars ((wchar_t *) buffer, txtlen);
3596
+		    printw ("%*s", len - txtwidth - still, "");
3597
+		}
3598
+#endif
3599
+	    } else {
3600
+		if (over) {
3601
+		    if (IS_FIT (format->just_mode))
3602
+			strcpy (buffer, name_trunc(txt, len));
3603
+		    else
3604
+			memcpy (buffer, txt + still, len);
3605
+		} else {
3606
+		    memset (buffer, ' ', still);
3607
+		    memcpy (buffer + still, txt, txtlen);
3608
+		    memset (buffer + still + txtlen, ' ',
3609
+			    len - txtlen - still);
3610
+		}
3611
+		buffer[len] = '\0';
3612
 
3613
+		if (perm)
3614
+		    add_permission_string (buffer, format->field_len, fe,
3615
+					   attr, color, perm - 1);
3616
+		else
3617
+		    addstr (buffer);
3618
+	    }
3619
+
3620
+	    length += len;
3621
 	} else {
3622
             if (attr == SELECTED || attr == MARKED_SELECTED)
3623
                 attrset (SELECTED_COLOR);
3624
@@ -589,7 +697,6 @@
3625
 {
3626
     int    second_column = 0;
3627
     int	   width, offset;
3628
-    char   buffer [BUF_MEDIUM];
3629
 
3630
     offset = 0;
3631
     if (!isstatus && panel->split){
3632
@@ -618,7 +725,7 @@
3633
 	    widget_move (&panel->widget, file_index - panel->top_file + 2, 1);
3634
     }
3635
 
3636
-    format_file (buffer, sizeof(buffer), panel, file_index, width, attr, isstatus);
3637
+    format_file (panel, file_index, width, attr, isstatus);
3638
 
3639
     if (!isstatus && panel->split){
3640
 	if (second_column)
3641
@@ -1068,6 +1175,12 @@
3642
     int  side, width;
3643
 
3644
     const char *txt;
3645
+#ifdef UTF8
3646
+    char buffer[30 * sizeof (wchar_t)];
3647
+    mbstate_t s;
3648
+
3649
+    memset (&s, 0, sizeof (s));
3650
+#endif
3651
     if (!panel->split)
3652
 	adjust_top_file (panel);
3653
 
3654
@@ -1092,16 +1205,37 @@
3655
             if (format->string_fn){
3656
                 txt = format->title;
3657
 
3658
+		attrset (MARKED_COLOR);
3659
+		width -= format->field_len;
3660
+#ifdef UTF8
3661
+		if (SLsmg_Is_Unicode) {
3662
+		    const char *str = txt;
3663
+		    header_len = mbsrtowcs ((wchar_t *) buffer, &str,
3664
+					    sizeof (buffer) / sizeof (wchar_t),
3665
+					    &s);
3666
+		    if (header_len < 0) {
3667
+			memset (&s, 0, sizeof (s));
3668
+			printw ("%*s", format->field_len, "");
3669
+			continue;
3670
+		    }
3671
+		    if (header_len > format->field_len)
3672
+			header_len = format->field_len;
3673
+		    spaces = (format->field_len - header_len) / 2;
3674
+		    extra  = (format->field_len - header_len) % 2;
3675
+		    printw ("%*s", spaces, "");
3676
+		    SLsmg_write_nwchars ((wchar_t *) buffer, header_len);
3677
+		    printw ("%*s", spaces + extra, "");
3678
+		    continue;
3679
+		}
3680
+#endif
3681
 		header_len = strlen (txt);
3682
 		if (header_len > format->field_len)
3683
 		    header_len = format->field_len;
3684
 
3685
-                attrset (MARKED_COLOR);
3686
                 spaces = (format->field_len - header_len) / 2;
3687
                 extra  = (format->field_len - header_len) % 2;
3688
 		printw ("%*s%.*s%*s", spaces, "",
3689
 			 header_len, txt, spaces+extra, "");
3690
-		width -= 2 * spaces + extra + header_len;
3691
 	    } else {
3692
 		attrset (NORMAL_COLOR);
3693
 		one_vline ();
3694
diff -Naur mc-4.6.1-old/src/slint.c mc-4.6.1/src/slint.c
3695
--- mc-4.6.1-old/src/slint.c	2005-05-27 16:19:18.000000000 +0200
3696
+++ mc-4.6.1/src/slint.c	2005-10-28 10:08:35.422038384 +0200
3697
@@ -180,6 +180,9 @@
3698
     struct sigaction act, oact;
3699
     
3700
     SLtt_get_terminfo ();
3701
+#if SLANG_VERSION >= 20000
3702
+    SLutf8_enable (-1);
3703
+#endif
3704
 
3705
    /*
3706
     * If the terminal in not in terminfo but begins with a well-known
3707
diff -Naur mc-4.6.1-old/src/util.c mc-4.6.1/src/util.c
3708
--- mc-4.6.1-old/src/util.c	2005-05-27 16:19:18.000000000 +0200
3709
+++ mc-4.6.1/src/util.c	2005-10-28 10:19:11.683311968 +0200
3710
@@ -32,7 +32,11 @@
3711
 #include <stdarg.h>
3712
 #include <string.h>
3713
 #include <ctype.h>
3714
+#include <iconv.h>
3715
+#include <langinfo.h>
3716
+#include <errno.h>
3717
 
3718
+#include "tty.h"
3719
 #include "global.h"
3720
 #include "profile.h"
3721
 #include "main.h"		/* mc_home */
3722
@@ -44,9 +48,22 @@
3723
 #include "charsets.h"
3724
 #endif
3725
 
3726
+#ifdef UTF8
3727
+#include <wctype.h>
3728
+#include <wchar.h>
3729
+#endif
3730
+
3731
 static const char app_text [] = "Midnight-Commander";
3732
 int easy_patterns = 1;
3733
 
3734
+#if SLANG_VERSION >= 20000
3735
+void SLsmg_write_nwchars(wchar_t *s, size_t n)
3736
+{
3737
+ while(n--)
3738
+    SLsmg_write_char(*s++);
3739
+}
3740
+#endif
3741
+
3742
 extern void str_replace(char *s, char from, char to)
3743
 {
3744
     for (; *s != '\0'; s++) {
3745
@@ -77,9 +94,106 @@
3746
     return (c > 31 && c != 127 && c != 155);
3747
 }
3748
 
3749
+size_t
3750
+mbstrlen (const char *str)
3751
+{
3752
+#ifdef UTF8
3753
+    if (SLsmg_Is_Unicode) {
3754
+        size_t width = 0;
3755
+
3756
+        for (; *str; str++) {
3757
+            wchar_t c;
3758
+            size_t len;
3759
+
3760
+            len = mbrtowc (&c, str, MB_CUR_MAX, NULL);
3761
+	    
3762
+            if (len == (size_t)(-1) || len == (size_t)(-2)) break;
3763
+	    
3764
+            if (len > 0) {
3765
+                int wcsize = wcwidth(c);
3766
+                width += wcsize > 0 ? wcsize : 0;
3767
+                str += len-1;
3768
+            }
3769
+        }
3770
+
3771
+        return width;
3772
+    } else
3773
+#endif
3774
+	return strlen (str);
3775
+}
3776
+
3777
+#ifdef UTF8
3778
+
3779
+void 
3780
+fix_utf8(char *str)
3781
+{
3782
+    mbstate_t mbs;
3783
+
3784
+    char *p = str;
3785
+
3786
+    while (*p) {
3787
+	int len;
3788
+        memset (&mbs, 0, sizeof (mbs));
3789
+	len = mbrlen(p, MB_CUR_MAX, &mbs);
3790
+	if (len == -1) {
3791
+	    *p = '?';
3792
+	    p++;
3793
+	} else if (len > 0) {
3794
+	    p += len;
3795
+	} else {
3796
+	    p++;
3797
+	}
3798
+    }
3799
+}
3800
+#endif
3801
+
3802
+
3803
+
3804
+#ifdef UTF8
3805
+wchar_t *
3806
+mbstr_to_wchar (const char *str)
3807
+{
3808
+    int len = mbstrlen(str);
3809
+    wchar_t *buf = g_malloc((len+1) * sizeof(wchar_t));
3810
+    mbstate_t mbs;
3811
+    memset (&mbs, 0, sizeof (mbs));
3812
+    mbsrtowcs (buf, &str, len, &mbs);
3813
+    buf[len] = 0;
3814
+    return buf;
3815
+}
3816
+
3817
+char *
3818
+wchar_to_mbstr (const wchar_t *wstr)
3819
+{
3820
+    mbstate_t mbs;
3821
+    const wchar_t *wstr2;
3822
+    char * string;
3823
+    int len;
3824
+
3825
+    memset (&mbs, 0, sizeof (mbs));
3826
+    wstr2 = wstr;
3827
+    len = wcsrtombs(NULL, &wstr2, 0, &mbs);
3828
+    if (len <= 0) 
3829
+	return NULL;
3830
+
3831
+    string = g_malloc(len + 1);
3832
+
3833
+    wstr2 = wstr;
3834
+    wcsrtombs(string, &wstr2, len, &mbs);
3835
+    string[len] = 0;
3836
+    return string;
3837
+}
3838
+#endif
3839
+
3840
+
3841
+
3842
 int
3843
 is_printable (int c)
3844
 {
3845
+#ifdef UTF8
3846
+    if (SLsmg_Is_Unicode)
3847
+	return iswprint (c);
3848
+#endif
3849
     c &= 0xff;
3850
 
3851
 #ifdef HAVE_CHARSET
3852
@@ -97,7 +211,7 @@
3853
 #endif				/* !HAVE_CHARSET */
3854
 }
3855
 
3856
-/* Returns the message dimensions (lines and columns) */
3857
+/* Returns the message dimensions columns */
3858
 int msglen (const char *text, int *lines)
3859
 {
3860
     int max = 0;
3861
@@ -108,8 +222,18 @@
3862
 	    line_len = 0;
3863
 	    (*lines)++;
3864
 	} else {
3865
-	    line_len++;
3866
-	    if (line_len > max)
3867
+#ifdef UTF8
3868
+            size_t len;
3869
+            wchar_t c;
3870
+
3871
+            len = mbrtowc (&c, text, MB_CUR_MAX, NULL);
3872
+            if (len > 0 && len != (size_t)(-1) && len != (size_t)(-2)) {
3873
+                int wcsize = wcwidth(c);
3874
+                line_len += wcsize > 0 ? wcsize-1 : -1;
3875
+                text += len-1;
3876
+            }
3877
+#endif
3878
+            if (++line_len > max)
3879
 		max = line_len;
3880
 	}
3881
     }
3882
@@ -201,7 +325,24 @@
3883
 		*d++ = '\\';
3884
 	    break;
3885
 	}
3886
+#ifndef UTF8
3887
 	*d = *s;
3888
+#else /* UTF8 */
3889
+	{
3890
+	    mbstate_t mbs;
3891
+           int len;
3892
+           memset (&mbs, 0, sizeof (mbs));
3893
+           len = mbrlen(s, MB_CUR_MAX, &mbs);
3894
+	    if (len > 0) {
3895
+        	while (len-- > 1)
3896
+            	    *d++ = *s++;
3897
+		*d = *s;
3898
+	    } else {
3899
+                *d = '?';
3900
+	    }
3901
+
3902
+	}
3903
+#endif /* UTF8 */
3904
     }
3905
     *d = '\0';
3906
     return ret;
3907
@@ -222,25 +363,90 @@
3908
 name_trunc (const char *txt, int trunc_len)
3909
 {
3910
     static char x[MC_MAXPATHLEN + MC_MAXPATHLEN];
3911
-    int txt_len;
3912
+    int txt_len, first, skip;
3913
     char *p;
3914
+    const char *str;
3915
 
3916
     if ((size_t) trunc_len > sizeof (x) - 1) {
3917
 	trunc_len = sizeof (x) - 1;
3918
     }
3919
-    txt_len = strlen (txt);
3920
-    if (txt_len <= trunc_len) {
3921
-	strcpy (x, txt);
3922
-    } else {
3923
-	int y = (trunc_len / 2) + (trunc_len % 2);
3924
-	strncpy (x, txt, y);
3925
-	strncpy (x + y, txt + txt_len - (trunc_len / 2), trunc_len / 2);
3926
-	x[y] = '~';
3927
-    }
3928
-    x[trunc_len] = 0;
3929
-    for (p = x; *p; p++)
3930
-	if (!is_printable (*p))
3931
-	    *p = '?';
3932
+    txt_len = mbstrlen (txt);
3933
+    first = 0;
3934
+    skip = 0;
3935
+    if (txt_len > trunc_len) {
3936
+      first = trunc_len / 2;
3937
+      skip = txt_len - trunc_len + 1;
3938
+    }
3939
+
3940
+#ifdef UTF8
3941
+    if (SLsmg_Is_Unicode) {
3942
+      mbstate_t s;
3943
+      int mbmax;
3944
+
3945
+      str = txt;
3946
+      memset (&s, 0, sizeof (s));
3947
+      mbmax = MB_CUR_MAX;
3948
+      p = x;
3949
+      while (p < x + sizeof (x) - 1 && trunc_len) {
3950
+	  wchar_t wc;
3951
+	  int len;
3952
+
3953
+	  len = mbrtowc (&wc, str, mbmax, &s);
3954
+	  if (!len)
3955
+	      break;
3956
+	  if (len < 0) {
3957
+	      memset (&s, 0, sizeof (s));
3958
+	      *p = '?';
3959
+	      len = 1;
3960
+	      str++;
3961
+	  } else if (!is_printable (wc)) {
3962
+	      *p = '?';
3963
+	      str += len;
3964
+	      len = 1;
3965
+	  } else if (p >= x + sizeof (x) - len)
3966
+	      break;
3967
+	  else {
3968
+	      memcpy (p, str, len);
3969
+	      str += len;
3970
+	  }
3971
+	  if (first) {
3972
+	      --trunc_len;
3973
+	      --first;
3974
+	      p += len;
3975
+	      if (!first && p < x + sizeof (x) - 1 && trunc_len) {
3976
+		  *p++ = '~';
3977
+		  --trunc_len;
3978
+	      }
3979
+	  } else if (skip)
3980
+	      --skip;
3981
+	  else {
3982
+	      --trunc_len;
3983
+	      p += len;
3984
+	  }
3985
+      }
3986
+    } else
3987
+#endif
3988
+    {
3989
+      str = txt;
3990
+      p = x;
3991
+      while (p < x + sizeof (x) - 1) {
3992
+	  if (*str == '\0')
3993
+	      break;
3994
+	  else if (!is_printable (*str))
3995
+	      *p++ = '?';
3996
+	  else
3997
+	      *p++ = *str;
3998
+	  ++str;
3999
+	  if (first) {
4000
+	      --first;
4001
+	      if (!first) {
4002
+		  *p++ = '~';
4003
+		  str += skip;
4004
+	      }
4005
+	  }
4006
+      }
4007
+    }
4008
+    *p = '\0';
4009
     return x;
4010
 }
4011
 
4012
@@ -650,11 +856,66 @@
4013
 }
4014
 
4015
 char *
4016
+utf8_to_local(char *str)
4017
+{
4018
+   iconv_t cd;
4019
+   size_t buflen;
4020
+   char *output;
4021
+   int retry = 1;
4022
+
4023
+   if (str == NULL)
4024
+	   return NULL;
4025
+   else
4026
+	   buflen = strlen(str);
4027
+        
4028
+   cd = iconv_open (nl_langinfo(CODESET), "UTF-8");
4029
+   if (cd == (iconv_t) -1) {
4030
+	return g_strdup(str);
4031
+   }
4032
+
4033
+   output = g_malloc(buflen + 1);
4034
+     
4035
+   while (retry)
4036
+   {
4037
+	char *wrptr = output;
4038
+	char *inptr = str;
4039
+	size_t insize = buflen;
4040
+	size_t avail = buflen;
4041
+        size_t nconv;
4042
+     
4043
+        nconv = iconv (cd, &inptr, &insize, &wrptr, &avail);
4044
+        if (nconv == (size_t) -1)
4045
+        {
4046
+    	    if (errno == E2BIG)
4047
+	    {
4048
+		buflen *= 2;
4049
+		g_free(output);
4050
+		output = g_malloc(buflen + 1);
4051
+	    }
4052
+	    else
4053
+	    {
4054
+		g_free(output);
4055
+		return g_strdup(str);
4056
+	    }
4057
+	}
4058
+	else {
4059
+	    retry = 0;
4060
+	    *wrptr = 0;
4061
+	}
4062
+    }
4063
+     
4064
+    iconv_close (cd);
4065
+    
4066
+    return output;
4067
+}
4068
+
4069
+char *
4070
 load_mc_home_file (const char *filename, char **allocated_filename)
4071
 {
4072
     char *hintfile_base, *hintfile;
4073
     char *lang;
4074
     char *data;
4075
+    char *conv_data;
4076
 
4077
     hintfile_base = concat_dir_and_file (mc_home, filename);
4078
     lang = guess_message_value ();
4079
@@ -687,7 +948,10 @@
4080
     else
4081
 	g_free (hintfile);
4082
 
4083
-    return data;
4084
+    conv_data = utf8_to_local(data);
4085
+    g_free(data);
4086
+    
4087
+    return conv_data;
4088
 }
4089
 
4090
 /* Check strftime() results. Some systems (i.e. Solaris) have different
4091
@@ -695,12 +959,14 @@
4092
 size_t i18n_checktimelength (void)
4093
 {
4094
     size_t length, a, b;
4095
-    char buf [MAX_I18NTIMELENGTH + 1];
4096
+    char buf [4 * MAX_I18NTIMELENGTH + 1];
4097
     time_t testtime = time (NULL);
4098
     
4099
-    a = strftime (buf, sizeof(buf)-1, _("%b %e %H:%M"), localtime(&testtime));
4100
-    b = strftime (buf, sizeof(buf)-1, _("%b %e  %Y"), localtime(&testtime));
4101
-    
4102
+    strftime (buf, sizeof(buf)-1, _("%b %e %H:%M"), localtime(&testtime));
4103
+    a = mbstrlen (buf);
4104
+    strftime (buf, sizeof(buf)-1, _("%b %e  %Y"), localtime(&testtime));
4105
+    b = mbstrlen (buf);
4106
+
4107
     length = max (a, b);
4108
     
4109
     /* Don't handle big differences. Use standard value (email bug, please) */
4110
@@ -712,15 +978,12 @@
4111
 
4112
 const char *file_date (time_t when)
4113
 {
4114
-    static char timebuf [MAX_I18NTIMELENGTH + 1];
4115
+    static char timebuf [4 * MAX_I18NTIMELENGTH + 1];
4116
     time_t current_time = time ((time_t) 0);
4117
-    static size_t i18n_timelength = 0;
4118
     static const char *fmtyear, *fmttime;
4119
     const char *fmt;
4120
 
4121
-    if (i18n_timelength == 0){
4122
-	i18n_timelength = i18n_checktimelength() + 1;
4123
-	
4124
+    if (fmtyear == NULL) {
4125
 	/* strftime() format string for old dates */
4126
 	fmtyear = _("%b %e  %Y");
4127
 	/* strftime() format string for recent dates */
4128
@@ -743,7 +1007,7 @@
4129
     else
4130
 	fmt = fmttime;
4131
     
4132
-    strftime (timebuf, i18n_timelength, fmt, localtime(&when));
4133
+    strftime (timebuf, sizeof (timebuf) - 1, fmt, localtime(&when));
4134
     return timebuf;
4135
 }
4136
 
4137
@@ -868,10 +1131,27 @@
4138
 		r++;
4139
 	    continue;
4140
 	}
4141
-
4142
+#ifndef UTF8
4143
 	if (is_printable(*r))
4144
 	    *w++ = *r;
4145
 	++r;
4146
+#else /* UTF8 */
4147
+	{
4148
+	    mbstate_t mbs;
4149
+           int len;
4150
+	    memset (&mbs, 0, sizeof (mbs));
4151
+	    len = mbrlen(r, MB_CUR_MAX, &mbs);
4152
+		
4153
+	    if (len > 0 && (unsigned char)*r >= ' ') 
4154
+		while (len--)
4155
+		    *w++ = *r++;
4156
+	    else {
4157
+		if (len == -1)
4158
+		    *w++ = '?';
4159
+		r++;
4160
+	    }
4161
+	}
4162
+#endif /* UTF8 */
4163
     }
4164
     *w = 0;
4165
     return s;
4166
diff -Naur mc-4.6.1-old/src/util.h mc-4.6.1/src/util.h
4167
--- mc-4.6.1-old/src/util.h	2005-01-13 20:20:47.000000000 +0100
4168
+++ mc-4.6.1/src/util.h	2005-10-28 10:08:07.852229632 +0200
4169
@@ -93,6 +93,13 @@
4170
 char *get_group (int);
4171
 char *get_owner (int);
4172
 
4173
+void fix_utf8(char *str);
4174
+size_t mbstrlen (const char *);
4175
+wchar_t *mbstr_to_wchar (const char *);
4176
+char *wchar_to_mbstr (const wchar_t *);
4177
+char *utf8_to_local(char *str);
4178
+
4179
+
4180
 #define MAX_I18NTIMELENGTH 14
4181
 #define MIN_I18NTIMELENGTH 10
4182
 #define STD_I18NTIMELENGTH 12
4183
diff -Naur mc-4.6.1-old/src/view.c mc-4.6.1/src/view.c
4184
--- mc-4.6.1-old/src/view.c	2005-05-27 16:19:18.000000000 +0200
4185
+++ mc-4.6.1/src/view.c	2005-10-28 10:08:08.023203640 +0200
4186
@@ -36,6 +36,10 @@
4187
 #include <errno.h>
4188
 #include <limits.h>
4189
 
4190
+#ifdef UTF8
4191
+#include <wctype.h>
4192
+#endif /* UTF8 */
4193
+
4194
 #include "global.h"
4195
 #include "tty.h"
4196
 #include "cmd.h"		/* For view_other_cmd */
4197
@@ -793,7 +797,7 @@
4198
 
4199
     if (!i18n_adjust) {
4200
 	file_label = _("File: %s");
4201
-	i18n_adjust = strlen (file_label) - 2;
4202
+	i18n_adjust = mbstrlen (file_label) - 2;
4203
     }
4204
 
4205
     if (w < i18n_adjust + 6)
4206
@@ -849,7 +853,11 @@
4207
 	widget_erase ((Widget *) view);
4208
 }
4209
 
4210
+#ifndef UTF8
4211
 #define view_add_character(view,c) addch (c)
4212
+#else /* UTF8 */
4213
+#define view_add_character(view,c) SLsmg_write_char(c)
4214
+#endif /* UTF8 */
4215
 #define view_add_one_vline()       one_vline()
4216
 #define view_add_string(view,s)    addstr (s)
4217
 #define view_gotoyx(v,r,c)    widget_move (v,r,c)
4218
@@ -1071,6 +1079,12 @@
4219
 	if (view->growing_buffer && from == view->last_byte)
4220
 	    get_byte (view, from);
4221
 	for (; row < height && from < view->last_byte; from++) {
4222
+#ifdef UTF8
4223
+            mbstate_t mbs;
4224
+            char mbbuf[MB_LEN_MAX];
4225
+            int mblen;
4226
+            wchar_t wc;
4227
+#endif /* UTF8 */
4228
 	    c = get_byte (view, from);
4229
 	    if ((c == '\n') || (col >= width && view->wrap_mode)) {
4230
 		col = frame_shift;
4231
@@ -1084,7 +1098,37 @@
4232
 		col = ((col - frame_shift) / 8) * 8 + 8 + frame_shift;
4233
 		continue;
4234
 	    }
4235
+#ifndef UTF8
4236
 	    if (view->viewer_nroff_flag && c == '\b') {
4237
+#else /* UTF8 */
4238
+                mblen = 1;
4239
+                mbbuf[0] = convert_to_display_c (c);
4240
+
4241
+                while (mblen < MB_LEN_MAX) {
4242
+                    int res;
4243
+                    memset (&mbs, 0, sizeof (mbs));
4244
+                    res = mbrtowc (&wc, mbbuf, mblen, &mbs);
4245
+                    if (res <= 0 && res != -2) {
4246
+                        wc = '.';
4247
+                        mblen = 1;
4248
+                        break;
4249
+                    }
4250
+                    if (res == mblen)
4251
+                        break;
4252
+
4253
+                    mbbuf[mblen] = convert_to_display_c (get_byte (view, from + mblen));
4254
+                    mblen++;
4255
+                }
4256
+
4257
+                if (mblen == MB_LEN_MAX) {
4258
+                    wc = '.';
4259
+                    mblen = 1;
4260
+                }
4261
+
4262
+                from += mblen - 1;
4263
+
4264
+            if (view->viewer_nroff_flag && wc == '\b') {
4265
+#endif /* UTF8 */
4266
 		int c_prev;
4267
 		int c_next;
4268
 
4269
@@ -1122,12 +1166,23 @@
4270
 		&& col < width - view->start_col) {
4271
 		view_gotoyx (view, row, col + view->start_col);
4272
 
4273
+#ifndef UTF8
4274
 		c = convert_to_display_c (c);
4275
-
4276
 		if (!is_printable (c))
4277
 		    c = '.';
4278
-
4279
 		view_add_character (view, c);
4280
+#else /* UTF8 */
4281
+		if (!iswprint (wc))
4282
+		    wc = '.';
4283
+		view_add_character (view, wc);
4284
+
4285
+		{
4286
+		    int cw = wcwidth(wc);
4287
+		    if (cw > 1)
4288
+			col+= cw - 1;
4289
+		}
4290
+#endif /* UTF8 */
4291
+
4292
 	    }
4293
 	    col++;
4294
 	    if (boldflag != MARK_NORMAL) {
4295
diff -Naur mc-4.6.1-old/src/widget.c mc-4.6.1/src/widget.c
4296
--- mc-4.6.1-old/src/widget.c	2005-05-27 16:19:19.000000000 +0200
4297
+++ mc-4.6.1/src/widget.c	2005-10-28 10:08:07.888224160 +0200
4298
@@ -33,6 +33,9 @@
4299
 #include <ctype.h>
4300
 #include "global.h"
4301
 #include "tty.h"
4302
+#ifdef UTF8
4303
+#include <wctype.h>
4304
+#endif /* UTF8 */
4305
 #include "color.h"
4306
 #include "mouse.h"
4307
 #include "dialog.h"
4308
@@ -148,6 +151,11 @@
4309
 	if (b->hotpos >= 0) {
4310
 	    attrset ((b->selected) ? HOT_FOCUSC : HOT_NORMALC);
4311
 	    widget_move (&b->widget, 0, b->hotpos + off);
4312
+#ifdef UTF8
4313
+	    if (SLsmg_Is_Unicode) 
4314
+		SLsmg_write_nwchars (&b->hotwc, 1);
4315
+	    else
4316
+#endif
4317
 	    addch ((unsigned char) b->text[b->hotpos]);
4318
 	}
4319
 	return MSG_HANDLED;
4320
@@ -179,7 +187,7 @@
4321
 static int
4322
 button_len (const char *text, unsigned int flags)
4323
 {
4324
-    int ret = strlen (text);
4325
+    int ret = mbstrlen (text);
4326
     switch (flags){
4327
 	case DEFPUSH_BUTTON:
4328
 	    ret += 6;
4329
@@ -202,14 +210,36 @@
4330
  * the button text is g_malloc()ed, we can safely change and shorten it.
4331
  */
4332
 static void
4333
-button_scan_hotkey (WButton *b)
4334
+scan_hotkey (char *text, int *hotposp, int *hotkeyp, wchar_t *hotwcp)
4335
 {
4336
-    char *cp = strchr (b->text, '&');
4337
+    char *cp = strchr (text, '&');
4338
 
4339
     if (cp != NULL && cp[1] != '\0') {
4340
-	g_strlcpy (cp, cp + 1, strlen (cp));
4341
-	b->hotkey = tolower (*cp);
4342
-	b->hotpos = cp - b->text;
4343
+#ifdef UTF8
4344
+    if (SLsmg_Is_Unicode) {
4345
+        mbstate_t s;
4346
+        int len;
4347
+
4348
+        *cp = '\0';
4349
+        memset (&s, 0, sizeof (s));
4350
+        len = mbrtowc (hotwcp, cp + 1, MB_CUR_MAX, &s);
4351
+        if (len > 0) {
4352
+            *hotposp = mbstrlen (text);
4353
+            if (*hotposp < 0) {
4354
+                *hotposp = -1;
4355
+            } else {
4356
+                /* FIXME */
4357
+                *hotkeyp = tolower (*hotwcp);
4358
+            }
4359
+        }
4360
+      } else
4361
+#endif
4362
+      {
4363
+        *hotkeyp = tolower (cp[1]);
4364
+        *hotposp = cp - text;
4365
+      }
4366
+
4367
+      memmove (cp, cp + 1, strlen (cp + 1) + 1);
4368
     }
4369
 }
4370
 
4371
@@ -231,22 +261,23 @@
4372
     widget_want_hotkey (b->widget, 1);
4373
     b->hotkey = 0;
4374
     b->hotpos = -1;
4375
+    b->hotwc = L'\0';
4376
 
4377
-    button_scan_hotkey(b);
4378
+    scan_hotkey(b->text, &b->hotpos, &b->hotkey, &b->hotwc);
4379
     return b;
4380
 }
4381
 
4382
 void
4383
 button_set_text (WButton *b, const char *text)
4384
 {
4385
-   g_free (b->text);
4386
+    g_free (b->text);
4387
     b->text = g_strdup (text);
4388
     b->widget.cols = button_len (text, b->flags);
4389
-    button_scan_hotkey(b);
4390
+    scan_hotkey(b->text, &b->hotpos, &b->hotkey, &b->hotwc);
4391
     dlg_redraw (b->widget.parent);
4392
 }
4393
 
4394
-
4395
+
4396
 /* Radio button widget */
4397
 static int radio_event (Gpm_Event *event, WRadio *r);
4398
 
4399
@@ -320,16 +351,37 @@
4400
 	    widget_move (&r->widget, i, 0);
4401
 
4402
 	    printw ("(%c) ", (r->sel == i) ? '*' : ' ');
4403
-	    for (cp = r->texts[i]; *cp; cp++) {
4404
-		if (*cp == '&') {
4405
-		    attrset ((i == r->pos && msg == WIDGET_FOCUS)
4406
-			     ? HOT_FOCUSC : HOT_NORMALC);
4407
-		    addch (*++cp);
4408
-		    attrset ((i == r->pos
4409
-			      && msg == WIDGET_FOCUS) ? FOCUSC : NORMALC);
4410
+	    cp = strchr (r->texts[i], '&');
4411
+	    if (cp != NULL) {
4412
+#ifdef UTF8
4413
+		mbstate_t s;
4414
+		wchar_t wc;
4415
+		int len;
4416
+#endif
4417
+		printw ("%.*s", (int) ((char *) cp - r->texts[i]),
4418
+			r->texts[i]);
4419
+		attrset ((i == r->pos && msg == WIDGET_FOCUS)
4420
+			 ? HOT_FOCUSC : HOT_NORMALC);
4421
+#ifdef UTF8
4422
+		if (SLsmg_Is_Unicode) {
4423
+		    memset (&s, 0, sizeof (s));
4424
+		    len = mbrtowc (&wc, cp + 1, MB_CUR_MAX, &s);
4425
+		    ++cp;
4426
+		    if (len > 0) {
4427
+			printw ("%.*s", len, cp);
4428
+			cp += len;
4429
+		    }
4430
 		} else
4431
-		    addch (*cp);
4432
-	    }
4433
+#endif
4434
+		{
4435
+		    addch (*++cp);
4436
+		    ++cp;
4437
+		}
4438
+		attrset ((i == r->pos && msg == WIDGET_FOCUS)
4439
+			 ? FOCUSC : NORMALC);
4440
+	    } else
4441
+		cp = r->texts[i];
4442
+	    addstr ((char *) cp);
4443
 	}
4444
 	return MSG_HANDLED;
4445
 
4446
@@ -365,7 +417,7 @@
4447
     /* Compute the longest string */
4448
     max = 0;
4449
     for (i = 0; i < count; i++){
4450
-	m = strlen (texts [i]);
4451
+	m = mbstrlen (texts [i]);
4452
 	if (m > max)
4453
 	    max = m;
4454
     }
4455
@@ -426,6 +478,11 @@
4456
 	if (c->hotpos >= 0) {
4457
 	    attrset ((msg == WIDGET_FOCUS) ? HOT_FOCUSC : HOT_NORMALC);
4458
 	    widget_move (&c->widget, 0, +c->hotpos + 4);
4459
+#ifdef UTF8
4460
+	    if (SLsmg_Is_Unicode)
4461
+		SLsmg_write_nwchars (&c->hotwc, 1);
4462
+	    else
4463
+#endif
4464
 	    addch ((unsigned char) c->text[c->hotpos]);
4465
 	}
4466
 	return MSG_HANDLED;
4467
@@ -460,32 +517,18 @@
4468
 check_new (int y, int x, int state, const char *text)
4469
 {
4470
     WCheck *c =  g_new (WCheck, 1);
4471
-    const char *s;
4472
-    char *t;
4473
     
4474
-    init_widget (&c->widget, y, x, 1, strlen (text),
4475
+    init_widget (&c->widget, y, x, 1, mbstrlen (text),
4476
 		 (callback_fn)check_callback,
4477
 		 (mouse_h) check_event);
4478
     c->state = state ? C_BOOL : 0;
4479
     c->text = g_strdup (text);
4480
     c->hotkey = 0;
4481
     c->hotpos = -1;
4482
+    c->hotwc = L'\0';
4483
     widget_want_hotkey (c->widget, 1);
4484
 
4485
-    /* Scan for the hotkey */
4486
-    for (s = text, t = c->text; *s; s++, t++){
4487
-	if (*s != '&'){
4488
-	    *t = *s;
4489
-	    continue;
4490
-	}
4491
-	s++;
4492
-	if (*s){
4493
-	    c->hotkey = tolower (*s);
4494
-	    c->hotpos = t - c->text;
4495
-	}
4496
-	*t = *s;
4497
-    }
4498
-    *t = 0;
4499
+    scan_hotkey (c->text, &c->hotpos, &c->hotkey, &c->hotwc);
4500
     return c;
4501
 }
4502
 
4503
@@ -527,7 +570,7 @@
4504
 		}
4505
 		widget_move (&l->widget, y, 0);
4506
 		printw ("%s", p);
4507
-		xlen = l->widget.cols - strlen (p);
4508
+		xlen = l->widget.cols - mbstrlen (p);
4509
 		if (xlen > 0)
4510
 		    printw ("%*s", xlen, " ");
4511
 		if (!q)
4512
@@ -561,7 +604,7 @@
4513
     if (text){
4514
 	label->text = g_strdup (text);
4515
 	if (label->auto_adjust_cols) {
4516
-	    newcols = strlen (text);
4517
+	    newcols = mbstrlen (text);
4518
 	    if (newcols > label->widget.cols)
4519
 	    label->widget.cols = newcols;
4520
 	}
4521
@@ -585,7 +628,7 @@
4522
     if (!text || strchr(text, '\n'))
4523
 	width = 1;
4524
     else
4525
-	width = strlen (text);
4526
+	width = mbstrlen (text);
4527
 
4528
     l = g_new (WLabel, 1);
4529
     init_widget (&l->widget, y, x, 1, width,
4530
@@ -734,13 +777,69 @@
4531
 /* Pointer to killed data */
4532
 static char *kill_buffer = 0;
4533
 
4534
+#ifdef UTF8
4535
+static int
4536
+charpos(WInput *in, int idx)
4537
+{
4538
+    int i, pos, l, len;
4539
+    mbstate_t mbs;
4540
+    memset (&mbs, 0, sizeof (mbs));
4541
+    i = 0;
4542
+    pos = 0;
4543
+    len = strlen(in->buffer);
4544
+
4545
+    while (in->buffer[pos]) {
4546
+	if (i == idx)
4547
+	    return pos;
4548
+	l = mbrlen(in->buffer + pos, len - pos, &mbs);
4549
+	if (l <= 0)
4550
+	    return pos;
4551
+	pos+=l;
4552
+	i++;
4553
+    };
4554
+    return pos;
4555
+}
4556
+
4557
+static int
4558
+charcolumn(WInput *in, int idx)
4559
+{
4560
+    int i, pos, l, width, len;
4561
+    mbstate_t mbs;
4562
+    memset (&mbs, 0, sizeof (mbs));
4563
+    i = 0;
4564
+    pos = 0; width = 0;
4565
+    len = strlen(in->buffer);
4566
+
4567
+    while (in->buffer[pos]) {
4568
+	wchar_t wc;
4569
+	if (i == idx)
4570
+	    return width;
4571
+	l = mbrtowc(&wc, in->buffer + pos, len - pos, &mbs);
4572
+	if (l <= 0)
4573
+	    return width;
4574
+	pos += l; width += wcwidth(wc);
4575
+	i++;
4576
+    };
4577
+    return width;
4578
+}
4579
+#else
4580
+#define charpos(in, idx) (idx)
4581
+#define charcolumn(in, idx) (idx)
4582
+#endif /* UTF8 */
4583
+
4584
 void
4585
 update_input (WInput *in, int clear_first)
4586
 {
4587
     int has_history = 0;
4588
     int    i, j;
4589
-    unsigned char   c;
4590
-    int    buf_len = strlen (in->buffer);
4591
+    int    buf_len = mbstrlen (in->buffer);
4592
+#ifndef UTF8
4593
+    unsigned char c;
4594
+#else /* UTF8 */
4595
+    wchar_t c;
4596
+    mbstate_t mbs;
4597
+    memset (&mbs, 0, sizeof (mbs));
4598
+#endif /* UTF8 */
4599
 
4600
     if (should_show_history_button (in))
4601
 	has_history = HISTORY_BUTTON_WIDTH;
4602
@@ -750,7 +849,7 @@
4603
 
4604
     /* Make the point visible */
4605
     if ((in->point < in->first_shown) ||
4606
-	(in->point >= in->first_shown+in->field_len - has_history)){
4607
+	(charcolumn(in, in->point) >= charcolumn(in, in->first_shown) + in->field_len - has_history)){
4608
 	in->first_shown = in->point - (in->field_len / 3);
4609
 	if (in->first_shown < 0)
4610
 	    in->first_shown = 0;
4611
@@ -770,14 +869,29 @@
4612
 	addch (' ');
4613
     widget_move (&in->widget, 0, 0);
4614
     
4615
+#ifndef UTF8
4616
     for (i = 0, j = in->first_shown; i < in->field_len - has_history && in->buffer [j]; i++){
4617
 	c = in->buffer [j++];
4618
 	c = is_printable (c) ? c : '.';
4619
-	if (in->is_password)
4620
+#else /* UTF8 */
4621
+    for (i = 0, j = in->first_shown; (i < in->field_len - has_history) && (j < buf_len); i++,j++){
4622
+	char * chp = in->buffer + charpos(in,j);
4623
+	size_t res = mbrtowc(&c, chp, strlen(chp), &mbs);
4624
+	c = (res && iswprint (c)) ? 0 : '.';
4625
+#endif /* UTF8 */
4626
+	if (in->is_password) 
4627
 	    c = '*';
4628
+#ifndef UTF8
4629
 	addch (c);
4630
+#else /* UTF8 */
4631
+	if (c) {
4632
+	    addch (c); 
4633
+	}
4634
+	else
4635
+	    SLsmg_write_nchars (chp, res);
4636
+#endif /* UTF8 */
4637
     }
4638
-    widget_move (&in->widget, 0, in->point - in->first_shown);
4639
+    widget_move (&in->widget, 0, charcolumn(in, in->point) - charcolumn(in, in->first_shown));
4640
 
4641
     if (clear_first)
4642
 	    in->first = 0;
4643
@@ -919,7 +1033,7 @@
4644
 show_hist (GList *history, int widget_x, int widget_y)
4645
 {
4646
     GList *hi, *z;
4647
-    size_t maxlen = strlen (i18n_htitle ()), i, count = 0;
4648
+    size_t maxlen = mbstrlen (i18n_htitle ()), i, count = 0;
4649
     int x, y, w, h;
4650
     char *q, *r = 0;
4651
     Dlg_head *query_dlg;
4652
@@ -932,7 +1046,7 @@
4653
     z = g_list_first (history);
4654
     hi = z;
4655
     while (hi) {
4656
-	if ((i = strlen ((char *) hi->data)) > maxlen)
4657
+	if ((i = mbstrlen ((char *) hi->data)) > maxlen)
4658
 	    maxlen = i;
4659
 	count++;
4660
 	hi = g_list_next (hi);
4661
@@ -1104,35 +1218,83 @@
4662
     in->need_push = 1;
4663
     in->buffer [0] = 0;
4664
     in->point = 0;
4665
+    in->charpoint = 0;
4666
     in->mark = 0;
4667
     free_completions (in);
4668
     update_input (in, 0);
4669
 }
4670
 
4671
+static void
4672
+move_buffer_backward (WInput *in, int point)
4673
+{
4674
+    int i, pos, len;
4675
+    int str_len = mbstrlen (in->buffer);
4676
+    if (point >= str_len) return;
4677
+
4678
+    pos = charpos(in,point);
4679
+    len = charpos(in,point + 1) - pos;
4680
+
4681
+    for (i = pos; in->buffer [i + len - 1]; i++)
4682
+	in->buffer [i] = in->buffer [i + len];
4683
+}
4684
+
4685
 static cb_ret_t
4686
 insert_char (WInput *in, int c_code)
4687
 {
4688
     size_t i;
4689
+#ifdef UTF8
4690
+    mbstate_t mbs;
4691
+    int res;
4692
+
4693
+    memset (&mbs, 0, sizeof (mbs));
4694
+#else
4695
+    in->charpoint = 0;
4696
+#endif /* UTF8 */
4697
 
4698
     if (c_code == -1)
4699
 	return MSG_NOT_HANDLED;
4700
     
4701
+#ifdef UTF8
4702
+    if (in->charpoint >= MB_CUR_MAX) return 1;
4703
+
4704
+    in->charbuf[in->charpoint++] = c_code;
4705
+
4706
+    res = mbrlen((char *)in->charbuf, in->charpoint, &mbs);
4707
+    if (res < 0) {
4708
+	if (res != -2) in->charpoint = 0; /* broken multibyte char, skip */
4709
+        return 1;
4710
+    }
4711
+
4712
+#endif /* UTF8 */
4713
     in->need_push = 1;
4714
-    if (strlen (in->buffer)+1 == (size_t) in->current_max_len){
4715
+    if (strlen (in->buffer) + 1 + in->charpoint >= (size_t) in->current_max_len){
4716
 	/* Expand the buffer */
4717
-	char *narea = g_realloc (in->buffer, in->current_max_len + in->field_len);
4718
+	char *narea = g_realloc (in->buffer, in->current_max_len + in->field_len + in->charpoint);
4719
 	if (narea){
4720
 	    in->buffer = narea;
4721
-	    in->current_max_len += in->field_len;
4722
+	    in->current_max_len += in->field_len + in->charpoint;
4723
 	}
4724
     }
4725
+#ifndef UTF8
4726
     if (strlen (in->buffer)+1 < (size_t) in->current_max_len){
4727
 	size_t l = strlen (&in->buffer [in->point]);
4728
 	for (i = l+1; i > 0; i--)
4729
 	    in->buffer [in->point+i] = in->buffer [in->point+i-1];
4730
 	in->buffer [in->point] = c_code;
4731
+#else /* UTF8 */
4732
+    if (strlen (in->buffer) + in->charpoint < in->current_max_len){
4733
+        size_t ins_point = charpos(in,in->point); /* bytes from begin */
4734
+	/* move chars */
4735
+	size_t rest_bytes = strlen (in->buffer + ins_point);
4736
+
4737
+	for (i = rest_bytes + 1; i > 0; i--) 
4738
+	    in->buffer [ins_point + i + in->charpoint - 1] = in->buffer [ins_point + i - 1];
4739
+
4740
+	memcpy(in->buffer + ins_point, in->charbuf, in->charpoint); 
4741
+#endif /* UTF8 */
4742
 	in->point++;
4743
     }
4744
+    in->charpoint = 0;
4745
     return MSG_HANDLED;
4746
 }
4747
 
4748
@@ -1140,12 +1302,14 @@
4749
 beginning_of_line (WInput *in)
4750
 {
4751
     in->point = 0;
4752
+    in->charpoint = 0;
4753
 }
4754
 
4755
 static void
4756
 end_of_line (WInput *in)
4757
 {
4758
-    in->point = strlen (in->buffer);
4759
+    in->point = mbstrlen (in->buffer);
4760
+    in->charpoint = 0;
4761
 }
4762
 
4763
 static void
4764
@@ -1153,18 +1317,21 @@
4765
 {
4766
     if (in->point)
4767
 	in->point--;
4768
+    in->charpoint = 0;
4769
 }
4770
 
4771
 static void
4772
 forward_char (WInput *in)
4773
 {
4774
-    if (in->buffer [in->point])
4775
+    if (in->buffer [charpos(in,in->point)])
4776
 	in->point++;
4777
+    in->charpoint = 0;
4778
 }
4779
 
4780
 static void
4781
 forward_word (WInput *in)
4782
 {
4783
+#ifndef UTF8
4784
     unsigned char *p = in->buffer+in->point;
4785
 
4786
     while (*p && (isspace (*p) || ispunct (*p)))
4787
@@ -1172,11 +1339,39 @@
4788
     while (*p && isalnum (*p))
4789
 	p++;
4790
     in->point = p - in->buffer;
4791
+#else /* UTF8 */
4792
+    mbstate_t mbs;
4793
+    int len = mbstrlen (in->buffer);
4794
+    memset (&mbs, 0, sizeof (mbs));
4795
+
4796
+    while (in->point < len) {
4797
+        wchar_t c;
4798
+        char *p = in->buffer + charpos(in,in->point);
4799
+        size_t res = mbrtowc(&c, p, strlen(p), &mbs);
4800
+        if (res <= 0 || !(iswspace (c) || iswpunct (c)))
4801
+            break;
4802
+        in->point++;
4803
+    }
4804
+
4805
+    memset (&mbs, 0, sizeof (mbs));
4806
+
4807
+    while (in->point < len) {
4808
+        wchar_t c;
4809
+        char *p = in->buffer + charpos(in,in->point);
4810
+        size_t res = mbrtowc(&c, p, strlen(p), &mbs);
4811
+        if (res <= 0 || !iswalnum (c))
4812
+            break;
4813
+        in->point++;
4814
+    }
4815
+
4816
+    in->charpoint = 0;
4817
+#endif /* UTF8 */
4818
 }
4819
 
4820
 static void
4821
 backward_word (WInput *in)
4822
 {
4823
+#ifndef UTF8
4824
     unsigned char *p = in->buffer+in->point;
4825
 
4826
     while (p-1 > in->buffer-1 && (isspace (*(p-1)) || ispunct (*(p-1))))
4827
@@ -1184,6 +1379,32 @@
4828
     while (p-1 > in->buffer-1 && isalnum (*(p-1)))
4829
 	p--;
4830
     in->point = p - in->buffer;
4831
+#else /* UTF8 */
4832
+    mbstate_t mbs;
4833
+
4834
+    memset (&mbs, 0, sizeof (mbs));
4835
+    while (in->point > 0) {
4836
+      wchar_t c;
4837
+      char *p = in->buffer + charpos(in,in->point);
4838
+      size_t res = mbrtowc(&c, p, strlen(p), &mbs);
4839
+      if (*p && (res <= 0 || !(iswspace (c) || iswpunct (c))))
4840
+          break;
4841
+      in->point--;
4842
+    }
4843
+
4844
+    memset (&mbs, 0, sizeof (mbs));
4845
+
4846
+    while (in->point > 0) {
4847
+      wchar_t c;
4848
+      char *p = in->buffer + charpos(in,in->point);
4849
+      size_t res = mbrtowc(&c, p, strlen(p), &mbs);
4850
+      if (*p && (res <= 0 || !iswalnum (c)))
4851
+          break;
4852
+      in->point--;
4853
+    }
4854
+
4855
+    in->charpoint = 0;
4856
+#endif /* UTF8 */
4857
 }
4858
 
4859
 static void
4860
@@ -1216,8 +1437,9 @@
4861
     
4862
     if (!in->point)
4863
 	return;
4864
-    for (i = in->point; in->buffer [i-1]; i++)
4865
-	in->buffer [i-1] = in->buffer [i];
4866
+
4867
+    move_buffer_backward(in, in->point - 1);    
4868
+    in->charpoint = 0;
4869
     in->need_push = 1;
4870
     in->point--;
4871
 }
4872
@@ -1225,10 +1447,8 @@
4873
 static void
4874
 delete_char (WInput *in)
4875
 {
4876
-    int i;
4877
-
4878
-    for (i = in->point; in->buffer [i]; i++)
4879
-	in->buffer [i] = in->buffer [i+1];
4880
+    move_buffer_backward(in, in->point);    
4881
+    in->charpoint = 0;
4882
     in->need_push = 1;
4883
 }
4884
 
4885
@@ -1243,6 +1463,9 @@
4886
     
4887
     g_free (kill_buffer);
4888
 
4889
+    first=charpos(in,first);
4890
+    last=charpos(in,last);
4891
+    
4892
     kill_buffer = g_strndup(in->buffer+first,last-first);
4893
 }
4894
 
4895
@@ -1251,11 +1474,13 @@
4896
 {
4897
    int first = min (x_first, x_last);
4898
    int last  = max (x_first, x_last);
4899
-   size_t len = strlen (&in->buffer [last]) + 1;
4900
+   size_t len;
4901
 
4902
    in->point = first;
4903
    in->mark  = first;
4904
-   memmove (&in->buffer [first], &in->buffer [last], len);
4905
+   len = strlen (&in->buffer [charpos(in,last)]) + 1;
4906
+   memmove (&in->buffer [charpos(in,first)], &in->buffer [charpos(in,last)], len);
4907
+   in->charpoint = 0;
4908
    in->need_push = 1;
4909
 }
4910
 
4911
@@ -1272,6 +1497,8 @@
4912
     copy_region (in, old_point, new_point);
4913
     delete_region (in, old_point, new_point);
4914
     in->need_push = 1;
4915
+    in->charpoint = 0;
4916
+    in->charpoint = 0;
4917
 }
4918
 
4919
 static void
4920
@@ -1315,16 +1542,20 @@
4921
     
4922
     if (!kill_buffer)
4923
         return;
4924
+    in->charpoint = 0;
4925
     for (p = kill_buffer; *p; p++)
4926
 	insert_char (in, *p);
4927
+    in->charpoint = 0;
4928
 }
4929
 
4930
 static void
4931
 kill_line (WInput *in)
4932
 {
4933
+    int chp = charpos(in,in->point);
4934
     g_free (kill_buffer);
4935
-    kill_buffer = g_strdup (&in->buffer [in->point]);
4936
-    in->buffer [in->point] = 0;
4937
+    kill_buffer = g_strdup (&in->buffer [chp]);
4938
+    in->buffer [chp] = 0;
4939
+    in->charpoint = 0;
4940
 }
4941
 
4942
 void
4943
@@ -1334,9 +1565,10 @@
4944
     g_free (in->buffer);
4945
     in->buffer = g_strdup (text);	/* was in->buffer->text */
4946
     in->current_max_len = strlen (in->buffer) + 1;
4947
-    in->point = strlen (in->buffer);
4948
+    in->point = mbstrlen (in->buffer);
4949
     in->mark = 0;
4950
     in->need_push = 1;
4951
+    in->charpoint = 0;
4952
 }
4953
 
4954
 static void
4955
@@ -1461,6 +1693,7 @@
4956
     *in->buffer = 0;
4957
     in->point = 0;
4958
     in->first = 0;
4959
+    in->charpoint = 0;
4960
 }
4961
 
4962
 cb_ret_t
4963
@@ -1489,7 +1722,11 @@
4964
 	}
4965
     }
4966
     if (!input_map [i].fn){
4967
+#ifndef UTF8
4968
 	if (c_code > 255 || !is_printable (c_code))
4969
+#else /* UTF8 */
4970
+	if (c_code > 255)
4971
+#endif /* UTF8 */
4972
 	    return MSG_NOT_HANDLED;
4973
 	if (in->first){
4974
 	    port_region_marked_for_delete (in);
4975
@@ -1523,6 +1760,9 @@
4976
     if (pos != in->point)
4977
     	free_completions (in);
4978
     in->point = pos;
4979
+#ifdef UTF8
4980
+    in->charpoint = 0;
4981
+#endif /* UTF8 */
4982
     update_input (in, 1);
4983
 }
4984
 
4985
@@ -1562,7 +1802,7 @@
4986
 	return MSG_HANDLED;
4987
 
4988
     case WIDGET_CURSOR:
4989
-	widget_move (&in->widget, 0, in->point - in->first_shown);
4990
+        widget_move (&in->widget, 0, charcolumn(in, in->point) - charcolumn(in, in->first_shown));
4991
 	return MSG_HANDLED;
4992
 
4993
     case WIDGET_DESTROY:
4994
@@ -1584,7 +1824,7 @@
4995
 	    && should_show_history_button (in)) {
4996
 	    do_show_hist (in);
4997
 	} else {
4998
-	    in->point = strlen (in->buffer);
4999
+	    in->point = mbstrlen (in->buffer);
5000
 	    if (event->x - in->first_shown - 1 < in->point)
5001
 		in->point = event->x - in->first_shown - 1;
5002
 	    if (in->point < 0)
5003
@@ -1642,7 +1882,8 @@
5004
     in->is_password = 0;
5005
 
5006
     strcpy (in->buffer, def_text);
5007
-    in->point = strlen (in->buffer);
5008
+    in->point = mbstrlen (in->buffer);
5009
+    in->charpoint = 0;
5010
     return in;
5011
 }
5012
 
5013
diff -Naur mc-4.6.1-old/src/widget.h mc-4.6.1/src/widget.h
5014
--- mc-4.6.1-old/src/widget.h	2004-08-29 20:46:16.000000000 +0200
5015
+++ mc-4.6.1/src/widget.h	2005-10-28 10:08:08.064197408 +0200
5016
@@ -25,6 +25,7 @@
5017
     char *text;			/* text of button */
5018
     int hotkey;			/* hot KEY */
5019
     int hotpos;			/* offset hot KEY char in text */
5020
+    wchar_t hotwc;
5021
     bcback callback;		/* Callback function */
5022
 } WButton;
5023
 
5024
@@ -43,6 +44,7 @@
5025
     char *text;			/* text of check button */
5026
     int hotkey;                 /* hot KEY */                    
5027
     int hotpos;			/* offset hot KEY char in text */
5028
+    wchar_t hotwc;
5029
 } WCheck;
5030
 
5031
 typedef struct WGauge {
5032
@@ -58,16 +60,20 @@
5033
 
5034
 typedef struct {
5035
     Widget widget;
5036
-    int  point;			/* cursor position in the input line */
5037
-    int  mark;			/* The mark position */
5038
-    int  first_shown;		/* Index of the first shown character */
5039
-    int  current_max_len;	/* Maximum length of input line */
5040
-    int  field_len;		/* Length of the editing field */
5041
+    int  point;			/* cursor position in the input line (mb chars) */
5042
+    int  mark;			/* The mark position (mb chars) */
5043
+    int  first_shown;		/* Index of the first shown character (mb chars) */
5044
+    int  current_max_len;	/* Maximum length of input line (bytes) */
5045
+    int  field_len;		/* Length of the editing field (mb chars) */
5046
     int  color;			/* color used */
5047
     int  first;			/* Is first keystroke? */
5048
     int  disable_update;	/* Do we want to skip updates? */
5049
     int  is_password;		/* Is this a password input line? */
5050
     unsigned char *buffer;	/* pointer to editing buffer */
5051
+#ifdef UTF8
5052
+    unsigned char charbuf[MB_LEN_MAX];
5053
+#endif /* UTF8 */
5054
+    int charpoint;
5055
     GList *history;		/* The history */
5056
     int  need_push;		/* need to push the current Input on hist? */
5057
     char **completions;		/* Possible completions array */
5058
diff -Naur mc-4.6.1-old/src/wtools.c mc-4.6.1/src/wtools.c
5059
--- mc-4.6.1-old/src/wtools.c	2005-05-27 16:19:19.000000000 +0200
5060
+++ mc-4.6.1/src/wtools.c	2005-10-28 10:08:08.036201664 +0200
5061
@@ -48,11 +48,11 @@
5062
     /* Adjust sizes */
5063
     lines = (lines > LINES - 6) ? LINES - 6 : lines;
5064
 
5065
-    if (title && (cols < (len = strlen (title) + 2)))
5066
+    if (title && (cols < (len = mbstrlen (title) + 2)))
5067
 	cols = len;
5068
 
5069
     /* no &, but 4 spaces around button for brackets and such */
5070
-    if (cols < (len = strlen (cancel_string) + 3))
5071
+    if (cols < (len = mbstrlen (cancel_string) + 3))
5072
 	cols = len;
5073
 
5074
     cols = cols > COLS - 6 ? COLS - 6 : cols;
5075
@@ -123,7 +123,7 @@
5076
 	va_start (ap, count);
5077
 	for (i = 0; i < count; i++) {
5078
 	    char *cp = va_arg (ap, char *);
5079
-	    win_len += strlen (cp) + 6;
5080
+	    win_len += mbstrlen (cp) + 6;
5081
 	    if (strchr (cp, '&') != NULL)
5082
 		win_len--;
5083
 	}
5084
@@ -131,7 +131,7 @@
5085
     }
5086
 
5087
     /* count coordinates */
5088
-    cols = 6 + max (win_len, max ((int) strlen (header), msglen (text, &lines)));
5089
+    cols = 6 + max (win_len, max ((int) mbstrlen (header), msglen (text, &lines)));
5090
     lines += 4 + (count > 0 ? 2 : 0);
5091
     xpos = COLS / 2 - cols / 2;
5092
     ypos = LINES / 3 - (lines - 3) / 2;
5093
@@ -146,7 +146,7 @@
5094
 	va_start (ap, count);
5095
 	for (i = 0; i < count; i++) {
5096
 	    cur_name = va_arg (ap, char *);
5097
-	    xpos = strlen (cur_name) + 6;
5098
+	    xpos = mbstrlen (cur_name) + 6;
5099
 	    if (strchr (cur_name, '&') != NULL)
5100
 		xpos--;
5101
 
5102
@@ -457,7 +457,7 @@
5103
     g_strlcpy (histname + 3, header, 61);
5104
     quick_widgets[2].histname = histname;
5105
 
5106
-    len = max ((int) strlen (header), msglen (text, &lines)) + 4;
5107
+    len = max ((int) mbstrlen (header), msglen (text, &lines)) + 4;
5108
     len = max (len, 64);
5109
 
5110
     /* The special value of def_text is used to identify password boxes
5111
@@ -477,7 +477,7 @@
5112
      */
5113
     quick_widgets[0].relative_x = len / 2 + 4;
5114
     quick_widgets[1].relative_x =
5115
-	len / 2 - (strlen (_(quick_widgets[1].text)) + 9);
5116
+	len / 2 - (mbstrlen (_(quick_widgets[1].text)) + 9);
5117
     quick_widgets[0].x_divisions = quick_widgets[1].x_divisions = len;
5118
 #endif				/* ENABLE_NLS */
5119
 
(-)files/patch-doc-ru-Makefile.in (-11 lines)
Removed Link Here
1
--- doc/ru/Makefile.in.orig	Tue Aug  2 21:12:42 2005
2
+++ doc/ru/Makefile.in	Tue Aug  2 21:14:25 2005
3
@@ -206,7 +206,7 @@
4
 libdir = @libdir@
5
 libexecdir = @libexecdir@
6
 localstatedir = @localstatedir@
7
-mandir = @mandir@/ru
8
+mandir = @mandir@/ru.KOI8-R
9
 mkdir_p = @mkdir_p@
10
 oldincludedir = @oldincludedir@
11
 prefix = @prefix@
(-)files/patch-lib-Makefile.in (-17 lines)
Removed Link Here
1
--- lib/Makefile.in.orig	Thu Aug 23 21:10:12 2007
2
+++ lib/Makefile.in	Thu Aug 23 21:11:54 2007
3
@@ -220,10 +220,10 @@
4
 @CHARSET_FALSE@LIBFILES_ADD = 
5
 @CHARSET_TRUE@LIBFILES_ADD = mc.charsets
6
 LIBFILES_OUT = mc.ext
7
-LIBFILES_CONST = mc.hint mc.hint.cs mc.hint.es mc.hint.hu mc.hint.it	\
8
-	mc.hint.nl mc.hint.pl mc.hint.ru mc.hint.sr mc.hint.uk		\
9
-	mc.hint.zh mc.lib mc.menu mc.menu.sr cedit.menu edit.indent.rc	\
10
-	edit.spell.rc
11
+LIBFILES_CONST = mc.hint mc.lib mc.menu cedit.menu edit.indent.rc edit.spell.rc
12
+LIBFILES_ADD += mc.hint.cs mc.hint.es mc.hint.hu mc.hint.it \
13
+	mc.hint.nl mc.hint.pl mc.hint.ru mc.hint.sr mc.hint.uk \
14
+	mc.hint.zh mc.menu.sr
15
 
16
 noinst_DATA = README.xterm mcserv.init mcserv.pamd xterm.ad
17
 SCRIPTS_IN = mc.csh.in mc.sh.in mc-wrapper.csh.in mc-wrapper.sh.in
(-)files/patch-lib_Makefile.am (+17 lines)
Added Link Here
1
--- lib/Makefile.am.orig
2
+++ lib/Makefile.am
3
@@ -7,10 +7,10 @@
4
 endif
5
 
6
 LIBFILES_OUT = mc.ext
7
-LIBFILES_CONST = mc.hint mc.hint.cs mc.hint.es mc.hint.hu mc.hint.it	\
8
-	mc.hint.nl mc.hint.pl mc.hint.ru mc.hint.sr mc.hint.uk		\
9
-	mc.hint.zh mc.lib mc.menu mc.menu.sr cedit.menu edit.indent.rc	\
10
-	edit.spell.rc
11
+LIBFILES_CONST = mc.hint mc.lib mc.menu cedit.menu edit.indent.rc edit.spell.rc
12
+LIBFILES_ADD += mc.hint.cs mc.hint.es mc.hint.hu mc.hint.it \
13
+	mc.hint.nl mc.hint.pl mc.hint.ru mc.hint.sr mc.hint.uk \
14
+	mc.hint.zh mc.menu.sr
15
 
16
 noinst_DATA = README.xterm mcserv.init mcserv.pamd xterm.ad
17
 
(-)files/patch-mhl_string.h (+37 lines)
Added Link Here
1
2
$FreeBSD$
3
4
--- mhl/string.h.orig
5
+++ mhl/string.h
6
@@ -7,9 +7,30 @@
7
 #include <mhl/memory.h>
8
 
9
 #define	mhl_str_dup(str)	((str ? strdup(str) : strdup("")))
10
-#define mhl_str_ndup(str,len)	((str ? strndup(str,len) : strdup("")))
11
+#define mhl_str_ndup(str,len)	((str ? mystrndup(str,len) : strdup("")))
12
 #define mhl_str_len(str)	((str ? strlen(str) : 0))
13
 
14
+// XXX Implement strndup for FreeBSD.
15
+#ifdef __FreeBSD__
16
+#ifdef __cplusplus
17
+extern "C" {
18
+#endif
19
+static char *
20
+mystrndup(const char *str, int len) {
21
+    char *ret;
22
+
23
+    if ((str == NULL || len < 0)) return(NULL);
24
+    ret = (char *)malloc(len + 1);
25
+    if (ret == NULL) return(NULL);
26
+    memcpy(ret, str, len);
27
+    ret[len] = '\0';
28
+    return(ret);
29
+}
30
+#ifdef __cplusplus
31
+}
32
+#endif
33
+#endif
34
+
35
 static inline char * mhl_str_dup_range(const char * s_start, const char * s_bound)
36
 {
37
     return mhl_str_ndup(s_start, s_bound - s_start);
(-)files/patch-regex (-32 / +32 lines)
Lines 1-6 Link Here
1
--- src/cmd.c.orig	Sat Jun 24 19:44:21 2006
1
--- src/cmd.c.orig	2009-02-03 18:49:42.000000000 +0800
2
+++ src/cmd.c	Sat Jun 24 19:45:46 2006
2
+++ src/cmd.c	2009-02-03 18:50:16.000000000 +0800
3
@@ -510,7 +510,7 @@
3
@@ -513,7 +513,7 @@
4
 		continue;
4
 		continue;
5
 	}
5
 	}
6
 	c = regexp_match (reg_exp_t, current_panel->dir.list[i].fname,
6
 	c = regexp_match (reg_exp_t, current_panel->dir.list[i].fname,
Lines 9-17 Link Here
9
 	if (c == -1) {
9
 	if (c == -1) {
10
 	    message (1, MSG_ERROR, _("  Malformed regular expression  "));
10
 	    message (1, MSG_ERROR, _("  Malformed regular expression  "));
11
 	    g_free (reg_exp);
11
 	    g_free (reg_exp);
12
--- src/dir.c.orig	Sat Jun 24 19:51:05 2006
12
--- src/dir.c.orig	2009-02-03 18:51:43.000000000 +0800
13
+++ src/dir.c	Sat Jun 24 19:51:31 2006
13
+++ src/dir.c	2009-02-03 18:51:57.000000000 +0800
14
@@ -405,7 +405,7 @@
14
@@ -327,7 +327,7 @@
15
 	    *stale_link = 1;
15
 	    *stale_link = 1;
16
     }
16
     }
17
     if (!(S_ISDIR (buf1->st_mode) || *link_to_dir) && filter
17
     if (!(S_ISDIR (buf1->st_mode) || *link_to_dir) && filter
Lines 20-28 Link Here
20
 	return 0;
20
 	return 0;
21
 
21
 
22
     /* Need to grow the *list? */
22
     /* Need to grow the *list? */
23
--- src/ext.c.orig	Sat Jun 24 19:52:00 2006
23
--- src/ext.c.orig	2009-02-03 18:52:36.000000000 +0800
24
+++ src/ext.c	Sat Jun 24 19:52:21 2006
24
+++ src/ext.c	2009-02-03 18:53:11.000000000 +0800
25
@@ -394,7 +394,7 @@
25
@@ -395,7 +395,7 @@
26
     }
26
     }
27
 
27
 
28
     if (content_string[0]
28
     if (content_string[0]
Lines 31-37 Link Here
31
 	found = 1;
31
 	found = 1;
32
     }
32
     }
33
 
33
 
34
@@ -534,11 +534,11 @@
34
@@ -519,11 +519,11 @@
35
 		/* Do not transform shell patterns, you can use shell/ for
35
 		/* Do not transform shell patterns, you can use shell/ for
36
 		 * that
36
 		 * that
37
 		 */
37
 		 */
Lines 45-71 Link Here
45
 		    found = 1;
45
 		    found = 1;
46
 	    } else if (!strncmp (p, "shell/", 6)) {
46
 	    } else if (!strncmp (p, "shell/", 6)) {
47
 		p += 6;
47
 		p += 6;
48
--- src/find.c.orig	Sat Jun 24 20:36:41 2006
48
--- src/find.c.orig	2009-02-03 18:54:16.000000000 +0800
49
+++ src/find.c	Sat Jun 24 20:37:58 2006
49
+++ src/find.c	2009-02-03 18:56:56.000000000 +0800
50
@@ -575,6 +575,7 @@
50
@@ -615,6 +615,7 @@
51
     struct stat tmp_stat;
51
     struct stat tmp_stat;
52
     static int pos;
52
     static int pos;
53
     static int subdirs_left = 0;
53
     static int subdirs_left = 0;
54
+    int cflags = 0;
54
+	int cflags = 0;
55
 
55
 
56
     if (!h) { /* someone forces me to close dirp */
56
     if (!h) { /* someone forces me to close dirp */
57
 	if (dirp) {
57
 	if (dirp) {
58
@@ -586,6 +587,9 @@
58
@@ -626,6 +627,9 @@
59
         dp = 0;
59
         dp = 0;
60
 	return 1;
60
 	return 1;
61
     }
61
     }
62
+
62
+
63
+    if (case_sensitive == 0)
63
+	if (case_sensitive == 0)
64
+	cflags |= REG_ICASE;
64
+		cflags |= REG_ICASE;
65
  do_search_begin:
65
  do_search_begin:
66
     while (!dp){
66
     while (!dp){
67
 	
67
 	
68
@@ -662,7 +666,7 @@
68
@@ -702,7 +706,7 @@
69
 	g_free (tmp_name);
69
 	g_free (tmp_name);
70
     }
70
     }
71
 
71
 
Lines 74-82 Link Here
74
 	if (content_pattern) {
74
 	if (content_pattern) {
75
 	    if (search_content (h, directory, dp->d_name)) {
75
 	    if (search_content (h, directory, dp->d_name)) {
76
 		return 1;
76
 		return 1;
77
--- src/user.c.orig	Sat Jun 24 19:54:48 2006
77
--- src/user.c.orig	2009-02-03 18:57:38.000000000 +0800
78
+++ src/user.c	Sat Jun 24 19:55:10 2006
78
+++ src/user.c	2009-02-03 18:58:17.000000000 +0800
79
@@ -412,18 +412,18 @@
79
@@ -416,18 +416,18 @@
80
 	    break;
80
 	    break;
81
 	case 'f': /* file name pattern */
81
 	case 'f': /* file name pattern */
82
 	    p = extract_arg (p, arg, sizeof (arg));
82
 	    p = extract_arg (p, arg, sizeof (arg));
Lines 98-111 Link Here
98
 	    break;
98
 	    break;
99
 	case 't':
99
 	case 't':
100
 	    p = extract_arg (p, arg, sizeof (arg));
100
 	    p = extract_arg (p, arg, sizeof (arg));
101
--- src/util.c.orig	Sat Jun 24 19:55:21 2006
101
--- src/util.c.orig	2009-02-03 18:58:31.000000000 +0800
102
+++ src/util.c	Sat Jun 24 19:57:49 2006
102
+++ src/util.c	2009-02-03 19:00:41.000000000 +0800
103
@@ -563,25 +563,28 @@
103
@@ -586,25 +586,28 @@
104
 	return  g_strdup (pattern);
105
 }
104
 }
106
 
105
 
107
-int regexp_match (const char *pattern, const char *string, int match_type)
106
 int
108
+int regexp_match (const char *pattern, const char *string, int match_type, int cflags)
107
-regexp_match (const char *pattern, const char *string, int match_type)
108
+regexp_match (const char *pattern, const char *string, int match_type, int cflags)
109
 {
109
 {
110
     static regex_t r;
110
     static regex_t r;
111
     static char *old_pattern = NULL;
111
     static char *old_pattern = NULL;
Lines 115-122 Link Here
115
     char *my_pattern;
115
     char *my_pattern;
116
 
116
 
117
-    if (!old_pattern || STRCOMP (old_pattern, pattern) || old_type != match_type){
117
-    if (!old_pattern || STRCOMP (old_pattern, pattern) || old_type != match_type){
118
+    if (!old_pattern || STRCOMP (old_pattern, pattern) || 
118
+    if (!old_pattern || STRCOMP (old_pattern, pattern) ||
119
+		old_type != match_type || cflags != old_cflags){
119
+			old_type != match_type || cflags != old_cflags){
120
 	if (old_pattern){
120
 	if (old_pattern){
121
 	    regfree (&r);
121
 	    regfree (&r);
122
 	    g_free (old_pattern);
122
 	    g_free (old_pattern);
Lines 132-140 Link Here
132
 	old_pattern = my_pattern;
132
 	old_pattern = my_pattern;
133
 	old_type = match_type;
133
 	old_type = match_type;
134
     }
134
     }
135
--- src/util.h.orig	Sat Jun 24 19:57:50 2006
135
--- src/util.h.orig	2009-02-03 19:00:50.000000000 +0800
136
+++ src/util.h	Sat Jun 24 19:58:03 2006
136
+++ src/util.h	2009-02-03 19:01:21.000000000 +0800
137
@@ -116,7 +116,7 @@
137
@@ -125,7 +125,7 @@
138
 
138
 
139
 extern int easy_patterns;
139
 extern int easy_patterns;
140
 char *convert_pattern (const char *pattern, int match_type, int do_group);
140
 char *convert_pattern (const char *pattern, int match_type, int do_group);
(-)files/patch-src-Makefile.in (-11 lines)
Removed Link Here
1
--- src/Makefile.in.orig	Thu Feb  6 00:09:09 2003
2
+++ src/Makefile.in	Tue Jun 15 03:14:17 2004
3
@@ -700,7 +700,7 @@
4
 
5
 install-data-am:
6
 
7
-install-exec-am: install-binPROGRAMS install-pkglibPROGRAMS
8
+install-exec-am: install-binPROGRAMS
9
 	@$(NORMAL_INSTALL)
10
 	$(MAKE) $(AM_MAKEFLAGS) install-exec-hook
11
 
(-)files/patch-src-subshell.c (-109 / +9 lines)
Lines 1-111 Link Here
1
diff -ruN src/subshell.c.orig src/subshell.c
1
--- src/subshell.c.orig
2
--- src/subshell.c.orig	Wed Jun 14 15:45:12 2006
2
+++ src/subshell.c
3
+++ src/subshell.c	Wed Jun 14 15:45:39 2006
3
@@ -386,6 +386,8 @@
4
@@ -395,6 +395,8 @@
4
 	    subshell_type = ZSH;
5
	    subshell_type = ZSH;
5
 	else if (strstr (shell, "/tcsh"))
6
	else if (strstr (shell, "/tcsh"))
6
 	    subshell_type = TCSH;
7
	    subshell_type = TCSH;
8
+	else if (strstr (shell, "/csh"))
7
+	else if (strstr (shell, "/csh"))
9
+	    subshell_type = TCSH;
8
+	    subshell_type = TCSH;
10
	else if (strstr (shell, "/bash") || getenv ("BASH"))
9
 	else if (strstr (shell, "/bash") || getenv ("BASH"))
11
	    subshell_type = BASH;
10
 	    subshell_type = BASH;
12
	else {
11
 	else {
13
@@ -701,30 +687,25 @@
14
  * executing any commands in the shell.  Escape all control characters.
15
  * Use following technique:
16
  *
17
- * for bash - echo with `-e', 3-digit octal numbers:
18
- *   cd "`echo -e '\ooo...\ooo'`"
19
+ * printf(1) with format string containing a single conversion specifier,
20
+ * "b", and an argument which contains a copy of the string passed to 
21
+ * subshell_name_quote() with all characters, except digits and letters,
22
+ * replaced by the backslash-escape sequence \0nnn, where "nnn" is the
23
+ * numeric value of the character converted to octal number.
24
+ * 
25
+ *   cd "`printf "%b" 'ABC\0nnnDEF\0nnnXYZ'`"
26
  *
27
- * for zsh - echo with `-e', 4-digit octal numbers:
28
- *   cd "`echo '\oooo...\oooo'`"
29
- *
30
- * for tcsh - echo without `-e', 4-digit octal numbers:
31
- *   cd "`echo '\oooo...\oooo'`"
32
  */
33
 static char *
34
 subshell_name_quote (const char *s)
35
 {
36
     char *ret, *d;
37
-    const char echo_cmd[] = "\"`echo '";
38
-    const char echo_e_cmd[] = "\"`echo -e '";
39
-    const char common_end[] = "'`\"";
40
-    const char *cmd_start;
41
-    int len;
42
+    const char quote_cmd_start[] = "\"`printf \"%b\" '";
43
+    const char quote_cmd_end[] = "'`\"";
44
 
45
-    /*
46
-     * Factor 5 because we need \, 0 and 3 other digits per character
47
-     * in the worst case (tcsh and zsh).
48
-     */
49
-    d = ret = g_malloc (5 * strlen (s) + 16);
50
+    /* Factor 5 because we need \, 0 and 3 other digits per character. */
51
+    d = ret = g_malloc (1 + (5 * strlen (s)) + (sizeof(quote_cmd_start) - 1)
52
+				+ (sizeof(quote_cmd_end) - 1));
53
     if (!d)
54
 	return NULL;
55
 
56
@@ -734,43 +715,25 @@
57
 	*d++ = '/';
58
     }
59
 
60
-    /* echo in tcsh doesn't understand the "-e" option */
61
-    if (subshell_type == TCSH)
62
-	cmd_start = echo_cmd;
63
-    else
64
-	cmd_start = echo_e_cmd;
65
-
66
     /* Copy the beginning of the command to the buffer */
67
-    len = strlen (cmd_start);
68
-    memcpy (d, cmd_start, len);
69
-    d += len;
70
+    strcpy (d, quote_cmd_start);
71
+    d += sizeof(quote_cmd_start) - 1;
72
 
73
     /*
74
-     * Print every character in octal format with the leading backslash.
75
-     * tcsh and zsh may require 4-digit octals, bash < 2.05b doesn't like them.
76
+     * Print every character except digits and letters as a backslash-escape
77
+     * sequence of the form \0nnn, where "nnn" is the numeric value of the
78
+     * character converted to octal number.
79
      */
80
-    if (subshell_type == BASH) {
81
-	for (; *s; s++) {
82
-	    /* Must quote numbers, so that they are not glued to octals */
83
-	    if (isalpha ((unsigned char) *s)) {
84
-		*d++ = (unsigned char) *s;
85
-	    } else {
86
-		sprintf (d, "\\%03o", (unsigned char) *s);
87
-		d += 4;
88
-	    }
89
-	}
90
-    } else {
91
-	for (; *s; s++) {
92
-	    if (isalnum ((unsigned char) *s)) {
93
-		*d++ = (unsigned char) *s;
94
-	    } else {
95
-		sprintf (d, "\\0%03o", (unsigned char) *s);
96
-		d += 5;
97
-	    }
98
+    for (; *s; s++) {
99
+	if (isalnum ((unsigned char) *s)) {
100
+	    *d++ = (unsigned char) *s;
101
+	} else {
102
+	    sprintf (d, "\\0%03o", (unsigned char) *s);
103
+	    d += 5;
104
 	}
105
     }
106
 
107
-    memcpy (d, common_end, sizeof (common_end));
108
+    strcpy (d, quote_cmd_end);
109
 
110
     return ret;
111
 }
(-)files/patch-vfs-ftpfs-bug3727 (-52 lines)
Removed Link Here
1
--- vfs/ftpfs.c.orig	2004-11-03 03:54:00.000000000 +0200
2
+++ vfs/ftpfs.c	2005-02-07 17:34:25.000000000 +0200
3
@@ -316,6 +316,8 @@
4
     va_list ap;
5
     char *cmdstr;
6
     int status, cmdlen;
7
+    static int retry = 0;
8
+    static int level = 0;	/* ftpfs_login_server() use ftpfs_command() */
9
 
10
     va_start (ap, fmt);
11
     cmdstr = g_strdup_vprintf (fmt, ap);
12
@@ -343,7 +345,6 @@
13
 	code = 421;
14
 
15
 	if (errno == EPIPE) {	/* Remote server has closed connection */
16
-	    static int level = 0;	/* ftpfs_login_server() use ftpfs_command() */
17
 	    if (level == 0) {
18
 		level = 1;
19
 		status = ftpfs_reconnect (me, super);
20
@@ -359,14 +360,30 @@
21
 	disable_interrupt_key ();
22
 	return TRANSIENT;
23
     }
24
+    retry = 0;
25
   ok:
26
-    g_free (cmdstr);
27
     disable_interrupt_key ();
28
 
29
     if (wait_reply)
30
-	return ftpfs_get_reply (me, SUP.sock,
31
+    {
32
+	status = ftpfs_get_reply (me, SUP.sock,
33
 			  (wait_reply & WANT_STRING) ? reply_str : NULL,
34
 			  sizeof (reply_str) - 1);
35
+	if ((wait_reply & WANT_STRING) && !retry && !level && code == 421)
36
+	{
37
+	    retry = 1;
38
+	    level = 1;
39
+    	    status = ftpfs_reconnect (me, super);	    
40
+	    level = 0;
41
+	    if (status && (write (SUP.sock, cmdstr, cmdlen) > 0)) {
42
+	        goto ok;
43
+	    }
44
+	}
45
+	retry = 0;
46
+        g_free (cmdstr);	
47
+	return status;
48
+    }
49
+    g_free (cmdstr);    
50
     return COMPLETE;
51
 }
52
 

Return to bug 131355