Package: moc
Version: 2.3.3-1
Severity: important
Tags: patch l10n

When run with UTF-8 locale moc does not display non-latin characters
well, as shown on (locale uk_UA.UTF-8):
    http://www.cluster.kiev.ua/eugen/moc-bug/bad.png

Attached patch fixes this problem, result is shown in
    http://www.cluster.kiev.ua/eugen/moc-bug/good.png

Patch changes one m4 file, so you will need to regenerate auto* files
after applying the patch.

Severity is due to UTF8 to be default in etch.

-- System Information:
Debian Release: testing/unstable
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.16-rc1-me
Locale: LANG=uk_UA.UTF-8, LC_CTYPE=uk_UA.UTF-8 (charmap=UTF-8)

Versions of packages moc depends on:
ii  libasound2    1.0.10-2                   ALSA library
ii  libc6         2.3.5-12                   GNU C Library: Shared libraries an
ii  libcomerr2    1.38+1.39-WIP-2005.12.31-1 common error description library
ii  libcurl3-gnut 7.15.1-1                   Multi-protocol file transfer libra
ii  libflac7      1.1.2-3+b1                 Free Lossless Audio Codec - runtim
ii  libgnutls12   1.2.9-2                    the GNU TLS library - runtime libr
ii  libid3tag0    0.15.1b-8                  ID3 tag reading library from the M
ii  libidn11      0.5.18-1                   GNU libidn library, implementation
ii  libjack0.100. 0.100.0-4                  JACK Audio Connection Kit (librari
ii  libkrb53      1.4.3-5                    MIT Kerberos runtime libraries
ii  libmad0       0.15.1b-2.1                MPEG audio decoder library
ii  libmpcdec3    1.2.2-1                    Musepack (MPC) format library
ii  libncursesw5  5.5-1                      Shared libraries for terminal hand
ii  libogg0       1.1.2-1                    Ogg Bitstream Library
ii  libsamplerate 0.1.2-2                    audio rate conversion library
ii  libsndfile1   1.0.12-3                   Library for reading/writing audio 
ii  libspeex1     1.1.11.1-1                 The Speex Speech Codec
ii  libtagc0      1.4-3                      TagLib Audio Meta-Data Library (C 
ii  libvorbis0a   1.1.0-1                    The Vorbis General Audio Compressi
ii  libvorbisfile 1.1.0-1                    The Vorbis General Audio Compressi
ii  zlib1g        1:1.2.3-9                  compression library - runtime

moc recommends no packages.

-- no debconf information
diff -ur --exclude configure --exclude aclocal.m4 --exclude config.h.in moc-orig/debian/control moc-2.3.3/debian/control
--- moc-orig/debian/control	2006-01-18 11:52:55.000000000 +0200
+++ moc-2.3.3/debian/control	2006-01-18 11:53:54.000000000 +0200
@@ -5,7 +5,7 @@
 Uploaders: Bartosz Fenski <[EMAIL PROTECTED]>
 Standards-Version: 3.6.2.1
 Build-Conflicts-Indep: libcurl3-gssapi
-Build-Depends: debhelper (>> 4.0.0), libncurses5-dev, libncursesw5-dev, libasound2-dev [!kfreebsd-i386], libvorbis-dev (>= 1.1.0), libmad0-dev, libid3tag0-dev, zlib1g-dev, libsndfile1-dev, libflac-dev (>= 1.1.1), libogg-dev (>=1.1.2), dpatch (>= 2.0.10), libsamplerate0-dev, libspeex-dev, libmpcdec-dev, libtagc0-dev, libjack0.100.0-dev, libcurl3-gnutls-dev (>= 7.14.1-3)
+Build-Depends: debhelper (>> 4.0.0), libncursesw5-dev, libasound2-dev [!kfreebsd-i386], libvorbis-dev (>= 1.1.0), libmad0-dev, libid3tag0-dev, zlib1g-dev, libsndfile1-dev, libflac-dev (>= 1.1.1), libogg-dev (>=1.1.2), dpatch (>= 2.0.10), libsamplerate0-dev, libspeex-dev, libmpcdec-dev, libtagc0-dev, libjack0.100.0-dev, libcurl3-gnutls-dev (>= 7.14.1-3)
 
 Package: moc
 Architecture: any
diff -ur --exclude configure --exclude aclocal.m4 --exclude config.h.in moc-orig/interface.c moc-2.3.3/interface.c
--- moc-orig/interface.c	2005-12-29 16:06:55.000000000 +0200
+++ moc-2.3.3/interface.c	2006-01-18 20:02:35.000000000 +0200
@@ -30,7 +30,7 @@
 #ifdef HAVE_NCURSES_H
 # include <ncurses.h>
 #elif HAVE_CURSES_H
-# include <curses.h>
+# include <ncursesw/curses.h>
 #endif
 
 #include <string.h>
@@ -41,6 +41,8 @@
 #include <assert.h>
 #include <ctype.h>
 #include <locale.h>
+#define __USE_XOPEN
+#include <wchar.h>
 
 #define DEBUG
 
@@ -190,6 +192,59 @@
 static char *urls_history[HISTORY_MAX];
 static int urls_history_len = 0;
 
+static int moc_strwidth(const char *s)
+{
+	wchar_t wc;
+	int n = 0;
+	mbstate_t st;
+
+	memset(&st, 0, sizeof(st));
+
+	while (*s) {
+		int m;
+		int l;
+		
+		if ((l = mbrtowc(&wc, s, MB_CUR_MAX, &st)) <= 0)
+			return n;
+		m = wcwidth(wc);
+		if (m < 0)
+			n++;
+		else
+			n += m;
+		s += l;
+	}
+	return n;
+}
+
+size_t moc_pfxlen(const char *s, int w, int *rw)
+{
+	int n = 0;
+	mbstate_t st;
+	size_t len = 0;
+	
+	memset(&st, 0, sizeof(st));
+	
+	while (*s) {
+		int m;
+		int l;
+		wchar_t wc;
+	
+		if ((l = mbrtowc(&wc, s, MB_CUR_MAX, &st)) <= 0)
+			break;
+		m = wcwidth(wc);
+		if (m < 0)
+			m = 1;
+		if (m + n > w)
+			break;
+		n += m;
+		len += l;
+		s += l;
+	}
+	if (rw)
+		*rw = n;
+	return len;
+}
+
 static void xterm_clear_title ()
 {
 	if (has_xterm)
@@ -274,7 +329,7 @@
 			lines.ulcorn, lines.urcorn, lines.vert, lines.vert);
 
 	/* The title */
-	wmove (main_win, 0, COLS / 2 - strlen(mainwin_title) / 2 - 1);
+	wmove (main_win, 0, COLS / 2 - moc_strwidth(mainwin_title) / 2 - 1);
 	
 	wattrset (main_win, get_color(CLR_FRAME));
 	waddch (main_win, lines.rtee);
@@ -288,11 +343,13 @@
 
 static void set_title (const char *title)
 {
-	int len = strlen (title);
+	int width = moc_strwidth (title);
 
-	if (len > COLS - 4) {
+	if (width > COLS - 4) {
+		size_t pl = moc_pfxlen(title, COLS - 7, NULL);
+		
 		snprintf (mainwin_title, sizeof(mainwin_title),
-				"...%s", title + len - COLS + 7);
+				"...%s", title + pl);
 	}
 	else
 		strcpy (mainwin_title, title);
@@ -319,7 +376,7 @@
 	
 	wattrset (info_win, get_color(CLR_STATUS));
 	mvwaddstr (info_win, 0, 6, interface_status);
-	for (i = strlen(interface_status); i < STATUS_LINE_LEN; i++)
+	for (i = moc_strwidth(interface_status); i < STATUS_LINE_LEN; i++)
 		waddch (info_win, ' ');
 }
 
@@ -534,7 +591,7 @@
 		
 		/* the text fits into the screen */
 		wprintw (info_win, " %-*s", entry.width, entry.text);
-		wmove (info_win, 0, entry.cur_pos + strlen(entry.title) + 3);
+		wmove (info_win, 0, entry.cur_pos + moc_strwidth(entry.title) + 3);
 	}
 	else {
 
@@ -542,7 +599,7 @@
 		wprintw (info_win, " %-*s", entry.width,
 				entry.text + entry.display_from);
 		wmove (info_win, 0, entry.cur_pos - entry.display_from
-				+ strlen(entry.title) + 3);
+				+ moc_strwidth(entry.title) + 3);
 	}
 
 	/* Restore the truncated char */
