aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKalle Wallin <kaw@linux.se>2004-03-19 19:15:43 +0000
committerKalle Wallin <kaw@linux.se>2004-03-19 19:15:43 +0000
commita48c2fe2c2d13fbc879a6b5111fc9f3c866ac5b3 (patch)
tree8a5ff0674412243fd2610f0c0b3f21cd6e176506
parent526b460e750f52f5b9b04df72b6601fe4c1fd5f7 (diff)
downloadmpd-a48c2fe2c2d13fbc879a6b5111fc9f3c866ac5b3.tar.gz
mpd-a48c2fe2c2d13fbc879a6b5111fc9f3c866ac5b3.tar.xz
mpd-a48c2fe2c2d13fbc879a6b5111fc9f3c866ac5b3.zip
Added iconv support
git-svn-id: https://svn.musicpd.org/ncmpc/trunk@308 09075e82-0dd4-0310-85a5-a0d7c8717e4f
-rw-r--r--configure.ac13
-rw-r--r--mpc.c24
-rw-r--r--screen_file.c8
-rw-r--r--support.c124
-rw-r--r--support.h7
5 files changed, 153 insertions, 23 deletions
diff --git a/configure.ac b/configure.ac
index 8adb481ee..1d537c6e9 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 ccb083590..f62d9789c 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 bd60872e6..d83a1870c 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 ce67dc81e..d2dc9759c 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 <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include "config.h"
+
+#ifdef HAVE_LOCALE_H
+#ifdef HAVE_LANGINFO_H
+#ifdef HAVE_ICONV
+#include <locale.h>
+#include <langinfo.h>
+#include <iconv.h>
+#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 834dd8cda..c0b9c34dc 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);
+