From a48c2fe2c2d13fbc879a6b5111fc9f3c866ac5b3 Mon Sep 17 00:00:00 2001 From: Kalle Wallin Date: Fri, 19 Mar 2004 19:15:43 +0000 Subject: [PATCH] Added iconv support git-svn-id: https://svn.musicpd.org/ncmpc/trunk@308 09075e82-0dd4-0310-85a5-a0d7c8717e4f --- configure.ac | 13 ++++++ mpc.c | 24 +++++++--- screen_file.c | 8 +++- support.c | 124 ++++++++++++++++++++++++++++++++++++++++++++------ support.h | 7 ++- 5 files changed, 153 insertions(+), 23 deletions(-) diff --git a/configure.ac b/configure.ac index 8adb481..1d537c6 100644 --- a/configure.ac +++ b/configure.ac @@ -18,6 +18,7 @@ set -- $CFLAGS CFLAGS="-Wall $CFLAGS" + dnl dnl Check for libaries dnl @@ -44,6 +45,18 @@ AC_CHECK_TYPE(socklen_t, dnl dnl Check for headers dnl + +AM_ICONV + +AC_CHECK_HEADER(langinfo.h, + AC_DEFINE(HAVE_LANGINFO_H, 1, langinfo.h), + ,) + +AC_CHECK_HEADER(locale.h, + AC_DEFINE(HAVE_LOCALE_H, 1, locale.h), + ,) + + AC_CHECK_HEADER(libgen.h, AC_DEFINE(HAVE_LIBGEN_H, 1, glibc - libgen.h), ,) diff --git a/mpc.c b/mpc.c index ccb0835..f62d978 100644 --- a/mpc.c +++ b/mpc.c @@ -16,6 +16,8 @@ #include "mpc.h" #include "options.h" +#define MAX_SONG_LENGTH 1024 + void mpc_update_song(mpd_client_t *c) { @@ -186,21 +188,31 @@ mpc_playlist_get_song(mpd_client_t *c, int n) char * mpc_get_song_name(mpd_Song *song) { + static char buf[MAX_SONG_LENGTH]; + char *name; + if( song->title ) { if( song->artist ) { - static char buf[512]; - - snprintf(buf, 512, "%s - %s", song->artist, song->title); - return utf8(buf); + snprintf(buf, MAX_SONG_LENGTH, "%s - %s", song->artist, song->title); + name = utf8_to_locale(buf); + strncpy(buf, name, MAX_SONG_LENGTH); + free(name); + return buf; } else { - return utf8(song->title); + name = utf8_to_locale(song->title); + strncpy(buf, name, MAX_SONG_LENGTH); + free(name); + return buf; } } - return utf8(basename(song->file)); + name = utf8_to_locale(song->file); + strncpy(buf, name, MAX_SONG_LENGTH); + free(name); + return buf; } int diff --git a/screen_file.c b/screen_file.c index bd60872..d83a187 100644 --- a/screen_file.c +++ b/screen_file.c @@ -16,10 +16,12 @@ #include "screen.h" #include "screen_file.h" +#define BUFSIZE 1024 static char * list_callback(int index, int *highlight, void *data) { + static char buf[BUFSIZE]; mpd_client_t *c = (mpd_client_t *) data; filelist_entry_t *entry; mpd_InfoEntity *entity; @@ -37,10 +39,12 @@ list_callback(int index, int *highlight, void *data) } if( entity->type==MPD_INFO_ENTITY_TYPE_DIRECTORY ) { - mpd_Directory *dir = entity->info.directory; + char *dirname = utf8_to_locale(dir->path); - return utf8(basename(dir->path)); + strncpy(buf, dirname, BUFSIZE); + free(dirname); + return buf; } else if( entity->type==MPD_INFO_ENTITY_TYPE_SONG ) { diff --git a/support.c b/support.c index ce67dc8..d2dc975 100644 --- a/support.c +++ b/support.c @@ -1,16 +1,35 @@ -/* - * $Id: support.c,v 1.2 2004/03/17 23:17:09 kalle Exp $ - * - */ - +#include #include #include #include #include #include "config.h" + +#ifdef HAVE_LOCALE_H +#ifdef HAVE_LANGINFO_H +#ifdef HAVE_ICONV +#include +#include +#include +#define ENABLE_CHARACTER_SET_CONVERSION +#endif +#endif +#endif + #include "support.h" +#define BUFSIZE 1024 + +#ifdef ENABLE_CHARACTER_SET_CONVERSION +static char *locale = NULL; +static char *charset = NULL; +iconv_t iconv_from_uft8 = (iconv_t)(-1); +iconv_t iconv_to_uft8 = (iconv_t)(-1); +#endif + + + #ifndef HAVE_LIBGEN_H char * @@ -48,17 +67,94 @@ basename(char *path) #endif /* HAVE_LIBGEN_H */ -char * -utf8(char *str) + +int +charset_init(void) { - static const gchar *charset = NULL; - static gboolean locale_is_utf8 = FALSE; +#ifdef ENABLE_CHARACTER_SET_CONVERSION + /* get current locale */ + if( (locale=setlocale(LC_CTYPE,"")) == NULL ) + { + fprintf(stderr,"setlocale() - failed!\n"); + return -1; + } + + /* get charset */ + if( (charset=nl_langinfo(CODESET)) == NULL ) + { + fprintf(stderr,"nl_langinfo() - failed!\n"); + return -1; + } + + /* allocate descriptor for character set conversion */ + iconv_from_uft8 = iconv_open(charset, "UTF-8"); + if( iconv_from_uft8 == (iconv_t)(-1) ) + { + perror("iconv_open"); + return -1; + } +#endif + + return 0; +} - if( !charset ) - locale_is_utf8 = g_get_charset(&charset); +int +charset_close(void) +{ +#ifdef ENABLE_CHARACTER_SET_CONVERSION + if( iconv_from_uft8 == (iconv_t)(-1) ) + { + iconv_close(iconv_from_uft8); + iconv_from_uft8 = (iconv_t)(-1); + } + if( iconv_to_uft8 == (iconv_t)(-1) ) + { + iconv_close(iconv_to_uft8); + iconv_to_uft8 = (iconv_t)(-1); + } +#endif + return 0; +} - if( locale_is_utf8 ) - return str; - return g_locale_from_utf8(str, -1, NULL, NULL, NULL); + +char * +utf8_to_locale(char *str) +{ +#ifdef ENABLE_CHARACTER_SET_CONVERSION + size_t inleft; + size_t retlen; + char *ret; + + if( iconv_from_uft8 == (iconv_t)(-1) ) + return strdup(str); + + ret = NULL; + retlen = 0; + inleft = strlen(str); + while( inleft>0 ) + { + char buf[BUFSIZE]; + size_t outleft = BUFSIZE; + char *bufp = buf; + + if( iconv(iconv_from_uft8, &str, &inleft, &bufp, &outleft) <0 ) + { + perror("iconv"); + free(ret); + return NULL; + } + ret = realloc(ret, BUFSIZE-outleft+1); + memcpy(ret+retlen, buf, BUFSIZE-outleft); + retlen += BUFSIZE-outleft; + ret[retlen] = '\0'; + } + return ret; + +#else + return strdup(str); +#endif } + + + diff --git a/support.h b/support.h index 834dd8c..c0b9c34 100644 --- a/support.h +++ b/support.h @@ -5,5 +5,10 @@ char *basename(char *path); #endif -char *utf8(char *str); + + +int charset_init(void); +int charset_close(void); +char *utf8_to_locale(char *str); + -- 2.30.2