@@ -555,7 +612,7 @@
 	entry.text[0] = 0;
 	entry.file = NULL;
 	strncpy (entry.title, title, sizeof(entry.title));
-	entry.width = COLS - strlen(title) - 4;
+	entry.width = COLS - moc_strwidth(title) - 4;
 	entry.cur_pos = 0;
 	entry.display_from = 0;
 	entry_draw ();
@@ -731,7 +788,7 @@
 			: get_color(CLR_MESSAGE));
 	mvwaddnstr (info_win, 1, 1, message, COLS - 2);
 
-	len = strlen (message);
+	len = moc_strwidth (message);
 	for (i = 0; i < COLS - 2 - len; i++)
 		waddch (info_win, ' ');
 }
@@ -788,11 +845,11 @@
 	wattrset (info_win, get_color(CLR_SOUND_PARAMS));
 
 	/* Rate */
-	wmove (info_win, 2, 25 - strlen(file_info.rate));
+	wmove (info_win, 2, 25 - moc_strwidth(file_info.rate));
 	waddstr (info_win, file_info.rate);
 	
 	/* Bitrate */
-	wmove (info_win, 2, 33 - strlen(file_info.bitrate));
+	wmove (info_win, 2, 33 - moc_strwidth(file_info.bitrate));
 	waddstr (info_win, file_info.bitrate);
 
 	/* Channels */
@@ -846,7 +903,7 @@
 
 static void set_interface_status (const char *msg)
 {
-	assert (!msg || strlen(msg) <= STATUS_LINE_LEN);
+	assert (!msg || moc_strwidth(msg) <= STATUS_LINE_LEN);
 
 	if (info_win) {
 		if (msg)
@@ -1989,7 +2046,7 @@
 	send_int_to_srv (CMD_GET_MIXER_CHANNEL_NAME);
 	name = get_data_str ();
 
-	assert (strlen(name) <= 14);
+	assert (moc_strwidth(name) <= 14);
 
 	strcpy (mixer_name, name);
 	free (name);
@@ -3839,7 +3896,7 @@
 	mvwin (info_win, LINES - 4, 0);
 	werase (main_win);
 	
-	entry.width = COLS - strlen(entry.title) - 4;
+	entry.width = COLS - moc_strwidth(entry.title) - 4;
 	entry_end ();
 
 	if (curr_plist_menu)
diff -ur --exclude configure --exclude aclocal.m4 --exclude config.h.in moc-orig/interface.h moc-2.3.3/interface.h
--- moc-orig/interface.h	2005-06-19 12:21:47.000000000 +0300
+++ moc-2.3.3/interface.h	2006-01-18 13:39:16.000000000 +0200
@@ -22,4 +22,6 @@
 void interface_cmdline_play_first (int server_sock);
 void interface_cmdline_file_info (const int server_sock);
 void interface_cmdline_playit (int server_sock, char **args, const int arg_num);
+
+size_t moc_pfxlen(const char *s, int w, int *rw);
 #endif
diff -ur --exclude configure --exclude aclocal.m4 --exclude config.h.in moc-orig/keys.c moc-2.3.3/keys.c
--- moc-orig/keys.c	2005-07-29 12:10:36.000000000 +0300
+++ moc-2.3.3/keys.c	2006-01-18 12:08:38.000000000 +0200
@@ -20,7 +20,7 @@
 #ifdef HAVE_NCURSES_H
 # include <ncurses.h>
 #elif HAVE_CURSES_H
-# include <curses.h>
+# include <ncursesw/curses.h>
 #endif
 
 #include <stdio.h>
diff -ur --exclude configure --exclude aclocal.m4 --exclude config.h.in moc-orig/m4/mp_with_curses.m4 moc-2.3.3/m4/mp_with_curses.m4
--- moc-orig/m4/mp_with_curses.m4	2005-06-15 19:56:43.000000000 +0300
+++ moc-2.3.3/m4/mp_with_curses.m4	2006-01-18 12:00:04.000000000 +0200
@@ -14,36 +14,18 @@
 dnl @author Mark Pulford <[EMAIL PROTECTED]>
 dnl
 AC_DEFUN([MP_WITH_CURSES],
-  [AC_ARG_WITH(ncurses, [  --with-ncurses          Force the use of ncurses over curses],,)
-   mp_save_LIBS="$LIBS"
+  [mp_save_LIBS="$LIBS"
    CURSES_LIB=""
-   if test "$with_ncurses" != yes
+   AC_CACHE_CHECK([for working ncursesw], mp_cv_curses,
+     [LIBS="$LIBS -lncursesw"
+      AC_TRY_LINK(
+        [#include <ncursesw/curses.h>],
+        [chtype a; int b=A_STANDOUT, c=KEY_LEFT; initscr(); ],
+        mp_cv_curses=yes, mp_cv_curses=no)])
+   if test "$mp_cv_curses" = yes
    then
-     AC_CACHE_CHECK([for working curses], mp_cv_curses,
-       [LIBS="$LIBS -lcurses"
-        AC_TRY_LINK(
-          [#include <curses.h>],
-          [chtype a; int b=A_STANDOUT, c=KEY_LEFT; initscr(); ],
-          mp_cv_curses=yes, mp_cv_curses=no)])
-     if test "$mp_cv_curses" = yes
-     then
-       AC_DEFINE(HAVE_CURSES_H, 1, [Define if you have curses.h])
-       CURSES_LIB="-lcurses"
-     fi
-   fi
-   if test ! "$CURSES_LIB"
-   then
-     AC_CACHE_CHECK([for working ncurses], mp_cv_ncurses,
-       [LIBS="$mp_save_LIBS -lncurses"
-        AC_TRY_LINK(
-          [#include <ncurses.h>],
-          [chtype a; int b=A_STANDOUT, c=KEY_LEFT; initscr(); ],
-          mp_cv_ncurses=yes, mp_cv_ncurses=no)])
-     if test "$mp_cv_ncurses" = yes
-     then
-       AC_DEFINE(HAVE_NCURSES_H, 1, [Define if you have ncurses.h])
-       CURSES_LIB="-lncurses"
-     fi
+     AC_DEFINE(HAVE_CURSES_H, 1, [Define if you have curses.h])
+     CURSES_LIB="-lncursesw"
    fi
    LIBS="$mp_save_LIBS"
 ])dnl
diff -ur --exclude configure --exclude aclocal.m4 --exclude config.h.in moc-orig/menu.c moc-2.3.3/menu.c
--- moc-orig/menu.c	2005-10-04 10:34:19.000000000 +0300
+++ moc-2.3.3/menu.c	2006-01-18 16:13:55.000000000 +0200
@@ -20,7 +20,7 @@
 #ifdef HAVE_NCURSES_H
 # include <ncurses.h>
 #elif HAVE_CURSES_H
-# include <curses.h>
+# include <ncursesw/curses.h>
 #endif
 
 #include <assert.h>
@@ -28,6 +28,7 @@
 #include "main.h"
 #include "menu.h"
 #include "files.h"
+#include "interface.h"
 
 /* Initial number of items to allocate in a new menu. */
 #define INIT_NUM_ITEMS	64
@@ -66,10 +67,11 @@
 static void draw_item (const struct menu *menu, const int num, const int pos,
 		const int item_info_pos, const int title_space)
 {
-	int title_len;
 	const struct menu_item *item = &menu->items[num];
 	int j;
-
+	size_t pl;
+	int n;
+	
 	wmove (menu->win, pos, 1);
 	
 	/* Set attributes */
@@ -82,15 +84,15 @@
 	else
 		wattrset (menu->win, item->attr_normal);
 	
-	waddnstr (menu->win, item->title, title_space);
-	title_len = strlen (item->title);
+	pl = moc_pfxlen(item->title, title_space, &n);
+	waddnstr (menu->win, item->title, pl);
 	
 	/* Make blank line to the right side of the screen */
 	if (num == menu->selected) {
-		for (j = title_len + 1; j <= title_space; j++)
+		for (j = n + 1; j <= title_space; j++)
 			waddch (menu->win, ' ');
 	}
-
+	
 	/* Description */
 	wattrset (menu->win, menu->info_attr);
 	wmove (menu->win, pos, item_info_pos);
diff -ur --exclude configure --exclude aclocal.m4 --exclude config.h.in moc-orig/menu.h moc-2.3.3/menu.h
--- moc-orig/menu.h	2005-06-19 19:50:14.000000000 +0300
+++ moc-2.3.3/menu.h	2006-01-18 12:09:10.000000000 +0200
@@ -4,7 +4,7 @@
 #ifdef HAVE_NCURSES_H
 # include <ncurses.h>
 #elif HAVE_CURSES_H
-# include <curses.h>
+# include <ncursesw/curses.h>
 #endif
 
 #include "files.h"
diff -ur --exclude configure --exclude aclocal.m4 --exclude config.h.in moc-orig/themes.c moc-2.3.3/themes.c
--- moc-orig/themes.c	2005-07-29 12:10:36.000000000 +0300
+++ moc-2.3.3/themes.c	2006-01-18 12:09:27.000000000 +0200
@@ -16,7 +16,7 @@
 #ifdef HAVE_NCURSES_H
 # include <ncurses.h>
 #elif HAVE_CURSES_H
-# include <curses.h>
+# include <ncursesw/curses.h>
 #endif
 
 #include <assert.h>

Reply via email to